Field
The composition that ties a label, a control, its description and its errors into one announced unit.
import { Field } from "@glint/components/field.slint";import { Input } from "@glint/components/input.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
in-out property <string> email-val: "";
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 320px;
email-field := Field { label: "Email Address"; required: true; description: "We'll never share your email with third parties."; label-clicked => { email-input.focus(); }
email-input := Input { text <=> root.email-val; invalid: email-field.invalid; } } } } }}Usage
import { Field } from "@glint/components/field.slint";import { Input } from "@glint/components/input.slint";
export component AppWindow inherits Window { in-out property <string> username: "";
VerticalLayout { alignment: center;
username-field := Field { label: "Username"; required: true; description: "Your unique public handle."; errors: root.username == "" ? ["Username is required."] : []; label-clicked => { username-input.focus(); }
username-input := Input { text <=> root.username; invalid: username-field.invalid; } } }}Field acts as the single source of truth for form field composition. It pairs a label, helper description, and validation errors with an arbitrary slotted control.
Bind your control’s invalid property to the surrounding Field.invalid output so that visual error borders and message text remain synchronized.
Examples
Orientations
The orientation property controls label placement relative to the control.
FieldOrientation.vertical stacks the label above the control (standard for form columns).
FieldOrientation.horizontal places the label beside the control (ideal for settings rows and switches).
FieldOrientation.responsive places the label beside the control when container width exceeds responsive-breakpoint (default 448px), falling back to stacked on narrower widths.
import { Field, FieldOrientation } from "@glint/components/field.slint";import { Input } from "@glint/components/input.slint";import { Switch } from "@glint/components/switch.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 380px; background: Tokens.color-background;
VerticalLayout { alignment: center; spacing: 20px; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 360px; spacing: 16px;
Field { label: "Profile Name"; orientation: FieldOrientation.vertical; description: "Displayed on your public profile.";
Input { placeholder: "Jane Doe"; } }
Field { label: "Auto-sync Data"; orientation: FieldOrientation.horizontal; description: "Sync changes across all registered devices.";
Switch { checked: true; } }
Field { label: "Responsive Field"; orientation: FieldOrientation.responsive; description: "Adapts layout depending on available width.";
Input { placeholder: "Adaptive layout"; } } } } }}Validation errors and live region
Pass an array of error messages to errors. When non-empty, Field.invalid becomes true and each message is rendered in destructive red text below the control.
Each error is declared as an assertive live region so assistive technology immediately announces the failure upon validation.
import { Field } from "@glint/components/field.slint";import { Input } from "@glint/components/input.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 320px;
field := Field { label: "Account Password"; required: true; errors: [ "Password must be at least 8 characters long.", "Must contain at least one uppercase letter." ];
Input { text: "pass"; invalid: field.invalid; } } } } }}Disabled field
Setting disabled: true on Field cascades disabled styling (dimmed opacity and silenced click interactions) to the label.
import { Field } from "@glint/components/field.slint";import { Input } from "@glint/components/input.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 320px;
Field { label: "License Key"; description: "Managed by your enterprise organization."; disabled: true;
Input { text: "GLINT-ENTERPRISE-9842"; enabled: false; } } } } }}API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
label | in string | no default | Label shown beside or above the control; empty hides the label row. |
required | in bool | false | Appends the destructive asterisk to the label. |
description | in string | no default | Helper text under the label; empty hides it. |
errors | in [string] | no default | Validation messages under the control, one text node each; an empty list means "valid". A control failing two rules reports two messages rather than one string the consumer had to join. |
orientation | in FieldOrientation | FieldOrientation.vertical | Where the label sits — see FieldOrientation. |
responsive-breakpoint | in length | 448px | The width a responsive field needs before it lays out as a row. shadcn's is the @md container query; a narrower form column can say so here. |
disabled | in bool | false | Carries the row's disabled state to the label this Field owns, so a disabled form row is said once here rather than on the label and the control both. The control in the slot still takes its own disabled — it is the thing that stops answering. |
invalid | out bool | no default | True while errors carries a message — bind the control's invalid to it. |
Callbacks
| Callback | Description |
|---|---|
label-clicked() | Fired when the label is clicked; forward focus to your control. |
Enums
| Enum | Values |
|---|---|
FieldOrientation | vertical, horizontal, responsive |
Accessibility
- Groupbox role.
Fieldpublishes an accessiblegroupboxnode carryingaccessible-label: root.label. - Descriptive context. The accessible description joins
descriptionand the first validation error message (ADR-0013). - Live region error announcements. Every error in
errorsis announced viaaccessible-live-region: AccessibleLiveness.assertive. - Label forwarding. Activating the label runs
label-clicked(), allowing the parent container to forward keyboard focus to the slotted control.