@godxjp/ui 18.9.0 → 18.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/dist/components/data-display/badge.d.ts +7 -0
- package/dist/components/data-display/badge.js +1 -1
- package/dist/components/data-display/data-table.js +2 -2
- package/dist/components/data-display/index.d.ts +2 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/permission-matrix.d.ts +26 -0
- package/dist/components/data-display/permission-matrix.js +219 -0
- package/dist/components/data-display/table.d.ts +12 -0
- package/dist/components/data-entry/branch-scope-picker.d.ts +43 -0
- package/dist/components/data-entry/branch-scope-picker.js +200 -0
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/select.d.ts +7 -1
- package/dist/components/data-entry/select.js +46 -26
- package/dist/components/feedback/alert.d.ts +2 -20
- package/dist/components/feedback/alert.js +1 -11
- package/dist/components/feedback/banner.d.ts +21 -0
- package/dist/components/feedback/banner.js +19 -0
- package/dist/components/feedback/index.d.ts +4 -2
- package/dist/components/feedback/index.js +2 -2
- package/dist/components/general/typography.d.ts +1 -0
- package/dist/components/general/typography.js +32 -13
- package/dist/components/layout/auth-shell.d.ts +2 -2
- package/dist/components/layout/index.d.ts +2 -2
- package/dist/components/layout/index.js +2 -2
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +61 -15
- package/dist/components/layout/resizable.d.ts +1 -1
- package/dist/components/layout/resizable.js +26 -8
- package/dist/components/layout/service-role-panel.d.ts +25 -0
- package/dist/components/layout/service-role-panel.js +206 -0
- package/dist/components/navigation/filter-bar.d.ts +2 -2
- package/dist/components/navigation/filter-bar.js +113 -34
- package/dist/components/navigation/index.d.ts +1 -1
- package/dist/components/navigation/pagination.js +20 -1
- package/dist/components/navigation/tabs.js +6 -1
- package/dist/i18n/messages/en.json +59 -4
- package/dist/i18n/messages/ja.json +54 -5
- package/dist/i18n/messages/vi.json +53 -4
- package/dist/lib/field-a11y.d.ts +7 -0
- package/dist/lib/field-a11y.js +6 -0
- package/dist/lib/hooks.d.ts +15 -0
- package/dist/lib/hooks.js +37 -0
- package/dist/props/components/data-display.prop.d.ts +66 -0
- package/dist/props/components/data-entry.prop.d.ts +54 -0
- package/dist/props/components/feedback.prop.d.ts +3 -3
- package/dist/props/components/general.prop.d.ts +8 -1
- package/dist/props/components/layout.prop.d.ts +80 -51
- package/dist/props/components/navigation.prop.d.ts +77 -50
- package/dist/props/registry.d.ts +274 -54
- package/dist/props/registry.js +362 -73
- package/dist/props/vocabulary/content.prop.d.ts +5 -0
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +4 -7
- package/dist/props/vocabulary/layout.prop.d.ts +2 -2
- package/dist/styles/alert-layout.css +15 -32
- package/dist/styles/badge-layout.css +5 -0
- package/dist/styles/control.css +5 -0
- package/dist/styles/layout.css +118 -108
- package/dist/styles/shell-layout.css +16 -7
- package/dist/styles/table-layout.css +92 -2
- package/dist/styles/text-layout.css +13 -0
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/badge.css +5 -0
- package/dist/tokens/components/banner.css +16 -0
- package/dist/tokens/components/navigation.css +10 -25
- package/dist/tokens/components/shell.css +20 -9
- package/dist/tokens/components/table.css +41 -1
- package/dist/tokens/semantic/layout.css +8 -7
- package/package.json +15 -2
- package/dist/components/layout/page-header.d.ts +0 -22
- package/dist/components/layout/page-header.js +0 -89
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Layout component prop types — @see docs/COMPONENTS.md#layout */
|
|
2
2
|
import type * as React from "react";
|
|
3
3
|
import type { ComponentType, ReactNode, SVGProps } from "react";
|
|
4
|
-
import type { BreadcrumbProp, TitleProp, SubtitleProp, ExtraProp, FooterProp, PageDensityProp, PageContainerVariantProp, CenteredShellWidthProp, CenteredShellAlignProp, CenteredShellPresetProp, ErrorSurfaceModeProp, ErrorSurfaceStatusProp, AuthShellPresetProp, BreakpointProp, GapProp, ClassNameProp, ChildrenProp, IdProp, DisabledProp, DescriptionProp, ActionProp, IconProp, HeadingLevelProp } from "../vocabulary/index.js";
|
|
4
|
+
import type { BreadcrumbProp, TitleProp, SubtitleProp, StatusProp, ExtraProp, FooterProp, PageDensityProp, PageContainerVariantProp, CenteredShellWidthProp, CenteredShellAlignProp, CenteredShellPresetProp, ErrorSurfaceModeProp, ErrorSurfaceStatusProp, AuthShellPresetProp, BreakpointProp, GapProp, ClassNameProp, ChildrenProp, IdProp, DisabledProp, DescriptionProp, ActionProp, IconProp, HeadingLevelProp } from "../vocabulary/index.js";
|
|
5
5
|
import type { EmptyStateToneProp } from "./data-display.prop.js";
|
|
6
6
|
/**
|
|
7
7
|
* Arrangement of the page header's title band and its `extra` slot below the 640px step.
|
|
@@ -24,54 +24,27 @@ export type PageContainerPresetProp = "default" | "admin-collection";
|
|
|
24
24
|
* fluid at the compact gutter.
|
|
25
25
|
*/
|
|
26
26
|
export type PageContainerMeasureProp = "default" | "narrow" | "medium";
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
* mount the SAME token-owned geometry outside a full page shell (a Sheet detail, a MasterDetail
|
|
30
|
-
* pane, a tab body) instead of re-authoring `.ui-page-header` CSS locally (gh#255).
|
|
31
|
-
*/
|
|
32
|
-
export type PageHeaderProp = {
|
|
27
|
+
/** @see PageContainer */
|
|
28
|
+
export type PageContainerProp = {
|
|
33
29
|
title: TitleProp;
|
|
34
30
|
subtitle?: SubtitleProp;
|
|
35
31
|
/**
|
|
36
|
-
* Status
|
|
37
|
-
*
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Override the breadcrumb `<nav>` landmark's accessible name. Defaults to a localized
|
|
45
|
-
* "Breadcrumb". Needed when more than one header (each with its own `breadcrumb`) renders on the
|
|
46
|
-
* same page/view — two `<nav>` landmarks sharing one name/role fail axe's `landmark-unique`
|
|
47
|
-
* (WCAG 2.4.1 / 1.3.1).
|
|
48
|
-
*/
|
|
49
|
-
breadcrumbLabel?: string;
|
|
50
|
-
/** Kebab/DOM-style alias of `breadcrumbLabel` (same landmark-unique override). */
|
|
51
|
-
breadcrumbAriaLabel?: string;
|
|
52
|
-
linkComponent?: React.ElementType;
|
|
53
|
-
/**
|
|
54
|
-
* How the title band and `extra` share the header row below the 640px step. Defaults to
|
|
55
|
-
* `stack`. @see PageContainerHeaderLayoutProp
|
|
32
|
+
* Status/meta band rendered beside the title inside the heading — StatusBadge, environment
|
|
33
|
+
* tag, "updated …" meta text. Geometry is token-owned (`--page-header-status-gap`): the band
|
|
34
|
+
* sits on the title line and WRAPS under it on compact viewports, so a consumer never
|
|
35
|
+
* hand-lays a badge next to an `<h1>`. Part of the canonical page-header contract
|
|
36
|
+
* (godxjp-ui#255): PageContainer's embedded header IS the DXS `PageHeader` — breadcrumbs
|
|
37
|
+
* (`breadcrumb`), title, subtitle, status/meta (this), actions (`extra`) and responsive
|
|
38
|
+
* overflow (`headerLayout` / `measure`) all live on this one renderer.
|
|
56
39
|
*/
|
|
57
|
-
|
|
40
|
+
status?: StatusProp;
|
|
58
41
|
/**
|
|
59
|
-
* Pending state for the title band while the page's own
|
|
60
|
-
* /
|
|
61
|
-
* document with an accessible name (an empty heading is an axe
|
|
62
|
-
* outline never disappears mid-load. Breadcrumbs and `extra`
|
|
63
|
-
* from the route, not the record.
|
|
42
|
+
* Pending state for the title band while the page's own record resolves. Renders the
|
|
43
|
+
* title/subtitle as `ui-skeleton-block` placeholders and marks the header `aria-busy`, keeping
|
|
44
|
+
* the `<h1>` in the document with an sr-only accessible name (an empty heading is an axe
|
|
45
|
+
* violation) so the page's heading outline never disappears mid-load. Breadcrumbs and `extra`
|
|
46
|
+
* are NOT skeletonised — they come from the route, not the record.
|
|
64
47
|
*/
|
|
65
|
-
loading?: boolean;
|
|
66
|
-
className?: ClassNameProp;
|
|
67
|
-
};
|
|
68
|
-
/** @see PageContainer */
|
|
69
|
-
export type PageContainerProp = {
|
|
70
|
-
title: TitleProp;
|
|
71
|
-
subtitle?: SubtitleProp;
|
|
72
|
-
/** Status / meta band rendered inline with the title. @see PageHeaderProp.meta */
|
|
73
|
-
meta?: ReactNode;
|
|
74
|
-
/** Skeletonise the title band while the page record loads. @see PageHeaderProp.loading */
|
|
75
48
|
headerLoading?: boolean;
|
|
76
49
|
extra?: ExtraProp;
|
|
77
50
|
footer?: FooterProp;
|
|
@@ -276,8 +249,8 @@ export type AuthShellProp = {
|
|
|
276
249
|
/**
|
|
277
250
|
* Named flow MEASURE — the page geometry contract for one canonical hosted-identity flow: the
|
|
278
251
|
* auth card's max-width plus the desktop and mobile page gutters, all owned by component tokens
|
|
279
|
-
* (`--auth-shell-{login,device,context,recovery}-*`). Selecting a preset replaces
|
|
280
|
-
* consumer-side geometry override.
|
|
252
|
+
* (`--auth-shell-{login,registration,device,context,recovery}-*`). Selecting a preset replaces
|
|
253
|
+
* every consumer-side geometry override.
|
|
281
254
|
*
|
|
282
255
|
* - `"default"` (default) — the shell's own measure; nothing changes.
|
|
283
256
|
* - `"login"` — SCR-001's 360px card at x=540/332/15 and y=363/363/353 for the canonical
|
|
@@ -286,13 +259,14 @@ export type AuthShellProp = {
|
|
|
286
259
|
* position without truncating or inventing requester data. Pass AuthIdentity, Card and
|
|
287
260
|
* AuthFooter as direct children (an anchor may wrap AuthIdentity).
|
|
288
261
|
* - `"registration"` — the 360px sign-up measure with a 15px inline gutter at 390px (the same
|
|
289
|
-
* page rhythm as `"login"`, so sign-in → sign-up never jumps on a phone).
|
|
290
|
-
*
|
|
291
|
-
*
|
|
262
|
+
* page rhythm as `"login"`, so sign-in → sign-up never jumps on a phone). START-aligned like
|
|
263
|
+
* login, because a registration card is the tallest surface in the hosted-identity set
|
|
264
|
+
* (name · email · password · confirm · strength · consent · submit · providers) and a
|
|
292
265
|
* vertically centred tall card overflows ABOVE the scroll origin on a short viewport, putting
|
|
293
|
-
* its first field out of reach
|
|
294
|
-
* own, so the legal/consent footer never sits
|
|
295
|
-
* password form and the pending-email
|
|
266
|
+
* its first field out of reach — start-aligned, a long form simply scrolls. It is also the
|
|
267
|
+
* only preset with a footer-clearance knob of its own, so the legal/consent footer never sits
|
|
268
|
+
* flush against the submit button. Carries the full password form and the pending-email
|
|
269
|
+
* confirmation state with no consumer geometry CSS.
|
|
296
270
|
* - `"device-authorization"` — 380px card measure with a 5px inline page gutter at a 390px
|
|
297
271
|
* viewport (canonical device-grant artboard).
|
|
298
272
|
* - `"context-selection"` — 25rem card measure on desktop/tablet, edge-to-edge on mobile, and a
|
|
@@ -814,3 +788,58 @@ export type LegalDocumentShellProp = {
|
|
|
814
788
|
id?: IdProp;
|
|
815
789
|
className?: ClassNameProp;
|
|
816
790
|
};
|
|
791
|
+
/** @see ServiceRolePanel — one role in the master rail. Domain data is consumer-supplied. */
|
|
792
|
+
export type ServiceRoleItemProp = {
|
|
793
|
+
/** Stable role id (the selection value). */
|
|
794
|
+
id: string;
|
|
795
|
+
/** Human role name (also used in accessible labels, so a plain string). */
|
|
796
|
+
name: string;
|
|
797
|
+
/** Secondary line under the role name. */
|
|
798
|
+
description?: string;
|
|
799
|
+
/** Member count caption, pluralized via CLDR. */
|
|
800
|
+
memberCount?: number;
|
|
801
|
+
/** A locked (system) role shows a lock badge and never offers deletion. */
|
|
802
|
+
locked?: boolean;
|
|
803
|
+
};
|
|
804
|
+
/** @see ServiceRolePanel */
|
|
805
|
+
export type ServiceRolePanelProp = {
|
|
806
|
+
/** The roles in the master collection, in render order. */
|
|
807
|
+
roles: readonly ServiceRoleItemProp[];
|
|
808
|
+
/** Controlled selected role id. */
|
|
809
|
+
value?: string;
|
|
810
|
+
/** Uncontrolled initial selected role id. Defaults to the first role. */
|
|
811
|
+
defaultValue?: string;
|
|
812
|
+
/** Selection change handler. */
|
|
813
|
+
onValueChange?: (roleId: string) => void;
|
|
814
|
+
/**
|
|
815
|
+
* Detail surface for the current selection. A render function receives the selected role
|
|
816
|
+
* (or `undefined` when nothing is selected); a plain node is rendered as-is.
|
|
817
|
+
*/
|
|
818
|
+
children?: ReactNode | ((role: ServiceRoleItemProp | undefined) => ReactNode);
|
|
819
|
+
/**
|
|
820
|
+
* Confirmed-deletion handler. Its PRESENCE adds a delete affordance per non-locked role behind
|
|
821
|
+
* the built-in destructive `AlertDialog`; the handler fires only AFTER the user confirms.
|
|
822
|
+
*/
|
|
823
|
+
onDeleteRole?: (roleId: string) => void;
|
|
824
|
+
/** Hide every mutating affordance (locked view). */
|
|
825
|
+
readOnly?: boolean;
|
|
826
|
+
/** Show the loading skeleton instead of the panel. Precedence: loading → denied → error → empty. */
|
|
827
|
+
loading?: boolean;
|
|
828
|
+
/** Custom empty content when `roles` is empty; defaults to a localized EmptyState. */
|
|
829
|
+
empty?: ReactNode;
|
|
830
|
+
/** Failure state: `true` = built-in localized message, any other node replaces it. */
|
|
831
|
+
error?: ReactNode;
|
|
832
|
+
/** Permission-denied state — refused, not failed. Takes precedence over `error`. */
|
|
833
|
+
denied?: ReactNode;
|
|
834
|
+
/** Retry handler for the built-in `error` state; omit to hide the retry action. */
|
|
835
|
+
onRetry?: () => void;
|
|
836
|
+
/** Accessible names for the two regions (localized defaults otherwise). */
|
|
837
|
+
masterLabel?: string;
|
|
838
|
+
detailLabel?: string;
|
|
839
|
+
/** Forwarded MasterDetail geometry. */
|
|
840
|
+
railWidth?: MasterDetailRailWidthProp;
|
|
841
|
+
masterViewport?: MasterDetailMasterViewportProp;
|
|
842
|
+
collapseBelow?: BreakpointProp | false;
|
|
843
|
+
id?: IdProp;
|
|
844
|
+
className?: ClassNameProp;
|
|
845
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Navigation component prop types — @see docs/COMPONENTS.md#navigation */
|
|
2
2
|
import type * as React from "react";
|
|
3
|
-
import type { ChildrenProp, ClassNameProp, DisabledProp, HasActiveFiltersProp, IdProp, LabelProp, OnClearFiltersProp, StickyProp } from "../vocabulary/index.js";
|
|
3
|
+
import type { ActionsProp, ChildrenProp, ClassNameProp, DisabledProp, ErrorProp, HasActiveFiltersProp, IdProp, LabelProp, OnClearFiltersProp, PendingProp, PlaceholderProp, StickyProp } from "../vocabulary/index.js";
|
|
4
|
+
import type { SearchSelectOptionProp } from "./data-entry.prop.js";
|
|
4
5
|
/**
|
|
5
6
|
* How a {@link ToolbarProp} strip resolves more filters than fit one row (#216).
|
|
6
7
|
* `wrap` (default) stacks on narrow viewports then wraps onto extra rows; `scroll` keeps ONE
|
|
@@ -8,61 +9,60 @@ import type { ChildrenProp, ClassNameProp, DisabledProp, HasActiveFiltersProp, I
|
|
|
8
9
|
*/
|
|
9
10
|
export type FilterBarOverflowProp = "wrap" | "scroll";
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
* Typed search slot of the FilterBar model (gh#258). Renders the canonical SearchInput as the
|
|
13
|
+
* FIRST control of the strip, with a token-owned consistent width (`--filter-bar-search-width`,
|
|
14
|
+
* full-width below 640px). Controlled by consumer data via the `value`/`defaultValue`/
|
|
15
|
+
* `onValueChange` triad; `onSearch` mirrors SearchInput's debounced-term callback.
|
|
16
|
+
*/
|
|
17
|
+
export type FilterBarSearchProp = {
|
|
18
|
+
value?: string;
|
|
19
|
+
defaultValue?: string;
|
|
20
|
+
/** Fires on EVERY keystroke — required to keep a controlled `value` responsive. */
|
|
21
|
+
onValueChange?: (query: string) => void;
|
|
22
|
+
/** Fires with the DEBOUNCED term. Omit it when filtering is driven off `onValueChange`. */
|
|
23
|
+
onSearch?: (query: string) => void;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
/** Visible label above the search field. Omit for the placeholder-only compact form. */
|
|
26
|
+
label?: React.ReactNode;
|
|
27
|
+
/** Accessible name when no visible `label` is given (defaults to the localized "Search"). */
|
|
28
|
+
ariaLabel?: string;
|
|
29
|
+
id?: IdProp;
|
|
30
|
+
disabled?: DisabledProp;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* One typed filter of the FilterBar model (gh#258): a labelled, domain-neutral Select whose
|
|
34
|
+
* options and selection are consumer data. `value` is the filter's stable identity (never shown);
|
|
35
|
+
* the visible `label` is rendered as the control's real `<label htmlFor>` (WCAG 2.5.3 / 1.3.1).
|
|
36
|
+
* Selection is controlled via `selected`/`defaultSelected`/`onSelectedChange` — the standard
|
|
37
|
+
* triad, renamed so the filter's own identity `value` stays unambiguous.
|
|
38
|
+
*/
|
|
39
|
+
export type FilterBarFilterProp = {
|
|
40
|
+
/** Stable filter identity (drives the control id + React key). */
|
|
41
|
+
value: string;
|
|
42
|
+
label: LabelProp;
|
|
43
|
+
options: SearchSelectOptionProp[];
|
|
44
|
+
selected?: string;
|
|
45
|
+
defaultSelected?: string;
|
|
46
|
+
onSelectedChange?: (selected: string) => void;
|
|
47
|
+
placeholder?: PlaceholderProp;
|
|
48
|
+
disabled?: DisabledProp;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* One applied-filter chip of the FilterBar model (gh#258). Chips are pure consumer data — the
|
|
52
|
+
* lifecycle is: ADD by including the chip in `chips`, REMOVE via `onChipRemove(value)` (the ×
|
|
53
|
+
* button), CLEAR-ALL via the bar's `onClear`. `label` should be a string when possible so the
|
|
54
|
+
* remove button's accessible name can quote it; otherwise `value` is quoted instead.
|
|
17
55
|
*/
|
|
18
56
|
export type FilterBarChipProp = {
|
|
19
|
-
/** Stable identity
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Per-chip removal. Omit for a chip the user cannot lift; the bar then renders no remove control
|
|
25
|
-
* rather than a disabled one, so nothing focusable is dead.
|
|
26
|
-
*/
|
|
27
|
-
onRemove?: () => void;
|
|
57
|
+
/** Stable chip identity, passed to `onChipRemove`. */
|
|
58
|
+
value: string;
|
|
59
|
+
label: React.ReactNode;
|
|
60
|
+
disabled?: DisabledProp;
|
|
28
61
|
};
|
|
29
62
|
/** @see Toolbar */
|
|
30
63
|
export type ToolbarProp = {
|
|
31
64
|
onClear?: OnClearFiltersProp;
|
|
32
65
|
hasActiveFilters?: HasActiveFiltersProp;
|
|
33
|
-
/**
|
|
34
|
-
* The search control (#258). A slot, not a rendered input: the bar owns its MEASURE
|
|
35
|
-
* (`--filter-bar-search-width`) and its position at the START of the row, while the caller
|
|
36
|
-
* still chooses the real primitive (`SearchInput`, or a `Select showSearch` for scoped search)
|
|
37
|
-
* and owns its debounce and value. Passing the control as a child instead is what produced the
|
|
38
|
-
* inconsistent search widths the issue was filed against.
|
|
39
|
-
*/
|
|
40
|
-
search?: ChildrenProp;
|
|
41
|
-
/**
|
|
42
|
-
* Applied filters as removable chips (#258). The bar owns the CHIP LIFECYCLE — chips render
|
|
43
|
-
* below the control row, each with an accessible remove control, and the row disappears entirely
|
|
44
|
-
* when the array is empty (never an empty reserved strip). It owns no state: removing a chip
|
|
45
|
-
* calls back and the caller re-renders the array.
|
|
46
|
-
*/
|
|
47
|
-
chips?: readonly FilterBarChipProp[];
|
|
48
|
-
/**
|
|
49
|
-
* Called with the chip's `id` when its remove control is activated. Fires in addition to that
|
|
50
|
-
* chip's own `onRemove`, so a caller may handle removal per chip, centrally, or both.
|
|
51
|
-
*/
|
|
52
|
-
onChipRemove?: (id: string) => void;
|
|
53
|
-
/**
|
|
54
|
-
* Number of records the current filters resolve to (#258). Rendered in a POLITE LIVE REGION and
|
|
55
|
-
* formatted with `Intl.NumberFormat` + CLDR plurals for the active locale — which is the point:
|
|
56
|
-
* a sighted user sees the table change, and this is what tells everyone else that filtering
|
|
57
|
-
* happened. Omit when the count is unknown or still loading.
|
|
58
|
-
*/
|
|
59
|
-
resultCount?: number;
|
|
60
|
-
/**
|
|
61
|
-
* Trailing action region (#258) — export, column settings, a saved-view menu. Rendered AFTER the
|
|
62
|
-
* reset control, so "clear filters" never sits at the end of the row beside an unrelated primary
|
|
63
|
-
* action. The bar owns the ordering; the caller owns the controls.
|
|
64
|
-
*/
|
|
65
|
-
actions?: ChildrenProp;
|
|
66
66
|
/**
|
|
67
67
|
* Pin the strip to the top of its scroll container while the list scrolls beneath it
|
|
68
68
|
* (list-page filter bars, #197). Opt-in — default `false` keeps the toolbar quiet. Tune
|
|
@@ -76,8 +76,35 @@ export type ToolbarProp = {
|
|
|
76
76
|
* Tune the scrollbar gutter with the `--filter-bar-scroll-padding-y` theme knob.
|
|
77
77
|
*/
|
|
78
78
|
overflow?: FilterBarOverflowProp;
|
|
79
|
+
/**
|
|
80
|
+
* Typed model (gh#258) — search slot. When ANY model prop (`search`/`filters`/`chips`/
|
|
81
|
+
* `onChipRemove`/`actions`/`resultCount`/`loading`/`disabled`/`error`) is present the bar renders
|
|
82
|
+
* the canonical model layout: strip (search → filters → children → reset → actions) → chips row →
|
|
83
|
+
* result-count/error line, with token-owned widths and stacking. Without any of them the bar
|
|
84
|
+
* stays the plain children-composition toolbar — existing markup is unchanged.
|
|
85
|
+
*/
|
|
86
|
+
search?: FilterBarSearchProp;
|
|
87
|
+
/** Typed model — labelled Select filters rendered after the search slot, in array order. */
|
|
88
|
+
filters?: FilterBarFilterProp[];
|
|
89
|
+
/** Typed model — applied-filter chips (consumer data; add = include, remove = `onChipRemove`). */
|
|
90
|
+
chips?: FilterBarChipProp[];
|
|
91
|
+
/** Remove ONE chip by its `value`. Required for chips to render their × remove button. */
|
|
92
|
+
onChipRemove?: (value: string) => void;
|
|
93
|
+
/** Typed model — trailing action slot (e.g. a primary "Add" Button), parked at the inline end. */
|
|
94
|
+
actions?: ActionsProp;
|
|
95
|
+
/**
|
|
96
|
+
* Typed model — localized, pluralized result count ("{count} results") announced politely via a
|
|
97
|
+
* `role="status"` line under the strip. `0` is the rendered empty state, not "hidden".
|
|
98
|
+
*/
|
|
99
|
+
resultCount?: number;
|
|
100
|
+
/** Typed model — marks the strip `aria-busy` while results are being (re)fetched. */
|
|
101
|
+
loading?: PendingProp;
|
|
102
|
+
/** Typed model — disables every model-rendered control (search, filters, reset, chip removes). */
|
|
103
|
+
disabled?: DisabledProp;
|
|
104
|
+
/** Typed model — consumer error content, announced via `role="alert"` in place of the count. */
|
|
105
|
+
error?: ErrorProp;
|
|
79
106
|
className?: ClassNameProp;
|
|
80
|
-
children
|
|
107
|
+
children?: ChildrenProp;
|
|
81
108
|
};
|
|
82
109
|
/** @see ToolbarGroup */
|
|
83
110
|
export type ToolbarGroupProp = {
|