Available from v1.0.0
TextInput (Form Label)
TextInput is a themed replacement for UITextField with title, helper text, error handling, icons, and multiple state styles.
Platform availability: iOS 17.0+
When to use:
- Use TextInput when you need a text field with built-in support for labels, helper text, error states, and icons.
- Consider PasswordInput when the field is specifically for password entry with visibility toggle.
It includes the following features:
- Multiple style states: normal, focus, editing, error, disabled, and read-only.
- Title label positioned above the text field.
- Helper text label for additional guidance.
- Error label with optional error icon.
- Leading and trailing icon support.
- Password visibility toggle.
- Configurable corner radius, border, and padding.
Import
import BackbaseDesignSystem
Visual reference
|
|
|
|
|
|
|
|
API reference
TextInput
A UIView subclass containing a styled text field with title, helper, and error labels.
Properties
|
Property |
Type |
Description |
|---|---|---|
|
textField |
UITextField |
The text field for user input |
|
titleLabel |
UILabel |
The label above the text field |
|
helperLabel |
UILabel |
The helper text label below the text field |
|
errorLabel |
UILabel |
The error message label |
|
errorImage |
UIImage? |
The image for the error icon view |
|
normalStyle |
Style<TextInput>? |
The style for normal state |
|
focusStyle |
Style<TextInput>? |
The style for focused state |
|
editingStyle |
Style<TextInput>? |
The style for editing state |
|
errorStyle |
Style<TextInput>? |
The style for error state |
|
disableStyle |
Style<TextInput>? |
The style for disabled state |
|
readOnlyStyle |
Style<TextInput>? |
The style for read-only state |
|
cornerRadius |
DesignSystem.CornerRadiusTypes |
The corner radius. Default is .none |
|
border |
DesignSystem.BorderOptions? |
The border options |
|
textFieldPaddings |
UIEdgeInsets |
The padding inside the text field. Default is .zero |
|
leftViewOffset |
CGVector |
The offset for left view. Default is .zero |
|
rightViewOffset |
CGVector |
The offset for right view. Default is .zero |
|
showPasswordVisibilityAccessory |
Bool |
The flag to show password toggle button. Default is false |
|
placeholderTextColor |
UIColor |
The color for placeholder text |
Initializers
- init()
- Creates a text input without accessibility label.
- init(frame:accessibilityLabel:)
|
Parameter |
Type |
Description |
|---|---|---|
|
frame |
CGRect |
The frame rectangle. Default is .zero |
|
accessibilityLabel |
String? |
The accessibility label for the text field |
Methods
- setError(errorMessage:)
- Shows an error message and applies error styling.
|
Parameter |
Type |
Description |
|---|---|---|
|
errorMessage |
String |
The error message to display |
- clearError()
- Clears the error message and restores appropriate styling.
- setReadOnly(_:)
- Sets the read-only state.
|
Parameter |
Type |
Description |
|---|---|---|
|
isReadOnly |
Bool |
Whether the input is read-only |
- setTrailingViewImage(_:for:mode:accessibilityLabel:)
- Sets an image to the trailing (right) view.
|
Parameter |
Type |
Description |
|---|---|---|
|
image |
UIImage? |
The image to set |
|
state |
UIControl.State |
The control state |
|
mode |
UITextField.ViewMode |
The view mode. Default is .always |
|
accessibilityLabel |
String? |
The accessibility label |
- setTrailingViewImage(_:for:mode:accessibilityLabel:trailingButtonAction:)
- Sets an image with tap action to the trailing view.
|
Parameter |
Type |
Description |
|---|---|---|
|
image |
UIImage? |
The image to set |
|
state |
UIControl.State |
The control state |
|
mode |
UITextField.ViewMode |
The view mode. Default is .always |
|
accessibilityLabel |
String? |
The accessibility label |
|
trailingButtonAction |
(UITextField) -> Void |
The action when button is tapped |
- setLeadingViewImage(_:for:mode:accessibilityLabel:)
- Sets an image to the leading (left) view.
|
Parameter |
Type |
Description |
|---|---|---|
|
image |
UIImage? |
The image to set |
|
state |
UIControl.State |
The control state |
|
mode |
UITextField.ViewMode |
The view mode. Default is .always |
|
accessibilityLabel |
String? |
The accessibility label |
- setPasswordVisibilityButtonAccessibilityLabel(_:)
- Sets accessibility label for the password visibility toggle.
|
Parameter |
Type |
Description |
|---|---|---|
|
accessibilityLabel |
String |
The accessibility label |
Configuration
|
Property |
Type |
Default |
|---|---|---|
|
cornerRadius |
DesignSystem.CornerRadiusTypes |
.none |
|
border |
DesignSystem.BorderOptions? |
nil |
|
textFieldPaddings |
UIEdgeInsets |
.zero |
|
showPasswordVisibilityAccessory |
Bool |
false |
Global properties
These global settings affect the formLabel style:
|
Property |
Description |
|---|---|
|
design.colors.surfacePrimary.default |
Background color for normal state |
|
design.colors.surfacePrimary.onSurfacePrimary.default |
Text color for normal state |
|
design.colors.inputBorder |
Border color for normal state |
|
design.colors.primary.default |
Border color for focused state |
|
design.colors.danger.default |
Border and text color for error state |
|
design.colors.surfaceDisabled.onSurfaceDisabled.disabled |
Border and text color for disabled state |
|
design.colors.surfaceDisabled.default |
Background color for disabled state |
|
design.sizer.sm |
Top and bottom padding |
|
design.sizer.md |
Leading and trailing padding |
|
design.spacer.xs |
Spacing between error label and text field |
Usage
Basic usage
let textInput = TextInput(accessibilityLabel: "Email address")
textInput.textField.placeholder = "Enter your email"
With title label
let textInput = TextInput(accessibilityLabel: "Full name")
textInput.titleLabel.text = "Full Name"
textInput.textField.placeholder = "Enter your full name"
With helper text
let textInput = TextInput(accessibilityLabel: "Password")
textInput.titleLabel.text = "Password"
textInput.helperLabel.text = "Must be at least 8 characters"
textInput.showPasswordVisibilityAccessory = true
With error icon
let textInput = TextInput(accessibilityLabel: "Amount")
textInput.errorImage = UIImage(systemName: "exclamationmark.circle")
textInput.setError(errorMessage: "Invalid amount")
Password field with visibility toggle
let passwordInput = TextInput(accessibilityLabel: "Password")
passwordInput.titleLabel.text = "Password"
passwordInput.showPasswordVisibilityAccessory = true
passwordInput.setPasswordVisibilityButtonAccessibilityLabel("Toggle password visibility")
With leading icon
let searchInput = TextInput(accessibilityLabel: "Search")
searchInput.setLeadingViewImage(
UIImage(systemName: "magnifyingglass"),
for: .normal,
accessibilityLabel: "Search icon"
)
With trailing icon and action
let textInput = TextInput(accessibilityLabel: "Input")
textInput.setTrailingViewImage(
UIImage(systemName: "xmark.circle.fill"),
for: .normal,
accessibilityLabel: "Clear text"
) { textField in
textField.text = ""
}
Read-only state
let textInput = TextInput(accessibilityLabel: "Account number")
textInput.textField.text = "1234567890"
textInput.setReadOnly(true)
Disabled state
let textInput = TextInput(accessibilityLabel: "Disabled field")
textInput.isUserInteractionEnabled = false
States and variants
Normal state
The default interactive state when the field is not focused.
Visual characteristics:
- Surface primary background
- Default border color
- Placeholder text when empty
let textInput = TextInput(accessibilityLabel: "Email")
// Normal state is applied by default
Focus state
Active when the user is interacting with the text field.
Visual characteristics:
- Primary color border
- Cursor visible
- Keyboard presented
textInput.textField.becomeFirstResponder()
Error state
Displayed when validation fails or an error occurs.
Visual characteristics:
- Danger-colored border
- Error label visible
- Optional error icon
textInput.setError(errorMessage: "Please enter a valid email address")
Disabled state
Applied when the input should not be interactive.
Visual characteristics:
- Disabled background color
- Muted text and border colors
- No user interaction
textInput.isUserInteractionEnabled = false
Read-only state
Displays content that cannot be modified by the user.
Visual characteristics:
- Distinct styling from editable state
- Text visible but not editable
textInput.setReadOnly(true)
Customization
Styling
|
Style |
Description |
|---|---|
|
DesignSystem.shared.styles.formLabel |
Default form label style |
|
DesignSystem.shared.styles.textInput |
Alternative text input style |
Custom styling
let textInput = TextInput(accessibilityLabel: "Custom input")
textInput.normalStyle = { input in
input.textField.backgroundColor = .systemBackground
input.textField.layer.borderColor = UIColor.systemGray.cgColor
input.textField.layer.borderWidth = 1
}
textInput.focusStyle = { input in
input.textField.layer.borderColor = UIColor.systemBlue.cgColor
input.textField.layer.borderWidth = 2
}
textInput.errorStyle = { input in
input.textField.layer.borderColor = UIColor.systemRed.cgColor
input.errorLabel.textColor = .systemRed
}
Error handling
Display and clear error messages:
let textInput = TextInput(accessibilityLabel: "Email")
textInput.textField.placeholder = "Enter email"
// Show error
textInput.setError(errorMessage: "Please enter a valid email address")
// Clear error
textInput.clearError()
Accessibility
The TextInput component is built with accessibility in mind. See the information below for supported behaviors and configuration options to ensure a fully accessible experience for all users.
Accessibility configuration
|
Property |
Description |
Type |
|---|---|---|
|
accessibilityLabel |
The accessible label for the text field |
String? |
|
accessibilityIdentifier |
The identifier for UI testing |
String? |
The component sets appropriate accessibility identifiers for all subviews:
|
Element |
Identifier Pattern |
|---|---|
|
Title label |
[accessibilityIdentifier].titleLabel |
|
Helper label |
[accessibilityIdentifier].helperLabel |
|
Text field |
[accessibilityIdentifier].textInput.textField |
|
Error label |
[accessibilityIdentifier].errorLabel |
|
Error icon |
[accessibilityIdentifier].errorIcon |
Best practices
- Set a descriptive accessibilityLabel for the text field
- Use meaningful placeholder text
- Error messages are announced to VoiceOver users
Localization
"DesignSystem.InputText.Accessibility.errorIcon" = "Error icon";
Dependencies
- External dependencies: None
- Internal dependencies:
- TextField: Internal text field implementation
- IconView: Used for error icon display
- DesignSystem.CornerRadiusTypes: Corner radius configuration
- DesignSystem.BorderOptions: Border configuration
Design tokens
Component styling is applied automatically through the design system's theming infrastructure.
JSON tokens
Tokens are defined in defaultTokens.json, which is integrated in the bundle of the framework, and can be customized by providing your own theme JSON file.
Token groups used by TextInput:
- color/text-input/default: Default state colors
- color/text-input/focused: Focused state colors
- color/text-input/error: Error state colors
- color/text-input/disabled: Disabled state colors
- color/input-border: Input border color
State tokens:
|
Token |
JSON Path |
Default Value |
|---|---|---|
|
Default |
theme.color.text-input.default.[background|foreground|border] |
See TextInput |
|
Focused |
theme.color.text-input.focused.[background|foreground|border] |
See TextInput |
|
Error |
theme.color.text-input.error.[background|foreground|border] |
See TextInput |
|
Disabled |
theme.color.text-input.disabled.[background|foreground|border] |
See TextInput |
Dimension tokens:
|
Token |
JSON Path |
Default Value |
|---|---|---|
|
Corner Radius |
theme.radius.input.default |
8 |
|
Height |
theme.height.input.default |
44 |
|
Padding Y |
theme.padding-y.input.default |
8 |
|
Padding X |
theme.padding-x.input.default |
16 |
|
Border Width |
theme.border-width.input.default |
1 |
Semantic tokens
|
Token |
API Reference |
Description |
|---|---|---|
|
Colors |
Theme.colors.foreground.default |
Default text color |
|
Colors |
Theme.colors.foreground.danger |
Error text color |
|
Colors |
Theme.colors.surfacePrimary.default |
Background color |
|
Colors |
Theme.colors.primary.default |
Focused border color |
|
Colors |
Theme.colors.inputBorder |
Normal border color |
|
Typography |
DesignSystem.shared.fonts.preferredFont(.body, .regular) |
Input text font |
|
Spacing |
DesignSystem.shared.spacer.sm |
Small spacing |
|
Spacing |
DesignSystem.shared.spacer.xs |
Spacing between error label and field |
|
Sizer |
DesignSystem.shared.sizer.sm |
Top and bottom padding |
|
Sizer |
DesignSystem.shared.sizer.md |
Leading and trailing padding |
|
Styles |
DesignSystem.shared.styles.formLabel |
Default form label style |
|
Styles |
DesignSystem.shared.styles.textInput |
Alternative text input style |
See also
- TextFieldDateInput - Date input with text field
- Checkbox - Checkbox component
- Button - Action button component