Text Field
Material Design 3 text field for single-line input with validation,
icons, and character counting. Not intended for multi-line prose; use
ds-textarea for longer input.
Basic Usage
Use a label for accessible, consistent input affordances. Always include a label — it provides the field's accessible name and anchors error messages. This is the recommended minimum.
<ds-text-field label="Full Name"></ds-text-field>
Initial Value
Prefill inputs to reflect existing data.
<ds-text-field label="Email" value="alex@example.com"> </ds-text-field>
Variants
Choose filled or outlined to match layout density and emphasis.
Filled
Default variant with filled background.
- Use when: The input sits on a flat or neutral surface.
- Avoid when: The input must stand out on an elevated or tonal surface.
<ds-text-field variant="filled" label="First Name"></ds-text-field>
Outlined
Outlined variant with a visible border.
- Use when: Inputs appear on elevated or tonal surfaces where filled background would blend in.
- Avoid when: The filled variant already meets the visual hierarchy requirements.
<ds-text-field variant="outlined" label="Last Name"></ds-text-field>
Input Types
Use native input types for built-in validation.
Icons
Provide leading or trailing icons for context.
<ds-text-field label="Search"> <ds-icon slot="leading-icon" name="search"></ds-icon> </ds-text-field>
Supporting Text
Use helper text and validation messages for guidance.
<ds-text-field label="Email" type="email" error error-text="Please enter a valid email"> </ds-text-field>
Character Counter
Show a live count when a maximum length is set.
<ds-text-field label="Bio" maxlength="100" show-counter> </ds-text-field>
States
Show disabled, required, and error states clearly.
Disabled
Required
Error
Interactive Example
Listen for input and change events to update UI state.
Event: none
Value: none
<ds-text-field id="event-field" label="Project Name"></ds-text-field> <p>Event: <span id="event-type">none</span></p> <p>Value: <span id="event-value">none</span></p>
API
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
name |
string | "" | Form field name. The current text is submitted under it; without a name the field is left out. |
variant |
string | "filled" | Visual style: "filled" or "outlined". |
type |
string | "text" | Input type: text, email, password, number, tel, url. |
label |
string | "" | Floating label text. |
value |
string | "" | Input value. |
placeholder |
string | "" | Placeholder text. |
supporting-text |
string | "" | Helper text below the input. |
error-text |
string | "" | Error message shown when error is set. |
disabled |
boolean | false | Disables the field. |
error |
boolean | false | Shows error state. |
required |
boolean | false | Marks the field as required. |
maxlength |
number | - | Maximum character length. |
show-counter |
boolean | false | Shows the character counter. |
Forms
Submits its text, "" when empty, like a native <input>. Its validity mirrors the inner input, so required, type and maxlength all block submission. It resets with its form, and a disabled <fieldset> disables it. form, validity, validationMessage, checkValidity() and reportValidity() behave as on a native control.
Events
| Event | Detail | Description |
|---|---|---|
ds-text-field:input |
{ value: string } |
Fired on input. |
ds-text-field:change |
{ value: string } |
Fired when value commits. |
ds-text-field:focus |
{ value: string } |
Fired when the input receives focus. |
ds-text-field:blur |
{ value: string } |
Fired when the input loses focus. |
Slots
| Slot | Description |
|---|---|
leading-icon |
Icon before the input. |
trailing-icon |
Icon after the input. |
CSS Parts
| Part | Description |
|---|---|
input |
Native input element. |
label |
Floating label. |
leading-icon |
Leading icon container. |
trailing-icon |
Trailing icon container. |
supporting-text-container |
Helper text wrapper. |
supporting-text |
Helper or error text. |
character-counter |
Character counter label. |
CSS Custom Properties
| Property | Description |
|---|---|
--ds-text-field-width |
Controls the field width (default: 100%). |
Methods
| Method | Description |
|---|---|
focus() |
Moves focus to the input. |
blur() |
Removes focus from the input. |
select() |
Selects the input text. |
checkValidity() |
Returns the input validity state. |
reportValidity() |
Reports the input validity state. |
Accessibility
Keyboard Map
| Key | Context | Expected Result |
|---|---|---|
Tab |
Field not focused | Moves focus to the input. |
Shift+Tab |
Field focused | Moves focus to previous element. |
| Any printable key | Field focused | Appends to input value. |
Semantics
- Uses native
<input>element semantics. - Error state is exposed via
aria-invalid. - Focus indicators follow MD3 contrast requirements.
Usage Guidelines
- When to use: Short, single-line input for names, emails, or free-form text.
-
When not to use: Multi-line prose or notes; use
ds-textareainstead. -
Composition: Pair with
errorandsupporting-textfor inline validation guidance. - Common mistakes: Omitting labels, using only placeholder text, and missing error feedback.