TextField validation is a pain, hopefully this is a bit easier
Full documentation & pattern guides → — basic screens, ViewModel, MVI/UDF, and Circuit wiring, with every example compiled in CI against the current API.
@Composable
fun BasicSignUpScreen(onSubmit: (email: String, password: String) -> Unit) {
// No state holder: the validators live in the composable, remembered across
// recompositions. Each one owns its TextFieldValue draft + validation state.
val email = rememberTextFieldValueValidator(rules = listOf(Required, Email))
val password = rememberTextFieldValueValidator(rules = listOf(Required, MinLength(8)))
Column {
with(email) {
OutlinedTextField(
value = value,
onValueChange = ::onValueChange,
label = { Text("Email") },
isError = isError(),
supportingText = supportingText(),
singleLine = true,
modifier = Modifier
.fillMaxWidth()
// Show errors when focus leaves the field; shake on invalid submit.
.validationConfig(validateOnFocusLost = true, shakeOnInvalid = true),
)
}
with(password) {
OutlinedTextField(
value = value,
onValueChange = ::onValueChange,
label = { Text("Password") },
isError = isError(),
supportingText = supportingText(),
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.validationConfig(validateOnFocusLost = true, shakeOnInvalid = true),
)
}
Button(
onClick = {
// Form-level validate(): surfaces errors on every field, true when all pass.
if (listOf(email, password).validate()) {
onSubmit(email.value.text, password.value.text)
}
},
modifier = Modifier.fillMaxWidth(),
) { Text("Create account") }
}
}Prefer the state holder to own the form? Yakcov also works headlessly — a
ViewModel/presenter owns a FieldValidator, or a pure MVI reducer folds rules with
toFieldState. See the
ViewModel and
MVI/UDF guides.
By default we publish to Maven Central.
We publish all targets (Android, JVM, JS, Wasm, iOS) you can include the common library in your project and it will pull in the correct target for what ever targets you have specified.
commonMain {
dependencies {
implementation("com.chrisjenx.yakcov:library:${version}")
}
}If you only need a specific target you can include that directly, for example for Android:
dependencies {
implementation("com.chrisjenx.yakcov:library-android:${version}")
}The PhoneFormat rule validates phone-number format with no extra dependencies. The
region-aware Phone rule needs the (compileOnly) libphonenumber dependency added to your app —
see phone validation.
- check your system with KDoctor
- install JDK 17 or higher on your machine
- You will need Chrome installed for JS based tests to run
- run tests with
./gradlew :library:allTests
