@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,195 @@
|
|
|
1
|
+
# Resizable
|
|
2
|
+
|
|
3
|
+
> A group of panels separated by draggable handles that let the user resize adjacent regions along one axis. Composable parts (panel group, panel, handle); the handle is a thin divider with an optional grab-bar grip and resizes its neighbouring panels on drag or arrow keys.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** layout · **Since:** v0.23.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<ResizablePanelGroup orientation="horizontal">
|
|
17
|
+
<ResizablePanel defaultSize={50}>One</ResizablePanel>
|
|
18
|
+
<ResizableHandle />
|
|
19
|
+
<ResizablePanel defaultSize={50}>Two</ResizablePanel>
|
|
20
|
+
</ResizablePanelGroup>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
A group of panels separated by draggable handles, letting users resize adjacent
|
|
24
|
+
regions along one axis. Composable from a panel group, panels, and handles — the
|
|
25
|
+
React adapter wraps [`react-resizable-panels`](https://github.com/bvaughn/react-resizable-panels).
|
|
26
|
+
|
|
27
|
+
## When to use
|
|
28
|
+
|
|
29
|
+
- Split layouts the user should be able to re-proportion: a sidebar + content, a
|
|
30
|
+
list + detail (master/detail), an editor + preview.
|
|
31
|
+
- Any two-or-more-pane surface where a fixed split would be too rigid.
|
|
32
|
+
|
|
33
|
+
## When not to use
|
|
34
|
+
|
|
35
|
+
- Fixed layout chrome that shouldn't move — use a plain sidebar/grid.
|
|
36
|
+
- Reordering or moving items — that's drag-and-drop, not resizing.
|
|
37
|
+
- A single scrollable region — resizing needs at least two panels.
|
|
38
|
+
|
|
39
|
+
## Parts
|
|
40
|
+
|
|
41
|
+
| Part | Role |
|
|
42
|
+
| --------------------- | ------------------------------------------------------------ |
|
|
43
|
+
| `ResizablePanelGroup` | Container; sets the axis via `orientation` and tracks sizes. |
|
|
44
|
+
| `ResizablePanel` | A resizable region (`defaultSize` / `minSize` / `maxSize`). |
|
|
45
|
+
| `ResizableHandle` | The draggable separator (cursor + border change on hover). |
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import {
|
|
51
|
+
ResizablePanelGroup,
|
|
52
|
+
ResizablePanel,
|
|
53
|
+
ResizableHandle,
|
|
54
|
+
} from '@acronis-platform/ui-react';
|
|
55
|
+
|
|
56
|
+
// Horizontal split
|
|
57
|
+
<ResizablePanelGroup orientation="horizontal" className="h-64 rounded border">
|
|
58
|
+
<ResizablePanel defaultSize={30} minSize={20}>
|
|
59
|
+
Sidebar
|
|
60
|
+
</ResizablePanel>
|
|
61
|
+
<ResizableHandle />
|
|
62
|
+
<ResizablePanel defaultSize={70}>Content</ResizablePanel>
|
|
63
|
+
</ResizablePanelGroup>;
|
|
64
|
+
|
|
65
|
+
// Vertical split (panels stacked)
|
|
66
|
+
<ResizablePanelGroup orientation="vertical" className="h-96">
|
|
67
|
+
<ResizablePanel defaultSize={60}>Editor</ResizablePanel>
|
|
68
|
+
<ResizableHandle />
|
|
69
|
+
<ResizablePanel defaultSize={40}>Preview</ResizablePanel>
|
|
70
|
+
</ResizablePanelGroup>;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
> The group needs a bounded height (or width, when vertical) from its container —
|
|
74
|
+
> set one on the group or its parent, as in the `h-64` / `h-96` above.
|
|
75
|
+
|
|
76
|
+
## Theming
|
|
77
|
+
|
|
78
|
+
Colors, sizes, and the cursor come from the `--ui-resizable-*` token tier in
|
|
79
|
+
`@acronis-platform/tokens-pd` (generated from `@acronis-platform/design-tokens`)
|
|
80
|
+
and resolve per brand/theme — see `tokens.yaml`. Don't hard-code values.
|
|
81
|
+
|
|
82
|
+
## Props
|
|
83
|
+
|
|
84
|
+
| Prop | Type | Default | Required | Description |
|
|
85
|
+
|------|------|---------|----------|-------------|
|
|
86
|
+
| `orientation` | `'horizontal' | 'vertical'` | `horizontal` | no | Resize axis of the group (panel-group part). `horizontal` arranges panels in a row with vertical handles; `vertical` stacks them with horizontal handles. |
|
|
87
|
+
| `defaultSize` | `number` | `undefined` | no | Initial size of a panel as a percentage of the group (panel part). Panels without one share the remaining space. |
|
|
88
|
+
| `minSize` | `number` | `undefined` | no | Minimum size of a panel, in percent of the group (panel part). |
|
|
89
|
+
| `maxSize` | `number` | `undefined` | no | Maximum size of a panel, in percent of the group (panel part). |
|
|
90
|
+
| `collapsible` | `boolean` | `false` | no | Whether the panel can collapse below its `minSize` to a collapsed size (panel part). |
|
|
91
|
+
| `disableResize` | `boolean` | `false` | no | Disable resizing through the handle or panel (`disabled` on the React `ResizableHandle` / `ResizablePanel`). Named `disableResize` here so it is not confused with a root-level disabled state — resizing is a per-part capability, the group is never globally "disabled". |
|
|
92
|
+
|
|
93
|
+
## Events
|
|
94
|
+
|
|
95
|
+
| Event | Payload | Description |
|
|
96
|
+
|-------|---------|-------------|
|
|
97
|
+
| `resize` | `undefined` | Fired as a panel's size changes during a drag (panel part). The React adapter exposes this as the panel's `onResize` callback. |
|
|
98
|
+
|
|
99
|
+
## Content slots
|
|
100
|
+
|
|
101
|
+
| Slot | Description |
|
|
102
|
+
|------|-------------|
|
|
103
|
+
| `default` | The composed group. Author it from the parts: a panel group wrapping panels, with a handle between each adjacent pair. |
|
|
104
|
+
|
|
105
|
+
## Behavior
|
|
106
|
+
|
|
107
|
+
Given/When/Then scenarios for the panel group, its panels, and the drag handle.
|
|
108
|
+
|
|
109
|
+
### Dragging a handle resizes its neighbours
|
|
110
|
+
|
|
111
|
+
- **Given** a horizontal panel group with two panels split 50/50 and a handle between them,
|
|
112
|
+
- **When** the user drags the handle to the right,
|
|
113
|
+
- **Then** the left panel grows and the right panel shrinks by the same amount,
|
|
114
|
+
staying within each panel's `minSize` / `maxSize`.
|
|
115
|
+
|
|
116
|
+
### Sizes are clamped to min/max
|
|
117
|
+
|
|
118
|
+
- **Given** a panel with `minSize={20}`,
|
|
119
|
+
- **When** the user drags the handle past the point where that panel would fall below 20%,
|
|
120
|
+
- **Then** the panel stops at 20% and the handle does not move further in that direction.
|
|
121
|
+
|
|
122
|
+
### Keyboard resizing
|
|
123
|
+
|
|
124
|
+
- **Given** keyboard focus on a handle,
|
|
125
|
+
- **When** the user presses the Arrow keys along the resize axis (Left/Right for a
|
|
126
|
+
horizontal group, Up/Down for a vertical group),
|
|
127
|
+
- **Then** the adjacent panels resize by a step, and **Home** / **End** jump to the
|
|
128
|
+
handle's min / max extent.
|
|
129
|
+
|
|
130
|
+
### Orientation flips the axis
|
|
131
|
+
|
|
132
|
+
- **Given** a group with `orientation="vertical"`,
|
|
133
|
+
- **When** it renders,
|
|
134
|
+
- **Then** the panels stack in a column, the handle becomes a horizontal divider
|
|
135
|
+
(`aria-orientation="horizontal"`), and the cursor over it is `ns-resize`.
|
|
136
|
+
|
|
137
|
+
### Disabled handles don't resize
|
|
138
|
+
|
|
139
|
+
- **Given** a handle (or its panels) is `disabled`,
|
|
140
|
+
- **When** the user drags or arrow-keys it,
|
|
141
|
+
- **Then** the panels do not resize through that handle.
|
|
142
|
+
|
|
143
|
+
### Collapsible panels
|
|
144
|
+
|
|
145
|
+
- **Given** a `collapsible` panel with a `minSize`,
|
|
146
|
+
- **When** the user drags below that `minSize`,
|
|
147
|
+
- **Then** the panel collapses to its collapsed size, and dragging back out (or
|
|
148
|
+
calling the panel's `expand()` method) restores it.
|
|
149
|
+
|
|
150
|
+
## Accessibility
|
|
151
|
+
|
|
152
|
+
## Roles
|
|
153
|
+
|
|
154
|
+
- The **handle** is a `separator` (`role="separator"`) — a focusable, operable
|
|
155
|
+
window splitter, not a decorative one. It carries `aria-orientation`
|
|
156
|
+
(`vertical` for a horizontal group's vertical divider, `horizontal` for a
|
|
157
|
+
vertical group's horizontal divider).
|
|
158
|
+
- The **panel group** is a generic `group` container; **panels** are generic
|
|
159
|
+
regions. Give a panel a meaningful label (`aria-label` / `aria-labelledby`) when
|
|
160
|
+
its content isn't self-describing.
|
|
161
|
+
|
|
162
|
+
## Keyboard
|
|
163
|
+
|
|
164
|
+
| Key | Action |
|
|
165
|
+
| ---------------------- | ------------------------------------------------------------- |
|
|
166
|
+
| `Tab` / `Shift+Tab` | Move focus to / from the handle. |
|
|
167
|
+
| `Arrow` along the axis | Resize the adjacent panels by a step (Left/Right or Up/Down). |
|
|
168
|
+
| `Home` / `End` | Resize to the handle's minimum / maximum extent. |
|
|
169
|
+
| `Enter` | Toggle a collapsible panel between collapsed and expanded. |
|
|
170
|
+
|
|
171
|
+
The handle is reachable and fully operable by keyboard — resizing never requires a
|
|
172
|
+
pointer.
|
|
173
|
+
|
|
174
|
+
## Focus
|
|
175
|
+
|
|
176
|
+
- The handle shows a visible focus ring on `:focus-visible` (3px
|
|
177
|
+
`--ui-focus-primary`), distinct from hover, so keyboard users can see which
|
|
178
|
+
handle is active.
|
|
179
|
+
- Focus order follows the DOM: panel content, then the handle, then the next
|
|
180
|
+
panel.
|
|
181
|
+
|
|
182
|
+
## Screen readers
|
|
183
|
+
|
|
184
|
+
- As a `separator` with `aria-orientation`, the handle is announced as a
|
|
185
|
+
resizable splitter. `aria-valuenow` / `aria-valuemin` / `aria-valuemax` are
|
|
186
|
+
managed by the underlying panel library to convey the current split.
|
|
187
|
+
- The handle has no decorative children — its visual affordance is the cursor
|
|
188
|
+
change and the border color shift on hover/active.
|
|
189
|
+
|
|
190
|
+
## Contrast
|
|
191
|
+
|
|
192
|
+
- The divider line uses `--ui-border-on-surface-border` (idle) and
|
|
193
|
+
`--ui-resizable-border-color-hover` / `-active`, which resolve per brand/theme;
|
|
194
|
+
they must keep a visible contrast against the adjacent panel surfaces in both
|
|
195
|
+
light and dark schemes.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# SankeyChart
|
|
2
|
+
|
|
3
|
+
> A typed Sankey flow-diagram composition over the shared `Chart` primitives. Renders a graph of `nodes` + `links` where each link's width is proportional to its flow value, inside a `ChartContainer`, with token-themed node bars and link ribbons plus a tooltip. No axes or grid, and no variant axes; an optional count/% legend (`showLegend`) renders below the chart, and geometry (`nodePadding` / `nodeWidth` / `linkCurvature`) is plain props. Themed through custom node/link renderers (recharts' defaults paint one flat grey and have no token hooks). Built on recharts' `Sankey` primitive (no apps/demo playground existed).
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** data-display · **Since:** v0.60.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { SankeyChart } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<SankeyChart
|
|
17
|
+
config={config}
|
|
18
|
+
data={{ nodes, links }}
|
|
19
|
+
className="h-[360px] w-[620px]"
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
A typed Sankey flow diagram built on the shared `Chart` primitives. Give it a
|
|
24
|
+
graph (`data.nodes` + `data.links`) and a per-node `config`; it renders a themed
|
|
25
|
+
recharts `Sankey` — node bars colored per name, link ribbons whose width is
|
|
26
|
+
proportional to the flow value and tinted by their target node — so you don't
|
|
27
|
+
hand-compose recharts children.
|
|
28
|
+
|
|
29
|
+
Node colors come from the `palette` prop — a dataviz palette resolving to the
|
|
30
|
+
`--ui-dataviz-*` tokens, `categorical` by default — not from `config`. Link
|
|
31
|
+
ribbons tint from their target node unless a link sets its own `color`.
|
|
32
|
+
|
|
33
|
+
> **Design-pending v1.** Built on recharts' `Sankey` primitive (no apps/demo
|
|
34
|
+
> playground existed). The chrome is reconciled with Figma later; Code Connect is
|
|
35
|
+
> deferred.
|
|
36
|
+
|
|
37
|
+
## When to use
|
|
38
|
+
|
|
39
|
+
- Showing how a total **flows/breaks down** across stages where the width of each
|
|
40
|
+
flow matters (tenants → certification status, traffic → outcomes, budget → spend).
|
|
41
|
+
- A part-to-whole across two or more levels in one picture.
|
|
42
|
+
|
|
43
|
+
## When not to use
|
|
44
|
+
|
|
45
|
+
- Precise value comparison — ribbon width is hard to judge; a bar chart reads better.
|
|
46
|
+
- A single-level part-to-whole — a pie/donut or a `CategoryBar` is clearer.
|
|
47
|
+
- Very dense graphs (many nodes/links) — ribbons overlap and labels collide.
|
|
48
|
+
|
|
49
|
+
## Variants
|
|
50
|
+
|
|
51
|
+
None. SankeyChart has no CVA variant axes — everything is plain props: geometry
|
|
52
|
+
(`nodePadding` / `nodeWidth` / `linkCurvature`), `sort` (auto-order vs the given
|
|
53
|
+
node order), `showLabels` / `showLegend`, and a per-link `color` override
|
|
54
|
+
(rendered full-opacity; the default ribbon is the target color at 35%).
|
|
55
|
+
|
|
56
|
+
## Example
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { SankeyChart } from '@acronis-platform/ui-react';
|
|
60
|
+
import type { ChartConfig } from '@acronis-platform/ui-react';
|
|
61
|
+
|
|
62
|
+
const data = {
|
|
63
|
+
nodes: [{ name: 'all' }, { name: 'certified' }, { name: 'expired' }],
|
|
64
|
+
links: [
|
|
65
|
+
{ source: 0, target: 1, value: 209 },
|
|
66
|
+
{ source: 0, target: 2, value: 31 },
|
|
67
|
+
],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const config = {
|
|
71
|
+
all: {
|
|
72
|
+
label: 'All tenants',
|
|
73
|
+
color: 'var(--ui-background-status-strong-info)',
|
|
74
|
+
},
|
|
75
|
+
certified: {
|
|
76
|
+
label: 'Certified',
|
|
77
|
+
color: 'var(--ui-background-status-strong-info)',
|
|
78
|
+
},
|
|
79
|
+
expired: {
|
|
80
|
+
label: 'Expired',
|
|
81
|
+
color: 'var(--ui-background-status-strong-danger)',
|
|
82
|
+
},
|
|
83
|
+
} satisfies ChartConfig;
|
|
84
|
+
|
|
85
|
+
<SankeyChart config={config} data={data} className="h-[360px] w-[620px]" />;
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`showLegend` renders a built-in legend below the chart — a color dot + label per
|
|
89
|
+
node plus each node's value and its share of the largest node (the count + %
|
|
90
|
+
shown in the "Certification compliance" card). Pair it with `showLabels={false}`
|
|
91
|
+
to move naming off the chart. Give a link an explicit `color` to override its
|
|
92
|
+
default target tint (rendered full-opacity to match its node bar).
|
|
93
|
+
|
|
94
|
+
Node `name`s are the color keys, so they must be unique and CSS-safe;
|
|
95
|
+
`config[name].label` carries the human-readable text.
|
|
96
|
+
|
|
97
|
+
## Props
|
|
98
|
+
|
|
99
|
+
| Prop | Type | Default | Required | Description |
|
|
100
|
+
|------|------|---------|----------|-------------|
|
|
101
|
+
| `data` | `{ nodes: ReadonlyArray<{ name: string }>; links: ReadonlyArray<{ source: number; target: number; value: number; color?: string }> }` | — | yes | The graph. `nodes` carry a CSS-safe `name` (the color/config key); `links` reference nodes by their index in `nodes` and carry the flow `value` that sizes the ribbon, plus an optional `color` (rendered at full opacity to match its node; omit for the target node's color at 35%). |
|
|
102
|
+
| `config` | `ChartConfig` | — | yes | Nodes take their colour from the container's `palette`; each entry, keyed by the node's `name`, maps that node to a `label` and an optional `tone`. Resolved into the `--color-<name>` custom properties the node bars fill from (and the link ribbons tint from). |
|
|
103
|
+
| `nodePadding` | `number` | `24` | no | Vertical gap between nodes in the same column. |
|
|
104
|
+
| `nodeWidth` | `number` | `12` | no | Thickness of each node bar. |
|
|
105
|
+
| `linkCurvature` | `number` | `0.5` | no | Curviness of the link ribbons (0 = straight, 1 = fully curved). |
|
|
106
|
+
| `sort` | `boolean` | `false` | no | Sort nodes vertically to minimize link crossings (recharts' relaxation). Defaults to false — nodes render in the given order per column, which keeps curated flows tidy; set true to auto-order. |
|
|
107
|
+
| `showLabels` | `boolean` | `true` | no | Render each node's `config` label beside its bar. |
|
|
108
|
+
| `showLegend` | `boolean` | `false` | no | Render a legend below the chart — a color dot + label per node, with its computed value (incoming flow) and share of the largest node. |
|
|
109
|
+
| `showTooltip` | `boolean` | `true` | no | Render the hover tooltip. |
|
|
110
|
+
| `tooltipContent` | `ReactElement | ((props) => ReactNode)` | — | no | Replace the default tooltip. Pass a configured ChartTooltipContent (from this library) — e.g. with a formatter / labelFormatter — to customize the tooltip content without composing recharts. Ignored when showTooltip is false. |
|
|
111
|
+
|
|
112
|
+
## Behavior
|
|
113
|
+
|
|
114
|
+
`SankeyChart` is a typed [recharts](https://recharts.org) composition over the
|
|
115
|
+
shared `Chart` primitives. It renders a flow diagram from a `nodes` + `links`
|
|
116
|
+
graph inside a `ChartContainer`.
|
|
117
|
+
|
|
118
|
+
```gherkin
|
|
119
|
+
Scenario: Render nodes and links from data and config
|
|
120
|
+
Given a graph with nodes (each a CSS-safe name) and links (source/target indices + value)
|
|
121
|
+
And a config mapping each node name to a label and color
|
|
122
|
+
Then one bar renders per node, filled from its --color-<name> custom property
|
|
123
|
+
And one ribbon renders per link, its width proportional to the link value
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```gherkin
|
|
127
|
+
Scenario: Link ribbon color
|
|
128
|
+
Given a link with no explicit color
|
|
129
|
+
Then its ribbon is stroked in the target node's color at 35% opacity
|
|
130
|
+
Given a link with an explicit color
|
|
131
|
+
Then its ribbon is stroked in that color at full opacity (matching its node bar)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```gherkin
|
|
135
|
+
Scenario: Node labels
|
|
136
|
+
Given showLabels is true
|
|
137
|
+
Then each node shows its config label — to the right for nodes with outgoing
|
|
138
|
+
links, to the left for terminal (sink) nodes
|
|
139
|
+
And when showLabels is false no node labels render (e.g. an external legend names them)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```gherkin
|
|
143
|
+
Scenario: Legend
|
|
144
|
+
Given showLegend is true
|
|
145
|
+
Then a legend renders below the chart with a color dot + label per node
|
|
146
|
+
And each node's value (incoming flow, or outgoing for a source) plus its share
|
|
147
|
+
of the largest node as a percentage
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```gherkin
|
|
151
|
+
Scenario: Node order
|
|
152
|
+
Given sort is false (the default)
|
|
153
|
+
Then nodes render in the order given by data.nodes within each column
|
|
154
|
+
Given sort is true
|
|
155
|
+
Then recharts reorders nodes vertically to minimize link crossings
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```gherkin
|
|
159
|
+
Scenario: Geometry
|
|
160
|
+
Given nodePadding, nodeWidth, and linkCurvature
|
|
161
|
+
Then nodes are spaced/sized accordingly and ribbons curve by that amount
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```gherkin
|
|
165
|
+
Scenario: Tooltip on hover
|
|
166
|
+
Given showTooltip is true
|
|
167
|
+
When the user hovers a node or link
|
|
168
|
+
Then a card shows a color dot matching the ribbon (its link color + opacity),
|
|
169
|
+
the source → target labels, and the value
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```gherkin
|
|
173
|
+
Scenario: Minimal graph
|
|
174
|
+
Given a two-node, single-link graph
|
|
175
|
+
Then the chart renders one ribbon and does not throw
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Accessibility
|
|
179
|
+
|
|
180
|
+
- **recharts gives a Sankey no accessibility layer.** Unlike the cartesian charts,
|
|
181
|
+
recharts' `Sankey` (v3.8) implements no `accessibilityLayer`: it renders no
|
|
182
|
+
`role`, no `tabIndex`, and no generated description, so the plot is **not
|
|
183
|
+
keyboard-focusable** and its hover tooltip is pointer-only. Treat the chart as
|
|
184
|
+
an image and carry the numbers in accessible content next to it.
|
|
185
|
+
- A Sankey is inherently visual (ribbon width is a weak quantitative encoding).
|
|
186
|
+
**Pair it with a text alternative** — a caption, a summary, or an adjacent
|
|
187
|
+
legend/table carrying the same numbers (as the reference "Certification
|
|
188
|
+
compliance" usage does) — and give the chart an accessible name (`aria-label` /
|
|
189
|
+
`aria-labelledby` referencing a visible heading). The wrapper forwards native
|
|
190
|
+
`div` attributes, so `aria-*` pass through.
|
|
191
|
+
- Do **not** rely on color alone to distinguish nodes/flows. Keep `showLabels` on
|
|
192
|
+
(or supply an external legend) so each node is named, and keep `showTooltip` on
|
|
193
|
+
so values are recoverable on hover.
|
|
194
|
+
- Node labels use the `--ui-text-on-surface-primary` token (fill-foreground), so
|
|
195
|
+
they read on the themed surface in both modes. Node/link colors come from
|
|
196
|
+
`config` and are the caller's responsibility — keep adjacent nodes
|
|
197
|
+
distinguishable and flows legible at the low ribbon opacity (matched data-viz
|
|
198
|
+
colors are a design-pending item for the `--ui-chart-*` palette).
|
|
199
|
+
- Watch recharts issue [#4809](https://github.com/recharts/recharts/issues/4809)
|
|
200
|
+
on the a11y layer — if `Sankey` ever gains one, this component should adopt it
|
|
201
|
+
instead of relying purely on the caller's text alternative.
|
|
202
|
+
|
|
203
|
+
## Contrast
|
|
204
|
+
|
|
205
|
+
Tooltip chrome and node labels meet contrast in both themes via the semantic
|
|
206
|
+
tokens. Node bar fills and link ribbon tints come from `config` and are the
|
|
207
|
+
caller's responsibility — pick node colors that stay distinguishable from each
|
|
208
|
+
other and legible as ~35%-opacity ribbons.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# ScatterChart
|
|
2
|
+
|
|
3
|
+
> A typed scatter-chart composition over the shared `Chart` primitives. Plots each `series[]` entry's points on numeric `xKey` / `yKey` axes inside a `ChartContainer`, with tooltip and legend chrome. Optionally maps a `zKey` to point size (a bubble chart). Scatter has no variant axes — its expressiveness comes from the data mapping, not a visual mode. Ported from the apps/demo `ScatterChartPlayground`.
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** data-display · **Since:** v0.58.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ScatterChart } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<ScatterChart
|
|
17
|
+
config={config}
|
|
18
|
+
series={series}
|
|
19
|
+
xKey="hours"
|
|
20
|
+
yKey="score"
|
|
21
|
+
zKey="weight"
|
|
22
|
+
className="h-[360px] w-[520px]"
|
|
23
|
+
/>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
A typed scatter-chart built on the shared `Chart` primitives. Give it a `series`
|
|
27
|
+
list (each `{ key, data }`), a per-series `config`, and the numeric axis fields
|
|
28
|
+
(`xKey` / `yKey`); it renders a themed recharts `ScatterChart` — tooltip, legend,
|
|
29
|
+
axes, and grid included — so you don't hand-compose recharts children. Add a
|
|
30
|
+
`zKey` to size points by a third field (a bubble chart).
|
|
31
|
+
|
|
32
|
+
Series colors come from the `palette` prop — a dataviz palette resolving to the
|
|
33
|
+
`--ui-dataviz-*` tokens, `categorical` by default — not from `config`.
|
|
34
|
+
|
|
35
|
+
> **Design-pending v1.** Ported from the apps/demo `ScatterChartPlayground`. The
|
|
36
|
+
> chrome is reconciled with Figma later; Code Connect is deferred.
|
|
37
|
+
|
|
38
|
+
## When to use
|
|
39
|
+
|
|
40
|
+
- Showing the relationship/correlation between two numeric variables.
|
|
41
|
+
- Revealing clusters or outliers across groups (one `series` entry per group).
|
|
42
|
+
- Adding a third dimension via point size (`zKey` → bubble chart).
|
|
43
|
+
|
|
44
|
+
## When not to use
|
|
45
|
+
|
|
46
|
+
- A trend over an ordered/continuous dimension — use a line or area chart.
|
|
47
|
+
- Comparing a quantity across discrete categories — use a bar chart.
|
|
48
|
+
- Part-to-whole — use a pie/donut chart.
|
|
49
|
+
|
|
50
|
+
## Variants
|
|
51
|
+
|
|
52
|
+
None. ScatterChart has no CVA variant axes — its shape is fixed and its
|
|
53
|
+
expressiveness comes from the data mapping (`xKey` / `yKey` / `zKey` and the
|
|
54
|
+
number of `series`). Marker `shape` and bubble sizing are plain props.
|
|
55
|
+
|
|
56
|
+
## Example
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { ScatterChart } from '@acronis-platform/ui-react';
|
|
60
|
+
import type { ChartConfig } from '@acronis-platform/ui-react';
|
|
61
|
+
|
|
62
|
+
const series = [
|
|
63
|
+
{
|
|
64
|
+
key: 'classA',
|
|
65
|
+
data: [
|
|
66
|
+
{ hours: 2, score: 55 },
|
|
67
|
+
{ hours: 6, score: 78 },
|
|
68
|
+
{ hours: 8, score: 92 },
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
key: 'classB',
|
|
73
|
+
data: [
|
|
74
|
+
{ hours: 1, score: 70 },
|
|
75
|
+
{ hours: 5, score: 82 },
|
|
76
|
+
{ hours: 9, score: 95 },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
const config = {
|
|
82
|
+
classA: { label: 'Class A', color: 'var(--ui-background-brand-secondary)' },
|
|
83
|
+
classB: {
|
|
84
|
+
label: 'Class B',
|
|
85
|
+
color: 'var(--ui-background-status-strong-danger)',
|
|
86
|
+
},
|
|
87
|
+
} satisfies ChartConfig;
|
|
88
|
+
|
|
89
|
+
<ScatterChart
|
|
90
|
+
config={config}
|
|
91
|
+
series={series}
|
|
92
|
+
xKey="hours"
|
|
93
|
+
yKey="score"
|
|
94
|
+
className="h-[360px] w-[520px]"
|
|
95
|
+
/>;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Series colors reference existing semantic `--ui-*` tokens. `--ui-background-status-strong-*`
|
|
99
|
+
is chromatic in every brand; `--ui-background-brand-secondary` is brand-dependent
|
|
100
|
+
(blue in `default`, neutral in some white-label brands), so it is not color-stable
|
|
101
|
+
across brands until the real data-viz palette lands.
|
|
102
|
+
|
|
103
|
+
## Props
|
|
104
|
+
|
|
105
|
+
| Prop | Type | Default | Required | Description |
|
|
106
|
+
|------|------|---------|----------|-------------|
|
|
107
|
+
| `series` | `ScatterSeries[]` | — | yes | One `<Scatter>` per entry, each `{ key, data }` with its own point array. `key` matches a `config` entry and drives its `--color-<key>` fill. A single entry gives an ungrouped scatter. |
|
|
108
|
+
| `config` | `ChartConfig` | — | yes | Series take their colour from the container's `palette`; each entry, keyed by a `series[].key`, maps that series to a `label` and an optional `tone`. Resolved into the `--color-<key>` custom properties the points fill from. |
|
|
109
|
+
| `xKey` | `string` | — | yes | Numeric field for the horizontal axis. |
|
|
110
|
+
| `yKey` | `string` | — | yes | Numeric field for the vertical axis. |
|
|
111
|
+
| `xAxisLabel` | `string` | — | no | Title rendered beneath the horizontal (X) axis. |
|
|
112
|
+
| `yAxisLabel` | `string` | — | no | Title rendered beside the vertical (Y) axis (rotated). |
|
|
113
|
+
| `xUnit` | `string` | — | no | Unit suffix appended to X-axis tick values (recharts `unit`). |
|
|
114
|
+
| `yUnit` | `string` | — | no | Unit suffix appended to Y-axis tick values (recharts `unit`). |
|
|
115
|
+
| `zKey` | `string` | — | no | Optional numeric field mapped to point size (a bubble chart), via recharts `ZAxis`. |
|
|
116
|
+
| `zRange` | `[number, number]` | `[60, 400]` | no | Point-size range `[min, max]` the `zKey` maps into. Ignored when `zKey` is unset (points use recharts' default size). |
|
|
117
|
+
| `shape` | `'circle' | 'cross' | 'diamond' | 'square' | 'star' | 'triangle' | 'wye'` | `'circle'` | no | Marker shape for every point. |
|
|
118
|
+
| `showGrid` | `boolean` | `true` | no | Render the CartesianGrid. |
|
|
119
|
+
| `showTooltip` | `boolean` | `true` | no | Render the hover tooltip. |
|
|
120
|
+
| `showLegend` | `boolean` | `true` | no | Render the legend. |
|
|
121
|
+
| `tooltipContent` | `ReactElement | ((props) => ReactNode)` | — | no | Replace the default tooltip. Pass a configured ChartTooltipContent (from this library) — e.g. with a formatter / labelFormatter — to customize the tooltip content without composing recharts. Ignored when showTooltip is false. |
|
|
122
|
+
| `showXAxis` | `boolean` | `true` | no | Render the X axis (its ticks and title). Set false to hide it. |
|
|
123
|
+
| `showYAxis` | `boolean` | `true` | no | Render the Y axis (its ticks and title). Set false to hide it. |
|
|
124
|
+
| `xTickFormatter` | `(value: number | string, index?: number) => string` | — | no | Format each X-axis tick value. Unlike the `unit` suffix (append-only), a formatter transforms the value — abbreviate, prefix a symbol, or map to a label. Use formatCompactNumber / formatPercent / createTickFormatter from the shared Chart primitives, or any function. |
|
|
125
|
+
| `yTickFormatter` | `(value: number | string, index?: number) => string` | — | no | Format each Y-axis tick value (see xTickFormatter). |
|
|
126
|
+
| `xAxisAngle` | `number` | — | no | Rotate the X-axis tick labels by this many degrees (a negative angle tilts them up toward the right); the tick anchor + axis height adjust. |
|
|
127
|
+
| `xAxisInterval` | `number | 'preserveStart' | 'preserveEnd' | 'preserveStartEnd' | 'equidistantPreserveStart'` | — | no | X-axis tick density — a recharts placement strategy, or a fixed number of ticks to skip between two rendered ones (recharts interval: 0 shows every tick, 1 every other one, 2 every third). |
|
|
128
|
+
| `yAxisTickCount` | `number` | — | no | Desired number of ticks on the value axis (recharts tickCount; a hint, not exact). Applies to whichever axis holds the values — Y for most charts, X for BarChart with orientation="horizontal". |
|
|
129
|
+
| `yAxisDomain` | `'auto' | 'dataMin-dataMax' | 'zero'` | — | no | Value-axis domain preset — auto (fit the data at both ends; the axis need not include 0), zero (anchor the axis at 0, which is also recharts' behaviour when the prop is omitted), or dataMin-dataMax (tight to the data, no padding). Applies to whichever axis holds the values — Y for most charts, X for BarChart with orientation="horizontal". |
|
|
130
|
+
| `gridDashed` | `boolean` | — | no | Draw grid lines dashed instead of solid. |
|
|
131
|
+
| `gridHorizontal` | `boolean` | — | no | Show horizontal grid lines (defaults to the chart's own default when unset). |
|
|
132
|
+
| `gridVertical` | `boolean` | — | no | Show vertical grid lines (defaults to the chart's own default when unset). |
|
|
133
|
+
| `animate` | `boolean` | `false` | no | Enable entrance animation. Off by default so output/baselines are unchanged. |
|
|
134
|
+
| `animationDuration` | `number` | — | no | Animation duration in ms. |
|
|
135
|
+
| `animationBegin` | `number` | — | no | Delay before the animation starts, in ms. |
|
|
136
|
+
| `animationEasing` | `'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear'` | — | no | Easing curve. |
|
|
137
|
+
|
|
138
|
+
## Behavior
|
|
139
|
+
|
|
140
|
+
`ScatterChart` is a typed [recharts](https://recharts.org) composition over the
|
|
141
|
+
shared `Chart` primitives. It plots each `series[]` entry's points on numeric
|
|
142
|
+
`xKey` / `yKey` axes inside a `ChartContainer`, optionally sizing points by a
|
|
143
|
+
`zKey` (bubble chart).
|
|
144
|
+
|
|
145
|
+
```gherkin
|
|
146
|
+
Scenario: Render points from series and config
|
|
147
|
+
Given a series list, each { key, data }, and a config mapping each key to a label and color
|
|
148
|
+
Then one <Scatter> renders per series
|
|
149
|
+
And each series' points fill from its injected --color-<key> custom property
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```gherkin
|
|
153
|
+
Scenario: Single (ungrouped) scatter
|
|
154
|
+
Given series has one entry
|
|
155
|
+
Then a single set of points renders against the x/y axes
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```gherkin
|
|
159
|
+
Scenario: Grouped scatter
|
|
160
|
+
Given series has two or more entries
|
|
161
|
+
Then each renders as its own colored set of points
|
|
162
|
+
And the legend distinguishes them by color + label
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```gherkin
|
|
166
|
+
Scenario: Bubble sizing
|
|
167
|
+
Given a zKey is supplied
|
|
168
|
+
Then a ZAxis maps that field to point size across zRange
|
|
169
|
+
But when zKey is omitted every point uses a fixed size
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```gherkin
|
|
173
|
+
Scenario: Marker shape
|
|
174
|
+
Given shape is one of circle / cross / diamond / square / star / triangle / wye
|
|
175
|
+
Then every point renders with that marker glyph
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```gherkin
|
|
179
|
+
Scenario: Tooltip on hover
|
|
180
|
+
Given showTooltip is true
|
|
181
|
+
When the user hovers a point
|
|
182
|
+
Then a card shows that point's axis values
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```gherkin
|
|
186
|
+
Scenario: Legend
|
|
187
|
+
Given showLegend is true
|
|
188
|
+
Then a swatch + label renders for each series
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```gherkin
|
|
192
|
+
Scenario: Empty series
|
|
193
|
+
Given series is an empty array
|
|
194
|
+
Then the chart renders its axes and grid with no points and does not throw
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```gherkin
|
|
198
|
+
Scenario: Entrance animation is opt-in
|
|
199
|
+
Given animate is unset
|
|
200
|
+
Then the series render at their final geometry with no entrance animation
|
|
201
|
+
And the committed visual baselines are unaffected
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```gherkin
|
|
205
|
+
Scenario: Reduced motion
|
|
206
|
+
Given animate is true
|
|
207
|
+
And a user with prefers-reduced-motion
|
|
208
|
+
Then the entrance animation does not play and the series render at their final geometry
|
|
209
|
+
And the same applies when rendering on the server
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Accessibility
|
|
213
|
+
|
|
214
|
+
- recharts' `accessibilityLayer` is **on by default** (recharts v3), giving the
|
|
215
|
+
chart keyboard focus and an accessible description of the plotted points.
|
|
216
|
+
- A scatter chart is inherently visual. **Pair it with a text alternative** — a
|
|
217
|
+
caption, a summary sentence, or an adjacent data table carrying the same
|
|
218
|
+
numbers — and give the chart an accessible name (`aria-label` /
|
|
219
|
+
`aria-labelledby` referencing a visible heading) when it is meaningful on its
|
|
220
|
+
own. The wrapper forwards native `div` attributes, so `aria-*` pass through.
|
|
221
|
+
- Do **not** rely on color alone to distinguish series. Keep `showLegend` (or the
|
|
222
|
+
tooltip) visible so each color is paired with a text label; the `shape` marker
|
|
223
|
+
can add a second, non-color channel when several series overlap.
|
|
224
|
+
- In a bubble chart (`zKey`), size encodes a value — call it out in the caption,
|
|
225
|
+
since point area is hard to read precisely and impossible for a screen reader
|
|
226
|
+
to infer.
|
|
227
|
+
- The chrome (tooltip, legend, axis ticks, grid) resolves to semantic `--ui-*`
|
|
228
|
+
tokens that meet contrast in light and dark. **Series colors are
|
|
229
|
+
caller-supplied** via `config` — pick values that meet 3:1 against the surface
|
|
230
|
+
and are distinguishable for color-vision deficiencies. The borrowed semantic
|
|
231
|
+
tokens are a design-pending stopgap until the `--ui-chart-*` palette lands.
|
|
232
|
+
- Watch recharts issue [#4809](https://github.com/recharts/recharts/issues/4809)
|
|
233
|
+
on the a11y layer for heavily-customized charts.
|
|
234
|
+
|
|
235
|
+
## Contrast
|
|
236
|
+
|
|
237
|
+
Chart chrome meets contrast in both themes via the semantic tokens. Point fills
|
|
238
|
+
come from `config` and are the caller's responsibility — keep overlapping points
|
|
239
|
+
distinguishable from each other, not just against the surface.
|