Skip to main content
xriptxr

Field

Info:Form
33

A labelled text input with helper text, validation, adornments, and built-in clear and reveal actions.

input text input text field search box textbox form input

Live demo

live · @xtyle/astro

Field

A signed-in form

We'll only use this to sign you in.
At least 12 characters.

Adornments

$USD

Sizes

States

Use only letters, numbers, and dashes.
Generated once. Copy it now.

Type-ahead

Suggestions come from the field's own datalist, so they work inside the shadow root.

Code-shaped

A mono field for hex, ids, and paths; spellcheck is forwarded off.

Field is the complete single-line text input: a label, an input, a persistent description, and an error message wired together with the right accessibility relationships out of the box. The input inherits the shared .xtyle-control chrome and adds field-specific layout: a unified control box that holds leading and trailing adornment slots (icons, currency prefixes, unit suffixes) alongside the input.

It generates a stable id and links it to the label, builds aria-describedby from both the description and the error, and ships two optional built-in actions: a clear button and a password reveal toggle. In the HTML and Svelte bindings the element is form-associated, participating in native form submission and constraint validation. Sizes (sm / md / lg) match the Button padding scale, and readonly, required, disabled, and invalid are all first-class.

When to use

How this component composes with the rest of the set.

Pair with Button (type="submit") inside a native <form>; the form-associated element submits its value by name.
Use the prefix / suffix slots with any inline SVG or text node; they'll take an Icon component directly when one ships.
The clear button and password reveal are JS-driven, so they appear in the html and svelte bindings; the Astro binding is zero-JS and omits them.
For type-ahead, pass options rather than a hand-authored <datalist>; a page-level datalist can't reach the input across the shadow boundary, so Field owns the list itself.
Native input attributes (spellcheck, inputmode, autocomplete, autocapitalize, autocorrect, enterkeyhint) set on the host are forwarded to the inner input, so spellcheck="false" on a code field works without reaching through ::part.

Props

22 props, straight from the manifest.

PropTypeDefaultBindingsDescription
label string
html svelte astro
The visible label text, linked to the input. When omitted, falls back to an aria-label from the placeholder.
name string
html svelte astro
The form field name. Drives form submission and the form-associated value.
value string
html svelte astro
The input value. Two-way bindable in Svelte (bind:value).
type string text
html svelte astro
The native input type (text, email, password, number, …). password enables the reveal toggle.
placeholder string
html svelte astro
Placeholder text shown when empty.
size Size
sm md lg
md
html svelte astro
Control size; matches the Button padding scale.
description string
html svelte astro
Persistent helper text below the control, linked via aria-describedby.
error string
html svelte astro
Validation message; shown (and linked via aria-describedby) only while invalid.
invalid boolean false
html svelte astro
Marks the field invalid: danger border, error message, aria-invalid, and a custom validity in form-associated mode.
required boolean false
html svelte astro
Marks the field required: a * indicator, required + aria-required, and a valueMissing validity.
requiredMessage html: required-message string Please fill out this field.
html svelte astro
The message the browser shows when required is unmet. The platform localizes its own constraint messages and this one is xtyle's, so an app that is not in English should set it.
readonly boolean false
html svelte astro
Renders the input read-only with a muted background; the value still submits.
disabled boolean false
html svelte astro
Disables the input and dims the field.
clearable boolean false
html svelte
Shows a built-in clear button when the field has a value. (html / svelte: needs JS.)
options string[] | { value: string; label?: string }[]
html svelte astro
Type-ahead suggestions. Field renders them into a <datalist> it owns inside the input's own root and wires the input's list to it, so suggestions work even though the input lives in a shadow root (where a page-level <datalist> could never reach it). Set the JS property in html / svelte; the Astro binding takes a JSON array attribute. Needs the runtime. (html / svelte / astro on hydrate.)
mono boolean false
html svelte astro
Renders the input in the monospace stack (--font-mono) for code-shaped values: identifiers, paths, hex colors, expressions, env values. A presentational swap on an existing token, so it bakes into the zero-JS Astro markup too.
spellcheck "true" | "false"
html svelte astro
Forwarded to the inner control: turn the browser's own spell-checker off for a value it would only underline in red — a markup source, a code snippet, an identifier. Enumerated rather than boolean, so it needs an explicit spellcheck="false" — a bare spellcheck is the HTML spelling of on.
inputmode "text" | "numeric" | "decimal" | "tel" | "email" | "url" | "search" | "none"
html svelte astro
Forwarded to the inner control: which on-screen keyboard a touch device should raise. Purely a hint — it does not validate or restrict what can be typed.
autocomplete string
html svelte astro
Forwarded to the inner control: the autofill token the browser should match against, such as email, street-address, or off.
autocapitalize "off" | "none" | "on" | "sentences" | "words" | "characters"
html svelte astro
Forwarded to the inner control: whether a touch keyboard capitalizes as you type.
autocorrect "on" | "off"
html svelte astro
Forwarded to the inner control: the browser's own autocorrect. Non-standard but widely honored, and worth turning off wherever spellcheck is.
enterkeyhint "enter" | "done" | "go" | "next" | "previous" | "search" | "send"
html svelte astro
Forwarded to the inner control: what a touch keyboard's action key should read.

Events

What the component emits, and what rides along on event.detail. The name in the first column is the one addEventListener takes.

EventDetailBindingsDescription
input { value }
html svelte astro
The control's value changed as it was typed.
change { value }
html svelte astro
The control's value settled.

Appearance

Variants

default

.xtyle-field

The standard field: neutral border, accent focus ring.

invalid

.xtyle-field--invalid

Error treatment: danger border, a danger-tinted focus ring, and the error message shown.

Sizes

sm

.xtyle-field--sm

Compact.

md

default
.xtyle-field

Default.

lg

.xtyle-field--lg

Large.

States

focus-visible

.xtyle-field__control:focus-within

Keyboard focus inside the control: accent border and a token-colored ring via :focus-within.

invalid

.xtyle-field--invalid .xtyle-field__control

Invalid: danger border; the focus-within ring shifts to a danger tint.

disabled

.xtyle-field--disabled .xtyle-field__control

Non-interactive: muted ink and a disabled-tinted control.

readonly

.xtyle-field--readonly .xtyle-field__control

Read-only: a subtly recessed background; the value still submits.

required

.xtyle-field__required

Required: a danger-colored * indicator on the label.

Anatomy

The named parts that make up the component. A ::part() handle is reachable from your own stylesheet; the class beside it is the component's internal selector, which a shadow boundary keeps to itself.

field

Success:::part(field) .xtyle-field

The outer column wrapper carrying the size and state modifiers.

--font-sans --space-1

label

Success:::part(label) .xtyle-field__label

The field label, linked to the input via for; carries the required indicator.

--text-sm --weight-medium --fg-1 --leading-normal --space-1

control

Success:::part(control) .xtyle-field__control

The bordered box that wraps the input and its adornments; paints the focus-within ring.

--field-bg --field-border --border-thin --radius-md --accent --ring --border-normal

input

Success:::part(input) .xtyle-field__input

The native input, styled by .xtyle-control with its own chrome neutralized so the control box owns the border.

adornment

Success:::part(adornment) .xtyle-field__adornment

A leading (prefix) or trailing (suffix) slot for icons, currency symbols, or units.

--space-3 --fg-2 --text-sm --leading-tight

description

Success:::part(description) .xtyle-field__description

Persistent helper text below the control, linked via aria-describedby.

--text-sm --leading-normal --fg-2

error

Success:::part(error) .xtyle-field__error

The validation message shown when invalid, linked via aria-describedby.

--text-sm --leading-normal --danger

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 33/33 consumed tokens produced default register: 310 tokens

Live coverage check against the xtyle-default register (derive(xtyleDefault, { anchors })coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--accent --bg-1 --border-normal --border-thin --danger --danger-bg --danger-text --duration-fast --ease-standard --fg-0 --fg-1 --fg-2 --fg-disabled --field-bg --field-border --font-mono --font-sans --leading-normal --leading-tight --radius-md --radius-sm --ring --space-1 --space-2 --space-3 --space-4 --state-disabled --state-hover --state-press --text-lg --text-sm --weight-medium --weight-semibold

Slots

prefix
html svelte astro

A leading adornment: icon, currency symbol, or unit.

suffix
html svelte astro

A trailing adornment: icon, unit, or status marker.

clear-icon
html

Overrides the built-in clear-button glyph.

reveal-icon
html

Overrides the built-in password-reveal glyph.

Accessibility

Always generates a stable input id and links the label with for, so clicking the label focuses the input.
aria-describedby is built from both the description and the error, so assistive tech announces helper text and validation together.
invalid sets aria-invalid; required sets aria-required and a non-color * indicator so requirement is not conveyed by color alone.
When no label is given, the placeholder (or an explicit aria-label) becomes the accessible name; the binding warns when none of the three is present.
Focus is shown on the control via :focus-within with a token ring plus the transparent-outline pattern that forced-colors mode promotes to a real outline.
Form-associated (html / svelte): participates in native submission and constraint validation via setFormValue and setValidity.

Code

Labels, validation, and adornments

A required email, a password with helper text, a clearable search with a leading icon, and an invalid amount with a currency prefix.

<xtyle-field label="Email" name="email" type="email" placeholder="you@example.com" required></xtyle-field>

<xtyle-field
	label="Password"
	name="password"
	type="password"
	description="At least 12 characters."
	required
></xtyle-field>

<xtyle-field
	label="Search"
	name="q"
	placeholder="Search…"
	clearable
>
	<svg slot="prefix" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true">
		<path fill="currentColor" d="M10 4a6 6 0 1 0 3.5 10.9l4.3 4.3 1.4-1.4-4.3-4.3A6 6 0 0 0 10 4Zm0 2a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z" />
	</svg>
</xtyle-field>

<xtyle-field label="Amount" name="amount" type="number" invalid error="Must be greater than zero.">
	<span slot="prefix">$</span>
</xtyle-field>

Type-ahead suggestions

Pass options and Field renders a <datalist> in the input's own root, so suggestions work across the shadow boundary where a page-level datalist can't reach.

<xtyle-field id="branch" label="Branch" name="branch" placeholder="Type to filter…"></xtyle-field>
<script>
	document.getElementById("branch").options = ["main", "develop", "release/1.0", "hotfix"];
</script>