@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.
Files changed (219) hide show
  1. package/dist/components/ui/accordion-container/accordion-container.js +14 -14
  2. package/dist/components/ui/accordion-container/accordion-container.js.map +1 -1
  3. package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
  4. package/dist/components/ui/area-chart/area-chart.js +141 -139
  5. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  6. package/dist/components/ui/bar-chart/bar-chart.js +295 -293
  7. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  8. package/dist/components/ui/category-bar/category-bar.js +109 -93
  9. package/dist/components/ui/category-bar/category-bar.js.map +1 -1
  10. package/dist/components/ui/chart/chart-palette.js +113 -0
  11. package/dist/components/ui/chart/chart-palette.js.map +1 -0
  12. package/dist/components/ui/chart/chart.js +176 -129
  13. package/dist/components/ui/chart/chart.js.map +1 -1
  14. package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
  15. package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
  16. package/dist/components/ui/chart-state/chart-state.js +48 -34
  17. package/dist/components/ui/chart-state/chart-state.js.map +1 -1
  18. package/dist/components/ui/chart-widget/chart-widget.js +87 -0
  19. package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
  20. package/dist/components/ui/composed-chart/composed-chart.js +117 -115
  21. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
  22. package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
  23. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
  24. package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
  25. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
  26. package/dist/components/ui/histogram/histogram.js +94 -92
  27. package/dist/components/ui/histogram/histogram.js.map +1 -1
  28. package/dist/components/ui/input/input.js.map +1 -1
  29. package/dist/components/ui/label/label.js +2 -9
  30. package/dist/components/ui/label/label.js.map +1 -1
  31. package/dist/components/ui/line-chart/line-chart.js +143 -141
  32. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  33. package/dist/components/ui/metric/metric.js +74 -185
  34. package/dist/components/ui/metric/metric.js.map +1 -1
  35. package/dist/components/ui/page-content/page-content.js.map +1 -1
  36. package/dist/components/ui/pie-chart/pie-chart.js +201 -195
  37. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
  38. package/dist/components/ui/radar-chart/radar-chart.js +133 -131
  39. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
  40. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
  41. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
  42. package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
  43. package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
  44. package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
  45. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  46. package/dist/components/ui/section/section.js +157 -31
  47. package/dist/components/ui/section/section.js.map +1 -1
  48. package/dist/components/ui/stepper/stepper.js +24 -24
  49. package/dist/components/ui/stepper/stepper.js.map +1 -1
  50. package/dist/components/ui/stepper-item/stepper-item.js +43 -24
  51. package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
  52. package/dist/components/ui/treemap/treemap.js +133 -124
  53. package/dist/components/ui/treemap/treemap.js.map +1 -1
  54. package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
  55. package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
  56. package/dist/components/ui/wizard/wizard.js +59 -0
  57. package/dist/components/ui/wizard/wizard.js.map +1 -0
  58. package/dist/hooks/use-wizard.js +75 -0
  59. package/dist/hooks/use-wizard.js.map +1 -0
  60. package/dist/index.js +502 -497
  61. package/dist/index.js.map +1 -1
  62. package/dist/llms/accordion-container.md +181 -0
  63. package/dist/llms/accordion.md +124 -0
  64. package/dist/llms/alert.md +225 -0
  65. package/dist/llms/app-shell-chat.md +415 -0
  66. package/dist/llms/area-chart.md +355 -0
  67. package/dist/llms/avatar.md +208 -0
  68. package/dist/llms/bar-chart.md +406 -0
  69. package/dist/llms/breadcrumb.md +326 -0
  70. package/dist/llms/button-group.md +298 -0
  71. package/dist/llms/button-icon-input.md +142 -0
  72. package/dist/llms/button-icon-menu.md +209 -0
  73. package/dist/llms/button-icon.md +128 -0
  74. package/dist/llms/button-menu.md +172 -0
  75. package/dist/llms/button.md +185 -0
  76. package/dist/llms/calendar-panel.md +733 -0
  77. package/dist/llms/calendar.md +188 -0
  78. package/dist/llms/card-filter.md +214 -0
  79. package/dist/llms/card-section.md +293 -0
  80. package/dist/llms/card.md +447 -0
  81. package/dist/llms/carousel-dialog.md +156 -0
  82. package/dist/llms/category-bar.md +193 -0
  83. package/dist/llms/chart-state.md +190 -0
  84. package/dist/llms/chart-widget.md +209 -0
  85. package/dist/llms/chart.md +182 -0
  86. package/dist/llms/checkbox.md +257 -0
  87. package/dist/llms/chip.md +195 -0
  88. package/dist/llms/combobox.md +164 -0
  89. package/dist/llms/composed-chart.md +508 -0
  90. package/dist/llms/confidence-cone.md +277 -0
  91. package/dist/llms/data-table.md +474 -0
  92. package/dist/llms/date-range-picker.md +272 -0
  93. package/dist/llms/description-list.md +131 -0
  94. package/dist/llms/dialog-footer-carousel.md +147 -0
  95. package/dist/llms/dialog-footer-default.md +142 -0
  96. package/dist/llms/dialog-root.md +246 -0
  97. package/dist/llms/dialog-welcome.md +223 -0
  98. package/dist/llms/dialog.md +403 -0
  99. package/dist/llms/dropdown-menu.md +193 -0
  100. package/dist/llms/empty-overlay.md +146 -0
  101. package/dist/llms/empty.md +156 -0
  102. package/dist/llms/field.md +185 -0
  103. package/dist/llms/filter-cards.md +157 -0
  104. package/dist/llms/filter-chips.md +323 -0
  105. package/dist/llms/filter-search.md +512 -0
  106. package/dist/llms/form.md +154 -0
  107. package/dist/llms/funnel-chart.md +333 -0
  108. package/dist/llms/grid.md +80 -0
  109. package/dist/llms/histogram.md +190 -0
  110. package/dist/llms/input-date-picker.md +203 -0
  111. package/dist/llms/input-otp.md +173 -0
  112. package/dist/llms/input-password.md +197 -0
  113. package/dist/llms/input-search.md +170 -0
  114. package/dist/llms/input-select.md +278 -0
  115. package/dist/llms/input-text-area.md +271 -0
  116. package/dist/llms/input-text.md +192 -0
  117. package/dist/llms/line-chart.md +369 -0
  118. package/dist/llms/link.md +209 -0
  119. package/dist/llms/loading.md +130 -0
  120. package/dist/llms/meter.md +177 -0
  121. package/dist/llms/metric.md +204 -0
  122. package/dist/llms/number-field.md +122 -0
  123. package/dist/llms/page-content.md +69 -0
  124. package/dist/llms/page-header.md +182 -0
  125. package/dist/llms/pagination.md +133 -0
  126. package/dist/llms/pie-chart.md +307 -0
  127. package/dist/llms/popover.md +252 -0
  128. package/dist/llms/progress-circle.md +126 -0
  129. package/dist/llms/progress.md +111 -0
  130. package/dist/llms/radar-chart.md +316 -0
  131. package/dist/llms/radial-bar-chart.md +319 -0
  132. package/dist/llms/radio.md +255 -0
  133. package/dist/llms/resizable.md +195 -0
  134. package/dist/llms/sankey-chart.md +208 -0
  135. package/dist/llms/scatter-chart.md +239 -0
  136. package/dist/llms/scroll-area.md +183 -0
  137. package/dist/llms/section.md +401 -0
  138. package/dist/llms/select.md +210 -0
  139. package/dist/llms/separator.md +87 -0
  140. package/dist/llms/sheet.md +202 -0
  141. package/dist/llms/sidebar-primary.md +360 -0
  142. package/dist/llms/sidebar-secondary.md +417 -0
  143. package/dist/llms/skeleton.md +81 -0
  144. package/dist/llms/slider.md +97 -0
  145. package/dist/llms/spinner.md +100 -0
  146. package/dist/llms/stack.md +80 -0
  147. package/dist/llms/stepper-item.md +309 -0
  148. package/dist/llms/stepper.md +251 -0
  149. package/dist/llms/switch.md +140 -0
  150. package/dist/llms/table.md +436 -0
  151. package/dist/llms/tabs.md +197 -0
  152. package/dist/llms/tag.md +139 -0
  153. package/dist/llms/timeline.md +361 -0
  154. package/dist/llms/timer.md +259 -0
  155. package/dist/llms/toast.md +241 -0
  156. package/dist/llms/toggle-group.md +121 -0
  157. package/dist/llms/toolbar.md +453 -0
  158. package/dist/llms/tooltip.md +164 -0
  159. package/dist/llms/treemap.md +254 -0
  160. package/dist/llms/trend-indicator.md +132 -0
  161. package/dist/llms/widget-placeholder.md +169 -0
  162. package/dist/llms/wizard.md +412 -0
  163. package/dist/llms.txt +142 -0
  164. package/dist/react.js +502 -497
  165. package/dist/react.js.map +1 -1
  166. package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
  167. package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
  168. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
  169. package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
  170. package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
  171. package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
  172. package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
  173. package/dist/src/components/ui/chart/chart.d.ts +66 -15
  174. package/dist/src/components/ui/chart/index.d.ts +4 -2
  175. package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
  176. package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
  177. package/dist/src/components/ui/chart-state/index.d.ts +1 -0
  178. package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
  179. package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
  180. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
  181. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
  182. package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +1 -1
  183. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
  184. package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
  185. package/dist/src/components/ui/label/index.d.ts +1 -1
  186. package/dist/src/components/ui/label/label.d.ts +1 -5
  187. package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
  188. package/dist/src/components/ui/metric/metric.d.ts +13 -14
  189. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
  190. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
  191. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
  192. package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
  193. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
  194. package/dist/src/components/ui/section/index.d.ts +1 -1
  195. package/dist/src/components/ui/section/section.d.ts +75 -6
  196. package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
  197. package/dist/src/components/ui/tag/tag.d.ts +1 -1
  198. package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
  199. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
  200. package/dist/src/components/ui/wizard/index.d.ts +1 -0
  201. package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
  202. package/dist/src/hooks/index.d.ts +1 -0
  203. package/dist/src/hooks/use-wizard.d.ts +80 -0
  204. package/dist/src/index.d.ts +2 -3
  205. package/dist/ui-react.css +1 -1
  206. package/package.json +9 -3
  207. package/dist/components/ui/app-shell/app-shell.js +0 -75
  208. package/dist/components/ui/app-shell/app-shell.js.map +0 -1
  209. package/dist/components/ui/auth-layout/auth-layout.js +0 -56
  210. package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
  211. package/dist/components/ui/collapsible/collapsible.js +0 -22
  212. package/dist/components/ui/collapsible/collapsible.js.map +0 -1
  213. package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
  214. package/dist/src/components/ui/app-shell/index.d.ts +0 -1
  215. package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
  216. package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
  217. package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
  218. package/dist/src/components/ui/collapsible/index.d.ts +0 -1
  219. 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.