@acronis-platform/ui-react 5.0.0 → 5.1.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/dist/components/ui/area-chart/area-chart.js +191 -85
- package/dist/components/ui/area-chart/area-chart.js.map +1 -1
- package/dist/components/ui/bar-chart/bar-chart.js +288 -225
- package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
- package/dist/components/ui/card-widget-carousel/card-widget-carousel.js +85 -0
- package/dist/components/ui/card-widget-carousel/card-widget-carousel.js.map +1 -0
- package/dist/components/ui/card-widget-carousel/card-widget.js +82 -0
- package/dist/components/ui/card-widget-carousel/card-widget.js.map +1 -0
- package/dist/components/ui/category-bar/category-bar.js.map +1 -1
- package/dist/components/ui/chart/chart-format.js +25 -22
- package/dist/components/ui/chart/chart-format.js.map +1 -1
- package/dist/components/ui/chart/chart-palette.js +9 -8
- package/dist/components/ui/chart/chart-palette.js.map +1 -1
- package/dist/components/ui/chart/chart.js +118 -83
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/line-chart/line-chart.js +194 -86
- package/dist/components/ui/line-chart/line-chart.js.map +1 -1
- package/dist/components/ui/scatter-chart/scatter-chart.js +5 -2
- package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
- package/dist/components/ui/separator/separator.js +52 -10
- package/dist/components/ui/separator/separator.js.map +1 -1
- package/dist/components/ui/sidebar-secondary/sidebar-secondary.js +144 -121
- package/dist/components/ui/sidebar-secondary/sidebar-secondary.js.map +1 -1
- package/dist/components/ui/tree-item/tree-item.js +67 -0
- package/dist/components/ui/tree-item/tree-item.js.map +1 -0
- package/dist/components/ui/treemap/treemap.js +73 -66
- package/dist/components/ui/treemap/treemap.js.map +1 -1
- package/dist/index.js +109 -107
- package/dist/llms/area-chart.md +2 -1
- package/dist/llms/bar-chart.md +132 -33
- package/dist/llms/card-widget-carousel.md +252 -0
- package/dist/llms/category-bar.md +2 -2
- package/dist/llms/line-chart.md +2 -1
- package/dist/llms/metric.md +10 -5
- package/dist/llms/scatter-chart.md +2 -1
- package/dist/llms/separator.md +27 -8
- package/dist/llms/sidebar-secondary.md +235 -4
- package/dist/llms/tree-item.md +359 -0
- package/dist/llms/treemap.md +47 -36
- package/dist/llms.txt +4 -3
- package/dist/react.js +109 -107
- package/dist/src/components/ui/area-chart/area-chart.d.ts +10 -0
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +75 -10
- package/dist/src/components/ui/bar-chart/bar-chart.docs.d.ts +146 -0
- package/dist/src/components/ui/bar-chart/index.d.ts +1 -1
- package/dist/src/components/ui/card-widget-carousel/card-widget-carousel.d.ts +9 -0
- package/dist/src/components/ui/card-widget-carousel/card-widget.d.ts +43 -0
- package/dist/src/components/ui/card-widget-carousel/index.d.ts +2 -0
- package/dist/src/components/ui/chart/chart-format.d.ts +9 -1
- package/dist/src/components/ui/chart/chart-palette.d.ts +38 -10
- package/dist/src/components/ui/chart/index.d.ts +2 -2
- package/dist/src/components/ui/line-chart/line-chart.d.ts +11 -1
- package/dist/src/components/ui/separator/separator.d.ts +9 -1
- package/dist/src/components/ui/sidebar-secondary/sidebar-secondary.d.ts +23 -3
- package/dist/src/components/ui/tree-item/index.d.ts +1 -0
- package/dist/src/components/ui/tree-item/tree-item.d.ts +64 -0
- package/dist/src/components/ui/treemap/treemap.d.ts +16 -5
- package/dist/src/index.d.ts +2 -1
- package/dist/ui-react.css +1 -1
- package/package.json +3 -3
- package/dist/components/ui/meter/meter.js +0 -79
- package/dist/components/ui/meter/meter.js.map +0 -1
- package/dist/llms/meter.md +0 -177
- package/dist/src/components/ui/meter/index.d.ts +0 -1
- package/dist/src/components/ui/meter/meter.d.ts +0 -25
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# TreeItem
|
|
2
|
+
|
|
3
|
+
> One flat row of a tree or nested-list UI — an optional expand chevron, an optional checkbox, an optional leading icon, the row title, and an optional trailing extras slot. It is a single row and nothing more: it renders no nested list and implements no expand/collapse, so `isExpandable` and `expanded` are purely visual affordances and `selected` is a prop the consumer drives. The tree itself — its ARIA roles, indentation, expand state, selection, and keyboard roving — belongs to the composition, the same way `Breadcrumb` ships the trail's primitives without owning the trail.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** navigation · **Since:** v5.1.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { TreeItem } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<ul role="tree" aria-label="Workloads">
|
|
17
|
+
<li role="treeitem" aria-expanded={open}>
|
|
18
|
+
<TreeItem
|
|
19
|
+
expanded={open}
|
|
20
|
+
hasIcon
|
|
21
|
+
icon={<FolderIcon size={16} />}
|
|
22
|
+
title="All workloads"
|
|
23
|
+
onClick={() => setOpen((v) => !v)}
|
|
24
|
+
onKeyDown={(event) => {
|
|
25
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
26
|
+
event.preventDefault();
|
|
27
|
+
setOpen((v) => !v);
|
|
28
|
+
}
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<Tag variant="info">24</Tag>
|
|
32
|
+
</TreeItem>
|
|
33
|
+
<ul role="group" className="ps-4">
|
|
34
|
+
<li role="treeitem" aria-selected>
|
|
35
|
+
<TreeItem
|
|
36
|
+
isExpandable={false}
|
|
37
|
+
hasIcon
|
|
38
|
+
selected
|
|
39
|
+
title="Cloud applications"
|
|
40
|
+
/>
|
|
41
|
+
</li>
|
|
42
|
+
</ul>
|
|
43
|
+
</li>
|
|
44
|
+
</ul>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
One flat row of a tree or nested-list UI: an optional expand chevron, an optional
|
|
48
|
+
checkbox, an optional leading icon, the row title, and an optional trailing
|
|
49
|
+
extras slot. It is deliberately **one row** — it renders no nested list, owns no
|
|
50
|
+
expand state, and selects nothing. You compose the rows, indent them, hold the
|
|
51
|
+
open/selected state, and supply the ARIA tree semantics.
|
|
52
|
+
|
|
53
|
+
## When to use
|
|
54
|
+
|
|
55
|
+
- A file tree, a workload/resource hierarchy, a nested navigation panel — one
|
|
56
|
+
`TreeItem` per row.
|
|
57
|
+
- A multi-select hierarchy: turn on `hasCheckbox` and drive the box through
|
|
58
|
+
`checkboxProps`.
|
|
59
|
+
|
|
60
|
+
## When not to use
|
|
61
|
+
|
|
62
|
+
- For a flat, non-hierarchical secondary nav — use
|
|
63
|
+
[`SidebarSecondary`](../sidebar-secondary/README.md).
|
|
64
|
+
- For a path back to the current location — use
|
|
65
|
+
[`Breadcrumb`](../breadcrumb/README.md).
|
|
66
|
+
- For collapsible **content** panels rather than a hierarchy of rows — use
|
|
67
|
+
`Accordion` / `AccordionContainer`.
|
|
68
|
+
- As the whole tree. There is no `Tree` container component today; the row is the
|
|
69
|
+
primitive and the tree is assembled in the application.
|
|
70
|
+
|
|
71
|
+
## Usage
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { TreeItem } from '@acronis-platform/ui-react';
|
|
75
|
+
|
|
76
|
+
const [open, setOpen] = React.useState(true);
|
|
77
|
+
|
|
78
|
+
<ul role="tree" aria-label="Workloads">
|
|
79
|
+
<TreeItem
|
|
80
|
+
render={<li role="treeitem" aria-expanded={open} aria-level={1} />}
|
|
81
|
+
expanded={open}
|
|
82
|
+
hasIcon
|
|
83
|
+
icon={<FolderIcon size={16} />}
|
|
84
|
+
title="All workloads"
|
|
85
|
+
onClick={() => setOpen((v) => !v)}
|
|
86
|
+
>
|
|
87
|
+
<Tag variant="info">24</Tag>
|
|
88
|
+
</TreeItem>
|
|
89
|
+
|
|
90
|
+
{open && (
|
|
91
|
+
<ul role="group" className="ps-4">
|
|
92
|
+
<TreeItem
|
|
93
|
+
render={<li role="treeitem" aria-level={2} aria-selected />}
|
|
94
|
+
isExpandable={false}
|
|
95
|
+
hasIcon
|
|
96
|
+
selected
|
|
97
|
+
title="Cloud applications"
|
|
98
|
+
/>
|
|
99
|
+
<TreeItem
|
|
100
|
+
render={<li role="treeitem" aria-level={2} />}
|
|
101
|
+
isExpandable={false}
|
|
102
|
+
hasIcon
|
|
103
|
+
title="Unmanaged workloads"
|
|
104
|
+
/>
|
|
105
|
+
</ul>
|
|
106
|
+
)}
|
|
107
|
+
</ul>;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Three things the row hands back to you on purpose:
|
|
111
|
+
|
|
112
|
+
- **`isExpandable` and `expanded` are artwork, not behavior.** The first draws
|
|
113
|
+
the chevron, the second rotates it a quarter turn to point down. Neither
|
|
114
|
+
expands anything, and there is no change event: the Figma node's expandable
|
|
115
|
+
slot has no interaction either. Pass `expanded` from the same boolean that
|
|
116
|
+
feeds your `aria-expanded`, so the affordance and the announced state agree.
|
|
117
|
+
- **`selected` is a look you drive.** The row never selects itself on click; it
|
|
118
|
+
only reflects the flag. Figma's `state=active` swatch paints the same fill,
|
|
119
|
+
which is why `active` is not wired to CSS `:active`.
|
|
120
|
+
- **The ARIA tree is yours.** No `role="treeitem"`, no tab stop by default — see
|
|
121
|
+
[`accessibility.md`](./accessibility.md) for why a role on an orphan row would
|
|
122
|
+
make the tree invalid rather than accessible.
|
|
123
|
+
|
|
124
|
+
## Parts
|
|
125
|
+
|
|
126
|
+
| Part | Element | Notes |
|
|
127
|
+
| ---------- | ------- | ------------------------------------------------------------------------------------------------- |
|
|
128
|
+
| row (root) | `div` | Polymorphic via `render`; carries the hover / `selected` fill and focus ring |
|
|
129
|
+
| `expander` | `span` | Optional (`isExpandable`, default on); `aria-hidden` chevron, flips in RTL, rotates on `expanded` |
|
|
130
|
+
| `checkbox` | `span` | Optional (`hasCheckbox`); the shared `Checkbox`, `aria-label` defaults to title |
|
|
131
|
+
| `icon` | `span` | Optional (`hasIcon`); falls back to the design's square-dashed placeholder |
|
|
132
|
+
| `title` | `span` | The row label; takes the remaining width and truncates |
|
|
133
|
+
| `extras` | `span` | Optional (`hasExtras`, default on); the trailing `children` slot |
|
|
134
|
+
|
|
135
|
+
## Design status
|
|
136
|
+
|
|
137
|
+
**No dedicated token tier.** `tokens-pd` ships no `Tree` tier: the Figma node's
|
|
138
|
+
variables still sit in the pre-next-gen `componentLegacy/tree/*` and
|
|
139
|
+
`componentLegacy/sidebar/*` namespaces, which the `brand.components` migration
|
|
140
|
+
has not reached. Every colour the row paints therefore comes from the semantic
|
|
141
|
+
tier, and the layout numbers (8px gap/padding, 128px minimum row width, 4px slot
|
|
142
|
+
inset, 16px minimum extras well) are plain utilities matching the design's pixel
|
|
143
|
+
values — see [`tokens.yaml`](./tokens.yaml) for the full reasoning. Re-point both
|
|
144
|
+
when a `--ui-tree-item-*` tier lands.
|
|
145
|
+
|
|
146
|
+
**Deviation from the Figma frame — the extras well.** Figma measures the trailing
|
|
147
|
+
slot as `min-w-[16px] w-[24px]`; the 24px is the resolved width of its
|
|
148
|
+
placeholder content in a hug-content frame, not a constraint. The implementation
|
|
149
|
+
keeps the 16px minimum and lets the slot grow, because a hard 24px would clip the
|
|
150
|
+
action buttons and count badges the slot exists to hold.
|
|
151
|
+
|
|
152
|
+
## Props
|
|
153
|
+
|
|
154
|
+
| Prop | Type | Default | Required | Description |
|
|
155
|
+
|------|------|---------|----------|-------------|
|
|
156
|
+
| `title` | `string` | `Title` | no | The row label. Truncates rather than wrapping. Note this shadows the native `title` tooltip attribute on the underlying element: the Figma component names the property `title`, and it is the row's visible label. |
|
|
157
|
+
| `isExpandable` | `boolean` | `true` | no | Show the leading expand chevron. Purely a visual affordance — the row implements no expand/collapse and renders no nested list, and emits no change event. Set it false for a leaf row. |
|
|
158
|
+
| `expanded` | `boolean` | `false` | no | Whether the row's nested list is currently expanded. Purely visual — like `isExpandable`, the row owns no expand/collapse state and renders no nested list. Rotates the leading chevron to reflect the state the consumer is already tracking (and should also be reflecting via `aria-expanded` on its own element, e.g. `<li role="treeitem" aria-expanded={open}>`). Has no effect when `isExpandable` is false. |
|
|
159
|
+
| `hasCheckbox` | `boolean` | `false` | no | Show a leading checkbox, for a multi-select tree. |
|
|
160
|
+
| `checkboxProps` | `CheckboxProps` | — | no | Props forwarded verbatim to the leading checkbox (`checked`, `onCheckedChange`, `indeterminate`, `aria-label`, …). The row keeps no checked state of its own, so the consumer controls the box exactly as it would a standalone `Checkbox`. `aria-label` defaults to `title`. |
|
|
161
|
+
| `hasIcon` | `boolean` | `false` | no | Show the leading icon slot. |
|
|
162
|
+
| `icon` | `ReactNode` | — | no | The leading icon. Only rendered when `hasIcon` is set; falls back to the design's square-dashed placeholder icon, which is what the Figma node draws. |
|
|
163
|
+
| `hasExtras` | `boolean` | `true` | no | Render the trailing extras slot at all. When false, `children` are dropped entirely rather than merely hidden. |
|
|
164
|
+
| `selected` | `boolean` | `false` | no | Whether the row is selected — the Figma `variant` axis. Paints the persistent highlighted background, the same fill the design's `state=active` swatch previews. Selection is the consumer's state to own; the row only reflects it. |
|
|
165
|
+
| `render` | `RenderProp` | — | no | Base UI composition prop — replaces the rendered `<div>` while merging props and classes. This is how a real ARIA tree supplies the semantics the standalone row deliberately does not force (`<li role="treeitem" aria-expanded aria-level>`). React-only; other frameworks use their own polymorphism. |
|
|
166
|
+
|
|
167
|
+
## Events
|
|
168
|
+
|
|
169
|
+
| Event | Payload | Description |
|
|
170
|
+
|-------|---------|-------------|
|
|
171
|
+
| `onClick` | `(event: MouseEvent) => void` | Fired when the row is clicked. Expanding and selecting are the consumer's to implement — the row emits nothing of its own for either. |
|
|
172
|
+
|
|
173
|
+
## Content slots
|
|
174
|
+
|
|
175
|
+
| Slot | Description |
|
|
176
|
+
|------|-------------|
|
|
177
|
+
| `default` | The trailing extras slot: action buttons, a count badge. Rendered only when `hasExtras` is true. |
|
|
178
|
+
|
|
179
|
+
## Behavior
|
|
180
|
+
|
|
181
|
+
### Renders one row
|
|
182
|
+
|
|
183
|
+
- **Given** no props
|
|
184
|
+
**Then** the row renders the expand chevron (`isExpandable` defaults to true),
|
|
185
|
+
the default `title`, and an empty extras slot — exactly the Figma default.
|
|
186
|
+
- **Given** a `title`
|
|
187
|
+
**Then** it renders in the row's remaining width and truncates rather than
|
|
188
|
+
wrapping or widening the row.
|
|
189
|
+
- **Given** `hasIcon`
|
|
190
|
+
**Then** the leading icon slot renders, using `icon` if supplied and the
|
|
191
|
+
design's square-dashed placeholder otherwise.
|
|
192
|
+
- **Given** an `icon` **but not** `hasIcon`
|
|
193
|
+
**Then** nothing renders — `hasIcon` is the gate, matching the Figma boolean.
|
|
194
|
+
- **Given** `hasCheckbox`
|
|
195
|
+
**Then** the shared `Checkbox` renders before the icon, unlabelled, with its
|
|
196
|
+
`aria-label` defaulting to `title`.
|
|
197
|
+
- **Given** `checkboxProps`
|
|
198
|
+
**Then** they are forwarded verbatim to that checkbox, including an
|
|
199
|
+
`aria-label` that overrides the `title` default. The row itself keeps no
|
|
200
|
+
checked state.
|
|
201
|
+
- **Given** `isExpandable={false}`
|
|
202
|
+
**Then** the chevron is not rendered and the row reads as a leaf.
|
|
203
|
+
- **Then** the slot order is always chevron, checkbox, icon, title, extras.
|
|
204
|
+
|
|
205
|
+
### The extras slot is gated, not hidden
|
|
206
|
+
|
|
207
|
+
- **Given** `children` **and** `hasExtras` (the default)
|
|
208
|
+
**Then** the trailing slot renders them, reserving a 16px minimum so an empty
|
|
209
|
+
slot still keeps a column of rows aligned.
|
|
210
|
+
- **Given** `children` **and** `hasExtras={false}`
|
|
211
|
+
**Then** the slot and the children are removed from the DOM entirely — a
|
|
212
|
+
button in there is not merely invisible, it does not exist, so it cannot be
|
|
213
|
+
tabbed to.
|
|
214
|
+
|
|
215
|
+
### Selection is a prop, not an interaction
|
|
216
|
+
|
|
217
|
+
- **Given** `selected={false}` (the default)
|
|
218
|
+
**Then** the row background is transparent.
|
|
219
|
+
- **Given** the pointer over the row
|
|
220
|
+
**Then** the background takes the hover token — regardless of `selected`,
|
|
221
|
+
since the design draws hover as its own swatch.
|
|
222
|
+
- **Given** `selected`
|
|
223
|
+
**Then** the background takes the highlighted `--ui-background-surface-active`
|
|
224
|
+
fill persistently, and the row carries `data-selected` so a consumer can key
|
|
225
|
+
off it. This is the same fill the Figma `state=active` swatch previews.
|
|
226
|
+
- **Given** a click
|
|
227
|
+
**Then** `onClick` fires and nothing else changes: the row does not select
|
|
228
|
+
itself. Selection belongs to the tree the consumer composes.
|
|
229
|
+
|
|
230
|
+
### Expansion is reflected, not implemented
|
|
231
|
+
|
|
232
|
+
- **Given** a click on the chevron
|
|
233
|
+
**Then** nothing expands. The chevron is `aria-hidden` artwork; the row renders
|
|
234
|
+
no nested list and emits no expand event, matching the Figma node, whose
|
|
235
|
+
expandable slot has no interaction either.
|
|
236
|
+
- The consumer owns the expand state, renders the child level itself, and puts
|
|
237
|
+
`aria-expanded` on the element it supplies through `render`.
|
|
238
|
+
- **Given** `expanded={false}` (the default)
|
|
239
|
+
**Then** the chevron points along the inline-end direction — the collapsed
|
|
240
|
+
affordance.
|
|
241
|
+
- **Given** `expanded`
|
|
242
|
+
**Then** the chevron rotates a quarter turn to point down, so the affordance
|
|
243
|
+
agrees with the `aria-expanded` the consumer publishes. It is a reflection of
|
|
244
|
+
the consumer's state, not a state the row holds: nothing else about the row
|
|
245
|
+
changes, no nested list appears, and no event fires.
|
|
246
|
+
- **Given** `expanded` **and** `isExpandable={false}`
|
|
247
|
+
**Then** it has no effect — there is no chevron to rotate.
|
|
248
|
+
|
|
249
|
+
### Focus
|
|
250
|
+
|
|
251
|
+
- **Given** the default rendering
|
|
252
|
+
**Then** the row is not in the tab order — it sets no `tabIndex` and no role.
|
|
253
|
+
- **Given** a consumer-supplied `tabIndex` (or a composed focusable element)
|
|
254
|
+
**Then** keyboard focus paints the library's standard 3px `--ui-focus-primary`
|
|
255
|
+
ring, flush to the row's 2px radius. Mouse focus does not, because it is a
|
|
256
|
+
`:focus-visible` ring.
|
|
257
|
+
|
|
258
|
+
### RTL
|
|
259
|
+
|
|
260
|
+
- **Given** `dir="rtl"`
|
|
261
|
+
**Then** the whole row mirrors: the slot order, the gap, and the padding are
|
|
262
|
+
all logical, and the collapsed chevron artwork itself flips via an explicit
|
|
263
|
+
`rtl:rotate-180` — logical layout alone would leave it pointing the wrong way.
|
|
264
|
+
- **Given** `dir="rtl"` **and** `expanded`
|
|
265
|
+
**Then** the chevron points down, the same as in LTR: "open" is a
|
|
266
|
+
direction-agnostic direction, so the expanded rotation replaces the RTL mirror
|
|
267
|
+
rather than compounding with it.
|
|
268
|
+
|
|
269
|
+
### Composition
|
|
270
|
+
|
|
271
|
+
- **Given** a `render` prop
|
|
272
|
+
**Then** the rendered element is replaced (e.g. by `<li role="treeitem">`) and
|
|
273
|
+
the row's props, classes, and data attributes merge onto it.
|
|
274
|
+
- **Given** native `<div>` attributes (`onClick`, `tabIndex`, `aria-*`,
|
|
275
|
+
`className`)
|
|
276
|
+
**Then** they pass through, and `className` merges with the row's own classes.
|
|
277
|
+
|
|
278
|
+
### Not owned here
|
|
279
|
+
|
|
280
|
+
- The tree: its `role="tree"` owner, indentation, `aria-level`, keyboard roving,
|
|
281
|
+
and type-ahead. The consumer composes rows and supplies all of it.
|
|
282
|
+
- Expand/collapse state and the nested list. The row only mirrors that state
|
|
283
|
+
visually, through `expanded`.
|
|
284
|
+
- Selection state, single vs. multi-select, and the checkbox's checked value.
|
|
285
|
+
|
|
286
|
+
## Accessibility
|
|
287
|
+
|
|
288
|
+
- **No `role="treeitem"` is forced, on purpose.** A tree item is only valid
|
|
289
|
+
inside a `role="tree"` (or `role="group"`) owner, and to be announced usefully
|
|
290
|
+
it needs `aria-expanded`, `aria-level`, `aria-selected`, and a roving
|
|
291
|
+
`tabindex` — none of which a standalone row can know. Stamping the role on an
|
|
292
|
+
orphan row would produce an **invalid** tree, not an accessible one. The row is
|
|
293
|
+
a plain `<div>`, and `render` is how the consumer supplies the real semantics:
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
<ul role="tree" aria-label="Workloads">
|
|
297
|
+
<TreeItem render={<li role="treeitem" aria-expanded={open} aria-level={1} />} … />
|
|
298
|
+
</ul>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
This is the same boundary `Breadcrumb` draws — it ships `nav`/`ol`/`li` and the
|
|
302
|
+
current-page part, not the trail — and `StepperItem`, which documents that
|
|
303
|
+
sequence semantics belong to the container.
|
|
304
|
+
|
|
305
|
+
- **Not in the tab order by default.** The row sets no `tabIndex`, so it never
|
|
306
|
+
becomes a silent tab stop inside a tree that manages focus itself. Pass
|
|
307
|
+
`tabIndex` (or compose a focusable element) when your tree wants the row
|
|
308
|
+
focusable; a roving `tabindex` — exactly one focusable row — is the pattern the
|
|
309
|
+
ARIA tree view calls for.
|
|
310
|
+
|
|
311
|
+
- **Keyboard focus is visible.** The row carries the library's standard 3px
|
|
312
|
+
`--ui-focus-primary` `focus-visible` ring, the same one `Button` and
|
|
313
|
+
`BreadcrumbLink` use, so a focusable row is never focused invisibly.
|
|
314
|
+
|
|
315
|
+
- **The chevron is `aria-hidden` decoration.** It is a visual affordance only:
|
|
316
|
+
the row implements no expand/collapse, so there is no state for it to announce.
|
|
317
|
+
Announce expansion with `aria-expanded` on the element you compose — that is
|
|
318
|
+
where the state actually lives. Do **not** give the chevron its own button
|
|
319
|
+
role; a row that only _looks_ expandable would then promise an action nothing
|
|
320
|
+
handles.
|
|
321
|
+
|
|
322
|
+
- **Keep `expanded` and `aria-expanded` in step.** `expanded` rotates the chevron
|
|
323
|
+
but publishes nothing to assistive technology; `aria-expanded` on your `render`
|
|
324
|
+
element publishes the state but paints nothing. They are two renderings of the
|
|
325
|
+
one boolean you own, so drive both from it (`aria-expanded={open}` +
|
|
326
|
+
`expanded={open}`). Setting only one leaves the sighted affordance and the
|
|
327
|
+
announced state disagreeing — which is the bug `expanded` exists to close.
|
|
328
|
+
|
|
329
|
+
- **The checkbox is always named.** Composed without a visible label, it would
|
|
330
|
+
otherwise be an unnamed control, so its `aria-label` defaults to `title`.
|
|
331
|
+
Override it through `checkboxProps` when the row title is not the right name
|
|
332
|
+
for the box (e.g. `aria-label="Select all workloads"`).
|
|
333
|
+
|
|
334
|
+
- **Selection is announced by the consumer.** `selected` is a _visual_ fill.
|
|
335
|
+
Colour alone is not a status, so put `aria-selected` on the element you compose
|
|
336
|
+
via `render` (and `aria-current` if the row marks a location rather than a
|
|
337
|
+
selection). The row also exposes `data-selected` for styling and testing.
|
|
338
|
+
|
|
339
|
+
- **One localizable string.** `title` is the only text the component renders on
|
|
340
|
+
its own, and the literal `'Title'` appears only as that prop's default —
|
|
341
|
+
callers pass a localized value. Everything else (`children`, `icon`,
|
|
342
|
+
`checkboxProps['aria-label']`) is consumer-supplied.
|
|
343
|
+
|
|
344
|
+
- **RTL**: the slot order, gap, and padding are logical, so the row mirrors under
|
|
345
|
+
`dir="rtl"` on its own. The collapsed chevron is direction-sensitive
|
|
346
|
+
**artwork**, which logical properties cannot mirror, so it carries an explicit
|
|
347
|
+
`rtl:rotate-180`. The `expanded` chevron points down in both directions —
|
|
348
|
+
"open" has no inline direction to mirror.
|
|
349
|
+
|
|
350
|
+
## Contrast
|
|
351
|
+
|
|
352
|
+
The title uses `--ui-text-on-surface-primary` and the glyphs
|
|
353
|
+
`--ui-glyph-on-surface-primary`, both over the row's transparent, hover, or
|
|
354
|
+
`selected` background (`--ui-background-surface-hover` /
|
|
355
|
+
`--ui-background-surface-active`). All are semantic-tier tokens defined per brand
|
|
356
|
+
and light/dark mode via `light-dark()`. Re-check the title and glyph contrast
|
|
357
|
+
against the **selected** fill specifically when a brand overrides either — the
|
|
358
|
+
idle case sits on the page surface, the selected case does not. Should a
|
|
359
|
+
dedicated `--ui-tree-item-*` tier land (see `tokens.yaml`), re-check all pairs.
|
package/dist/llms/treemap.md
CHANGED
|
@@ -28,13 +28,18 @@ it renders a themed recharts `Treemap` — cells sized by value, colored + label
|
|
|
28
28
|
per name, with a tooltip — so you don't hand-compose recharts children.
|
|
29
29
|
|
|
30
30
|
Cell colors come from the `palette` prop — a dataviz palette resolving to the
|
|
31
|
-
`--ui-dataviz-*` tokens, `
|
|
31
|
+
`--ui-dataviz-*` tokens, `diverging` (blue-orange) by default — not from `config`.
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
On-cell labels adapt their text color to three fill tones, decided structurally
|
|
34
|
+
by the resolved token name suffix (not a runtime luminance check):
|
|
35
|
+
|
|
36
|
+
- **dark** (diverging a3/b3, sequential 3–6, categorical, status): always white
|
|
37
|
+
text (`--ui-text-on-status-strong-neutral`).
|
|
38
|
+
- **pale** (diverging a2/b2/a1/b1, sequential 1–2): theme-adaptive text via
|
|
39
|
+
`--ui-text-on-surface-primary` (dark in light, light in dark).
|
|
40
|
+
- **inverts** (sequential 7–8, whose `light-dark()` values mirror across themes):
|
|
41
|
+
`--ui-text-on-status-strong-primary` — near-white in light (fill is dark),
|
|
42
|
+
near-black in dark (fill is pale).
|
|
38
43
|
|
|
39
44
|
## When to use
|
|
40
45
|
|
|
@@ -67,16 +72,10 @@ const data = [
|
|
|
67
72
|
];
|
|
68
73
|
|
|
69
74
|
const config = {
|
|
70
|
-
React: { label: 'React'
|
|
71
|
-
Vue: { label: 'Vue'
|
|
72
|
-
Angular: {
|
|
73
|
-
|
|
74
|
-
color: 'var(--ui-background-status-strong-danger)',
|
|
75
|
-
},
|
|
76
|
-
Svelte: {
|
|
77
|
-
label: 'Svelte',
|
|
78
|
-
color: 'var(--ui-background-status-strong-warning)',
|
|
79
|
-
},
|
|
75
|
+
React: { label: 'React' },
|
|
76
|
+
Vue: { label: 'Vue' },
|
|
77
|
+
Angular: { label: 'Angular' },
|
|
78
|
+
Svelte: { label: 'Svelte' },
|
|
80
79
|
} satisfies ChartConfig;
|
|
81
80
|
|
|
82
81
|
<Treemap
|
|
@@ -88,11 +87,9 @@ const config = {
|
|
|
88
87
|
/>;
|
|
89
88
|
```
|
|
90
89
|
|
|
91
|
-
Cell colors
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
in some white-label brands), so it is not color-stable across brands until the
|
|
95
|
-
real data-viz palette lands.
|
|
90
|
+
Cell colors are assigned automatically from the active `palette` (diverging
|
|
91
|
+
blue-orange by default). The `--ui-dataviz-*` tokens are `light-dark()` pairs,
|
|
92
|
+
so light/dark and brand overrides come for free.
|
|
96
93
|
|
|
97
94
|
## Props
|
|
98
95
|
|
|
@@ -104,7 +101,7 @@ real data-viz palette lands.
|
|
|
104
101
|
| `nameKey` | `string` | — | yes | The field that keys each leaf (drives the legend, tooltip, and `--color-<name>` lookup). Values should be unique and CSS-safe (they become part of a custom-property name) — the human name shown on the tile is the leaf's config label. |
|
|
105
102
|
| `aspectRatio` | `number` | `1.3333` | no | Width-to-height ratio the tiling targets (default 4 / 3). |
|
|
106
103
|
| `showLabels` | `boolean` | `true` | no | Render each leaf's label inside its cell (when it fits). |
|
|
107
|
-
| `labelAlign` | `'bottom-start' | 'top-start' | 'center'` | `'
|
|
104
|
+
| `labelAlign` | `'bottom-start' | 'top-start' | 'center'` | `'center'` | no | Where a cell's label block sits — centered in the tile (the Figma-canonical default), anchored at the tile's bottom start corner, or at its top start corner. Named for the start edge, not a physical one: the corner variants mirror under dir="rtl". |
|
|
108
105
|
| `secondaryKeys` | `ReadonlyArray<string>` | — | no | Fields whose values make up a second label line under the leaf's name (e.g. a value and a count). Dropped on cells too short to hold it. |
|
|
109
106
|
| `secondaryFormatter` | `(value: number | string, index?: number) => string` | — | no | Format each secondary value. Receives the field's index in secondaryKeys, so one formatter can cover fields of different kinds. |
|
|
110
107
|
| `secondarySeparator` | `string` | `' · '` | no | Separator drawn between multiple secondary values. |
|
|
@@ -134,7 +131,7 @@ Scenario: Render cells from data and config
|
|
|
134
131
|
```gherkin
|
|
135
132
|
Scenario: On-cell labels
|
|
136
133
|
Given showLabels is true
|
|
137
|
-
Then each cell large enough shows its name
|
|
134
|
+
Then each cell large enough shows its name centered in the tile (the default)
|
|
138
135
|
And the name shown is the leaf's config label, falling back to its nameKey value
|
|
139
136
|
But small cells omit the label to avoid overflow
|
|
140
137
|
And when showLabels is false no labels render
|
|
@@ -143,19 +140,29 @@ Scenario: On-cell labels
|
|
|
143
140
|
```gherkin
|
|
144
141
|
Scenario: Tiles are separated by the surface, not a stroke
|
|
145
142
|
Given any data
|
|
146
|
-
Then each tile is inset inside its node's rectangle
|
|
143
|
+
Then each tile is inset inside its node's rectangle (sharp corners, no rounding)
|
|
147
144
|
And the gap between neighbouring tiles is the chart's surface showing through
|
|
148
145
|
```
|
|
149
146
|
|
|
150
147
|
```gherkin
|
|
151
148
|
Scenario: Label alignment
|
|
152
|
-
Given labelAlign is "
|
|
153
|
-
Then the label block is anchored at the tile's top start corner
|
|
149
|
+
Given labelAlign is "bottom-start" or "top-start"
|
|
150
|
+
Then the label block is anchored at the tile's bottom or top start corner
|
|
151
|
+
And the default ("center") centers the block in the tile
|
|
154
152
|
And what the alignment aligns is the block, not its first line
|
|
155
153
|
And a corner-anchored block hugs the tile's start edge, so it mirrors under dir="rtl"
|
|
156
154
|
And every alignment leaves each line as wide as the tile, so it can still ellipsize
|
|
157
155
|
```
|
|
158
156
|
|
|
157
|
+
```gherkin
|
|
158
|
+
Scenario: Adaptive text color (three tones)
|
|
159
|
+
Given a palette with dark, pale, and theme-inverting stops
|
|
160
|
+
Then "dark" fills (diverging a3/b3, sequential 3–6, categorical, status) use white text (--ui-text-on-status-strong-neutral)
|
|
161
|
+
And "pale" fills (diverging a2/b2/a1/b1, sequential 1–2) use on-surface-primary (dark in light, light in dark)
|
|
162
|
+
And "inverts" fills (sequential 7–8, which mirror across themes) use on-strong-primary (near-white in light, near-black in dark)
|
|
163
|
+
And the decision is structural (based on the resolved token name suffix), not a runtime luminance check
|
|
164
|
+
```
|
|
165
|
+
|
|
159
166
|
```gherkin
|
|
160
167
|
Scenario: A second label line
|
|
161
168
|
Given secondaryKeys naming other fields on the row
|
|
@@ -236,19 +243,23 @@ Scenario: Reduced motion
|
|
|
236
243
|
- Do **not** rely on color alone to distinguish cells. The on-cell labels name
|
|
237
244
|
the larger cells; keep `showTooltip` on so small (unlabelled) cells are still
|
|
238
245
|
identifiable on hover.
|
|
239
|
-
- On-cell labels
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
- On-cell labels **adapt their text color** to three fill tones (structural,
|
|
247
|
+
based on the token name suffix — not a runtime luminance check):
|
|
248
|
+
- **dark** (diverging a3/b3, sequential 3–6, categorical, status): white via
|
|
249
|
+
`--ui-text-on-status-strong-neutral`.
|
|
250
|
+
- **pale** (diverging a2/b2/a1/b1, sequential 1–2): dark/light via
|
|
251
|
+
`--ui-text-on-surface-primary`.
|
|
252
|
+
- **inverts** (sequential 7–8, whose fills mirror across themes): near-white
|
|
253
|
+
in light, near-black in dark via `--ui-text-on-status-strong-primary`.
|
|
254
|
+
The tooltip chrome and cell separators resolve to semantic `--ui-*` tokens
|
|
255
|
+
that meet contrast in both themes.
|
|
246
256
|
- Watch recharts issue [#4809](https://github.com/recharts/recharts/issues/4809)
|
|
247
257
|
on the a11y layer for heavily-customized charts.
|
|
248
258
|
|
|
249
259
|
## Contrast
|
|
250
260
|
|
|
251
261
|
Tooltip chrome and the surface-colored cell separators meet contrast in both
|
|
252
|
-
themes via the semantic tokens. Cell fills come from
|
|
253
|
-
|
|
254
|
-
adjacent cells distinguishable
|
|
262
|
+
themes via the semantic tokens. Cell fills come from the active palette's
|
|
263
|
+
`--ui-dataviz-*` tokens. The adaptive label text ensures contrast on every
|
|
264
|
+
palette-assigned stop; adjacent cells are kept distinguishable by the
|
|
265
|
+
interleaved/ramp ordering of the palette.
|
package/dist/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Acronis UI Kit for React — LLM Reference
|
|
2
2
|
|
|
3
|
-
> `@acronis-platform/ui-react` v5.
|
|
3
|
+
> `@acronis-platform/ui-react` v5.1.0
|
|
4
4
|
|
|
5
5
|
Machine-readable component reference compiled from framework-agnostic specs.
|
|
6
6
|
Each entry links to a self-contained markdown file with props, behavior,
|
|
@@ -29,8 +29,9 @@ accessibility notes, and usage examples.
|
|
|
29
29
|
|
|
30
30
|
- [AreaChart](./llms/area-chart.md): A typed area-chart composition over the shared `Chart` primitives. Takes `data` + `config` + a set of series `dataKeys` and renders a themed recharts `AreaChart` inside a `ChartContainer`, with tooltip and legend chrome. Two variant axes: `layout` (single / stacked areas) and `fill` (solid flat fill / vertical gradient); single vs multi area is driven by the number of `dataKeys`. Ported from the apps/demo `AreaChartPlayground`.
|
|
31
31
|
- [Avatar](./llms/avatar.md): A user or entity avatar — a circular badge showing a profile image, initials, or an icon. Eight color schemes; stack several with AvatarGroup for an overlapping row.
|
|
32
|
-
- [BarChart](./llms/bar-chart.md):
|
|
32
|
+
- [BarChart](./llms/bar-chart.md): Two renderings behind one name, selected by `orientation`. `vertical` (the default) is a typed bar-chart composition over the shared `Chart` primitives: `data` + `config` + a set of series `dataKeys` become a themed recharts `BarChart` inside a `ChartContainer`, with tooltip and legend chrome, grouped or stacked by `layout`. `horizontal` is a labelled proportional bar list — one row per `items` entry carrying its label, value, share of `max`, and a track bar — with no axes, grid, or recharts at all.
|
|
33
33
|
- [CardFilter](./llms/card-filter.md): A compact stat/filter card: a caption label above a prominent value, with an optional leading icon. Three variants — `static` (presentational), `static-empty` (presentational placeholder with an em-dash), and `clickable` (an interactive filter that renders a button with hover / active / focus states).
|
|
34
|
+
- [CardWidgetCarousel](./llms/card-widget-carousel.md): A horizontal scroll carousel that holds a row of action-widget cards and exposes floating Previous/Next chevron buttons to navigate the view. The carousel shell manages scroll; the individual cards are passed as `children`. Ships with a companion `CardWidget` component (same barrel) — a status-colored card with icon box, optional skeleton, and footer slot.
|
|
34
35
|
- [CategoryBar](./llms/category-bar.md): A single horizontal bar split into proportional colored segments — one part-to-whole across a handful of categories in one row (onboarding stages, certification status, a pass/fail split). Each segment's width is its value over the sum of all values; segment colors are caller-supplied via `config`. A plain flex composition (not a recharts chart) with one CVA axis (`size`), an optional count/% legend, and per-segment hover tooltips. Design-pending v1 — no chart token tier exists yet.
|
|
35
36
|
- [Chart](./llms/chart.md): A theming layer over recharts — a `ChartContainer` that supplies series colors and recharts class overrides, plus tooltip and legend chrome (`ChartTooltipContent`, `ChartLegendContent`). The chart type (bar / line / area / pie / …) is composed from recharts primitives by the caller. Ported from the legacy shadcn-uikit `chart`.
|
|
36
37
|
- [ChartState](./llms/chart-state.md): A shared loading / empty / error placeholder for the chart types, rendered in place of the chart inside the same sized slot. A compact status block — a leading glyph over a centered label, with an optional retry action for the error state. The `empty` state draws the silhouette the design defines for each chart type (`variant`), plus an optional "Widget description" line; `loading` and `error` share one treatment. Distinct from `WidgetPlaceholder`, which is the composable skeleton for a widget that isn't a chart — see behavior.md.
|
|
@@ -47,7 +48,6 @@ accessibility notes, and usage examples.
|
|
|
47
48
|
- [FunnelChart](./llms/funnel-chart.md): A typed funnel-chart composition over the shared `Chart` primitives. The root is a row: a 120×120 square plot, a 16px gutter, then a stage-list legend taking every remaining pixel — the same composition `PieChart` and `RadialBarChart` use. The plot stacks one series of stages (`data` rows) as narrowing, 2px-gapped, 2px-rounded segments inside a `ChartContainer`, with a tooltip and optional on-plot labels. One variant axis: `lastShape` (the funnel narrows to a `triangle` point or ends `rectangle` flat). Stages are painted from the sequential blue ramp by default, because a funnel's stages are an ordered series rather than unrelated categories. Card-less by design: Figma's card, header and metric row are `ChartWidget`'s.
|
|
48
49
|
- [Histogram](./llms/histogram.md): A frequency histogram — bins a set of continuous samples (`values`) into equal-width ranges and plots the count of each as contiguous bars. Distinct from `BarChart`, which plots pre-categorized rows: the binning is the component's own job (a pure helper). Built on the shared `Chart` primitives; design-pending v1 (no `--ui-chart-*` palette yet, no `apps/demo` playground).
|
|
49
50
|
- [LineChart](./llms/line-chart.md): A typed line-chart composition over the shared `Chart` primitives. Takes `data` + `config` + a set of series `dataKeys` and renders a themed recharts `LineChart` inside a `ChartContainer`, with tooltip and legend chrome. Two variant axes: `curve` (linear / monotone / step interpolation) and `lineStyle` (solid / dashed stroke); single vs multi line is driven by the number of `dataKeys`. Ported from the apps/demo `ChartPlayground`.
|
|
50
|
-
- [Meter](./llms/meter.md): A labelled bar showing a scalar value within a known range — a fractional value / share (`role="meter"`, mirroring the HTML `<meter>` element), as opposed to `Progress` which tracks a task over time. One row: label + `value · %` over a proportional track bar, with a hover tooltip; designed to be stacked into a ranked breakdown (a "bar list"). Design-pending v1 (no `--ui-chart-*` palette; the fill color is caller-supplied per row).
|
|
51
51
|
- [Metric](./llms/metric.md): A presentational stats strip: an optional info-tinted icon badge + primary value + unit on the left, an optional caption on the right, an optional trend row (auto-composed from `trend` + `trendValue` as a `TrendIndicator`), optional supporting text, and an optional `children` body (a chart, Separator, insight line, …). No Card wrapper, no size or status axes — nest inside `ChartWidget` or a `Card` when card chrome is needed. It owns visual hierarchy and layout only; it never computes or formats the value or decides whether a change is good or bad. Design-pending v1.
|
|
52
52
|
- [PieChart](./llms/pie-chart.md): A typed pie/donut-chart composition over the shared `Chart` primitives. Takes `data` + `config` + a `dataKey` (slice value) and `nameKey` (slice label) and renders a themed recharts `PieChart` inside a `ChartContainer`, with tooltip and legend chrome. One variant axis: `shape` (filled pie / hollow-centre donut). Ported from the apps/demo `PieChartPlayground`.
|
|
53
53
|
- [RadarChart](./llms/radar-chart.md): A typed radar-chart composition over the shared `Chart` primitives (the first polar chart type). Plots a set of series `dataKeys` over one shared angular axis (`angleKey`) inside a `ChartContainer`, with a polar grid, tooltip, and legend. One variant axis: `gridType` (the web drawn as straight-edged `polygon` rings or smooth `circle` rings). Ported from the apps/demo `RadarChartPlayground`.
|
|
@@ -128,6 +128,7 @@ accessibility notes, and usage examples.
|
|
|
128
128
|
- [Stepper](./llms/stepper.md): The root of a step sequence. It renders the sequence two ways and lets CSS pick one: on wide viewports a start-aligned, wrapping row of `StepperItem` children; on narrow ones a two-line text summary — "Step 3 of 5: <current step>" and "Next: <next step>" — with no items at all. The switch is a real viewport media query (Tailwind's `lg:`, `min-width: 1024px`), not a JS measurement, so both subtrees are always in the DOM and only one is ever displayed. It owns that layout switch and the summary copy only: the steps, their order, which one is current, and all navigation belong to the application.
|
|
129
129
|
- [StepperItem](./llms/stepper-item.md): One step in a stepper — a consumer-composed avatar marker followed by the step name. `variant` is the step's structural role in the sequence (`current`, `completed`, `future`) and drives the container background, border, and label color; `state` is the interaction look and only changes anything on a completed step. The component owns the container and the label only: the marker is supplied and styled entirely by the caller, and the row layout, the step sequence, its ordering, and navigation belong to `Stepper` and the application.
|
|
130
130
|
- [Tabs](./llms/tabs.md): Switches between related panels of content within the same context. A bordered segmented-control tab group (list, trigger, content) built on the Base UI Tabs primitive. Ported from the legacy shadcn-uikit `Tabs`; themed by the shared semantic tokens (no `--ui-tabs-*` tier yet).
|
|
131
|
+
- [TreeItem](./llms/tree-item.md): One flat row of a tree or nested-list UI — an optional expand chevron, an optional checkbox, an optional leading icon, the row title, and an optional trailing extras slot. It is a single row and nothing more: it renders no nested list and implements no expand/collapse, so `isExpandable` and `expanded` are purely visual affordances and `selected` is a prop the consumer drives. The tree itself — its ARIA roles, indentation, expand state, selection, and keyboard roving — belongs to the composition, the same way `Breadcrumb` ships the trail's primitives without owning the trail.
|
|
131
132
|
|
|
132
133
|
## Overlay
|
|
133
134
|
|