@juwel-development/design-system 3.9.0 → 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 +1043 -589
- 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/Slider/Slider.d.ts +9 -4
- 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/Slider/Slider.tsx +34 -18
- 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 {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FunctionComponent } from 'react';
|
|
2
2
|
import type { Subject } from 'rxjs';
|
|
3
3
|
export interface ISliderProps {
|
|
4
4
|
/** The operating range's lower bound - interaction geometry, not a content rule (ADR 0009). */
|
|
@@ -20,7 +20,10 @@ export interface ISliderProps {
|
|
|
20
20
|
* could never read a value at all.
|
|
21
21
|
*/
|
|
22
22
|
onInput$: Subject<number>;
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Always rendered as a visible label associated with the control, the way `Input`'s is (#112);
|
|
25
|
+
* it doubles as the accessible name.
|
|
26
|
+
*/
|
|
24
27
|
label: string;
|
|
25
28
|
/**
|
|
26
29
|
* How the value is announced, in the consumer's wording ("$60 a week"). Left out, assistive
|
|
@@ -35,7 +38,9 @@ export interface ISliderProps {
|
|
|
35
38
|
* A control that sets one numeric value by moving one thumb along a fixed, visible operating
|
|
36
39
|
* range. Controlled: the consumer holds the value and passes it back in, and a value it does not
|
|
37
40
|
* pass back is never adopted. It renders the value nowhere - the consumer sets any figures beside
|
|
38
|
-
* it with typography - and it fills its container's width the way `Input` does.
|
|
39
|
-
*
|
|
41
|
+
* it with typography - and it fills its container's width the way `Input` does. Its label follows
|
|
42
|
+
* `Input` too: visible, associated, and the only text the component renders (#112). It is still
|
|
43
|
+
* a live control and not a form field, so none of Input's annotations - hint, error, optional
|
|
44
|
+
* marker - come with it. `disabled` is the explicit non-operable state.
|
|
40
45
|
*/
|
|
41
46
|
export declare const Slider: FunctionComponent<ISliderProps>;
|
|
@@ -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>;
|