Structure
OUDSPinCodeInput
PIN code input is a UI element that allows to capture short, fixed-length numeric codes, typically for authentication or confirmation purposes, such as a four, six or eight-digit personal identification number (PIN). PIN code input is presented as a series of individual input fields or boxes, each representing a single digit, to enhance readability and encourage accurate input, while supporting smooth keyboard navigation and secured input masking if needed.
@MainActor struct OUDSPinCodeInput
Mentioned In
Layouts
The component can be rendered as two different layouts:
outlined layout: A minimalist input with a transparent background and a visible stroke outlining the field. This style may be interesting for contexts other than form pages, e.g. when inputs need to feel lightweight and unobtrusive, in a header (search field), or in a selection/filtering feature in a product catalog
not outlined (default): An input with a subtle background fill and visible bottom border, creating a softer and more contained look. Best suited for dense layouts or to enhance visibility.
The component provides 3 layouts for the input: 4 boxes, 6 boxes or 8 boxes.
A helper text can be used to support text to convey additional information about the input field, such as how it will be used. It should ideally only take up a single line, though may wrap to multiple lines if required, and be either persistently visible or visible only on focus.
Error status
The Error status indicates that the user input does not meet validation rules or expected formatting. It provides immediate visual feedback, typically through a red border, error icon, and a clear, accessible error message positioned below the input (mandatory). This state helps users quickly identify and correct mistakes by explaining what went wrong and, when possible, how to fix it. The input remains editable, encouraging users to revise their input without starting over. The error state must be triggered by an explicit validation (submission, API response), and not in real time with each keystroke. This can occur either because the entered code does not match the expected code, because the user entered an expired or already used code, or finally if the maximum number of attempts has been exceeded.
Specific design guidelines
In the context of a PIN code input, in addition to the input’s “Error” UI rendering, it is essential to also include an “Alert” component (also in its “Error” status) in the interface.
Particular cases
The OUDSPinCodeInput component supports autofill feature of values like OTP code. For example if the user receives a message with inside a code the system can extract, the keyboard can suggest to the user to fill it. If the digits fits the component, it will be filled. If the digits are longer, they will be truncated. If the digits are shorter, they will be filled, letting other fields empty.
The copy/paste feature is also available and has the same behavior.
Technical considerations
For some cases, on phones screens or with 8 boxes in iPhone, you may need to use a ScrollView to embed the component and let user move it.
ScrollView(.horizontal) {
OUDSPinCodeInput($value,
length: .eight,
helperText: "Enter your secret code sent to your phone")
}
Note also the exposed value Binding will be updated when all digits are written.
Accessibility considerations
The content of the fields is vocalized by Voice Over; the placeholders (defined in obfuscationCharacter and placeholderCharacter) are not vocalized to let users know what they wrote.
The component gets only numeric values, not letters or symbols, only numbers.
Depending on the component configuration, autofocus can still be used when the component appears, and focus is moved to the next field as digits are entered. For example if Voice Over is enavled, the autoficus is disabled.
The component and its digit fields are vocalized with internal wording.
When using the error status, provide a clear, concise error message explaining what went wrong and, when possible, how to fix it (for example: “The code you entered is invalid. Try again.”).
Use helper text to communicate additional guidance (for example: “Check the 6‑digit code sent by SMS”), and keep this text short so it remains easy to vocalize and understand.
Rich text
Rich text can be used for error and helper texts.
Strong text can be used sparingly to highlight key information within the content. No other text styles should be used. Underlined text must not be applied manually (e.g. in error message), as it is commonly associated with hyperlinks and may mislead users.
Code samples
// The value with the code
@State private var pinCode: String = ""
// By default, the PIN code input displays only 6 boxes
OUDSPinCodeInput($pinCode)
// It can have also up 4 or 8 boxes, with an helper text
OUDSPinCodeInput($pinCode, length: .eight, helperText: "Enter your 8 secret digits")
// The component can be used in error contexts
OUDSPinCodeInput($pinCode, length: .six, status: .error(message: "The OTP code you entered is not correct"))
Design documentation
unified-design-system.orange.com
Themes rendering
Orange

Orange Compact

Sosh

Wireframe

Version
1.2.0 (Figma component design version)
Since
1.4.0
Topics
Initializers
init(Binding<String>, length: OUDSPinCodeInput.Length, helperText: AttributedString, isOutlined: Bool, status: OUDSPinCodeInput.Status, autofocus: Bool)Defines a PIN code imput component with several boxes to fill the code and an helper text in rich text
init(Binding<String>, length: OUDSPinCodeInput.Length, helperText: String?, isOutlined: Bool, status: OUDSPinCodeInput.Status, autofocus: Bool)Defines a PIN code imput component with several boxes to fill the code
init(Binding<String>, length: OUDSPinCodeInput.Length, helperText: LocalizedStringKey, tableName: String?, bundle: Bundle, isOutlined: Bool, status: OUDSPinCodeInput.Status, autofocus: Bool)Defines a PIN code imput component with several boxes to fill the code, and an helper text in rich text.
Instance Properties
Type Properties
Enumerations