? Form Conductor
A declarative form validation library for Kotlin.
Form conductor is more than form validation. It provides a handful of reusable API to construct a form in simple easy steps. Form conductor tries to tackle three aspects of forms:
Form Data Handling
Form State Management
Form Validation
Table of contents
? Form construction using built-in annotations
FormData.kt
data class SignUpForm(
@MinLength(2)
val name: String = "",
@IntegerRange(min = 18, max = 99)
val age: Int = 0,
@EmailAddress
val emailAddress: String = "",
val gender: Gender = Gender.Male,
@Optional
@MaxLength(150)
val address: String? = null
@IsChecked
val termsAndConditionAgreed: Boolean = false
@MaxLength(200)
val bio: String = ""
)
Using Jetpack Compose
form
composable
@Composable
fun FormScreen() {
Column {
form(SignUpForm::class) {
/**
* Following properties are available
* formState - State<FormResult<SignUpForm>>
* registerField() - returns field object
*/
Button(
text = "Sign Up",
enabled = this.formState.value is FormResult.Success
)
}
}
}
field
composable
form(SignUpForm::class) {
field(SignUpForm::name) {
/**
* Following properties are available
* state - compose state with field value: State<FieldValue<String>>
* resultState - validation result state: State<FieldResult<String>>
* setField() - sets the field value and validate
*/
TextField(
value = state.value?.value.orEmpty(),
onValueChange = this::setField,
isError = resultState.value is FieldResult.Error
)
}
}
Full Example
@Composable
fun FormScreen() {
Column {
form(SignUpForm::class) {
field(SignUpFormData::name) {
TextField(
value = state.value?.value.orEmpty(),
onValueChange = this::setField,
isError = resultState.value is FieldResult.Error
)
}
field(SignUpFormData::emailAddress) {
TextField(
value = state.value?.value.orEmpty(),
onValueChange = this::setField
)
}
field(SignUpFormData::gender) {
Row(Modifier.selectableGroup()) {
RadioButton(
selected = state.value?.value == Gender.Male,
onClick = { setField(Gender.Male) },
modifier = Modifier.semantics { contentDescription = "Male" }
)
RadioButton(
selected = state.value?.value == Gender.Female,
onClick = { setField(Gender.Female) },
modifier = Modifier.semantics { contentDescription = "Male" }
)
}
}
}
}
}
Installation
Single dependency (imports all the modules as a single dependency)
// Groovy
dependencies {
implementation "com.github.NaingAungLuu:form-conductor:$<latest_version>"
}
// Kts
dependencies {
implementation("com.github.NaingAungLuu:form-conductor:$<latest_version>")
}
Modular dependency
// Groovy
dependencies {
implementation "com.github.NaingAungLuu.form-conductor:core:$<latest_version>"
implementation "com.github.NaingAungLuu.form-conductor:compose-ui:$<latest_version>"
}
// Kts
dependencies {
implementation("com.github.NaingAungLuu.form-conductor:core:$<latest_version>")
implementation("com.github.NaingAungLuu.form-conductor:compose-ui:$<latest_version>")
}
Available Modules
form-conductor:core
– Pure Kotlin library with all form validation features
form-conductor:compose-ui
– Android library with form
and field
composables with scopes for easy form state handling