@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.
Files changed (65) hide show
  1. package/dist/components/ui/area-chart/area-chart.js +191 -85
  2. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  3. package/dist/components/ui/bar-chart/bar-chart.js +288 -225
  4. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  5. package/dist/components/ui/card-widget-carousel/card-widget-carousel.js +85 -0
  6. package/dist/components/ui/card-widget-carousel/card-widget-carousel.js.map +1 -0
  7. package/dist/components/ui/card-widget-carousel/card-widget.js +82 -0
  8. package/dist/components/ui/card-widget-carousel/card-widget.js.map +1 -0
  9. package/dist/components/ui/category-bar/category-bar.js.map +1 -1
  10. package/dist/components/ui/chart/chart-format.js +25 -22
  11. package/dist/components/ui/chart/chart-format.js.map +1 -1
  12. package/dist/components/ui/chart/chart-palette.js +9 -8
  13. package/dist/components/ui/chart/chart-palette.js.map +1 -1
  14. package/dist/components/ui/chart/chart.js +118 -83
  15. package/dist/components/ui/chart/chart.js.map +1 -1
  16. package/dist/components/ui/line-chart/line-chart.js +194 -86
  17. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  18. package/dist/components/ui/scatter-chart/scatter-chart.js +5 -2
  19. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  20. package/dist/components/ui/separator/separator.js +52 -10
  21. package/dist/components/ui/separator/separator.js.map +1 -1
  22. package/dist/components/ui/sidebar-secondary/sidebar-secondary.js +144 -121
  23. package/dist/components/ui/sidebar-secondary/sidebar-secondary.js.map +1 -1
  24. package/dist/components/ui/tree-item/tree-item.js +67 -0
  25. package/dist/components/ui/tree-item/tree-item.js.map +1 -0
  26. package/dist/components/ui/treemap/treemap.js +73 -66
  27. package/dist/components/ui/treemap/treemap.js.map +1 -1
  28. package/dist/index.js +109 -107
  29. package/dist/llms/area-chart.md +2 -1
  30. package/dist/llms/bar-chart.md +132 -33
  31. package/dist/llms/card-widget-carousel.md +252 -0
  32. package/dist/llms/category-bar.md +2 -2
  33. package/dist/llms/line-chart.md +2 -1
  34. package/dist/llms/metric.md +10 -5
  35. package/dist/llms/scatter-chart.md +2 -1
  36. package/dist/llms/separator.md +27 -8
  37. package/dist/llms/sidebar-secondary.md +235 -4
  38. package/dist/llms/tree-item.md +359 -0
  39. package/dist/llms/treemap.md +47 -36
  40. package/dist/llms.txt +4 -3
  41. package/dist/react.js +109 -107
  42. package/dist/src/components/ui/area-chart/area-chart.d.ts +10 -0
  43. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +75 -10
  44. package/dist/src/components/ui/bar-chart/bar-chart.docs.d.ts +146 -0
  45. package/dist/src/components/ui/bar-chart/index.d.ts +1 -1
  46. package/dist/src/components/ui/card-widget-carousel/card-widget-carousel.d.ts +9 -0
  47. package/dist/src/components/ui/card-widget-carousel/card-widget.d.ts +43 -0
  48. package/dist/src/components/ui/card-widget-carousel/index.d.ts +2 -0
  49. package/dist/src/components/ui/chart/chart-format.d.ts +9 -1
  50. package/dist/src/components/ui/chart/chart-palette.d.ts +38 -10
  51. package/dist/src/components/ui/chart/index.d.ts +2 -2
  52. package/dist/src/components/ui/line-chart/line-chart.d.ts +11 -1
  53. package/dist/src/components/ui/separator/separator.d.ts +9 -1
  54. package/dist/src/components/ui/sidebar-secondary/sidebar-secondary.d.ts +23 -3
  55. package/dist/src/components/ui/tree-item/index.d.ts +1 -0
  56. package/dist/src/components/ui/tree-item/tree-item.d.ts +64 -0
  57. package/dist/src/components/ui/treemap/treemap.d.ts +16 -5
  58. package/dist/src/index.d.ts +2 -1
  59. package/dist/ui-react.css +1 -1
  60. package/package.json +3 -3
  61. package/dist/components/ui/meter/meter.js +0 -79
  62. package/dist/components/ui/meter/meter.js.map +0 -1
  63. package/dist/llms/meter.md +0 -177
  64. package/dist/src/components/ui/meter/index.d.ts +0 -1
  65. 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.
@@ -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, `categorical` by default — not from `config`.
31
+ `--ui-dataviz-*` tokens, `diverging` (blue-orange) by default — not from `config`.
32
32
 
33
- > **Design-pending v1.** Ported from the apps/demo `TreemapChartPlayground`.
34
- > On-cell labels still use `--ui-text-on-status-strong-neutral` — a generic
35
- > "text on a colored surface" color — over the palette's cell fills, so the
36
- > palette owes matched per-stop label colors. The chrome is reconciled with Figma
37
- > later; Code Connect is deferred.
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', color: 'var(--ui-background-brand-secondary)' },
71
- Vue: { label: 'Vue', color: 'var(--ui-background-status-strong-success)' },
72
- Angular: {
73
- label: 'Angular',
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 reference existing semantic `--ui-*` tokens, keyed by each leaf's
92
- `nameKey` value. `--ui-background-status-strong-*` is chromatic in every brand;
93
- `--ui-background-brand-secondary` is brand-dependent (blue in `default`, neutral
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'` | `'bottom-start'` | no | Where a cell's label block sits — anchored at the tile's bottom start corner (the design's placement), at its top start corner, or centered in the tile. Named for the start edge, not a physical one: the corner variants mirror under dir="rtl". |
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 at the tile's bottom start corner
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 and its corners are rounded
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 "top-start" or "center"
153
- Then the label block is anchored at the tile's top start corner, or centered in it
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 use the `--ui-text-on-status-strong-neutral` token ("text on a
240
- strong colored surface", constant white in both themes) to read over the
241
- saturated series colors. This is legible on the chromatic brand/status tokens
242
- used here but is **not** guaranteed for arbitrary caller colors — pick cell
243
- colors dark enough for the light label text (matched per-cell label colors are a
244
- design-pending item for the `--ui-chart-*` palette). The tooltip chrome and cell
245
- separators resolve to semantic `--ui-*` tokens that meet contrast in both themes.
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 `config` and are the
253
- caller's responsibility — keep them dark enough for the white on-cell labels, and
254
- adjacent cells distinguishable from each other.
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.0.0
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): A typed bar-chart composition over the shared `Chart` primitives. Takes `data` + `config` + a set of series `dataKeys` and renders a themed recharts `BarChart` inside a `ChartContainer`, with tooltip and legend chrome. Two variant axes: `orientation` (vertical / horizontal bars) and `layout` (grouped / stacked). Ported from the apps/demo `BarChartPlayground`.
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