Import
Reach for this when a batch of records comes in — a file upload or a pull — and someone has to review what is staged before anything is committed. The floorplan owns the frame: the phase line, the summary band and its filter doors, the checks that gate Confirm, the commit footer and the discard dialog. The review body is yours, and a RecordsScreen there nests as embedded. Step through phase to see every face, and change confirmGate to see how Confirm waits for the checks.
Spec of record: design-system/components/floorplans/ImportScreen.d.ts
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.
The host maps its own statuses onto these six; the frame changes face with each.
How Confirm behaves while a check is unmet. Read at the review phase, where one check blocks.
Dart for these values
screen_import() 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.
ImportScreen widget
The FLOORPLAN for bringing a batch of records in (`design-system/components/floorplans/ImportScreen.d.ts`): a file upload or a pull from another system, read, STAGED, reviewed, and only then committed. THE FLOORPLAN KNOWS NOTHING ABOUT THE DATA: no table, no status word, no staging store.
Full dartdoc
The FLOORPLAN for bringing a batch of records in (`design-system/components/floorplans/ImportScreen.d.ts`): a file upload or a pull from another system, read, STAGED, reviewed, and only then committed. ```dart ImportScreen( phase: phaseFor(upload.status), title: 'Import tasks', meta: 'tasks-october.xlsx', syncStatus: const SyncStatusButton(), onBack: leave, stats: const [ KpiStat(key: 'all', label: 'Rows read', value: '1,000', door: true), KpiStat(key: 'attention', label: 'Need attention', value: '23', tone: KpiStatTone.critical, door: true), ], checks: [ ImportCheck(key: 'refs', label: 'Every assignee exists', met: false, stat: 'attention', actions: excludeAll), ], review: (context, view) => RecordsScreen<Staged>( title: 'Staged rows', rows: staged.where(byStat(view.activeStat)).toList(), ... ), tally: const ['927 new', '50 updates', '23 excluded'], confirmLabel: 'Import 977 rows', onConfirm: commit, stagedWork: true, onDiscard: discardAndLeave, ) ``` THE FLOORPLAN KNOWS NOTHING ABOUT THE DATA: no table, no status word, no staging store. The host maps its statuses onto phase, computes stats and checks, renders review, and performs every write. **Not generic.** The contract's flutter line sketches `ImportScreen<TView>`, but nothing on this stack could construct a host's `TView`: the view state is the FLOORPLAN's (ImportView — which door is active), minted here and grown additively here. A type parameter no argument can bind would be noise every host writes `<ImportView>` to satisfy. **Not carried:** `captureDisplay` — the contract forwards `FormView.d.ts`'s display resolver, and this kit's capture tiles render through the capture scopes capture installs, exactly as `FormScreen` on this stack takes none. THE DROP is not planned on this kit (see the file header).
ImportScreendefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| activeStat | String? | _kActiveStatUncontrolled | 'review': the active door, CONTROLLED. Pair with onActiveStatChange. Omitted (the default) leaves the floorplan owning it, seeded from initialActiveStat; null controls it to "no door active". |
| addFiles | bool | false | FILES JOIN AN OPEN REVIEW (`ImportScreen.d.ts`, 2026-10-30). True, with a sourceFiles zone: the review's bar carries "Add files", which opens the source card — the source form's fields and the zone after them — as a modal sheet over the review, its submit onSubmitSource under the same refusal rule… |
| banner | Widget? | null | A surface notice between the phase line and the phase's content, surviving every face (`RecordsScreen.banner`). |
| capture | FormCapture? | null | 'source': what the capture tiles stage through, forwarded verbatim (`FormScreen.capture` — a capture field is read-only unless its own kind's capture is present). |
| checks | List<ImportCheck> | const [] | 'review': the checks. Empty renders no card, and nothing gates; a ImportCheck.notice among them never gates and is never counted. |
| committingCopy | String? | null | 'committing': whether leaving stops it, and where the outcome shows. |
| committingLabel | String | 'Importing' | 'committing': the Progress word. Default 'Importing'. |
| committingTitle | String? | null | 'committing': the headline ("Importing 977 rows into Tasks"). |
| confirmGate | ImportConfirmGate inert · hidden · refuses | ImportConfirmGate.inert | How Confirm behaves while any check is unmet (THE GATE). Default ImportConfirmGate.inert. |
| confirmLabel | String | 'Import' | 'review': Confirm's label; a host says the count. Default 'Import'. |
| copy | ImportCopy | const ImportCopy() | The floorplan's own sentences outside the discard dialog, for a batch that is not an import (THE SCREEN'S WORDS ARE THE HOST'S, #1709); each absent member keeps its default. |
| detail | ImportDetail? | null | 'review': the record the body opened, shown IN PLACE (`ImportScreen.d.ts` THE REVIEW OPENS A RECORD IN PLACE, #1710) — docked at the inline end at expanded and wider, a card in place of the checks column that takes the records pane's grammar (THE DOCKED RECORD TAKES THE RECORDS PANE'S GRAMMAR,… |
| discardCopy | ImportDiscardCopy | const ImportDiscardCopy() | The discard dialog's words. |
| error | FloorplanError? | null | A failure the floorplan could not see (THE LOAD FACES), on any phase. |
| failure | ImportFailure? | null | 'failed': what did not fit. |
| failureActions | List<ActionSpec> | const [] | 'failed': the recoveries. |
| hostUndo | RecordsHostUndo? | null | 'review': the host's latest write at the import's level, with its Undo (`ImportScreen.d.ts` THE REVIEW'S BAND CARRIES A HOST WRITE'S UNDO): a new RecordsHostUndo.id states its message in the commit footer's Modeline with "Undo", on a transient clock and below a commit failure, and a ctrl/⌘ Z nothing… |
| initialActiveStat | String? | null | The active stat on first mount when activeStat is not controlled; a key that names no door is ignored. Default null (no door active). |
| initialPrefs | ImportViewPrefs? | null | Restored view state (ImportViewPrefs), read ONCE — the first time it is non-null, at mount or later — and cancelled by a change the reader makes before it lands (`RecordsScreen.d.ts` `initialPrefs`, the same rule). A later change to an already-read value is ignored. |
| loading | bool | false | The phase's content is still arriving: the phase's skeleton face. |
| meta | String? | null | The subtitle line: the file or source name. |
| onActiveStatChange | ValueChanged<String?>? | null | The active door changed — a door tapped, a check's "Show rows", the refusing gate opening the first unmet check's door. |
| onBack * | VoidCallback? | — | The bar's Back, DECLARED, never inferred (`DetailScreen.d.ts` THE EXITS ARE DECLARED). REQUIRED BUT NULLABLE (#1639, EVERY PHASE HAS A WAY OUT): `committing` and `result` carry no Cancel, so a screen with no Back and no resultActions had no control that left it. Null states "deliberately no Back",… |
| onConfirm | FutureOr<void> Function()? | null | 'review': the commit. Null renders no Confirm (a read-only review). While its future is pending Confirm is inert (one commit at a time). |
| onDiscard * | VoidCallback | — | REQUIRED. Discard ends the screen: the host navigates. |
| onPrefsChanged | ValueChanged<ImportViewPrefs>? | null | Fires after every view-state change the reader makes — a seam drag that settles (writes `paneWidth`, clears `paneWide`), the widen press (writes `paneWide`), the seam's reset (writes both null) — for the host's prefs store. |
| onRetry | VoidCallback? | null | The error face's Retry. Null renders the cause with no Retry. |
| onSubmitSource | Future<void> Function(Map<String, Object?> values)? | null | 'source': called with the valid values; the host moves phase on. A rejection keeps the form and is stated in the footer, in the host's words: sourceFailureText's, else a thrown SaveRefusal's `refused`, else "<sourceSubmitLabel> failed. Try again." (`ImportScreen.d.ts` THE SOURCE'S REFUSAL IS IN THE… |
| phase * | ImportPhase source · working · review · committing · result · failed | — | REQUIRED, no default. The phase this screen shows (THE PHASES); controlled by the host, which maps its own statuses onto it. |
| phaseLabels | ImportPhaseLabels | _kPhaseLabels | The phase line's four step names, in the host's words ('Fetch' for a pull). Default ('Upload', 'Read', 'Review', 'Import'). The first is hidden when the screen has no source (sourceFields or sourceFiles). |
| phaseLine | bool | true | Default true. False removes the phase line under the bar; the phases themselves are unchanged. |
| presence | Widget? | null | THE PRESENCE STACK (`ImportScreen.d.ts` `presence`; `Presence.d.ts` EVERY FLOORPLAN CARRIES IT AS A KNOB, steady-core #1331): the `AppPresenceStack` of the scope this import joins. The HOST builds it; the screen never joins a channel. It is this screen's own bar's AppHeaderBar.presence, immediately… |
| readingLine | String? | null | 'review': the host's words for what is still being read ("8 of 12 read"), while any item is (`ImportScreen.d.ts` THE REVIEW SHOWS WHILE ITEMS ARE STILL BEING READ, 2026-10-30). Drawn on one quiet line leading the review's main column, above the band, after an AppProgress carrying workingLabel; a… |
| refOptions | FormRefOptionsResolver? | null | 'source': `FormView.d.ts`'s ref resolver, forwarded verbatim (`FormScreen.refOptions`). |
| resultActions | List<ActionSpec> | const [] | 'result': the next steps, in a card beside the result body. |
| resultBody | Widget? | null | The result phase's body, typically what was skipped and why. Installs the nesting scope. |
| resultLine | String? | null | 'result': the outcome line in the neutral banner. |
| resultStats | List<KpiStat> | const [] | 'result': the result band; doors are ignored here. |
| review * | ImportReviewBuilder | — | The review body, rendered from the view state. INSTALLS THE NESTING SCOPE: a floorplan here is nested and resolves its posture from this screen — the canonical body, `RecordsScreen`, resolves to embedded (no bar, no Fab, its pane the modal sheet). Any other kit composition is equally first-class. |
| sourceFailureText | String? Function(Object error)? | null | 'source': the footer's sentence for a rejected onSubmitSource, from what it threw, so a host maps its own refusal (a file too large, a type it will not read, a duplicate) to its words. Null, blank or a throw falls to a SaveRefusal's `refused`, else the generic line; the error's own message is never… |
| sourceFields | List<FieldSpec>? | null | 'source': the form's field specs. The screen HAS a source phase when it has these OR sourceFiles; with neither the phase line hides its step and the import opens at Read. |
| sourceFiles | AppFileDrop? | null | 'source': MANY FILES AT ONCE (`ImportScreen.d.ts`, 2026-10-20, steady-build/steady-build-app#160) — the zone itself, drawn at the source card's foot after the fields: the host's own AppFileDrop, which hands it the whole picked set. A typed slot rather than the web's props object: the widget IS the… |
| sourceSections | List<FormSectionSpec> | const [] | 'source': the form's section declarations, forwarded verbatim. |
| sourceSubmitLabel | String | 'Upload' | 'source': the submit's verb. Default 'Upload'. |
| stagedWork | bool | false | Default false. True makes Cancel and Back confirm before onDiscard (THE DISCARD CONFIRMATION); the host sets it once anything is staged. |
| stats | List<KpiStat> | const [] | 'review': the summary band. Empty renders no band. |
| syncStatus * | Widget? | — | The bar's last slot (`AppBar.d.ts` `syncStatus`). REQUIRED BUT NULLABLE: null renders none. |
| tally | List<String> | const [] | 'review': the footer's tally, as Modeline segments, in host words. |
| title * | String | — | The bar's title: what is being imported INTO ("Import tasks"). |
| workingCopy | String? | null | 'working': one line of host copy (how long, whether leaving stops it). |
| workingLabel | String | 'Reading' | 'working': the Progress word ('Fetching' for a pull). Default 'Reading'. |
| workingTitle | String? | null | 'working': the headline. Default "workingLabel meta" (#1639: it read "Reading meta" whatever the label). |
AppFileDrop widget
The zone for picking MANY files at once (`FileDrop.d.ts`). "Choose files" always, "Choose a folder" where FileCapture.canPickFolder.
Full dartdoc
The zone for picking MANY files at once (`FileDrop.d.ts`). ```dart AppFileDrop( label: 'Files', maxFiles: 500, maxTotalBytes: 2 * 1024 * 1024 * 1024, accept: const ['.pdf', '.zip'], onFiles: (files) async { for (final f in files) held.add(await stagePickedFile(context, f)); }, ) ``` "Choose files" always, "Choose a folder" where FileCapture.canPickFolder. Every set is settled the same way before the host sees it: a walked folder's litter left behind, the set ordered by path, and refused WHOLE when it is empty, past maxFiles or maxTotalBytes, or carries a file outside accept — the refusal on the error line, in refusalText's words where the host gives some. A set that passes goes to onFiles once; while its future is pending the zone is busy. With no FileCaptureScope above it the zone is disabled: nothing can be picked, and nothing pretends it can.
AppFileDropdefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| accept | List<String> | const [] | The extensions or MIME types every file must match ('.pdf', 'application/zip', 'image/*'). Empty accepts any file. |
| chooseFilesLabel | String | 'Choose files' | The files launcher's label. |
| chooseFolderLabel | String | 'Choose a folder' | The folder launcher's label. |
| disabled | bool | false | Non-interactive: no launcher acts, and the lock mark shows. |
| error | String? | null | The host's error line. |
| helper | String? | null | The quiet line below; a refusal, then error, wins. |
| label | String? | null | The micro-label above the zone. |
| maxFiles * | int | — | The most files one pick may carry. |
| maxTotalBytes * | int | — | The most bytes one pick may carry, in total. |
| onClear | VoidCallback? | null | Renders "Clear" while summary stands. |
| onFiles * | FutureOr<void> Function(List<PickedFile> files) | — | The set that passed the bounds, whole and ordered by path. |
| refusalText | String? Function(FileSetRefusal refusal)? | null | The host's sentence for a refusal, or null for the kit's. A blank answer or a throw counts as null. |
| summary | String? | null | What the host holds from earlier sets ("12 files, 48 MB"). Null or empty is not provided. |
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.
ActionSpec support
One app-agnostic action — the runtime primitive behind every action button. Pure affordance metadata plus an onInvoke callback.
| Field | Type | Default | What it does |
|---|---|---|---|
| enabled | bool | true | Whether the action is invokable. A disabled action renders grayed out and does not fire onInvoke. |
| glyph | KitIconRef? | null | The action's design-system glyph. Wins over icon when both are set — the same two-channel contract every glyph-bearing kit API carries. |
| icon | IconData? | null | The action's Material glyph, for a consumer that has not moved to glyph yet. |
| isDestructive | bool | false | Whether the action is destructive (delete, discard, revoke). Purely a visual treatment — hosts render the affordance in the danger color role. Any confirmation dialog is the consumer's onInvoke responsibility; the action layer stays behavior-blind. |
| label * | String | — | User-visible label — also the `IconButton` tooltip, the overflow menu-item text, and the `Semantics` label. |
| navigates | bool | false | THE ACTION THAT ONLY OPENS A PAGE (`ActionStrip.d.ts`, steady-core #1673): true declares that invoking it does ONE thing — it opens another screen (a pushed route, a layer) and writes nothing. The host reports the control, or the ⋯ item it folds into, as a link (`Semantics(link: true)`); paint,… |
| onInvoke * | ActionInvokeCallback | — | Invoked on tap. See ActionInvokeCallback. |
| placement | ActionPlacement | ActionPlacement.secondary | Where the action renders. See ActionPlacement. |
| shortLabel | String? | null | The primary slab's SHORT-VERB face (refinements D4: "New", never "New Observation" — the noun is the screen title). Read only where the action renders as the header-band slab; label stays the descriptive accessible name everywhere else (the compact FAB's tooltip, overflow rows). Null falls back to… |
| visible | bool Function(BuildContext context)? | null | Optional visibility predicate. `null` (the default) means always visible. When non-null, hosts re-evaluate the predicate on every build and omit the affordance entirely when it returns false — independent of enabled (which grays but does not hide). Receives BuildContext so predicates can read theme,… |
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". |
FileSetRefusal support
Why a set was refused WHOLE (`FileDrop.d.ts` THE BOUNDS ARE THE HOST'S), handed to AppFileDrop.refusalText so the host can word it.
FormCapture support
What a form's capture tiles stage through — the `FormScreen.d.ts` `capture` slot, which is `FormView.d.ts`'s `capture` resolver in the spelling THIS kit's editors read. `FormView.d.ts`'s own flutter clause names them: on this stack a capture tile resolves its value through an inherited capture…
| Field | Type | Default | What it does |
|---|---|---|---|
| canvas | CanvasCapture? | null | Stages a `signature` / `drawing` field's rasterized pad (CanvasCaptureScope). |
| file | FileCapture? | null | Stages a `file` field's pick (FileCaptureScope). |
| image | ImageCapture? | null | Stages an `image` field's camera/library pick (ImageCaptureScope). |
| location | LocationCapture? | null | Reads the device location a `latLong` field offers (LocationCaptureScope). |
| locationCenter | CaptureLocationCenterResolver? | null | Answers where an EMPTY `latLong` field's picker opens — `FormView.d.ts` `CaptureLocationPicker.fallbackCenter` (CaptureField.d.ts THE EMPTY FIELD'S OPENING CAMERA, #1373): per field and per record over the live values, a project's centroid say. It is shown while the picker's opening locate is… |
FormSectionSpec support
One form section's DECLARATION (`FormView.d.ts` THE SECTION IS DECLARED ONCE; `FormSection`, Contained, 2026-09-29, #846). Fields JOIN a section by naming its id — its key, else its label — in `FieldSpec.section`; this entry only adds the words the Contained form card states beside them.
| Field | Type | Default | What it does |
|---|---|---|---|
| collapsed | bool? | null | The CONTROLLED collapse state of a collapsible section. Set, it is the state on every build: the head's toggle, the index's selection and a blocked save only ask through onCollapsedChanged, and the section moves when the host hands the new value back. A controlled section with no onCollapsedChanged… |
| collapsible | bool | false | When true the section's title is a disclosure toggle and its fields may collapse: out of the view and the focus order, still mounted, still gating the save (React `FormSection.collapsible`). Default false. |
| initiallyCollapsed | bool | false | The UNCONTROLLED seed of a collapsible section: read once, when the view first sees the section, and never re-seeded by a later value. Ignored while collapsed is set (React `FormSection.defaultClosed`). |
| key | String? | null | The section's stable identity, the string its fields name in `FieldSpec.section` (`FormView.d.ts` A SECTION HAS A KEY, #1496). When set, label is the title alone, free to change, and two keyed sections with one label stay two sections. Null: label is the identity, as before (React… |
| label * | String | — | The section's title (the title role); with no key, also the string its fields name in `FieldSpec.section`. |
| onCollapsedChanged | ValueChanged<bool>? | null | Reports the state the USER asks for — `true` to collapse: the head's toggle, or `false` when the index selects a collapsed section or a blocked save lands in one. Controlled or not; never at mount and never for a collapsed value the host changed (React `FormSection.onCollapsedChange`). |
| purpose | String? | null | One sentence stating what the section is for ("Who does the work, and where."), set in the purpose column beside the fields, or under the title when the card is stacked. Null renders the title alone. |
ImportCheck support
One fact that must hold before anything is committed, or one worth reading first (`ImportCheck`, THE CHECKS).
| Field | Type | Default | What it does |
|---|---|---|---|
| actions | List<ActionSpec> | const [] | The check's own remedies while unmet (always, for a notice) ("Exclude all"), as outline buttons. Never a commit. A met gating check renders none. |
| detail | String? | null | What is wrong, or why it is fine. |
| key * | String | — | Identity. |
| label * | String | — | A fact that should be true, sentence case: "Every assignee exists". A notice states what will happen: "3 saved views are removed". |
| met * | bool | — | Computed by the host; the gate reads nothing else. True on a notice, which never blocks. |
| stat | String? | null | A door's key: while unmet (always, for a notice), "Show rows" makes that door active. |
| Field | Type | Default | What it does |
|---|---|---|---|
| actions | List<ActionSpec> | const [] | The check's own remedies while unmet (always, for a notice) ("Exclude all"), as outline buttons. Never a commit. A met gating check renders none. |
| detail | String? | null | What is wrong, or why it is fine. |
| key * | String | — | Identity. |
| label * | String | — | A fact that should be true, sentence case: "Every assignee exists". A notice states what will happen: "3 saved views are removed". |
| stat | String? | null | A door's key: while unmet (always, for a notice), "Show rows" makes that door active. |
ImportCopy support
The sentences the floorplan writes itself, outside the discard dialog (`ImportScreen.d.ts` THE SCREEN'S WORDS ARE THE HOST'S, #1709): the same frame stages an uninstall or an update as well as an import. Each absent member keeps its default.
| Field | Type | Default | What it does |
|---|---|---|---|
| blocking | String Function(int unmet, int? of)? | null | Default "`n` checks block the import", or with `of` "`n` of `m` checks block the import": the refusal banner (no `of`) and the compact banner (`of` the gating total). A function, because the count decides the grammar. |
| checksTitle | String? | null | Default "Before you import": the checks card's head and the compact sheet's title. |
| commitFailed | String? | null | Default kImportDidNotStart: the footer's statement for a rejected `onConfirm`. |
| nothingStaged | String? | null | Default "Nothing was staged.": the failed face's banner lead. |
| notices | String Function(int count)? | null | Default "1 notice to read" / "`n` notices to read": the compact neutral banner while no check blocks. |
ImportDetail support
The record the review opened, shown on this screen (`ImportScreen.d.ts` THE REVIEW OPENS A RECORD IN PLACE, #1710): the review body's push channel sets the host's state, and the host hands the record back as ImportScreen.detail, so the review and its body's state stay mounted while the reader fixes…
| Field | Type | Default | What it does |
|---|---|---|---|
| body * | Widget | — | The record's detail, typically a `DetailScreen` or a fix form. INSTALLS THE NESTING SCOPE, and THE HOST OWNS THE PANE CHROME there: a `DetailScreen` takes the pane posture and draws no ✕ and no expand of its own. |
| onClose * | VoidCallback | — | The ✕, Escape, and a dismissed sheet. The host clears ImportScreen.detail; the floorplan never closes it on its own. |
| onOpenFull | VoidCallback? | null | THE EXPAND (`ImportScreen.d.ts` THE DOCKED RECORD TAKES THE RECORDS PANE'S GRAMMAR, 2026-10-30): the host's own fuller route, the drill-in. Present, the expand stands before the ✕ in the docked card and in the sheet's head below 960; a press calls this and NOTHING ELSE — the host pushes, and keeps… |
| title * | String | — | The pane's head and its accessible name: the record's own name ("Row 14 · Pump 3"). |
ImportDiscardCopy support
The discard dialog's words (`ImportScreenProps.discardCopy`); each member keeps its default unless the host says otherwise.
| Field | Type | Default | What it does |
|---|---|---|---|
| body | String | 'The staged rows and any fixes are removed. Nothing has been imported.' | The consequence, stated flat. |
| cancel | String | 'Keep reviewing' | The way back to the import. |
| confirm | String | 'Discard import' | The destructive confirm's verb. |
| title | String | 'Discard this import?' | The dialog's title. |
ImportFailure support
What did not fit (`ImportScreenProps.failure`, THE PHASES, `'failed'`).
| Field | Type | Default | What it does |
|---|---|---|---|
| detail | String? | null | The danger banner's message, after its "Nothing was staged." lead. |
| problems | List<ImportProblem> | const [] | The problems table's rows; empty renders no table. |
| title * | String | — | The headline. |
ImportViewPrefs support
The reader's own view state on the import, device-local and never synced (`ImportScreen.d.ts` THE DOCKED RECORD TAKES THE RECORDS PANE'S GRAMMAR, THE VIEW PREFS): restored through ImportScreen.initialPrefs and reported through ImportScreen.onPrefsChanged. Each member is written only from the…
| Field | Type | Default | What it does |
|---|---|---|---|
| paneWide | bool? | null | The docked record card WIDENED by its chrome row's toggle: true takes the seam's whole reach, false is the reader's own narrow. A drag that settles clears it, and the seam's reset writes both members null. |
| paneWidth | double? | null | The docked record card's width the reader dragged its seam to, in logical pixels. Null: the resting share. A width the review row can no longer seat is clamped at layout and kept as stored. |
KpiStat support
One number in a KPI band (`KpiStat`, Charts.d.ts THE KPI BAND).
| Field | Type | Default | What it does |
|---|---|---|---|
| caption | String? | null | One quiet --ink40 line under the value: "pass every check". |
| door | bool | false | True makes the stat a FILTER DOOR: a press makes it the active door, a press on the active door clears it (the host floorplan decides which). |
| key * | String | — | Identity: what a floorplan's active door carries, and what an import check's `stat` names. |
| label * | String | — | Sentence case, short: "Ready", "Needs a fix". |
| tone | KpiStatTone | KpiStatTone.neutral | The value's paint. KpiStatTone.critical paints it --danger (a count that blocks), KpiStatTone.positive --ok. |
| value * | String | — | Display-formatted by the host: "1,000". The floorplan never computes it. |
RecordsHostUndo support
The host's latest write outside cell editing, with the band's words (`RecordsScreen.d.ts` `RecordsHostUndo`, A HOST WRITE CARRIES ITS UNDO): a new id shows message on the band with "Undo", the table body keeps it in its history, and a ctrl/⌘ Z the surface left unanswered runs it.…
| Field | Type | Default | What it does |
|---|---|---|---|
| id * | Object | — | |
| message * | String | — | The band's message, in the host's words: "Accepted 4 values". |
| onUndo * | VoidCallback | — |
Where it lives
| Class | File |
|---|---|
| ImportScreen | packages/app_widgets/lib/src/floorplans/import_screen.dart |
| AppFileDrop | packages/app_widgets/lib/src/kit/forms/file_drop.dart |