Skip to content

Phone validation

Yakcov ships two phone rules. Pick based on whether you need the libphonenumber dependency:

Rule Dependency Checks
PhoneFormat none Lenient "looks like a phone number" format gate: optional leading +, digits and ( ) . / - separators, 7–15 digits.
Phone libphonenumber-kotlin (compileOnly) Region-aware validity via Google's libphonenumber.

Default: PhoneFormat (no setup)

PhoneFormat has no dependencies and runs on every target. Use it when the server is authoritative (normalizes to E.164 / verifies with a provider, e.g. Telnyx Verify) and the client only needs a cheap format gate:

@Composable
fun PhoneFormatField() {
    // PhoneFormat is a lenient, dependency-free format check — no libphonenumber needed.
    // The server stays authoritative and normalizes to E.164.
    val phone = rememberTextFieldValueValidator(rules = listOf(Required, PhoneFormat))
    with(phone) {
        OutlinedTextField(
            value = value,
            onValueChange = ::onValueChange,
            label = { Text("Phone") },
            isError = isError(),
            supportingText = supportingText(),
            singleLine = true,
            modifier = Modifier
                .fillMaxWidth()
                .validationConfig(validateOnFocusLost = true),
        )
    }
}

It deliberately accepts a wide range of real-world formats (international +, IDD 00/011 prefixes, national trunk 0, spaces/dashes/dots/parens) and leaves authoritative checks to the server. It does not reject wrong-region or structurally-invalid-but-well-formed numbers — that's Phone's job. The underlying check is also available directly as the public String?.isPhoneNumberFormat() helper.

Region-aware: Phone (opt-in)

Phone validates with libphonenumber-kotlin (luca992's multiplatform port of Google's libphonenumber). Yakcov declares it compileOnly, so this rule needs your app (or shared module) to provide the dependency:

commonMain {
    dependencies {
        implementation("io.github.luca992.libphonenumber-kotlin:libphonenumber:0.1.9")
    }
}
@Composable
fun PhoneField() {
    // Phone(defaultRegion) is powered by libphonenumber-kotlin, which yakcov declares
    // compileOnly — your app must add the dependency (see this page's install section).
    val phone = rememberTextFieldValueValidator(rules = listOf(Required, Phone("US")))
    with(phone) {
        OutlinedTextField(
            value = value,
            onValueChange = ::onValueChange,
            label = { Text("Phone") },
            isError = isError(),
            supportingText = supportingText(),
            singleLine = true,
            modifier = Modifier
                .fillMaxWidth()
                .validationConfig(validateOnFocusLost = true),
        )
    }
}

Phone also accepts a State<String> for the region, so the default region can react to a country picker: Phone(defaultRegion = countryState).

Without the dependency, using Phone fails at runtime with a missing-class error — everything else in Yakcov (including PhoneFormat) works without it.

Roll your own

Need a specific national format or an extension field? Write a ValueValidatorRule<String> — see custom rules. The dependency-free String?.isPhoneNumberFormat() helper is public and reusable as a building block.