Text fields let users enter and edit text. This component implements M3's filled text
field: a floating label, an animated focus/active indicator,
and optional leading/trailing icons and supporting text.
The Textfield component implements the Material Design 3 Text Field pattern. The label starts centered inside the field and floats
up when the field is focused or has a value.
Use leadingIconProps/trailingIconProps for icon affordances (e.g. a clear button), and supportingText for helper or validation copy below the field.
import { Textfield } from '@noxlovette/material'; See it live, with Controls, in Storybook rather than a hand-rolled preview here.
Playground
Open the Textfield story with full Controls for label, state, and character limit.
Bind value to read and set the field's contents:
<script lang="ts">
import { Textfield } from '@noxlovette/material';
let email = $state('');
</script>
<Textfield label="Email" bind:value={email} required>
{#snippet supportingText()}
We'll never share your email.
{/snippet}
</Textfield> | Prop | Type | Default | Description |
|---|---|---|---|
value | string | number | null | DateValue | — | The current value of the text field. Bindable. |
label required | string | — | The floating label text for the input. |
id | string | auto-generated | The id for the input element. Auto-generated via useId() but can be replaced. |
placeholder | '' | '' | Not used in M3 — the floating label replaces the placeholder pattern. |
elementRef | HTMLInputElement | — | Reference to the underlying HTML input element. |
supportingText | Snippet | — | Helper text displayed below the input. |
leadingIconProps | IconProps | — | Props for an optional leading icon. |
trailingIconProps | IconProps | — | Props for an optional trailing icon, rendered as a ButtonIcon. |
trailingIcon | Snippet | — | Overrides the default trailing icon button with custom content. |
characterLimit | number | — | Maximum character count, shown as a counter next to the supporting text. |
disabled | boolean | false | Disables the field. |
error | boolean | false | Renders the field in an error state (sets aria-invalid). |
required | boolean | false | Marks the field as required and shows a trailing asterisk on the label. |
trailingOnClick | () => void | — | Click handler for the default trailing icon button. |
inputChild | Snippet<[{ props }]> | — | Overrides the default <input> element entirely, e.g. to render a masked or date input. |
Additional native <input> attributes (e.g. type, maxlength, autocomplete) pass through via ...restProps.
Invalid state
error sets aria-invalid on the input so assistive tech announces the validation state.
Required fields
required sets aria-required and required on the input, and shows a visual asterisk on the label.
Label association
The floating label uses a for/id pairing (auto-generated via useId when not provided) instead of aria-label.