@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,170 @@
|
|
|
1
|
+
# InputSearch
|
|
2
|
+
|
|
3
|
+
> A full search field: an optional label (with an optional required marker) above the search box. Builds on the bare `Search` box (leading magnifier, input, and clear button) and the `--ui-input-search-*` token tier.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** forms · **Since:** v0.29.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { InputSearch } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<InputSearch label="Find" placeholder="Search table" />
|
|
17
|
+
|
|
18
|
+
{/* Required */}
|
|
19
|
+
<InputSearch label="Find" required />
|
|
20
|
+
|
|
21
|
+
{/* Controlled with clear */}
|
|
22
|
+
<InputSearch
|
|
23
|
+
label="Find"
|
|
24
|
+
value={query}
|
|
25
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
26
|
+
onClear={() => setQuery('')}
|
|
27
|
+
/>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
A full search field: a label (with an optional required marker) above the search
|
|
31
|
+
box. It composes the bare [`Search`](../search/README.md) box — a leading
|
|
32
|
+
magnifier, the input, and a clear (×) button — and adds the surrounding field
|
|
33
|
+
furniture.
|
|
34
|
+
|
|
35
|
+
## When to use
|
|
36
|
+
|
|
37
|
+
- A labelled search / filter field in a form or panel, where the field needs a
|
|
38
|
+
visible label above the box.
|
|
39
|
+
|
|
40
|
+
## When not to use
|
|
41
|
+
|
|
42
|
+
- For a bare search box with no label (e.g. in a toolbar or table header) — use
|
|
43
|
+
the [`Search`](../search/README.md) box directly.
|
|
44
|
+
- For a plain labelled text field with no leading magnifier — use `InputText`.
|
|
45
|
+
|
|
46
|
+
## Examples
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { InputSearch } from '@acronis-platform/ui-react';
|
|
50
|
+
|
|
51
|
+
// Basic labelled search field
|
|
52
|
+
<InputSearch label="Find" placeholder="Search table" />;
|
|
53
|
+
|
|
54
|
+
// Required
|
|
55
|
+
<InputSearch label="Find" required />;
|
|
56
|
+
|
|
57
|
+
// Controlled with clear
|
|
58
|
+
<InputSearch
|
|
59
|
+
label="Find"
|
|
60
|
+
value={query}
|
|
61
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
62
|
+
onClear={() => setQuery('')}
|
|
63
|
+
/>;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Parts
|
|
67
|
+
|
|
68
|
+
| Part | Element | Description |
|
|
69
|
+
| ---------- | ---------- | ----------------------------------------------------------- |
|
|
70
|
+
| `label` | `<label>` | Field label (associated via `htmlFor`/`id`). |
|
|
71
|
+
| `required` | `<span>` | Required `*` marker (decorative; `aria-hidden`). |
|
|
72
|
+
| `icon` | `<svg>` | Leading magnifier inside the box (from `Search`). |
|
|
73
|
+
| `input` | `<input>` | The search box input (`role="searchbox"`, from `Search`). |
|
|
74
|
+
| `clear` | `<button>` | Optional clear (×) button; calls `onClear` (from `Search`). |
|
|
75
|
+
|
|
76
|
+
## Props
|
|
77
|
+
|
|
78
|
+
| Prop | Type | Default | Required | Description |
|
|
79
|
+
|------|------|---------|----------|-------------|
|
|
80
|
+
| `label` | `ReactNode` | — | no | Field label rendered above the box, associated via `htmlFor`/`id`. |
|
|
81
|
+
| `required` | `boolean` | `false` | no | Appends a required marker (`*`) after the label and sets `aria-required` on the input. |
|
|
82
|
+
| `placeholder` | `string` | — | no | Hint text shown when empty (e.g. "Search table"). |
|
|
83
|
+
| `value` | `string` | — | no | Controlled value. Pair with the change event. |
|
|
84
|
+
| `default-value` | `string` | — | no | Initial value when uncontrolled. |
|
|
85
|
+
| `disabled` | `boolean` | `false` | no | Disables the field; hides the clear button and applies the disabled tokens. |
|
|
86
|
+
|
|
87
|
+
## Events
|
|
88
|
+
|
|
89
|
+
| Event | Payload | Description |
|
|
90
|
+
|-------|---------|-------------|
|
|
91
|
+
| `change` | `ChangeEvent<HTMLInputElement>` | Native input change — forwarded to the underlying `<input>`. Also fires when the value is cleared. |
|
|
92
|
+
| `clear` | `void` | Fired after the clear (×) button empties the field (React: `onClear`). |
|
|
93
|
+
|
|
94
|
+
## Content slots
|
|
95
|
+
|
|
96
|
+
| Slot | Description |
|
|
97
|
+
|------|-------------|
|
|
98
|
+
| `label` | The label content. |
|
|
99
|
+
|
|
100
|
+
## Behavior
|
|
101
|
+
|
|
102
|
+
### Rendering
|
|
103
|
+
|
|
104
|
+
**Given** a `label`
|
|
105
|
+
**When** the field renders
|
|
106
|
+
**Then** the label appears above the box and is associated with the input via
|
|
107
|
+
`htmlFor`/`id` (clicking the label focuses the input), and `Search`'s built-in
|
|
108
|
+
`aria-label` is cleared so it doesn't shadow the visible label.
|
|
109
|
+
|
|
110
|
+
**Given** no `label`
|
|
111
|
+
**When** the field renders
|
|
112
|
+
**Then** the field falls back to the composed `Search`'s accessible name
|
|
113
|
+
(a caller-supplied `aria-label`, otherwise the default "Search").
|
|
114
|
+
|
|
115
|
+
**Given** `required`
|
|
116
|
+
**When** the field renders
|
|
117
|
+
**Then** a `*` marker is appended after the label and the input gets
|
|
118
|
+
`aria-required="true"`.
|
|
119
|
+
|
|
120
|
+
### Clear
|
|
121
|
+
|
|
122
|
+
**Given** a non-empty `value` (controlled or uncontrolled)
|
|
123
|
+
**When** the field is not disabled
|
|
124
|
+
**Then** the clear (×) button appears inside the box.
|
|
125
|
+
|
|
126
|
+
**Given** the clear button
|
|
127
|
+
**When** it is activated (click, Enter, or Space)
|
|
128
|
+
**Then** the field empties, the input refocuses, and `onClear` fires alongside a
|
|
129
|
+
native change event with an empty value.
|
|
130
|
+
|
|
131
|
+
**Given** the field is `disabled`
|
|
132
|
+
**Then** the clear button is not shown.
|
|
133
|
+
|
|
134
|
+
### Interaction
|
|
135
|
+
|
|
136
|
+
**Given** the box
|
|
137
|
+
**When** the pointer hovers / the input receives keyboard focus
|
|
138
|
+
**Then** the box border shifts to its hover token and keyboard focus paints a 3px
|
|
139
|
+
`--ui-focus-primary` ring (via `:focus-within`).
|
|
140
|
+
|
|
141
|
+
**Given** any typing
|
|
142
|
+
**When** the value changes
|
|
143
|
+
**Then** the native `change` event is forwarded to the consumer.
|
|
144
|
+
|
|
145
|
+
## Accessibility
|
|
146
|
+
|
|
147
|
+
- **Label association:** the `label` is a real `<label htmlFor>` tied to the
|
|
148
|
+
input's `id` (auto-generated when not supplied), so clicking it focuses the
|
|
149
|
+
input and screen readers announce the field name. When a visible label is
|
|
150
|
+
present, the composed `Search`'s default `aria-label` is cleared so the
|
|
151
|
+
accessible name matches the visible label (WCAG 2.5.3, label in name).
|
|
152
|
+
- **Unlabelled fallback:** with no `label`, the field keeps `Search`'s accessible
|
|
153
|
+
name — a caller-supplied `aria-label`, or the default "Search".
|
|
154
|
+
- **Required:** `required` sets `aria-required="true"` on the input; the visual `*`
|
|
155
|
+
marker is `aria-hidden` (decorative — the required semantics come from the
|
|
156
|
+
attribute).
|
|
157
|
+
- **Search semantics:** the input is a native `<input type="search">`
|
|
158
|
+
(`role="searchbox"`).
|
|
159
|
+
- **Clear button:** a native `<button>` with `aria-label="Clear search"`; reachable
|
|
160
|
+
by Tab and activated by Enter / Space, after which focus returns to the input.
|
|
161
|
+
- **Keyboard:** the input is a native search field; the clear button is a separate
|
|
162
|
+
tab stop after it.
|
|
163
|
+
- **Focus visible:** keyboard focus paints a 3px `--ui-focus-primary` ring flush to
|
|
164
|
+
the box (via `:focus-within`).
|
|
165
|
+
- **Disabled:** native `disabled` removes the input (and clear button) from the tab
|
|
166
|
+
order; the field is also inert, so state is not conveyed by color alone.
|
|
167
|
+
- **Contrast:** label / value / placeholder / icon / border pairs come from the
|
|
168
|
+
design tokens, authored to meet WCAG contrast.
|
|
169
|
+
- **WCAG:** 1.3.1 (info/relationships), 2.1.1 (keyboard), 2.4.7 (focus visible),
|
|
170
|
+
2.5.3 (label in name), 1.4.3 / 1.4.11 (contrast), 3.3.2 (labels), 4.1.2.
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# InputSelect
|
|
2
|
+
|
|
3
|
+
> The next-gen select field: an optional label (with a required marker), a trigger box showing the value / placeholder and a chevron, an optional description or error message, and a floating dropdown with an in-dropdown search, sections (groups), single or multiple selectable items, and loading / empty / error status. Composes Base UI `Select` and the `--ui-input-select-*` token tier.
|
|
4
|
+
|
|
5
|
+
**Status:** ready · **Category:** forms · **Since:** v0.29.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { InputSelect, InputSelectField, InputSelectLabel, InputSelectTrigger, InputSelectValue, InputSelectContent, InputSelectSearch, InputSelectSection, InputSelectSectionLabel, InputSelectItem, InputSelectExpander, InputSelectDescription, InputSelectError, InputSelectStatus, useInputSelectFilter } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<InputSelect items={{ apple: 'Apple', banana: 'Banana' }} value={fruit} onValueChange={setFruit}>
|
|
17
|
+
<InputSelectField>
|
|
18
|
+
<InputSelectLabel required>Fruit</InputSelectLabel>
|
|
19
|
+
<InputSelectTrigger aria-invalid={Boolean(error)}>
|
|
20
|
+
<InputSelectValue placeholder="Select an option" />
|
|
21
|
+
</InputSelectTrigger>
|
|
22
|
+
{error ? (
|
|
23
|
+
<InputSelectError>{error}</InputSelectError>
|
|
24
|
+
) : (
|
|
25
|
+
<InputSelectDescription>Pick your favourite</InputSelectDescription>
|
|
26
|
+
)}
|
|
27
|
+
</InputSelectField>
|
|
28
|
+
<InputSelectContent>
|
|
29
|
+
<InputSelectSearch placeholder="Search" value={q} onChange={(e) => setQ(e.target.value)} />
|
|
30
|
+
<InputSelectSection>
|
|
31
|
+
<InputSelectSectionLabel>Fruits</InputSelectSectionLabel>
|
|
32
|
+
<InputSelectItem value="apple">Apple</InputSelectItem>
|
|
33
|
+
<InputSelectItem value="banana">Banana</InputSelectItem>
|
|
34
|
+
</InputSelectSection>
|
|
35
|
+
</InputSelectContent>
|
|
36
|
+
</InputSelect>
|
|
37
|
+
|
|
38
|
+
{/* Status (instead of items) */}
|
|
39
|
+
<InputSelectContent>
|
|
40
|
+
<InputSelectStatus variant="empty">No data found</InputSelectStatus>
|
|
41
|
+
</InputSelectContent>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The next-gen select **field**: a label (with an optional required marker), a trigger
|
|
45
|
+
box showing the value / placeholder and a chevron, an optional description or error,
|
|
46
|
+
and a floating dropdown with an in-dropdown search, sections, single- or
|
|
47
|
+
multiple-selectable items, and loading / empty / error status. It composes Base UI
|
|
48
|
+
`Select` and the `--ui-input-select-*` token tier.
|
|
49
|
+
|
|
50
|
+
> `Select` is an alias of this family (re-pointed off the deleted `--ui-form-*` tier).
|
|
51
|
+
> Prefer importing `InputSelect*` directly in new code.
|
|
52
|
+
|
|
53
|
+
## When to use
|
|
54
|
+
|
|
55
|
+
- Choosing one (or several, with `multiple`) options from a list, with full field
|
|
56
|
+
furniture (label / description / error) and optional in-dropdown search / grouping /
|
|
57
|
+
status.
|
|
58
|
+
|
|
59
|
+
## When not to use
|
|
60
|
+
|
|
61
|
+
- For a free-text field — use `InputText`; for a search box — use `Search` /
|
|
62
|
+
`InputSearch`.
|
|
63
|
+
- For a small fixed set shown inline — consider `Radio` (single) or `Checkbox` group.
|
|
64
|
+
- The nested **tenant-tree** picker (Recent/Browse, collapsible tenant items) is a
|
|
65
|
+
separate follow-up component.
|
|
66
|
+
|
|
67
|
+
## Examples
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import {
|
|
71
|
+
InputSelect,
|
|
72
|
+
InputSelectField,
|
|
73
|
+
InputSelectLabel,
|
|
74
|
+
InputSelectTrigger,
|
|
75
|
+
InputSelectValue,
|
|
76
|
+
InputSelectContent,
|
|
77
|
+
InputSelectSearch,
|
|
78
|
+
InputSelectSection,
|
|
79
|
+
InputSelectSectionLabel,
|
|
80
|
+
InputSelectItem,
|
|
81
|
+
InputSelectDescription,
|
|
82
|
+
InputSelectError,
|
|
83
|
+
InputSelectStatus,
|
|
84
|
+
} from '@acronis-platform/ui-react';
|
|
85
|
+
|
|
86
|
+
<InputSelect
|
|
87
|
+
items={{ apple: 'Apple', banana: 'Banana' }}
|
|
88
|
+
value={fruit}
|
|
89
|
+
onValueChange={setFruit}
|
|
90
|
+
>
|
|
91
|
+
<InputSelectField>
|
|
92
|
+
<InputSelectLabel required>Fruit</InputSelectLabel>
|
|
93
|
+
<InputSelectTrigger>
|
|
94
|
+
<InputSelectValue placeholder="Select an option" />
|
|
95
|
+
</InputSelectTrigger>
|
|
96
|
+
<InputSelectDescription>Pick your favourite</InputSelectDescription>
|
|
97
|
+
</InputSelectField>
|
|
98
|
+
<InputSelectContent>
|
|
99
|
+
<InputSelectSection>
|
|
100
|
+
<InputSelectSectionLabel>Fruits</InputSelectSectionLabel>
|
|
101
|
+
<InputSelectItem value="apple">Apple</InputSelectItem>
|
|
102
|
+
<InputSelectItem value="banana">Banana</InputSelectItem>
|
|
103
|
+
</InputSelectSection>
|
|
104
|
+
</InputSelectContent>
|
|
105
|
+
</InputSelect>;
|
|
106
|
+
|
|
107
|
+
// Multiple selection
|
|
108
|
+
<InputSelect multiple value={tags} onValueChange={setTags}>
|
|
109
|
+
…
|
|
110
|
+
</InputSelect>;
|
|
111
|
+
|
|
112
|
+
// Empty status instead of items
|
|
113
|
+
<InputSelectContent>
|
|
114
|
+
<InputSelectStatus variant="empty">No data found</InputSelectStatus>
|
|
115
|
+
</InputSelectContent>;
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Parts
|
|
119
|
+
|
|
120
|
+
| Part | Element | Description |
|
|
121
|
+
| ------------------------- | ---------- | ----------------------------------------------------------------- |
|
|
122
|
+
| `InputSelectField` | `<div>` | Vertical field stack (label / trigger / description-error). |
|
|
123
|
+
| `InputSelectLabel` | `<label>` | Field label (auto-associated); `required` adds `*`. |
|
|
124
|
+
| `InputSelectTrigger` | `<button>` | The combobox box; `aria-invalid` switches to the error look. |
|
|
125
|
+
| `InputSelectValue` | `<span>` | Selected label or placeholder. |
|
|
126
|
+
| `InputSelectContent` | `<div>` | The floating listbox popup. |
|
|
127
|
+
| `InputSelectSearch` | `<div>` | In-dropdown search row; drives live filtering of the items. |
|
|
128
|
+
| `InputSelectSection` | `<div>` | A labelled group of items. |
|
|
129
|
+
| `InputSelectSectionLabel` | `<div>` | The group heading. |
|
|
130
|
+
| `InputSelectItem` | `<div>` | An option; trailing check (single) / leading checkbox (multiple). |
|
|
131
|
+
| `InputSelectExpander` | `<button>` | Non-selectable expand/collapse toggle for a tree group. |
|
|
132
|
+
| `InputSelectDescription` | `<p>` | Helper text (normal state). |
|
|
133
|
+
| `InputSelectError` | `<p>` | Error message; replaces the description. |
|
|
134
|
+
| `InputSelectStatus` | `<div>` | Loading / empty / error row shown instead of items. |
|
|
135
|
+
|
|
136
|
+
`useInputSelectFilter()` reads the search query set by `InputSelectSearch`;
|
|
137
|
+
use it inside a custom tree/item renderer to filter items the flat
|
|
138
|
+
`InputSelectItem` auto-filter doesn't cover.
|
|
139
|
+
|
|
140
|
+
## Props
|
|
141
|
+
|
|
142
|
+
| Prop | Type | Default | Required | Description |
|
|
143
|
+
|------|------|---------|----------|-------------|
|
|
144
|
+
| `value` | `string | string[]` | — | no | Controlled selected value(s). Pair with the change event. |
|
|
145
|
+
| `default-value` | `string | string[]` | — | no | Initial selection when uncontrolled. |
|
|
146
|
+
| `open` | `boolean` | — | no | Controlled open state of the options popup. |
|
|
147
|
+
| `default-open` | `boolean` | `false` | no | Whether the popup is initially open when uncontrolled. |
|
|
148
|
+
| `disabled` | `boolean` | `false` | no | Disables the control; applies the disabled tokens and blocks opening. |
|
|
149
|
+
| `multiple` | `boolean` | `false` | no | Whether more than one option can be selected. Items show a leading checkbox and the popup stays open on select. |
|
|
150
|
+
| `required` | `boolean` | `false` | no | Marks the control required; the label shows a `*` marker. |
|
|
151
|
+
| `name` | `string` | — | no | Form field name submitted with the form (via a hidden input). |
|
|
152
|
+
| `placeholder` | `string` | — | no | Hint shown by the value part when nothing is selected. |
|
|
153
|
+
| `items` | `Record<string, string>` | — | no | Map of value → label for every selectable option, so the value part can render a selected option's label while the popup is closed without inspecting the rendered items. |
|
|
154
|
+
|
|
155
|
+
## Events
|
|
156
|
+
|
|
157
|
+
| Event | Payload | Description |
|
|
158
|
+
|-------|---------|-------------|
|
|
159
|
+
| `value-change` | `string | string[]` | Fired when the selection changes (React: `onValueChange`). |
|
|
160
|
+
| `open-change` | `boolean` | Fired when the popup opens or closes (React: `onOpenChange`). |
|
|
161
|
+
|
|
162
|
+
## Content slots
|
|
163
|
+
|
|
164
|
+
| Slot | Description |
|
|
165
|
+
|------|-------------|
|
|
166
|
+
| `default` | The composed field: a field wrapper holding the label, the trigger (with the value), and the description / error; then the content holding the optional search, sections, items, or a status row. Provide an `items` map on the root so the value part can render a selected option's label while the popup is closed. |
|
|
167
|
+
|
|
168
|
+
## Behavior
|
|
169
|
+
|
|
170
|
+
### Rendering
|
|
171
|
+
|
|
172
|
+
**Given** a label
|
|
173
|
+
**When** the field renders
|
|
174
|
+
**Then** the label appears above the trigger and is auto-associated with it (Base UI
|
|
175
|
+
`Select.Label`), so clicking the label focuses the trigger and screen readers announce
|
|
176
|
+
the field name.
|
|
177
|
+
|
|
178
|
+
**Given** `required`
|
|
179
|
+
**When** the field renders
|
|
180
|
+
**Then** a `*` marker is appended after the label.
|
|
181
|
+
|
|
182
|
+
**Given** a description and no error
|
|
183
|
+
**Then** the helper text shows below the trigger; **given** the trigger is
|
|
184
|
+
`aria-invalid` with an error message, the error replaces the description and the
|
|
185
|
+
trigger takes the error border.
|
|
186
|
+
|
|
187
|
+
### Opening / selecting (single)
|
|
188
|
+
|
|
189
|
+
**Given** the trigger
|
|
190
|
+
**When** it is pressed (or Space / Enter / ArrowDown with focus)
|
|
191
|
+
**Then** the popup opens (`data-popup-open`, chevron rotates 180°) and emits
|
|
192
|
+
`open-change(true)`.
|
|
193
|
+
|
|
194
|
+
**Given** an open popup
|
|
195
|
+
**When** an item is clicked or activated with Enter
|
|
196
|
+
**Then** the value updates (emits `value-change`), the selected row tints and shows a
|
|
197
|
+
trailing check, the trigger shows the resolved label, and the popup closes.
|
|
198
|
+
|
|
199
|
+
### Multiple selection
|
|
200
|
+
|
|
201
|
+
**Given** `multiple`
|
|
202
|
+
**When** the popup is open and items are toggled
|
|
203
|
+
**Then** each item shows a leading checkbox reflecting its selected state, the row
|
|
204
|
+
background stays the unselected color, and the popup **stays open** so several items
|
|
205
|
+
can be picked.
|
|
206
|
+
|
|
207
|
+
### Search / sections / status
|
|
208
|
+
|
|
209
|
+
**Given** an in-dropdown search row (uncontrolled)
|
|
210
|
+
**When** the user types into it
|
|
211
|
+
**Then** it drives an internal filter query, and each flat `InputSelectItem`
|
|
212
|
+
whose label doesn't match hides itself; tree dropdowns read the query via
|
|
213
|
+
`useInputSelectFilter` and filter their own items. Passing `value`/`onChange`
|
|
214
|
+
controls the query externally instead. Printable keys are kept from Base UI's
|
|
215
|
+
own typeahead while it's focused; Arrow/Home/End/Enter/Escape still bubble so
|
|
216
|
+
the user can move from the search box into the filtered list.
|
|
217
|
+
|
|
218
|
+
**Given** an `InputSelectExpander` row inside a tree dropdown
|
|
219
|
+
**When** the user clicks it
|
|
220
|
+
**Then** it toggles `aria-expanded` and calls `onToggle` — it is not a
|
|
221
|
+
selectable `SelectPrimitive.Item` and never sets the select value.
|
|
222
|
+
|
|
223
|
+
**Given** a section with a label
|
|
224
|
+
**Then** its items render under a heading, divided from the previous section by a top
|
|
225
|
+
border.
|
|
226
|
+
|
|
227
|
+
**Given** a status row (`loading` / `empty` / `error`)
|
|
228
|
+
**When** rendered instead of items
|
|
229
|
+
**Then** it shows the matching icon and message (and, for `error`, an optional retry
|
|
230
|
+
action).
|
|
231
|
+
|
|
232
|
+
### Interaction
|
|
233
|
+
|
|
234
|
+
**Given** the trigger
|
|
235
|
+
**When** the pointer hovers / it receives keyboard focus
|
|
236
|
+
**Then** the box border shifts to its hover token and keyboard focus paints a 3px ring —
|
|
237
|
+
`--ui-focus-primary` normally, `--ui-focus-error` while `aria-invalid`.
|
|
238
|
+
|
|
239
|
+
**Given** the field is `disabled`
|
|
240
|
+
**Then** the trigger is inert (does not open) and uses the disabled token set.
|
|
241
|
+
|
|
242
|
+
## Accessibility
|
|
243
|
+
|
|
244
|
+
- **Roles:** the trigger is a `role="combobox"` button; the popup is a
|
|
245
|
+
`role="listbox"`; each item is a `role="option"` (provided by Base UI `Select`).
|
|
246
|
+
- **Label association:** `InputSelectLabel` (Base UI `Select.Label`) is automatically
|
|
247
|
+
associated with the trigger via the select context — clicking the label focuses the
|
|
248
|
+
trigger and screen readers announce the field name. No manual `htmlFor`/`id` needed.
|
|
249
|
+
- **Required:** `required` appends a visual `*` marker (`aria-hidden`); set the root
|
|
250
|
+
`required` so the form-level constraint is conveyed via the hidden input.
|
|
251
|
+
- **Error:** set `aria-invalid` on the trigger; pair with `InputSelectError`. Associate
|
|
252
|
+
the message via `aria-describedby` on the trigger when wiring a controlled error.
|
|
253
|
+
- **Keyboard:** Space / Enter / ArrowDown open the popup; arrows move the highlight;
|
|
254
|
+
Enter selects; Escape closes and returns focus to the trigger; type-ahead matches
|
|
255
|
+
items. In `multiple` mode the popup stays open so several items can be toggled.
|
|
256
|
+
- **Search box keyboard:** when the in-dropdown search row has focus, printable
|
|
257
|
+
keys are stopped from reaching Base UI's own typeahead (so they type into the
|
|
258
|
+
box instead of jumping the highlighted item); `Arrow*`/`Home`/`End`/`Enter`/
|
|
259
|
+
`Escape` still bubble, so the user can move from the search box into the
|
|
260
|
+
filtered list and select with the keyboard without leaving it first.
|
|
261
|
+
- **Expander:** `InputSelectExpander` is a plain button with `aria-expanded`
|
|
262
|
+
reflecting its toggle state; it is not a `role="option"` and does not
|
|
263
|
+
register with Base UI's composite list (unlike `SelectPrimitive.Item`), so
|
|
264
|
+
Arrow-key roaming inside the listbox skips it entirely — it cannot be
|
|
265
|
+
reached with the keyboard once the popup is open, only by pointer. It
|
|
266
|
+
remains a normal native tab stop outside that roving focus order.
|
|
267
|
+
- **Selection indicator:** single-select shows a trailing check on the selected item;
|
|
268
|
+
multiple-select shows a leading checkbox per item (not focusable — the row is the
|
|
269
|
+
control).
|
|
270
|
+
- **Focus visible:** keyboard focus paints a 3px ring flush to the trigger —
|
|
271
|
+
`--ui-focus-primary` normally, `--ui-focus-error` while `aria-invalid`.
|
|
272
|
+
- **Disabled:** native `disabled` removes the trigger from the tab order and blocks
|
|
273
|
+
opening; state is not conveyed by color alone (the control is also inert).
|
|
274
|
+
- **Status:** the loading / empty / error row is informational; provide a real message
|
|
275
|
+
and, for errors, a focusable retry control.
|
|
276
|
+
- **Contrast:** label / value / placeholder / border / item pairs come from the design
|
|
277
|
+
tokens, authored to meet WCAG contrast.
|
|
278
|
+
- **WCAG:** 1.3.1, 2.1.1, 2.4.7, 1.4.3 / 1.4.11, 3.3.1 / 3.3.2, 4.1.2.
|