Actions
Everything you press. Three button variants, three tones, the icon button, the split button, the FAB, and the two assembled action tiers — side by side, which is the only way the differences are a choice rather than a guess.
Spec of record: design-system/components/actions/Button.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.
Every specimen at once, in one state. Per-specimen controls would rebuild the wall a board exists to remove.
Dart for these values
family_actions() 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.
AppButton widget
The design-system Button — a themed, token-driven pressable claiming the M3 common-button archetype. Three variants (`slab` / `outline` / `ghost`), all fully flat per the constitution — uniform hairline outline or solid fill; the press cue is the content translating down 1 px.
Full dartdoc
The design-system Button — a themed, token-driven pressable claiming the M3 common-button archetype. Three variants (`slab` / `outline` / `ghost`), all fully flat per the constitution — uniform hairline outline or solid fill; the press cue is the content translating down 1 px. State contract (all honored): enabled · hover (bg/border shift, pointer enhancement only) · focus-visible (1 px solid accent border, zero offset) · pressed (1 px translateY) · disabled (onPressed null → DesignTokens.ink40 foreground, not tappable) · error (via `tone: danger`). No ripple. The tap target is always at least DesignTokens.touch (44 logical px) even when the visual height (DesignTokens.ctl) is smaller, and honors reduced motion (durations are zeroed by DesignTokens.reducedMotion). ```dart AppButton(variant: AppButtonVariant.slab, label: 'New', onPressed: create) AppButton( variant: AppButtonVariant.outline, tone: AppButtonTone.accent, count: 3, icon: KitIcon(KitGlyph.filter), label: 'Filter', onPressed: openFilters, ) ```
AppButtondefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| applied | bool | false | The APPLIED-BUT-CLOSED toggle treatment, as a tint — the labeled view-options control resting beside the app bar's search field (`AppBar.d.ts` THE BAR SHARES THE WORKSPACE'S EDGES: "the --accent-tint fill with an --accent border and --accent text and count"). On the `outline` variant it paints… |
| child | Widget? | null | Button text as a widget, for callers needing richer content than label. Mutually exclusive with label. |
| count | Object? | null | Optional count badge rendered after the label in the data font (DesignTokens.dataS) — the applied-filter-count pattern. Accepts an `int` or a `String`. |
| icon | Widget? | null | Optional leading icon (~16 px, painted in the current foreground via IconTheme). Renders at the start edge (direction-agnostic). |
| label | String? | null | Button text as a plain string (a verb or verb+noun). Mutually exclusive with child; styled as DesignTokens.bodyEm. |
| navigates | bool | false | THE ACTION THAT ONLY OPENS A PAGE (`ActionStrip.d.ts`, steady-core #1673): pressing it only opens another screen and writes nothing, so the button's node also reports a link. No paint or gesture change. Defaults to false. |
| onPressed | VoidCallback? | null | Tap callback. Null disables the button (not tappable, muted foreground). |
| stretch | bool | false | When true the button fills its parent's available width (content stays centered) — the full-width form-submit posture. Defaults to false: the button hugs its intrinsic content width. Requires a bounded-width parent. |
| title | String? | null | Tooltip and accessibility hint. Wraps the button in a Tooltip and feeds the Semantics label. Null speaks what the button SHOWS — the label and, when set, the count after it (label-in-name: a control reading "Filter 2" is announced "Filter 2", never a different string). |
| tone | AppButtonTone neutral · accent · danger | AppButtonTone.neutral | Paint intent for `outline` / `ghost` (ignored by `slab`). |
| variant | AppButtonVariant slab · outline · ghost | AppButtonVariant.ghost | Paint archetype — `slab` / `outline` / `ghost`. Defaults to `ghost`; promote the one primary action per surface to `slab`. |
AppIconButton widget
The design-system IconButton — a themed, token-driven, icon-only pressable claiming the M3 icon-button archetype. Square, sized to DesignTokens.ctl (density), rounded to DesignTokens.rS.
Full dartdoc
The design-system IconButton — a themed, token-driven, icon-only pressable claiming the M3 icon-button archetype. Square, sized to DesignTokens.ctl (density), rounded to DesignTokens.rS. Fully flat in every variant, like every pressable in the system. title is **mandatory**: the icon is the entire visible label, so title feeds both the kit AppTooltip (on hover and keyboard focus, `IconButton.d.ts` THE TITLE IS THE NAME AND THE TOOLTIP, #1896) and the Semantics label. State contract (all honored): enabled · hover (DesignTokens.ink4 wash, pointer enhancement only; a ghost control ON THE GROUND — the app bar's — washes with DesignTokens.groundHover instead, `AppBar.d.ts` THE BAR SHARES THE WORKSPACE'S EDGES) · focus-visible (1px solid accent, zero offset) · pressed (1px translateY) · active (solid DesignTokens.accent background + DesignTokens.onAccent foreground — the open-panel/open-mode toggle state) · disabled (onPressed null → DesignTokens.ink40 foreground, not tappable). No ripple. Focused, Enter or Space presses it. The tap target is always at least DesignTokens.touch (44 logical px) even when the visual box (DesignTokens.ctl) is smaller, and honors reduced motion (durations are zeroed by DesignTokens.reducedMotion). ```dart AppIconButton(glyph: KitGlyph.menu, title: 'Menu', onPressed: openNav) AppIconButton( glyph: KitGlyph.filter, title: 'Filter', active: panelOpen, onPressed: toggleFilters, ) AppIconButton( glyph: KitGlyph.sync, title: 'Sync 3 changes', variant: AppIconButtonVariant.outline, badge: 3, onPressed: syncNow, ) ```
AppIconButtondefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| active | bool | false | Solid-accent open-toggle state: true while the control's owned panel/mode is open. Paints DesignTokens.accent background + DesignTokens.onAccent foreground regardless of variant. |
| applied | bool | false | Applied-but-closed state (IconButton.d.ts `applied`) — the Button accent-outline grammar on the icon form: DesignTokens.paper fill, accent border, accent icon, and the corner badge renders accent. The view-control state ("2 filters applied, panel closed"). active wins while the panel is open. |
| badge | int? | null | Corner count badge (e.g. unsynced-change count). Null or zero hides it; otherwise renders in the data font (DesignTokens.dataS) on DesignTokens.danger — or DesignTokens.accent while applied or active (the view-control count). |
| checked | bool | false | The radio's checked state, read only under AppIconButtonRole.radio (ignored for a button). A host also sets active on the checked option: the role never changes the paint. |
| expanded | bool? | null | Disclosure state for assistive tech — the control owns a popover/menu and reports whether it is open (`expanded: open` from a menu trigger builder). Null omits the expanded flag entirely. Lives HERE because the button is its own semantics container: an ancestor `Semantics(expanded:)` wrapper can no… |
| focusNode | FocusNode? | null | The control's focus node, for a composite host that moves focus itself (THE ROVING STOP — the toolbar focuses the next control through it and listens to it to move its one tab stop). Owned by the caller. Null: the control keeps a node of its own. |
| glyph | KitIconRef? | null | The design-system stroke glyph (16px, painted in the current foreground via IconTheme). Wins over icon when both are set. |
| glyphTurns | double | 0 | Rotates the GLYPH (in quarter-turns) inside the stationary control — the disclosure idiom (the table's row-expand affordance turns its Open mark a quarter turn). Only the mark rotates: the focus ring, hit target, and pressed translate stay upright, per the state contract. Animates over… |
| icon | IconData? | null | A Material glyph, for a consumer that has not moved to glyph yet. |
| navigates | bool | false | THE ACTION THAT ONLY OPENS A PAGE (`ActionStrip.d.ts`, steady-core #1673): pressing it only opens another screen and writes nothing, so the control's node also reports a link. Ignored under AppIconButtonRole.radio. No paint or gesture change. |
| onPressed | VoidCallback? | null | Tap callback. Null disables the button (not tappable, muted foreground). |
| pressed | bool? | null | THE TOGGLE (`IconButton.d.ts`, 2026-10-31): the control is a toggle button in this state, reported as `Semantics(toggled:)` on its one node. The paint stays the host's active / applied. Null (the default): no toggled state. |
| role | AppIconButtonRole button · radio | AppIconButtonRole.button | The accessible role (IconButton.d.ts THE RADIO ROLE). AppIconButtonRole.radio reports a radio with checked as its state, in a group the host owns; the default reports a button. |
| skipTraversal | bool | false | THE ROVING STOP — the spec's `tabIndex: -1`: true takes the control out of the Tab order (Focus.skipTraversal) while leaving it focusable by the pointer and by its host (through focusNode). A composite host that moves focus with the arrow keys sets it on every control but its one stop. False (the… |
| title * | String | — | Mandatory tooltip + Semantics label — the icon is the only visible content, so this is the control's entire accessible name. |
| variant | AppIconButtonVariant ghost · outline | AppIconButtonVariant.ghost | Paint archetype — `ghost` (default) or `outline`. |
AppFab widget
The design-system Fab — a themed, token-driven floating action button claiming the M3 FAB archetype. The surface's single accent slab, floating in the thumb zone (host positions it, typically via `Scaffold.floatingActionButton`).
Full dartdoc
The design-system Fab — a themed, token-driven floating action button claiming the M3 FAB archetype. The surface's single accent slab, floating in the thumb zone (host positions it, typically via `Scaffold.floatingActionButton`). Compact: **56 square** (DesignTokens.accent bg, DesignTokens.onAccent fg, icon centered, radius DesignTokens.rS, no Material elevation — it pops at DesignTokens.sh3, the level of a surface over content, while enabled). The extended variant carries a verb label beside the icon (height 48) — use on list screens where the verb matters ("New record"); plain (compact) when space is tight. Wraps the already-themed FloatingActionButton / `.extended` (`floatingActionButtonTheme` in `app_theme.dart` supplies bg/fg/shape/ elevation) and adds the flat state contract stock M3 can't express: hover (subtle accent lighten via the button's own overlay), focus-visible (1px solid accent ring, zero offset), pressed (1px translateY — no ripple, no elevation bump). State contract (all honored): enabled · hover (pointer enhancement only) · focus-visible (1px solid accent ring) · pressed (1px translateY) · disabled (onPressed null → DesignTokens.ink4 bg / DesignTokens.ink40 fg, not tappable). No ripple. One FAB per screen; it IS the surface's accent slab — don't add another (constitution: "one accent slab per surface"). ```dart AppFab(glyph: KitGlyph.plus, tooltip: 'New record', onPressed: create) AppFab( glyph: KitGlyph.plus, label: 'New record', extended: true, onPressed: create, ) ```
AppFabdefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| badge | int? | null | Danger corner count (`Fab.d.ts` `badge`) — the data-font count pill on the FAB's top-end corner, the same anatomy as `AppNavItem.badge`. Null or 0 renders no badge. Paint-only, like the nav badge: the FAB's tooltip stays the accessible name. |
| count | int? | null | THE COUNT (`Fab.d.ts`, 2026-10-14, #1413): how many things the verb will act on, after the label of the EXTENDED posture ("Save revision 4") — a data-role figure at the regular weight on a plate of the Fab's own foreground at 18% over its fill, DesignTokens.rXs, 6 inline padding, one gap after the… |
| extended | bool | false | True renders the Extended FAB (48px tall, icon + label); false (the default) renders the compact 56-square slab. |
| glyph | KitIconRef? | null | The design-system stroke glyph (~20-22px, painted in the current foreground). Wins over icon when both are set. |
| heroTag | Object? | null | Hero tag for the cross-route FAB flight. **Null (the default) means no Hero at all** — deliberately not Material's shared `_defaultHeroTag`. That default tag is the same object for every stock FAB, so two FABs simultaneously mounted under one route — routine in `AppScaffold`, whose destinations stay… |
| icon | IconData? | null | A Material glyph, for a consumer that has not moved to glyph yet. |
| label | String? | null | The verb label carried beside the icon when extended is true (e.g. "New record"). Ignored (and not required) when extended is false. |
| navigates | bool | false | THE ACTION THAT ONLY OPENS A PAGE (`ActionStrip.d.ts`, #1744): pressing the FAB pushes another screen and writes nothing. Reported to assistive technology as a link (`Semantics(link: true)`) on the button; nothing else moves. Declared by the caller, never inferred from onPressed. |
| onPressed | VoidCallback? | null | Tap callback. Null disables the FAB (not tappable, muted paint). |
| tooltip * | String | — | Mandatory tooltip + Semantics label fallback — the icon is the compact form's only visible content. |
AppFabCluster widget
The design-system FabCluster — a speed-dial / M3 FAB menu claiming the FAB archetype's cluster mode. The compact-class home for swapped toolbar actions (constitution: "primary actions leave the app bar for a floating action cluster in the thumb zone (compact)").
Full dartdoc
The design-system FabCluster — a speed-dial / M3 FAB menu claiming the FAB archetype's cluster mode. The compact-class home for swapped toolbar actions (constitution: "primary actions leave the app bar for a floating action cluster in the thumb zone (compact)"). A main AppFab that, when tapped, reveals a vertical stack of one-container mini-action pills (icon + AppFabAction.label in a single paper slab, trailing edges aligned per the spec) above it; tapping the main FAB again, tapping a mini-action, or tapping the optional scrim closes it. Expands/collapses with DesignTokens.tMove / DesignTokens.easeIn motion, honoring reduced motion (durations are zeroed by DesignTokens.reducedMotion). An optional full-bleed scrim dims the surface behind the open cluster (the spec leaves this to the host; off by default so callers embedding the cluster inline aren't forced into a `Stack`). ```dart AppFabCluster( glyph: KitGlyph.plus, tooltip: 'Actions', actions: [ AppFabAction(glyph: KitGlyph.sync, label: 'Sync 3 changes', onPressed: sync), AppFabAction(glyph: KitGlyph.export, label: 'Export', onPressed: exportCsv), ], ) ```
AppFabClusterdefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| actions | List<AppFabAction> | const [] | The speed-dial rows revealed above the main FAB when open, in display order (first item renders nearest the main FAB). |
| glyph | KitIconRef? | null | The main FAB's design-system stroke glyph. Wins over icon when both are set. |
| icon | IconData? | null | A Material glyph, for a consumer that has not moved to glyph yet. |
| navigates | bool | false | THE ACTION THAT ONLY OPENS A PAGE (`ActionStrip.d.ts`, `Fab.d.ts`, #1749) for the PLAIN fallback: with empty actions the main FAB is just an AppFab, and pressing onMainPressed pushes another screen. Ignored when actions is non-empty (the main FAB then toggles the speed-dial, which opens nothing;… |
| onMainPressed | VoidCallback? | null | Fires when actions is empty and the main FAB is tapped directly (a plain-FAB fallback — a cluster with no actions is just an AppFab). Ignored when actions is non-empty (tapping the main FAB toggles the speed-dial instead). |
| scrim | bool | false | True dims the surface behind the open cluster with DesignTokens.scrim. Off by default. |
| tooltip * | String | — | Mandatory tooltip + Semantics label for the main FAB. |
AppSplitButton widget
The design-system SplitButton — a themed, token-driven two-segment pressable claiming the M3 split-button archetype. Anatomy (SplitButton.d.ts / .prompt.md): a primary segment (optional leading icon + optional label, firing onPrimary) + a hairline divider + a ▾ menu segment opening an AppMenu-style…
Full dartdoc
The design-system SplitButton — a themed, token-driven two-segment pressable claiming the M3 split-button archetype. Anatomy (SplitButton.d.ts / .prompt.md): a primary segment (optional leading icon + optional label, firing onPrimary) + a hairline divider + a ▾ menu segment opening an AppMenu-style popover of items — all sharing **one continuous outline** (this is the canonical sync/persistence control: "the sync/persistence control is a split button and ALWAYS the last inline-end app-bar action"). Paint mirrors AppButton's `outline` variant: DesignTokens.paper fill and a DesignTokens.btnBorder outline (→ `btnBorderHover` on hover) — fully flat, drawn once at the container level, while each segment tracks its own hover/press/focus independently (only the pressed segment's content depresses). State contract per segment (all honored): enabled · hover (DesignTokens.ink4 wash, pointer enhancement only) · focus-visible (1px solid accent, zero offset) · pressed (1px translateY on that segment's content only) · disabled (DesignTokens.ink40 foreground). Each segment disables independently: onPrimary null disables the primary segment only — the ▾ menu segment stays reachable while items is non-empty (SplitButton.d.ts: segment enablement derives from `onPrimary` / `items`), so menu-only variants (revert, delete) survive a disabled default action. enabled false (the d.ts whole-control `disabled`) forces both segments off regardless of content. No ripple. badge renders a danger-corner count (e.g. unsynced changes) — the same glyph as AppIconButton's badge, positioned at the control's trailing corner. Semantics: two merged nodes — the primary segment reports `button: true` with title (or label) as its label; the menu segment reports `button: true, expanded: <open>` (mirroring AppMenu's own contract) with menuTitle as its label ("more options", expandable). ```dart AppSplitButton( icon: const KitIcon(KitGlyph.sync), label: 'Sync now', title: 'Sync 3 changes', badge: 3, onPrimary: syncNow, items: [ AppSplitButtonItem(label: 'Sync now', onSelected: syncNow), AppSplitButtonItem(label: 'Pull latest only', onSelected: pull), AppSplitButtonItem( label: 'Auto-sync every 15 min', checked: autoSync, onSelected: toggleAuto, ), AppSplitButtonItem( label: 'Sync log', dividerBefore: true, onSelected: showLog, ), ], ) ```
AppSplitButtondefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| badge | int? | null | Danger-corner count badge (e.g. unsynced-change count). Null or zero hides it. |
| enabled | bool | true | Whole-control switch (SplitButton.d.ts `disabled`, inverted to kit convention). False disables **both** segments regardless of onPrimary and items; true (the default) lets each segment derive its own state. |
| icon | Widget? | null | Optional leading icon on the primary segment (~16px, painted in the current foreground via IconTheme). |
| items * | List<AppSplitButtonItem> | — | The menu segment's popover rows, in display order. Empty disables the menu segment. No row may set AppMenuItem.supporting: SplitButton.d.ts grants no supporting line (asserted). |
| label | String? | null | Primary segment text (a verb or verb+noun); omit for an icon-only primary. Styled as DesignTokens.bodyEm, matching AppButton. |
| menuTitle | String | 'More options' | Tooltip + Semantics label for the ▾ menu segment. |
| onPrimary | VoidCallback? | null | Fires when the primary segment is tapped. Null disables the **primary segment only** — the ▾ menu segment stays enabled while items is non-empty, keeping menu variants reachable when the default action is momentarily unavailable (e.g. Save disabled while clean, Revert/Delete still live). |
| title | String? | null | Tooltip + Semantics label for the primary segment. Falls back to label when null. |
AppActionStrip widget
The design-system's kit-native prominent-tier host — the canonical action-tier system rendered on kit widgets, for a view body to compose (under a pinned-facts strip, above the scalar flow, wherever the consumer places it). Reuses the app-agnostic partition pass (`partitionActions`) from…
Full dartdoc
The design-system's kit-native prominent-tier host — the canonical action-tier system rendered on kit widgets, for a view body to compose (under a pinned-facts strip, above the scalar flow, wherever the consumer places it). Reuses the app-agnostic partition pass (`partitionActions`) from `src/action/` — this widget owns paint only, never tier logic: * ActionPlacement.primary leads as one AppButton with `variant: AppButtonVariant.slab` — the surface's one accent slab. A second primary demotes to `prominent` (the demotion rule lives in `partitionActions`, not here). * ActionPlacement.prominent — and ActionPlacement.secondary, tolerated at its nearest hosted tier — render as AppButton with `variant: AppButtonVariant.outline` (the tonal-button equivalent in this kit's paint vocabulary: paper fill + border, never a second slab). * ActionPlacement.overflow and ActionPlacement.inline (which needs an in-content host this strip is not) fold into a trailing `⋮` AppMenu. A destructive action (ActionSpec.isDestructive) paints the danger role on whichever kit widget hosts it — `AppButtonTone.danger` on a slab/ outline button, a `danger: true` AppMenuItem in the overflow menu. Confirmation is never this widget's concern — that stays the consumer's `onInvoke` responsibility (constitution: the action layer is behavior-blind). The strip **wraps, never truncates**, on narrow widths — canon guidance is ≤3 buttons per strip, advisory rather than enforced. Renders nothing when no action is visible. ActionSpec carries the kit's two-channel glyph contract — `glyph:` (a `KitGlyph`, the design-system channel, wins) and `icon:` (a Material `IconData`, the compile-compatible path); the kit hosts render whichever they are handed. `submitIcon` / `duplicateIcon` / `deleteIcon` below stand in for the caller's own glyph constants. ```dart AppActionStrip( actions: [ ActionSpec( label: 'Submit', icon: submitIcon, placement: ActionPlacement.primary, onInvoke: (_) => submit(), ), ActionSpec( label: 'Duplicate', icon: duplicateIcon, placement: ActionPlacement.prominent, onInvoke: (_) => duplicate(), ), ActionSpec( label: 'Delete', icon: deleteIcon, placement: ActionPlacement.overflow, isDestructive: true, onInvoke: (_) => delete(), ), ], ) ```
AppActionStripdefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| actions * | List<ActionSpec> | — | The candidate actions. Each is filtered by ActionSpec.visible and partitioned by ActionSpec.placement at build — see partitionActions. |
AppActionBar widget
The design-system's kit-native app-bar-hosted action tiers — a screen drops this into AppHeaderBar.actions (via `AppHeaderBar(actions: [AppActionBar(actions: ...)])` or by splicing its children directly). Renders ActionPlacement.secondary (and ActionPlacement.prominent, tolerated at its nearest…
Full dartdoc
The design-system's kit-native app-bar-hosted action tiers — a screen drops this into AppHeaderBar.actions (via `AppHeaderBar(actions: [AppActionBar(actions: ...)])` or by splicing its children directly). Renders ActionPlacement.secondary (and ActionPlacement.prominent, tolerated at its nearest hosted tier) as direct AppIconButtons, capped at kAppBarDirectActionCap — extras fold into the trailing `⋮` AppMenu alongside ActionPlacement.overflow and ActionPlacement.inline. ActionPlacement.primary is **not** rendered here — the app-bar tier hosts no accent slab (constitution: one accent slab per surface, and the primary's home is AppActionStrip or a FAB/prominent button a screen composes separately); a primary action passed to this bar folds to the overflow menu rather than silently vanishing. A destructive secondary/prominent renders as a plain AppIconButton — icon-only controls carry no danger tone slot in this kit (see AppIconButtonVariant), so there is no visible danger cue at this tier. A destructive overflow/inline entry does paint the danger role, as a `danger: true` AppMenuItem. Callers needing a visibly-danger direct action should route it to ActionPlacement.overflow instead. ```dart AppHeaderBar( title: 'Inspection', actions: [AppActionBar(actions: actions)], ) ```
AppActionBardefault constructor
| Knob | Type | Default | What it does |
|---|---|---|---|
| actions * | List<ActionSpec> | — | The candidate actions. Each is filtered by ActionSpec.visible and partitioned by ActionSpec.placement at build — see partitionActions. |
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,… |
AppFabAction support
One mini-action in an AppFabCluster's expanded speed-dial. Mirrors `FabClusterAction` (Fab.d.ts): a glyph + label rendered together in a single paper pill (the "one-container action button" the spec calls for — never icon-only), firing onPressed when tapped.
| Field | Type | Default | What it does |
|---|---|---|---|
| enabled | bool | true | Disables the action (DesignTokens.ink40 foreground, not tappable) when false, independent of onPressed. |
| glyph | KitIconRef? | null | The mini-action's leading design-system glyph (16px, painted in the current foreground). Wins over icon when both are set. |
| icon | IconData? | null | A Material glyph, for a consumer that has not moved to glyph yet. |
| label * | String | — | The mini-action's label, rendered in the pill beside the icon. |
| navigates | bool | false | THE ACTION THAT ONLY OPENS A PAGE (`ActionStrip.d.ts`, `Fab.d.ts` cluster, #1749): choosing it pushes another screen and writes nothing. Reported to assistive technology as a link (`Semantics(link: true)`) on the mini-action; nothing else moves. Declared by the caller, never inferred from onPressed. |
| onPressed | VoidCallback? | null | Fires when the mini-action is chosen. The cluster closes first, then this fires. Null (or enabled false) disables the action. |
| tooltip | String? | null | Optional accessibility override; defaults to label. |
KitIconRef support
A glyph, by NAME — what every glyph-bearing kit API takes (a pin, a legend key, a nav item, an action, an empty face, a category card). Two shapes implement it: - a KitGlyph — a glyph in the kit's own name table, checked by the compiler (`KitGlyph.syringe`); - KitIconRef.named — any name as a…
| Field | Type | Default | What it does |
|---|---|---|---|
| name * | String | — |
Where it lives
| Class | File |
|---|---|
| AppButton | packages/app_widgets/lib/src/kit/actions/button.dart |
| AppIconButton | packages/app_widgets/lib/src/kit/actions/icon_button.dart |
| AppFab | packages/app_widgets/lib/src/kit/actions/fab.dart |
| AppFabCluster | packages/app_widgets/lib/src/kit/actions/fab.dart |
| AppSplitButton | packages/app_widgets/lib/src/kit/actions/split_button.dart |
| AppActionStrip | packages/app_widgets/lib/src/kit/actions/action_strip.dart |
| AppActionBar | packages/app_widgets/lib/src/kit/actions/action_strip.dart |