@juwel-development/design-system 3.9.1 → 3.10.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/README.md +9 -298
- package/dist/design-system.js +1026 -582
- package/dist/index.css +1 -1
- package/dist/types/Arrangement/ColumnLayout/ColumnLayout.d.ts +92 -0
- package/dist/types/Arrangement/ColumnLayout/ColumnLayoutCompositionError.d.ts +3 -0
- package/dist/types/Arrangement/ColumnLayout/ColumnLayoutConfigurationError.d.ts +3 -0
- package/dist/types/Arrangement/FieldRow/FieldRow.d.ts +87 -0
- package/dist/types/Arrangement/FieldRow/FieldRowCompositionError.d.ts +3 -0
- package/dist/types/Arrangement/FieldRow/FieldRowConfigurationError.d.ts +3 -0
- package/dist/types/Arrangement/FieldRow/IControlEdge.d.ts +6 -0
- package/dist/types/Arrangement/FieldRow/alignControlEdges.d.ts +7 -0
- package/dist/types/Display/Box/Box.d.ts +41 -0
- package/dist/types/Display/Brandmark/Brandmark.d.ts +1 -1
- package/dist/types/Display/DefinitionList/DefinitionList.d.ts +59 -9
- package/dist/types/Display/DefinitionList/DefinitionListConfigurationError.d.ts +3 -0
- package/dist/types/Display/Figure/Figure.d.ts +2 -2
- package/dist/types/Display/Icon/Icon.d.ts +26 -0
- package/dist/types/Display/Table/Table.d.ts +118 -8
- package/dist/types/Display/Table/TableConfigurationError.d.ts +3 -0
- package/dist/types/Display/Typography/Eyebrow/Eyebrow.d.ts +1 -1
- package/dist/types/Display/Typography/H1/H1.d.ts +3 -2
- package/dist/types/Display/Typography/H2/H2.d.ts +3 -2
- package/dist/types/Display/Typography/H3/H3.d.ts +3 -2
- package/dist/types/Display/Typography/H4/H4.d.ts +3 -2
- package/dist/types/Display/Typography/H5/H5.d.ts +3 -2
- package/dist/types/Display/Typography/H6/H6.d.ts +3 -2
- package/dist/types/Display/Typography/Note/Note.d.ts +1 -1
- package/dist/types/Display/Typography/P/P.d.ts +3 -2
- package/dist/types/Display/Typography/Prose/Prose.d.ts +1 -1
- package/dist/types/Interaction/Button/Button.d.ts +23 -3
- package/dist/types/Interaction/Tabs/Tabs.d.ts +31 -6
- package/dist/types/Layout/Header/Header.d.ts +67 -8
- package/dist/types/Layout/ScrollContainer/ScrollContainer.d.ts +37 -0
- package/dist/types/Layout/Section/Section.d.ts +1 -1
- package/dist/types/Layout/Sidebar/Sidebar.d.ts +4 -0
- package/dist/types/Theme/Palette.d.ts +31 -7
- package/dist/types/index.d.ts +6 -0
- package/package.json +1 -1
- package/src/Arrangement/ColumnLayout/ColumnLayout.tsx +249 -0
- package/src/Arrangement/ColumnLayout/ColumnLayoutCompositionError.ts +8 -0
- package/src/Arrangement/ColumnLayout/ColumnLayoutConfigurationError.ts +6 -0
- package/src/Arrangement/FieldRow/FieldRow.tsx +313 -0
- package/src/Arrangement/FieldRow/FieldRowCompositionError.ts +6 -0
- package/src/Arrangement/FieldRow/FieldRowConfigurationError.ts +6 -0
- package/src/Arrangement/FieldRow/IControlEdge.ts +6 -0
- package/src/Arrangement/FieldRow/alignControlEdges.ts +35 -0
- package/src/Display/Box/Box.tsx +77 -0
- package/src/Display/Checklist/Checklist.tsx +1 -1
- package/src/Display/DefinitionList/DefinitionList.tsx +164 -22
- package/src/Display/DefinitionList/DefinitionListConfigurationError.ts +6 -0
- package/src/Display/Icon/Icon.tsx +63 -0
- package/src/Display/Table/Table.tsx +434 -44
- package/src/Display/Table/TableConfigurationError.ts +6 -0
- package/src/Display/Typography/H1/H1.tsx +3 -2
- package/src/Display/Typography/H2/H2.tsx +3 -2
- package/src/Display/Typography/H3/H3.tsx +3 -2
- package/src/Display/Typography/H4/H4.tsx +3 -2
- package/src/Display/Typography/H5/H5.tsx +3 -2
- package/src/Display/Typography/H6/H6.tsx +3 -2
- package/src/Display/Typography/P/P.tsx +3 -2
- package/src/Display/Typography/Prose/Prose.tsx +3 -3
- package/src/Interaction/Button/Button.tsx +45 -17
- package/src/Interaction/Input/Input.tsx +1 -1
- package/src/Interaction/MultiSelect/MultiSelect.tsx +1 -1
- package/src/Interaction/NumberInput/NumberInput.tsx +1 -1
- package/src/Interaction/Select/Select.tsx +1 -1
- package/src/Interaction/Tabs/Tabs.tsx +38 -11
- package/src/Interaction/TextArea/TextArea.tsx +1 -1
- package/src/Layout/Dialog/Dialog.tsx +4 -3
- package/src/Layout/Header/Header.tsx +139 -39
- package/src/Layout/PageHead/PageHead.tsx +6 -5
- package/src/Layout/ScrollContainer/ScrollContainer.tsx +149 -0
- package/src/Layout/Sidebar/Sidebar.tsx +8 -4
- package/src/Theme/Palette.ts +37 -9
- package/src/Theme/renderTokens.ts +101 -5
- package/src/index.ts +6 -0
- package/src/tokens.css +68 -4
- package/src/tokens.dark.css +66 -4
- package/src/tokens.light.css +64 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const figure: (props?: ({
|
|
4
|
-
ratio?: "
|
|
5
|
-
focus?: "center" | "
|
|
4
|
+
ratio?: "square" | "portrait" | "landscape" | "wide" | null | undefined;
|
|
5
|
+
focus?: "center" | "left" | "right" | "bottom" | "top" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
export interface IFigureProps extends VariantProps<typeof figure> {
|
|
8
8
|
/** The image source. Produce it through the consuming build's image pipeline - see @UXGuidelines. */
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FunctionComponent } from 'react';
|
|
2
|
+
declare const drawings: {
|
|
3
|
+
readonly sort: readonly ["M5.5 13V3", "M3 5.5l2.5-2.5L8 5.5", "M10.5 3v10", "M8 10.5l2.5 2.5 2.5-2.5"];
|
|
4
|
+
readonly 'sort-ascending': readonly ["M8 13V3", "M4 7l4-4 4 4"];
|
|
5
|
+
readonly 'sort-descending': readonly ["M8 3v10", "M4 9l4 4 4-4"];
|
|
6
|
+
};
|
|
7
|
+
export interface IIconProps {
|
|
8
|
+
/** Which drawing. A name selects a shape, never a state or a behaviour. */
|
|
9
|
+
name: keyof typeof drawings;
|
|
10
|
+
testId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A reusable visual glyph: the three sort indicators a consumer composes inside a header cell's
|
|
14
|
+
* plain Button, or beside any text that names what the icon reinforces.
|
|
15
|
+
*
|
|
16
|
+
* @Guarantees — enforced on every render
|
|
17
|
+
* - Hidden from assistive technology and out of the tab order: it adds no stop and no spoken name.
|
|
18
|
+
* - Scales with the surrounding font-size and takes the surrounding text colour.
|
|
19
|
+
* - The three drawings differ in shape, so the ordering is never carried by colour alone.
|
|
20
|
+
*
|
|
21
|
+
* @CallerMustEnsure
|
|
22
|
+
* - The control or text beside it carries the meaning: a `Button` label, a header cell's `ariaSort`.
|
|
23
|
+
* An icon standing alone says nothing to a screen reader.
|
|
24
|
+
*/
|
|
25
|
+
export declare const Icon: FunctionComponent<IIconProps>;
|
|
26
|
+
export {};
|
|
@@ -1,33 +1,78 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
|
-
import type
|
|
2
|
+
import { type FunctionComponent, type ReactNode } from 'react';
|
|
3
|
+
import type { Observable, Subject } from 'rxjs';
|
|
4
|
+
declare const table: (props?: ({
|
|
5
|
+
density?: "compact" | "comfortable" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
3
7
|
declare const tableCell: (props?: ({
|
|
4
|
-
variant?: "
|
|
8
|
+
variant?: "value" | "note" | null | undefined;
|
|
5
9
|
align?: "center" | "left" | "right" | null | undefined;
|
|
6
10
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
11
|
declare const tableHeaderCell: (props?: ({
|
|
8
12
|
align?: "center" | "left" | "right" | null | undefined;
|
|
9
13
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
10
|
-
|
|
14
|
+
/** The width roles a column may take, as its fixed width or as a floor. Each names a column job the
|
|
15
|
+
* consumer specification attests - the subject's name, a short comparison fact, a tabular figure
|
|
16
|
+
* with its unit, one action control - and is read from the theme as `--table-column-<role>`. */
|
|
17
|
+
type TableColumnWidthRole = 'name' | 'fact' | 'figure' | 'action';
|
|
18
|
+
/**
|
|
19
|
+
* One column's allocation of a table's width, independent of the rows currently displayed: either
|
|
20
|
+
* fixed at a named width role, or a positive share of the width the fixed columns leave, with an
|
|
21
|
+
* optional named minimum as its floor. Declared once on `Table.Root`, in cell order.
|
|
22
|
+
*/
|
|
23
|
+
export type TableColumnAllocation = {
|
|
24
|
+
/** The role whose width this column takes exactly, at any available width. */
|
|
25
|
+
readonly width: TableColumnWidthRole;
|
|
26
|
+
readonly weight?: never;
|
|
27
|
+
/** A floor: a `width` smaller than its minimum resolves to the minimum. */
|
|
28
|
+
readonly minWidth?: TableColumnWidthRole;
|
|
29
|
+
} | {
|
|
30
|
+
/** This column's share of the width the fixed columns leave, relative to its siblings' weights:
|
|
31
|
+
* a positive finite number. `3` beside `1` is three quarters and one quarter of it. */
|
|
32
|
+
readonly weight: number;
|
|
33
|
+
readonly width?: never;
|
|
34
|
+
/** The least this column takes. While a minimum holds a column, the other proportional columns
|
|
35
|
+
* share what is left; with none, the share may shrink to nothing. */
|
|
36
|
+
readonly minWidth?: TableColumnWidthRole;
|
|
37
|
+
};
|
|
38
|
+
export interface ITableRootProps extends VariantProps<typeof table> {
|
|
11
39
|
/** The table's accessible name. Rendered as the first child; always present. */
|
|
12
40
|
caption: string;
|
|
13
41
|
/** What the note column is. Governs narrow-viewport behaviour; omit when there is none. */
|
|
14
42
|
notes?: 'supplementary' | 'content';
|
|
43
|
+
/** The columns' allocations, in the order the cells of every row are written. Omit it and widths
|
|
44
|
+
* follow content as before; declare it and every row shares one allocation the rows' content
|
|
45
|
+
* cannot move, and the narrow-viewport `notes` behaviour is replaced by residual scrolling. */
|
|
46
|
+
columns?: readonly TableColumnAllocation[];
|
|
15
47
|
children?: ReactNode;
|
|
16
48
|
testId?: string;
|
|
17
49
|
}
|
|
18
|
-
interface ITableSectionProps {
|
|
50
|
+
export interface ITableSectionProps {
|
|
19
51
|
children?: ReactNode;
|
|
20
52
|
}
|
|
21
|
-
interface ITableRowProps {
|
|
53
|
+
export interface ITableRowProps {
|
|
22
54
|
children?: ReactNode;
|
|
23
55
|
testId?: string;
|
|
56
|
+
/** Emits once per activation of the row body - a click, or Enter or Space while the row has
|
|
57
|
+
* focus. Its presence is what makes the row interactive: a tab stop, a visible focus ring and a
|
|
58
|
+
* pointer cursor. Nested links and controls keep their own operations and never emit here.
|
|
59
|
+
* Activation changes nothing about the row; the consumer decides what the request means. */
|
|
60
|
+
onClick$?: Subject<void>;
|
|
61
|
+
/** The consumer's selection for this row. Rendered as `aria-selected` and the marker bar; omitted
|
|
62
|
+
* or not yet emitted means unselected. Selection is independent of `onClick$`: a selected row
|
|
63
|
+
* may be noninteractive, and an interactive row may be unselected. */
|
|
64
|
+
isSelected$?: Observable<boolean>;
|
|
24
65
|
}
|
|
25
|
-
interface ITableCellProps extends VariantProps<typeof tableCell> {
|
|
66
|
+
export interface ITableCellProps extends VariantProps<typeof tableCell> {
|
|
26
67
|
children?: ReactNode;
|
|
27
68
|
}
|
|
28
|
-
interface ITableHeaderCellProps extends VariantProps<typeof tableHeaderCell> {
|
|
69
|
+
export interface ITableHeaderCellProps extends VariantProps<typeof tableHeaderCell> {
|
|
29
70
|
/** Explicit, never inferred from Head/Body position - inference would need render-time context. */
|
|
30
71
|
scope: 'row' | 'col';
|
|
72
|
+
/** The order the column is *currently* displayed in, as accessibility metadata only. Omit it on a
|
|
73
|
+
* column that is not sortable; set it on the one ordered column. Changing it neither reorders rows
|
|
74
|
+
* nor triggers anything - the consumer owns the sort and composes the action in `children`. */
|
|
75
|
+
ariaSort?: 'none' | 'ascending' | 'descending' | 'other';
|
|
31
76
|
children?: ReactNode;
|
|
32
77
|
}
|
|
33
78
|
/**
|
|
@@ -41,9 +86,74 @@ interface ITableHeaderCellProps extends VariantProps<typeof tableHeaderCell> {
|
|
|
41
86
|
* - The block reads as a table from two rule weights alone: the heavier `rule` above the first row,
|
|
42
87
|
* `border` hairlines between rows, and no bottom rule on the last. No cell borders, fill, zebra or hover.
|
|
43
88
|
* - `Cell variant="value"` sets tabular figures; `variant="note"` does not. Both at the 15px small role.
|
|
44
|
-
* - `HeaderCell` emits the `scope` it is given; none is inferred.
|
|
89
|
+
* - `HeaderCell` emits the `scope` it is given; none is inferred. It emits `ariaSort` the same way:
|
|
90
|
+
* the attribute states the displayed order and the component never orders, cycles or requests one.
|
|
91
|
+
* - Residual horizontal overflow scrolls in every `notes` mode, with no opt-in. The wrapper is
|
|
92
|
+
* keyboard-reachable while there is something to scroll - always, as a named region, with no note
|
|
93
|
+
* column; as a named group only once the table overflows, with one. No vertical bound is ever set:
|
|
94
|
+
* a long table sits inside a `ScrollContainer` with `axis="vertical"`, which owns that axis.
|
|
95
|
+
* - `Root columns` declares every column's allocation once, in cell order, and every row shares it:
|
|
96
|
+
* a fixed column takes its named width role at any available width; proportional columns share
|
|
97
|
+
* the width the fixed ones leave by their weights, each floored at its named minimum, and while a
|
|
98
|
+
* minimum holds one column the others share what is left. A fixed width below its minimum is the
|
|
99
|
+
* minimum. Nothing a row holds moves a boundary: filtering, sorting, paging, long or short content,
|
|
100
|
+
* an empty body and its repopulation all leave the allocation as it was. Only the definitions, the
|
|
101
|
+
* theme's `--table-column-*` values and the available width can. All-fixed columns do not stretch.
|
|
102
|
+
* - With `columns` declared, no narrow-viewport rule applies whatever `notes` says: the note column
|
|
103
|
+
* stays, rows stay tabular, and what does not fit scrolls in the wrapper as above. Text wraps inside
|
|
104
|
+
* its allocation, an unbroken run included; the table never truncates, hides or resizes content.
|
|
105
|
+
* Without `columns`, widths follow content and both `notes` behaviours are exactly as before.
|
|
106
|
+
* - `Root density` insets every header and body cell from one theme pair: `comfortable` (the
|
|
107
|
+
* default, the former spacing exactly) or `compact`, per table. It moves no type size and no
|
|
108
|
+
* control's own dimensions. A non-positive or non-finite `weight` throws
|
|
109
|
+
* {@link TableConfigurationError}, loud and early.
|
|
110
|
+
* - A `Row` given `onClick$` is interactive: a tab stop with the shared focus ring, activated by a
|
|
111
|
+
* click on its body or by Enter or Space while focused, emitting exactly once per activation. A
|
|
112
|
+
* nested link, button or other control - and anything inside one - performs its own operation and
|
|
113
|
+
* never activates the row. Without `onClick$` the row body is inert and adds no tab stop; nested
|
|
114
|
+
* controls stay operable. Activation never changes selection.
|
|
115
|
+
* - A `Row` given `isSelected$` carries `aria-selected` and, when true, the marker bar along its
|
|
116
|
+
* leading edge in `foreground` - a shape, not a colour, and not the focus ring. Omitted or not yet
|
|
117
|
+
* emitted reads unselected; a replaced source reads unselected until it emits; unmounting
|
|
118
|
+
* unsubscribes. The selection input is independent of `onClick$`, so a row may be selected and
|
|
119
|
+
* noninteractive, interactive and unselected, or both. Rendering and selection changes emit nothing.
|
|
120
|
+
* - The row stays a `tr` in a `table`: no grid role, no arrow-key navigation. `aria-selected` is a
|
|
121
|
+
* WAI-ARIA 1.2 state of `row` and valid here, but Chromium exposes a row's selected state only
|
|
122
|
+
* inside a `grid`, so Chrome and Edge screen readers do not announce it on these rows (accepted
|
|
123
|
+
* limitation, #113). The marker bar is the one guaranteed selection cue.
|
|
124
|
+
* - A table holding a selection input anywhere insets every row's first cell by the cell padding,
|
|
125
|
+
* head and foot included, so the marker has room and no column shifts as the selection moves. A
|
|
126
|
+
* table holding an interactive row makes ring room around itself, so a focused row's ring is never
|
|
127
|
+
* clipped by the scroll region. A table with neither keeps its static geometry exactly.
|
|
128
|
+
*
|
|
129
|
+
* @CallerMustEnsure — the component cannot see these and does not check them
|
|
130
|
+
* - Every row writes exactly as many cells as there are `columns`, in the same order. A row with
|
|
131
|
+
* fewer leaves tracks empty; one with more breaks onto a second line of its own row.
|
|
132
|
+
* - A cell whose content cannot wrap - a `Button`, an `Input`, an image - sits in a column whose
|
|
133
|
+
* fixed width or minimum holds it: the `action` role holds one standard control at comfortable
|
|
134
|
+
* density. The allocation never widens for content, so an under-allocated control overflows its
|
|
135
|
+
* cell rather than moving its neighbours.
|
|
136
|
+
* - A cell's `align` and `variant` are the consumer's as before; an allocation sets neither.
|
|
137
|
+
* - Each row's `onClick$` and `isSelected$` are tied to that row's stable identity, so a reordered or
|
|
138
|
+
* temporarily removed row keeps its association. Table holds no identity, registry or policy, and
|
|
139
|
+
* removing a row never asks the consumer to clear or replace its selection.
|
|
140
|
+
* - What an activation means - select, open, toggle - is the consumer's answer, given by rerendering
|
|
141
|
+
* from its own state. A request left unanswered leaves the rendered selection unchanged.
|
|
142
|
+
* - An interactive row announces no verb of its own; the caption, a row header or a nested link
|
|
143
|
+
* should make the row's purpose plain.
|
|
45
144
|
*
|
|
46
145
|
* @UXGuidelines
|
|
146
|
+
* - Allocate by job, not by measurement: the subject's `name` first, proportional with a minimum so it
|
|
147
|
+
* wraps rather than vanishes; comparison facts proportional at `fact`; figures fixed at `figure`,
|
|
148
|
+
* right-aligned; the action column fixed at `action`, last. A theme that re-points a role moves
|
|
149
|
+
* every table using it, which is the point of naming the role rather than the width.
|
|
150
|
+
* - `compact` is for a dense comparison the viewer scans, not for fitting more in: it changes air,
|
|
151
|
+
* not type, so a table that overflows at `comfortable` mostly still overflows at `compact`.
|
|
152
|
+
* - A sortable column is composed, not configured: a `Button variant="plain"` inside the `HeaderCell`
|
|
153
|
+
* carries the label and an `Icon` (`sort`, `sort-ascending`, `sort-descending`) that matches the
|
|
154
|
+
* order the consumer currently displays, and `ariaSort` on the same cell says so to assistive
|
|
155
|
+
* technology. Only the ordered column carries `ariaSort`; an action-only column carries no sort
|
|
156
|
+
* control. Until the consumer's data arrives, both icon and `ariaSort` keep stating the old order.
|
|
47
157
|
* - `align` is a cell property but reads as a column one: set the same `align` on a `HeaderCell` and
|
|
48
158
|
* every `Cell` beneath it, and keep them in sync - the component cannot align a column for you.
|
|
49
159
|
* - Choose `notes` by what the note column *is*: `"supplementary"` drops it below 48rem for everyone
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const eyebrow: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IEyebrowProps extends VariantProps<typeof eyebrow> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const h1: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IH1Props extends VariantProps<typeof h1> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -12,7 +12,8 @@ interface IH1Props extends VariantProps<typeof h1> {
|
|
|
12
12
|
*
|
|
13
13
|
* @Guarantees — enforced on every render
|
|
14
14
|
* - Renders an `h1`; its outline level and the display role are one choice, not two (docs/adr/0005).
|
|
15
|
-
* - Reads `--font-
|
|
15
|
+
* - Reads `--font-heading`, the heading family that follows `--font-primary` until a theme
|
|
16
|
+
* re-points it (#120), sized by `--text-display`, led by `--leading-display` and optically
|
|
16
17
|
* corrected by `--tracking-optical`, the large-type correction every role from title up carries.
|
|
17
18
|
* - Bounded at `--measure-display`, the display role's own measure — narrower than the reading column
|
|
18
19
|
* because bigger type wants fewer characters per line (docs/adr/0004). The bound is the recipe's,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const h2: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IH2Props extends VariantProps<typeof h2> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -12,7 +12,8 @@ interface IH2Props extends VariantProps<typeof h2> {
|
|
|
12
12
|
*
|
|
13
13
|
* @Guarantees — enforced on every render
|
|
14
14
|
* - Renders an `h2`; its outline level and the title role are one choice, not two (docs/adr/0005).
|
|
15
|
-
* - Reads `--font-
|
|
15
|
+
* - Reads `--font-heading`, the heading family that follows `--font-primary` until a theme
|
|
16
|
+
* re-points it (#120), sized by `--text-title`, led by `--leading-title` and optically corrected
|
|
16
17
|
* by `--tracking-optical` — the title role is the smallest role that carries it, so `H3` and below
|
|
17
18
|
* take none.
|
|
18
19
|
* - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const h3: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IH3Props extends VariantProps<typeof h3> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -13,7 +13,8 @@ interface IH3Props extends VariantProps<typeof h3> {
|
|
|
13
13
|
*
|
|
14
14
|
* @Guarantees — enforced on every render
|
|
15
15
|
* - Renders an `h3`; its outline level and the subtitle role are one choice, not two (docs/adr/0005).
|
|
16
|
-
* - Reads `--font-
|
|
16
|
+
* - Reads `--font-heading`, the heading family that follows `--font-primary` until a theme
|
|
17
|
+
* re-points it (#120), sized by `--text-subtitle` and led by `--leading-subtitle`.
|
|
17
18
|
* - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
|
|
18
19
|
* paints text. A status tone changes colour only and adds no announcement semantics.
|
|
19
20
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const h4: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IH4Props extends VariantProps<typeof h4> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -12,7 +12,8 @@ interface IH4Props extends VariantProps<typeof h4> {
|
|
|
12
12
|
*
|
|
13
13
|
* @Guarantees — enforced on every render
|
|
14
14
|
* - Renders an `h4`; its outline level and the body role are one choice, not two (docs/adr/0005).
|
|
15
|
-
* - Reads `--font-
|
|
15
|
+
* - Reads `--font-heading`, the heading family that follows `--font-primary` until a theme
|
|
16
|
+
* re-points it (#120), sized by `--text-body`, and is bold so it stands apart from a paragraph.
|
|
16
17
|
* - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
|
|
17
18
|
* paints text. A status tone changes colour only and adds no announcement semantics.
|
|
18
19
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const h5: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IH5Props extends VariantProps<typeof h5> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -13,7 +13,8 @@ interface IH5Props extends VariantProps<typeof h5> {
|
|
|
13
13
|
*
|
|
14
14
|
* @Guarantees — enforced on every render
|
|
15
15
|
* - Renders an `h5`; its outline level and the body role are one choice, not two (docs/adr/0005).
|
|
16
|
-
* - Reads `--font-
|
|
16
|
+
* - Reads `--font-heading`, the heading family that follows `--font-primary` until a theme
|
|
17
|
+
* re-points it (#120), sized by `--text-body`, semibold so it stands apart from a paragraph.
|
|
17
18
|
* - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
|
|
18
19
|
* paints text. A status tone changes colour only and adds no announcement semantics.
|
|
19
20
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const h6: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IH6Props extends VariantProps<typeof h6> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -13,7 +13,8 @@ interface IH6Props extends VariantProps<typeof h6> {
|
|
|
13
13
|
*
|
|
14
14
|
* @Guarantees — enforced on every render
|
|
15
15
|
* - Renders an `h6`; its outline level and the body role are one choice, not two (docs/adr/0005).
|
|
16
|
-
* - Reads `--font-
|
|
16
|
+
* - Reads `--font-heading`, the heading family that follows `--font-primary` until a theme
|
|
17
|
+
* re-points it (#120), sized by `--text-body`, medium so it stands apart from a paragraph.
|
|
17
18
|
* - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
|
|
18
19
|
* paints text. A status tone changes colour only and adds no announcement semantics.
|
|
19
20
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const note: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
export interface INoteProps extends VariantProps<typeof note> {
|
|
7
7
|
/** The annotation. A `ReactNode` rather than a string, because these lines carry inline links. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const p: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IPProps extends VariantProps<typeof p> {
|
|
7
7
|
children: ReactNode;
|
|
@@ -12,7 +12,8 @@ interface IPProps extends VariantProps<typeof p> {
|
|
|
12
12
|
* table cell — because the reading measure belongs to whatever owns the reading column (Prose #21).
|
|
13
13
|
*
|
|
14
14
|
* @Guarantees — enforced on every render
|
|
15
|
-
* - Renders a `p`, reading `--font-
|
|
15
|
+
* - Renders a `p`, reading `--font-body` (the body family, which follows `--font-primary` until a
|
|
16
|
+
* theme re-points it, #120), sized by `--text-body` and led by `--leading-body`.
|
|
16
17
|
* - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
|
|
17
18
|
* paints text. A status tone changes colour only and adds no announcement semantics.
|
|
18
19
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const proseBody: (props?: ({
|
|
4
|
-
color?: "
|
|
4
|
+
color?: "error" | "foreground" | "muted" | "success" | "warning" | "info" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
interface IProseRootProps {
|
|
7
7
|
children?: ReactNode;
|
|
@@ -2,7 +2,7 @@ import type { VariantProps } from 'class-variance-authority';
|
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
import type { Subject } from 'rxjs';
|
|
4
4
|
declare const button: (props?: ({
|
|
5
|
-
variant?: "primary" | "secondary" | "ghost" | null | undefined;
|
|
5
|
+
variant?: "primary" | "secondary" | "ghost" | "outlined" | "destructive" | "plain" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
interface IButtonProps extends VariantProps<typeof button> {
|
|
8
8
|
/** Optional: an icon-only button renders none, and names itself with `ariaLabel` instead. */
|
|
@@ -22,10 +22,27 @@ interface IButtonProps extends VariantProps<typeof button> {
|
|
|
22
22
|
*
|
|
23
23
|
* @component
|
|
24
24
|
*
|
|
25
|
+
* @Variants
|
|
26
|
+
* - `primary` and `secondary`: the filled actions
|
|
27
|
+
* - `outlined`: the quiet secondary - `secondary` text and edge on an unfilled surface, for an
|
|
28
|
+
* action beside a primary one that must not compete with it
|
|
29
|
+
* - `destructive`: an action that removes or ends something, filled with the `error` status tone
|
|
30
|
+
* and inked with `errorForeground`. The tone reinforces words it never replaces: the label, or
|
|
31
|
+
* the `ariaLabel` of a symbol-only button, must say what the action does
|
|
32
|
+
* - `ghost`: the padded text action with a hover underline and no floor
|
|
33
|
+
*
|
|
34
|
+
* The four faced variants share the control minimum width and inset, so a row of them aligns, and
|
|
35
|
+
* every one of them shrinks and wraps its label where its holder is narrower than that.
|
|
36
|
+
*
|
|
25
37
|
* @UXGuidelines
|
|
26
38
|
* - Use clear, action-oriented text (e.g., "Save" instead of "OK")
|
|
27
|
-
* - Keep button text
|
|
39
|
+
* - Keep button text short; a translated label that runs longer wraps where the layout constrains
|
|
40
|
+
* it, so the words stay readable rather than overflowing
|
|
28
41
|
* - Use primary buttons for main actions, secondary buttons for alternative actions
|
|
42
|
+
* - `plain` is a plain action (CONTEXT.md): an operable button in the typography and colour of the
|
|
43
|
+
* text around it, with no face, padding, corner or hover underline of its own. Reach for it where
|
|
44
|
+
* the action belongs to a line of content - a sortable column header composed with `Icon` - and
|
|
45
|
+
* for `ghost` where a quiet but still button-shaped action is wanted
|
|
29
46
|
* - Maintain consistent button styling throughout the application
|
|
30
47
|
* - Provide visual feedback on hover/active states
|
|
31
48
|
* - Ensure sufficient touch target size (minimum 44x44px) for mobile users
|
|
@@ -35,8 +52,11 @@ interface IButtonProps extends VariantProps<typeof button> {
|
|
|
35
52
|
*
|
|
36
53
|
* @Accessibility
|
|
37
54
|
* - Ensure adequate color contrast (4.5:1 minimum ratio)
|
|
38
|
-
* - Provide focus styles for keyboard navigation
|
|
55
|
+
* - Provide focus styles for keyboard navigation: every variant, `plain` included, draws the shared
|
|
56
|
+
* focus ring and nothing else changes on focus
|
|
57
|
+
* - A disabled `plain` button is told apart by the `disabled` text tone and keeps native disabled semantics
|
|
39
58
|
* - Use appropriate ARIA attributes when needed
|
|
59
|
+
* - Status colour never stands alone: a destructive action is named by its words or symbol
|
|
40
60
|
*/
|
|
41
61
|
export declare const Button: FunctionComponent<IButtonProps>;
|
|
42
62
|
export {};
|
|
@@ -18,8 +18,10 @@ export interface ITabsTabProps {
|
|
|
18
18
|
/** The stable identity connecting this tab to its panel and emitted by selection requests.
|
|
19
19
|
* Not React's `key`, and never inferred from the label or the position. */
|
|
20
20
|
value: string;
|
|
21
|
-
/** The visible text
|
|
22
|
-
|
|
21
|
+
/** The label: visible text naming the view - a plain string still works - optionally with an
|
|
22
|
+
* icon, a count or inline emphasis beside it. Decorative parts carry the consumer's own
|
|
23
|
+
* `aria-hidden`; nothing in it is interactive, as the tab is the control. Rendered whole. */
|
|
24
|
+
children: ReactNode;
|
|
23
25
|
testId?: string;
|
|
24
26
|
}
|
|
25
27
|
export interface ITabsPanelProps {
|
|
@@ -47,15 +49,31 @@ export interface ITabsPanelProps {
|
|
|
47
49
|
* immediately; focus stays on the operated tab. Up/Down are left to the browser.
|
|
48
50
|
* - Roving tabindex: Tab enters the list at the active tab, then the active panel - a consistent
|
|
49
51
|
* Tab stop whether or not its content is focusable. Inactive panels add no stop.
|
|
50
|
-
* -
|
|
51
|
-
*
|
|
52
|
+
* - A label is rendered whole, text and markup alike, however long its translation runs: never
|
|
53
|
+
* clipped, shortened, elided or replaced by a hint. The tab's accessible name is computed from
|
|
54
|
+
* its content, so what the device reads is what the viewer sees, less what the consumer marked
|
|
55
|
+
* `aria-hidden`. A rich label and a plain string are one and the same control.
|
|
56
|
+
* - The row is one line of controls. As it narrows, a label's text wraps inside its tab, down to
|
|
57
|
+
* the tab's longest word; only when the controls still cannot fit does the row scroll
|
|
58
|
+
* horizontally - the row, never the page. The row holds its own ring room so the focused tab's
|
|
59
|
+
* ring survives the scroll clip, and focus reveals a scrolled-off tab, so every tab is reachable
|
|
60
|
+
* by keyboard without scrolling first.
|
|
61
|
+
* - The tabs on the row share one height, so every marker sits on one line whether or not a
|
|
62
|
+
* neighbour's label wrapped.
|
|
52
63
|
* - Selection is marked by a persistent line under the active tab: `--tab-marker-thickness` in
|
|
53
64
|
* `foreground`, constant thickness in both states, so switching shifts no widths and no weights.
|
|
54
65
|
* Keyboard focus is the separate shared focus ring. Colour moves on the one motion token.
|
|
55
66
|
*
|
|
56
67
|
* @CallerMustEnsure — the component cannot see these and does not check them
|
|
57
68
|
* - One List with Tab elements as direct DOM children (arrays and fragments are supported),
|
|
58
|
-
* and
|
|
69
|
+
* and the Panels under the same Root - as siblings of the List, or with it inside one
|
|
70
|
+
* arrangement such as a `Stack` (see the separation guidance below). Do not wrap tabs in host
|
|
71
|
+
* elements.
|
|
72
|
+
* - A label is a meaningful visible text name, with non-interactive decoration at most: no link,
|
|
73
|
+
* button, input or other focusable descendant, since the tab is the one control and a nested
|
|
74
|
+
* control inside a `button` is invalid. Decorative parts - an icon that repeats the text - carry
|
|
75
|
+
* `aria-hidden` so they stay out of the name; the library does not guess which parts those are.
|
|
76
|
+
* A count or an emphasis is meaning and stays in the name.
|
|
59
77
|
* - At least two tabs, each `value` unique and stable, each with exactly one matching `Panel`
|
|
60
78
|
* under the same `Root`, and `active` naming a declared pair. Invalid input is a contract
|
|
61
79
|
* violation, not a request for a fallback.
|
|
@@ -66,10 +84,17 @@ export interface ITabsPanelProps {
|
|
|
66
84
|
*
|
|
67
85
|
* @UXGuidelines
|
|
68
86
|
* - Labels are short names for views, not actions; the consuming app words and translates them.
|
|
87
|
+
* A long translation wraps inside its tab and the row scrolls only when even the longest words
|
|
88
|
+
* do not fit, so a label is never the reason to shorten a name.
|
|
69
89
|
* - This is not a router: no location, no history, no deep links. Wire `onSelect$` to whatever
|
|
70
90
|
* owns the active key and pass that key back in.
|
|
91
|
+
* - Tabs sets no spacing between the row and the panel; the separation is a `Stack` between Root
|
|
92
|
+
* and its members - `<Tabs.Root><Stack gap="region"><Tabs.List/>…<Tabs.Panel/>…</Stack>
|
|
93
|
+
* </Tabs.Root>`. `gap="stack"` holds the row and its view together as one block; `gap="region"`
|
|
94
|
+
* sets the view apart as a region of its own. Inactive panels are hidden, so the gap is exactly
|
|
95
|
+
* one whichever panel is active, from the token the consumer's other groups already use.
|
|
71
96
|
* - The panel is an opaque slot: compose the view's own rhythm inside it - a `Stack`, a `Prose` -
|
|
72
|
-
* as the view owns it
|
|
97
|
+
* as the view owns it.
|
|
73
98
|
*/
|
|
74
99
|
export declare const Tabs: {
|
|
75
100
|
readonly Root: FunctionComponent<ITabsRootProps>;
|
|
@@ -2,8 +2,14 @@ import type { VariantProps } from 'class-variance-authority';
|
|
|
2
2
|
import type { FunctionComponent, ReactNode } from 'react';
|
|
3
3
|
declare const header: (props?: ({
|
|
4
4
|
edge?: "none" | "rule" | null | undefined;
|
|
5
|
+
mode?: "navigation" | "statusAction" | null | undefined;
|
|
5
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
-
|
|
7
|
+
interface IHeaderShellProps extends Omit<VariantProps<typeof header>, 'mode'> {
|
|
8
|
+
testId?: string;
|
|
9
|
+
}
|
|
10
|
+
/** The navigation bar: the mode every existing caller is in, and the default. A standing link and a
|
|
11
|
+
* `<nav>`, and never a status or an action slot - the other shape is `IHeaderStatusActionProps`. */
|
|
12
|
+
export interface IHeaderNavigationProps extends IHeaderShellProps {
|
|
7
13
|
/** The standing link: a place name, a mark, or a home link. The consumer supplies the whole anchor -
|
|
8
14
|
* Header renders no link of its own. A place name uses `<Link treatment="quiet" href="/">…</Link>`; a
|
|
9
15
|
* mark uses `<Link treatment="graphic" href="/"><Brandmark …/></Link>`, whose `graphic` treatment
|
|
@@ -13,15 +19,45 @@ export interface IHeaderProps extends VariantProps<typeof header> {
|
|
|
13
19
|
navName?: string;
|
|
14
20
|
/** The nav links. */
|
|
15
21
|
children?: ReactNode;
|
|
16
|
-
|
|
22
|
+
status?: never;
|
|
23
|
+
action?: never;
|
|
17
24
|
}
|
|
25
|
+
/** The status/action bar: a bar that reports and acts rather than navigates, for a product whose
|
|
26
|
+
* shell carries a readout and a control and no links. It has no standing link and no `<nav>` - a
|
|
27
|
+
* button is not navigation - and the two shapes cannot be mixed: the compiler rejects a call that
|
|
28
|
+
* hands this bar a standing link, a nav name or nav children. */
|
|
29
|
+
export interface IHeaderStatusActionProps extends IHeaderShellProps {
|
|
30
|
+
/** The readout - a date, a balance, a short note, or a `Cluster` of them - at the start edge, first
|
|
31
|
+
* in reading order. A plain `div` with no role, no name and no live region: what it holds carries its
|
|
32
|
+
* own semantics, and whether a change is announced is the consumer's decision, made by wrapping its
|
|
33
|
+
* own live region. Long and unbroken wording wraps inside the slot. Omitted, nothing renders. */
|
|
34
|
+
status?: ReactNode;
|
|
35
|
+
/** The control - a `Button`, or a `Cluster` of them - at the end edge, last in reading and keyboard
|
|
36
|
+
* order, on whichever line it lands when the bar breaks. A plain `div` like `status`. Header never
|
|
37
|
+
* decides whether the control is available: pass it disabled, or withhold it (`{ready && <Button/>}`
|
|
38
|
+
* renders no box). Omitted, nothing renders. */
|
|
39
|
+
action?: ReactNode;
|
|
40
|
+
standing?: never;
|
|
41
|
+
navName?: never;
|
|
42
|
+
children?: never;
|
|
43
|
+
}
|
|
44
|
+
export type IHeaderProps = IHeaderNavigationProps | IHeaderStatusActionProps;
|
|
18
45
|
/**
|
|
19
|
-
* The shell's top edge
|
|
20
|
-
*
|
|
46
|
+
* The shell's top edge, at the label type role, in one of two mutually exclusive modes. The
|
|
47
|
+
* **navigation bar** - the default, and what every existing caller renders - is a standing link and a
|
|
48
|
+
* single `<nav>`. The **status/action bar** is a readout at the start edge and a control at the end
|
|
49
|
+
* edge, both plain boxes with no landmark of their own and no `<nav>` anywhere. The props type is a
|
|
50
|
+
* union of the two shapes, so a call that mixes them does not compile. Either bar arranges nothing
|
|
51
|
+
* beyond its slots and works with no hydration.
|
|
21
52
|
*
|
|
22
53
|
* @Guarantees — enforced on every render
|
|
23
54
|
* - The header is set at the label role and carries no size of its own: `font-secondary text-label
|
|
24
55
|
* leading-label tracking-label text-muted`, so it never grows past that role whatever the page font size.
|
|
56
|
+
* - The shell's air is one value above, below and between: `--space-region` vertically, between the
|
|
57
|
+
* nav's items and between the status/action bar's slots along a line, `--gutter` across, so the bar
|
|
58
|
+
* aligns with every inset `Section`. It is never sticky and needs no JavaScript.
|
|
59
|
+
*
|
|
60
|
+
* The navigation bar, unchanged by #125:
|
|
25
61
|
* - The nav's line box is the library's own rather than the consuming document's: the header leads
|
|
26
62
|
* itself at the label role, so the height it declares for its slot is the height it renders.
|
|
27
63
|
* - The standing slot is floored, never fixed: its minimum height is that same line box - the label
|
|
@@ -31,10 +67,24 @@ export interface IHeaderProps extends VariantProps<typeof header> {
|
|
|
31
67
|
* grows the slot, on one line, and is never clamped or wrapped.
|
|
32
68
|
* - A nav item marked `aria-current="page"` renders at `foreground` whatever supplied it - the treatment
|
|
33
69
|
* keys on the attribute, not on `Link`, so it holds against a bare anchor or any component.
|
|
34
|
-
* - The
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
70
|
+
* - The standing slot and the `<nav>` are the bar's two children whatever the caller passes, the nav
|
|
71
|
+
* flush with the end content edge and absorbing narrowing by wrapping its links. Omitting `navName`
|
|
72
|
+
* emits no `aria-label` at all, not an empty one.
|
|
73
|
+
*
|
|
74
|
+
* The status/action bar:
|
|
75
|
+
* - It renders no `<nav>`, no standing slot, no role, no name and no live region of its own. Each
|
|
76
|
+
* filled slot is one `div` directly inside the banner; an omitted or withheld slot (`false`, `null`)
|
|
77
|
+
* renders no box and reserves no space, so a status-only bar starts with its readout and an action-only
|
|
78
|
+
* bar is the control alone at the end edge.
|
|
79
|
+
* - Reading and keyboard order is status, then action, and the DOM order is the same at every width.
|
|
80
|
+
* - With both fitting, the readout sits at the start content edge and the control at the end content
|
|
81
|
+
* edge on one line. When they cannot share a line, the control drops below the readout and stays
|
|
82
|
+
* flush with the end edge; a readout then takes the whole line and wraps inside it, unbroken wording
|
|
83
|
+
* included, so the bar never widens the page and never clips.
|
|
84
|
+
* - Breaking is CSS alone: a width change re-flows the same elements, so descendant state and focus
|
|
85
|
+
* survive it.
|
|
86
|
+
* - What the consumer passes keeps its semantics: a heading stays a heading, a live region stays one, a
|
|
87
|
+
* disabled control stays disabled. Header adds, removes and announces nothing.
|
|
38
88
|
*
|
|
39
89
|
* @CallerMustEnsure — the component cannot see these and does not check them
|
|
40
90
|
* - A mark that should *fill* the standing slot is given a **definite width** by whoever placed it -
|
|
@@ -47,6 +97,10 @@ export interface IHeaderProps extends VariantProps<typeof header> {
|
|
|
47
97
|
* width; `flex: 1 1 0; min-width: 0` only collapses the mark when the bar is already out of room, so
|
|
48
98
|
* it is not the rule to reach for. The library cannot apply either rule for you: the same width on a
|
|
49
99
|
* place name would clamp the name and wrap it.
|
|
100
|
+
* - Set the type of what fills a status/action slot: the bar sets the label role, so a bare string in
|
|
101
|
+
* `status` reads as a label, while a `P` or a `Note` wears its own role and a `Button` its own.
|
|
102
|
+
* - Whether a changing readout interrupts is yours to decide: wrap your own live region inside `status`
|
|
103
|
+
* where a change must be announced, and leave it out where it must not. Header takes neither side.
|
|
50
104
|
*
|
|
51
105
|
* @UXGuidelines
|
|
52
106
|
* - Name the nav with `navName` once the page has more than one navigation landmark - a footer nav will
|
|
@@ -55,6 +109,11 @@ export interface IHeaderProps extends VariantProps<typeof header> {
|
|
|
55
109
|
* `aria-current`, so set `current` on the `Link` and style nothing yourself.
|
|
56
110
|
* - The nav does not collapse into a menu: a disclosure needs JavaScript, so on a narrow viewport the
|
|
57
111
|
* items wrap. A mobile menu is out of scope, not a follow-up.
|
|
112
|
+
* - A bar that reports and acts is a status/action bar, never a navigation bar with a button among its
|
|
113
|
+
* links: a Balance line or a Continue button inside a `<nav>` is announced as navigation. A product
|
|
114
|
+
* whose shell needs links as well as a control has two bars, not one.
|
|
115
|
+
* - Several readouts or several actions go in a `Cluster` inside the slot: `gap="stack"` keeps them one
|
|
116
|
+
* group, and the Cluster wraps inside the slot before the bar runs out of room.
|
|
58
117
|
*/
|
|
59
118
|
export declare const Header: FunctionComponent<IHeaderProps>;
|
|
60
119
|
export {};
|