@acronis-platform/ui-react 3.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.
- package/dist/components/ui/accordion-container/accordion-container.js +14 -14
- package/dist/components/ui/accordion-container/accordion-container.js.map +1 -1
- package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
- package/dist/components/ui/area-chart/area-chart.js +141 -139
- package/dist/components/ui/area-chart/area-chart.js.map +1 -1
- package/dist/components/ui/bar-chart/bar-chart.js +295 -293
- package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
- package/dist/components/ui/category-bar/category-bar.js +109 -93
- package/dist/components/ui/category-bar/category-bar.js.map +1 -1
- package/dist/components/ui/chart/chart-palette.js +113 -0
- package/dist/components/ui/chart/chart-palette.js.map +1 -0
- package/dist/components/ui/chart/chart.js +176 -129
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
- package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
- package/dist/components/ui/chart-state/chart-state.js +48 -34
- package/dist/components/ui/chart-state/chart-state.js.map +1 -1
- package/dist/components/ui/chart-widget/chart-widget.js +87 -0
- package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
- package/dist/components/ui/composed-chart/composed-chart.js +117 -115
- package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
- package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
- package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
- package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
- package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
- package/dist/components/ui/histogram/histogram.js +94 -92
- package/dist/components/ui/histogram/histogram.js.map +1 -1
- package/dist/components/ui/input/input.js.map +1 -1
- package/dist/components/ui/label/label.js +2 -9
- package/dist/components/ui/label/label.js.map +1 -1
- package/dist/components/ui/line-chart/line-chart.js +143 -141
- package/dist/components/ui/line-chart/line-chart.js.map +1 -1
- package/dist/components/ui/metric/metric.js +74 -185
- package/dist/components/ui/metric/metric.js.map +1 -1
- package/dist/components/ui/page-content/page-content.js.map +1 -1
- package/dist/components/ui/pie-chart/pie-chart.js +201 -195
- package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
- package/dist/components/ui/radar-chart/radar-chart.js +133 -131
- package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
- package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
- package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
- package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
- package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
- package/dist/components/ui/section/section.js +157 -31
- package/dist/components/ui/section/section.js.map +1 -1
- package/dist/components/ui/stepper/stepper.js +24 -24
- package/dist/components/ui/stepper/stepper.js.map +1 -1
- package/dist/components/ui/stepper-item/stepper-item.js +43 -24
- package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
- package/dist/components/ui/treemap/treemap.js +133 -124
- package/dist/components/ui/treemap/treemap.js.map +1 -1
- package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
- package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
- package/dist/components/ui/wizard/wizard.js +59 -0
- package/dist/components/ui/wizard/wizard.js.map +1 -0
- package/dist/hooks/use-wizard.js +75 -0
- package/dist/hooks/use-wizard.js.map +1 -0
- package/dist/index.js +502 -497
- package/dist/index.js.map +1 -1
- package/dist/llms/accordion-container.md +181 -0
- package/dist/llms/accordion.md +124 -0
- package/dist/llms/alert.md +225 -0
- package/dist/llms/app-shell-chat.md +415 -0
- package/dist/llms/area-chart.md +355 -0
- package/dist/llms/avatar.md +208 -0
- package/dist/llms/bar-chart.md +406 -0
- package/dist/llms/breadcrumb.md +326 -0
- package/dist/llms/button-group.md +298 -0
- package/dist/llms/button-icon-input.md +142 -0
- package/dist/llms/button-icon-menu.md +209 -0
- package/dist/llms/button-icon.md +128 -0
- package/dist/llms/button-menu.md +172 -0
- package/dist/llms/button.md +185 -0
- package/dist/llms/calendar-panel.md +733 -0
- package/dist/llms/calendar.md +188 -0
- package/dist/llms/card-filter.md +214 -0
- package/dist/llms/card-section.md +293 -0
- package/dist/llms/card.md +447 -0
- package/dist/llms/carousel-dialog.md +156 -0
- package/dist/llms/category-bar.md +193 -0
- package/dist/llms/chart-state.md +190 -0
- package/dist/llms/chart-widget.md +209 -0
- package/dist/llms/chart.md +182 -0
- package/dist/llms/checkbox.md +257 -0
- package/dist/llms/chip.md +195 -0
- package/dist/llms/combobox.md +164 -0
- package/dist/llms/composed-chart.md +508 -0
- package/dist/llms/confidence-cone.md +277 -0
- package/dist/llms/data-table.md +474 -0
- package/dist/llms/date-range-picker.md +272 -0
- package/dist/llms/description-list.md +131 -0
- package/dist/llms/dialog-footer-carousel.md +147 -0
- package/dist/llms/dialog-footer-default.md +142 -0
- package/dist/llms/dialog-root.md +246 -0
- package/dist/llms/dialog-welcome.md +223 -0
- package/dist/llms/dialog.md +403 -0
- package/dist/llms/dropdown-menu.md +193 -0
- package/dist/llms/empty-overlay.md +146 -0
- package/dist/llms/empty.md +156 -0
- package/dist/llms/field.md +185 -0
- package/dist/llms/filter-cards.md +157 -0
- package/dist/llms/filter-chips.md +323 -0
- package/dist/llms/filter-search.md +512 -0
- package/dist/llms/form.md +154 -0
- package/dist/llms/funnel-chart.md +333 -0
- package/dist/llms/grid.md +80 -0
- package/dist/llms/histogram.md +190 -0
- package/dist/llms/input-date-picker.md +203 -0
- package/dist/llms/input-otp.md +173 -0
- package/dist/llms/input-password.md +197 -0
- package/dist/llms/input-search.md +170 -0
- package/dist/llms/input-select.md +278 -0
- package/dist/llms/input-text-area.md +271 -0
- package/dist/llms/input-text.md +192 -0
- package/dist/llms/line-chart.md +369 -0
- package/dist/llms/link.md +209 -0
- package/dist/llms/loading.md +130 -0
- package/dist/llms/meter.md +177 -0
- package/dist/llms/metric.md +204 -0
- package/dist/llms/number-field.md +122 -0
- package/dist/llms/page-content.md +69 -0
- package/dist/llms/page-header.md +182 -0
- package/dist/llms/pagination.md +133 -0
- package/dist/llms/pie-chart.md +307 -0
- package/dist/llms/popover.md +252 -0
- package/dist/llms/progress-circle.md +126 -0
- package/dist/llms/progress.md +111 -0
- package/dist/llms/radar-chart.md +316 -0
- package/dist/llms/radial-bar-chart.md +319 -0
- package/dist/llms/radio.md +255 -0
- package/dist/llms/resizable.md +195 -0
- package/dist/llms/sankey-chart.md +208 -0
- package/dist/llms/scatter-chart.md +239 -0
- package/dist/llms/scroll-area.md +183 -0
- package/dist/llms/section.md +401 -0
- package/dist/llms/select.md +210 -0
- package/dist/llms/separator.md +87 -0
- package/dist/llms/sheet.md +202 -0
- package/dist/llms/sidebar-primary.md +360 -0
- package/dist/llms/sidebar-secondary.md +417 -0
- package/dist/llms/skeleton.md +81 -0
- package/dist/llms/slider.md +97 -0
- package/dist/llms/spinner.md +100 -0
- package/dist/llms/stack.md +80 -0
- package/dist/llms/stepper-item.md +309 -0
- package/dist/llms/stepper.md +251 -0
- package/dist/llms/switch.md +140 -0
- package/dist/llms/table.md +436 -0
- package/dist/llms/tabs.md +197 -0
- package/dist/llms/tag.md +139 -0
- package/dist/llms/timeline.md +361 -0
- package/dist/llms/timer.md +259 -0
- package/dist/llms/toast.md +241 -0
- package/dist/llms/toggle-group.md +121 -0
- package/dist/llms/toolbar.md +453 -0
- package/dist/llms/tooltip.md +164 -0
- package/dist/llms/treemap.md +254 -0
- package/dist/llms/trend-indicator.md +132 -0
- package/dist/llms/widget-placeholder.md +169 -0
- package/dist/llms/wizard.md +412 -0
- package/dist/llms.txt +142 -0
- package/dist/react.js +502 -497
- package/dist/react.js.map +1 -1
- package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
- package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
- package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
- package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
- package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
- package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
- package/dist/src/components/ui/chart/chart.d.ts +66 -15
- package/dist/src/components/ui/chart/index.d.ts +4 -2
- package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
- package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
- package/dist/src/components/ui/chart-state/index.d.ts +1 -0
- package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
- package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
- package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
- package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
- package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +1 -1
- package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
- package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
- package/dist/src/components/ui/label/index.d.ts +1 -1
- package/dist/src/components/ui/label/label.d.ts +1 -5
- package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
- package/dist/src/components/ui/metric/metric.d.ts +13 -14
- package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
- package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
- package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
- package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
- package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
- package/dist/src/components/ui/section/index.d.ts +1 -1
- package/dist/src/components/ui/section/section.d.ts +75 -6
- package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
- package/dist/src/components/ui/tag/tag.d.ts +1 -1
- package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
- package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
- package/dist/src/components/ui/wizard/index.d.ts +1 -0
- package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/use-wizard.d.ts +80 -0
- package/dist/src/index.d.ts +2 -3
- package/dist/ui-react.css +1 -1
- package/package.json +9 -3
- package/dist/components/ui/app-shell/app-shell.js +0 -75
- package/dist/components/ui/app-shell/app-shell.js.map +0 -1
- package/dist/components/ui/auth-layout/auth-layout.js +0 -56
- package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
- package/dist/components/ui/collapsible/collapsible.js +0 -22
- package/dist/components/ui/collapsible/collapsible.js.map +0 -1
- package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
- package/dist/src/components/ui/app-shell/index.d.ts +0 -1
- package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
- package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
- package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
- package/dist/src/components/ui/collapsible/index.d.ts +0 -1
- 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.
|