StylishPinInput

fun StylishPinInput(value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier, length: Int = 6, enabled: Boolean = true, isError: Boolean = false, filledColor: Color = MaterialTheme.colorScheme.primaryContainer, emptyColor: Color = MaterialTheme.colorScheme.surfaceVariant, errorColor: Color = MaterialTheme.colorScheme.error, boxSize: Dp = 48.dp, spacing: Dp = StylishTheme.dimensions.itemSpacing, interactionSource: MutableInteractionSource? = null)

A one-time password (OTP) / PIN entry field showing length boxes, each holding one digit of value.

The value is hoisted — the caller owns the state via value and onValueChange. Only digits are accepted and input is capped at length characters. A hidden BasicTextField (drawn with zero opacity, number-password keyboard) overlays the boxes and owns the real text state, so hardware and software keyboards, backspace, IME composition, and text-field semantics all work unchanged; tapping any box focuses the hidden field via a FocusRequester. While the field is focused, the box outlines highlight in the primary color; when isError is true the filled boxes and outlines render in errorColor.

The root is announced as a text field (via the underlying BasicTextField semantics), so screen readers report the entered digits. When enabled is false, the field rejects input and the boxes render in the empty color.

Testing

The root carries the default test tag stylish_pininput for UI tests. Callers can override it by passing their own Modifier.testTag(...) in modifier.

Parameters

value

The current PIN digits (controlled state). Only digits are expected; longer strings are truncated for display.

onValueChange

Called with the filtered digit string on every edit.

modifier

Modifier applied to the root Box.

length

The number of boxes. Defaults to 6.

enabled

When false, the field rejects input and the boxes render in the empty color.

isError

When true, filled boxes and outlines render in errorColor to signal a failed verification.

filledColor

Background of boxes holding a digit. Defaults to MaterialTheme.colorScheme.primaryContainer.

emptyColor

Background of empty boxes. Defaults to MaterialTheme.colorScheme.surfaceVariant.

errorColor

Color used for filled boxes and outlines while isError is true. Defaults to MaterialTheme.colorScheme.error.

boxSize

The edge length of each box. Defaults to 48.dp.

spacing

The gap between boxes. Defaults to StylishTheme.dimensions.itemSpacing.

interactionSource

The MutableInteractionSource for the hidden text field, used to observe focus interactions (driving the box outline highlight). When null, an internal one is remembered.