DSTextField
inputsText field with support for label, placeholder, leading/trailing icons, hint, error message, focus and disabled states.
Purpose
Primary text input for the system. Covers 90% of data-entry use cases in forms.
Interactive Reference
Live showroom
Need the full visual surface?
Screenshots do not scale well across every component, state, and variant. For the real interactive reference, import the package and launch DSShowcaseRoot().
Best for exploring:
variants, states, categories, and real app examples in one place.
States
Subtle border, no focus.
Primary-colour border + shadow sm.
Red border + error message below.
50% opacity. No interaction.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| label | String? | nil | Label above the field. |
| placeholder | String | "" | Placeholder text. |
| textreq | Binding<String> | — | Binding to the field value. |
| size | DSInputSize | .md | Field height and font size. |
| leadingIcon | String? | nil | SF Symbol on the left. |
| trailingIcon | String? | nil | SF Symbol on the right (when empty). |
| hint | String? | nil | Helper text below the field. |
| error | String? | nil | Error message. Overrides hint. |
| isDisabled | Bool | false | Disables the field. |
| onSubmit | (() -> Void)? | nil | Action when Return is pressed. |
Examples
Email field
Input with icon and validation.
DSTextField(
label: "Email",
placeholder: "name@company.com",
text: $email,
leadingIcon: "envelope",
error: emailError
)Inline search field
No label, with icon and submit.
DSTextField(
placeholder: "Search products...",
text: $query,
leadingIcon: "magnifyingglass",
onSubmit: { viewModel.search(query) }
)Form composition
Complete form with validation.
VStack(alignment: .leading, spacing: DSSpacing.md) {
DSTextField(
label: "Full Name",
placeholder: "John Doe",
text: $name,
error: name.isEmpty ? "Name is required" : nil
)
DSTextField(
label: "Email",
placeholder: "john@example.com",
text: $email,
leadingIcon: "envelope",
error: !isValidEmail(email) ? "Invalid email format" : nil
)
DSButton("Submit", variant: .primary) {
submitForm()
}
}Usage Guidelines
- Always provide a visible label or equivalent aria-label.
- Validate on .onSubmit to avoid unnecessary network calls.
- Never show an error without also explaining how to fix it.
When to Use
✓ Use DSTextField for:
- • Single-line text input in forms (name, email, username)
- • Search fields with onSubmit action
- • Numeric input with text keyboard (use TextField with .numberPad)
- • Fields with validation and error states
✗ Avoid using for:
- • Multi-line text (use DSTextArea)
- • Password input (use DSSecureField)
- • Dedicated search UI (use DSSearchBar with better styling)
- • Phone numbers (use DSPhoneField with formatting)
Consider instead:
For multi-line text input (comments, descriptions)
For password or sensitive data
For search with clear button and search styling
Accessibility
VoiceOver
Announces label, current value, and hint/error (e.g., 'Email, Text field, name@company.com')
Keyboard
- • Type to input
- • Return to submit (if onSubmit set)
- • Tab to next field
Dynamic Type
✓ Supported
Contrast
WCAG AA compliant (border 3:1, text 4.5:1)
Traits
.isTextFieldLabel via accessibilityLabelHint via accessibilityHint