@acronis-platform/ui-react 2.0.0 → 4.0.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 (243) hide show
  1. package/dist/components/ui/accordion-container/accordion-container.js +144 -0
  2. package/dist/components/ui/accordion-container/accordion-container.js.map +1 -0
  3. package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
  4. package/dist/components/ui/area-chart/area-chart.js +141 -139
  5. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  6. package/dist/components/ui/avatar/avatar.js +33 -22
  7. package/dist/components/ui/avatar/avatar.js.map +1 -1
  8. package/dist/components/ui/bar-chart/bar-chart.js +295 -293
  9. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  10. package/dist/components/ui/card/card.js +150 -74
  11. package/dist/components/ui/card/card.js.map +1 -1
  12. package/dist/components/ui/card-section/card-section.js +111 -0
  13. package/dist/components/ui/card-section/card-section.js.map +1 -0
  14. package/dist/components/ui/category-bar/category-bar.js +109 -93
  15. package/dist/components/ui/category-bar/category-bar.js.map +1 -1
  16. package/dist/components/ui/chart/chart-palette.js +113 -0
  17. package/dist/components/ui/chart/chart-palette.js.map +1 -0
  18. package/dist/components/ui/chart/chart.js +176 -129
  19. package/dist/components/ui/chart/chart.js.map +1 -1
  20. package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
  21. package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
  22. package/dist/components/ui/chart-state/chart-state.js +48 -34
  23. package/dist/components/ui/chart-state/chart-state.js.map +1 -1
  24. package/dist/components/ui/chart-widget/chart-widget.js +87 -0
  25. package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
  26. package/dist/components/ui/composed-chart/composed-chart.js +117 -115
  27. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
  28. package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
  29. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
  30. package/dist/components/ui/data-table/data-table.js +4 -2
  31. package/dist/components/ui/data-table/data-table.js.map +1 -1
  32. package/dist/components/ui/empty-overlay/empty-overlay.js +49 -0
  33. package/dist/components/ui/empty-overlay/empty-overlay.js.map +1 -0
  34. package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
  35. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
  36. package/dist/components/ui/histogram/histogram.js +94 -92
  37. package/dist/components/ui/histogram/histogram.js.map +1 -1
  38. package/dist/components/ui/input/input.js.map +1 -1
  39. package/dist/components/ui/label/label.js +2 -9
  40. package/dist/components/ui/label/label.js.map +1 -1
  41. package/dist/components/ui/line-chart/line-chart.js +143 -141
  42. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  43. package/dist/components/ui/metric/metric.js +74 -185
  44. package/dist/components/ui/metric/metric.js.map +1 -1
  45. package/dist/components/ui/page-content/page-content.js.map +1 -1
  46. package/dist/components/ui/pie-chart/pie-chart.js +201 -195
  47. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
  48. package/dist/components/ui/radar-chart/radar-chart.js +133 -131
  49. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
  50. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
  51. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
  52. package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
  53. package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
  54. package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
  55. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  56. package/dist/components/ui/section/section.js +157 -31
  57. package/dist/components/ui/section/section.js.map +1 -1
  58. package/dist/components/ui/stepper/stepper.js +24 -24
  59. package/dist/components/ui/stepper/stepper.js.map +1 -1
  60. package/dist/components/ui/stepper-item/stepper-item.js +43 -24
  61. package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
  62. package/dist/components/ui/table/table.js +27 -27
  63. package/dist/components/ui/table/table.js.map +1 -1
  64. package/dist/components/ui/treemap/treemap.js +133 -124
  65. package/dist/components/ui/treemap/treemap.js.map +1 -1
  66. package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
  67. package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
  68. package/dist/components/ui/wizard/wizard.js +59 -0
  69. package/dist/components/ui/wizard/wizard.js.map +1 -0
  70. package/dist/hooks/use-wizard.js +75 -0
  71. package/dist/hooks/use-wizard.js.map +1 -0
  72. package/dist/index.js +540 -525
  73. package/dist/index.js.map +1 -1
  74. package/dist/llms/accordion-container.md +181 -0
  75. package/dist/llms/accordion.md +124 -0
  76. package/dist/llms/alert.md +225 -0
  77. package/dist/llms/app-shell-chat.md +415 -0
  78. package/dist/llms/area-chart.md +355 -0
  79. package/dist/llms/avatar.md +208 -0
  80. package/dist/llms/bar-chart.md +406 -0
  81. package/dist/llms/breadcrumb.md +326 -0
  82. package/dist/llms/button-group.md +298 -0
  83. package/dist/llms/button-icon-input.md +142 -0
  84. package/dist/llms/button-icon-menu.md +209 -0
  85. package/dist/llms/button-icon.md +128 -0
  86. package/dist/llms/button-menu.md +172 -0
  87. package/dist/llms/button.md +185 -0
  88. package/dist/llms/calendar-panel.md +733 -0
  89. package/dist/llms/calendar.md +188 -0
  90. package/dist/llms/card-filter.md +214 -0
  91. package/dist/llms/card-section.md +293 -0
  92. package/dist/llms/card.md +447 -0
  93. package/dist/llms/carousel-dialog.md +156 -0
  94. package/dist/llms/category-bar.md +193 -0
  95. package/dist/llms/chart-state.md +190 -0
  96. package/dist/llms/chart-widget.md +209 -0
  97. package/dist/llms/chart.md +182 -0
  98. package/dist/llms/checkbox.md +257 -0
  99. package/dist/llms/chip.md +195 -0
  100. package/dist/llms/combobox.md +164 -0
  101. package/dist/llms/composed-chart.md +508 -0
  102. package/dist/llms/confidence-cone.md +277 -0
  103. package/dist/llms/data-table.md +474 -0
  104. package/dist/llms/date-range-picker.md +272 -0
  105. package/dist/llms/description-list.md +131 -0
  106. package/dist/llms/dialog-footer-carousel.md +147 -0
  107. package/dist/llms/dialog-footer-default.md +142 -0
  108. package/dist/llms/dialog-root.md +246 -0
  109. package/dist/llms/dialog-welcome.md +223 -0
  110. package/dist/llms/dialog.md +403 -0
  111. package/dist/llms/dropdown-menu.md +193 -0
  112. package/dist/llms/empty-overlay.md +146 -0
  113. package/dist/llms/empty.md +156 -0
  114. package/dist/llms/field.md +185 -0
  115. package/dist/llms/filter-cards.md +157 -0
  116. package/dist/llms/filter-chips.md +323 -0
  117. package/dist/llms/filter-search.md +512 -0
  118. package/dist/llms/form.md +154 -0
  119. package/dist/llms/funnel-chart.md +333 -0
  120. package/dist/llms/grid.md +80 -0
  121. package/dist/llms/histogram.md +190 -0
  122. package/dist/llms/input-date-picker.md +203 -0
  123. package/dist/llms/input-otp.md +173 -0
  124. package/dist/llms/input-password.md +197 -0
  125. package/dist/llms/input-search.md +170 -0
  126. package/dist/llms/input-select.md +278 -0
  127. package/dist/llms/input-text-area.md +271 -0
  128. package/dist/llms/input-text.md +192 -0
  129. package/dist/llms/line-chart.md +369 -0
  130. package/dist/llms/link.md +209 -0
  131. package/dist/llms/loading.md +130 -0
  132. package/dist/llms/meter.md +177 -0
  133. package/dist/llms/metric.md +204 -0
  134. package/dist/llms/number-field.md +122 -0
  135. package/dist/llms/page-content.md +69 -0
  136. package/dist/llms/page-header.md +182 -0
  137. package/dist/llms/pagination.md +133 -0
  138. package/dist/llms/pie-chart.md +307 -0
  139. package/dist/llms/popover.md +252 -0
  140. package/dist/llms/progress-circle.md +126 -0
  141. package/dist/llms/progress.md +111 -0
  142. package/dist/llms/radar-chart.md +316 -0
  143. package/dist/llms/radial-bar-chart.md +319 -0
  144. package/dist/llms/radio.md +255 -0
  145. package/dist/llms/resizable.md +195 -0
  146. package/dist/llms/sankey-chart.md +208 -0
  147. package/dist/llms/scatter-chart.md +239 -0
  148. package/dist/llms/scroll-area.md +183 -0
  149. package/dist/llms/section.md +401 -0
  150. package/dist/llms/select.md +210 -0
  151. package/dist/llms/separator.md +87 -0
  152. package/dist/llms/sheet.md +202 -0
  153. package/dist/llms/sidebar-primary.md +360 -0
  154. package/dist/llms/sidebar-secondary.md +417 -0
  155. package/dist/llms/skeleton.md +81 -0
  156. package/dist/llms/slider.md +97 -0
  157. package/dist/llms/spinner.md +100 -0
  158. package/dist/llms/stack.md +80 -0
  159. package/dist/llms/stepper-item.md +309 -0
  160. package/dist/llms/stepper.md +251 -0
  161. package/dist/llms/switch.md +140 -0
  162. package/dist/llms/table.md +436 -0
  163. package/dist/llms/tabs.md +197 -0
  164. package/dist/llms/tag.md +139 -0
  165. package/dist/llms/timeline.md +361 -0
  166. package/dist/llms/timer.md +259 -0
  167. package/dist/llms/toast.md +241 -0
  168. package/dist/llms/toggle-group.md +121 -0
  169. package/dist/llms/toolbar.md +453 -0
  170. package/dist/llms/tooltip.md +164 -0
  171. package/dist/llms/treemap.md +254 -0
  172. package/dist/llms/trend-indicator.md +132 -0
  173. package/dist/llms/widget-placeholder.md +169 -0
  174. package/dist/llms/wizard.md +412 -0
  175. package/dist/llms.txt +142 -0
  176. package/dist/react.js +540 -525
  177. package/dist/react.js.map +1 -1
  178. package/dist/src/components/ui/accordion-container/accordion-container.d.ts +44 -0
  179. package/dist/src/components/ui/accordion-container/index.d.ts +1 -0
  180. package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
  181. package/dist/src/components/ui/avatar/avatar.d.ts +27 -8
  182. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
  183. package/dist/src/components/ui/button/button.d.ts +1 -1
  184. package/dist/src/components/ui/card/card.d.ts +69 -8
  185. package/dist/src/components/ui/card/index.d.ts +1 -1
  186. package/dist/src/components/ui/card-section/card-section.d.ts +50 -0
  187. package/dist/src/components/ui/card-section/index.d.ts +1 -0
  188. package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
  189. package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
  190. package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
  191. package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
  192. package/dist/src/components/ui/chart/chart.d.ts +66 -15
  193. package/dist/src/components/ui/chart/index.d.ts +4 -2
  194. package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
  195. package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
  196. package/dist/src/components/ui/chart-state/index.d.ts +1 -0
  197. package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
  198. package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
  199. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
  200. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
  201. package/dist/src/components/ui/dialog/dialog.d.ts +1 -1
  202. package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +20 -0
  203. package/dist/src/components/ui/empty-overlay/index.d.ts +2 -0
  204. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
  205. package/dist/src/components/ui/grid/grid.d.ts +1 -1
  206. package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
  207. package/dist/src/components/ui/label/index.d.ts +1 -1
  208. package/dist/src/components/ui/label/label.d.ts +1 -5
  209. package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
  210. package/dist/src/components/ui/metric/metric.d.ts +13 -14
  211. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
  212. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
  213. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
  214. package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
  215. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
  216. package/dist/src/components/ui/section/index.d.ts +1 -1
  217. package/dist/src/components/ui/section/section.d.ts +75 -6
  218. package/dist/src/components/ui/sheet/sheet.d.ts +1 -1
  219. package/dist/src/components/ui/stack/stack.d.ts +1 -1
  220. package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
  221. package/dist/src/components/ui/tag/tag.d.ts +1 -1
  222. package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
  223. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
  224. package/dist/src/components/ui/wizard/index.d.ts +1 -0
  225. package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
  226. package/dist/src/hooks/index.d.ts +1 -0
  227. package/dist/src/hooks/use-wizard.d.ts +80 -0
  228. package/dist/src/index.d.ts +5 -3
  229. package/dist/ui-react.css +1 -1
  230. package/package.json +12 -6
  231. package/dist/components/ui/app-shell/app-shell.js +0 -75
  232. package/dist/components/ui/app-shell/app-shell.js.map +0 -1
  233. package/dist/components/ui/auth-layout/auth-layout.js +0 -56
  234. package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
  235. package/dist/components/ui/collapsible/collapsible.js +0 -22
  236. package/dist/components/ui/collapsible/collapsible.js.map +0 -1
  237. package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
  238. package/dist/src/components/ui/app-shell/index.d.ts +0 -1
  239. package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
  240. package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
  241. package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
  242. package/dist/src/components/ui/collapsible/index.d.ts +0 -1
  243. package/dist/src/components/ui/label/label.docs.d.ts +0 -10
@@ -0,0 +1,100 @@
1
+ # Spinner
2
+
3
+ > An indeterminate loading indicator — a spinning ring in four sizes. Ported from the legacy shadcn-uikit `Spinner`; a CSS spinner (no primitive), colored by the shared brand token via currentColor. As of 0.58.0, deliberately NOT exported from `@acronis-platform/ui-react`'s public entry point — it is an internal primitive consumed by `Loading` (icon) and `Toast` (a small inline icon). Apps building a standalone loading state should use `Loading` instead.
4
+
5
+ **Status:** deprecated · **Category:** feedback · **Since:** v0.15.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ Not exported from '@acronis-platform/ui-react' — internal only, used by `Loading`/`Toast`.
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ // Internal usage only (packages/ui-react/src/components/ui/loading/loading.tsx,
17
+ // .../toast/toast.tsx) — not importable by app code:
18
+ <Spinner size="lg" className="text-muted-foreground" />
19
+ ```
20
+
21
+ An indeterminate loading indicator — a spinning ring in four sizes.
22
+
23
+ > **Status: deprecated (internal only).** As of 0.58.0, `Spinner` is
24
+ > deliberately **not** exported from `@acronis-platform/ui-react`'s public
25
+ > entry point — it's an internal primitive consumed by `Loading` (its icon)
26
+ > and `Toast` (a small inline icon). Building a standalone loading state? Use
27
+ > [`Loading`](../loading/README.md) instead; it wraps this same ring with a
28
+ > label and placement-context container tokens. Ported from the legacy
29
+ > `@acronis-platform/shadcn-uikit` `Spinner`. No `--ui-spinner-*` tier; the
30
+ > ring defaults to the brand blue (`text-secondary`) and is overridable via a
31
+ > `text-*` class.
32
+
33
+ ## When to use
34
+
35
+ - Nowhere directly — it's not part of the public component set. Compose it
36
+ only from inside another `ui-react` component that needs an icon-scale
37
+ spinning glyph (see `Loading`, `Toast`).
38
+
39
+ ## When not to use
40
+
41
+ - For an app-facing standalone loading state — use `Loading`.
42
+ - For determinate progress — use `Progress`.
43
+ - For content placeholders — use a skeleton.
44
+
45
+ ## Example
46
+
47
+ ```tsx
48
+ // Internal usage only — Spinner isn't exported for app code.
49
+ import { Spinner } from '../spinner';
50
+
51
+ <Spinner />
52
+ <Spinner size="lg" />
53
+ <Spinner size="sm" className="text-muted-foreground" />
54
+ ```
55
+
56
+ ## Props
57
+
58
+ | Prop | Type | Default | Required | Description |
59
+ |------|------|---------|----------|-------------|
60
+ | `size` | `'sm' | 'md' | 'lg' | 'xl'` | `'md'` | no | Diameter — sm 16 · md 24 · lg 32 · xl 48 (px). |
61
+
62
+ ## Behavior
63
+
64
+ Spinner is an indeterminate loading indicator. It has no internal state and no
65
+ interaction — it spins continuously while mounted.
66
+
67
+ ```gherkin
68
+ Scenario: Sizing
69
+ Given a Spinner with size="lg"
70
+ Then it renders a 32px ring (sm 16 · md 24 · lg 32 · xl 48)
71
+ ```
72
+
73
+ ```gherkin
74
+ Scenario: Color
75
+ Given a Spinner with no color override
76
+ Then the ring uses the brand blue (text-secondary via currentColor)
77
+ And a `text-*` className overrides it (e.g. text-muted-foreground on a busy surface)
78
+ ```
79
+
80
+ ```gherkin
81
+ Scenario: Reduced motion
82
+ Given a user with prefers-reduced-motion
83
+ Then the platform animation honors that preference (the ring is still shown)
84
+ ```
85
+
86
+ ## Accessibility
87
+
88
+ - The root is `role="status"` with `aria-label="Loading"` and an `sr-only`
89
+ "Loading…" label, so assistive tech announces the loading state when the
90
+ spinner appears.
91
+ - `role="status"` is a polite live region — placing the spinner into the DOM
92
+ announces it without stealing focus. For a specific context, override the label
93
+ (e.g. `aria-label="Loading workloads"`).
94
+ - The spinner is decorative motion; pair it with text when the wait is long.
95
+
96
+ ## Contrast
97
+
98
+ The ring defaults to `--ui-background-brand-secondary` (brand blue), which meets
99
+ non-text contrast against the page surface in light and dark. Override with a
100
+ `text-*` class where the context needs it.
@@ -0,0 +1,80 @@
1
+ # Stack
2
+
3
+ > A flexbox layout primitive — lay children out in a row or column with configurable gap, alignment, justification, and wrapping. Ported 1:1 from the legacy shadcn-uikit `stack`.
4
+
5
+ **Status:** draft · **Category:** layout · **Since:** v0.51.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { Stack } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ <Stack direction="horizontal" gap="sm">{children}</Stack>
17
+ ```
18
+
19
+ A flexbox layout primitive — arrange children in a row or column with a chosen
20
+ gap, alignment, justification, and wrapping.
21
+
22
+ > Design-pending v1, ported 1:1 from the legacy shadcn-uikit `stack`.
23
+
24
+ ## When to use
25
+
26
+ - Quick one-dimensional layouts (toolbars, button rows, vertical form stacks)
27
+ without hand-writing flex utilities.
28
+
29
+ ## When not to use
30
+
31
+ - Two-dimensional layouts — use `Grid`.
32
+
33
+ ## Parts
34
+
35
+ `Stack` is a single component.
36
+
37
+ ## Example
38
+
39
+ ```tsx
40
+ import { Stack } from '@acronis-platform/ui-react';
41
+
42
+ <Stack direction="horizontal" gap="sm" align="center">
43
+ <Button>Save</Button>
44
+ <Button variant="ghost">Cancel</Button>
45
+ </Stack>;
46
+ ```
47
+
48
+ ## Props
49
+
50
+ | Prop | Type | Default | Required | Description |
51
+ |------|------|---------|----------|-------------|
52
+ | `direction` | `'vertical' | 'horizontal'` | `'vertical'` | no | Main-axis direction (flex-col / flex-row). |
53
+ | `gap` | `'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'` | `'md'` | no | Space between children. |
54
+ | `align` | `'start' | 'center' | 'end' | 'stretch'` | `'stretch'` | no | Cross-axis alignment (align-items). |
55
+ | `justify` | `'start' | 'center' | 'end' | 'between'` | `'start'` | no | Main-axis distribution (justify-content). |
56
+ | `wrap` | `boolean` | `false` | no | Whether children wrap onto multiple lines. |
57
+
58
+ ## Behavior
59
+
60
+ ```gherkin
61
+ Scenario: Arrange children
62
+ Given a Stack with direction / gap / align / justify
63
+ Then its children lay out as a flex row or column with that spacing and alignment
64
+ ```
65
+
66
+ ```gherkin
67
+ Scenario: Wrap
68
+ Given wrap is set
69
+ Then children wrap onto multiple lines when they overflow
70
+ ```
71
+
72
+ ## Accessibility
73
+
74
+ Stack is a presentational layout `<div>` with no semantics of its own. It does not
75
+ change reading order — children are laid out in source order. Choose a semantic
76
+ wrapper (e.g. `Section`, `<ul>`) where the content calls for one.
77
+
78
+ ## Contrast
79
+
80
+ No color; nothing to evaluate.
@@ -0,0 +1,309 @@
1
+ # StepperItem
2
+
3
+ > 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.
4
+
5
+ **Status:** ready · **Category:** navigation · **Since:** v0.63.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { StepperItem } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ <StepperItem
17
+ variant="completed"
18
+ label="Create an account"
19
+ avatar={<Avatar color="green"><CheckIcon size={16} /></Avatar>}
20
+ render={<button type="button" onClick={goToStep(1)} />}
21
+ />
22
+ <StepperItem
23
+ variant="current"
24
+ label="Choose a plan"
25
+ avatar={<Avatar color="blue"><AvatarFallback>2</AvatarFallback></Avatar>}
26
+ />
27
+ ```
28
+
29
+ One step in a stepper: a consumer-composed avatar marker followed by the step
30
+ name. `variant` says where the step sits in the sequence (`current`,
31
+ `completed`, `future`) and drives the container fill, border, and the label
32
+ color; `state` is the interaction look, and it only changes anything on a
33
+ completed step. Compose the steps inside `Stepper`, which lays them out.
34
+
35
+ ## When to use
36
+
37
+ - A wizard / checkout / onboarding progress indicator, one `StepperItem` per step.
38
+ - Any short, ordered sequence where the user needs to see what is done, where they
39
+ are, and what is still ahead — and can jump back to a completed step.
40
+
41
+ ## When not to use
42
+
43
+ - To show progress as a single quantity — use `Progress` or `ProgressCircle`.
44
+ - For a chronological log of things that already happened — use `Timeline`.
45
+ - As the whole stepper — that is `Stepper`, which lays the steps out in a row and
46
+ adds the compact, narrow-viewport summary. Don't hand-roll that row. The
47
+ application still decides each step's `variant` and owns the navigation.
48
+
49
+ ## Usage
50
+
51
+ ```tsx
52
+ <Stepper
53
+ currentStep={2}
54
+ totalSteps={3}
55
+ current="Choose a plan"
56
+ next="Confirm and pay"
57
+ >
58
+ <StepperItem
59
+ variant="completed"
60
+ label="Create an account"
61
+ avatar={
62
+ <Avatar color="green" className="[box-shadow:none]">
63
+ <CheckIcon size={16} />
64
+ </Avatar>
65
+ }
66
+ render={<button type="button" onClick={() => goToStep(1)} />}
67
+ />
68
+ <StepperItem
69
+ variant="current"
70
+ label="Choose a plan"
71
+ avatar={
72
+ <Avatar
73
+ color="blue"
74
+ className="[box-shadow:none] text-[var(--ui-stepper-item-current-label-color)]"
75
+ >
76
+ <AvatarFallback>2</AvatarFallback>
77
+ </Avatar>
78
+ }
79
+ />
80
+ <StepperItem
81
+ variant="future"
82
+ label="Confirm and pay"
83
+ avatar={
84
+ <Avatar
85
+ color="gray"
86
+ className="[box-shadow:none] text-[var(--ui-stepper-item-future-label-color)]"
87
+ >
88
+ <AvatarFallback>3</AvatarFallback>
89
+ </Avatar>
90
+ }
91
+ />
92
+ </Stepper>
93
+ ```
94
+
95
+ The marker is entirely yours: color scheme, initials vs. icon vs. image, size
96
+ overrides. The step renders the element verbatim and never restyles it — with
97
+ two caveats the caller applies via `className`, both shown above:
98
+
99
+ - Figma recolors the digit inside a `current`/`future` avatar to that step's
100
+ own label-color token, overriding `Avatar`'s usual per-scheme color
101
+ (`completed`'s checkmark is a fixed icon, so it needs none).
102
+ - `Avatar`'s 2px outset ring (`box-shadow`, meant to separate overlapping
103
+ avatars in an `AvatarGroup`) is switched off with `[box-shadow:none]` —
104
+ Figma's `StepperItem` avatars carry no stroke, and left on, the ring shows
105
+ as an unwanted halo on `current`'s blue fill and on `completed`'s
106
+ hover/active fills. See "Design status" below.
107
+
108
+ Only six `variant` x `state` combinations exist in the design, and the
109
+ component reproduces exactly that: `current` is always highlighted with a
110
+ border, `future` is always disabled, and only `completed` reads `state`
111
+ (`idle`, `hover`, `active`, `focus`).
112
+
113
+ `current` is the only variant that paints a visible border, but every variant
114
+ reserves the same border box (transparent on `completed` and `future`), so the
115
+ three render at the same size and a row of steps stays aligned.
116
+
117
+ ## Parts
118
+
119
+ | Part | Element | Notes |
120
+ | ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
121
+ | container (root) | `div` | Polymorphic via `render`; carries the fill, the focus ring, and a future step's `aria-disabled` / `tabindex="-1"` |
122
+ | `avatar-slot` | — | Required; the caller's `Avatar`, rendered verbatim |
123
+ | `label` | `span` | The step name; truncates |
124
+
125
+ ## Design status
126
+
127
+ The Figma component has a dedicated `--ui-stepper-item-*` token tier as of the
128
+ 2026-08-24 sync — see `tokens.yaml` for the full list.
129
+
130
+ **Resolved quirk — `Avatar`'s 2px ring on colored step backgrounds.**
131
+ `Avatar` always paints a 2px `--ui-avatar-global-avatar-border-color` ring
132
+ (white in light mode), meant to separate overlapping avatars in an
133
+ `AvatarGroup`. Figma's own `StepperItem` composition never draws this ring
134
+ (verified in the raw reference markup — none of the `current`/`completed`/
135
+ `future` avatar instances carry a border/box-shadow class), so it's invisible
136
+ where a step's container fill is transparent but becomes a visible halo on
137
+ `current`'s blue background and on `completed`'s hover/active fills. This is a
138
+ pre-existing `Avatar`-wide behavior (present anywhere an avatar sits on a
139
+ colored surface, e.g. `Timeline`'s marker), not something `StepperItem`
140
+ introduces or can fix by itself — `StepperItem` is documented to render the
141
+ marker verbatim, so the caller switches the ring off with
142
+ `className="[box-shadow:none]"` on the composed `Avatar`, as shown in Usage
143
+ above (the same pattern `Timeline`'s marker already used).
144
+
145
+ ## Props
146
+
147
+ | Prop | Type | Default | Required | Description |
148
+ |------|------|---------|----------|-------------|
149
+ | `variant` | `'current' | 'completed' | 'future'` | `current` | no | The step's structural role in the sequence. `current` is where the user is and always renders highlighted with a border; `completed` is already passed and is the only variant whose look responds to `state`; `future` is not reachable yet and always renders disabled and non-interactive. Defaults to `current` for prop ergonomics — in a real sequence every step declares its own. |
150
+ | `state` | `'idle' | 'hover' | 'active' | 'focus'` | `idle` | no | The interaction look. Only observable when `variant` is `completed` (`idle`, `hover`, and `active` each paint their own fill token — `idle`'s resolves to `transparent` in the shipped brands, so it reads as no fill; `focus` draws a 3px ring — its token is byte-identical to `--ui-focus-primary`, i.e. the same look `focus-visible` already draws automatically on a composed control). Ignored for `current`, which is always highlighted, and for `future`, which is always disabled. It is a declarative prop, not a CSS pseudo-state, because the design models it as distinct token roles and a consumer may need to force it. |
151
+ | `avatar` | `Element` | — | yes | The step's marker — an avatar element supplied and styled entirely by the caller (color scheme, initials / icon / image, size overrides). The step renders it verbatim and never restyles it. |
152
+ | `label` | `ReactNode` | — | no | The step name. Truncates rather than wrapping. |
153
+ | `render` | `RenderProp` | — | no | Base UI composition prop — replaces the rendered `<div>` with another element or component while merging props and classes. Use it to make a completed step a real `<button>` (or a router link) that jumps back. React-only; other frameworks use their own polymorphism. |
154
+
155
+ ## Events
156
+
157
+ | Event | Payload | Description |
158
+ |-------|---------|-------------|
159
+ | `onClick` | `(event: MouseEvent) => void` | Fired on activation. Only meaningful once the step is rendered as a real control via `render` — the default `<div>` is not focusable, and a future step does not receive pointer events at all. |
160
+
161
+ ## Content slots
162
+
163
+ | Slot | Description |
164
+ |------|-------------|
165
+ | `default` | Optional trailing content rendered after the label (e.g. a status tag). The marker and the step name come from `avatar` and `label`, not children. |
166
+
167
+ ## Behavior
168
+
169
+ ### Renders a marker and a name
170
+
171
+ - **Given** an `avatar`
172
+ **Then** it renders first inside the container, exactly as passed — the step
173
+ never sizes, tints, or recolors it.
174
+ - **Given** a `label`
175
+ **Then** it renders after the marker and truncates rather than wrapping.
176
+ - **Given** no `label`
177
+ **Then** only the marker renders; the container keeps its padding.
178
+ - **Given** `children`
179
+ **Then** they render last, after the label.
180
+
181
+ ### Variant drives the step's role
182
+
183
+ - **Given** `variant="current"`
184
+ **Then** the container is filled and bordered with the current-step tokens
185
+ and the name uses the current-step label color — regardless of `state`,
186
+ because the design draws the current step in exactly one look.
187
+ - **Given** `variant="completed"`
188
+ **Then** the name uses the completed-step label color and the container takes
189
+ the fill token for its `state`.
190
+ - **Given** `variant="future"`
191
+ **Then** the name uses the future-step label color, the container takes the
192
+ future-step container fill — `transparent` in every shipped brand, so nothing
193
+ paints today, but a brand that overrides it is honored — the element is marked
194
+ `aria-disabled`, it is removed from the tab order (`tabindex="-1"`), and it
195
+ receives no pointer events — again regardless of `state`. On the default
196
+ `<div>` it also carries `role="link"`, without which
197
+ `aria-disabled` would not be announced at all (see `accessibility.md`).
198
+ - **Given** any `variant`
199
+ **Then** the container reserves the same border box, so all three variants
200
+ measure the same and a row of steps keeps its markers and names aligned. Only
201
+ `current` paints a visible border color; on `completed` and `future` the
202
+ reserved border is transparent.
203
+
204
+ ### State is only observable on a completed step
205
+
206
+ - **Given** `variant="completed"` **and** `state="idle"`
207
+ **Then** the container is filled with the idle token, which resolves to
208
+ `transparent` in every shipped brand — so it reads as no fill today, but a
209
+ brand that overrides it is honored.
210
+ - **Given** `variant="completed"` **and** `state="hover"`
211
+ **Then** the container is filled with the hover token.
212
+ - **Given** `variant="completed"` **and** `state="active"`
213
+ **Then** the container is filled with the active token.
214
+ - **Given** `variant="completed"` **and** `state="focus"`
215
+ **Then** the container shows a 3px ring in the focus-ring token — the same
216
+ look `focus-visible` already draws automatically on a composed control, since
217
+ the two share the identical color value.
218
+ - **Given** any `state` **and** `variant` of `current` or `future`
219
+ **Then** nothing changes. `state` is not silently dropped from the contract: it
220
+ still appears as a data attribute, so a consumer can key off it.
221
+
222
+ ### RTL
223
+
224
+ - **Given** `dir="rtl"`
225
+ **Then** the whole step mirrors: the marker/label order, the container padding,
226
+ and the gap are all logical, with no physical directional utility to correct.
227
+
228
+ ### Composition
229
+
230
+ - **Given** a `render` prop
231
+ **Then** the rendered element is replaced (e.g. by a `<button>`) and the step's
232
+ props, classes, and data attributes merge onto it.
233
+ - **Given** a `render` of a focusable control
234
+ **Then** focusing it by keyboard shows the library's 3px `--ui-focus-primary`
235
+ ring. The default `<div>` never focuses, so the ring never appears on it.
236
+ - **Given** `variant="future"` **and** a `render` of a real control
237
+ **Then** the control still renders, but it is `aria-disabled`, inert to pointer
238
+ input, and removed from the tab order — so it cannot be tabbed to or activated
239
+ from the keyboard. It is **not** the native `disabled` attribute, so a
240
+ programmatic `.focus()` + `.click()` still works; the application should also
241
+ skip the step in its own navigation.
242
+
243
+ ### Not owned here
244
+
245
+ - The row layout and the narrow-viewport summary — that is `Stepper`, which these
246
+ steps are meant to be composed inside.
247
+ - The step sequence, its order, numbering, and which step is current — the
248
+ application decides and passes `variant` per step.
249
+ - The marker's content and appearance — the caller composes the avatar.
250
+ - Hover and press detection: `state` is declarative, so the consumer decides when
251
+ a step looks hovered, pressed, or focused (`Stepper` does not — it owns no
252
+ step state).
253
+
254
+ ## Accessibility
255
+
256
+ - **Presentational by default.** The step renders a `<div>`: no role, no tab
257
+ stop. That is correct for the current and future steps, which are not actions.
258
+ - **A completed step is usually a control** — compose it with `render` as a real
259
+ `<button>` (or a link, if it changes the URL). Doing so gives it keyboard focus,
260
+ Enter/Space activation, and a native accessible name for free. Never fake it
261
+ with a click handler on the default `<div>`.
262
+ - **Keyboard focus is visible.** The step carries the library's standard 3px
263
+ `--ui-focus-primary` `focus-visible` ring (the same one `CardFilter` and
264
+ `BreadcrumbLink` use), so a step composed as a control is never focused
265
+ invisibly. The default `<div>` is not focusable, so the ring never shows there.
266
+ - **The accessible name comes from the content you pass.** The step's name is the
267
+ `label`; the marker contributes whatever text the caller's avatar renders (a
268
+ number, initials). If the marker's digit would be noise, mark that avatar
269
+ `aria-hidden` in your own composition — the step cannot decide that for you.
270
+ - **A future step is `aria-disabled`, not `disabled`.** It stays in the reading
271
+ order so a screen-reader user can see the whole sequence, but it announces as
272
+ unavailable. Three things make that true rather than aspirational:
273
+ - On the default rendering it also carries **`role="link"`**. `aria-disabled` on
274
+ an element with no widget role is not announced (ARIA 1.2), and the default
275
+ rendering is a plain `<div>` — so without a role the flag would be inert. This
276
+ is the same fix `BreadcrumbPage` applies to the non-navigable current page: a
277
+ destination that is in the sequence but cannot be gone to. The role is
278
+ **omitted** when the step is composed via `render`, because the element the
279
+ consumer supplies brings its own (more accurate) role.
280
+ - It is removed from the tab order (**`tabindex="-1"`**), so a step composed as
281
+ a real `<button>` cannot be tabbed to or activated with Enter/Space.
282
+ - It receives no pointer events, so it cannot be clicked.
283
+
284
+ What this does **not** give you is the native `disabled` guarantee: a
285
+ programmatic `.focus()` + `.click()` on a composed control still fires its
286
+ handler. Skip future steps in your own navigation logic too.
287
+
288
+ - **Ships no strings.** Every piece of text is consumer-supplied (`label`, the
289
+ avatar's content), so there is nothing to localize inside the component and no
290
+ default English copy to override.
291
+ - **`state` is not a live interaction state.** It is a declarative look, so a
292
+ step forced to `hover`, `active`, or `focus` conveys nothing to assistive
293
+ tech. Never use it as the only signal of the step a user is on — that is
294
+ `variant="current"`, and the application should also expose the position in
295
+ text ("Step 2 of 3").
296
+ - **Sequence semantics belong to the container.** A single step is not a list. If
297
+ the whole stepper should announce as an ordered sequence, wrap the steps in an
298
+ `<ol>`/`<li>` (or a `role="list"`) at the application layer, and mark the
299
+ current step with `aria-current="step"` on the element you compose.
300
+ - **RTL**: the marker, label, padding, and gap all use logical properties, so the
301
+ whole step mirrors under `dir="rtl"` with no extra work.
302
+
303
+ ## Contrast
304
+
305
+ The step name uses the current/completed/future label-color tokens from the
306
+ dedicated `--ui-stepper-item-*` tier (see `tokens.yaml`), each defined per brand
307
+ and light/dark mode via `light-dark()`. Re-check contrast per brand when this
308
+ tier changes, since a brand may define distinct values now that it is
309
+ component-owned rather than borrowed from the semantic scale.