Skip to content

SushiOTPTextField

A customizable OTP (One-Time Password) input field component for the Sushi design system.

SushiOTPTextField provides a series of individual input fields for entering verification codes, with automatic focus management and styling consistent with the Sushi design system. It comes in three visual styles: filled, outlined, and underlined.

OTP Input Preview

Example

The SushiOTPTextField component is used to create OTP input fields for verification codes:

// Create an OTP state for 6 digits
val otpState = rememberOtpState(6)

// Use the filled style (default)
SushiOTPTextField(
    state = otpState,
    autoFocus = true, // Automatically focus the first field
    onComplete = { code ->
        // Handle the completed 6-digit code
        println("OTP completed: $code")
    }
)

// Or use the outlined style
SushiOutlinedOTPTextField(
    state = otpState,
    autoFocus = true,
    onComplete = { code ->
        // Handle the completed 6-digit code
    }
)

// Or use the underlined style
SushiUnderlinedOTPTextField(
    state = otpState,
    autoFocus = true,
    onComplete = { code ->
        // Handle the completed 6-digit code
    }
)

Customization Examples

// Custom length (4 digits)
val otpState4 = rememberOtpState(4)
SushiOTPTextField(
    state = otpState4,
    autoFocus = false,
    onComplete = { code -> /* Handle 4-digit code */ }
)

// Custom text style
SushiOTPTextField(
    state = otpState,
    textStyle = TextStyle(
        fontSize = 24.sp,
        fontWeight = FontWeight.Bold,
        textAlign = TextAlign.Center,
        color = SushiTheme.colors.blue.v700.value
    ),
    onComplete = { code -> /* Handle code */ }
)

// Password masking
SushiOTPTextField(
    state = otpState,
    visualTransformation = PasswordVisualTransformation(),
    onComplete = { code -> /* Handle code */ }
)

// Custom colors
val customColors = SushiOTPTextFieldDefaults.filledColors().copy(
    focusedContainerColor = SushiTheme.colors.blue.v100,
    unfocusedContainerColor = SushiTheme.colors.blue.v050,
    focusedTextColor = SushiTheme.colors.blue.v900,
    unfocusedTextColor = SushiTheme.colors.blue.v700,
    cursorColor = SushiTheme.colors.blue.v600
)

SushiOTPTextField(
    state = otpState,
    colors = customColors,
    onComplete = { code -> /* Handle code */ }
)

// Error state
SushiOTPTextField(
    state = otpState,
    isError = true,
    onComplete = { code -> /* Handle code */ }
)

// Disabled state
SushiOTPTextField(
    state = otpState,
    enabled = false,
    onComplete = { code -> /* Handle code */ }
)

// Read-only state (for displaying a pre-filled code)
SushiOTPTextField(
    state = otpState,
    readOnly = true,
    onComplete = { code -> /* Handle code */ }
)

// Alphanumeric keyboard (accepts letters and numbers)
SushiOTPTextField(
    state = otpState,
    keyboardType = KeyboardType.Text,
    onComplete = { code -> /* Handle code */ }
)

Programmatically Setting Values

// Pre-fill values
otpState.onDigitEntered(0, '1')
otpState.onDigitEntered(1, '2')
otpState.onDigitEntered(2, '3')
otpState.onDigitEntered(3, '4')

// Clear values
for (i in 0 until otpState.length) {
    otpState.onDigitDeleted(i)
}

// Check if complete
val isComplete = otpState.isComplete()

Component API

SushiOTPTextField Parameters

Parameter Description
state
State controlling the OTP value and behavior
enabled
Whether the input fields are enabled
readOnly
Whether the input fields are read-only
isError
Whether to display the component in an error state
autoFocus
Whether to automatically focus the first input field when displayed
textStyle
The style to apply to the input text
colors
Colors configuration for different states of the component
visualTransformation
Transformation to apply to the input text (e.g., for masking)
keyboardType
The type of keyboard to show for input
onComplete
Callback invoked when all fields are filled

SushiOTPState Methods

Method Description
onDigitEntered(index: Int, value: Char)
Programmatically sets a digit at the specified position
onDigitDeleted(index: Int)
Clears the digit at the specified position
isFieldEmpty(index: Int)
Checks if the field at the specified position is empty
isComplete()
Checks if all fields have been filled
code
Property that returns the current OTP value (padded with spaces)