@acronis-platform/ui-react 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/accordion-container/accordion-container.js +14 -14
- package/dist/components/ui/accordion-container/accordion-container.js.map +1 -1
- package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
- package/dist/components/ui/area-chart/area-chart.js +141 -139
- package/dist/components/ui/area-chart/area-chart.js.map +1 -1
- package/dist/components/ui/bar-chart/bar-chart.js +295 -293
- package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
- package/dist/components/ui/category-bar/category-bar.js +109 -93
- package/dist/components/ui/category-bar/category-bar.js.map +1 -1
- package/dist/components/ui/chart/chart-palette.js +113 -0
- package/dist/components/ui/chart/chart-palette.js.map +1 -0
- package/dist/components/ui/chart/chart.js +176 -129
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
- package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
- package/dist/components/ui/chart-state/chart-state.js +48 -34
- package/dist/components/ui/chart-state/chart-state.js.map +1 -1
- package/dist/components/ui/chart-widget/chart-widget.js +87 -0
- package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
- package/dist/components/ui/composed-chart/composed-chart.js +117 -115
- package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
- package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
- package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
- package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
- package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
- package/dist/components/ui/histogram/histogram.js +94 -92
- package/dist/components/ui/histogram/histogram.js.map +1 -1
- package/dist/components/ui/input/input.js.map +1 -1
- package/dist/components/ui/label/label.js +2 -9
- package/dist/components/ui/label/label.js.map +1 -1
- package/dist/components/ui/line-chart/line-chart.js +143 -141
- package/dist/components/ui/line-chart/line-chart.js.map +1 -1
- package/dist/components/ui/metric/metric.js +74 -185
- package/dist/components/ui/metric/metric.js.map +1 -1
- package/dist/components/ui/page-content/page-content.js.map +1 -1
- package/dist/components/ui/pie-chart/pie-chart.js +201 -195
- package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
- package/dist/components/ui/radar-chart/radar-chart.js +133 -131
- package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
- package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
- package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
- package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
- package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
- package/dist/components/ui/section/section.js +157 -31
- package/dist/components/ui/section/section.js.map +1 -1
- package/dist/components/ui/stepper/stepper.js +24 -24
- package/dist/components/ui/stepper/stepper.js.map +1 -1
- package/dist/components/ui/stepper-item/stepper-item.js +43 -24
- package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
- package/dist/components/ui/treemap/treemap.js +133 -124
- package/dist/components/ui/treemap/treemap.js.map +1 -1
- package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
- package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
- package/dist/components/ui/wizard/wizard.js +59 -0
- package/dist/components/ui/wizard/wizard.js.map +1 -0
- package/dist/hooks/use-wizard.js +75 -0
- package/dist/hooks/use-wizard.js.map +1 -0
- package/dist/index.js +502 -497
- package/dist/index.js.map +1 -1
- package/dist/llms/accordion-container.md +181 -0
- package/dist/llms/accordion.md +124 -0
- package/dist/llms/alert.md +225 -0
- package/dist/llms/app-shell-chat.md +415 -0
- package/dist/llms/area-chart.md +355 -0
- package/dist/llms/avatar.md +208 -0
- package/dist/llms/bar-chart.md +406 -0
- package/dist/llms/breadcrumb.md +326 -0
- package/dist/llms/button-group.md +298 -0
- package/dist/llms/button-icon-input.md +142 -0
- package/dist/llms/button-icon-menu.md +209 -0
- package/dist/llms/button-icon.md +128 -0
- package/dist/llms/button-menu.md +172 -0
- package/dist/llms/button.md +185 -0
- package/dist/llms/calendar-panel.md +733 -0
- package/dist/llms/calendar.md +188 -0
- package/dist/llms/card-filter.md +214 -0
- package/dist/llms/card-section.md +293 -0
- package/dist/llms/card.md +447 -0
- package/dist/llms/carousel-dialog.md +156 -0
- package/dist/llms/category-bar.md +193 -0
- package/dist/llms/chart-state.md +190 -0
- package/dist/llms/chart-widget.md +209 -0
- package/dist/llms/chart.md +182 -0
- package/dist/llms/checkbox.md +257 -0
- package/dist/llms/chip.md +195 -0
- package/dist/llms/combobox.md +164 -0
- package/dist/llms/composed-chart.md +508 -0
- package/dist/llms/confidence-cone.md +277 -0
- package/dist/llms/data-table.md +474 -0
- package/dist/llms/date-range-picker.md +272 -0
- package/dist/llms/description-list.md +131 -0
- package/dist/llms/dialog-footer-carousel.md +147 -0
- package/dist/llms/dialog-footer-default.md +142 -0
- package/dist/llms/dialog-root.md +246 -0
- package/dist/llms/dialog-welcome.md +223 -0
- package/dist/llms/dialog.md +403 -0
- package/dist/llms/dropdown-menu.md +193 -0
- package/dist/llms/empty-overlay.md +146 -0
- package/dist/llms/empty.md +156 -0
- package/dist/llms/field.md +185 -0
- package/dist/llms/filter-cards.md +157 -0
- package/dist/llms/filter-chips.md +323 -0
- package/dist/llms/filter-search.md +512 -0
- package/dist/llms/form.md +154 -0
- package/dist/llms/funnel-chart.md +333 -0
- package/dist/llms/grid.md +80 -0
- package/dist/llms/histogram.md +190 -0
- package/dist/llms/input-date-picker.md +203 -0
- package/dist/llms/input-otp.md +173 -0
- package/dist/llms/input-password.md +197 -0
- package/dist/llms/input-search.md +170 -0
- package/dist/llms/input-select.md +278 -0
- package/dist/llms/input-text-area.md +271 -0
- package/dist/llms/input-text.md +192 -0
- package/dist/llms/line-chart.md +369 -0
- package/dist/llms/link.md +209 -0
- package/dist/llms/loading.md +130 -0
- package/dist/llms/meter.md +177 -0
- package/dist/llms/metric.md +204 -0
- package/dist/llms/number-field.md +122 -0
- package/dist/llms/page-content.md +69 -0
- package/dist/llms/page-header.md +182 -0
- package/dist/llms/pagination.md +133 -0
- package/dist/llms/pie-chart.md +307 -0
- package/dist/llms/popover.md +252 -0
- package/dist/llms/progress-circle.md +126 -0
- package/dist/llms/progress.md +111 -0
- package/dist/llms/radar-chart.md +316 -0
- package/dist/llms/radial-bar-chart.md +319 -0
- package/dist/llms/radio.md +255 -0
- package/dist/llms/resizable.md +195 -0
- package/dist/llms/sankey-chart.md +208 -0
- package/dist/llms/scatter-chart.md +239 -0
- package/dist/llms/scroll-area.md +183 -0
- package/dist/llms/section.md +401 -0
- package/dist/llms/select.md +210 -0
- package/dist/llms/separator.md +87 -0
- package/dist/llms/sheet.md +202 -0
- package/dist/llms/sidebar-primary.md +360 -0
- package/dist/llms/sidebar-secondary.md +417 -0
- package/dist/llms/skeleton.md +81 -0
- package/dist/llms/slider.md +97 -0
- package/dist/llms/spinner.md +100 -0
- package/dist/llms/stack.md +80 -0
- package/dist/llms/stepper-item.md +309 -0
- package/dist/llms/stepper.md +251 -0
- package/dist/llms/switch.md +140 -0
- package/dist/llms/table.md +436 -0
- package/dist/llms/tabs.md +197 -0
- package/dist/llms/tag.md +139 -0
- package/dist/llms/timeline.md +361 -0
- package/dist/llms/timer.md +259 -0
- package/dist/llms/toast.md +241 -0
- package/dist/llms/toggle-group.md +121 -0
- package/dist/llms/toolbar.md +453 -0
- package/dist/llms/tooltip.md +164 -0
- package/dist/llms/treemap.md +254 -0
- package/dist/llms/trend-indicator.md +132 -0
- package/dist/llms/widget-placeholder.md +169 -0
- package/dist/llms/wizard.md +412 -0
- package/dist/llms.txt +142 -0
- package/dist/react.js +502 -497
- package/dist/react.js.map +1 -1
- package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
- package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
- package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
- package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
- package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
- package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
- package/dist/src/components/ui/chart/chart.d.ts +66 -15
- package/dist/src/components/ui/chart/index.d.ts +4 -2
- package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
- package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
- package/dist/src/components/ui/chart-state/index.d.ts +1 -0
- package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
- package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
- package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
- package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
- package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +1 -1
- package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
- package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
- package/dist/src/components/ui/label/index.d.ts +1 -1
- package/dist/src/components/ui/label/label.d.ts +1 -5
- package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
- package/dist/src/components/ui/metric/metric.d.ts +13 -14
- package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
- package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
- package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
- package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
- package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
- package/dist/src/components/ui/section/index.d.ts +1 -1
- package/dist/src/components/ui/section/section.d.ts +75 -6
- package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
- package/dist/src/components/ui/tag/tag.d.ts +1 -1
- package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
- package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
- package/dist/src/components/ui/wizard/index.d.ts +1 -0
- package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/use-wizard.d.ts +80 -0
- package/dist/src/index.d.ts +2 -3
- package/dist/ui-react.css +1 -1
- package/package.json +9 -3
- package/dist/components/ui/app-shell/app-shell.js +0 -75
- package/dist/components/ui/app-shell/app-shell.js.map +0 -1
- package/dist/components/ui/auth-layout/auth-layout.js +0 -56
- package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
- package/dist/components/ui/collapsible/collapsible.js +0 -22
- package/dist/components/ui/collapsible/collapsible.js.map +0 -1
- package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
- package/dist/src/components/ui/app-shell/index.d.ts +0 -1
- package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
- package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
- package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
- package/dist/src/components/ui/collapsible/index.d.ts +0 -1
- package/dist/src/components/ui/label/label.docs.d.ts +0 -10
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# ScrollArea
|
|
2
|
+
|
|
3
|
+
> A scrollable region with a custom overlay scrollbar built on the Base UI Scroll Area primitive. The bar floats over the content and reserves no layout space, so full-bleed content is never cropped by a scrollbar gutter, on every OS and browser. The bar is revealed on hover/scroll and hidden at rest. Ported from the legacy shadcn-uikit `ScrollArea`.
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** layout · **Since:** v0.53.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ScrollArea, ScrollBar } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<ScrollArea className="h-72">
|
|
17
|
+
{longContent}
|
|
18
|
+
</ScrollArea>
|
|
19
|
+
<ScrollArea orientation="both" className="h-72 w-96">
|
|
20
|
+
{wideTallContent}
|
|
21
|
+
</ScrollArea>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
A scrollable region with a custom **overlay** scrollbar built on the Base UI
|
|
25
|
+
Scroll Area primitive. The bar floats over the content and reserves **no**
|
|
26
|
+
layout space, so full-bleed content is never cropped by a scrollbar gutter — on
|
|
27
|
+
every OS and browser, not just where the platform happens to provide overlay
|
|
28
|
+
scrollbars. It is hidden at rest and revealed on hover/scroll.
|
|
29
|
+
|
|
30
|
+
> Design-pending v1: ported from the legacy shadcn-uikit `ScrollArea`. No Figma
|
|
31
|
+
> node yet; reconcile with `/figma-component ScrollArea <url> --update` once a
|
|
32
|
+
> design lands.
|
|
33
|
+
|
|
34
|
+
## When to use
|
|
35
|
+
|
|
36
|
+
- A fixed-height (or fixed-width) region whose content can overflow — sidebars,
|
|
37
|
+
menus, popovers, lists, code blocks, image strips.
|
|
38
|
+
- Anywhere a native `overflow: auto` scrollbar's **reserved gutter** would crop
|
|
39
|
+
edge-to-edge content (e.g. a sidebar's full-width selected row) or shift the
|
|
40
|
+
layout when the scrollbar appears.
|
|
41
|
+
|
|
42
|
+
## When not to use
|
|
43
|
+
|
|
44
|
+
- Page-level / document scrolling — let the browser own that.
|
|
45
|
+
- Very large/virtualized data sets — pair a virtualizer with the viewport, or
|
|
46
|
+
use a component designed for virtualization.
|
|
47
|
+
|
|
48
|
+
## Examples
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { ScrollArea } from '@acronis-platform/ui-react';
|
|
52
|
+
|
|
53
|
+
<ScrollArea className="h-72 w-64 rounded-md border border-border">
|
|
54
|
+
{longList}
|
|
55
|
+
</ScrollArea>;
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
// Both axes (renders the corner too)
|
|
60
|
+
<ScrollArea orientation="both" className="h-72 w-96">
|
|
61
|
+
{wideTallContent}
|
|
62
|
+
</ScrollArea>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
// Compose the parts directly for custom scrollbar placement
|
|
67
|
+
import { ScrollArea, ScrollBar } from '@acronis-platform/ui-react';
|
|
68
|
+
|
|
69
|
+
<ScrollArea orientation="horizontal">
|
|
70
|
+
{row}
|
|
71
|
+
<ScrollBar orientation="horizontal" />
|
|
72
|
+
</ScrollArea>;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Parts
|
|
76
|
+
|
|
77
|
+
| Part | Element | Notes |
|
|
78
|
+
| ------------ | ------- | ------------------------------------------------------------- |
|
|
79
|
+
| `ScrollArea` | `div` | Root + viewport + content + built-in scrollbar(s) (+ corner). |
|
|
80
|
+
| `ScrollBar` | `div` | Standalone overlay scrollbar (track + thumb); `orientation`. |
|
|
81
|
+
|
|
82
|
+
## Props
|
|
83
|
+
|
|
84
|
+
- `orientation` — `'vertical'` (default) · `'horizontal'` · `'both'`. Selects
|
|
85
|
+
the built-in scrollbar(s); `'both'` also renders the corner.
|
|
86
|
+
- All other props pass through to the Base UI `ScrollArea.Root`.
|
|
87
|
+
|
|
88
|
+
## Props
|
|
89
|
+
|
|
90
|
+
| Prop | Type | Default | Required | Description |
|
|
91
|
+
|------|------|---------|----------|-------------|
|
|
92
|
+
| `orientation` | `'vertical' | 'horizontal' | 'both'` | `'vertical'` | no | Which scrollbar(s) the all-in-one `ScrollArea` renders. `both` also renders the corner. For finer control, compose the exported `ScrollBar` part directly. |
|
|
93
|
+
|
|
94
|
+
## Content slots
|
|
95
|
+
|
|
96
|
+
| Slot | Description |
|
|
97
|
+
|------|-------------|
|
|
98
|
+
| `children` | The content to be scrolled, wrapped in the viewport/content parts. |
|
|
99
|
+
|
|
100
|
+
## Behavior
|
|
101
|
+
|
|
102
|
+
Given/When/Then scenarios for the scroll area.
|
|
103
|
+
|
|
104
|
+
### Overlay scrollbar — no reserved gutter
|
|
105
|
+
|
|
106
|
+
- **Given** content taller than the scroll area
|
|
107
|
+
**When** it renders
|
|
108
|
+
**Then** the content fills the full width of the viewport (the scrollbar
|
|
109
|
+
floats over it and reserves **no** layout space), so edge-to-edge content is
|
|
110
|
+
not cropped by a scrollbar gutter.
|
|
111
|
+
|
|
112
|
+
### Reveal on hover / scroll
|
|
113
|
+
|
|
114
|
+
- **Given** a scrollable area at rest
|
|
115
|
+
**Then** the scrollbar is hidden (opacity 0).
|
|
116
|
+
- **When** the pointer hovers the area, or the viewport is scrolled
|
|
117
|
+
**Then** the scrollbar fades in (driven by the primitive's `data-hovering` /
|
|
118
|
+
`data-scrolling` state), and fades back out when the interaction ends.
|
|
119
|
+
|
|
120
|
+
### Orientation
|
|
121
|
+
|
|
122
|
+
- **Given** `orientation="vertical"` (default)
|
|
123
|
+
**Then** only a vertical scrollbar is rendered.
|
|
124
|
+
- **Given** `orientation="horizontal"`
|
|
125
|
+
**Then** only a horizontal scrollbar is rendered.
|
|
126
|
+
- **Given** `orientation="both"`
|
|
127
|
+
**Then** both scrollbars are rendered plus the corner that fills the gap where
|
|
128
|
+
they meet.
|
|
129
|
+
|
|
130
|
+
### Dragging the thumb
|
|
131
|
+
|
|
132
|
+
- **When** the user presses and drags the thumb
|
|
133
|
+
**Then** the viewport scrolls proportionally; the thumb darkens
|
|
134
|
+
(`--ui-border-on-surface-border-active`) on hover.
|
|
135
|
+
|
|
136
|
+
### Keyboard
|
|
137
|
+
|
|
138
|
+
- **Given** the viewport is focused
|
|
139
|
+
**When** the user presses arrow keys / Page Up / Page Down / Home / End
|
|
140
|
+
**Then** the viewport scrolls accordingly (native scrolling on the focusable
|
|
141
|
+
viewport).
|
|
142
|
+
|
|
143
|
+
## Accessibility
|
|
144
|
+
|
|
145
|
+
## Roles & semantics
|
|
146
|
+
|
|
147
|
+
- The parts are plain `<div>`s; the component adds no landmark role. The
|
|
148
|
+
scrollable **viewport** is focusable so the region is reachable and operable
|
|
149
|
+
by keyboard.
|
|
150
|
+
- Content semantics are entirely the caller's — `ScrollArea` is a transparent
|
|
151
|
+
scroll container around arbitrary children.
|
|
152
|
+
|
|
153
|
+
## Keyboard
|
|
154
|
+
|
|
155
|
+
| Key | Action |
|
|
156
|
+
| ---------------------------- | -------------------------- |
|
|
157
|
+
| `Tab` | Move focus to the viewport |
|
|
158
|
+
| `Arrow Up` / `Arrow Down` | Scroll vertically |
|
|
159
|
+
| `Arrow Left` / `Arrow Right` | Scroll horizontally |
|
|
160
|
+
| `Page Up` / `Page Down` | Scroll by a page |
|
|
161
|
+
| `Home` / `End` | Scroll to start / end |
|
|
162
|
+
|
|
163
|
+
## Focus
|
|
164
|
+
|
|
165
|
+
- The viewport shows a visible focus ring (`--ui-focus-brand`) on
|
|
166
|
+
`:focus-visible`, so keyboard users can see when the scroll region holds focus.
|
|
167
|
+
|
|
168
|
+
## Screen readers
|
|
169
|
+
|
|
170
|
+
- No content is hidden from assistive tech: the scrollbar and corner are
|
|
171
|
+
decorative overlays; the scrolled children remain in the normal reading order.
|
|
172
|
+
|
|
173
|
+
## Pointer / motion
|
|
174
|
+
|
|
175
|
+
- The scrollbar reveal is an opacity transition only (no layout shift, no
|
|
176
|
+
parallax). The thumb remains operable by mouse drag and by the native
|
|
177
|
+
scroll gestures (wheel, trackpad, touch).
|
|
178
|
+
|
|
179
|
+
## Contrast
|
|
180
|
+
|
|
181
|
+
- The thumb uses the shared border token at rest and a darker active token on
|
|
182
|
+
hover, both of which meet non-text contrast against the page surfaces in the
|
|
183
|
+
shipped themes.
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
# Section
|
|
2
|
+
|
|
3
|
+
> A titled band that groups cards — or a table — on a page. Four content layouts pick the body shape: one full-width column, a 70/30 split, a three-column card grid, or a flush table that bleeds to the page edges. The header carries a title, optional description, an optional toggle switch, inline extras, and end-aligned actions; an optional bottom divider separates one band from the next. Collapsing is a composition with `AccordionContainer`, the same as `Card`.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** layout · **Since:** v3.0.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Section, SectionHeader, SectionContent } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Section variant="grid3" hasBottomBorder>
|
|
17
|
+
<SectionHeader
|
|
18
|
+
title="Protection"
|
|
19
|
+
description="3 plans applied to 24 workloads."
|
|
20
|
+
hasDescription
|
|
21
|
+
/>
|
|
22
|
+
<SectionContent>
|
|
23
|
+
<Card>…</Card>
|
|
24
|
+
<Card>…</Card>
|
|
25
|
+
<Card>…</Card>
|
|
26
|
+
</SectionContent>
|
|
27
|
+
</Section>
|
|
28
|
+
|
|
29
|
+
// A 70/30 split.
|
|
30
|
+
<Section variant="column2-70-30">
|
|
31
|
+
<SectionHeader title="Storage" />
|
|
32
|
+
<SectionContent secondaryContent={<Card>…</Card>}>
|
|
33
|
+
<Card>…</Card>
|
|
34
|
+
</SectionContent>
|
|
35
|
+
</Section>
|
|
36
|
+
|
|
37
|
+
// Collapsible — a composition, not a prop.
|
|
38
|
+
<Section>
|
|
39
|
+
<AccordionContainer collapsible defaultOpen>
|
|
40
|
+
<SectionHeader title="Protection" isCollapsible />
|
|
41
|
+
<AccordionContainer.Content>
|
|
42
|
+
<SectionContent>…</SectionContent>
|
|
43
|
+
</AccordionContainer.Content>
|
|
44
|
+
</AccordionContainer>
|
|
45
|
+
</Section>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
A titled band that groups content on a page. Where `Card` owns a single surface
|
|
49
|
+
and `CardSection` divides a card's body, `Section` is the layer above both: it
|
|
50
|
+
labels a run of cards — or a table — and separates it from the next run.
|
|
51
|
+
|
|
52
|
+
## When to use
|
|
53
|
+
|
|
54
|
+
- A page that reads as **several labelled bands** ("General", "Protection",
|
|
55
|
+
"Danger zone"), each holding one or more cards.
|
|
56
|
+
- A **row of cards** that needs a shared title and a consistent three-column
|
|
57
|
+
grid (`grid3`).
|
|
58
|
+
- A **primary/secondary split** where a wide main area is paired with a narrow
|
|
59
|
+
companion column (`column2-70-30`).
|
|
60
|
+
- A **full-bleed table** with a page-level title above it (`table`).
|
|
61
|
+
|
|
62
|
+
## When not to use
|
|
63
|
+
|
|
64
|
+
- Inside a card. Use `CardSection` — it is card chrome, with the smaller 14px
|
|
65
|
+
header and the card's own inset rhythm.
|
|
66
|
+
- As a bare layout wrapper with no title. Use `Stack` / `Grid`; a section with
|
|
67
|
+
no header adds a band with no meaning.
|
|
68
|
+
- As a surface. `Section` paints no background of its own; the page surface
|
|
69
|
+
shows through.
|
|
70
|
+
|
|
71
|
+
## Parts
|
|
72
|
+
|
|
73
|
+
| Part | Element | Notes |
|
|
74
|
+
| ---------------- | --------- | --------------------------------------------------------------------------- |
|
|
75
|
+
| `Section` | `section` | Owns `variant` + `hasBottomBorder` and publishes the layout to its parts. |
|
|
76
|
+
| `SectionHeader` | `div` | Optional. Switch, title, description, extras, `children`, actions, trigger. |
|
|
77
|
+
| `SectionContent` | `div` | The body. Its layout comes from the root's `variant`. |
|
|
78
|
+
|
|
79
|
+
## Layouts
|
|
80
|
+
|
|
81
|
+
| `variant` | Body |
|
|
82
|
+
| --------------- | ----------------------------------------------------------- |
|
|
83
|
+
| `column1` | One full-width area (default). |
|
|
84
|
+
| `column2-70-30` | 3-column grid; children span 2, `secondaryContent` spans 1. |
|
|
85
|
+
| `grid3` | 3-column grid the children flow into. |
|
|
86
|
+
| `table` | Flush — no root padding, so rows bleed to the page edges. |
|
|
87
|
+
|
|
88
|
+
## Examples
|
|
89
|
+
|
|
90
|
+
A row of cards under one title:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<Section variant="grid3">
|
|
94
|
+
<SectionHeader title="Recent activity" />
|
|
95
|
+
<SectionContent>
|
|
96
|
+
<Card>…</Card>
|
|
97
|
+
<Card>…</Card>
|
|
98
|
+
<Card>…</Card>
|
|
99
|
+
</SectionContent>
|
|
100
|
+
</Section>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
A 70/30 split:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<Section variant="column2-70-30">
|
|
107
|
+
<SectionHeader
|
|
108
|
+
title="Storage"
|
|
109
|
+
description="Usage across every connected location."
|
|
110
|
+
hasDescription
|
|
111
|
+
/>
|
|
112
|
+
<SectionContent secondaryContent={<QuotaCard />}>
|
|
113
|
+
<LocationsCard />
|
|
114
|
+
</SectionContent>
|
|
115
|
+
</Section>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
A full-bleed table:
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<Section variant="table">
|
|
122
|
+
<SectionHeader
|
|
123
|
+
title="Workloads"
|
|
124
|
+
actions={
|
|
125
|
+
<ButtonIcon aria-label="More actions">
|
|
126
|
+
<EllipsisIcon size={24} />
|
|
127
|
+
</ButtonIcon>
|
|
128
|
+
}
|
|
129
|
+
/>
|
|
130
|
+
<SectionContent>
|
|
131
|
+
<WorkloadsTable />
|
|
132
|
+
</SectionContent>
|
|
133
|
+
</Section>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Collapsible — a composition with the shared disclosure primitive, not a prop:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<Section variant="grid3">
|
|
140
|
+
<AccordionContainer collapsible defaultOpen>
|
|
141
|
+
<SectionHeader
|
|
142
|
+
title="Protection"
|
|
143
|
+
isCollapsible
|
|
144
|
+
collapseLabel="Toggle protection section"
|
|
145
|
+
/>
|
|
146
|
+
<AccordionContainer.Content>
|
|
147
|
+
<SectionContent>…</SectionContent>
|
|
148
|
+
</AccordionContainer.Content>
|
|
149
|
+
</AccordionContainer>
|
|
150
|
+
</Section>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Notes
|
|
154
|
+
|
|
155
|
+
- **No bottom padding without `hasBottomBorder`.** Stacked unbordered sections
|
|
156
|
+
would otherwise double their vertical gap, since the next one already opens
|
|
157
|
+
with its own top inset. Set `hasBottomBorder` on every section but the last
|
|
158
|
+
when you want visible separators.
|
|
159
|
+
- **The `table` variant is flush on purpose.** It has no padding on any side so
|
|
160
|
+
its rows reach the page edges; only the header re-applies the horizontal
|
|
161
|
+
inset. `hasBottomBorder` adds the divider without reintroducing padding.
|
|
162
|
+
- **`variant` is set once, on the root.** The header and content parts read it
|
|
163
|
+
from context, so there is nothing to keep in sync.
|
|
164
|
+
- **Collapsing lives in `AccordionContainer`.** `isCollapsible` only renders the
|
|
165
|
+
trigger; the open/closed state, ARIA wiring, and height animation belong to
|
|
166
|
+
the container — the same split `Card` uses.
|
|
167
|
+
- **Override `collapseLabel` / `switchLabel`** whenever a page stacks several
|
|
168
|
+
collapsible or switchable sections; the defaults are generic by necessity.
|
|
169
|
+
|
|
170
|
+
## Props
|
|
171
|
+
|
|
172
|
+
| Prop | Type | Default | Required | Description |
|
|
173
|
+
|------|------|---------|----------|-------------|
|
|
174
|
+
| `variant` | `'column1' | 'column2-70-30' | 'grid3' | 'table'` | `column1` | no | Root. Which content layout the section uses. `column1` is one full-width area; `column2-70-30` splits the body into a wide and a narrow column; `grid3` flows children into a three-column card grid; `table` drops the root inset entirely so a table's rows run edge-to-edge. The root publishes this to its header and content parts, so the consumer sets it in exactly one place. |
|
|
175
|
+
| `hasBottomBorder` | `boolean` | `false` | no | Root. Draws a bottom divider plus the matching bottom padding, separating this band from the next one stacked below it. Without it the root reserves no bottom padding at all, because the next section opens with its own top inset. The `table` variant stays flush either way and only gains the divider. |
|
|
176
|
+
| `title` | `string` | `undefined` | no | Header. The section title, at the 20px medium "headings/section" scale. Renders nothing when omitted. |
|
|
177
|
+
| `description` | `string` | `undefined` | no | Header. Supporting text under the title; shown only with `hasDescription`. |
|
|
178
|
+
| `hasDescription` | `boolean` | `false` | no | Header. Shows `description` below the title. |
|
|
179
|
+
| `isSwitchable` | `boolean` | `false` | no | Header. Shows a toggle switch at the start of the header, for turning the whole grouping on or off. |
|
|
180
|
+
| `switchChecked` | `boolean` | `undefined` | no | Header. Controlled checked state of the header switch. |
|
|
181
|
+
| `defaultSwitchChecked` | `boolean` | `undefined` | no | Header. Uncontrolled initial checked state of the header switch. |
|
|
182
|
+
| `switchDisabled` | `boolean` | `undefined` | no | Header. Disables the header switch. |
|
|
183
|
+
| `switchLabel` | `string` | `Toggle section` | no | Header. Accessible label for the header switch. |
|
|
184
|
+
| `extras` | `ReactNode` | `undefined` | no | Header. Content rendered inline next to the title (e.g. a tag). |
|
|
185
|
+
| `actions` | `ReactNode` | `undefined` | no | Header. Actions rendered at the end of the header row. |
|
|
186
|
+
| `isCollapsible` | `boolean` | `false` | no | Header. Renders the disclosure trigger at the end of the header. Only has an effect inside a collapsible `AccordionContainer`, which owns the open/closed state. |
|
|
187
|
+
| `collapseLabel` | `string` | `Collapse section` | no | Header. Accessible label for the collapse trigger. |
|
|
188
|
+
| `secondaryContent` | `ReactNode` | `undefined` | no | Content. The narrow (~30%) second column of the `column2-70-30` layout. Ignored by every other variant, which has a single content area. |
|
|
189
|
+
| `render` | `RenderProp` | `undefined` | no | Base UI composition prop — replaces the rendered element with another component while merging props and classes. Available on every part. React-only; other frameworks use their own polymorphism. |
|
|
190
|
+
|
|
191
|
+
## Events
|
|
192
|
+
|
|
193
|
+
| Event | Payload | Description |
|
|
194
|
+
|-------|---------|-------------|
|
|
195
|
+
| `switch-checked-change` | `boolean` | Header. Fires when the header switch is toggled. |
|
|
196
|
+
|
|
197
|
+
## Content slots
|
|
198
|
+
|
|
199
|
+
| Slot | Description |
|
|
200
|
+
|------|-------------|
|
|
201
|
+
| `default` | On the root, the section's parts (header, content). On the header, an additional slot rendered after the title/description block and before `actions` — used to supply a custom heading element (see accessibility.md). On the content part, the body itself — the wide column under `column2-70-30`, the grid items under `grid3`, and everything under `column1` / `table`. |
|
|
202
|
+
|
|
203
|
+
## Behavior
|
|
204
|
+
|
|
205
|
+
### Choosing a content layout
|
|
206
|
+
|
|
207
|
+
**Given** a `Section` with no `variant`
|
|
208
|
+
**When** it renders
|
|
209
|
+
**Then** it uses `column1`: the content part is one full-width area with no
|
|
210
|
+
imposed grid.
|
|
211
|
+
|
|
212
|
+
**Given** `variant="column2-70-30"`
|
|
213
|
+
**When** it renders
|
|
214
|
+
**Then** the content part is a three-column grid; the children span two columns
|
|
215
|
+
(~70%) and `secondaryContent` the remaining one (~30%). With no
|
|
216
|
+
`secondaryContent` the narrow column is not rendered at all and the wide column
|
|
217
|
+
keeps its 2:1 span rather than stretching.
|
|
218
|
+
|
|
219
|
+
**Given** `variant="grid3"`
|
|
220
|
+
**When** it renders
|
|
221
|
+
**Then** the content part is a three-column grid the children flow into. No row
|
|
222
|
+
count is imposed — four children wrap onto a second row.
|
|
223
|
+
|
|
224
|
+
**Given** `variant="table"`
|
|
225
|
+
**When** it renders
|
|
226
|
+
**Then** the root drops its padding entirely so the table's rows bleed to the
|
|
227
|
+
page edges, and the header re-applies the horizontal inset so the title still
|
|
228
|
+
lines up with the first column.
|
|
229
|
+
|
|
230
|
+
**Given** `secondaryContent` under any variant other than `column2-70-30`
|
|
231
|
+
**When** it renders
|
|
232
|
+
**Then** it is ignored — those layouts have a single content area.
|
|
233
|
+
|
|
234
|
+
### Stacking sections down a page
|
|
235
|
+
|
|
236
|
+
**Given** a section with `hasBottomBorder` unset
|
|
237
|
+
**When** it renders
|
|
238
|
+
**Then** no divider is painted and **no bottom padding is reserved**. This is
|
|
239
|
+
deliberate: the next section down opens with its own top inset, so reserving
|
|
240
|
+
bottom padding here would double the gap between two unbordered bands.
|
|
241
|
+
|
|
242
|
+
**Given** several sections stacked on one page
|
|
243
|
+
**When** every section except the last sets `hasBottomBorder`
|
|
244
|
+
**Then** each is separated by a divider with matching bottom padding, and the
|
|
245
|
+
last one closes flush.
|
|
246
|
+
|
|
247
|
+
**Given** `variant="table"` together with `hasBottomBorder`
|
|
248
|
+
**When** it renders
|
|
249
|
+
**Then** only the divider is added — the root stays flush, with no padding on
|
|
250
|
+
any side.
|
|
251
|
+
|
|
252
|
+
### The header
|
|
253
|
+
|
|
254
|
+
**Given** no `SectionHeader` child
|
|
255
|
+
**When** the section renders
|
|
256
|
+
**Then** there is no header row and the content is the section's only child.
|
|
257
|
+
There is no `hasHeader` flag: the part is simply omitted.
|
|
258
|
+
|
|
259
|
+
**Given** a `title` and `description` but no `hasDescription`
|
|
260
|
+
**When** it renders
|
|
261
|
+
**Then** only the title is shown — the description is opt-in.
|
|
262
|
+
|
|
263
|
+
**Given** `isSwitchable`
|
|
264
|
+
**When** it renders
|
|
265
|
+
**Then** a toggle switch appears at the start of the header, before the title,
|
|
266
|
+
carrying `switchLabel` as its accessible name. Toggling it emits
|
|
267
|
+
`switch-checked-change`; it never expands or collapses the section.
|
|
268
|
+
|
|
269
|
+
**Given** `extras` and `actions`
|
|
270
|
+
**When** it renders
|
|
271
|
+
**Then** `extras` sit inline immediately after the title and `actions` are
|
|
272
|
+
pushed to the inline end of the row, before the collapse trigger. The push
|
|
273
|
+
comes from the flex-grow wrapper around `title` / `description` / `extras`.
|
|
274
|
+
|
|
275
|
+
**Given** a header with `children` but no `title`, `description`, or `extras`
|
|
276
|
+
**When** it renders
|
|
277
|
+
**Then** that wrapper is not rendered at all, so `children` start at the inline
|
|
278
|
+
start of the row — this is what lets a consumer-supplied heading take the
|
|
279
|
+
title's place (see accessibility). Because nothing then grows, `actions`
|
|
280
|
+
follow `children` immediately rather than sitting at the inline end, unless the
|
|
281
|
+
consumer's own content grows (`flex-1`).
|
|
282
|
+
|
|
283
|
+
### Collapsing
|
|
284
|
+
|
|
285
|
+
**Given** `isCollapsible` on a header that is **not** inside a collapsible
|
|
286
|
+
`AccordionContainer`
|
|
287
|
+
**When** it renders
|
|
288
|
+
**Then** no trigger appears — `AccordionContainer.Trigger` renders `null`
|
|
289
|
+
outside a collapsible container, matching the design's `isCollapsable=false`
|
|
290
|
+
state, which has no disclosure UI at all.
|
|
291
|
+
|
|
292
|
+
**Given** a header with `isCollapsible` inside
|
|
293
|
+
`<AccordionContainer collapsible defaultOpen>`
|
|
294
|
+
**When** it renders
|
|
295
|
+
**Then** the trigger is shown expanded (`aria-expanded="true"`) and the content
|
|
296
|
+
wrapped in `AccordionContainer.Content` is visible — the design's
|
|
297
|
+
`true-expanded` state.
|
|
298
|
+
|
|
299
|
+
**Given** the same composition with `defaultOpen={false}`
|
|
300
|
+
**When** it renders
|
|
301
|
+
**Then** the trigger reads `aria-expanded="false"` and the panel is collapsed —
|
|
302
|
+
the design's `true-collapsed` state.
|
|
303
|
+
|
|
304
|
+
**When** the trigger is activated
|
|
305
|
+
**Then** the panel animates its height and the chevron rotates; the header,
|
|
306
|
+
including the switch and actions, stays visible throughout.
|
|
307
|
+
|
|
308
|
+
### Composition
|
|
309
|
+
|
|
310
|
+
**Given** a `render` prop on any part
|
|
311
|
+
**When** it renders
|
|
312
|
+
**Then** the element is replaced by the supplied element/component with props
|
|
313
|
+
and classes merged (Base UI composition) — e.g. rendering the root as an
|
|
314
|
+
`<article>`.
|
|
315
|
+
|
|
316
|
+
**Given** a `SectionHeader` or `SectionContent` rendered outside a `Section`
|
|
317
|
+
**When** it renders
|
|
318
|
+
**Then** it falls back to the `column1` layout rather than failing.
|
|
319
|
+
|
|
320
|
+
## Accessibility
|
|
321
|
+
|
|
322
|
+
## Roles and semantics
|
|
323
|
+
|
|
324
|
+
- The root renders a real `<section>` element. A `<section>` only becomes a
|
|
325
|
+
`region` landmark once it has an accessible name, so give it one whenever the
|
|
326
|
+
band is genuinely navigable content:
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
<Section aria-labelledby="protection-heading">…</Section>
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Do not name every section — an unnamed `<section>` is a generic grouping and
|
|
333
|
+
stays out of the landmark list, which is the right default for decorative
|
|
334
|
+
bands.
|
|
335
|
+
|
|
336
|
+
- The header title is a `<p>`, not a heading. A section's place in the document
|
|
337
|
+
outline depends on the page around it, so guessing a level (`h2`? `h3`?)
|
|
338
|
+
would produce a broken hierarchy in most compositions. When the band really
|
|
339
|
+
is a document section, supply your own heading through the header's
|
|
340
|
+
`children` slot (not `render` — that replaces the entire header row,
|
|
341
|
+
wrapping the switch, title, description, actions, and collapse trigger in
|
|
342
|
+
the heading element), omit `title` so you don't render two titles, match the
|
|
343
|
+
title's text scale yourself (`text-xl leading-6 font-medium
|
|
344
|
+
text-[var(--ui-text-on-surface-primary)]` — no exported class), and point
|
|
345
|
+
the root's `aria-labelledby` at it. With `title`, `description`, and `extras`
|
|
346
|
+
all omitted, the header renders no flex-grow wrapper at all, so give the
|
|
347
|
+
heading `min-w-0 flex-1` if the header also carries `actions` and they should
|
|
348
|
+
stay at the inline end.
|
|
349
|
+
|
|
350
|
+
- The `description` is ordinary text, not a description role. If it should name
|
|
351
|
+
or describe the region for assistive technology, wire it up explicitly with
|
|
352
|
+
`aria-describedby`.
|
|
353
|
+
|
|
354
|
+
## Keyboard
|
|
355
|
+
|
|
356
|
+
- The section itself is not focusable and imposes no keyboard behavior.
|
|
357
|
+
- Focus order follows DOM order: the header switch, then anything focusable in
|
|
358
|
+
`extras`, then anything in the header's `children` slot, then `actions`,
|
|
359
|
+
then the collapse trigger, then the content. Nothing is trapped or
|
|
360
|
+
re-ordered.
|
|
361
|
+
- The collapse trigger is a real `<button>` supplied by `AccordionContainer`
|
|
362
|
+
(Base UI Collapsible): `Tab` reaches it and `Enter` / `Space` toggle the
|
|
363
|
+
panel. Its `aria-expanded` and `aria-controls` are managed by the primitive.
|
|
364
|
+
- Collapsed content is hidden from the accessibility tree, so it is skipped by
|
|
365
|
+
both `Tab` and virtual-cursor navigation.
|
|
366
|
+
|
|
367
|
+
## Screen reader
|
|
368
|
+
|
|
369
|
+
- Icon-only controls in `actions` must supply their own accessible name; the
|
|
370
|
+
section adds none.
|
|
371
|
+
- The collapse trigger has no visible label, so it relies on `collapseLabel`
|
|
372
|
+
(default `'Collapse section'`). Override it with something specific when a
|
|
373
|
+
page stacks several collapsible sections — "Collapse section" three times in
|
|
374
|
+
a row is not navigable.
|
|
375
|
+
- The header switch likewise relies on `switchLabel` (default
|
|
376
|
+
`'Toggle section'`); override it per section for the same reason.
|
|
377
|
+
- The title may be visually truncated. Truncation is visual only — the full
|
|
378
|
+
string stays in the accessible text — but keep it short enough to be
|
|
379
|
+
meaningful.
|
|
380
|
+
|
|
381
|
+
## Contrast
|
|
382
|
+
|
|
383
|
+
- The title uses `--ui-text-on-surface-primary` and the description
|
|
384
|
+
`--ui-text-on-surface-secondary`, both against the page surface. Both meet
|
|
385
|
+
WCAG AA in every shipped brand and in both light and dark themes.
|
|
386
|
+
- The `hasBottomBorder` divider uses `--ui-border-on-surface-divider`. It is a
|
|
387
|
+
decorative separator, not a meaningful boundary, so it is exempt from the 3:1
|
|
388
|
+
non-text contrast requirement — the grouping is also conveyed by the header
|
|
389
|
+
and the spacing.
|
|
390
|
+
|
|
391
|
+
## Localization
|
|
392
|
+
|
|
393
|
+
- Every string the component renders on its own — `switchLabel` and
|
|
394
|
+
`collapseLabel` — is a prop whose literal exists only as that prop's default.
|
|
395
|
+
`title`, `description`, `extras`, `actions`, and the content are all
|
|
396
|
+
consumer-supplied.
|
|
397
|
+
- Layout uses logical spacing and a logical grid only, so the band mirrors
|
|
398
|
+
correctly under `dir="rtl"`: the switch and title sit at the inline start,
|
|
399
|
+
actions and the collapse trigger at the inline end, and the 70/30 split
|
|
400
|
+
reverses. The trigger's chevron flips through `AccordionContainer`'s own
|
|
401
|
+
`rtl:` variant.
|