@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,182 @@
|
|
|
1
|
+
# Chart
|
|
2
|
+
|
|
3
|
+
> A theming layer over recharts — a `ChartContainer` that supplies series colors and recharts class overrides, plus tooltip and legend chrome (`ChartTooltipContent`, `ChartLegendContent`). The chart type (bar / line / area / pie / …) is composed from recharts primitives by the caller. Ported from the legacy shadcn-uikit `chart`.
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** data-display · **Since:** v0.47.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<ChartContainer config={config} className="h-[300px] w-[500px]">
|
|
17
|
+
<BarChart data={data}>
|
|
18
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
19
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" />
|
|
20
|
+
</BarChart>
|
|
21
|
+
</ChartContainer>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
A theming layer over [recharts](https://recharts.org). `ChartContainer` resolves
|
|
25
|
+
each series' color from a **dataviz palette** and themes recharts' internals with
|
|
26
|
+
the semantic token vocabulary; `ChartTooltipContent` and `ChartLegendContent` give
|
|
27
|
+
the tooltip and legend the library's look. The chart type itself (bar / line /
|
|
28
|
+
area / pie / …) is composed by the caller from recharts primitives.
|
|
29
|
+
|
|
30
|
+
Series colors are never hand-written. `config` names the series, the `palette`
|
|
31
|
+
prop says which palette they are painted from, and `ChartContainer` resolves each
|
|
32
|
+
one into a `--color-<key>` custom property the recharts marks reference. Every
|
|
33
|
+
palette resolves to `--ui-dataviz-*` tokens on the semantic tier.
|
|
34
|
+
|
|
35
|
+
## When to use
|
|
36
|
+
|
|
37
|
+
- Visualizing quantitative data — trends, comparisons, distributions.
|
|
38
|
+
- You want recharts' flexibility but the Acronis tooltip/legend/axis styling.
|
|
39
|
+
|
|
40
|
+
## When not to use
|
|
41
|
+
|
|
42
|
+
- A single metric or KPI — use a `Tag`, `Badge`, or plain text.
|
|
43
|
+
- Tabular detail — use `Table` / `DataTable`.
|
|
44
|
+
- Progress toward a goal — use `Progress` or `ProgressCircle`.
|
|
45
|
+
|
|
46
|
+
## Parts
|
|
47
|
+
|
|
48
|
+
| Export | Purpose |
|
|
49
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
50
|
+
| `ChartContainer` | The wrapper. Takes `config` + `palette` + the recharts plot as children; resolves and injects series colors. |
|
|
51
|
+
| `ChartTooltip` | Re-export of recharts' `Tooltip`. Pass `ChartTooltipContent` as its `content`. |
|
|
52
|
+
| `ChartTooltipContent` | Themed tooltip body — label + per-series indicator/value. |
|
|
53
|
+
| `ChartLegend` | Re-export of recharts' `Legend`. Pass `ChartLegendContent` as its `content`. |
|
|
54
|
+
| `ChartLegendContent` | Themed legend body — swatch + label per series. |
|
|
55
|
+
| `ChartStyle` | Injects the `--color-<key>` custom properties (used internally by `ChartContainer`). |
|
|
56
|
+
|
|
57
|
+
`ChartConfig` is the per-series map of `label` / `icon` / `tone`. It carries no
|
|
58
|
+
color: `tone` only re-points a series **within** the palette — `{ slot: n }` for
|
|
59
|
+
another categorical hue, `{ status: '…' }` under the `status` palette, or
|
|
60
|
+
`{ sameAs: 'key' }` to share another series' color.
|
|
61
|
+
|
|
62
|
+
## Example
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import {
|
|
66
|
+
ChartContainer,
|
|
67
|
+
ChartTooltip,
|
|
68
|
+
ChartTooltipContent,
|
|
69
|
+
ChartLegend,
|
|
70
|
+
ChartLegendContent,
|
|
71
|
+
type ChartConfig,
|
|
72
|
+
} from '@acronis-platform/ui-react';
|
|
73
|
+
import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts';
|
|
74
|
+
|
|
75
|
+
// No colors here — the default `categorical` palette paints the series in the
|
|
76
|
+
// order they are declared.
|
|
77
|
+
const config = {
|
|
78
|
+
desktop: { label: 'Desktop' },
|
|
79
|
+
mobile: { label: 'Mobile' },
|
|
80
|
+
} satisfies ChartConfig;
|
|
81
|
+
|
|
82
|
+
<ChartContainer config={config} className="h-[300px] w-[500px]">
|
|
83
|
+
<BarChart data={data}>
|
|
84
|
+
<CartesianGrid vertical={false} />
|
|
85
|
+
<XAxis dataKey="month" tickLine={false} axisLine={false} />
|
|
86
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
87
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
88
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
89
|
+
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
90
|
+
</BarChart>
|
|
91
|
+
</ChartContainer>;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`recharts` is a peer-resolved dependency of `@acronis-platform/ui-react`; import
|
|
95
|
+
the chart primitives (`BarChart`, `Bar`, …) directly from `recharts`.
|
|
96
|
+
|
|
97
|
+
## Props
|
|
98
|
+
|
|
99
|
+
| Prop | Type | Default | Required | Description |
|
|
100
|
+
|------|------|---------|----------|-------------|
|
|
101
|
+
| `config` | `ChartConfig` | — | yes | Per-series map of label / icon / tone. ChartContainer resolves each entry's colour out of `palette` and emits it as a `--color-<key>` custom property. Declare exactly the series the chart plots: a stop is assigned by an entry's position here, so an entry for a series that isn't drawn still consumes a colour and shifts the ones that follow. |
|
|
102
|
+
| `palette` | `ChartPalette` | `{ type: 'categorical' }` | no | The dataviz palette the series are painted from — `categorical` (16 hues), `sequential` (a `ramp` of 8 stops), `diverging` (a `pair` of 6), or `status` (6 semantic tones). Series walk it in its defined order. There is no free-form colour and no "no palette" state, so a chart cannot paint a hue outside the design system. |
|
|
103
|
+
| `active` | `boolean` | — | no | Whether the tooltip is showing (set by recharts on hover/focus). Drives ChartTooltipContent rendering. |
|
|
104
|
+
| `hideLabel` | `boolean` | `false` | no | Hide the tooltip's heading label. |
|
|
105
|
+
| `hideIndicator` | `boolean` | `false` | no | Hide the per-series color dot in the tooltip. |
|
|
106
|
+
| `hideIcon` | `boolean` | `false` | no | Hide the per-series icon in the legend (use the color swatch). |
|
|
107
|
+
| `nameKey` | `string` | — | no | Config key to resolve each series' label from the payload. |
|
|
108
|
+
| `labelKey` | `string` | — | no | Config key to resolve the tooltip's heading label. |
|
|
109
|
+
|
|
110
|
+
## Behavior
|
|
111
|
+
|
|
112
|
+
Chart is a theming layer over [recharts](https://recharts.org). `ChartContainer`
|
|
113
|
+
provides the series `config` (via context) and a sized, responsive box; the
|
|
114
|
+
caller composes the actual plot from recharts primitives (`BarChart`, `LineChart`,
|
|
115
|
+
`AreaChart`, `PieChart`, …). `ChartTooltipContent` and `ChartLegendContent` are
|
|
116
|
+
passed to recharts' `Tooltip` / `Legend` through their `content` prop.
|
|
117
|
+
|
|
118
|
+
```gherkin
|
|
119
|
+
Scenario: Render a chart
|
|
120
|
+
Given a config and a recharts plot as children
|
|
121
|
+
Then the plot renders inside a responsive, aspect-video container
|
|
122
|
+
And recharts' grid, axis, and cursor pick up the semantic theme tokens
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```gherkin
|
|
126
|
+
Scenario: Series colors from palette
|
|
127
|
+
Given a config entry { desktop: { label: 'Desktop' } } and palette={ type: 'categorical' }
|
|
128
|
+
Then a `--color-desktop` custom property is injected scoped to this chart
|
|
129
|
+
And the value is the first stop of the categorical palette
|
|
130
|
+
And series referencing fill="var(--color-desktop)" paint with that color
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```gherkin
|
|
134
|
+
Scenario: Series tone override
|
|
135
|
+
Given a config entry with { failed: { tone: { status: 'danger' } } } and palette={ type: 'status' }
|
|
136
|
+
Then the `--color-failed` custom property resolves to the danger status token
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```gherkin
|
|
140
|
+
Scenario: Tooltip on hover
|
|
141
|
+
Given a ChartTooltip with content={<ChartTooltipContent />}
|
|
142
|
+
When the user hovers a data point
|
|
143
|
+
Then a card shows the point's label and one row per series
|
|
144
|
+
And each row has a color indicator (dot by default; line or dashed via `indicator`)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```gherkin
|
|
148
|
+
Scenario: Legend
|
|
149
|
+
Given a ChartLegend with content={<ChartLegendContent />}
|
|
150
|
+
Then a swatch + label renders for each configured series
|
|
151
|
+
And a series icon replaces the swatch unless hideIcon is set
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```gherkin
|
|
155
|
+
Scenario: Default palette
|
|
156
|
+
Given a ChartContainer with no explicit palette prop
|
|
157
|
+
Then the categorical palette is used
|
|
158
|
+
And each series takes the next categorical stop in config-declaration order
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Accessibility
|
|
162
|
+
|
|
163
|
+
- Charts are inherently visual. recharts renders an SVG surface; on its own a
|
|
164
|
+
chart conveys little to assistive tech, so **pair every chart with a text
|
|
165
|
+
alternative** — a caption, a summary sentence, or an adjacent data table that
|
|
166
|
+
carries the same numbers.
|
|
167
|
+
- Give the `ChartContainer` an accessible name when the chart is meaningful on its
|
|
168
|
+
own (`aria-label` / `aria-labelledby` referencing a visible heading).
|
|
169
|
+
- Do **not** rely on color alone to distinguish series. The legend pairs each
|
|
170
|
+
color swatch with a text label, and the tooltip shows series names next to
|
|
171
|
+
values — keep both visible (don't `hideLabel` + `hideIndicator` together).
|
|
172
|
+
- The tooltip surface uses `--ui-background-surface-primary` with
|
|
173
|
+
`--ui-text-on-surface-primary` values and `--ui-text-on-surface-secondary`
|
|
174
|
+
labels; axis ticks use the muted token. These meet contrast in light and dark.
|
|
175
|
+
Series colors are caller-supplied — pick values that meet 3:1 against the
|
|
176
|
+
surface and are distinguishable for color-vision deficiencies.
|
|
177
|
+
|
|
178
|
+
## Contrast
|
|
179
|
+
|
|
180
|
+
The chart chrome (tooltip, legend, axis labels, grid) resolves to semantic
|
|
181
|
+
`--ui-*` tokens that meet contrast in both themes. Series fills/strokes come from
|
|
182
|
+
`config` and are the caller's responsibility.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Checkbox
|
|
2
|
+
|
|
3
|
+
> A control that lets users select or deselect an option. Supports checked, unchecked, and indeterminate states; used individually for a binary choice or in groups where any number of options may be selected.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** forms · **Since:** v0.7.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Checkbox } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
{/* Box only — name it with aria-label */}
|
|
17
|
+
<Checkbox
|
|
18
|
+
aria-label="Accept terms"
|
|
19
|
+
checked={accepted}
|
|
20
|
+
onCheckedChange={setAccepted}
|
|
21
|
+
/>
|
|
22
|
+
|
|
23
|
+
{/* With label + description (the whole row toggles) */}
|
|
24
|
+
<Checkbox
|
|
25
|
+
label="Email notifications"
|
|
26
|
+
description="Get notified when someone mentions you."
|
|
27
|
+
checked={accepted}
|
|
28
|
+
onCheckedChange={setAccepted}
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
{/* Indeterminate (e.g. a partially-selected parent) */}
|
|
32
|
+
<Checkbox aria-label="Select all" indeterminate />
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
A control that lets users select or deselect an option. Use it for a single
|
|
36
|
+
binary choice (on/off) or in a group where users may select any number of
|
|
37
|
+
options — including none. Supports an **indeterminate** state for a parent that
|
|
38
|
+
summarizes a partially-selected group.
|
|
39
|
+
|
|
40
|
+
## When to Use
|
|
41
|
+
|
|
42
|
+
- A single on/off choice (e.g. "I accept the terms").
|
|
43
|
+
- A list of non-exclusive options where any combination may be selected.
|
|
44
|
+
- A "select all" parent that reflects a partial selection (indeterminate).
|
|
45
|
+
|
|
46
|
+
## When NOT to Use
|
|
47
|
+
|
|
48
|
+
- **Mutually exclusive** choices — use a radio group.
|
|
49
|
+
- **On/off that applies immediately** (a setting toggle) — use a Switch.
|
|
50
|
+
- **A single action** — use a Button.
|
|
51
|
+
|
|
52
|
+
## Quick Examples
|
|
53
|
+
|
|
54
|
+
### React
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { Checkbox } from '@acronis-platform/ui-react';
|
|
58
|
+
|
|
59
|
+
function Terms() {
|
|
60
|
+
const [accepted, setAccepted] = useState(false);
|
|
61
|
+
return (
|
|
62
|
+
<Checkbox
|
|
63
|
+
label="I accept the terms"
|
|
64
|
+
description="You agree to the privacy policy."
|
|
65
|
+
checked={accepted}
|
|
66
|
+
onCheckedChange={setAccepted}
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Pass `label` (and optional `description`) to compose the full field — the whole
|
|
73
|
+
row becomes clickable and the box is wired to the text for accessibility. Omit
|
|
74
|
+
them for a bare box, and name it with `aria-label`:
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
<Checkbox aria-label="Select all" indeterminate />
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## States
|
|
81
|
+
|
|
82
|
+
| State | How | Visual |
|
|
83
|
+
| ------------- | ----------------------------- | ---------------------------------- |
|
|
84
|
+
| Unchecked | default | Idle border, no glyph |
|
|
85
|
+
| Checked | `checked` / `default-checked` | Active fill + check glyph |
|
|
86
|
+
| Indeterminate | `indeterminate` | Active fill + minus glyph, `mixed` |
|
|
87
|
+
| Disabled | `disabled` | Disabled tokens; not interactive |
|
|
88
|
+
|
|
89
|
+
## Spec Files
|
|
90
|
+
|
|
91
|
+
| File | Contents |
|
|
92
|
+
| ------------------ | ----------------------------------------------------------------- |
|
|
93
|
+
| `index.yaml` | Identity, status, category, dependencies, Figma link |
|
|
94
|
+
| `anatomy.yaml` | Root, container/content/label/description/indicator parts, states |
|
|
95
|
+
| `api.yaml` | Framework-agnostic contract + framework adapters |
|
|
96
|
+
| `tokens.yaml` | `--ui-checkbox-*` token references |
|
|
97
|
+
| `behavior.md` | Given/When/Then behavior scenarios |
|
|
98
|
+
| `accessibility.md` | ARIA roles, keyboard map, screen-reader and contrast requirements |
|
|
99
|
+
|
|
100
|
+
## Props
|
|
101
|
+
|
|
102
|
+
| Prop | Type | Default | Required | Description |
|
|
103
|
+
|------|------|---------|----------|-------------|
|
|
104
|
+
| `checked` | `boolean` | — | no | Controlled checked state. Pair with the change event. |
|
|
105
|
+
| `default-checked` | `boolean` | `false` | no | Initial checked state when uncontrolled. |
|
|
106
|
+
| `indeterminate` | `boolean` | `false` | no | Renders the mixed/indeterminate state (minus glyph, aria-checked="mixed"). Independent of `checked` — set by the consumer, not toggled by clicking. |
|
|
107
|
+
| `disabled` | `boolean` | `false` | no | Disables interaction; applies the disabled form tokens. |
|
|
108
|
+
| `required` | `boolean` | `false` | no | Marks the control as required in a form. |
|
|
109
|
+
| `name` | `string` | — | no | Form field name submitted with the form. |
|
|
110
|
+
| `value` | `string` | — | no | Form field value when checked. |
|
|
111
|
+
| `label` | `ReactNode` | — | no | Optional label rendered beside the box. When provided, the whole row becomes a clickable `<label>` and the box is named via aria-labelledby. |
|
|
112
|
+
| `description` | `ReactNode` | — | no | Optional secondary description rendered under the label, associated with the box via aria-describedby. |
|
|
113
|
+
|
|
114
|
+
## Events
|
|
115
|
+
|
|
116
|
+
| Event | Payload | Description |
|
|
117
|
+
|-------|---------|-------------|
|
|
118
|
+
| `checked-change` | `boolean` | Fired when the checked state changes (React: `onCheckedChange`). Payload is the new checked value. |
|
|
119
|
+
|
|
120
|
+
## Behavior
|
|
121
|
+
|
|
122
|
+
### Rendering
|
|
123
|
+
|
|
124
|
+
#### Renders unchecked by default
|
|
125
|
+
|
|
126
|
+
**Given** a Checkbox with no `checked` / `default-checked`
|
|
127
|
+
**When** it renders
|
|
128
|
+
**Then** it exposes `role="checkbox"` with `aria-checked="false"`
|
|
129
|
+
**And** no glyph is shown
|
|
130
|
+
|
|
131
|
+
#### Reflects a controlled checked prop
|
|
132
|
+
|
|
133
|
+
**Given** a Checkbox with `checked`
|
|
134
|
+
**When** it renders
|
|
135
|
+
**Then** `aria-checked="true"` and the check glyph is shown
|
|
136
|
+
|
|
137
|
+
#### Renders the indeterminate state
|
|
138
|
+
|
|
139
|
+
**Given** a Checkbox with `indeterminate`
|
|
140
|
+
**When** it renders
|
|
141
|
+
**Then** `aria-checked="mixed"` and the minus glyph is shown
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Interaction
|
|
146
|
+
|
|
147
|
+
#### Toggles on click (uncontrolled)
|
|
148
|
+
|
|
149
|
+
**Given** an uncontrolled Checkbox
|
|
150
|
+
**When** the user clicks it (or presses Space while focused)
|
|
151
|
+
**Then** the checked state flips
|
|
152
|
+
**And** `checked-change` fires with the new value
|
|
153
|
+
|
|
154
|
+
#### Controlled mode defers to the consumer
|
|
155
|
+
|
|
156
|
+
**Given** a Checkbox with a controlled `checked` value
|
|
157
|
+
**When** the user clicks it
|
|
158
|
+
**Then** `checked-change` fires with the requested value
|
|
159
|
+
**And** the visual state changes only when the consumer updates `checked`
|
|
160
|
+
|
|
161
|
+
#### Disabled blocks interaction
|
|
162
|
+
|
|
163
|
+
**Given** a Checkbox with `disabled`
|
|
164
|
+
**When** the user clicks it
|
|
165
|
+
**Then** the state does not change
|
|
166
|
+
**And** `checked-change` does not fire
|
|
167
|
+
**And** the disabled form tokens are applied
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### States
|
|
172
|
+
|
|
173
|
+
#### Hover
|
|
174
|
+
|
|
175
|
+
**Given** an enabled Checkbox
|
|
176
|
+
**When** the pointer hovers it
|
|
177
|
+
**Then** the border uses `--ui-checkbox-unchecked-box-border-color-hover`
|
|
178
|
+
|
|
179
|
+
#### Focus
|
|
180
|
+
|
|
181
|
+
**Given** a Checkbox
|
|
182
|
+
**When** it receives keyboard focus
|
|
183
|
+
**Then** a 3px focus ring (`--ui-focus-primary`) is shown
|
|
184
|
+
|
|
185
|
+
#### Checked / indeterminate fill
|
|
186
|
+
|
|
187
|
+
**Given** a checked or indeterminate Checkbox
|
|
188
|
+
**When** it renders
|
|
189
|
+
**Then** the box fills with `--ui-checkbox-checked-box-color-idle` and the border with
|
|
190
|
+
`--ui-checkbox-checked-box-border-color-idle`
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Edge Cases
|
|
195
|
+
|
|
196
|
+
#### Indeterminate is independent of checked
|
|
197
|
+
|
|
198
|
+
**Given** a Checkbox with both `indeterminate` and `checked`
|
|
199
|
+
**When** it renders
|
|
200
|
+
**Then** `aria-checked="mixed"` wins (the minus glyph is shown)
|
|
201
|
+
|
|
202
|
+
#### Form submission
|
|
203
|
+
|
|
204
|
+
**Given** a Checkbox with `name` and `value` inside a form
|
|
205
|
+
**When** the form is submitted while checked
|
|
206
|
+
**Then** the field is included with its value
|
|
207
|
+
|
|
208
|
+
## Accessibility
|
|
209
|
+
|
|
210
|
+
Implements the [WAI-ARIA Checkbox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/)
|
|
211
|
+
via Base UI's Checkbox primitive.
|
|
212
|
+
|
|
213
|
+
## ARIA Roles and Attributes
|
|
214
|
+
|
|
215
|
+
| Attribute | Value | Reason |
|
|
216
|
+
| --------------- | ---------------------------- | -------------------------------------------- |
|
|
217
|
+
| `role` | `"checkbox"` | Identifies the control |
|
|
218
|
+
| `aria-checked` | `"true" / "false" / "mixed"` | Reflects checked / unchecked / indeterminate |
|
|
219
|
+
| `aria-disabled` | present when disabled | Conveyed via the disabled state |
|
|
220
|
+
|
|
221
|
+
The control must have an **accessible name** — provide a visible `<label>`
|
|
222
|
+
associated with it, or an `aria-label` / `aria-labelledby` when used standalone.
|
|
223
|
+
|
|
224
|
+
## Keyboard Navigation
|
|
225
|
+
|
|
226
|
+
| Key | Action |
|
|
227
|
+
| ----- | ----------------------------- |
|
|
228
|
+
| Tab | Moves focus to / from the box |
|
|
229
|
+
| Space | Toggles checked / unchecked |
|
|
230
|
+
|
|
231
|
+
The box is focusable in its enabled state and removed from the tab order when
|
|
232
|
+
disabled.
|
|
233
|
+
|
|
234
|
+
## Screen Reader Requirements
|
|
235
|
+
|
|
236
|
+
1. Announced as a checkbox with its accessible name.
|
|
237
|
+
2. Announces "checked", "not checked", or "mixed" from `aria-checked`.
|
|
238
|
+
3. The glyph (check / minus) is decorative — it carries no separate semantics.
|
|
239
|
+
|
|
240
|
+
## Color and Contrast
|
|
241
|
+
|
|
242
|
+
| Element | Minimum Ratio | Standard |
|
|
243
|
+
| ------------------------ | ------------- | ---------------------- |
|
|
244
|
+
| Box border vs background | 3:1 | WCAG 1.4.11 (non-text) |
|
|
245
|
+
| Glyph vs active fill | 3:1 | WCAG 1.4.11 (non-text) |
|
|
246
|
+
| Focus indicator | 3:1 | WCAG 1.4.11 |
|
|
247
|
+
|
|
248
|
+
State is not conveyed by color alone — the check / minus glyph and
|
|
249
|
+
`aria-checked` distinguish checked, indeterminate, and unchecked.
|
|
250
|
+
|
|
251
|
+
## Testing Checklist
|
|
252
|
+
|
|
253
|
+
- [ ] `role="checkbox"` with `aria-checked` reflecting true / false / mixed
|
|
254
|
+
- [ ] Has an accessible name (label / `aria-label`)
|
|
255
|
+
- [ ] Space toggles; Tab reaches it; disabled removes it from the tab order
|
|
256
|
+
- [ ] Focus ring meets 3:1; border and glyph meet 3:1
|
|
257
|
+
- [ ] `checked-change` does not fire while disabled
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Chip
|
|
2
|
+
|
|
3
|
+
> A compact, interactive label for a selection, a removable token, or an inline action. The `removable` variant carries a trailing × button; `selectable` is a toggle that shows an active style when selected; `operational` is a plain action chip with a strong-link label. All three accept an optional leading icon.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** data-display · **Since:** v0.36.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Chip } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Chip onRemove={() => remove(id)}>Filter</Chip>
|
|
17
|
+
<Chip variant="selectable" selected={on} onClick={toggle}>Option</Chip>
|
|
18
|
+
<Chip variant="selectable" icon={<CircleInfoIcon />}>With icon</Chip>
|
|
19
|
+
<Chip variant="operational" onClick={addFilter}>Add filter</Chip>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
A compact, interactive label — a removable token, a selectable toggle, or an
|
|
23
|
+
operational action.
|
|
24
|
+
|
|
25
|
+
## When to use
|
|
26
|
+
|
|
27
|
+
- **Removable:** represent a dismissible selection — applied filters, recipients,
|
|
28
|
+
uploaded files, entered tags. The × lets the user drop one.
|
|
29
|
+
- **Selectable:** offer a small, toggleable choice — filter/quick-pick chips,
|
|
30
|
+
multi-select option pills.
|
|
31
|
+
- **Operational:** offer a small inline action that sits in a row of chips —
|
|
32
|
+
"Add filter", "Clear all", "Show 3 more". Its strong-link label marks it as
|
|
33
|
+
the actionable one among neighbouring chips.
|
|
34
|
+
|
|
35
|
+
## When not to use
|
|
36
|
+
|
|
37
|
+
- For a **static**, non-interactive status/category label, use
|
|
38
|
+
[`Tag`](../tag/README.md) instead — Chip implies an action (remove or toggle).
|
|
39
|
+
- For a primary action, use `Button`. For a binary setting, use `Switch` or
|
|
40
|
+
`Checkbox`.
|
|
41
|
+
|
|
42
|
+
## Parts
|
|
43
|
+
|
|
44
|
+
| Part | Element | Notes |
|
|
45
|
+
| -------- | -------- | -------------------------------------------------------------------------------------- |
|
|
46
|
+
| `root` | `div` | The pill. `selectable` becomes a `role="button"` toggle, `operational` a plain button. |
|
|
47
|
+
| `icon` | `svg` | Optional leading icon (16px), tinted by the icon token. |
|
|
48
|
+
| `label` | text | Children; truncates with an ellipsis. Semibold + blue for `operational`. |
|
|
49
|
+
| `remove` | `button` | Trailing × (`removable` only); emits `remove` / `onRemove`. |
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { Chip } from '@acronis-platform/ui-react';
|
|
55
|
+
import { CircleInfoIcon } from '@acronis-platform/icons-react/stroke-mono';
|
|
56
|
+
|
|
57
|
+
// Removable filter token
|
|
58
|
+
<Chip onRemove={() => removeFilter(id)}>Status: Active</Chip>
|
|
59
|
+
|
|
60
|
+
// Selectable (controlled) toggle
|
|
61
|
+
<Chip variant="selectable" selected={on} onClick={() => setOn(!on)}>
|
|
62
|
+
Only my devices
|
|
63
|
+
</Chip>
|
|
64
|
+
|
|
65
|
+
// With a leading icon
|
|
66
|
+
<Chip variant="selectable" icon={<CircleInfoIcon />}>Info</Chip>
|
|
67
|
+
|
|
68
|
+
// Operational — an inline action among the chips
|
|
69
|
+
<Chip variant="operational" onClick={addFilter}>Add filter</Chip>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Notes
|
|
73
|
+
|
|
74
|
+
- Selection and removal are **controlled** — Chip renders the visual state and
|
|
75
|
+
emits intent; the consumer owns the data.
|
|
76
|
+
- Theming is driven entirely by the `--ui-chip-*` token tier; the focus ring
|
|
77
|
+
reuses `--ui-focus-primary`.
|
|
78
|
+
|
|
79
|
+
## Props
|
|
80
|
+
|
|
81
|
+
| Prop | Type | Default | Required | Description |
|
|
82
|
+
|------|------|---------|----------|-------------|
|
|
83
|
+
| `variant` | `'removable' | 'selectable' | 'operational'` | `removable` | no | `removable` renders a trailing × button; `selectable` is a toggle (`role="button"` + `aria-pressed`) that applies the active style when `selected`; `operational` is a plain action chip (`role="button"`, no ×, no pressed state) whose label uses the strong-link style. All three share the `--ui-chip-*` box/border tokens and carry a per-variant label color. |
|
|
84
|
+
| `selected` | `boolean` | `false` | no | `selectable` only — applies the selected (active) styling and sets `aria-pressed`. |
|
|
85
|
+
| `icon` | `ReactNode` | — | no | Optional leading icon, rendered at 16px before the label. |
|
|
86
|
+
| `removeLabel` | `string` | `Remove` | no | Accessible label for the remove (×) button. |
|
|
87
|
+
|
|
88
|
+
## Events
|
|
89
|
+
|
|
90
|
+
| Event | Payload | Description |
|
|
91
|
+
|-------|---------|-------------|
|
|
92
|
+
| `remove` | `none` | `removable` only — emitted when the trailing × button is activated (React: `onRemove`). |
|
|
93
|
+
|
|
94
|
+
## Content slots
|
|
95
|
+
|
|
96
|
+
| Slot | Description |
|
|
97
|
+
|------|-------------|
|
|
98
|
+
| `default` | The chip label (children). Truncates when it overflows. |
|
|
99
|
+
|
|
100
|
+
## Behavior
|
|
101
|
+
|
|
102
|
+
### Removable
|
|
103
|
+
|
|
104
|
+
- **Given** a `removable` chip
|
|
105
|
+
**When** it renders
|
|
106
|
+
**Then** it shows the label and a trailing × button.
|
|
107
|
+
|
|
108
|
+
- **Given** a `removable` chip
|
|
109
|
+
**When** the user activates the × button (click, Enter, or Space)
|
|
110
|
+
**Then** the `remove` event fires (React: `onRemove`). The chip does **not**
|
|
111
|
+
remove itself — the consumer owns the list and decides what to drop.
|
|
112
|
+
|
|
113
|
+
- **Given** a `removable` chip
|
|
114
|
+
**When** the user hovers or presses the chip
|
|
115
|
+
**Then** the container shows the hover / active fill + border.
|
|
116
|
+
|
|
117
|
+
### Selectable
|
|
118
|
+
|
|
119
|
+
- **Given** a `selectable` chip
|
|
120
|
+
**When** it renders
|
|
121
|
+
**Then** it is exposed as a toggle button (`role="button"`,
|
|
122
|
+
`aria-pressed` reflecting `selected`) with an optional leading icon and no ×.
|
|
123
|
+
|
|
124
|
+
- **Given** a `selectable` chip
|
|
125
|
+
**When** the user activates it (click, Enter, or Space)
|
|
126
|
+
**Then** its `onClick` fires. Selection is **controlled**: the consumer flips
|
|
127
|
+
`selected`, which applies the active fill + border.
|
|
128
|
+
|
|
129
|
+
- **Given** a `selectable` chip with `selected`
|
|
130
|
+
**When** it renders
|
|
131
|
+
**Then** the container uses the active fill + border and `aria-pressed="true"`.
|
|
132
|
+
|
|
133
|
+
### Operational
|
|
134
|
+
|
|
135
|
+
- **Given** an `operational` chip
|
|
136
|
+
**When** it renders
|
|
137
|
+
**Then** it is exposed as a button (`role="button"`) with an optional leading
|
|
138
|
+
icon, no ×, and a label in the strong-link style (semibold,
|
|
139
|
+
`--ui-chip-operational-label-color`).
|
|
140
|
+
|
|
141
|
+
- **Given** an `operational` chip
|
|
142
|
+
**When** the user activates it (click, Enter, or Space)
|
|
143
|
+
**Then** its `onClick` fires. It has no selected state — unlike `selectable`
|
|
144
|
+
it does not report `aria-pressed`, because it triggers an operation rather
|
|
145
|
+
than toggling one.
|
|
146
|
+
|
|
147
|
+
- **Given** an `operational` chip
|
|
148
|
+
**When** the user hovers or presses the chip
|
|
149
|
+
**Then** the container shows the hover / active fill + border, the same as
|
|
150
|
+
`removable`.
|
|
151
|
+
|
|
152
|
+
### Content
|
|
153
|
+
|
|
154
|
+
- **Given** a label longer than the chip's width
|
|
155
|
+
**When** it renders
|
|
156
|
+
**Then** the label truncates with an ellipsis; the chip keeps its min-width.
|
|
157
|
+
|
|
158
|
+
## Accessibility
|
|
159
|
+
|
|
160
|
+
## Roles
|
|
161
|
+
|
|
162
|
+
- **Removable:** the chip container is presentational; the **× is a real
|
|
163
|
+
`<button>`** with an accessible name (`removeLabel`, default "Remove"). Give
|
|
164
|
+
it a contextual name when there are several chips (e.g. "Remove Backup").
|
|
165
|
+
- **Selectable:** the chip container is a toggle — `role="button"` with
|
|
166
|
+
`aria-pressed` reflecting `selected`.
|
|
167
|
+
- **Operational:** the chip container is a plain button — `role="button"` with
|
|
168
|
+
**no** `aria-pressed`, since it triggers an operation rather than toggling a
|
|
169
|
+
state. Announcing it as pressable-but-never-pressed would be a lie.
|
|
170
|
+
|
|
171
|
+
## Keyboard
|
|
172
|
+
|
|
173
|
+
- **Removable:** Tab focuses the × button; Enter / Space activate it (native
|
|
174
|
+
`<button>`).
|
|
175
|
+
- **Selectable / operational:** Tab focuses the chip; Enter / Space activate it
|
|
176
|
+
(the component mirrors native button activation for the `div[role=button]`).
|
|
177
|
+
|
|
178
|
+
## Focus
|
|
179
|
+
|
|
180
|
+
- A visible 3px `--ui-focus-primary` ring marks focus — on the × button for
|
|
181
|
+
`removable` (via `focus-within` on the container) and on the chip itself for
|
|
182
|
+
`selectable` / `operational` (`focus-visible`). Focus is never suppressed
|
|
183
|
+
without a replacement indicator.
|
|
184
|
+
|
|
185
|
+
## Screen readers
|
|
186
|
+
|
|
187
|
+
- Selectable chips announce their pressed/unpressed state via `aria-pressed`;
|
|
188
|
+
operational chips announce as an ordinary button.
|
|
189
|
+
- The remove button announces its label; pair it with the chip's text in the
|
|
190
|
+
accessible name when ambiguity is possible.
|
|
191
|
+
|
|
192
|
+
## Contrast
|
|
193
|
+
|
|
194
|
+
- Label, border, and icon colors come from `--ui-chip-*` tokens that meet the
|
|
195
|
+
contrast bar per theme; do not override them with ad-hoc colors.
|