Skip to content
ArcadiaDesign

TSX

Field wires a label, a hint and an error to one Input or Textarea. A format belongs in the placeholder and a rule in the error, shown when it fails; a field whose label cannot explain it takes a hint. A field is transparent in a 10% frame (radius 10, 12 at lg), findable on a card as well as on the page. Focus shows through the frame, never a ring: under the pointer it steps to 20%, and focus draws it in the ring's ink (--ring, the 40% every focused control wears) with a 3px halo over 200ms; the caret carries the rest. Placeholders are text-3, so they stay readable. Clicking the frame's padding or its icon focuses the field, as a native one would. Heights are 24, 28 (the default) and 32. A value longer than the field fades at its end while the field is unfocused, never dots; focused, the caret shows where it runs.

Examples

Slots

A decorative leadingIcon, and an end slot for a key hint, a clear button or a spinner.

⌘K

Ghost

No fill and no border: menu search rows, inline rename, a field inside its own frame.

Mono

mono sets a machine fact in the code face, its placeholder too: an invite or one-time code, an API key, a path. What a person writes stays in the UI face.

In a form

Controlled with value and onChange, submitted natively.

On a bad submit the error appears under the field, is tied to it with aria-describedby, and focus goes back to the field so it is read out.

Size and state

rootStyle takes where the field sits (margins, self-alignment, flex and grid placement, size bounds) and the knobs below, each a token of its kind. A colour, a raw length or any other property is a type error: a look that comes up twice becomes a variant.

TSX
--input-h
Ref<Control>Default var(--control-md)
Height.
--input-px
Ref<Space>Default var(--space-2-5)
Inline padding.
--input-radius
Ref<Radius>Default var(--radius-row)
Corner radius.
--input-bg
PaintDefault transparent
Fill.
--input-fg
PaintDefault var(--text-1)
Text colour.
--input-fg-disabled
PaintDefault var(--text-4)
Text colour when disabled.
--input-placeholder
PaintDefault var(--text-3)
Placeholder colour.
--input-icon
PaintDefault var(--icon-3)
Leading glyph colour.
--input-icon-disabled
PaintDefault var(--icon-4)
Leading glyph colour when disabled.
--input-border
PaintDefault var(--stroke-2)
Frame colour (1px) at rest.
--input-border-hover
PaintDefault var(--stroke-1)
Frame colour under the pointer.
--input-border-focus
PaintDefault var(--ring)
Frame colour while the field has focus.
--input-border-disabled
PaintDefault var(--stroke-4)
Frame colour when disabled.
--input-halo
PaintDefault var(--fill-3)
The halo (--halo-width) around a focused frame.

rootStyle lands on the frame. Each state reads its own knob (--input-border-hover, --input-border-focus, --input-border-disabled). Invalid turns the frame and the halo to the danger colour whatever the knobs say, so an error always reads.

A native <input>. Inside Field, the label's for, aria-describedby (hint and error) and aria-invalid are wired for you, and an error always shows. The leadingIcon is decorative and the end slot's controls carry their own labels.

Without a Field, name the input yourself: a <label htmlFor> or aria-label. A placeholder is not a label; it disappears as soon as someone types.

Pass required for a required field and say so in the label text too. An error appears when it is set, so on submit move focus to the first invalid field (or to a summary with role="alert") to have it announced. Give autoComplete a real value (email, name, url) so browsers and password managers can fill it, and off only for search fields.

Tab
Moves into and out of the field
Enter
Submits the surrounding form

Input

size
"sm" | "md" | "lg"Default "md"
Height: sm 24px, md 28px, lg 32px.
variant
"default" | "ghost"Default "default"
ghost drops fill and border (menu search rows, inline rename).
leadingIcon
IconName
Decorative glyph before the text (icon-3).
end
ReactNode
Trailing slot: a Spinner, a key hint, a clear IconButton.
invalid
boolean
Marks the control invalid (aria-invalid); a surrounding Field with error does it too.
mono
boolean
A machine fact typed as it reads (an invite or one-time code, an API key, a path): the value and its placeholder in mono.
rootStyle
InputStyle
Typed StyleX override for the .ui-input frame: where it sits and its --input-* knobs.
onValueChange
(value: string, details: { event: Event }) => void
Called with the new text on every change (beside onChange).
render
RenderProp
Replaces the <input>. Every other prop, ref included, lands on the input.
className
string
A product's hook class on the frame, for its own layout rules. Being retired: new code places a field with rootStyle; the call sites left are counted by ui.lint (kit-classname) and only go down.
disabled
boolean
Disables the field; the frame dims.
placeholder
string
Placeholder at text-4.

Rest props go to <input> props.

label
ReactNode
hint
string
Why or how, for a field its label cannot explain: a Hint after the label, and the control's description. At most 160 characters.
description
ReactNode
Help text under the label (text-3, 12/16).
error
ReactNode
Error message; when present the field is invalid and the message is always shown.
invalid
boolean
disabled
booleanDefault false
Disables the control and dims the label.
rootStyle
RootStyle
Typed StyleX override: where the field sits.
className
string
A product's hook class for its own layout rules. Being retired: new code places a field with rootStyle; the call sites left are counted by ui.lint (kit-classname) and only go down.

Rest props go to <div> props.