@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,271 @@
1
+ # InputTextArea
2
+
3
+ > A full multiline text field: an optional label (with an optional required marker), a `<textarea>` box that grows with vertical resize, and an optional description or error message. For entering and editing longer free-text (notes, comments, descriptions). Themed by the `--ui-input-text-area-*` token tier.
4
+
5
+ **Status:** ready · **Category:** forms · **Since:** v0.23.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { InputTextArea } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ <InputTextArea
17
+ label="Bio"
18
+ placeholder="Tell us about yourself"
19
+ description="Shown on your profile"
20
+ value={bio}
21
+ onChange={(e) => setBio(e.target.value)}
22
+ />
23
+
24
+ {/* Error */}
25
+ <InputTextArea label="Comment" value={value} error="Must be at least 20 characters" onChange={onChange} />
26
+ ```
27
+
28
+ A multiline text field for entering and editing longer free-text — notes,
29
+ comments, descriptions, and other multi-line content. It grows with vertical
30
+ resize. Pair it with a clear label and, when validation fails, an associated
31
+ error message.
32
+
33
+ ## When to Use
34
+
35
+ - Collect a longer, multi-line value (notes, comments, descriptions, …).
36
+ - Any free-text where line breaks are expected.
37
+
38
+ ## When NOT to Use
39
+
40
+ - **Single short value** (name, email, URL) — use an Input.
41
+ - **Choosing from a fixed set** — use a select / combobox / radio group.
42
+ - **Binary on/off** — use a checkbox or switch.
43
+
44
+ ## States
45
+
46
+ | State | How | Visual |
47
+ | -------- | ------------------------ | ------------------------------------------------------------------- |
48
+ | Idle | default | Idle border, idle fill |
49
+ | Hover | pointer hover | `border-color-hover` + `box-color-hover` |
50
+ | Focus | focus | `border-color-focus` + 3px `--ui-focus-primary` ring |
51
+ | Error | `error` / `aria-invalid` | Red `error-msg-box-border-color-*` border + `--ui-focus-error` ring |
52
+ | Disabled | `disabled` | Faint fill/border, muted text, not interactive |
53
+
54
+ ## Quick Examples
55
+
56
+ ### React
57
+
58
+ ```tsx
59
+ import { InputTextArea } from '@acronis-platform/ui-react';
60
+
61
+ function BioField() {
62
+ const [bio, setBio] = useState('');
63
+ return (
64
+ <InputTextArea
65
+ label="Bio"
66
+ description="Shown on your profile"
67
+ placeholder="Tell us about yourself"
68
+ value={bio}
69
+ onChange={(e) => setBio(e.target.value)}
70
+ />
71
+ );
72
+ }
73
+ ```
74
+
75
+ Error state — `error` switches the field to the error treatment (red border +
76
+ red message replacing the description):
77
+
78
+ ```tsx
79
+ <InputTextArea
80
+ label="Comment"
81
+ value={value}
82
+ error="Comment must be at least 20 characters."
83
+ onChange={onChange}
84
+ />
85
+ ```
86
+
87
+ ## Spec Files
88
+
89
+ | File | Contents |
90
+ | ------------------ | ----------------------------------------------------------- |
91
+ | `index.yaml` | Identity, status, category |
92
+ | `anatomy.yaml` | Root element/role, pseudo + prop states |
93
+ | `api.yaml` | Framework-agnostic contract + framework adapters |
94
+ | `tokens.yaml` | `--ui-input-text-area-*` + focus-ring token references |
95
+ | `behavior.md` | Given/When/Then behavior scenarios |
96
+ | `accessibility.md` | ARIA, keyboard map, screen-reader and contrast requirements |
97
+
98
+ ## Props
99
+
100
+ | Prop | Type | Default | Required | Description |
101
+ |------|------|---------|----------|-------------|
102
+ | `label` | `ReactNode` | — | no | Field label rendered above the textarea, associated via `htmlFor`/`id`. |
103
+ | `required` | `boolean` | `false` | no | Appends a required marker (`*`) after the label and sets `aria-required` on the textarea. |
104
+ | `description` | `ReactNode` | — | no | Helper text below the textarea. Hidden while `error` is set. |
105
+ | `error` | `ReactNode` | — | no | Error message below the textarea. Its presence switches the field to the error treatment (red box border via `aria-invalid`, red message replacing the description). |
106
+ | `placeholder` | `string` | — | no | Example/hint text shown when empty. Not a label substitute. |
107
+ | `value` | `string` | — | no | Controlled value. Pair with the change event. |
108
+ | `default-value` | `string` | — | no | Initial value when uncontrolled. |
109
+ | `rows` | `number` | — | no | Initial visible number of text rows. The field can still grow taller via vertical resize; its minimum height is the `box-height-min` token. |
110
+ | `disabled` | `boolean` | `false` | no | Disables interaction; applies the disabled form tokens. |
111
+ | `name` | `string` | — | no | Form field name submitted with the form. |
112
+ | `aria-invalid` | `boolean` | `false` | no | Marks the textarea invalid directly (an alternative to the `error` prop when the consumer renders its own message). Switches the border to `error-msg-box-border-color-{idle,hover}` and the focus ring to `--ui-focus-error`. |
113
+
114
+ ## Events
115
+
116
+ | Event | Payload | Description |
117
+ |-------|---------|-------------|
118
+ | `change` | `string` | Fired as the value changes (React: native `onChange`). The new value is on `event.target.value`. |
119
+
120
+ ## Content slots
121
+
122
+ | Slot | Description |
123
+ |------|-------------|
124
+ | `label` | The label content. |
125
+ | `description` | The helper text. |
126
+ | `error` | The error message. |
127
+
128
+ ## Behavior
129
+
130
+ ### Rendering
131
+
132
+ #### Renders an empty multiline field
133
+
134
+ **Given** an InputTextArea with no value
135
+ **When** it renders
136
+ **Then** it exposes `role="textbox"` on a native `<textarea>`
137
+ **And** the placeholder (if set) is shown in `--ui-input-text-area-placeholder-color-idle`
138
+ **And** its height is at least `--ui-input-text-area-box-height-min`
139
+
140
+ #### Grows with vertical resize
141
+
142
+ **Given** a rendered InputTextArea
143
+ **When** the user drags the resize handle down
144
+ **Then** the field grows taller (vertical resize only)
145
+ **And** it never shrinks below `--ui-input-text-area-box-height-min`
146
+
147
+ ---
148
+
149
+ ### Interaction
150
+
151
+ #### Accepts typed input
152
+
153
+ **Given** an enabled InputTextArea
154
+ **When** the user types (including line breaks)
155
+ **Then** the value updates
156
+ **And** the change event fires with the new value
157
+
158
+ #### Disabled blocks input
159
+
160
+ **Given** an InputTextArea with `disabled`
161
+ **When** the user attempts to type
162
+ **Then** the value does not change
163
+ **And** the disabled form tokens (faint fill/border, muted text) apply
164
+
165
+ ---
166
+
167
+ ### States
168
+
169
+ #### Hover
170
+
171
+ **Given** an enabled InputTextArea
172
+ **When** the pointer hovers it
173
+ **Then** the border uses `--ui-input-text-area-border-color-hover`
174
+ **And** the fill uses `--ui-input-text-area-box-color-hover`
175
+
176
+ #### Focus
177
+
178
+ **Given** an InputTextArea
179
+ **When** it receives focus
180
+ **Then** the border uses `--ui-input-text-area-border-color-focus`
181
+ **And** a 3px `--ui-focus-primary` ring is shown
182
+
183
+ #### Error (error prop / aria-invalid)
184
+
185
+ **Given** an InputTextArea with `error` set (or `aria-invalid`)
186
+ **When** it renders
187
+ **Then** the box border uses `--ui-input-text-area-error-msg-box-border-color-idle`
188
+ (`-hover` on hover / focus)
189
+ **And** on focus the ring uses `--ui-focus-error` (not the primary ring)
190
+ **And** the `error` message replaces the description below the field, in
191
+ `--ui-input-text-area-error-msg-error-color`
192
+
193
+ #### Label, required, description
194
+
195
+ **Given** a `label` (with optional `required`) and a `description`
196
+ **When** the field renders
197
+ **Then** the label appears above the box (associated via `htmlFor`/`id`), a `*`
198
+ marker follows it when `required`, and the description shows below — associated
199
+ via `aria-describedby`.
200
+
201
+ ---
202
+
203
+ ### Edge Cases
204
+
205
+ #### Placeholder is not a label
206
+
207
+ **Given** an InputTextArea that relies on a placeholder for its name
208
+ **When** reviewed for accessibility
209
+ **Then** it still needs an associated `<label>` / `aria-label` — the
210
+ placeholder is guidance, not a label.
211
+
212
+ #### Controlled vs uncontrolled
213
+
214
+ **Given** an InputTextArea with `value` and a change handler
215
+ **When** the user types
216
+ **Then** the displayed value changes only when the consumer updates `value`
217
+ (uncontrolled fields update themselves via `default-value`).
218
+
219
+ ## Accessibility
220
+
221
+ ## ARIA Roles and Attributes
222
+
223
+ | Attribute | Value | Reason |
224
+ | ------------------- | --------------------------- | -------------------------------------------- |
225
+ | native `<textarea>` | — | Exposes `role="textbox"` (multiline) |
226
+ | `aria-invalid` | `"true"` when invalid | Conveys the error state to assistive tech |
227
+ | `aria-describedby` | id of the error/description | Associates the message text with the field |
228
+ | `aria-disabled` | implied by `disabled` | Disabled fields are skipped in the tab order |
229
+
230
+ **Always provide an accessible name** — the built-in `label` prop (preferred,
231
+ auto-associated via `htmlFor`/`id`) or `aria-label` / `aria-labelledby` for the
232
+ bare usage. The placeholder is **not** a label; it disappears on input and fails
233
+ contrast as a label.
234
+
235
+ ## Keyboard Navigation
236
+
237
+ | Key | Action |
238
+ | ---------- | ------------------------------- |
239
+ | Tab | Moves focus to / from the field |
240
+ | Enter | Inserts a line break (native) |
241
+ | Text keys | Edit the value |
242
+ | Home / End | Move the caret (native) |
243
+
244
+ Disabled fields are removed from the tab order.
245
+
246
+ ## Screen Reader Requirements
247
+
248
+ 1. Announced as a multiline edit/text field with its accessible name.
249
+ 2. Announces the current value (or placeholder when empty).
250
+ 3. When `aria-invalid="true"`, announces "invalid"; the message referenced by
251
+ `aria-describedby` is read.
252
+
253
+ ## Color and Contrast
254
+
255
+ | Element | Minimum Ratio | Standard |
256
+ | -------------------------------- | ------------- | ---------------------- |
257
+ | Value text vs field background | 4.5:1 | WCAG 1.4.3 (AA) |
258
+ | Placeholder text vs background | 4.5:1 | WCAG 1.4.3 (AA) |
259
+ | Border vs surrounding background | 3:1 | WCAG 1.4.11 (non-text) |
260
+ | Focus ring | 3:1 | WCAG 1.4.11 |
261
+
262
+ Error is not signalled by color alone — pair `aria-invalid` with a visible,
263
+ associated error message.
264
+
265
+ ## Testing Checklist
266
+
267
+ - [ ] Has an accessible name (label / `aria-label`)
268
+ - [ ] `aria-invalid="true"` + `aria-describedby` wired for errors
269
+ - [ ] Reachable via Tab; disabled removes it from the tab order
270
+ - [ ] Value / placeholder text meet 4.5:1; border + focus ring meet 3:1
271
+ - [ ] Placeholder is not used as the only label
@@ -0,0 +1,192 @@
1
+ # InputText
2
+
3
+ > A full single-line text field: an optional label (with an optional required marker), the text input box, an optional clear button, and an optional description or error message. Builds on the bare `Input` primitive and the `--ui-input-text-*` token tier.
4
+
5
+ **Status:** ready · **Category:** forms · **Since:** v0.26.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { InputText } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ <InputText label="Email" placeholder="you@example.com" description="We never share it" />
17
+
18
+ {/* Error */}
19
+ <InputText label="Email" value={value} error="Enter a valid email" onChange={onChange} />
20
+
21
+ {/* Clearable (controlled) */}
22
+ <InputText
23
+ label="Search"
24
+ value={value}
25
+ clearable
26
+ onChange={onChange}
27
+ onClear={() => setValue('')}
28
+ />
29
+ ```
30
+
31
+ A full single-line text field: a label, the input box, an optional clear button,
32
+ and an optional description or error message. It composes the bare
33
+ [`Input`](../input/README.md) primitive and adds the surrounding field furniture.
34
+
35
+ ## When to use
36
+
37
+ - Any labelled single-line text entry in a form (email, name, search term…).
38
+ - When you need built-in label / description / error wiring and an optional clear
39
+ affordance.
40
+
41
+ ## When not to use
42
+
43
+ - For a bare input with no label/description (e.g. inside a custom layout) — use
44
+ the `Input` primitive directly.
45
+ - For multi-line text — use `InputTextArea`.
46
+ - For a search field with a leading icon — use `Search`.
47
+
48
+ ## Examples
49
+
50
+ ```tsx
51
+ import { InputText } from '@acronis-platform/ui-react';
52
+
53
+ // Basic field with helper text
54
+ <InputText
55
+ label="Email"
56
+ placeholder="you@example.com"
57
+ description="We never share it"
58
+ />;
59
+
60
+ // Required
61
+ <InputText label="Email" required />;
62
+
63
+ // Error
64
+ <InputText
65
+ label="Email"
66
+ value={value}
67
+ error="Enter a valid email"
68
+ onChange={onChange}
69
+ />;
70
+
71
+ // Clearable (controlled)
72
+ <InputText
73
+ label="Search"
74
+ value={value}
75
+ clearable
76
+ onChange={(e) => setValue(e.target.value)}
77
+ onClear={() => setValue('')}
78
+ />;
79
+ ```
80
+
81
+ ## Parts
82
+
83
+ | Part | Element | Description |
84
+ | ------------- | ---------- | ----------------------------------------------------- |
85
+ | `label` | `<label>` | Field label (associated via `htmlFor`/`id`). |
86
+ | `required` | `<span>` | Required `*` marker (decorative; `aria-hidden`). |
87
+ | `input` | `<input>` | The text box (the `Input` primitive). |
88
+ | `clear` | `<button>` | Optional clear (✕) button; calls `onClear`. |
89
+ | `description` | `<p>` | Helper text (normal state). |
90
+ | `error` | `<p>` | Error message; replaces the description when `error`. |
91
+
92
+ ## Props
93
+
94
+ | Prop | Type | Default | Required | Description |
95
+ |------|------|---------|----------|-------------|
96
+ | `label` | `ReactNode` | — | no | Field label rendered above the input, associated via `htmlFor`/`id`. |
97
+ | `required` | `boolean` | `false` | no | Appends a required marker (`*`) after the label and sets `aria-required` on the input. |
98
+ | `description` | `ReactNode` | — | no | Helper text below the input. Hidden while `error` is set. |
99
+ | `error` | `ReactNode` | — | no | Error message below the input. Its presence switches the field to the error treatment (red box border via `aria-invalid`, red message replacing the description). |
100
+ | `clearable` | `boolean` | `false` | no | Show a clear (✕) button while the (controlled) field has a value. |
101
+ | `disabled` | `boolean` | `false` | no | Disables the field (native `<input disabled>`). |
102
+ | `value` | `string` | — | no | Controlled value. Required for the clear button to appear. |
103
+
104
+ ## Events
105
+
106
+ | Event | Payload | Description |
107
+ |-------|---------|-------------|
108
+ | `change` | `ChangeEvent<HTMLInputElement>` | Native input change — forwarded to the underlying `<input>`. |
109
+ | `clear` | `void` | Fired when the clear (✕) button is activated. |
110
+
111
+ ## Content slots
112
+
113
+ | Slot | Description |
114
+ |------|-------------|
115
+ | `label` | The label content. |
116
+ | `description` | The helper text. |
117
+ | `error` | The error message. |
118
+
119
+ ## Behavior
120
+
121
+ ### Rendering
122
+
123
+ **Given** a `label`
124
+ **When** the field renders
125
+ **Then** the label appears above the input and is associated with it via
126
+ `htmlFor`/`id` (clicking the label focuses the input).
127
+
128
+ **Given** `required`
129
+ **When** the field renders
130
+ **Then** a `*` marker is appended after the label and the input gets
131
+ `aria-required="true"`.
132
+
133
+ **Given** a `description`
134
+ **When** no `error` is set
135
+ **Then** the helper text shows below the input, associated via `aria-describedby`.
136
+
137
+ ### Error
138
+
139
+ **Given** `error` is set
140
+ **When** the field renders
141
+ **Then** the input shows the error border (via `aria-invalid`), the error message
142
+ replaces the description below the input, and the message is associated via
143
+ `aria-describedby`.
144
+
145
+ ### Clear
146
+
147
+ **Given** `clearable` and a non-empty (controlled) `value`
148
+ **When** the field is not disabled
149
+ **Then** a clear (✕) button appears inside the box.
150
+
151
+ **Given** the clear button
152
+ **When** it is activated (click, Enter, or Space)
153
+ **Then** `onClear` fires (the consumer clears the value).
154
+
155
+ **Given** the field is `disabled`
156
+ **Then** the clear button is not shown.
157
+
158
+ ### Interaction
159
+
160
+ **Given** the input
161
+ **When** the pointer hovers / it receives keyboard focus
162
+ **Then** the box border shifts to its hover token and keyboard focus paints a 3px
163
+ ring — `--ui-focus-primary` normally, `--ui-focus-error` while in the error state.
164
+
165
+ **Given** any typing
166
+ **When** the value changes
167
+ **Then** the native `change` event is forwarded to the consumer.
168
+
169
+ ## Accessibility
170
+
171
+ - **Label association:** the `label` is a real `<label htmlFor>` tied to the
172
+ input's `id` (auto-generated when not supplied), so clicking it focuses the
173
+ input and screen readers announce the field name.
174
+ - **Required:** `required` sets `aria-required="true"` on the input; the visual `*`
175
+ marker is `aria-hidden` (the asterisk is decorative — the required semantics come
176
+ from the attribute).
177
+ - **Description / error:** whichever message is shown is linked to the input via
178
+ `aria-describedby`, so it is announced with the field. The error message also
179
+ drives `aria-invalid="true"` on the input.
180
+ - **Clear button:** a native `<button>` with `aria-label="Clear"`; reachable by Tab
181
+ and activated by Enter / Space.
182
+ - **Keyboard:** the input is a native text field; the clear button is a separate tab
183
+ stop after it.
184
+ - **Focus visible:** keyboard focus paints a 3px ring — `--ui-focus-primary` normally
185
+ and `--ui-focus-error` in the error state — flush to the box; the clear button has
186
+ its own focus ring.
187
+ - **Disabled:** native `disabled` removes the input (and clear button) from the tab
188
+ order; not used to convey state by color alone (the field is also inert).
189
+ - **Contrast:** label / value / placeholder / message / border pairs come from the
190
+ design tokens, authored to meet WCAG contrast.
191
+ - **WCAG:** 1.3.1 (info/relationships), 2.1.1 (keyboard), 2.4.7 (focus visible),
192
+ 1.4.3 / 1.4.11 (contrast), 3.3.1 / 3.3.2 (error identification + labels), 4.1.2.