@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.
- package/dist/components/ui/accordion-container/accordion-container.js +144 -0
- package/dist/components/ui/accordion-container/accordion-container.js.map +1 -0
- 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/avatar/avatar.js +33 -22
- package/dist/components/ui/avatar/avatar.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/card/card.js +150 -74
- package/dist/components/ui/card/card.js.map +1 -1
- package/dist/components/ui/card-section/card-section.js +111 -0
- package/dist/components/ui/card-section/card-section.js.map +1 -0
- 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/data-table/data-table.js +4 -2
- package/dist/components/ui/data-table/data-table.js.map +1 -1
- package/dist/components/ui/empty-overlay/empty-overlay.js +49 -0
- package/dist/components/ui/empty-overlay/empty-overlay.js.map +1 -0
- 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/table/table.js +27 -27
- package/dist/components/ui/table/table.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 +540 -525
- 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 +540 -525
- package/dist/react.js.map +1 -1
- package/dist/src/components/ui/accordion-container/accordion-container.d.ts +44 -0
- package/dist/src/components/ui/accordion-container/index.d.ts +1 -0
- package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
- package/dist/src/components/ui/avatar/avatar.d.ts +27 -8
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
- package/dist/src/components/ui/button/button.d.ts +1 -1
- package/dist/src/components/ui/card/card.d.ts +69 -8
- package/dist/src/components/ui/card/index.d.ts +1 -1
- package/dist/src/components/ui/card-section/card-section.d.ts +50 -0
- package/dist/src/components/ui/card-section/index.d.ts +1 -0
- 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/dialog/dialog.d.ts +1 -1
- package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +20 -0
- package/dist/src/components/ui/empty-overlay/index.d.ts +2 -0
- package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
- package/dist/src/components/ui/grid/grid.d.ts +1 -1
- 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/sheet/sheet.d.ts +1 -1
- package/dist/src/components/ui/stack/stack.d.ts +1 -1
- 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 +5 -3
- package/dist/ui-react.css +1 -1
- package/package.json +12 -6
- 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,130 @@
|
|
|
1
|
+
# Loading
|
|
2
|
+
|
|
3
|
+
> A composite loading indicator — a spinning ring plus an optional label — for four placement contexts: inline (flush in text flow), two card-like chips for a primary/secondary app surface, and a higher-contrast chip for busy/photo surfaces. Distinct from `Spinner` (the bare ring primitive it reuses for its icon): `Spinner` has no label or container and is unaffected by this addition.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** feedback · **Since:** v0.58.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Loading } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Loading />
|
|
17
|
+
<Loading variant="onSurfacePrimary" label="Fetching your data…" />
|
|
18
|
+
<Loading variant="onScreen" hasLabel={false} />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
A composite loading indicator — a spinning ring plus an optional label — for
|
|
22
|
+
four placement contexts.
|
|
23
|
+
|
|
24
|
+
## When to use
|
|
25
|
+
|
|
26
|
+
- Indicating an in-progress, indeterminate operation, with a message, in one
|
|
27
|
+
of four contexts: inline in text flow, as a card-like chip over an app
|
|
28
|
+
surface, or as a higher-contrast chip over a busy/photo/video surface.
|
|
29
|
+
|
|
30
|
+
## When not to use
|
|
31
|
+
|
|
32
|
+
- For a small inline icon-scale spinner (e.g. inside a `Button` or `Toast`) —
|
|
33
|
+
those compose the internal `Spinner` primitive directly; it isn't part of
|
|
34
|
+
the public component set.
|
|
35
|
+
- For determinate progress — use `Progress`.
|
|
36
|
+
- For content placeholders — use a skeleton.
|
|
37
|
+
|
|
38
|
+
## Parts
|
|
39
|
+
|
|
40
|
+
| Part | Description |
|
|
41
|
+
| ----- | ------------------------------------------------------------------ |
|
|
42
|
+
| icon | The `Spinner` primitive, sized/colored per variant, `aria-hidden`. |
|
|
43
|
+
| label | Optional visible text (`hasLabel`), colored per variant. |
|
|
44
|
+
|
|
45
|
+
## Example
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { Loading } from '@acronis-platform/ui-react';
|
|
49
|
+
|
|
50
|
+
<Loading />
|
|
51
|
+
<Loading variant="onSurfacePrimary" label="Fetching your data…" />
|
|
52
|
+
<Loading variant="onSurfaceSecondary" />
|
|
53
|
+
<Loading variant="onScreen" hasLabel={false} />
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Props
|
|
57
|
+
|
|
58
|
+
| Prop | Type | Default | Required | Description |
|
|
59
|
+
|------|------|---------|----------|-------------|
|
|
60
|
+
| `variant` | `'inline' | 'onSurfacePrimary' | 'onSurfaceSecondary' | 'onScreen'` | `'inline'` | no | Placement context. `inline` sits flush in text flow; `onSurfacePrimary`/ `onSurfaceSecondary` are card-like chips for a primary/secondary app surface; `onScreen` is the higher-contrast dark chip for busy/photo/video surfaces. Each maps to its own `--ui-loading-<variant>-*` tokens. |
|
|
61
|
+
| `hasLabel` | `boolean` | `true` | no | Whether `label` renders visibly. When false, `label` is still exposed to assistive tech via the root's `aria-label`. |
|
|
62
|
+
| `label` | `string` | `'Data is loading…'` | no | The loading message. |
|
|
63
|
+
|
|
64
|
+
## Behavior
|
|
65
|
+
|
|
66
|
+
Loading is a pure function of its props — no internal state, no interaction.
|
|
67
|
+
It renders continuously (via `Spinner`) while mounted.
|
|
68
|
+
|
|
69
|
+
```gherkin
|
|
70
|
+
Scenario: Default variant
|
|
71
|
+
Given a Loading with no props
|
|
72
|
+
Then it renders the inline variant with a 16px spinner and a visible label
|
|
73
|
+
And the label reads "Data is loading…"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```gherkin
|
|
77
|
+
Scenario: Card variants
|
|
78
|
+
Given a Loading with variant="onSurfacePrimary" (or "onSurfaceSecondary")
|
|
79
|
+
Then it renders a rounded, padded chip with a 32px spinner stacked above the label
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```gherkin
|
|
83
|
+
Scenario: On-screen variant
|
|
84
|
+
Given a Loading with variant="onScreen"
|
|
85
|
+
Then it renders a higher-contrast dark chip with a 48px white spinner and white label,
|
|
86
|
+
suited to placement over busy/photo/video surfaces
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```gherkin
|
|
90
|
+
Scenario: Custom label
|
|
91
|
+
Given a Loading with label="Uploading files…"
|
|
92
|
+
Then the visible label (or, when hasLabel is false, the root's aria-label) reads that text
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```gherkin
|
|
96
|
+
Scenario: Label hidden but still accessible
|
|
97
|
+
Given a Loading with hasLabel={false}
|
|
98
|
+
Then no visible label renders
|
|
99
|
+
And the root carries aria-label equal to `label`, so assistive tech still announces it
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```gherkin
|
|
103
|
+
Scenario: Reduced motion
|
|
104
|
+
Given a user with prefers-reduced-motion
|
|
105
|
+
Then the platform animation honors that preference (the ring is still shown)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Accessibility
|
|
109
|
+
|
|
110
|
+
- The root is `role="status"` (a polite live region) — mounting it announces
|
|
111
|
+
the loading state without stealing focus.
|
|
112
|
+
- The `Spinner` icon is rendered `aria-hidden="true"`: it is purely decorative
|
|
113
|
+
motion here, since the root already owns the accessible name/announcement.
|
|
114
|
+
This also prevents assistive tech from double-announcing `Spinner`'s own
|
|
115
|
+
built-in "Loading" label alongside Loading's own label.
|
|
116
|
+
- When `hasLabel` is true (default), the visible label's text content is the
|
|
117
|
+
live region's announcement — no separate `aria-label` is needed or set.
|
|
118
|
+
- When `hasLabel` is false, the root carries `aria-label={label}` so the
|
|
119
|
+
loading state is still announced even though nothing is shown on screen.
|
|
120
|
+
- Pair with real content once the operation completes; Loading has no
|
|
121
|
+
"complete" state of its own — remove it from the DOM (or swap it for the
|
|
122
|
+
loaded content) when the operation finishes.
|
|
123
|
+
|
|
124
|
+
## Contrast
|
|
125
|
+
|
|
126
|
+
Each variant wires its own icon/label color tokens
|
|
127
|
+
(`--ui-loading-<variant>-icon-color` / `-label-color`), so contrast against the
|
|
128
|
+
variant's own container background is guaranteed independent of the ambient
|
|
129
|
+
page background — this is why `onScreen` exists as a distinct, higher-contrast
|
|
130
|
+
variant for busy/photo/video surfaces rather than reusing `onSurfacePrimary`.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Meter
|
|
2
|
+
|
|
3
|
+
> 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).
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** data-display · **Since:** v0.58.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Meter } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Meter
|
|
17
|
+
label="Critical"
|
|
18
|
+
value={6}
|
|
19
|
+
max={29}
|
|
20
|
+
color="var(--ui-background-status-strong-danger)"
|
|
21
|
+
/>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
A labelled proportional bar for a value within a known range — a fractional
|
|
25
|
+
value / share. Built on Base UI's `Meter` (`role="meter"`, like the HTML
|
|
26
|
+
`<meter>` element), as opposed to `Progress` / `ProgressCircle`, which track a
|
|
27
|
+
task over time. One row: label + `value · %` over a track bar, with a hover
|
|
28
|
+
tooltip; stack several to build a ranked breakdown (a "bar list").
|
|
29
|
+
|
|
30
|
+
> **Design-pending v1.** No chart token tier yet, so the fill color is
|
|
31
|
+
> **caller-supplied** per row via `color` (a dedicated `--ui-chart-*` data-viz
|
|
32
|
+
> palette is a pending upstream design deliverable). The tooltip uses the
|
|
33
|
+
> chart-tooltip look (light card). Code Connect deferred.
|
|
34
|
+
|
|
35
|
+
## When to use
|
|
36
|
+
|
|
37
|
+
- One row of a **breakdown** — a category's value and its share of a total,
|
|
38
|
+
with a proportional bar (severity split, top browsers, storage by type).
|
|
39
|
+
- Stacked and sorted, as a ranked bar-list.
|
|
40
|
+
|
|
41
|
+
## When not to use
|
|
42
|
+
|
|
43
|
+
- Task progress over time (uploads, loading) — use
|
|
44
|
+
[`Progress`](/components/progress) / `ProgressCircle`.
|
|
45
|
+
- Many categories compared without a part-to-whole reading — a bar chart.
|
|
46
|
+
|
|
47
|
+
## Example
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { Meter } from '@acronis-platform/ui-react';
|
|
51
|
+
|
|
52
|
+
<Meter
|
|
53
|
+
label="Critical"
|
|
54
|
+
value={6}
|
|
55
|
+
max={29}
|
|
56
|
+
color="var(--ui-background-status-strong-danger)"
|
|
57
|
+
/>;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Stack several sharing one `max` (the total), sorted by value, for a ranked
|
|
61
|
+
breakdown:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const rows = [
|
|
65
|
+
{
|
|
66
|
+
label: 'High',
|
|
67
|
+
value: 9,
|
|
68
|
+
color: 'var(--ui-background-status-strong-warning)',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
label: 'Medium',
|
|
72
|
+
value: 8,
|
|
73
|
+
color: 'var(--ui-background-status-strong-info)',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
label: 'Critical',
|
|
77
|
+
value: 6,
|
|
78
|
+
color: 'var(--ui-background-status-strong-danger)',
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
const total = rows.reduce((sum, r) => sum + r.value, 0);
|
|
82
|
+
|
|
83
|
+
<div className="flex flex-col gap-4">
|
|
84
|
+
{rows
|
|
85
|
+
.sort((a, b) => b.value - a.value)
|
|
86
|
+
.map((r) => (
|
|
87
|
+
<Meter
|
|
88
|
+
key={r.label}
|
|
89
|
+
label={r.label}
|
|
90
|
+
value={r.value}
|
|
91
|
+
max={total}
|
|
92
|
+
color={r.color}
|
|
93
|
+
/>
|
|
94
|
+
))}
|
|
95
|
+
</div>;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The fill color references an existing semantic `--ui-*` token; the status tokens
|
|
99
|
+
are chromatic across brands, so they read consistently until the real data-viz
|
|
100
|
+
palette lands.
|
|
101
|
+
|
|
102
|
+
## Props
|
|
103
|
+
|
|
104
|
+
| Prop | Type | Default | Required | Description |
|
|
105
|
+
|------|------|---------|----------|-------------|
|
|
106
|
+
| `label` | `string` | — | yes | Row label shown on the left. |
|
|
107
|
+
| `value` | `number` | — | yes | The value this meter represents. |
|
|
108
|
+
| `max` | `number` | `100` | no | Upper bound of the range — the whole the value is a share of. |
|
|
109
|
+
| `color` | `string` | — | yes | Fill color for the bar — an existing semantic `--ui-*` token (or any CSS color). Caller-supplied; there is no chart palette tier yet. |
|
|
110
|
+
| `valueFormatter` | `(value: number) => string` | `toLocaleString` | no | Format the numeric value in the label + tooltip. |
|
|
111
|
+
| `showTooltip` | `boolean` | `true` | no | Show the hover tooltip (`label · value of max · %`). |
|
|
112
|
+
| `tooltip` | `ReactNode` | — | no | Custom tooltip content — replaces the default (dot + label + `value of max · %`) inside the same chart-style card. Ignored when `showTooltip` is false. |
|
|
113
|
+
| `defaultOpen` | `boolean` | — | no | Render with the tooltip initially open (Base UI `defaultOpen`). |
|
|
114
|
+
|
|
115
|
+
## Behavior
|
|
116
|
+
|
|
117
|
+
`Meter` is a labelled proportional bar for a value within a range (Base UI
|
|
118
|
+
`Meter`, `role="meter"`).
|
|
119
|
+
|
|
120
|
+
```gherkin
|
|
121
|
+
Scenario: Render a value's share
|
|
122
|
+
Given a label, value, and max
|
|
123
|
+
Then the fill spans value / max of the track (Base UI sizes the indicator)
|
|
124
|
+
And the row shows the formatted value and `· <pct>%` on the right
|
|
125
|
+
And the fill uses the caller-supplied color
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```gherkin
|
|
129
|
+
Scenario: Accessible value
|
|
130
|
+
Given value and max
|
|
131
|
+
Then the meter exposes role="meter" with aria-valuenow / aria-valuemin (0) /
|
|
132
|
+
aria-valuemax (max), an accessible name from the label, and an
|
|
133
|
+
aria-valuetext of "value of max (pct%)"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```gherkin
|
|
137
|
+
Scenario: Tooltip on hover
|
|
138
|
+
Given showTooltip is true (the default)
|
|
139
|
+
When the user hovers or focuses the meter
|
|
140
|
+
Then a chart-style tooltip card (light surface + border + shadow) shows a color
|
|
141
|
+
dot, the label, and "value of max · pct%"
|
|
142
|
+
And with showTooltip false, no tooltip is wired
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```gherkin
|
|
146
|
+
Scenario: Zero or empty range
|
|
147
|
+
Given max is 0 (or value is 0)
|
|
148
|
+
Then the share reads 0% and the fill is empty, without dividing by zero
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
```gherkin
|
|
152
|
+
Scenario: Stacked into a ranked breakdown
|
|
153
|
+
Given several meters sharing one max (the total), sorted by value
|
|
154
|
+
Then they read as a ranked bar-list of shares
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Accessibility
|
|
158
|
+
|
|
159
|
+
- Built on Base UI `Meter`, so the root carries `role="meter"` with
|
|
160
|
+
`aria-valuenow` / `aria-valuemin` (0) / `aria-valuemax` (the `max`), an
|
|
161
|
+
accessible name wired from `Meter.Label` (`aria-labelledby`), and an
|
|
162
|
+
`aria-valuetext` giving the human-readable "value of max (pct%)".
|
|
163
|
+
- `role="meter"` (not `progressbar`) is deliberate — a meter is a scalar value
|
|
164
|
+
within a known range, not task progress over time. Screen readers announce it
|
|
165
|
+
as a gauge/measurement.
|
|
166
|
+
- The percentage and value are real text in the row, so the meaning is in the
|
|
167
|
+
accessible tree, not only the bar. **Don't rely on the fill color alone** to
|
|
168
|
+
distinguish stacked meters — pair each with its label (already shown).
|
|
169
|
+
- The tooltip repeats the value/share; it's supplementary. When it's shown the
|
|
170
|
+
meter root is focusable (`tabIndex={0}`), so keyboard users reach it on focus,
|
|
171
|
+
not just hover. The bar's color is caller-supplied, so pick a token with enough
|
|
172
|
+
contrast on the surface.
|
|
173
|
+
|
|
174
|
+
## Contrast
|
|
175
|
+
|
|
176
|
+
The label, value, track, and tooltip resolve semantic `--ui-*` tokens that meet
|
|
177
|
+
contrast in both themes. The fill color is the caller's responsibility.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Metric
|
|
2
|
+
|
|
3
|
+
> 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.
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** data-display
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Metric } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Metric
|
|
17
|
+
value="73"
|
|
18
|
+
unit="%"
|
|
19
|
+
caption={<Tag>Last 30 days</Tag>}
|
|
20
|
+
icon={<ChartPieIcon />}
|
|
21
|
+
trend="down"
|
|
22
|
+
trendValue="5%"
|
|
23
|
+
supportingText="Target: 80%"
|
|
24
|
+
>
|
|
25
|
+
<BarChart {...} />
|
|
26
|
+
<Separator className="my-3" />
|
|
27
|
+
<p>Margin eroding — check labor cost per client…</p>
|
|
28
|
+
</Metric>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
A presentational metric / statistic **card**, modelled on the Figma MetricCard
|
|
32
|
+
node: a label + optional caption over a primary value (with an optional
|
|
33
|
+
status-tinted icon badge, unit, and trend), plus an optional body for a chart,
|
|
34
|
+
breakdown, or insight.
|
|
35
|
+
|
|
36
|
+
## When to use
|
|
37
|
+
|
|
38
|
+
- A dashboard KPI tile: a headline number with a trend and a small visual.
|
|
39
|
+
- Any "value + context" surface (health score, coverage, ARR, MTTR, at-risk
|
|
40
|
+
count, …).
|
|
41
|
+
|
|
42
|
+
## When not to use
|
|
43
|
+
|
|
44
|
+
- To plot a series over time — use a Line / Area / Composed chart (compose it as
|
|
45
|
+
the Metric body).
|
|
46
|
+
- To compute the value or the trend — the consumer passes a ready-formatted
|
|
47
|
+
`value` and a resolved `status`; Metric never does maths or business rules.
|
|
48
|
+
|
|
49
|
+
## Anatomy
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
GROSS MARGIN [Last 30 days] ← label + caption
|
|
53
|
+
[◐] 73 % ↘ 5% vs prev 30d ← icon badge + value + unit · trend
|
|
54
|
+
—————————————————————————————————————— ← (children body: chart / Separator / insight)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Composition
|
|
58
|
+
|
|
59
|
+
Metric is a Card. Put the trend in the `trend` slot (a `TrendIndicator`), a
|
|
60
|
+
timeframe in `caption` (a `Tag`), and drop a chart / `Meter` breakdown /
|
|
61
|
+
`Separator` / insight line into `children`:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<Metric
|
|
65
|
+
label="At-risk customers"
|
|
66
|
+
status="critical"
|
|
67
|
+
icon={<ChartPieIcon />}
|
|
68
|
+
caption={<Tag>Now</Tag>}
|
|
69
|
+
value="3"
|
|
70
|
+
trend={
|
|
71
|
+
<TrendIndicator
|
|
72
|
+
direction="up"
|
|
73
|
+
sentiment="negative"
|
|
74
|
+
value="1"
|
|
75
|
+
size="small"
|
|
76
|
+
/>
|
|
77
|
+
}
|
|
78
|
+
>
|
|
79
|
+
<Meter
|
|
80
|
+
label="Healthy"
|
|
81
|
+
value={46}
|
|
82
|
+
max={54}
|
|
83
|
+
color="var(--ui-background-status-strong-success)"
|
|
84
|
+
/>
|
|
85
|
+
<Separator className="my-3" />
|
|
86
|
+
<p>+3 customers predicted at-risk within 30 days.</p>
|
|
87
|
+
</Metric>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Notes
|
|
91
|
+
|
|
92
|
+
- **Design-pending v1** — the Figma node is a reference, not a published
|
|
93
|
+
component; no dedicated `--ui-metric-*` token tier yet.
|
|
94
|
+
- Value may be numeric or a ReactNode; the kit never formats it.
|
|
95
|
+
- `status` (`neutral | info | success | warning | danger | critical`) tints the
|
|
96
|
+
icon badge only (subtle) — the `--ui-background-status-<status>-pressed` fill +
|
|
97
|
+
the `--ui-text-on-status-<status>` icon color — never a full color fill, so
|
|
98
|
+
many metrics stay calm together.
|
|
99
|
+
|
|
100
|
+
## Props
|
|
101
|
+
|
|
102
|
+
| Prop | Type | Default | Required | Description |
|
|
103
|
+
|------|------|---------|----------|-------------|
|
|
104
|
+
| `value` | `ReactNode` | — | yes | The primary value, already formatted (`73`, `"94%"`, `"$72K"`, `"2.8"`). The kit does not format currency, units, or decimals. |
|
|
105
|
+
| `unit` | `ReactNode` | — | no | Unit shown next to the value at a smaller, muted size — e.g. "%" or "hours". |
|
|
106
|
+
| `caption` | `ReactNode` | — | no | Caption at the right end of the stats row — e.g. a timeframe `Tag`. |
|
|
107
|
+
| `trend` | `'up' | 'down' | 'stable'` | — | no | Trend direction — renders a `TrendIndicator` on its own row below the value. Sentiment follows direction automatically: `up` → positive, `down` → negative, `stable` → neutral. Pair with `trendValue` for the change text. |
|
|
108
|
+
| `trendValue` | `ReactNode` | — | no | Already-formatted change text shown next to the trend arrow — e.g. "20%", "+3". Requires `trend`. |
|
|
109
|
+
| `supportingText` | `ReactNode` | — | no | Secondary line below the trend — e.g. a target or note. |
|
|
110
|
+
| `badge` | `ReactNode` | — | no | A small badge / metadata slot beside the value — e.g. a Tag. |
|
|
111
|
+
| `icon` | `ReactNode` | — | no | Icon rendered in a status-info-tinted badge before the value. Always uses the info tint — the badge is a contextual cue, not a status signal. The icon is cloned to 16 px (icons-react sizes from a `size` prop). |
|
|
112
|
+
| `tooltip` | `ReactNode` | — | no | Contextual hint shown on an info affordance next to the value (Base UI Tooltip). |
|
|
113
|
+
| `tooltipLabel` | `string` | `More information` | no | Accessible name for the info affordance that reveals `tooltip`. |
|
|
114
|
+
| `loading` | `boolean` | `false` | no | Show a skeleton in place of the value, preserving its space. |
|
|
115
|
+
|
|
116
|
+
## Content slots
|
|
117
|
+
|
|
118
|
+
| Slot | Description |
|
|
119
|
+
|------|-------------|
|
|
120
|
+
| `default` | Content below the stats strip (`children`) — e.g. a chart, a `Separator`, an AI-insight line. Composed by the consumer. |
|
|
121
|
+
|
|
122
|
+
## Behavior
|
|
123
|
+
|
|
124
|
+
### Renders the value
|
|
125
|
+
|
|
126
|
+
- **Given** `value`, `unit`
|
|
127
|
+
**Then** the value is the highest-hierarchy element (`text-2xl font-semibold`)
|
|
128
|
+
with the unit beside it at a smaller muted size — both share one baseline row.
|
|
129
|
+
|
|
130
|
+
### Stats row layout
|
|
131
|
+
|
|
132
|
+
- **Given** any combination of `icon`, `value`, `unit`, `badge`, `tooltip`, `caption`
|
|
133
|
+
**Then** the left side of the stats row holds icon badge → value → unit → badge
|
|
134
|
+
→ tooltip affordance (in that order); the right side holds the optional caption.
|
|
135
|
+
The row is `justify-between`, so left and right sit at the ends.
|
|
136
|
+
|
|
137
|
+
### Composes a trend
|
|
138
|
+
|
|
139
|
+
- **Given** `trend="up"` (or `"down"` or `"stable"`)
|
|
140
|
+
**Then** a `TrendIndicator` renders on its own row below the stats row.
|
|
141
|
+
Direction and sentiment are derived automatically: `up` → positive,
|
|
142
|
+
`down` → negative, `stable` → neutral. Pair with `trendValue` for the change
|
|
143
|
+
text. Metric never computes or interprets the values.
|
|
144
|
+
|
|
145
|
+
### Value is caller-formatted
|
|
146
|
+
|
|
147
|
+
- **Given** `value="$72K"` (or `value={82}`, or a ReactNode)
|
|
148
|
+
**Then** it renders verbatim — the kit never formats currency, units, or
|
|
149
|
+
decimals, and never decides whether the value is good or bad.
|
|
150
|
+
|
|
151
|
+
### Icon badge is always info-tinted
|
|
152
|
+
|
|
153
|
+
- **Given** an `icon`
|
|
154
|
+
**Then** it renders in a fixed `size-9` rounded badge using the info status
|
|
155
|
+
tint (`--ui-background-status-info` fill, `--ui-glyph-on-surface-neutral-dark`
|
|
156
|
+
icon color) unconditionally — the badge is a contextual slot, not a status
|
|
157
|
+
signal.
|
|
158
|
+
|
|
159
|
+
### Loading
|
|
160
|
+
|
|
161
|
+
- **Given** `loading`
|
|
162
|
+
**Then** a `Skeleton` renders in place of the value, preserving its space.
|
|
163
|
+
- No data: the consumer passes `value="—"` — never `0`, which is a real value.
|
|
164
|
+
|
|
165
|
+
### Tooltip
|
|
166
|
+
|
|
167
|
+
- **Given** a `tooltip`, **then** an info affordance (`CircleInfoIcon`, 16 px,
|
|
168
|
+
named by `tooltipLabel`) appears next to the value and reveals the hint on
|
|
169
|
+
hover/focus; it is keyboard-reachable via Base UI `Tooltip`.
|
|
170
|
+
|
|
171
|
+
### Body
|
|
172
|
+
|
|
173
|
+
- **Given** `children` (a chart, a `Separator`, an insight line)
|
|
174
|
+
**Then** they render below the stats strip. No card chrome wraps them — Metric
|
|
175
|
+
is a plain `<div>`.
|
|
176
|
+
|
|
177
|
+
## Accessibility
|
|
178
|
+
|
|
179
|
+
- **DOM order matches reading order**: icon badge → value + unit → badge →
|
|
180
|
+
tooltip affordance (left), caption (right), then trend, supporting text, body.
|
|
181
|
+
Assistive tech reads a coherent "73 % ↓ 5% …".
|
|
182
|
+
- The unit stays adjacent to the value so they're announced together.
|
|
183
|
+
- The icon in the badge is decorative (`aria-hidden`). The badge tint is always
|
|
184
|
+
the info color — it is a contextual slot, not a status signal, so it carries
|
|
185
|
+
no meaning that must be communicated via ARIA.
|
|
186
|
+
- **Tooltip affordance**: when `tooltip` is set, the info trigger is a real
|
|
187
|
+
focusable element named by `tooltipLabel` (default "More information"), so it
|
|
188
|
+
is keyboard-reachable and announced. The tooltip must not be the only source
|
|
189
|
+
of essential information.
|
|
190
|
+
- **Trend**: the rendered `TrendIndicator` is decorative by default (glyph +
|
|
191
|
+
text, no `role="img"`). Supply an `ariaLabel` on the TrendIndicator directly
|
|
192
|
+
when a screen reader needs the full sentence ("Revenue down 5% vs last
|
|
193
|
+
quarter").
|
|
194
|
+
- Abbreviations (ARR, MTTR) may need a `tooltip` / accessible expansion supplied
|
|
195
|
+
by the consumer.
|
|
196
|
+
- Dynamically-updating values are not announced via `aria-live` unless the
|
|
197
|
+
consumer wraps them.
|
|
198
|
+
|
|
199
|
+
## Contrast
|
|
200
|
+
|
|
201
|
+
The value resolves the primary surface-text token; unit, supporting text, and
|
|
202
|
+
the tooltip icon use the secondary token. The info badge pairs
|
|
203
|
+
`--ui-background-status-info` with `--ui-glyph-on-surface-neutral-dark`. All
|
|
204
|
+
meet contrast in light and dark.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# NumberField
|
|
2
|
+
|
|
3
|
+
> A numeric input with decrement / increment steppers, min/max/step, and scrub support. Built on Base UI's NumberField; the field box reuses the InputText token tier. Ported from the legacy shadcn-uikit `number-field`.
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** forms · **Since:** v0.51.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { NumberField, NumberFieldGroup, NumberFieldDecrement, NumberFieldInput, NumberFieldIncrement } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<NumberField defaultValue={1} min={0} max={99}>
|
|
17
|
+
<NumberFieldGroup>
|
|
18
|
+
<NumberFieldDecrement />
|
|
19
|
+
<NumberFieldInput />
|
|
20
|
+
<NumberFieldIncrement />
|
|
21
|
+
</NumberFieldGroup>
|
|
22
|
+
</NumberField>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
A numeric input with decrement / increment steppers, min/max/step, and keyboard
|
|
26
|
+
stepping. Built on Base UI's NumberField; the box reuses the InputText token tier
|
|
27
|
+
so it matches the other inputs.
|
|
28
|
+
|
|
29
|
+
> Design-pending v1, ported from the legacy shadcn-uikit `number-field`.
|
|
30
|
+
|
|
31
|
+
## When to use
|
|
32
|
+
|
|
33
|
+
- Entering a bounded number where stepping by a fixed amount helps (quantity,
|
|
34
|
+
retention days, counts).
|
|
35
|
+
|
|
36
|
+
## When not to use
|
|
37
|
+
|
|
38
|
+
- An approximate value across a range — use `Slider`.
|
|
39
|
+
- Free text — use `InputText`.
|
|
40
|
+
|
|
41
|
+
## Parts
|
|
42
|
+
|
|
43
|
+
| Export | Purpose |
|
|
44
|
+
| ---------------------- | ------------------------------------------ |
|
|
45
|
+
| `NumberField` | Root — holds the value / min / max / step. |
|
|
46
|
+
| `NumberFieldGroup` | The bordered box. |
|
|
47
|
+
| `NumberFieldDecrement` | − stepper (defaults to a minus icon). |
|
|
48
|
+
| `NumberFieldInput` | The numeric input. |
|
|
49
|
+
| `NumberFieldIncrement` | + stepper (defaults to a plus icon). |
|
|
50
|
+
|
|
51
|
+
## Example
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import {
|
|
55
|
+
NumberField,
|
|
56
|
+
NumberFieldGroup,
|
|
57
|
+
NumberFieldDecrement,
|
|
58
|
+
NumberFieldInput,
|
|
59
|
+
NumberFieldIncrement,
|
|
60
|
+
} from '@acronis-platform/ui-react';
|
|
61
|
+
|
|
62
|
+
<NumberField defaultValue={3} min={0} max={99}>
|
|
63
|
+
<NumberFieldGroup>
|
|
64
|
+
<NumberFieldDecrement aria-label="Decrease" />
|
|
65
|
+
<NumberFieldInput aria-label="Quantity" />
|
|
66
|
+
<NumberFieldIncrement aria-label="Increase" />
|
|
67
|
+
</NumberFieldGroup>
|
|
68
|
+
</NumberField>;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Props
|
|
72
|
+
|
|
73
|
+
| Prop | Type | Default | Required | Description |
|
|
74
|
+
|------|------|---------|----------|-------------|
|
|
75
|
+
| `value` | `number | null` | — | no | The value (controlled). |
|
|
76
|
+
| `defaultValue` | `number | null` | — | no | The initial value (uncontrolled). |
|
|
77
|
+
| `min` | `number` | — | no | Minimum value (clamped). |
|
|
78
|
+
| `max` | `number` | — | no | Maximum value (clamped). |
|
|
79
|
+
| `step` | `number` | `1` | no | Increment for the steppers / arrow keys. |
|
|
80
|
+
| `disabled` | `boolean` | `false` | no | Disables the field and steppers. |
|
|
81
|
+
|
|
82
|
+
## Events
|
|
83
|
+
|
|
84
|
+
| Event | Payload | Description |
|
|
85
|
+
|-------|---------|-------------|
|
|
86
|
+
| `onValueChange` | `(value: number | null, eventDetails) => void` | Fired when the value changes. |
|
|
87
|
+
|
|
88
|
+
## Behavior
|
|
89
|
+
|
|
90
|
+
```gherkin
|
|
91
|
+
Scenario: Step the value
|
|
92
|
+
Given a NumberField with a value
|
|
93
|
+
When the user clicks − / + (or presses ↓ / ↑)
|
|
94
|
+
Then the value decrements / increments by step, clamped to min/max
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```gherkin
|
|
98
|
+
Scenario: Type a value
|
|
99
|
+
Given the input is focused
|
|
100
|
+
When the user types a number and blurs
|
|
101
|
+
Then the value is parsed and clamped to min/max
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```gherkin
|
|
105
|
+
Scenario: Disabled
|
|
106
|
+
Given disabled is set
|
|
107
|
+
Then the input and both steppers are non-interactive
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Accessibility
|
|
111
|
+
|
|
112
|
+
- Built on Base UI's NumberField: the input is keyboard-operable (↑/↓ step,
|
|
113
|
+
PageUp/PageDown, Home/End) and exposes the value to assistive tech; the steppers
|
|
114
|
+
are real `<button>`s.
|
|
115
|
+
- Give the steppers accessible labels ("Increase" / "Decrease") and the input a
|
|
116
|
+
name — via `aria-label` or by pairing the field with a `Field` / `FieldLabel`.
|
|
117
|
+
|
|
118
|
+
## Contrast
|
|
119
|
+
|
|
120
|
+
The box reuses the InputText tier (border / value text meet contrast in light and
|
|
121
|
+
dark); the stepper icons use the muted `--ui-text-on-surface-secondary`, going to
|
|
122
|
+
the primary text on hover, and the disabled token when disabled.
|