Theme
Customize the design system

Every control starts at the preset. Change one and every preview on the site follows, on this page and the next, until you reset it.

Contrast

Text against what it sits on. Below 4.5:1 fails WCAG AA for body text — the check a reviewer runs on any surface that takes a tone.

Waiting for the first preview to report its palette.

Corners

Sets all three radii at once. The individual values are under Geometry.

Brand 5

The accent seam an app actually brands itself through. Change these and you have made the decision a real `DesignTokens.graphite(...)` call makes.

Geometry 15

Square or rounded, and how heavy every line is. The radius row above the controls sets all three corners at once, because "what does square feel like" is one decision rather than three numbers.

Surfaces 17

Everything the app is painted ON — the ground behind the content (the frame paints it too), the cards over it, the well inset in a card, and the washes that show state.

Bands 10

The rail's head and the view bar beside it (one band across the top at 960 and wider), a pushed screen's bar, the compact bar and the compact nav bar — the band's fill, its rule, its hover and active faces, the resting field box on it, and the ink and accent control that sit on it. The rail's tree and its footer stay on the ground.

Text and controls 11

The ink ramp, the control outlines and the field's focus halo. Every pair the panel can break is watched by a contrast badge above.

Status 7

The three voices that mean something — danger, caution and ok — each as a foreground and a surface wash, danger with a border as well.

Data 5

The default pin head, its glyph and its halo, and the group bands. A pin's category color comes from the palette, named in the theme seed.

Map 11

The basemap's roles — land, water, parks, roads and their casings, buildings, labels — and the pending pin's gray. A raster basemap keeps its own imagery; these paint the map's plate and any kit-drawn map.

Scrollbars 6

Every scroller's bar: the thumb at rest and while hovered or dragged, the strip it rides, and the desk bar's thickness, side gap and corners. The desk half shows only while a fine pointer is attached; at touch the platform's own overlay keeps its size.

Advanced 6

Real controls that are not decisions — motion durations, the focus ring offset, the touch floor. Opens collapsed on purpose.

Take it with you

The Dart that reproduces what you are looking at. It is a real constructor call, because the configurator edits a real preset — what you copy is what an app can paste.

Components

Inputs

Every editor a form is built from, at rest and in the states a field actually reaches: required and empty, and carrying an error.

Spec of record: design-system/components/forms/TextField.d.ts

1
Knobs

Live

Real widgets, built from the real kit. Turn a knob and it rebuilds; the theme bar above applies the design system's own tokens — including anything you changed under Customize — and the device selector uses the same sizes the golden baselines gate on, so what you see here is what CI holds the widget to.

Press Focus on any preview to take it to the full window — at a desktop width that renders most devices at 1:1, which is when the widget's own controls become clickable. The bar always states the device and the scale, so a shrunk preview says it is shrunk. Esc leaves.

family_inputs
Knobs
Theme

Every specimen at once, in one state. Per-specimen controls would rebuild the wall a board exists to remove.

Dart for these values
family_inputs()

What it is made of

The widgets this screen assembles, with their full API below. They used to live on a second entry of their own; one thing you choose gets one page.

AppTextField widget

The design-system TextField — a themed, token-driven text input claiming the M3 outlined-text-field archetype. Anatomy (the FIELD pattern every later kit field reuses): a DesignTokens.label micro-label rendered above the box (never a floating label — `app_theme.dart` sets…

Full dartdoc

The design-system TextField — a themed, token-driven text input claiming the M3 outlined-text-field archetype. Anatomy (the FIELD pattern every later kit field reuses): a DesignTokens.label micro-label rendered above the box (never a floating label — `app_theme.dart` sets `FloatingLabelBehavior.never` on the shared `inputDecorationTheme`), a box-style field painted entirely by that theme (fill, the 3:1 field border, the focus halo, the DesignTokens.fld height), and an inline danger error line below the box. **Validation runs on blur, not per keystroke.** validator is called once when the field loses focus; a non-null return sets the box to its 2px danger border drawn inside the box (the theme's `errorBorder`; focused, `focusedErrorBorder` with the danger halo) and renders the family's error line 6 below the box — the Warning glyph, then the message in the label size and DesignTokens.danger (TextField.d.ts THE FIELD STATES), the message also being the field node's hint. Typing after an error clears it immediately (re-validated on the next blur) rather than leaving a stale error visible while the user is mid-edit. Uncontrolled by default (`value` / `onChanged`, mirroring the `TextEditingController` idiom in the repo's variation-point canon); pass controller for programmatic control. Exactly one of `value` / `controller` should be supplied. ```dart AppTextField(label: 'Name', onChanged: setName) AppTextField( label: 'Min %', variant: AppTextFieldVariant.data, keyboardType: TextInputType.number, value: min, onChanged: setMin, validator: (v) => rangeError(v), ) ```

AppTextFielddefault constructor

Knob Type Default What it does
autofocus bool false Requests focus as soon as the field mounts.
controller TextEditingController? null Programmatic controller — the `TextEditingController` idiom. When null, the widget owns an internal controller seeded from value.
enabled bool true Disables the field (DesignTokens.ink40 foreground, not focusable) when false.
error String? null Controlled inline error. When non-null the field renders exactly this copy as the inline danger error — same anatomy as a validator-produced error (danger border on the box, danger message line below). The blur validator still runs and wins after interaction: from the first blur onward its result…
focusNode FocusNode? null External focus node — for composition into focus-coordinating hosts (e.g. an autocomplete overlay). When null the widget owns one. Blur validation runs against whichever node is in effect.
helper String? null Helper text rendered below the box when there is no active error. An error from validator (or a controlled error) replaces this line rather than stacking beneath it.
hint String? null Placeholder shown while the field is empty (theme's `hintStyle`).
inputFormatters List<TextInputFormatter>? null Input filters applied before the text changes (TextField.inputFormatters pass-through) — e.g. a digit filter on a numeric field so a rejected character never desyncs the display from the stored value.
isRequired bool false Renders the required marker — the trailing accent `*` on the micro-label (design-system pin `5908e48`). Visual only; the programmatic requiredness channel is the form's validation.
keyboardType TextInputType? null Software keyboard type. Defaults to TextInputType.text; pass e.g. TextInputType.number alongside `variant: AppTextFieldVariant.data` for numeric fields.
label String? null Micro-label rendered above the box, in the label role — sentence case, exactly as passed (`--type-label-transform: none`). Optional per the spec (`label?`): null renders the bare box — used by hosts that own the label row themselves (the stepped-number editor renders its label full-width above the…
obscureText bool false Masks the value (password entry).
onChanged ValueChanged<String>? null Fires on every keystroke with the field's current text.
onSubmitted ValueChanged<String>? null Fired when the user submits from the software keyboard (the TextField.onSubmitted pass-through). Null ignores keyboard submit.
prefix String? null A quiet leading text inside the box — the currency symbol (`$`). `TextField.d.ts` THE ADORNMENTS (#783): data font, ink40, NOT the value (never typed, never in onChanged), shown on an empty box and on the disabled face. It joins the field's accessible label after the micro-label. Null or blank:…
readOnly bool false Renders the value but blocks editing (distinct from enabled: a read-only field still looks and focuses like an active field).
suffix String? null A quiet trailing text inside the box — the unit (`lb`, `%`), drawn before any trailing widget. Same contract as prefix.
textAlign TextAlign TextAlign.start How the value aligns in the box (TextField.textAlign pass-through). Default start; a number in a data-table cell is END-aligned (`DataTable.d.ts` THE EDITOR PER TYPE — the digits line up with the column they edit).
textInputAction TextInputAction? null The keyboard's action key (TextField.textInputAction pass-through). `next` advances focus to the next field, `done` dismisses — the form assigns these by position so the keyboard walks the form.
trailing Widget? null Optional single trailing widget (e.g. a clear or reveal-password affordance). Sized and centered by the field; the caller supplies only the icon/content.
validator String? Function(String value)? null Runs on blur (focus loss), not per keystroke. A non-null return is shown as the inline danger error and switches the box to the danger border; null clears any existing error.
value String? null Initial value for the uncontrolled form (ignored when controller is supplied).
variant AppTextFieldVariant
text · data
AppTextFieldVariant.text Selects the value's font — AppTextFieldVariant.data for number / date / time values (per the spec, these render in the data font automatically), AppTextFieldVariant.text (default) for free text.

AppTextArea widget

The design-system TextArea — a themed, token-driven multi-line text input claiming the M3 outlined-text-field archetype. Anatomy mirrors AppTextField's FIELD pattern exactly: a DesignTokens.label micro-label above the box, a box-style field painted entirely by the shared `inputDecorationTheme`, and…

Full dartdoc

The design-system TextArea — a themed, token-driven multi-line text input claiming the M3 outlined-text-field archetype. Anatomy mirrors AppTextField's FIELD pattern exactly: a DesignTokens.label micro-label above the box, a box-style field painted entirely by the shared `inputDecorationTheme`, and an inline danger error line below the box. The differences are multi-line specific: the value text top-aligns, the field grows from minLines to maxLines (then scrolls — no drag-to-resize handle, touch-first), and there is no single-line submit action. **Validation runs on blur, not per keystroke** — identical contract to AppTextField: validator is called once when the field loses focus; a non-null return sets the box to its danger border and renders the message in DesignTokens.dataS / DesignTokens.danger below the box. Typing after an error clears it immediately. When maxLength is set, a quiet `count/max` counter renders in the data font at the trailing end of the meta row (error line leads, counter trails) — never the stock `TextField` counter widget. Uncontrolled by default (`value` / `onChanged`); pass controller for programmatic control. Exactly one of `value` / `controller` should be supplied. ```dart AppTextArea(label: 'Work note', onChanged: setNote) AppTextArea( label: 'Work note', value: note, onChanged: setNote, minLines: 3, maxLines: 6, maxLength: 280, hint: 'What the next crew needs to know', ) ```

AppTextAreadefault constructor

Knob Type Default What it does
autoGrow bool true `TextArea.d.ts` `autoGrow` — true (the default) grows from minLines to maxLines then scrolls; false pins the box height to minLines and scrolls inside it.
autofocus bool false Requests focus as soon as the field mounts.
controller TextEditingController? null Programmatic controller — the `TextEditingController` idiom. When null, the widget owns an internal controller seeded from value.
enabled bool true Disables the field (DesignTokens.ink40 foreground, not focusable) when false.
error String? null Controlled inline error. When non-null the field renders exactly this copy as the inline danger error — same anatomy as a validator-produced error (danger border on the box, danger message line below). The blur validator still runs and wins after interaction: from the first blur onward its result…
focusNode FocusNode? null Optional external focus node (the TextField.focusNode idiom) — lets a host land focus programmatically (the form kit's auto-advance). When null, the widget owns an internal node.
helper String? null Helper text rendered below the box when there is no active error. An error from validator (or a controlled error) replaces this line rather than stacking beneath it.
hint String? null Placeholder shown while the field is empty (theme's `hintStyle`).
isRequired bool false Renders the required marker — the trailing accent `*` on the micro-label (design-system pin `5908e48`). Visual only.
label String? null Micro-label rendered above the box, in the label role — sentence case, exactly as passed (`--type-label-transform: none`). Optional, matching `TextArea.d.ts` (`label?`) — the Dart port was stricter than its own spec until the thread composer needed the label-less pinned posture. Null renders no…
maxLength int? null Hard character cap — input refuses the `maxLength + 1`th character (enforced by a LengthLimitingTextInputFormatter). When set, renders a quiet `count/max` counter in the data font under the box instead of the stock `TextField` counter.
maxLines int? 8 Auto-grow cap before the box scrolls. Defaults to 8 (spec: auto-grow from rows to maxRows then scroll); pass null to grow unbounded.
minLines int 3 Starting height in text rows. Defaults to 3 (spec default).
onChanged ValueChanged<String>? null Fires on every keystroke with the field's current text.
readOnly bool false Renders the value but blocks editing (distinct from enabled: a read-only field still looks and focuses like an active field).
validator String? Function(String value)? null Runs on blur (focus loss), not per keystroke. A non-null return is shown as the inline danger error and switches the box to the danger border; null clears any existing error.
value String? null Initial value for the uncontrolled form (ignored when controller is supplied).

AppSelect widget

The design-system Select — a themed, token-driven single-select dropdown claiming the M3 exposed-dropdown-menu archetype. Anatomy (the FIELD pattern shared with `AppTextField`): a DesignTokens.label micro-label rendered above the box, and a box-style trigger showing the selected option's label (or…

Full dartdoc

The design-system Select — a themed, token-driven single-select dropdown claiming the M3 exposed-dropdown-menu archetype. Anatomy (the FIELD pattern shared with `AppTextField`): a DesignTokens.label micro-label rendered above the box, and a box-style trigger showing the selected option's label (or hint when value is null) plus a trailing ▾ chevron that flips when open. Tapping (or activating via keyboard) the trigger opens a hairline popover menu of options; the current selection carries a trailing ✓. Selected state is the ✓ only — no filled row, no accent background (constitution: encode once). Uncontrolled selection is not supported — value / onChanged is the only shape (mirrors `AppRadio`'s `value`/`groupValue`/`onChanged`, not `AppTextField`'s controller idiom, since a select's "value" is a single atomic choice rather than editable text). ```dart AppSelect<String>( label: 'Crew', value: crew, onChanged: setCrew, options: const [ ('B-7', 'B-7 — bridge crew'), ('C-2', 'C-2'), ], hint: 'Select crew', ) ```

AppSelectdefault constructor

Knob Type Default What it does
dataValue bool false Renders the selected value — and the popover option labels — in the data type role (DesignTokens.data): enum codes, IDs, and other machine values. The hint placeholder stays in the body role. Default false (body role, current behavior).
disabledValues Set<T> const {} Option values rendered as per-option disabled (Select.jsx `o.disabled`): DesignTokens.ink40 label, not tappable, skipped by keyboard traversal (a disabled `MenuItemButton` never takes focus). Additive to the `(value, label)` tuple so existing option lists keep compiling. Default empty — every option…
enabled bool true Disables the trigger (DesignTokens.ink40 foreground, not focusable, popover suppressed) when false.
error String? null Controlled inline error. When non-null the select renders exactly this copy as the field family's error line below the box (the Warning glyph, then the message in the UI font at the label size in DesignTokens.danger — `KitFieldMessage`) and the trigger border switches to danger. Default null — no…
hint String 'Select' Placeholder shown in DesignTokens.ink40 while value is null.
isRequired bool false Renders the required marker — the trailing accent `*` on the micro-label (design-system pin `5908e48`). Visual only.
label String? null Micro-label rendered above the box, in the label role — sentence case, exactly as passed (`--type-label-transform: none`).
onChanged ValueChanged<T>? null Fires with the tapped option's value when an option is chosen. Null disables the control (not tappable, muted paint).
onCleared VoidCallback? null THE NO-VALUE ROW (Select.d.ts, the web kit's `clearable`): non-null makes this a NULLABLE select — its list leads with a row labeled kSelectNoneLabel that fires this and closes, carrying the ✓ while value is null. Null (the default) offers no such row: a required field has no honest "none" to offer.…
options * List<AppSelectOption<T>> — The options offered by the popover, in display order.
registerOpen ValueChanged<VoidCallback?>? null Hands the host an OPEN for the options — called with it at mount and with null at dispose (the `FieldController.registerActivator` shape the form editors already speak). The form's enum editor registers it as its activator, so auto-advance and a data-table cell's open land on the options, as a…
value T? null The current selection, or `null` when nothing is selected yet.

AppDateField widget

The design-system DateField — a themed, token-driven box-style date input claiming the M3 `showDatePicker` archetype. Anatomy (the FIELD pattern shared with `AppTextField`): a DesignTokens.label micro-label above the box, a box-style field painted entirely by the theme's `inputDecorationTheme`, and…

Full dartdoc

The design-system DateField — a themed, token-driven box-style date input claiming the M3 `showDatePicker` archetype. Anatomy (the FIELD pattern shared with `AppTextField`): a DesignTokens.label micro-label above the box, a box-style field painted entirely by the theme's `inputDecorationTheme`, and an inline danger error line below the box. **The native picker is the touch surface.** Tapping anywhere in the box (not only the trailing calendar glyph) opens `showDatePicker` — manual ISO typing on mobile is poor, so this field is read-only text with a picker-driven value, matching the spec's "native picker IS the picking surface" rule. The trailing calendar glyph is an *accelerator* for the same picker, not a separate or required affordance. **value is a `DateTime?`**, rendered in ISO `yyyy-MM-dd` form using DesignTokens.data (dates are machine text). onChanged fires with the picked `DateTime`, or `null` when the clearable affordance blanks an optional field. **min / max constrain the picker** (`firstDate` / `lastDate`) — they never silently clamp a value that falls outside the range. If value falls before min or after max, the field renders that value with an inline danger error below the box instead of correcting it. ```dart AppDateField(label: 'Due', value: due, onChanged: setDue) AppDateField( label: 'Due', value: due, onChanged: setDue, min: opened, hint: 'Select a date', ) ```

AppDateFielddefault constructor

Knob Type Default What it does
clearable bool false Renders a clear (✕) affordance beside the calendar glyph while a value is set; activating it fires `onChanged(null)`. Off by default — a required field stays one-way. Without it, an OPTIONAL date field can never be blanked once set.
enabled bool true Disables the field (DesignTokens.ink40 foreground, not focusable, picker not launchable) when false.
error String? null Controlled inline error. When non-null the field renders exactly this copy as the inline danger error (same anatomy as the self-computed range error), overriding the built-in min/max copy. Default null — range violations render the built-in copy (current behavior).
helper String? null Helper text rendered below the box when there is no active error. An error (controlled error or self-computed range copy) replaces this line rather than stacking beneath it.
hint String? null Placeholder shown while value is null (theme's `hintStyle`).
includeTime bool false Renders the value as `yyyy-MM-dd HH:mm` instead of the date-only ISO form — the dateTime editor's display, so the picked time-of-day is visible and reviewable in the box.
isRequired bool false Renders the required marker — the trailing accent `*` on the micro-label (design-system pin `5908e48`). Visual only.
label * String — Micro-label rendered above the box, in the label role — sentence case, exactly as passed (`--type-label-transform: none`).
max DateTime? null Latest selectable date, passed to `showDatePicker` as `lastDate`. Never silently clamps value — a value after max instead renders an inline danger error.
min DateTime? null Earliest selectable date, passed to `showDatePicker` as `firstDate`. Never silently clamps value — a value before min instead renders an inline danger error.
onChanged ValueChanged<DateTime?>? null Fires with the newly picked date whenever `showDatePicker` resolves to a non-null selection, and with `null` when the clear affordance (clearable) is activated — the spec's "onChange receives '' when cleared" contract.
value DateTime? null The field's current value. Rendered as ISO `yyyy-MM-dd` in the data font; `null` renders hint instead.

AppSearchField widget

The design-system SearchField — a themed, token-driven box-style search input claiming the M3 `TextField` archetype (never the pill-shaped `SearchBar`). Anatomy: a leading search glyph, the value rendered in DesignTokens.data (operator grammar like `status:blocked` works but is never advertised —…

Full dartdoc

The design-system SearchField — a themed, token-driven box-style search input claiming the M3 `TextField` archetype (never the pill-shaped `SearchBar`). Anatomy: a leading search glyph, the value rendered in DesignTokens.data (operator grammar like `status:blocked` works but is never advertised — hint stays plain), and an intrinsic clear (✕) affordance that appears once the field is non-empty. No micro-label — a search box uses hint in place of the FIELD pattern's above-box label. **Esc clears the field; Enter submits** (onSubmitted). At most ONE trailing action may be supplied in addition to the intrinsic clear — the constitution's "search fields may host one trailing action" ceiling. **On a chrome band** (`chrome: accent | deep` — the compact bar's search mode, the hero band; `AppBar.d.ts` ON A BAND, #1186) the box is the band's FIELD BOX: at rest the DesignTokens.chromeField tonal fill with no border, the value and the placeholder in the on-chrome ink and the glyphs in the on-chrome 60 ink (text needs 4.5:1 on the tonal fill, a glyph 3:1); hovered the 18% state layer; focused it LIFTS to the ordinary field face — paper, ink, the ink60 placeholder and glyphs, and the normal focus ring. Under `chrome: ground` nothing changes. Uncontrolled by default (`value` / `onChanged`, mirroring the `TextEditingController` idiom used by the sibling `AppTextField`); pass controller for programmatic control. Exactly one of `value` / `controller` should be supplied — controller wins when both are given. ```dart AppSearchField(onChanged: setQuery, onSubmitted: runQuery) AppSearchField( hint: 'Search records', value: query, onChanged: setQuery, onSubmitted: runQuery, trailing: AppIconButton(glyph: KitGlyph.filter, title: 'Filter', onPressed: openFilters), ) ```

AppSearchFielddefault constructor

Knob Type Default What it does
autofocus bool false Requests focus as soon as the field mounts.
controller TextEditingController? null Programmatic controller — the `TextEditingController` idiom. When null, the widget owns an internal controller seeded from value.
enabled bool true Disables the field (DesignTokens.ink40 foreground, not focusable, clear affordance hidden) when false.
hint String 'Search' Placeholder shown while the field is empty (theme's `hintStyle`). Stays plain prose — operator grammar is a hidden power layer, never advertised here.
onChanged ValueChanged<String>? null Fires on every keystroke (and when Esc or the clear ✕ empties the field) with the field's current text.
onSubmitted ValueChanged<String>? null Fires when Enter is pressed (or the software keyboard's search action is invoked), with the field's current text.
trailing Widget? null At most ONE trailing action widget (e.g. a ghost `AppIconButton` for "Filter"), rendered after the intrinsic clear ✕. Null renders none.
value String? null Initial value for the uncontrolled form (ignored when controller is supplied).

ImageEditorWidget widget

Tap-to-capture editor for an image field.

ImageEditorWidgetdefault constructor

Knob Type Default What it does
controller * FieldController — The field controller (read/write the `staged://{id}` string).
spec * FieldSpec — The field spec.

FileEditorWidget widget

Tap-to-attach editor for a file field.

FileEditorWidgetdefault constructor

Knob Type Default What it does
controller * FieldController — The field controller (read/write the `staged://{id}` string).
spec * FieldSpec — The field spec.

CanvasEditorWidget widget

Tap-to-capture editor for a signature / drawing field.

CanvasEditorWidgetdefault constructor

Knob Type Default What it does
controller * FieldController — The field controller (read/write the `staged://{id}` string).
mode * CanvasEditorMode
signature · drawing
— Signature vs drawing vocabulary.
spec * FieldSpec — The field spec.

LatLongEditorWidget widget

Map-window + tile editor for a `"lat,long"` field.

LatLongEditorWidgetdefault constructor

Knob Type Default What it does
controller * FieldController — The field controller (read/write the `"lat,long"` string).
spec * FieldSpec — The field spec.
tileProvider TileProvider? null Explicit tile provider for the nudge window AND the pushed LatLongPicker (ledger F-51) — the picker's own sanctioned seam, so the editor→picker→commit chain is testable headlessly. A host wanting it registers a closure over LatLongEditorWidget instead of the bare latLongEditor entry. Null keeps the…

ImagePointEditorWidget widget

Tile + preview + picker editor for an `"x, y"` image-point field.

ImagePointEditorWidgetdefault constructor

Knob Type Default What it does
controller * FieldController — The field controller (reads/writes the `"x, y"` string).
spec * FieldSpec — The field spec.

CanvasPadScreen widget

The full-screen capture pad — a paper canvas collecting freehand strokes, a Clear ghost action, and a Done slab that pops the rasterized image. Public for widget tests; hosts never construct it directly.

CanvasPadScreendefault constructor

Knob Type Default What it does
clearLabel * String — Clear-strokes action label.
doneLabel * String — Commit action label.
title * String — Header title (signature vs drawing vocabulary).

Types its knobs take

These are not things you choose — they are the shapes the knobs above expect. They live under this entry rather than in the navigation for exactly that reason.

FieldController support

Per-field handle threaded into each `FieldEditor` widget. Bundles read/write access to the field's value with its derived editable / required / error state.

Field Type Default What it does
_parent * FormController —
_spec * FieldSpec —
onAdvance void Function(FieldSpec spec)? null
setActivator void Function(Object owner, String snakeName, VoidCallback? activate)? null
textInputAction TextInputAction? null The software keyboard's action key for this field, assigned by the form from the field's position: `next` on every single-line editor except the last, `done` on the last — so the keyboard walks the form instead of dismissing between every field. Null (a standalone editor host) keeps the platform…

FieldSpec support

Per-field static metadata describing how a single column renders in a `FormView`. Pure data — no widget references, no controllers.

Field Type Default What it does
allowOtherValues bool false Whether an `enumValue` or `enumList` column accepts values outside enumValues (origin `AllowOtherValues:true` — 238/263 enums). When true an `enumValue` editor is an open combobox: a text input + filtered suggestions + a pinned `Add "{typed}"` row committing the typed value verbatim; an `enumList`…
columnType * ColumnType — Column type — drives editor dispatch in `FieldEditorRegistry`.
decimalPlaces int? null An `exactDecimal` field (and a quantity's number): at most this many digits after the point, counted as typed (`FormView.d.ts` AN EXACT DECIMAL IS ITS STRING). An intrinsic check. Null: any number of places, within `numeric`'s limit.
defaultUnit String? null A quantity field's starting unit code; null starts at the first of units.
derive FieldDeriver? null Recomputes this field's value from the live values map whenever any field changes — the in-form face of a write-time computed column. A derived field is **read-only by construction**: `FormController.isEditable` returns false for it, so a user edit can never be clobbered by the next unrelated…
editableIf FieldPredicate? null Reactive `Editable_If` — when non-null, overrides isReadOnly: the editor accepts input only while this returns true. Null falls back to `!isReadOnly`. §D1.
enumDisplay EnumDisplay EnumDisplay.buttons Display mode for `enumValue` columns (see EnumDisplay). Ignored for every other column type. Defaults to EnumDisplay.buttons.
enumValues List<String>? null Pre-defined value set for `enumValue` / `enumList` / `color` editors. Null for other column types.
exactMax ExactDecimal? null The inclusive upper bound, as exactMin.
exactMin ExactDecimal? null An `exactDecimal` field (and a quantity's number): the inclusive lower bound, compared EXACTLY (ExactDecimal.compareTo, never through a float). An intrinsic check. A quantity's bound is in the value's own unit; a bound in another unit is the host's validator.
formatRules List<FormatRule<Map<String, Object?>>>? null FORMAT RULES on the LOCKED face only (`FormView.d.ts` THE LOCKED FACE WEARS ITS RULE, #1006; `FormatRules.d.ts`): while the field is locked (read-only, editableIf false, a derived field) its value wears the first holding rule, as a detail field does. The SUBJECT is the field's value, and the ROW an…
helper String? null Optional helper text rendered below the field label. Slice 18 surfaces this in `FieldCard`; emit threads it from the source per-field description when present.
initialValue Object? Function()? null Optional seed for the field's value at form construction. A plain thunk — `() => DateTime.now()`, `() => 0.45` — invoked once when the controller builds (and again on reset). Returning `null` (or leaving it unset) starts the field empty.
inlineAction FieldAction? null Field-scoped auxiliary action rendered beneath this field's editor — see FieldAction. Null renders no affordance.
isHidden bool false Hidden fields are seeded into form state and round-trip through save, but render no editor — useful for a system key column carrying a generated id via initialValue.
isOwed bool false Required LATER, never at save (`FormView.d.ts` A FIELD MAY BE OWED, #1496): the micro-label carries the required marker and the control is announced required, but the field never gates the save, never counts toward `FormController.requiredBlankCount` and never raises the required message, and its…
isReadOnly bool false Static read-only flag — the editor is disabled whenever this is true.
isRequired bool false Static "required regardless of state" flag — drives the required-blank validation in `FormController`.
label * String — Human-readable label rendered as the editor's `labelText`.
listSeparator String? null The write separator of an `enumList` / `refList` field — the column's own spelling (`ColumnDef.listSeparator`, threaded by the field plan, `bindFieldPlan`). Null writes `kEnumListSeparator`. The source platform's item separator is a per-column property; reads are separator-tolerant.
listValue bool false An `enumList` (or a list of refs) whose value is a `List<String>`, not the joined string (`FormView.d.ts` AN ENUM LIST'S VALUE MAY BE ITS LIST, #1496): members verbatim, in held order, any text, never split, so a member may hold the separator. A held joined string is read through the list grammar…
maxDate DateTime? null The latest offered day, inclusive, as minDate.
minDate DateTime? null A `date` / `dateTime` field's earliest offered day, inclusive (`FormView.d.ts` A DATE CAN BE BOUNDED): reaches `AppDateField.min` and an intrinsic check. Null: unbounded.
noLabel String? null The no-word of a `yesNo` field (origin `NoLabel`) — where the value is READ BACK rather than edited (a detail, a cell, a review line); the form's row never shows it. Null reads "No". §D4.
numberFormat AppNumberFormat? null How a `number` / `decimal` / `percent` value reads on the field's LOCKED face (`FormView.d.ts` `FormField.numberFormat`; the rules are `DataTable.d.ts` NumberFormat's). THE LOCKED FACE READS AS THE CELL READS: while the field is not editable (read-only, editableIf false, a derived field) the box…
options List<FieldOption>? null Labeled options for an `enumValue` / `enumList` field (`FormView.d.ts` AN OPTION HAS A LABEL, AND A RETIRED OPTION IS ONLY EVER HELD; steady-core #1491). When set it wins over enumValues: the stored value is FieldOption.value, every face shows FieldOption.label, and a FieldOption.retired option is…
override FieldOverride? null The field's value comes from a WIDER SCOPE and may be overridden here (`FormView.d.ts` A FIELD MAY INHERIT ITS VALUE) — see FieldOverride. Null: an ordinary field whose value is its own, and nothing renders.
placeholderOf String? Function(Map<String, Object?> values)? null What an EMPTY value MEANS, read against the live values (`FormView.d.ts` `FormField.placeholderOf`, 2026-10-09, #1217) — a nullable override whose blank is "auto", or a typical rate the blank falls back to. The answer paints in `--ink40` inside the editor's box while the value is blank: on the form,…
ref RefFieldConfig? null Ref-column config — target table, choice-list stream, add-new builder. Null for every column that holds no ref: a `ref` column, and a LIST of refs (an `enumList` whose members are target keys — its editor is `kitRefListEditor`), carry one.
requiredIf FieldPredicate? null Reactive `Required_If` — when non-null, overrides isRequired: the field is a save-gate only while this returns true. Null falls back to the static isRequired. §D1.
resetRule ResetRule? null Reactive reset rule (origin `Reset_If` / `ResetOnEdit`). Null means the field is never auto-cleared. See ResetRule, §D1.
ruleLock FieldRuleReading? null A DECLARED RULE's lock (`FormView.d.ts` `FormField.ruleLock`, FieldRules.d.ts THE BINDING): why the rule locks the field over the live and stored values, or null while it does not. The binding sets it (withFieldRules) and ANDs the same answer into editableIf; the form reads it only for THE WORDS…
ruleRefusal FieldRuleReading? null A DECLARED RULE's save-time check (`FormField.ruleRefusal`): why the server would refuse THIS save's write of the field, or null when it permits. A refusal is the field's error line, in THE WORDS (`FormController.ruleRefusal`). The binding sets it.
section String? null Optional section grouping. Null means "no section header" — the field still renders, but in the default un-headered section. Sourced from the source form's section settings.
showIf FieldPredicate? null Reactive `Show_If` — when non-null, the field renders an editor only while this returns true over the form's current values. Null means "always visible" (the static default). A hidden-by-rule field leaves the layout, semantics, and focus tree; it does **not** null its value (only an explicit reset…
snakeName * String — snake_case column name. Matches the key produced by `RowCodec<T>.encode(row)` and serves as the form-state map key.
span FieldSpan FieldSpan.auto Layout span on tablet form factors (see FieldSpan). Phone always collapses to single column regardless of span. Defaults to FieldSpan.auto — the editor's natural width decides pairing.
stepValue num? null Step increment for a `number` / `decimal` / `percent` editor (origin `StepValue`, e.g. `number_of_people` StepValue 1; a percent steps in the whole points it shows). When non-null the editor flanks the field with −/+ 48dp targets; the field still accepts typed input. Null renders a plain numeric…
suggestedValues SuggestedValuesResolver? null Live suggestion source for an OPEN enum's combobox, and an OPEN enum list's entry surface (allowOtherValues) — typically the column's own already-used values, so free entry converges on the estate's vocabulary instead of minting near-duplicates. The editor subscribes once for its lifetime and merges…
temporal TemporalSemantic TemporalSemantic.instant What a NAIVE `dateTime` value means (`FormView.d.ts` `temporal`, the column's `ColumnDef.temporal`, threaded by `bindFieldPlan`): TemporalSemantic.instant (the default) reads it in device-local time; TemporalSemantic.wallClock keeps the time as written. Read by a data table cell's typed entry and a…
units List<QuantityUnit>? null An `exactDecimal` field that edits a QUANTITY (`FormView.d.ts` A QUANTITY IS A NUMBER AND ITS UNIT): the units it offers, in order. When set the value is a QuantityValue (`value`, `unit`), never a string; one unit is the box's suffix, several an `AppSelect` beside it. Null: a plain exact decimal.
validator FieldValidator? null Value-level validation rule. Null means "any non-blank value is acceptable" (the static default) — this field is the ONLY way a form rejects a value on grounds other than blankness. The rule runs **after** the blank / required decision and only on a non-blank value, so it never re-implements…
yesLabel String? null The yes-word of a `yesNo` field — the label of its one checkbox row, what ticking asserts (origin `YesLabel`, e.g. `report_request.is_report_package` → "Report Package"). Static: it is never re-worded per toggle. Null renders "Yes".

Where it lives

Class File
AppTextField packages/app_widgets/lib/src/kit/forms/text_field.dart
AppTextArea packages/app_widgets/lib/src/kit/forms/text_area.dart
AppSelect packages/app_widgets/lib/src/kit/forms/select.dart
AppDateField packages/app_widgets/lib/src/kit/forms/date_field.dart
AppSearchField packages/app_widgets/lib/src/kit/forms/search_field.dart
ImageEditorWidget packages/app_widgets/lib/src/form/_image_editor.dart
FileEditorWidget packages/app_widgets/lib/src/form/_file_editor.dart
CanvasEditorWidget packages/app_widgets/lib/src/form/_canvas_editor.dart
LatLongEditorWidget packages/app_widgets/lib/src/form/_lat_long_editor.dart
ImagePointEditorWidget packages/app_widgets/lib/src/form/_image_point_editor.dart
CanvasPadScreen packages/app_widgets/lib/src/form/_canvas_editor.dart