@bspk/ui 1.3.21 → 1.3.23

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 (307) 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 +5 -0
  20. package/dist/components/CheckboxGroup/checkbox-group.css.js +5 -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 +39 -20
  46. package/dist/components/Field/Field.js +10 -40
  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 +9 -7
  55. package/dist/components/Field/field.css.js +9 -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 +10 -6
  67. package/dist/components/Flex/Flex.js +10 -6
  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 +59 -15
  73. package/dist/components/Input/Input.js +40 -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/Link/Link.d.ts +0 -1
  104. package/dist/components/Link/Link.js +0 -1
  105. package/dist/components/Link/Link.js.map +1 -1
  106. package/dist/components/ListItem/list-item.css +1 -0
  107. package/dist/components/ListItem/list-item.css.js +1 -0
  108. package/dist/components/Modal/Modal.js +22 -26
  109. package/dist/components/Modal/Modal.js.map +1 -1
  110. package/dist/components/Modal/ModalExample.js +4 -1
  111. package/dist/components/Modal/ModalExample.js.map +1 -1
  112. package/dist/components/Modal/modal.css +4 -2
  113. package/dist/components/Modal/modal.css.js +4 -2
  114. package/dist/components/OTPInput/otp-input.css +1 -0
  115. package/dist/components/OTPInput/otp-input.css.js +1 -0
  116. package/dist/components/Pagination/Pagination.js +2 -2
  117. package/dist/components/Pagination/Pagination.js.map +1 -1
  118. package/dist/components/Password/Password.d.ts +9 -7
  119. package/dist/components/Password/Password.js +13 -17
  120. package/dist/components/Password/Password.js.map +1 -1
  121. package/dist/components/Password/PasswordExample.js +3 -3
  122. package/dist/components/Password/PasswordExample.js.map +1 -1
  123. package/dist/components/PasswordField/PasswordField.d.ts +4 -4
  124. package/dist/components/PasswordField/PasswordField.js +6 -4
  125. package/dist/components/PasswordField/PasswordField.js.map +1 -1
  126. package/dist/components/Popover/Popover.d.ts +0 -1
  127. package/dist/components/Popover/Popover.js +0 -1
  128. package/dist/components/Popover/Popover.js.map +1 -1
  129. package/dist/components/RadioGroup/RadioGroup.d.ts +1 -2
  130. package/dist/components/RadioGroup/RadioGroup.js +5 -11
  131. package/dist/components/RadioGroup/RadioGroup.js.map +1 -1
  132. package/dist/components/RadioGroup/radio-group.css +3 -0
  133. package/dist/components/RadioGroup/radio-group.css.js +3 -0
  134. package/dist/components/RadioGroupField/RadioGroupField.d.ts +3 -3
  135. package/dist/components/RadioGroupField/RadioGroupField.js +6 -4
  136. package/dist/components/RadioGroupField/RadioGroupField.js.map +1 -1
  137. package/dist/components/SearchBar/SearchBar.d.ts +0 -1
  138. package/dist/components/SearchBar/SearchBar.js +0 -1
  139. package/dist/components/SearchBar/SearchBar.js.map +1 -1
  140. package/dist/components/SegmentedControl/SegmentedControl.d.ts +0 -1
  141. package/dist/components/SegmentedControl/SegmentedControl.js +0 -1
  142. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  143. package/dist/components/Select/Select.d.ts +7 -6
  144. package/dist/components/Select/Select.js +10 -15
  145. package/dist/components/Select/Select.js.map +1 -1
  146. package/dist/components/Select/SelectExample.js +3 -3
  147. package/dist/components/Select/SelectExample.js.map +1 -1
  148. package/dist/components/Select/select.css +0 -10
  149. package/dist/components/Select/select.css.js +0 -10
  150. package/dist/components/SelectField/SelectField.d.ts +4 -4
  151. package/dist/components/SelectField/SelectField.js +6 -4
  152. package/dist/components/SelectField/SelectField.js.map +1 -1
  153. package/dist/components/Slider/Slider.d.ts +1 -2
  154. package/dist/components/Slider/Slider.js +1 -2
  155. package/dist/components/Slider/Slider.js.map +1 -1
  156. package/dist/components/Snackbar/Snackbar.d.ts +0 -1
  157. package/dist/components/Snackbar/Snackbar.js +0 -1
  158. package/dist/components/Snackbar/Snackbar.js.map +1 -1
  159. package/dist/components/Switch/Switch.d.ts +0 -1
  160. package/dist/components/Switch/Switch.js +0 -1
  161. package/dist/components/Switch/Switch.js.map +1 -1
  162. package/dist/components/TabGroup/TabGroup.d.ts +0 -1
  163. package/dist/components/TabGroup/TabGroup.js +0 -1
  164. package/dist/components/TabGroup/TabGroup.js.map +1 -1
  165. package/dist/components/TabList/TabList.d.ts +0 -1
  166. package/dist/components/TabList/TabList.js +0 -1
  167. package/dist/components/TabList/TabList.js.map +1 -1
  168. package/dist/components/TabList/tab-list.css +1 -0
  169. package/dist/components/TabList/tab-list.css.js +1 -0
  170. package/dist/components/Table/table.css +2 -1
  171. package/dist/components/Table/table.css.js +2 -1
  172. package/dist/components/Textarea/Textarea.d.ts +4 -7
  173. package/dist/components/Textarea/Textarea.js +5 -16
  174. package/dist/components/Textarea/Textarea.js.map +1 -1
  175. package/dist/components/Textarea/TextareaExample.js +3 -3
  176. package/dist/components/Textarea/TextareaExample.js.map +1 -1
  177. package/dist/components/TextareaField/TextareaField.d.ts +4 -4
  178. package/dist/components/TextareaField/TextareaField.js +6 -4
  179. package/dist/components/TextareaField/TextareaField.js.map +1 -1
  180. package/dist/components/TimePicker/TimePicker.d.ts +8 -6
  181. package/dist/components/TimePicker/TimePicker.js +10 -14
  182. package/dist/components/TimePicker/TimePicker.js.map +1 -1
  183. package/dist/components/TimePicker/TimePickerExample.js +3 -3
  184. package/dist/components/TimePicker/TimePickerExample.js.map +1 -1
  185. package/dist/components/TimePickerField/TimePickerField.d.ts +4 -4
  186. package/dist/components/TimePickerField/TimePickerField.js +6 -4
  187. package/dist/components/TimePickerField/TimePickerField.js.map +1 -1
  188. package/dist/hooks/useFloating.d.ts +0 -6
  189. package/dist/hooks/useFloating.js +0 -6
  190. package/dist/hooks/useFloating.js.map +1 -1
  191. package/dist/styles/base.css +71 -81
  192. package/dist/styles/base.css.js +71 -81
  193. package/dist/types/common.d.ts +3 -0
  194. package/dist/types/common.js.map +1 -1
  195. package/package.json +3 -4
  196. package/src/components/Accordion/Accordion.tsx +2 -2
  197. package/src/components/Accordion/accordion.scss +10 -1
  198. package/src/components/BottomNavigation/BottomNavigation.tsx +0 -1
  199. package/src/components/BottomNavigation/bottom-navigation.scss +1 -0
  200. package/src/components/Button/button.scss +4 -0
  201. package/src/components/Checkbox/Checkbox.tsx +3 -3
  202. package/src/components/CheckboxGroup/CheckboxGroup.tsx +37 -52
  203. package/src/components/CheckboxGroup/CheckboxGroupExample.tsx +6 -0
  204. package/src/components/CheckboxGroup/checkbox-group.scss +6 -0
  205. package/src/components/CheckboxGroupField/CheckboxGroupField.tsx +16 -11
  206. package/src/components/ChipGroup/ChipGroup.tsx +0 -1
  207. package/src/components/ChipGroup/chip-group.scss +4 -0
  208. package/src/components/DatePicker/DatePicker.tsx +9 -20
  209. package/src/components/DatePicker/DatePickerExample.tsx +3 -5
  210. package/src/components/DatePickerField/DatePickerField.rtl.test.tsx +1 -1
  211. package/src/components/DatePickerField/DatePickerField.tsx +11 -6
  212. package/src/components/Dialog/Dialog.tsx +2 -3
  213. package/src/components/Fab/Fab.tsx +8 -5
  214. package/src/components/Fab/fab.scss +1 -0
  215. package/src/components/Field/Field.rtl.test.tsx +8 -6
  216. package/src/components/Field/Field.tsx +71 -63
  217. package/src/components/Field/FieldExample.tsx +27 -5
  218. package/src/components/Field/Fieldset.tsx +82 -0
  219. package/src/components/Field/field.scss +27 -26
  220. package/src/components/Field/index.tsx +1 -3
  221. package/src/components/Field/utils.ts +15 -77
  222. package/src/components/FileUpload/FileUpload.tsx +1 -1
  223. package/src/components/FileUploadItem/FileUploadItem.tsx +1 -1
  224. package/src/components/Flex/Flex.tsx +10 -6
  225. package/src/components/InlineAlert/InlineAlert.rtl.test.tsx +1 -1
  226. package/src/components/InlineAlert/InlineAlert.tsx +3 -3
  227. package/src/components/Input/Input.tsx +135 -48
  228. package/src/components/Input/InputExample.tsx +4 -6
  229. package/src/components/Input/index.tsx +0 -1
  230. package/src/components/InputField/InputField.tsx +11 -6
  231. package/src/components/InputNumber/InputNumber.tsx +11 -16
  232. package/src/components/InputNumber/InputNumberExample.tsx +7 -4
  233. package/src/components/InputNumber/input-number.scss +1 -0
  234. package/src/components/InputNumberField/InputNumberField.tsx +11 -6
  235. package/src/components/InputPhone/InputPhone.tsx +14 -18
  236. package/src/components/InputPhone/InputPhoneExample.tsx +7 -6
  237. package/src/components/InputPhone/input-phone.scss +1 -0
  238. package/src/components/InputPhoneField/InputPhoneField.tsx +11 -6
  239. package/src/components/Link/Link.tsx +0 -1
  240. package/src/components/ListItem/list-item.scss +1 -0
  241. package/src/components/Modal/Modal.tsx +26 -30
  242. package/src/components/Modal/ModalExample.tsx +7 -2
  243. package/src/components/Modal/modal.scss +1 -1
  244. package/src/components/OTPInput/otp-input.scss +1 -0
  245. package/src/components/Pagination/Pagination.tsx +2 -2
  246. package/src/components/Password/Password.tsx +15 -17
  247. package/src/components/Password/PasswordExample.tsx +13 -5
  248. package/src/components/PasswordField/PasswordField.tsx +11 -6
  249. package/src/components/Popover/Popover.tsx +0 -1
  250. package/src/components/RadioGroup/RadioGroup.tsx +14 -20
  251. package/src/components/RadioGroup/radio-group.scss +4 -0
  252. package/src/components/RadioGroupField/RadioGroupField.tsx +16 -11
  253. package/src/components/SearchBar/SearchBar.tsx +0 -1
  254. package/src/components/SegmentedControl/SegmentedControl.tsx +0 -1
  255. package/src/components/Select/Select.tsx +13 -14
  256. package/src/components/Select/SelectExample.tsx +7 -4
  257. package/src/components/Select/select.scss +0 -12
  258. package/src/components/SelectField/SelectField.rtl.test.tsx +7 -18
  259. package/src/components/SelectField/SelectField.tsx +11 -6
  260. package/src/components/Slider/Slider.tsx +1 -2
  261. package/src/components/Snackbar/Snackbar.tsx +0 -1
  262. package/src/components/Switch/Switch.tsx +0 -1
  263. package/src/components/TabGroup/TabGroup.tsx +0 -1
  264. package/src/components/TabList/TabList.tsx +0 -1
  265. package/src/components/TabList/tab-list.scss +1 -0
  266. package/src/components/Table/table.scss +2 -1
  267. package/src/components/Textarea/Textarea.tsx +8 -17
  268. package/src/components/Textarea/TextareaExample.tsx +3 -5
  269. package/src/components/TextareaField/TextareaField.tsx +11 -6
  270. package/src/components/TimePicker/TimePicker.tsx +12 -15
  271. package/src/components/TimePicker/TimePickerExample.tsx +3 -5
  272. package/src/components/TimePickerField/TimePickerField.tsx +11 -6
  273. package/src/hooks/useFloating.ts +0 -6
  274. package/src/styles/base.scss +109 -87
  275. package/src/types/common.ts +9 -0
  276. package/dist/components/Field/FieldDescription.d.ts +0 -9
  277. package/dist/components/Field/FieldDescription.js +0 -13
  278. package/dist/components/Field/FieldDescription.js.map +0 -1
  279. package/dist/components/Field/FieldError.d.ts +0 -11
  280. package/dist/components/Field/FieldError.js +0 -14
  281. package/dist/components/Field/FieldError.js.map +0 -1
  282. package/dist/components/Field/FieldLabel.d.ts +0 -21
  283. package/dist/components/Field/FieldLabel.js +0 -14
  284. package/dist/components/Field/FieldLabel.js.map +0 -1
  285. package/dist/components/FormField/FormField.d.ts +0 -66
  286. package/dist/components/FormField/FormField.js +0 -31
  287. package/dist/components/FormField/FormField.js.map +0 -1
  288. package/dist/components/FormField/FormFieldExample.d.ts +0 -9
  289. package/dist/components/FormField/FormFieldExample.js +0 -99
  290. package/dist/components/FormField/FormFieldExample.js.map +0 -1
  291. package/dist/components/FormField/index.d.ts +0 -1
  292. package/dist/components/FormField/index.js +0 -2
  293. package/dist/components/FormField/index.js.map +0 -1
  294. package/dist/components/Input/InputElement.d.ts +0 -82
  295. package/dist/components/Input/InputElement.js +0 -64
  296. package/dist/components/Input/InputElement.js.map +0 -1
  297. package/dist/components/Link/link.css +0 -18
  298. package/dist/components/Link/link.css.js +0 -23
  299. package/src/components/Field/FieldDescription.tsx +0 -17
  300. package/src/components/Field/FieldError.tsx +0 -25
  301. package/src/components/Field/FieldLabel.tsx +0 -44
  302. package/src/components/FormField/FormField.rtl.test.tsx +0 -20
  303. package/src/components/FormField/FormField.tsx +0 -95
  304. package/src/components/FormField/FormFieldExample.tsx +0 -277
  305. package/src/components/FormField/index.tsx +0 -1
  306. package/src/components/Input/InputElement.tsx +0 -192
  307. package/src/components/Link/link.scss +0 -21
@@ -14,7 +14,7 @@ export type InlineAlertProps = CommonProps<'owner'> & {
14
14
  * @type multiline
15
15
  * @required
16
16
  */
17
- children: string;
17
+ label: string;
18
18
  /**
19
19
  * The color variant of the inline alert.
20
20
  *
@@ -37,11 +37,11 @@ export type InlineAlertProps = CommonProps<'owner'> & {
37
37
  * @name InlineAlert
38
38
  * @phase Stable
39
39
  */
40
- export function InlineAlert({ children, variant = 'informational', id, owner }: InlineAlertProps) {
40
+ export function InlineAlert({ label, variant = 'informational', id, owner }: InlineAlertProps) {
41
41
  return (
42
42
  <div data-bspk="inline-alert" data-bspk-owner={owner || undefined} data-variant={variant} id={id} role="alert">
43
43
  {VARIANT_ICON[variant]}
44
- <Txt variant="body-small">{children}</Txt>
44
+ <Txt variant="body-small">{label}</Txt>
45
45
  </div>
46
46
  );
47
47
  }
@@ -1,39 +1,87 @@
1
1
  import './input.scss';
2
- import { DEFAULT, InputElement, InputElementProps } from './InputElement';
3
- import { useFieldInit } from '-/components/Field';
4
- import { ElementProps } from '-/types/common';
2
+ import { SvgCancel } from '@bspk/icons/Cancel';
3
+ import { HTMLInputTypeAttribute, ReactNode, useMemo, useRef } from 'react';
4
+ import { Button } from '-/components/Button';
5
+ import { useTimeout } from '-/hooks/useTimeout';
6
+ import { CommonProps, ElementProps, SetRef, FieldControlProps } from '-/types/common';
5
7
 
6
- export type InputProps = Omit<InputElementProps, 'ariaDescribedBy' | 'ariaErrorMessage'>;
8
+ export const DEFAULT = {
9
+ size: 'medium',
10
+ value: '',
11
+ type: 'text' as Extract<HTMLInputTypeAttribute, 'number' | 'text'>,
12
+ autoComplete: 'off',
13
+ } as const;
14
+
15
+ export type InputProps = CommonProps<'owner' | 'size'> &
16
+ FieldControlProps & {
17
+ /** The ref of the container. */
18
+ containerRef?: SetRef<HTMLDivElement>;
19
+ /** The ref of the input. */
20
+ inputRef?: SetRef<HTMLInputElement>;
21
+ /**
22
+ * The trailing element to display in the field.
23
+ *
24
+ * @exampleType string
25
+ */
26
+ trailing?: ReactNode;
27
+ /**
28
+ * The leading element to display in the field.
29
+ *
30
+ * @exampleType string
31
+ */
32
+ leading?: ReactNode;
33
+ /** The placeholder of the field. */
34
+ placeholder?: string;
35
+ /**
36
+ * The type of the input.
37
+ *
38
+ * @default text
39
+ */
40
+ type?: Extract<HTMLInputTypeAttribute, 'number' | 'password' | 'text'>;
41
+ /**
42
+ * Specifies if user agent has any permission to provide automated assistance in filling out form field values
43
+ *
44
+ * @default off
45
+ */
46
+ autoComplete?: 'off' | 'on';
47
+ /**
48
+ * Specifies if the clear button should be shown. This should almost always be true, but can be set to false.
49
+ *
50
+ * @default true
51
+ */
52
+ showClearButton?: boolean;
53
+ /** Additional props to pass to the underlying input element. */
54
+ inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, keyof InputProps>;
55
+ };
7
56
 
8
57
  /**
9
- * An input that allows users to enter text, numbers or symbols in a singular line.
10
- *
11
- * For a more complete example with field usage, see the InputField component.
58
+ * An input that allows users to enter text, numbers or symbols in a singular line. This is a utility element and is not
59
+ * intended to be used directly but rather through the Input, and other components.
12
60
  *
13
61
  * @example
14
- * import { useState } from 'react';
15
62
  * import { Input } from '@bspk/ui/Input';
16
- * import { Field, FieldLabel, FieldDescription } from '@bspk/ui/Field';
17
63
  *
18
64
  * () => {
19
- * const [fieldDate, setFieldDate] = useState<string>();
65
+ * const [value, setValue] = useState<string>();
20
66
  *
21
67
  * return (
22
68
  * <div style={{ width: 320 }}>
23
- * <Field>
24
- * <FieldLabel>Example Label</FieldLabel>
25
- * <Input name="example-name" onChange={setFieldDate} value={fieldDate} />
26
- * <FieldDescription>This is an example input field.</FieldDescription>
69
+ * <Field
70
+ * controlId="example-control-id"
71
+ * helperText="This is an example input field."
72
+ * label="Example Input"
73
+ * >
74
+ * <Input id="example-control-id" name="example-name" onChange={setValue} value={value} />
27
75
  * </Field>
28
76
  * </div>
29
77
  * );
30
78
  * };
31
79
  *
32
80
  * @name Input
33
- * @phase UXReview
81
+ * @phase Stable
34
82
  */
35
83
  export function Input({
36
- invalid: invalidProp,
84
+ invalid,
37
85
  onChange,
38
86
  size = DEFAULT.size,
39
87
  value = DEFAULT.value,
@@ -42,7 +90,7 @@ export function Input({
42
90
  inputRef,
43
91
  required = false,
44
92
  placeholder,
45
- id: idProp,
93
+ id,
46
94
  leading,
47
95
  trailing,
48
96
  type = DEFAULT.type,
@@ -53,42 +101,81 @@ export function Input({
53
101
  showClearButton: showClearButtonProp = true,
54
102
  owner,
55
103
  inputProps,
104
+ 'aria-describedby': ariaDescribedBy,
105
+ 'aria-errormessage': ariaErrorMessage,
56
106
  ...props
57
107
  }: ElementProps<InputProps, 'div'>) {
58
- const { id, ariaDescribedBy, ariaErrorMessage, invalid } = useFieldInit({
59
- idProp,
60
- required,
61
- disabled,
62
- readOnly,
63
- invalidProp,
64
- });
108
+ const showClearButton = useMemo(
109
+ () => showClearButtonProp !== false && !readOnly && !disabled && !!value?.toString().length,
110
+ [showClearButtonProp, readOnly, disabled, value],
111
+ );
112
+
113
+ const inputRefInternal = useRef<HTMLInputElement | null>(null);
114
+
115
+ const focusTimeout = useTimeout();
65
116
 
66
117
  return (
67
- // data-bspk="input" -- because InputElement already has it :)
68
- <InputElement
118
+ <div
69
119
  {...props}
70
- aria-label={ariaLabel}
71
- ariaDescribedBy={ariaDescribedBy}
72
- ariaErrorMessage={ariaErrorMessage}
73
- autoComplete={autoComplete}
74
- containerRef={containerRef}
75
- disabled={disabled}
76
- id={id}
77
- inputProps={inputProps}
78
- inputRef={inputRef}
79
- invalid={invalid}
80
- leading={leading}
81
- name={name}
82
- onChange={onChange}
83
- owner={owner}
84
- placeholder={placeholder}
85
- readOnly={readOnly}
86
- showClearButton={showClearButtonProp}
87
- size={size}
88
- trailing={trailing}
89
- type={type}
90
- value={value}
91
- />
120
+ data-bspk="input"
121
+ data-bspk-owner={owner || undefined}
122
+ data-disabled={disabled || undefined}
123
+ data-empty={!value.toString().length || undefined}
124
+ data-invalid={invalid || undefined}
125
+ data-readonly={readOnly || undefined}
126
+ data-show-clear-button={showClearButton || undefined}
127
+ data-size={size}
128
+ ref={containerRef}
129
+ >
130
+ {leading && <span data-leading>{leading}</span>}
131
+
132
+ <input
133
+ {...inputProps}
134
+ aria-describedby={ariaDescribedBy || undefined}
135
+ aria-errormessage={ariaErrorMessage || undefined}
136
+ aria-invalid={invalid || undefined}
137
+ aria-label={ariaLabel}
138
+ autoComplete={autoComplete}
139
+ data-main-input
140
+ disabled={disabled || undefined}
141
+ id={id}
142
+ name={name}
143
+ onChange={(event) => {
144
+ onChange(event.target.value, event);
145
+ }}
146
+ onFocus={(event) => {
147
+ inputProps?.onFocus?.(event);
148
+ }}
149
+ placeholder={placeholder || ' '}
150
+ readOnly={readOnly || undefined}
151
+ ref={(node) => {
152
+ if (!node) return;
153
+ inputRef?.(node);
154
+ inputRefInternal.current = node;
155
+ }}
156
+ required={required || undefined}
157
+ type={type}
158
+ value={value || ''}
159
+ />
160
+ {trailing && <span data-trailing>{trailing}</span>}
161
+ {showClearButton && (
162
+ <Button
163
+ data-clear-button
164
+ icon={<SvgCancel />}
165
+ iconOnly
166
+ label="Clear"
167
+ onClick={() => {
168
+ onChange('');
169
+ inputRefInternal.current?.focus();
170
+ }}
171
+ onFocus={() => {
172
+ focusTimeout.clear();
173
+ }}
174
+ size={size}
175
+ variant="tertiary"
176
+ />
177
+ )}
178
+ </div>
92
179
  );
93
180
  }
94
181
 
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { Input, InputProps } from '.';
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 type InputExampleProps = InputProps & { label: string; description?: string };
@@ -62,14 +62,12 @@ export const InputExample: ComponentExample<InputExampleProps> = {
62
62
  };
63
63
 
64
64
  export const Usage = () => {
65
- const [fieldDate, setFieldDate] = useState<string>();
65
+ const [value, setValue] = useState<string>();
66
66
 
67
67
  return (
68
68
  <div style={{ width: 320 }}>
69
- <Field>
70
- <FieldLabel>Example Label</FieldLabel>
71
- <Input name="example-name" onChange={setFieldDate} value={fieldDate} />
72
- <FieldDescription>This is an example input field.</FieldDescription>
69
+ <Field controlId="example-control-id" helperText="This is an example input field." label="Example Input">
70
+ <Input id="example-control-id" name="example-name" onChange={setValue} value={value} />
73
71
  </Field>
74
72
  </div>
75
73
  );
@@ -1,2 +1 @@
1
1
  export * from './Input';
2
- export * from './InputElement';
@@ -1,7 +1,8 @@
1
- import { FormField, FormFieldControlProps } from '-/components/FormField';
1
+ import { Field, ComposedFieldProps, propsWithAria } from '-/components/Field';
2
2
  import { Input, InputProps } from '-/components/Input';
3
+ import { useId } from '-/hooks/useId';
3
4
 
4
- export type InputFieldProps = FormFieldControlProps<InputProps>;
5
+ export type InputFieldProps = ComposedFieldProps<InputProps>;
5
6
 
6
7
  /**
7
8
  * A field wrapper for the Input component.
@@ -9,7 +10,7 @@ export type InputFieldProps = FormFieldControlProps<InputProps>;
9
10
  * This component takes properties from the FormField and Input components.
10
11
  *
11
12
  * @name InputField
12
- * @phase Stable
13
+ * @phase UXReview
13
14
  *
14
15
  * @generated
15
16
  */
@@ -19,18 +20,22 @@ export function InputField({
19
20
  labelTrailing,
20
21
  errorMessage,
21
22
  style,
23
+ id: idProp,
22
24
  ...controlProps
23
25
  }: InputFieldProps) {
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}
34
+ required={controlProps.required}
30
35
  style={style}
31
36
  >
32
- <Input {...controlProps} />
33
- </FormField>
37
+ <Input {...propsWithAria({ id, controlProps, errorMessage, helperText })} />
38
+ </Field>
34
39
  );
35
40
  }
36
41
 
@@ -1,7 +1,6 @@
1
1
  import './input-number.scss';
2
2
  import { useEffect, useRef } from 'react';
3
3
  import { IncrementButton } from './IncrementButton';
4
- import { useFieldInit } from '-/components/Field';
5
4
  import { useId } from '-/hooks/useId';
6
5
  import { CommonProps, FieldControlProps } from '-/types/common';
7
6
 
@@ -51,24 +50,25 @@ export type InputNumberProps = CommonProps<'size'> &
51
50
  * For a more complete example with field usage, see the InputNumberField component.
52
51
  *
53
52
  * @example
54
- * import { InputNumber } from '@bspk/ui/InputNumber';
53
+ * import { InputNumber } from '-/components/InputNumber';
55
54
  *
56
55
  * () => {
57
56
  * const [value, setValue] = useState<number | undefined>();
58
57
  *
59
58
  * return (
60
59
  * <div style={{ width: 320 }}>
61
- * <Field>
62
- * <FieldLabel>Example Input Number</FieldLabel>
60
+ * <Field
61
+ * controlId="example-input-number"
62
+ * helperText="The input number allows you to increment or decrement a value."
63
+ * label="Example Input Number"
64
+ * >
63
65
  * <InputNumber
64
66
  * aria-label="Example aria-label"
67
+ * id="example-input-number"
65
68
  * name="example-name"
66
69
  * onChange={(nextValue) => setValue(nextValue)}
67
70
  * value={value}
68
71
  * />
69
- * <FieldDescription>
70
- * The input number allows you to increment or decrement a value.
71
- * </FieldDescription>
72
72
  * </Field>
73
73
  * </div>
74
74
  * );
@@ -89,21 +89,16 @@ export function InputNumber({
89
89
  'aria-label': ariaLabel = 'Input number',
90
90
  max: maxProp,
91
91
  min = 0,
92
- invalid: invalidProp = false,
92
+ invalid = false,
93
93
  step = 1,
94
94
  required = false,
95
+ 'aria-describedby': ariaDescribedBy,
96
+ 'aria-errormessage': ariaErrorMessage,
95
97
  ...inputElementProps
96
98
  }: InputNumberProps) {
97
- const { id, ariaDescribedBy, ariaErrorMessage, invalid } = useFieldInit({
98
- idProp,
99
- required,
100
- disabled,
101
- readOnly,
102
- invalidProp,
103
- });
99
+ const inputId = useId(idProp);
104
100
  const max = typeof maxProp === 'number' && maxProp >= min ? maxProp : Number.MAX_SAFE_INTEGER;
105
101
  const centered = align !== 'left';
106
- const inputId = useId(id);
107
102
  const value = isNumber(valueProp, min);
108
103
  const removeDisabled = disabled || value + step * -1 < min;
109
104
  const addDisabled = disabled || value + step > max;
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { InputNumber, InputNumberProps } from './InputNumber';
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 InputNumberExample: ComponentExample<InputNumberProps> = {
@@ -18,15 +18,18 @@ export const Usage = () => {
18
18
 
19
19
  return (
20
20
  <div style={{ width: 320 }}>
21
- <Field>
22
- <FieldLabel>Example Input Number</FieldLabel>
21
+ <Field
22
+ controlId="example-input-number"
23
+ helperText="The input number allows you to increment or decrement a value."
24
+ label="Example Input Number"
25
+ >
23
26
  <InputNumber
24
27
  aria-label="Example aria-label"
28
+ id="example-input-number"
25
29
  name="example-name"
26
30
  onChange={(nextValue) => setValue(nextValue)}
27
31
  value={value}
28
32
  />
29
- <FieldDescription>The input number allows you to increment or decrement a value.</FieldDescription>
30
33
  </Field>
31
34
  </div>
32
35
  );
@@ -16,6 +16,7 @@
16
16
 
17
17
  &:focus-within {
18
18
  outline: solid 2px var(--stroke-neutral-focus);
19
+ isolation: isolate;
19
20
  }
20
21
 
21
22
  [data-divider] {
@@ -1,7 +1,8 @@
1
- import { FormField, FormFieldControlProps } from '-/components/FormField';
1
+ import { Field, ComposedFieldProps, propsWithAria } from '-/components/Field';
2
2
  import { InputNumber, InputNumberProps } from '-/components/InputNumber';
3
+ import { useId } from '-/hooks/useId';
3
4
 
4
- export type InputNumberFieldProps = FormFieldControlProps<InputNumberProps>;
5
+ export type InputNumberFieldProps = ComposedFieldProps<InputNumberProps>;
5
6
 
6
7
  /**
7
8
  * A field wrapper for the InputNumber component.
@@ -9,7 +10,7 @@ export type InputNumberFieldProps = FormFieldControlProps<InputNumberProps>;
9
10
  * This component takes properties from the FormField and InputNumber components.
10
11
  *
11
12
  * @name InputNumberField
12
- * @phase Stable
13
+ * @phase UXReview
13
14
  *
14
15
  * @generated
15
16
  */
@@ -19,18 +20,22 @@ export function InputNumberField({
19
20
  labelTrailing,
20
21
  errorMessage,
21
22
  style,
23
+ id: idProp,
22
24
  ...controlProps
23
25
  }: InputNumberFieldProps) {
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}
34
+ required={controlProps.required}
30
35
  style={style}
31
36
  >
32
- <InputNumber {...controlProps} />
33
- </FormField>
37
+ <InputNumber {...propsWithAria({ id, controlProps, errorMessage, helperText })} />
38
+ </Field>
34
39
  );
35
40
  }
36
41
 
@@ -3,12 +3,12 @@ import { SvgIcon } from '@bspk/icons/SvgIcon';
3
3
  import { AsYouType, getCountryCallingCode } from 'libphonenumber-js';
4
4
  import { useMemo, useRef, useState } from 'react';
5
5
  import { Button } from '-/components/Button';
6
- import { useFieldInit } from '-/components/Field';
7
- import { InputElement, InputProps } from '-/components/Input';
6
+ import { Input, InputProps } from '-/components/Input';
8
7
  import { ListItem } from '-/components/ListItem';
9
8
  import { Menu } from '-/components/Menu';
10
9
  import { useArrowNavigation } from '-/hooks/useArrowNavigation';
11
10
  import { useFloating } from '-/hooks/useFloating';
11
+ import { useId } from '-/hooks/useId';
12
12
  import { useOutsideClick } from '-/hooks/useOutsideClick';
13
13
  import { FieldControlProps } from '-/types/common';
14
14
  import { countryCodeData, countryCodes, SupportedCountryCode } from '-/utils/countryCodes';
@@ -57,26 +57,26 @@ export type InputPhoneProps = FieldControlProps<string, SupportedCountryCode> &
57
57
  * For a more complete example with field usage, see the InputPhoneField component.
58
58
  *
59
59
  * @example
60
- * import { InputPhone } from '@bspk/ui/InputPhone';
61
- * import { Field, FieldDescription, FieldLabel } from '@bspk/ui/Field';
60
+ * import { InputPhone } from '-/components/InputPhone';
62
61
  *
63
62
  * () => {
64
63
  * const [value, onChange] = useState<string | undefined>();
65
64
  *
66
65
  * return (
67
66
  * <div style={{ width: 320 }}>
68
- * <Field>
69
- * <FieldLabel>Example Input Phone</FieldLabel>
67
+ * <Field
68
+ * controlId="example-input-phone"
69
+ * helperText="The phone input allows you to enter a phone number with country code."
70
+ * label="Example Input Phone"
71
+ * >
70
72
  * <InputPhone
71
73
  * aria-label="Phone Number"
74
+ * id="example-input-phone"
72
75
  * initialCountryCode="US"
73
76
  * name="example-name"
74
77
  * onChange={onChange}
75
78
  * value={value}
76
79
  * />
77
- * <FieldDescription>
78
- * The phone input allows you to enter a phone number with country code.
79
- * </FieldDescription>
80
80
  * </Field>
81
81
  * </div>
82
82
  * );
@@ -94,20 +94,16 @@ export function InputPhone({
94
94
  readOnly,
95
95
  name,
96
96
  id: idProp,
97
- invalid: invalidProp,
97
+ invalid = false,
98
98
  required = false,
99
99
  size = 'medium',
100
100
  inputRef,
101
101
  scrollLimit = 5,
102
102
  'aria-label': ariaLabel = 'Phone number input',
103
+ 'aria-describedby': ariaDescribedBy,
104
+ 'aria-errormessage': ariaErrorMessage,
103
105
  }: InputPhoneProps) {
104
- const { id, ariaDescribedBy, ariaErrorMessage, invalid } = useFieldInit({
105
- idProp,
106
- required,
107
- disabled,
108
- readOnly,
109
- invalidProp,
110
- });
106
+ const id = useId(idProp);
111
107
  const menuId = useMemo(() => `${id}-menu`, [id]);
112
108
 
113
109
  const items = useIds(`input-phone-${id}`, SELECT_OPTIONS);
@@ -174,7 +170,7 @@ export function InputPhone({
174
170
  },
175
171
  })}
176
172
  >
177
- <InputElement
173
+ <Input
178
174
  aria-describedby={ariaDescribedBy}
179
175
  aria-errormessage={ariaErrorMessage}
180
176
  aria-label={ariaLabel || undefined}
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { InputPhone, InputPhoneProps } from '.';
3
- import { Field, FieldDescription, FieldLabel } from '-/components/Field';
3
+ import { Field } from '-/components/Field';
4
4
  import { Preset, ComponentExample } from '-/utils/demo';
5
5
 
6
6
  export const presets: Preset<InputPhoneProps>[] = [];
@@ -19,18 +19,19 @@ export const Usage = () => {
19
19
 
20
20
  return (
21
21
  <div style={{ width: 320 }}>
22
- <Field>
23
- <FieldLabel>Example Input Phone</FieldLabel>
22
+ <Field
23
+ controlId="example-input-phone"
24
+ helperText="The phone input allows you to enter a phone number with country code."
25
+ label="Example Input Phone"
26
+ >
24
27
  <InputPhone
25
28
  aria-label="Phone Number"
29
+ id="example-input-phone"
26
30
  initialCountryCode="US"
27
31
  name="example-name"
28
32
  onChange={onChange}
29
33
  value={value}
30
34
  />
31
- <FieldDescription>
32
- The phone input allows you to enter a phone number with country code.
33
- </FieldDescription>
34
35
  </Field>
35
36
  </div>
36
37
  );
@@ -12,6 +12,7 @@
12
12
 
13
13
  input:focus-visible {
14
14
  outline: solid 2px var(--stroke-neutral-focus);
15
+ isolation: isolate;
15
16
  border-radius: var(--radius-sm);
16
17
  }
17
18
 
@@ -1,7 +1,8 @@
1
- import { FormField, FormFieldControlProps } from '-/components/FormField';
1
+ import { Field, ComposedFieldProps, propsWithAria } from '-/components/Field';
2
2
  import { InputPhone, InputPhoneProps } from '-/components/InputPhone';
3
+ import { useId } from '-/hooks/useId';
3
4
 
4
- export type InputPhoneFieldProps = FormFieldControlProps<InputPhoneProps>;
5
+ export type InputPhoneFieldProps = ComposedFieldProps<InputPhoneProps>;
5
6
 
6
7
  /**
7
8
  * A field wrapper for the InputPhone component.
@@ -9,7 +10,7 @@ export type InputPhoneFieldProps = FormFieldControlProps<InputPhoneProps>;
9
10
  * This component takes properties from the FormField and InputPhone components.
10
11
  *
11
12
  * @name InputPhoneField
12
- * @phase Stable
13
+ * @phase UXReview
13
14
  *
14
15
  * @generated
15
16
  */
@@ -19,18 +20,22 @@ export function InputPhoneField({
19
20
  labelTrailing,
20
21
  errorMessage,
21
22
  style,
23
+ id: idProp,
22
24
  ...controlProps
23
25
  }: InputPhoneFieldProps) {
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}
34
+ required={controlProps.required}
30
35
  style={style}
31
36
  >
32
- <InputPhone {...controlProps} />
33
- </FormField>
37
+ <InputPhone {...propsWithAria({ id, controlProps, errorMessage, helperText })} />
38
+ </Field>
34
39
  );
35
40
  }
36
41
 
@@ -1,4 +1,3 @@
1
- import './link.scss';
2
1
  import { AnchorHTMLAttributes, ComponentType, lazy, LazyExoticComponent, Suspense } from 'react';
3
2
  import { CommonPropsLibrary, ElementProps } from '-/types/common';
4
3
 
@@ -24,6 +24,7 @@
24
24
  &:focus-visible,
25
25
  &:has(*:focus-visible) {
26
26
  outline: solid 2px var(--stroke-neutral-focus);
27
+ isolation: isolate;
27
28
 
28
29
  [data-inner] {
29
30
  border-color: transparent;