@bspk/ui 1.3.20 → 1.3.22

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 (290) hide show
  1. package/dist/components/Accordion/Accordion.js +1 -1
  2. package/dist/components/Accordion/Accordion.js.map +1 -1
  3. package/dist/components/Accordion/accordion.css +19 -12
  4. package/dist/components/Accordion/accordion.css.js +19 -12
  5. package/dist/components/BottomNavigation/BottomNavigation.d.ts +0 -1
  6. package/dist/components/BottomNavigation/BottomNavigation.js +0 -1
  7. package/dist/components/BottomNavigation/BottomNavigation.js.map +1 -1
  8. package/dist/components/BottomNavigation/bottom-navigation.css +1 -0
  9. package/dist/components/BottomNavigation/bottom-navigation.css.js +1 -0
  10. package/dist/components/Button/button.css +4 -0
  11. package/dist/components/Button/button.css.js +4 -0
  12. package/dist/components/Checkbox/Checkbox.js +3 -3
  13. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  14. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +4 -5
  15. package/dist/components/CheckboxGroup/CheckboxGroup.js +8 -13
  16. package/dist/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
  17. package/dist/components/CheckboxGroup/CheckboxGroupExample.js +5 -0
  18. package/dist/components/CheckboxGroup/CheckboxGroupExample.js.map +1 -1
  19. package/dist/components/CheckboxGroup/checkbox-group.css +2 -0
  20. package/dist/components/CheckboxGroup/checkbox-group.css.js +2 -0
  21. package/dist/components/CheckboxGroupField/CheckboxGroupField.d.ts +3 -3
  22. package/dist/components/CheckboxGroupField/CheckboxGroupField.js +6 -4
  23. package/dist/components/CheckboxGroupField/CheckboxGroupField.js.map +1 -1
  24. package/dist/components/ChipGroup/ChipGroup.d.ts +0 -1
  25. package/dist/components/ChipGroup/ChipGroup.js +0 -1
  26. package/dist/components/ChipGroup/ChipGroup.js.map +1 -1
  27. package/dist/components/ChipGroup/chip-group.css +3 -0
  28. package/dist/components/ChipGroup/chip-group.css.js +3 -0
  29. package/dist/components/DatePicker/DatePicker.d.ts +4 -8
  30. package/dist/components/DatePicker/DatePicker.js +6 -18
  31. package/dist/components/DatePicker/DatePicker.js.map +1 -1
  32. package/dist/components/DatePicker/DatePickerExample.js +3 -3
  33. package/dist/components/DatePicker/DatePickerExample.js.map +1 -1
  34. package/dist/components/DatePickerField/DatePickerField.d.ts +4 -4
  35. package/dist/components/DatePickerField/DatePickerField.js +6 -4
  36. package/dist/components/DatePickerField/DatePickerField.js.map +1 -1
  37. package/dist/components/Dialog/Dialog.d.ts +2 -3
  38. package/dist/components/Dialog/Dialog.js +2 -3
  39. package/dist/components/Dialog/Dialog.js.map +1 -1
  40. package/dist/components/Fab/Fab.d.ts +8 -5
  41. package/dist/components/Fab/Fab.js +8 -5
  42. package/dist/components/Fab/Fab.js.map +1 -1
  43. package/dist/components/Fab/fab.css +1 -0
  44. package/dist/components/Fab/fab.css.js +1 -0
  45. package/dist/components/Field/Field.d.ts +32 -18
  46. package/dist/components/Field/Field.js +8 -38
  47. package/dist/components/Field/Field.js.map +1 -1
  48. package/dist/components/Field/FieldExample.d.ts +1 -0
  49. package/dist/components/Field/FieldExample.js +10 -3
  50. package/dist/components/Field/FieldExample.js.map +1 -1
  51. package/dist/components/Field/Fieldset.d.ts +40 -0
  52. package/dist/components/Field/Fieldset.js +44 -0
  53. package/dist/components/Field/Fieldset.js.map +1 -0
  54. package/dist/components/Field/field.css +5 -7
  55. package/dist/components/Field/field.css.js +5 -7
  56. package/dist/components/Field/index.d.ts +1 -3
  57. package/dist/components/Field/index.js +1 -3
  58. package/dist/components/Field/index.js.map +1 -1
  59. package/dist/components/Field/utils.d.ts +8 -38
  60. package/dist/components/Field/utils.js +6 -33
  61. package/dist/components/Field/utils.js.map +1 -1
  62. package/dist/components/FileUpload/FileUpload.js +1 -1
  63. package/dist/components/FileUpload/FileUpload.js.map +1 -1
  64. package/dist/components/FileUploadItem/FileUploadItem.js +1 -1
  65. package/dist/components/FileUploadItem/FileUploadItem.js.map +1 -1
  66. package/dist/components/Flex/Flex.d.ts +11 -7
  67. package/dist/components/Flex/Flex.js +12 -8
  68. package/dist/components/Flex/Flex.js.map +1 -1
  69. package/dist/components/InlineAlert/InlineAlert.d.ts +2 -2
  70. package/dist/components/InlineAlert/InlineAlert.js +2 -2
  71. package/dist/components/InlineAlert/InlineAlert.js.map +1 -1
  72. package/dist/components/Input/Input.d.ts +60 -15
  73. package/dist/components/Input/Input.js +42 -25
  74. package/dist/components/Input/Input.js.map +1 -1
  75. package/dist/components/Input/InputExample.js +4 -4
  76. package/dist/components/Input/InputExample.js.map +1 -1
  77. package/dist/components/Input/index.d.ts +0 -1
  78. package/dist/components/Input/index.js +0 -1
  79. package/dist/components/Input/index.js.map +1 -1
  80. package/dist/components/InputField/InputField.d.ts +4 -4
  81. package/dist/components/InputField/InputField.js +6 -4
  82. package/dist/components/InputField/InputField.js.map +1 -1
  83. package/dist/components/InputNumber/InputNumber.d.ts +8 -7
  84. package/dist/components/InputNumber/InputNumber.js +9 -16
  85. package/dist/components/InputNumber/InputNumber.js.map +1 -1
  86. package/dist/components/InputNumber/InputNumberExample.js +3 -3
  87. package/dist/components/InputNumber/InputNumberExample.js.map +1 -1
  88. package/dist/components/InputNumber/input-number.css +1 -0
  89. package/dist/components/InputNumber/input-number.css.js +1 -0
  90. package/dist/components/InputNumberField/InputNumberField.d.ts +4 -4
  91. package/dist/components/InputNumberField/InputNumberField.js +6 -4
  92. package/dist/components/InputNumberField/InputNumberField.js.map +1 -1
  93. package/dist/components/InputPhone/InputPhone.d.ts +8 -8
  94. package/dist/components/InputPhone/InputPhone.js +12 -18
  95. package/dist/components/InputPhone/InputPhone.js.map +1 -1
  96. package/dist/components/InputPhone/InputPhoneExample.js +3 -3
  97. package/dist/components/InputPhone/InputPhoneExample.js.map +1 -1
  98. package/dist/components/InputPhone/input-phone.css +1 -0
  99. package/dist/components/InputPhone/input-phone.css.js +1 -0
  100. package/dist/components/InputPhoneField/InputPhoneField.d.ts +4 -4
  101. package/dist/components/InputPhoneField/InputPhoneField.js +6 -4
  102. package/dist/components/InputPhoneField/InputPhoneField.js.map +1 -1
  103. package/dist/components/ListItem/list-item.css +1 -0
  104. package/dist/components/ListItem/list-item.css.js +1 -0
  105. package/dist/components/Modal/Modal.js +22 -26
  106. package/dist/components/Modal/Modal.js.map +1 -1
  107. package/dist/components/Modal/ModalExample.js +4 -1
  108. package/dist/components/Modal/ModalExample.js.map +1 -1
  109. package/dist/components/Modal/modal.css +4 -2
  110. package/dist/components/Modal/modal.css.js +4 -2
  111. package/dist/components/OTPInput/otp-input.css +1 -0
  112. package/dist/components/OTPInput/otp-input.css.js +1 -0
  113. package/dist/components/Pagination/Pagination.js +2 -2
  114. package/dist/components/Pagination/Pagination.js.map +1 -1
  115. package/dist/components/Password/Password.d.ts +9 -7
  116. package/dist/components/Password/Password.js +13 -17
  117. package/dist/components/Password/Password.js.map +1 -1
  118. package/dist/components/Password/PasswordExample.js +3 -3
  119. package/dist/components/Password/PasswordExample.js.map +1 -1
  120. package/dist/components/PasswordField/PasswordField.d.ts +4 -4
  121. package/dist/components/PasswordField/PasswordField.js +6 -4
  122. package/dist/components/PasswordField/PasswordField.js.map +1 -1
  123. package/dist/components/Popover/Popover.d.ts +0 -1
  124. package/dist/components/Popover/Popover.js +0 -1
  125. package/dist/components/Popover/Popover.js.map +1 -1
  126. package/dist/components/RadioGroup/RadioGroup.d.ts +1 -2
  127. package/dist/components/RadioGroup/RadioGroup.js +5 -11
  128. package/dist/components/RadioGroup/RadioGroup.js.map +1 -1
  129. package/dist/components/RadioGroupField/RadioGroupField.d.ts +3 -3
  130. package/dist/components/RadioGroupField/RadioGroupField.js +6 -4
  131. package/dist/components/RadioGroupField/RadioGroupField.js.map +1 -1
  132. package/dist/components/SearchBar/SearchBar.d.ts +0 -1
  133. package/dist/components/SearchBar/SearchBar.js +0 -1
  134. package/dist/components/SearchBar/SearchBar.js.map +1 -1
  135. package/dist/components/SegmentedControl/SegmentedControl.d.ts +0 -1
  136. package/dist/components/SegmentedControl/SegmentedControl.js +0 -1
  137. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  138. package/dist/components/Select/Select.d.ts +7 -6
  139. package/dist/components/Select/Select.js +10 -15
  140. package/dist/components/Select/Select.js.map +1 -1
  141. package/dist/components/Select/SelectExample.js +3 -3
  142. package/dist/components/Select/SelectExample.js.map +1 -1
  143. package/dist/components/SelectField/SelectField.d.ts +4 -4
  144. package/dist/components/SelectField/SelectField.js +6 -4
  145. package/dist/components/SelectField/SelectField.js.map +1 -1
  146. package/dist/components/Slider/Slider.d.ts +1 -2
  147. package/dist/components/Slider/Slider.js +1 -2
  148. package/dist/components/Slider/Slider.js.map +1 -1
  149. package/dist/components/Snackbar/Snackbar.d.ts +0 -1
  150. package/dist/components/Snackbar/Snackbar.js +0 -1
  151. package/dist/components/Snackbar/Snackbar.js.map +1 -1
  152. package/dist/components/Switch/Switch.d.ts +0 -1
  153. package/dist/components/Switch/Switch.js +0 -1
  154. package/dist/components/Switch/Switch.js.map +1 -1
  155. package/dist/components/TabGroup/TabGroup.d.ts +0 -1
  156. package/dist/components/TabGroup/TabGroup.js +0 -1
  157. package/dist/components/TabGroup/TabGroup.js.map +1 -1
  158. package/dist/components/TabList/TabList.d.ts +0 -1
  159. package/dist/components/TabList/TabList.js +0 -1
  160. package/dist/components/TabList/TabList.js.map +1 -1
  161. package/dist/components/TabList/tab-list.css +1 -0
  162. package/dist/components/TabList/tab-list.css.js +1 -0
  163. package/dist/components/Table/table.css +2 -1
  164. package/dist/components/Table/table.css.js +2 -1
  165. package/dist/components/Textarea/Textarea.d.ts +4 -7
  166. package/dist/components/Textarea/Textarea.js +5 -16
  167. package/dist/components/Textarea/Textarea.js.map +1 -1
  168. package/dist/components/Textarea/TextareaExample.js +3 -3
  169. package/dist/components/Textarea/TextareaExample.js.map +1 -1
  170. package/dist/components/TextareaField/TextareaField.d.ts +4 -4
  171. package/dist/components/TextareaField/TextareaField.js +6 -4
  172. package/dist/components/TextareaField/TextareaField.js.map +1 -1
  173. package/dist/components/TimePicker/TimePicker.d.ts +8 -6
  174. package/dist/components/TimePicker/TimePicker.js +10 -14
  175. package/dist/components/TimePicker/TimePicker.js.map +1 -1
  176. package/dist/components/TimePicker/TimePickerExample.js +3 -3
  177. package/dist/components/TimePicker/TimePickerExample.js.map +1 -1
  178. package/dist/components/TimePickerField/TimePickerField.d.ts +4 -4
  179. package/dist/components/TimePickerField/TimePickerField.js +6 -4
  180. package/dist/components/TimePickerField/TimePickerField.js.map +1 -1
  181. package/dist/types/common.d.ts +2 -0
  182. package/dist/types/common.js.map +1 -1
  183. package/dist/utils/demo.js +1 -1
  184. package/dist/utils/demo.js.map +1 -1
  185. package/package.json +3 -4
  186. package/src/components/Accordion/Accordion.tsx +2 -2
  187. package/src/components/Accordion/accordion.scss +10 -1
  188. package/src/components/BottomNavigation/BottomNavigation.tsx +0 -1
  189. package/src/components/BottomNavigation/bottom-navigation.scss +1 -0
  190. package/src/components/Button/button.scss +4 -0
  191. package/src/components/Checkbox/Checkbox.tsx +3 -3
  192. package/src/components/CheckboxGroup/CheckboxGroup.tsx +37 -52
  193. package/src/components/CheckboxGroup/CheckboxGroupExample.tsx +6 -0
  194. package/src/components/CheckboxGroup/checkbox-group.scss +2 -0
  195. package/src/components/CheckboxGroupField/CheckboxGroupField.tsx +15 -11
  196. package/src/components/ChipGroup/ChipGroup.tsx +0 -1
  197. package/src/components/ChipGroup/chip-group.scss +4 -0
  198. package/src/components/DatePicker/DatePicker.tsx +9 -20
  199. package/src/components/DatePicker/DatePickerExample.tsx +3 -5
  200. package/src/components/DatePickerField/DatePickerField.rtl.test.tsx +1 -1
  201. package/src/components/DatePickerField/DatePickerField.tsx +10 -6
  202. package/src/components/Dialog/Dialog.tsx +2 -3
  203. package/src/components/Fab/Fab.tsx +8 -5
  204. package/src/components/Fab/fab.scss +1 -0
  205. package/src/components/Field/Field.rtl.test.tsx +8 -6
  206. package/src/components/Field/Field.tsx +64 -61
  207. package/src/components/Field/FieldExample.tsx +27 -5
  208. package/src/components/Field/Fieldset.tsx +78 -0
  209. package/src/components/Field/field.scss +23 -27
  210. package/src/components/Field/index.tsx +1 -3
  211. package/src/components/Field/utils.ts +15 -77
  212. package/src/components/FileUpload/FileUpload.tsx +1 -1
  213. package/src/components/FileUploadItem/FileUploadItem.tsx +1 -1
  214. package/src/components/Flex/Flex.tsx +12 -7
  215. package/src/components/InlineAlert/InlineAlert.rtl.test.tsx +1 -1
  216. package/src/components/InlineAlert/InlineAlert.tsx +3 -3
  217. package/src/components/Input/Input.tsx +140 -48
  218. package/src/components/Input/InputExample.tsx +4 -6
  219. package/src/components/Input/index.tsx +0 -1
  220. package/src/components/InputField/InputField.tsx +10 -6
  221. package/src/components/InputNumber/InputNumber.tsx +11 -16
  222. package/src/components/InputNumber/InputNumberExample.tsx +7 -4
  223. package/src/components/InputNumber/input-number.scss +1 -0
  224. package/src/components/InputNumberField/InputNumberField.tsx +10 -6
  225. package/src/components/InputPhone/InputPhone.tsx +14 -18
  226. package/src/components/InputPhone/InputPhoneExample.tsx +7 -6
  227. package/src/components/InputPhone/input-phone.scss +1 -0
  228. package/src/components/InputPhoneField/InputPhoneField.tsx +10 -6
  229. package/src/components/ListItem/list-item.scss +1 -0
  230. package/src/components/Modal/Modal.tsx +26 -30
  231. package/src/components/Modal/ModalExample.tsx +7 -2
  232. package/src/components/Modal/modal.scss +1 -1
  233. package/src/components/OTPInput/otp-input.scss +1 -0
  234. package/src/components/Pagination/Pagination.tsx +2 -2
  235. package/src/components/Password/Password.tsx +15 -17
  236. package/src/components/Password/PasswordExample.tsx +13 -5
  237. package/src/components/PasswordField/PasswordField.tsx +10 -6
  238. package/src/components/Popover/Popover.tsx +0 -1
  239. package/src/components/RadioGroup/RadioGroup.tsx +14 -20
  240. package/src/components/RadioGroupField/RadioGroupField.tsx +16 -11
  241. package/src/components/SearchBar/SearchBar.tsx +0 -1
  242. package/src/components/SegmentedControl/SegmentedControl.tsx +0 -1
  243. package/src/components/Select/Select.tsx +13 -14
  244. package/src/components/Select/SelectExample.tsx +7 -4
  245. package/src/components/SelectField/SelectField.rtl.test.tsx +7 -18
  246. package/src/components/SelectField/SelectField.tsx +10 -6
  247. package/src/components/Slider/Slider.tsx +1 -2
  248. package/src/components/Snackbar/Snackbar.tsx +0 -1
  249. package/src/components/Switch/Switch.tsx +0 -1
  250. package/src/components/TabGroup/TabGroup.tsx +0 -1
  251. package/src/components/TabList/TabList.tsx +0 -1
  252. package/src/components/TabList/tab-list.scss +1 -0
  253. package/src/components/Table/table.scss +2 -1
  254. package/src/components/Textarea/Textarea.tsx +8 -17
  255. package/src/components/Textarea/TextareaExample.tsx +3 -5
  256. package/src/components/TextareaField/TextareaField.tsx +10 -6
  257. package/src/components/TimePicker/TimePicker.tsx +12 -15
  258. package/src/components/TimePicker/TimePickerExample.tsx +3 -5
  259. package/src/components/TimePickerField/TimePickerField.tsx +10 -6
  260. package/src/types/common.ts +8 -0
  261. package/src/utils/demo.ts +1 -1
  262. package/dist/components/Field/FieldDescription.d.ts +0 -9
  263. package/dist/components/Field/FieldDescription.js +0 -13
  264. package/dist/components/Field/FieldDescription.js.map +0 -1
  265. package/dist/components/Field/FieldError.d.ts +0 -11
  266. package/dist/components/Field/FieldError.js +0 -14
  267. package/dist/components/Field/FieldError.js.map +0 -1
  268. package/dist/components/Field/FieldLabel.d.ts +0 -21
  269. package/dist/components/Field/FieldLabel.js +0 -14
  270. package/dist/components/Field/FieldLabel.js.map +0 -1
  271. package/dist/components/FormField/FormField.d.ts +0 -66
  272. package/dist/components/FormField/FormField.js +0 -31
  273. package/dist/components/FormField/FormField.js.map +0 -1
  274. package/dist/components/FormField/FormFieldExample.d.ts +0 -9
  275. package/dist/components/FormField/FormFieldExample.js +0 -99
  276. package/dist/components/FormField/FormFieldExample.js.map +0 -1
  277. package/dist/components/FormField/index.d.ts +0 -1
  278. package/dist/components/FormField/index.js +0 -2
  279. package/dist/components/FormField/index.js.map +0 -1
  280. package/dist/components/Input/InputElement.d.ts +0 -82
  281. package/dist/components/Input/InputElement.js +0 -64
  282. package/dist/components/Input/InputElement.js.map +0 -1
  283. package/src/components/Field/FieldDescription.tsx +0 -17
  284. package/src/components/Field/FieldError.tsx +0 -25
  285. package/src/components/Field/FieldLabel.tsx +0 -44
  286. package/src/components/FormField/FormField.rtl.test.tsx +0 -20
  287. package/src/components/FormField/FormField.tsx +0 -95
  288. package/src/components/FormField/FormFieldExample.tsx +0 -277
  289. package/src/components/FormField/index.tsx +0 -1
  290. package/src/components/Input/InputElement.tsx +0 -192
@@ -1,11 +1,11 @@
1
1
  import './select.scss';
2
2
  import { SvgKeyboardArrowDown } from '@bspk/icons/KeyboardArrowDown';
3
3
  import { useMemo, KeyboardEvent, MouseEvent } from 'react';
4
- import { useFieldInit } from '-/components/Field';
5
4
  import { ListItem, ListItemProps } from '-/components/ListItem';
6
5
  import { Menu, MenuProps } from '-/components/Menu';
7
6
  import { useArrowNavigation } from '-/hooks/useArrowNavigation';
8
7
  import { useFloating } from '-/hooks/useFloating';
8
+ import { useId } from '-/hooks/useId';
9
9
  import { useOutsideClick } from '-/hooks/useOutsideClick';
10
10
  import { CommonProps, ElementProps, FieldControlProps } from '-/types/common';
11
11
  import { getElementById } from '-/utils/dom';
@@ -82,9 +82,13 @@ export type SelectProps = CommonProps<'size'> &
82
82
  *
83
83
  * return (
84
84
  * <div style={{ width: 320 }}>
85
- * <Field>
86
- * <FieldLabel>Select an option</FieldLabel>
85
+ * <Field
86
+ * controlId="example-select"
87
+ * helperText="The select allows you to choose one option from a list of options."
88
+ * label="Select an option"
89
+ * >
87
90
  * <Select
91
+ * id="example-select"
88
92
  * name="example-select"
89
93
  * onChange={setSelected}
90
94
  * options={OPTIONS}
@@ -93,9 +97,6 @@ export type SelectProps = CommonProps<'size'> &
93
97
  * size="medium"
94
98
  * value={selected}
95
99
  * />
96
- * <FieldDescription>
97
- * The select allows you to choose one option from a list of options.
98
- * </FieldDescription>
99
100
  * </Field>
100
101
  * </div>
101
102
  * );
@@ -112,22 +113,19 @@ export function Select({
112
113
  size = 'medium',
113
114
  disabled,
114
115
  id: idProp,
115
- invalid: invalidProp,
116
+ invalid = false,
116
117
  readOnly,
117
118
  name,
118
119
  scrollLimit,
119
120
  required = false,
120
121
  'aria-label': ariaLabel,
121
122
  menuWidth,
123
+ 'aria-describedby': ariaDescribedBy,
124
+ 'aria-errormessage': ariaErrorMessage,
122
125
  ...elementProps
123
126
  }: ElementProps<SelectProps, 'button'>) {
124
- const { id, ariaDescribedBy, ariaErrorMessage, invalid } = useFieldInit({
125
- idProp,
126
- required,
127
- disabled,
128
- readOnly,
129
- invalidProp,
130
- });
127
+ const id = useId(idProp);
128
+
131
129
  const menuId = useMemo(() => `${id}-menu`, [id]);
132
130
 
133
131
  const { items, availableItems } = useMemo(() => {
@@ -188,6 +186,7 @@ export function Select({
188
186
  aria-expanded={open}
189
187
  aria-haspopup="listbox"
190
188
  aria-readonly={readOnly || undefined}
189
+ aria-required={required || undefined}
191
190
  data-bspk="select"
192
191
  data-invalid={invalid || undefined}
193
192
  data-open={open || undefined}
@@ -2,7 +2,7 @@
2
2
  import { useState } from 'react';
3
3
  import { Select, SelectProps } from '.';
4
4
  import { Avatar } from '-/components/Avatar';
5
- import { Field, FieldDescription, FieldLabel } from '-/components/Field';
5
+ import { Field } from '-/components/Field';
6
6
  import { Tag } from '-/components/Tag';
7
7
  import { Txt } from '-/components/Txt';
8
8
  import { ComponentExample, Preset } from '-/utils/demo';
@@ -180,9 +180,13 @@ export const Usage = () => {
180
180
 
181
181
  return (
182
182
  <div style={{ width: 320 }}>
183
- <Field>
184
- <FieldLabel>Select an option</FieldLabel>
183
+ <Field
184
+ controlId="example-select"
185
+ helperText="The select allows you to choose one option from a list of options."
186
+ label="Select an option"
187
+ >
185
188
  <Select
189
+ id="example-select"
186
190
  name="example-select"
187
191
  onChange={setSelected}
188
192
  options={OPTIONS}
@@ -191,7 +195,6 @@ export const Usage = () => {
191
195
  size="medium"
192
196
  value={selected}
193
197
  />
194
- <FieldDescription>The select allows you to choose one option from a list of options.</FieldDescription>
195
198
  </Field>
196
199
  </div>
197
200
  );
@@ -1,28 +1,17 @@
1
- import { SelectField, SelectFieldProps } from './';
2
- import { presets } from '-/components/Select/SelectExample';
1
+ import { SelectField } from '.';
3
2
  import { hasNoBasicA11yIssues } from '-/rtl/hasNoBasicA11yIssues';
4
3
  import { render } from '-/rtl/util';
5
4
 
6
- const nonPresetProps = {
7
- name: 'Example name',
8
- onChange: () => {},
9
- };
10
-
11
- const TestBed = (props: SelectFieldProps) => <SelectField {...props} placeholder="SelectField an option" />;
5
+ const TestBed = () => (
6
+ <SelectField label="Example field label" name="example-field-name" onChange={() => {}} options={[]} value="" />
7
+ );
12
8
 
13
9
  describe('SelectField (RTL)', () => {
14
- presets.forEach((preset) => {
15
- it(
16
- `has no basic a11y issues - ${preset.label}`,
17
- hasNoBasicA11yIssues(<TestBed label={preset.label} {...preset.propState} {...nonPresetProps} />),
18
- );
19
- });
10
+ it('has no basic a11y issues', hasNoBasicA11yIssues(<TestBed />));
20
11
 
21
12
  it('renders', () => {
22
- const { queryByText } = render(
23
- <TestBed label={presets[0].label} {...presets[0].propState} {...nonPresetProps} />,
24
- );
13
+ const { getAllByLabelText } = render(<TestBed />);
25
14
 
26
- expect(queryByText('SelectField an option')).toBeInTheDocument();
15
+ expect(getAllByLabelText('Example field label')[0]).toBeInTheDocument();
27
16
  });
28
17
  });
@@ -1,7 +1,8 @@
1
- import { FormField, FormFieldControlProps } from '-/components/FormField';
1
+ import { Field, FieldControlProps, propsWithAria } from '-/components/Field';
2
2
  import { Select, SelectProps } from '-/components/Select';
3
+ import { useId } from '-/hooks/useId';
3
4
 
4
- export type SelectFieldProps = FormFieldControlProps<SelectProps>;
5
+ export type SelectFieldProps = FieldControlProps<SelectProps>;
5
6
 
6
7
  /**
7
8
  * A field wrapper for the Select component.
@@ -9,7 +10,7 @@ export type SelectFieldProps = FormFieldControlProps<SelectProps>;
9
10
  * This component takes properties from the FormField and Select components.
10
11
  *
11
12
  * @name SelectField
12
- * @phase Stable
13
+ * @phase UXReview
13
14
  *
14
15
  * @generated
15
16
  */
@@ -19,18 +20,21 @@ export function SelectField({
19
20
  labelTrailing,
20
21
  errorMessage,
21
22
  style,
23
+ id: idProp,
22
24
  ...controlProps
23
25
  }: SelectFieldProps) {
26
+ const id = useId(idProp);
24
27
  return (
25
- <FormField
28
+ <Field
29
+ controlId={id}
26
30
  errorMessage={errorMessage}
27
31
  helperText={helperText}
28
32
  label={label}
29
33
  labelTrailing={labelTrailing}
30
34
  style={style}
31
35
  >
32
- <Select {...controlProps} />
33
- </FormField>
36
+ <Select {...propsWithAria({ id, controlProps, errorMessage, helperText })} />
37
+ </Field>
34
38
  );
35
39
  }
36
40
 
@@ -72,8 +72,7 @@ export type SliderProps<Value> = Pick<CommonPropsLibrary, 'disabled' | 'readOnly
72
72
  * track.
73
73
  *
74
74
  * @example
75
- * import { Slider } from '@bspk/ui/Slider';
76
- * import { useState } from 'react';
75
+ * import { Slider } from '-/components/Slider';
77
76
  *
78
77
  * () => {
79
78
  * const [value, setValue] = useState(50);
@@ -83,7 +83,6 @@ export type SnackbarProps = CommonProps<'id'> & {
83
83
  * @example
84
84
  * import { Snackbar } from '@bspk/ui/Snackbar';
85
85
  * import { Button } from '@bspk/ui/Button';
86
- * import { useState } from 'react';
87
86
  * import { sendSnackbar } from '@bspk/ui/Snackbar/Manager';
88
87
  *
89
88
  * () => {
@@ -26,7 +26,6 @@ export type SwitchProps = CommonProps<'aria-label' | 'disabled' | 'id' | 'name'>
26
26
  * will more often be used in the SwitchOption component.
27
27
  *
28
28
  * @example
29
- * import { useState } from 'react';
30
29
  * import { Switch } from '@bspk/ui/Switch';
31
30
  *
32
31
  * () => {
@@ -18,7 +18,6 @@ export type TabGroupProps = Omit<TabListProps<TabOption>, 'iconsOnly'> & {
18
18
  * Navigation tool that organizes content across different screens and views.
19
19
  *
20
20
  * @example
21
- * import { useState } from 'react';
22
21
  * import { TabGroup } from '@bspk/ui/TabGroup';
23
22
  *
24
23
  * () => {
@@ -123,7 +123,6 @@ export type TabListProps<O extends TabOption = TabOption> = {
123
123
  * See TabGroup or SegmentedControl for examples.
124
124
  *
125
125
  * @example
126
- * import { useState } from 'react';
127
126
  * import { TabList } from '@bspk/ui/TabList';
128
127
  *
129
128
  * () => {
@@ -6,6 +6,7 @@ ul[data-bspk-utility='tab-list'] {
6
6
  list-style: none;
7
7
  height: var(--height);
8
8
  font: var(--font);
9
+ width: fit-content; // default to hug content
9
10
 
10
11
  &[data-width='fill'] {
11
12
  align-items: stretch;
@@ -5,6 +5,7 @@
5
5
  --grey-background: var(--surface-neutral-t2-lowest);
6
6
  --icon-size: var(--spacing-sizing-05);
7
7
 
8
+ display: block;
8
9
  min-width: 100%;
9
10
  overflow: auto hidden;
10
11
  border-collapse: separate;
@@ -135,7 +136,7 @@
135
136
  z-index: var(--z-index-focus);
136
137
  inset: 0;
137
138
  outline: solid 2px var(--stroke-neutral-focus);
138
- outline-offset: -2px;
139
+ isolation: isolate;
139
140
  }
140
141
  }
141
142
  }
@@ -1,6 +1,5 @@
1
1
  import './textarea.scss';
2
2
  import { ChangeEvent, useRef } from 'react';
3
- import { useFieldInit } from '-/components/Field';
4
3
  import { CommonProps, FieldControlProps, SetRef } from '-/types/common';
5
4
  import { cssWithVars } from '-/utils/cwv';
6
5
 
@@ -46,18 +45,15 @@ export type TextareaProps = CommonProps<'size'> &
46
45
  * For a more complete example with field usage, see the TextareaField component.
47
46
  *
48
47
  * @example
49
- * import { useState } from 'react';
50
- * import { Textarea } from '@bspk/ui/Textarea';
48
+ * import { Textarea } from '-/components/Textarea';
51
49
  *
52
50
  * () => {
53
51
  * const [value, setValue] = useState<string | undefined>('');
54
52
  *
55
53
  * return (
56
54
  * <div style={{ width: 320 }}>
57
- * <Field>
58
- * <FieldLabel>Example Textarea</FieldLabel>
59
- * <Textarea name="example-name" onChange={setValue} value={value} />
60
- * <FieldDescription>This is an example textarea field.</FieldDescription>
55
+ * <Field controlId="example-textarea" helperText="This is an example textarea field." label="Textarea">
56
+ * <Textarea id="example-textarea" name="example-name" onChange={setValue} value={value} />
61
57
  * </Field>
62
58
  * </div>
63
59
  * );
@@ -69,30 +65,24 @@ export type TextareaProps = CommonProps<'size'> &
69
65
  * @phase Stable
70
66
  */
71
67
  export function Textarea({
72
- invalid: invalidProp,
68
+ invalid = false,
73
69
  onChange,
74
70
  size = 'medium',
75
71
  value = '',
76
72
  name,
77
73
  innerRef,
78
74
  placeholder,
79
- id: idProp,
75
+ id,
80
76
  minRows = 4,
81
77
  maxRows = 10,
82
78
  required = false,
83
79
  readOnly,
84
80
  disabled,
85
81
  'aria-label': ariaLabel,
82
+ 'aria-describedby': ariaDescribedBy,
83
+ 'aria-errormessage': ariaErrorMessage,
86
84
  ...otherProps
87
85
  }: TextareaProps) {
88
- const { id, ariaDescribedBy, ariaErrorMessage, invalid } = useFieldInit({
89
- idProp,
90
- required,
91
- disabled,
92
- readOnly,
93
- invalidProp,
94
- });
95
-
96
86
  const onInput = () => {
97
87
  const target = textareaElement.current;
98
88
  if (!target) return;
@@ -137,6 +127,7 @@ export function Textarea({
137
127
  textareaElement.current = node;
138
128
  onInput();
139
129
  }}
130
+ required={required || undefined}
140
131
  value={value}
141
132
  wrap="hard"
142
133
  />
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { Textarea, TextareaProps } from '.';
3
- import { Field, FieldDescription, FieldLabel } from '-/components/Field';
3
+ import { Field } from '-/components/Field';
4
4
  import { ComponentExample } from '-/utils/demo';
5
5
 
6
6
  export const TextareaExample: ComponentExample<TextareaProps> = {
@@ -19,10 +19,8 @@ export const Usage = () => {
19
19
 
20
20
  return (
21
21
  <div style={{ width: 320 }}>
22
- <Field>
23
- <FieldLabel>Example Textarea</FieldLabel>
24
- <Textarea name="example-name" onChange={setValue} value={value} />
25
- <FieldDescription>This is an example textarea field.</FieldDescription>
22
+ <Field controlId="example-textarea" helperText="This is an example textarea field." label="Textarea">
23
+ <Textarea id="example-textarea" name="example-name" onChange={setValue} value={value} />
26
24
  </Field>
27
25
  </div>
28
26
  );
@@ -1,7 +1,8 @@
1
- import { FormField, FormFieldControlProps } from '-/components/FormField';
1
+ import { Field, FieldControlProps, propsWithAria } from '-/components/Field';
2
2
  import { Textarea, TextareaProps } from '-/components/Textarea';
3
+ import { useId } from '-/hooks/useId';
3
4
 
4
- export type TextareaFieldProps = FormFieldControlProps<TextareaProps>;
5
+ export type TextareaFieldProps = FieldControlProps<TextareaProps>;
5
6
 
6
7
  /**
7
8
  * A field wrapper for the Textarea component.
@@ -9,7 +10,7 @@ export type TextareaFieldProps = FormFieldControlProps<TextareaProps>;
9
10
  * This component takes properties from the FormField and Textarea components.
10
11
  *
11
12
  * @name TextareaField
12
- * @phase Stable
13
+ * @phase UXReview
13
14
  *
14
15
  * @generated
15
16
  */
@@ -19,18 +20,21 @@ export function TextareaField({
19
20
  labelTrailing,
20
21
  errorMessage,
21
22
  style,
23
+ id: idProp,
22
24
  ...controlProps
23
25
  }: TextareaFieldProps) {
26
+ const id = useId(idProp);
24
27
  return (
25
- <FormField
28
+ <Field
29
+ controlId={id}
26
30
  errorMessage={errorMessage}
27
31
  helperText={helperText}
28
32
  label={label}
29
33
  labelTrailing={labelTrailing}
30
34
  style={style}
31
35
  >
32
- <Textarea {...controlProps} />
33
- </FormField>
36
+ <Textarea {...propsWithAria({ id, controlProps, errorMessage, helperText })} />
37
+ </Field>
34
38
  );
35
39
  }
36
40
 
@@ -13,11 +13,11 @@ import {
13
13
  stringValueToParts,
14
14
  } from './utils';
15
15
  import { Button } from '-/components/Button';
16
- import { useFieldInit } from '-/components/Field';
17
16
  import { InputProps } from '-/components/Input';
18
17
  import { Menu } from '-/components/Menu';
19
18
  import { Portal } from '-/components/Portal';
20
19
  import { useFloating } from '-/hooks/useFloating';
20
+ import { useId } from '-/hooks/useId';
21
21
  import { useOutsideClick } from '-/hooks/useOutsideClick';
22
22
  import { ElementProps, FieldControlProps } from '-/types/common';
23
23
  import { handleKeyDown } from '-/utils/handleKeyDown';
@@ -31,17 +31,19 @@ export type TimePickerProps = FieldControlProps & Pick<InputProps, 'size'>;
31
31
  * For a more complete example with field usage, see the TimePickerField component.
32
32
  *
33
33
  * @example
34
- * import { TimePicker } from '@bspk/ui/TimePicker';
34
+ * import { TimePicker } from '-/components/TimePicker';
35
35
  *
36
36
  * () => {
37
37
  * const [value, onChange] = useState<string | undefined>('');
38
38
  *
39
39
  * return (
40
40
  * <div style={{ width: 320 }}>
41
- * <Field>
42
- * <FieldLabel>Time</FieldLabel>
43
- * <TimePicker name="time" onChange={onChange} value={value} />
44
- * <FieldDescription>The time picker allows you to select a time.</FieldDescription>
41
+ * <Field
42
+ * controlId="destination-time"
43
+ * helperText="The time picker allows you to select a time."
44
+ * label="Time"
45
+ * >
46
+ * <TimePicker id="destination-time" name="time" onChange={onChange} value={value} />
45
47
  * </Field>
46
48
  * </div>
47
49
  * );
@@ -54,22 +56,17 @@ export function TimePicker({
54
56
  value,
55
57
  disabled,
56
58
  id: idProp,
57
- invalid: invalidProp,
59
+ invalid = false,
58
60
  readOnly,
59
61
  name,
60
62
  size,
61
- required = false,
62
63
  onChange: onChangeProp,
63
64
  'aria-label': ariaLabel = 'Time picker',
65
+ 'aria-describedby': ariaDescribedBy,
66
+ 'aria-errormessage': ariaErrorMessage,
64
67
  ...props
65
68
  }: ElementProps<TimePickerProps, 'div'>) {
66
- const { id, ariaDescribedBy, ariaErrorMessage, invalid } = useFieldInit({
67
- idProp,
68
- required,
69
- disabled,
70
- readOnly,
71
- invalidProp,
72
- });
69
+ const id = useId(idProp);
73
70
 
74
71
  const menuId = `${id}-time-picker-menu`;
75
72
 
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { TimePicker, TimePickerProps } from './TimePicker';
3
- import { Field, FieldLabel, FieldDescription } from '-/components/Field';
3
+ import { Field } from '-/components/Field';
4
4
  import { ComponentExample } from '-/utils/demo';
5
5
 
6
6
  export const TimePickerExample: ComponentExample<TimePickerProps> = {
@@ -17,10 +17,8 @@ export const Usage = () => {
17
17
 
18
18
  return (
19
19
  <div style={{ width: 320 }}>
20
- <Field>
21
- <FieldLabel>Time</FieldLabel>
22
- <TimePicker name="time" onChange={onChange} value={value} />
23
- <FieldDescription>The time picker allows you to select a time.</FieldDescription>
20
+ <Field controlId="destination-time" helperText="The time picker allows you to select a time." label="Time">
21
+ <TimePicker id="destination-time" name="time" onChange={onChange} value={value} />
24
22
  </Field>
25
23
  </div>
26
24
  );
@@ -1,7 +1,8 @@
1
- import { FormField, FormFieldControlProps } from '-/components/FormField';
1
+ import { Field, FieldControlProps, propsWithAria } from '-/components/Field';
2
2
  import { TimePicker, TimePickerProps } from '-/components/TimePicker';
3
+ import { useId } from '-/hooks/useId';
3
4
 
4
- export type TimePickerFieldProps = FormFieldControlProps<TimePickerProps>;
5
+ export type TimePickerFieldProps = FieldControlProps<TimePickerProps>;
5
6
 
6
7
  /**
7
8
  * A field wrapper for the TimePicker component.
@@ -9,7 +10,7 @@ export type TimePickerFieldProps = FormFieldControlProps<TimePickerProps>;
9
10
  * This component takes properties from the FormField and TimePicker components.
10
11
  *
11
12
  * @name TimePickerField
12
- * @phase Stable
13
+ * @phase UXReview
13
14
  *
14
15
  * @generated
15
16
  */
@@ -19,18 +20,21 @@ export function TimePickerField({
19
20
  labelTrailing,
20
21
  errorMessage,
21
22
  style,
23
+ id: idProp,
22
24
  ...controlProps
23
25
  }: TimePickerFieldProps) {
26
+ const id = useId(idProp);
24
27
  return (
25
- <FormField
28
+ <Field
29
+ controlId={id}
26
30
  errorMessage={errorMessage}
27
31
  helperText={helperText}
28
32
  label={label}
29
33
  labelTrailing={labelTrailing}
30
34
  style={style}
31
35
  >
32
- <TimePicker {...controlProps} />
33
- </FormField>
36
+ <TimePicker {...propsWithAria({ id, controlProps, errorMessage, helperText })} />
37
+ </Field>
34
38
  );
35
39
  }
36
40
 
@@ -164,6 +164,14 @@ export type FieldControlProps<
164
164
  * @required
165
165
  */
166
166
  onChange: (next: ValueType | undefined, event?: ChangeContext) => void;
167
+ /*
168
+ * The aria-describedby attribute for the field control.
169
+ */
170
+ 'aria-describedby'?: string;
171
+ /*
172
+ * The aria-errormessage attribute for the field control.
173
+ */
174
+ 'aria-errormessage'?: string;
167
175
  };
168
176
 
169
177
  export type Brand =
package/src/utils/demo.ts CHANGED
@@ -228,7 +228,7 @@ export function componentToString<Props extends Record<string, any> = Record<str
228
228
  formattedValue = `{${componentToString(subComponentName, value.props)}}`;
229
229
  } else if (Array.isArray(value)) {
230
230
  return ` ${key}={[${value
231
- .map((item) => (isValidElement(item) ? convertReactToCodeString(item) : '...')) // Simplified for brevity
231
+ .map((item) => (isValidElement(item) ? convertReactToCodeString(item) : item))
232
232
  .join(', ')}]}`;
233
233
  } else if (typeof value === 'object') {
234
234
  formattedValue = `{${JSON.stringify(value, null, 2)}}`;
@@ -1,9 +0,0 @@
1
- /**
2
- * FieldDescription component displays a description associated with a form field.
3
- *
4
- * @name FieldDescription
5
- * @parent Field
6
- */
7
- export declare function FieldDescription({ children }: {
8
- children?: string;
9
- }): import("react/jsx-runtime").JSX.Element | null;
@@ -1,13 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useFieldContext, describedById } from './utils';
3
- /**
4
- * FieldDescription component displays a description associated with a form field.
5
- *
6
- * @name FieldDescription
7
- * @parent Field
8
- */
9
- export function FieldDescription({ children }) {
10
- const { id } = useFieldContext();
11
- return children ? (_jsx("p", { "data-bspk": "field-description", id: describedById(id), children: children })) : null;
12
- }
13
- //# sourceMappingURL=FieldDescription.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FieldDescription.js","sourceRoot":"","sources":["../../../src/components/Field/FieldDescription.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAyB;IAChE,MAAM,EAAE,EAAE,EAAE,GAAG,eAAe,EAAE,CAAC;IAEjC,OAAO,QAAQ,CAAC,CAAC,CAAC,CACd,yBAAa,mBAAmB,EAAC,EAAE,EAAE,aAAa,CAAC,EAAE,CAAC,YACjD,QAAQ,GACT,CACP,CAAC,CAAC,CAAC,IAAI,CAAC;AACb,CAAC"}
@@ -1,11 +0,0 @@
1
- export type FieldErrorProps = {
2
- /** The error message text. */
3
- children?: string;
4
- };
5
- /**
6
- * FieldError component displays an error message associated with a form field.
7
- *
8
- * @name FieldError
9
- * @parent Field
10
- */
11
- export declare function FieldError({ children }: FieldErrorProps): "" | import("react/jsx-runtime").JSX.Element | undefined;
@@ -1,14 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { errorMessageId, useFieldContext } from './utils';
3
- import { InlineAlert } from '../InlineAlert';
4
- /**
5
- * FieldError component displays an error message associated with a form field.
6
- *
7
- * @name FieldError
8
- * @parent Field
9
- */
10
- export function FieldError({ children }) {
11
- const { id } = useFieldContext();
12
- return (children && (_jsx(InlineAlert, { id: errorMessageId(id), owner: "field-error", variant: "error", children: children })));
13
- }
14
- //# sourceMappingURL=FieldError.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FieldError.js","sourceRoot":"","sources":["../../../src/components/Field/FieldError.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAOvD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAmB;IACpD,MAAM,EAAE,EAAE,EAAE,GAAG,eAAe,EAAE,CAAC;IAEjC,OAAO,CACH,QAAQ,IAAI,CACR,KAAC,WAAW,IAAC,EAAE,EAAE,cAAc,CAAC,EAAE,CAAC,EAAE,KAAK,EAAC,aAAa,EAAC,OAAO,EAAC,OAAO,YACnE,QAAQ,GACC,CACjB,CACJ,CAAC;AACN,CAAC"}
@@ -1,21 +0,0 @@
1
- import { ElementType } from 'react';
2
- import { FieldContext } from './utils';
3
- import { ElementProps } from '-/types/common';
4
- export type FieldLabelProps<As extends ElementType = ElementType> = Pick<FieldContext, 'labelTrailing' | 'required'> & {
5
- /** The label text. */
6
- children: string;
7
- /**
8
- * The element type to render as.
9
- *
10
- * @default label
11
- * @type ElementType
12
- */
13
- as?: As;
14
- };
15
- /**
16
- * FieldLabel component displays a label associated with a form field.
17
- *
18
- * @name FieldLabel
19
- * @parent Field
20
- */
21
- export declare function FieldLabel<As extends ElementType = ElementType>({ children, labelTrailing, as, ...props }: ElementProps<FieldLabelProps<As>, As>): import("react/jsx-runtime").JSX.Element;