@hyphen/hyphen-components 2.9.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 (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/package.json +138 -0
  4. package/src/components/Alert/Alert.constants.ts +19 -0
  5. package/src/components/Alert/Alert.mdx +29 -0
  6. package/src/components/Alert/Alert.module.scss +74 -0
  7. package/src/components/Alert/Alert.stories.tsx +102 -0
  8. package/src/components/Alert/Alert.test.tsx +187 -0
  9. package/src/components/Alert/Alert.tsx +157 -0
  10. package/src/components/Alert/Alert.types.ts +14 -0
  11. package/src/components/Badge/Badge.mdx +28 -0
  12. package/src/components/Badge/Badge.module.scss +155 -0
  13. package/src/components/Badge/Badge.stories.tsx +52 -0
  14. package/src/components/Badge/Badge.test.tsx +74 -0
  15. package/src/components/Badge/Badge.tsx +70 -0
  16. package/src/components/Box/Box.mdx +259 -0
  17. package/src/components/Box/Box.module.scss +16 -0
  18. package/src/components/Box/Box.stories.tsx +1679 -0
  19. package/src/components/Box/Box.test.tsx +478 -0
  20. package/src/components/Box/Box.tsx +636 -0
  21. package/src/components/Button/Button.constants.ts +10 -0
  22. package/src/components/Button/Button.mdx +71 -0
  23. package/src/components/Button/Button.module.scss +312 -0
  24. package/src/components/Button/Button.stories.tsx +117 -0
  25. package/src/components/Button/Button.test.tsx +460 -0
  26. package/src/components/Button/Button.tsx +241 -0
  27. package/src/components/Card/Card.mdx +46 -0
  28. package/src/components/Card/Card.module.scss +6 -0
  29. package/src/components/Card/Card.stories.tsx +101 -0
  30. package/src/components/Card/Card.test.tsx +11 -0
  31. package/src/components/Card/Card.tsx +61 -0
  32. package/src/components/Card/components/CardFooter/CardFooter.test.tsx +11 -0
  33. package/src/components/Card/components/CardFooter/CardFooter.tsx +35 -0
  34. package/src/components/Card/components/CardHeader/CardHeader.test.tsx +23 -0
  35. package/src/components/Card/components/CardHeader/CardHeader.tsx +54 -0
  36. package/src/components/Card/components/CardSection/CardSection.test.tsx +28 -0
  37. package/src/components/Card/components/CardSection/CardSection.tsx +102 -0
  38. package/src/components/Card/components/index.ts +3 -0
  39. package/src/components/CheckboxInput/CheckboxInput.mdx +98 -0
  40. package/src/components/CheckboxInput/CheckboxInput.stories.tsx +254 -0
  41. package/src/components/CheckboxInput/CheckboxInput.test.tsx +436 -0
  42. package/src/components/CheckboxInput/CheckboxInput.tsx +171 -0
  43. package/src/components/CheckboxInput/components/Checkbox.module.scss +174 -0
  44. package/src/components/CheckboxInput/components/Checkbox.test.tsx +201 -0
  45. package/src/components/CheckboxInput/components/Checkbox.tsx +176 -0
  46. package/src/components/CheckboxInput/components/CheckboxIcon.tsx +71 -0
  47. package/src/components/DateInput/DateInput.mdx +61 -0
  48. package/src/components/DateInput/DateInput.stories.tsx +168 -0
  49. package/src/components/DateInput/DateInput.test.tsx +258 -0
  50. package/src/components/DateInput/DateInput.tsx +189 -0
  51. package/src/components/DatePicker/DatePicker.mdx +52 -0
  52. package/src/components/DatePicker/DatePicker.module.scss +603 -0
  53. package/src/components/DatePicker/DatePicker.stories.tsx +199 -0
  54. package/src/components/DatePicker/DatePicker.test.tsx +26 -0
  55. package/src/components/DatePicker/DatePicker.tsx +138 -0
  56. package/src/components/Details/Details.mdx +30 -0
  57. package/src/components/Details/Details.module.scss +32 -0
  58. package/src/components/Details/Details.stories.tsx +38 -0
  59. package/src/components/Details/Details.test.tsx +189 -0
  60. package/src/components/Details/Details.tsx +51 -0
  61. package/src/components/Details/DetailsSummary.tsx +65 -0
  62. package/src/components/Drawer/Drawer.mdx +117 -0
  63. package/src/components/Drawer/Drawer.module.scss +96 -0
  64. package/src/components/Drawer/Drawer.stories.tsx +380 -0
  65. package/src/components/Drawer/Drawer.test.tsx +90 -0
  66. package/src/components/Drawer/Drawer.tsx +249 -0
  67. package/src/components/FormControl/FormControl.tsx +78 -0
  68. package/src/components/FormLabel/FormLabel.mdx +24 -0
  69. package/src/components/FormLabel/FormLabel.module.scss +19 -0
  70. package/src/components/FormLabel/FormLabel.stories.tsx +20 -0
  71. package/src/components/FormLabel/FormLabel.test.tsx +35 -0
  72. package/src/components/FormLabel/FormLabel.tsx +96 -0
  73. package/src/components/Formik/Formik.mdx +10 -0
  74. package/src/components/Formik/Formik.stories.tsx +307 -0
  75. package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.test.tsx +172 -0
  76. package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.tsx +41 -0
  77. package/src/components/Formik/FormikRadioGroup/FormikRadioGroup.test.tsx +205 -0
  78. package/src/components/Formik/FormikRadioGroup/FormikRadioGroup.tsx +37 -0
  79. package/src/components/Formik/FormikSelectInput/FormikSelectInput.test.tsx +210 -0
  80. package/src/components/Formik/FormikSelectInput/FormikSelectInput.tsx +41 -0
  81. package/src/components/Formik/FormikSelectInputInset/FormikSelectInputInset.test.tsx +153 -0
  82. package/src/components/Formik/FormikSelectInputInset/FormikSelectInputInset.tsx +44 -0
  83. package/src/components/Formik/FormikSelectInputNative/FormikSelectInputNative.test.tsx +161 -0
  84. package/src/components/Formik/FormikSelectInputNative/FormikSelectInputNative.tsx +46 -0
  85. package/src/components/Formik/FormikTextInput/FormikTextInput.test.tsx +176 -0
  86. package/src/components/Formik/FormikTextInput/FormikTextInput.tsx +38 -0
  87. package/src/components/Formik/FormikTextInputInset/FormikTextInputInset.test.tsx +170 -0
  88. package/src/components/Formik/FormikTextInputInset/FormikTextInputInset.tsx +42 -0
  89. package/src/components/Formik/FormikTextareaInput/FormikTextareaInput.test.tsx +186 -0
  90. package/src/components/Formik/FormikTextareaInput/FormikTextareaInput.tsx +42 -0
  91. package/src/components/Formik/FormikTextareaInputInset/FormikTextareaInputInset.test.tsx +179 -0
  92. package/src/components/Formik/FormikTextareaInputInset/FormikTextareaInputInset.tsx +42 -0
  93. package/src/components/Formik/FormikTimePicker/FormikTimePicker.test.tsx +224 -0
  94. package/src/components/Formik/FormikTimePicker/FormikTimePicker.tsx +37 -0
  95. package/src/components/Formik/FormikTimePickerNative/FormikTimePickerNative.test.tsx +175 -0
  96. package/src/components/Formik/FormikTimePickerNative/FormikTimePickerNative.tsx +38 -0
  97. package/src/components/Formik/FormikToggle/FormikToggle.test.tsx +172 -0
  98. package/src/components/Formik/FormikToggle/FormikToggle.tsx +38 -0
  99. package/src/components/Heading/Heading.constants.ts +19 -0
  100. package/src/components/Heading/Heading.mdx +35 -0
  101. package/src/components/Heading/Heading.module.scss +5 -0
  102. package/src/components/Heading/Heading.stories.tsx +90 -0
  103. package/src/components/Heading/Heading.test.tsx +67 -0
  104. package/src/components/Heading/Heading.tsx +67 -0
  105. package/src/components/HelpText/HelpText.module.scss +14 -0
  106. package/src/components/HelpText/HelpText.tsx +33 -0
  107. package/src/components/Icon/Icon.mdx +40 -0
  108. package/src/components/Icon/Icon.stories.tsx +72 -0
  109. package/src/components/Icon/Icon.test.tsx +30 -0
  110. package/src/components/Icon/Icon.tsx +61 -0
  111. package/src/components/InputValidationMessage/InputValidationMessage.module.scss +3 -0
  112. package/src/components/InputValidationMessage/InputValidationMessage.tsx +27 -0
  113. package/src/components/Modal/Modal.mdx +60 -0
  114. package/src/components/Modal/Modal.module.scss +135 -0
  115. package/src/components/Modal/Modal.stories.tsx +194 -0
  116. package/src/components/Modal/Modal.test.tsx +81 -0
  117. package/src/components/Modal/Modal.tsx +174 -0
  118. package/src/components/Modal/components/ModalBody/ModalBody.test.tsx +20 -0
  119. package/src/components/Modal/components/ModalBody/ModalBody.tsx +24 -0
  120. package/src/components/Modal/components/ModalFooter/ModalFooter.test.tsx +32 -0
  121. package/src/components/Modal/components/ModalFooter/ModalFooter.tsx +37 -0
  122. package/src/components/Modal/components/ModalHeader/ModalHeader.test.tsx +29 -0
  123. package/src/components/Modal/components/ModalHeader/ModalHeader.tsx +58 -0
  124. package/src/components/Modal/components/index.ts +5 -0
  125. package/src/components/Pagination/Pagination.mdx +26 -0
  126. package/src/components/Pagination/Pagination.stories.tsx +55 -0
  127. package/src/components/Pagination/Pagination.test.tsx +225 -0
  128. package/src/components/Pagination/Pagination.tsx +162 -0
  129. package/src/components/Pagination/Pagination.utilities.test.ts +133 -0
  130. package/src/components/Pagination/Pagination.utilities.ts +101 -0
  131. package/src/components/Popover/Popover.mdx +104 -0
  132. package/src/components/Popover/Popover.module.scss +74 -0
  133. package/src/components/Popover/Popover.stories.tsx +471 -0
  134. package/src/components/Popover/Popover.test.tsx +128 -0
  135. package/src/components/Popover/Popover.tsx +277 -0
  136. package/src/components/RadioGroup/RadioGroup.mdx +81 -0
  137. package/src/components/RadioGroup/RadioGroup.module.scss +23 -0
  138. package/src/components/RadioGroup/RadioGroup.stories.tsx +375 -0
  139. package/src/components/RadioGroup/RadioGroup.test.tsx +282 -0
  140. package/src/components/RadioGroup/RadioGroup.tsx +145 -0
  141. package/src/components/RadioGroup/RadioInput/RadioInput.module.scss +114 -0
  142. package/src/components/RadioGroup/RadioInput/RadioInput.test.tsx +156 -0
  143. package/src/components/RadioGroup/RadioInput/RadioInput.tsx +148 -0
  144. package/src/components/RadioGroup/RadioInput/RadioInputIcon.tsx +59 -0
  145. package/src/components/ResponsiveProvider/ResponsiveProvider.mdx +36 -0
  146. package/src/components/ResponsiveProvider/ResponsiveProvider.stories.tsx +54 -0
  147. package/src/components/ResponsiveProvider/ResponsiveProvider.test.tsx +70 -0
  148. package/src/components/ResponsiveProvider/ResponsiveProvider.tsx +73 -0
  149. package/src/components/SelectInput/SelectInput.mdx +115 -0
  150. package/src/components/SelectInput/SelectInput.module.scss +357 -0
  151. package/src/components/SelectInput/SelectInput.stories.tsx +373 -0
  152. package/src/components/SelectInput/SelectInput.test.tsx +403 -0
  153. package/src/components/SelectInput/SelectInput.tsx +245 -0
  154. package/src/components/SelectInputInset/SelectInputInset.mdx +56 -0
  155. package/src/components/SelectInputInset/SelectInputInset.module.scss +397 -0
  156. package/src/components/SelectInputInset/SelectInputInset.stories.tsx +189 -0
  157. package/src/components/SelectInputInset/SelectInputInset.test.tsx +305 -0
  158. package/src/components/SelectInputInset/SelectInputInset.tsx +235 -0
  159. package/src/components/SelectInputNative/SelectInputNative.mdx +87 -0
  160. package/src/components/SelectInputNative/SelectInputNative.module.scss +356 -0
  161. package/src/components/SelectInputNative/SelectInputNative.stories.tsx +282 -0
  162. package/src/components/SelectInputNative/SelectInputNative.test.tsx +341 -0
  163. package/src/components/SelectInputNative/SelectInputNative.tsx +121 -0
  164. package/src/components/Spinner/Spinner.mdx +29 -0
  165. package/src/components/Spinner/Spinner.module.scss +16 -0
  166. package/src/components/Spinner/Spinner.stories.tsx +48 -0
  167. package/src/components/Spinner/Spinner.test.tsx +47 -0
  168. package/src/components/Spinner/Spinner.tsx +116 -0
  169. package/src/components/Table/Table.mdx +216 -0
  170. package/src/components/Table/Table.module.scss +61 -0
  171. package/src/components/Table/Table.stories.tsx +884 -0
  172. package/src/components/Table/Table.test.tsx +437 -0
  173. package/src/components/Table/Table.tsx +171 -0
  174. package/src/components/Table/TableBody/TableBody.module.scss +19 -0
  175. package/src/components/Table/TableBody/TableBody.test.tsx +38 -0
  176. package/src/components/Table/TableBody/TableBody.tsx +96 -0
  177. package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.module.scss +47 -0
  178. package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.test.tsx +81 -0
  179. package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.tsx +94 -0
  180. package/src/components/Table/TableHead/TableHead.test.tsx +20 -0
  181. package/src/components/Table/TableHead/TableHead.tsx +78 -0
  182. package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.module.scss +72 -0
  183. package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.test.tsx +187 -0
  184. package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.tsx +192 -0
  185. package/src/components/Table/common/TableRow/TableRow.module.scss +5 -0
  186. package/src/components/Table/common/TableRow/TableRow.test.tsx +52 -0
  187. package/src/components/Table/common/TableRow/TableRow.tsx +155 -0
  188. package/src/components/TextInput/TextInput.mdx +96 -0
  189. package/src/components/TextInput/TextInput.module.scss +405 -0
  190. package/src/components/TextInput/TextInput.stories.tsx +268 -0
  191. package/src/components/TextInput/TextInput.test.tsx +231 -0
  192. package/src/components/TextInput/TextInput.tsx +263 -0
  193. package/src/components/TextInputInset/TextInputInset.mdx +62 -0
  194. package/src/components/TextInputInset/TextInputInset.module.scss +418 -0
  195. package/src/components/TextInputInset/TextInputInset.stories.tsx +213 -0
  196. package/src/components/TextInputInset/TextInputInset.test.tsx +222 -0
  197. package/src/components/TextInputInset/TextInputInset.tsx +261 -0
  198. package/src/components/TextareaInput/TextareaInput.mdx +117 -0
  199. package/src/components/TextareaInput/TextareaInput.module.scss +275 -0
  200. package/src/components/TextareaInput/TextareaInput.stories.tsx +293 -0
  201. package/src/components/TextareaInput/TextareaInput.test.tsx +195 -0
  202. package/src/components/TextareaInput/TextareaInput.tsx +182 -0
  203. package/src/components/TextareaInputInset/TextareaInputInset.mdx +55 -0
  204. package/src/components/TextareaInputInset/TextareaInputInset.module.scss +337 -0
  205. package/src/components/TextareaInputInset/TextareaInputInset.stories.tsx +160 -0
  206. package/src/components/TextareaInputInset/TextareaInputInset.test.tsx +199 -0
  207. package/src/components/TextareaInputInset/TextareaInputInset.tsx +213 -0
  208. package/src/components/ThemeProvider/ThemeProvider.mdx +11 -0
  209. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +56 -0
  210. package/src/components/ThemeProvider/ThemeProvider.tsx +75 -0
  211. package/src/components/TimePicker/TimePicker.mdx +75 -0
  212. package/src/components/TimePicker/TimePicker.stories.tsx +149 -0
  213. package/src/components/TimePicker/TimePicker.test.tsx +97 -0
  214. package/src/components/TimePicker/TimePicker.tsx +83 -0
  215. package/src/components/TimePickerNative/TimePickerNative.mdx +67 -0
  216. package/src/components/TimePickerNative/TimePickerNative.stories.tsx +151 -0
  217. package/src/components/TimePickerNative/TimePickerNative.test.tsx +117 -0
  218. package/src/components/TimePickerNative/TimePickerNative.tsx +93 -0
  219. package/src/components/Toast/Toast.mdx +134 -0
  220. package/src/components/Toast/Toast.store.ts +280 -0
  221. package/src/components/Toast/Toast.stories.tsx +283 -0
  222. package/src/components/Toast/Toast.test.tsx +784 -0
  223. package/src/components/Toast/Toast.types.ts +98 -0
  224. package/src/components/Toast/ToastContainer.tsx +170 -0
  225. package/src/components/Toast/ToastNotification.module.scss +63 -0
  226. package/src/components/Toast/ToastNotification.tsx +176 -0
  227. package/src/components/Toast/index.ts +4 -0
  228. package/src/components/Toast/toast.ts +102 -0
  229. package/src/components/Toast/useToasts.ts +102 -0
  230. package/src/components/Toggle/Toggle.mdx +51 -0
  231. package/src/components/Toggle/Toggle.module.scss +294 -0
  232. package/src/components/Toggle/Toggle.stories.tsx +128 -0
  233. package/src/components/Toggle/Toggle.test.tsx +308 -0
  234. package/src/components/Toggle/Toggle.tsx +184 -0
  235. package/src/constants/keyCodes.ts +2 -0
  236. package/src/docs/Brands.mdx +153 -0
  237. package/src/docs/Colors.mdx +158 -0
  238. package/src/docs/DesignTokens.mdx +415 -0
  239. package/src/docs/GetStarted.mdx +47 -0
  240. package/src/docs/intro.mdx +12 -0
  241. package/src/fonts/AvenirBold.otf +0 -0
  242. package/src/fonts/AvenirBold.woff +0 -0
  243. package/src/fonts/AvenirBold.woff2 +0 -0
  244. package/src/fonts/AvenirLight.otf +0 -0
  245. package/src/fonts/AvenirLight.woff +0 -0
  246. package/src/fonts/AvenirLight.woff2 +0 -0
  247. package/src/fonts/AvenirRegular.otf +0 -0
  248. package/src/fonts/AvenirRegular.woff +0 -0
  249. package/src/fonts/AvenirRegular.woff2 +0 -0
  250. package/src/fonts/Geist-Bold.otf +0 -0
  251. package/src/fonts/Geist-Bold.woff +0 -0
  252. package/src/fonts/Geist-Bold.woff2 +0 -0
  253. package/src/fonts/Geist-Medium.otf +0 -0
  254. package/src/fonts/Geist-Medium.woff +0 -0
  255. package/src/fonts/Geist-Medium.woff2 +0 -0
  256. package/src/fonts/Geist-Regular.otf +0 -0
  257. package/src/fonts/Geist-Regular.woff +0 -0
  258. package/src/fonts/Geist-Regular.woff2 +0 -0
  259. package/src/fonts/Geist-SemiBold.otf +0 -0
  260. package/src/fonts/Geist-SemiBold.woff +0 -0
  261. package/src/fonts/Geist-SemiBold.woff2 +0 -0
  262. package/src/fonts/GeistMono-Regular.otf +0 -0
  263. package/src/fonts/GeistMono-Regular.woff +0 -0
  264. package/src/fonts/GeistMono-Regular.woff2 +0 -0
  265. package/src/hooks/index.ts +4 -0
  266. package/src/hooks/useBreakpoint/useBreakpoint.mdx +26 -0
  267. package/src/hooks/useBreakpoint/useBreakpoint.stories.tsx +30 -0
  268. package/src/hooks/useBreakpoint/useBreakpoint.test.tsx +19 -0
  269. package/src/hooks/useBreakpoint/useBreakpoint.ts +50 -0
  270. package/src/hooks/useIsomorphicLayoutEffect/useIsomorphicLayouEffect.ts +5 -0
  271. package/src/hooks/useOpenClose/useOpenClose.mdx +15 -0
  272. package/src/hooks/useOpenClose/useOpenClose.stories.tsx +41 -0
  273. package/src/hooks/useOpenClose/useOpenClose.test.tsx +119 -0
  274. package/src/hooks/useOpenClose/useOpenClose.tsx +95 -0
  275. package/src/hooks/useWindowSize/useWindowSize.mdx +25 -0
  276. package/src/hooks/useWindowSize/useWindowSize.stories.tsx +35 -0
  277. package/src/hooks/useWindowSize/useWindowSize.ts +24 -0
  278. package/src/index.ts +48 -0
  279. package/src/lib/cssShorthandToClasses.test.ts +149 -0
  280. package/src/lib/cssShorthandToClasses.ts +133 -0
  281. package/src/lib/doesStringIncludeCssUnit.ts +6 -0
  282. package/src/lib/generateResponsiveClasses.test.ts +24 -0
  283. package/src/lib/generateResponsiveClasses.ts +30 -0
  284. package/src/lib/getAutoCompleteValue.test.ts +27 -0
  285. package/src/lib/getAutoCompleteValue.ts +12 -0
  286. package/src/lib/getColumnKeys.ts +27 -0
  287. package/src/lib/getDimensionCss.test.ts +148 -0
  288. package/src/lib/getDimensionCss.ts +73 -0
  289. package/src/lib/getElementType.test.tsx +42 -0
  290. package/src/lib/getElementType.ts +42 -0
  291. package/src/lib/getFlexCss.test.ts +122 -0
  292. package/src/lib/getFlexCss.ts +67 -0
  293. package/src/lib/index.ts +15 -0
  294. package/src/lib/isFunction.ts +6 -0
  295. package/src/lib/mergeRefs.ts +15 -0
  296. package/src/lib/prefersReducedMotion.ts +12 -0
  297. package/src/lib/react-children-utilities/filter.ts +12 -0
  298. package/src/lib/react-children-utilities/index.ts +1 -0
  299. package/src/lib/reactRouterClickHandler.ts +37 -0
  300. package/src/lib/resolveValue.ts +7 -0
  301. package/src/lib/tokens.ts +139 -0
  302. package/src/modes.ts +8 -0
  303. package/src/styles/animation.scss +152 -0
  304. package/src/styles/cursor.scss +43 -0
  305. package/src/styles/display.scss +119 -0
  306. package/src/styles/flex.scss +453 -0
  307. package/src/styles/fonts.scss +44 -0
  308. package/src/styles/globals/utilities.scss +4 -0
  309. package/src/styles/mixins.scss +14 -0
  310. package/src/styles/overflow.scss +41 -0
  311. package/src/styles/position.scss +45 -0
  312. package/src/styles/reset.scss +108 -0
  313. package/src/styles/text-align.scss +21 -0
  314. package/src/styles/utilities.scss +9 -0
  315. package/src/styles/variables/forms.scss +71 -0
  316. package/src/styles/variables/index.scss +3 -0
  317. package/src/styles/white-space.scss +21 -0
  318. package/src/types/index.ts +201 -0
  319. package/src/types/lib.types.ts +3 -0
@@ -0,0 +1,254 @@
1
+ import React, { ChangeEvent, useState } from 'react';
2
+ import type { Meta } from '@storybook/react';
3
+ import { CheckboxInput } from './CheckboxInput';
4
+ import { Box } from '../Box/Box';
5
+
6
+ const meta: Meta<typeof CheckboxInput> = {
7
+ title: 'Components/CheckboxInput',
8
+ component: CheckboxInput,
9
+ };
10
+
11
+ export default meta;
12
+
13
+ export const Basic = () => (
14
+ <CheckboxInput
15
+ id="example"
16
+ label="Checkbox with a label"
17
+ isChecked
18
+ onChange={() => {}}
19
+ />
20
+ );
21
+
22
+ export const Default = () => {
23
+ const [value, setValue] = useState(false);
24
+ return (
25
+ <CheckboxInput
26
+ id="defaultStateIsUnchecked"
27
+ label="Label"
28
+ onChange={(event) => setValue(event.target.checked)}
29
+ isChecked={value}
30
+ />
31
+ );
32
+ };
33
+
34
+ export const States = () => (
35
+ <Box gap="md">
36
+ <CheckboxInput
37
+ id="statesUnchecked"
38
+ label="Unchecked"
39
+ onChange={() => {}}
40
+ isChecked={false}
41
+ />
42
+ <CheckboxInput
43
+ id="statesCHecked"
44
+ label="Checked"
45
+ onChange={() => {}}
46
+ isChecked={true}
47
+ />
48
+ <CheckboxInput
49
+ id="statesUnchecked"
50
+ label="Indeterminate"
51
+ onChange={() => {}}
52
+ isChecked={true}
53
+ isIndeterminate={true}
54
+ />
55
+ </Box>
56
+ );
57
+
58
+ export const IndeterminateCheckboxes = () => {
59
+ const [exampleOneChildOne, setExampleOneChildOne] = useState(false);
60
+ const [exampleOneChildTwo, setExampleOneChildTwo] = useState(true);
61
+ const handleParentChange = (event: ChangeEvent<HTMLInputElement>) => {
62
+ setExampleOneChildOne(event.target.checked);
63
+ setExampleOneChildTwo(event.target.checked);
64
+ };
65
+ return (
66
+ <Box gap="md">
67
+ <Box display="block" fontWeight="bold">
68
+ Nested Checkboxes (select all)
69
+ </Box>
70
+ <Box gap="sm">
71
+ <CheckboxInput
72
+ id="statesUnchecked"
73
+ label="Parent"
74
+ onChange={handleParentChange}
75
+ isChecked={exampleOneChildOne || exampleOneChildTwo}
76
+ isIndeterminate={exampleOneChildOne !== exampleOneChildTwo}
77
+ />
78
+ <Box padding="0 0 0 sm" gap="sm">
79
+ <CheckboxInput
80
+ id="statesUnchecked"
81
+ label="Child One"
82
+ onChange={(event) => setExampleOneChildOne(event.target.checked)}
83
+ isChecked={exampleOneChildOne}
84
+ />
85
+ <CheckboxInput
86
+ id="statesUnchecked"
87
+ label="Child Two"
88
+ onChange={(event) => setExampleOneChildTwo(event.target.checked)}
89
+ isChecked={exampleOneChildTwo}
90
+ />
91
+ </Box>
92
+ </Box>
93
+ </Box>
94
+ );
95
+ };
96
+
97
+ export const Required = () => {
98
+ const [value, setValue] = useState(false);
99
+ return (
100
+ <CheckboxInput
101
+ id="requiredCheckboxIsUnchecked"
102
+ label="Required Checkbox"
103
+ isChecked={value}
104
+ onChange={(event) => setValue(event.target.checked)}
105
+ isRequired
106
+ />
107
+ );
108
+ };
109
+
110
+ export const CustomRequiredIndicator = () => {
111
+ const [value, setValue] = useState(false);
112
+ const [value2, setValue2] = useState(false);
113
+ return (
114
+ <Box gap="md">
115
+ <CheckboxInput
116
+ id="requiredCheckboxNull"
117
+ label="Required Without Indicator"
118
+ isChecked={value}
119
+ onChange={(event) => setValue(event.target.checked)}
120
+ isRequired
121
+ requiredIndicator={null}
122
+ />
123
+ <CheckboxInput
124
+ id="requiredCheckboxCustom"
125
+ label="Required Custom Indicator"
126
+ isChecked={value2}
127
+ onChange={(event) => setValue2(event.target.checked)}
128
+ isRequired
129
+ requiredIndicator=" (required)"
130
+ />
131
+ </Box>
132
+ );
133
+ };
134
+
135
+ export const Sizes = () => {
136
+ const [sm, setSm] = useState(false);
137
+ const [md, setMd] = useState(false);
138
+ const [lg, setLg] = useState(false);
139
+ const [responsive, setResponsive] = useState(false);
140
+ return (
141
+ <Box gap="md">
142
+ <CheckboxInput
143
+ id="smCheckboxInput"
144
+ label="Small checkbox"
145
+ helpText="More helpful text about this checkbox"
146
+ isChecked={sm}
147
+ onChange={(event) => setSm(event.target.checked)}
148
+ size="sm"
149
+ />
150
+ <CheckboxInput
151
+ id="mdCheckboxInput"
152
+ label="Medium checkbox"
153
+ helpText="More helpful text about this checkbox"
154
+ isChecked={md}
155
+ onChange={(event) => setMd(event.target.checked)}
156
+ size="md"
157
+ />
158
+ <CheckboxInput
159
+ id="lgCheckboxInput"
160
+ label="Large checkbox"
161
+ helpText="More helpful text about this checkbox"
162
+ isChecked={lg}
163
+ onChange={(event) => setLg(event.target.checked)}
164
+ size="lg"
165
+ />
166
+ <CheckboxInput
167
+ id="responsiveCheckboxInput"
168
+ label="Responsive checkbox"
169
+ helpText="Will change sizes depending on viewport width"
170
+ isChecked={responsive}
171
+ onChange={(event) => setResponsive(event.target.checked)}
172
+ size={{ base: 'sm', tablet: 'md', desktop: 'lg', hd: 'sm' }}
173
+ />
174
+ </Box>
175
+ );
176
+ };
177
+
178
+ export const HelpText = () => {
179
+ const [value, setValue] = useState(false);
180
+ return (
181
+ <CheckboxInput
182
+ id="helpTextCheckbox"
183
+ label="Checkbox with help text"
184
+ helpText="More helpful text about this checkbox"
185
+ isChecked={value}
186
+ onChange={(event) => setValue(event.target.checked)}
187
+ />
188
+ );
189
+ };
190
+
191
+ export const CheckedInitialState = () => {
192
+ const [value, setValue] = useState(true);
193
+ return (
194
+ <CheckboxInput
195
+ id="initialStateChecked"
196
+ label="Label"
197
+ onChange={(event) => setValue(event.target.checked)}
198
+ isChecked={value}
199
+ />
200
+ );
201
+ };
202
+
203
+ export const HiddenLabel = () => {
204
+ const [value, setValue] = useState(false);
205
+ return (
206
+ <CheckboxInput
207
+ id="hiddenLabel"
208
+ label="Label"
209
+ hideLabel
210
+ onChange={(event) => setValue(event.target.checked)}
211
+ isChecked={value}
212
+ />
213
+ );
214
+ };
215
+
216
+ export const DisabledAndUnchecked = () => {
217
+ const [value, setValue] = useState(false);
218
+ return (
219
+ <CheckboxInput
220
+ id="disabledAndUnchecked"
221
+ label="Label"
222
+ isChecked={value}
223
+ onChange={(event) => setValue(event.target.checked)}
224
+ isDisabled
225
+ />
226
+ );
227
+ };
228
+
229
+ export const DisabledAndChecked = () => {
230
+ const [value, setValue] = useState(true);
231
+ return (
232
+ <CheckboxInput
233
+ id="disabledAndUnchecked"
234
+ label="Label"
235
+ isChecked={value}
236
+ onChange={(event) => setValue(event.target.checked)}
237
+ isDisabled
238
+ />
239
+ );
240
+ };
241
+
242
+ export const Error = () => {
243
+ const [value, setValue] = useState(false);
244
+ return (
245
+ <CheckboxInput
246
+ id="invalidCheckbox"
247
+ label="Label"
248
+ isChecked={value}
249
+ onChange={(event) => setValue(event.target.checked)}
250
+ isRequired
251
+ error="You must accept the Terms and Conditions"
252
+ />
253
+ );
254
+ };
@@ -0,0 +1,436 @@
1
+ import React from 'react';
2
+ import { render, fireEvent, screen } from '@testing-library/react';
3
+ import { CheckboxInput } from './CheckboxInput';
4
+ import { FormLabel } from '../FormLabel/FormLabel';
5
+ import { CheckboxSize } from './components/Checkbox';
6
+ jest.mock('../FormLabel/FormLabel');
7
+
8
+ describe('CheckboxInput', () => {
9
+ beforeEach(() => {
10
+ (FormLabel as jest.Mock).mockReturnValue(<div />);
11
+ });
12
+
13
+ afterEach(() => {
14
+ jest.resetAllMocks();
15
+ });
16
+
17
+ test('not disabled, checked, or invalid by default', () => {
18
+ const { getByLabelText } = render(
19
+ <CheckboxInput
20
+ id="testCheckbox"
21
+ label="test checkbox"
22
+ isChecked={false}
23
+ onChange={() => null}
24
+ />
25
+ );
26
+ const checkbox = getByLabelText('test checkbox') as HTMLInputElement;
27
+
28
+ expect(checkbox.checked).toBe(false);
29
+ expect(checkbox.disabled).toBe(false);
30
+ expect(checkbox.getAttribute('aria-invalid')).toBe('false');
31
+ });
32
+
33
+ test('it calls FormLabel with the correct props', () => {
34
+ const { getByLabelText } = render(
35
+ <CheckboxInput
36
+ id="testCheckbox"
37
+ label="test checkbox"
38
+ onChange={() => null}
39
+ isChecked={false}
40
+ helpText="i am help text"
41
+ />
42
+ );
43
+ expect(getByLabelText('test checkbox')).toBeDefined();
44
+ expect(FormLabel).toHaveBeenCalledTimes(1);
45
+ expect(FormLabel).toHaveBeenCalledWith(
46
+ {
47
+ inputId: 'testCheckbox',
48
+ helpText: 'i am help text',
49
+ children: 'test checkbox',
50
+ className: 'm-top-xs m-right-0 m-bottom-0 m-left-0',
51
+ isDisabled: false,
52
+ isFieldRequired: false,
53
+ requiredIndicator: ' *',
54
+ },
55
+ {}
56
+ );
57
+ });
58
+
59
+ test('it calls FormLabel with the correct props when checkbox is required', () => {
60
+ const { getByLabelText } = render(
61
+ <CheckboxInput
62
+ id="testCheckbox"
63
+ label="test checkbox"
64
+ onChange={() => null}
65
+ isChecked={false}
66
+ isRequired
67
+ />
68
+ );
69
+ expect(getByLabelText('test checkbox')).toBeDefined();
70
+ expect(FormLabel).toHaveBeenCalledTimes(1);
71
+ expect(FormLabel).toHaveBeenCalledWith(
72
+ {
73
+ inputId: 'testCheckbox',
74
+ helpText: undefined,
75
+ children: 'test checkbox',
76
+ className: 'm-top-xs m-right-0 m-bottom-0 m-left-0',
77
+ isDisabled: false,
78
+ isFieldRequired: true,
79
+ requiredIndicator: ' *',
80
+ },
81
+ {}
82
+ );
83
+ });
84
+
85
+ test('input is checked when isChecked is true', () => {
86
+ const { getByLabelText } = render(
87
+ <CheckboxInput
88
+ id="testCheckbox"
89
+ label="test checkbox"
90
+ onChange={() => null}
91
+ isChecked
92
+ />
93
+ );
94
+ const checkbox = getByLabelText('test checkbox') as HTMLInputElement;
95
+ expect(checkbox.checked).toEqual(true);
96
+ });
97
+
98
+ test('input is not checked when isChecked is false', () => {
99
+ const { getByLabelText } = render(
100
+ <CheckboxInput
101
+ id="testCheckbox"
102
+ label="test checkbox"
103
+ isChecked={false}
104
+ onChange={() => null}
105
+ />
106
+ );
107
+ const checkbox = getByLabelText('test checkbox') as HTMLInputElement;
108
+ expect(checkbox.checked).toEqual(false);
109
+ });
110
+
111
+ test('assigns the "aria-labelledby" attribute and calls FormLabel with expected props', () => {
112
+ const { getByLabelText } = render(
113
+ <CheckboxInput
114
+ isChecked={false}
115
+ id="testInput"
116
+ label="test label"
117
+ value="hello"
118
+ onChange={() => null}
119
+ />
120
+ );
121
+ expect(getByLabelText('test label')).toHaveAttribute(
122
+ 'aria-labelledby',
123
+ 'testInputLabel'
124
+ );
125
+ });
126
+
127
+ test('sets required properties when isRequired is true', () => {
128
+ const { getByLabelText } = render(
129
+ <CheckboxInput
130
+ isChecked={false}
131
+ id="testInput"
132
+ label="test label"
133
+ value="hello"
134
+ onChange={() => null}
135
+ isRequired
136
+ />
137
+ );
138
+ expect(getByLabelText('test label')).toHaveAttribute(
139
+ 'aria-required',
140
+ 'true'
141
+ );
142
+ expect(getByLabelText('test label')).toHaveAttribute('required');
143
+ });
144
+
145
+ describe('error states', () => {
146
+ test('renders error message if error exists and is not true', () => {
147
+ const { getByText } = render(
148
+ <CheckboxInput
149
+ id="testCheckbox"
150
+ label="test checkbox"
151
+ isChecked={false}
152
+ onChange={() => null}
153
+ error="This is the error message"
154
+ />
155
+ );
156
+ expect(getByText('This is the error message')).toBeInTheDocument();
157
+ });
158
+
159
+ test('calls FormLabel with the correct properties when error is a string', () => {
160
+ render(
161
+ <CheckboxInput
162
+ id="testCheckbox"
163
+ label="test checkbox"
164
+ isChecked={false}
165
+ onChange={() => null}
166
+ error="This is the error message"
167
+ />
168
+ );
169
+ expect(FormLabel).toHaveBeenCalledTimes(1);
170
+ expect(FormLabel).toHaveBeenCalledWith(
171
+ {
172
+ inputId: 'testCheckbox',
173
+ helpText: undefined,
174
+ children: 'test checkbox',
175
+ className: 'm-top-xs m-right-0 m-bottom-0 m-left-0',
176
+ isDisabled: false,
177
+ isFieldRequired: false,
178
+ requiredIndicator: ' *',
179
+ },
180
+ {}
181
+ );
182
+ });
183
+
184
+ test('calls FormLabel with the correct properties when error is a true', () => {
185
+ render(
186
+ <CheckboxInput
187
+ id="testCheckbox"
188
+ label="test checkbox"
189
+ isChecked={false}
190
+ onChange={() => null}
191
+ error
192
+ />
193
+ );
194
+ expect(FormLabel).toHaveBeenCalledTimes(1);
195
+ expect(FormLabel).toHaveBeenCalledWith(
196
+ {
197
+ inputId: 'testCheckbox',
198
+ helpText: undefined,
199
+ children: 'test checkbox',
200
+ className: 'm-top-xs m-right-0 m-bottom-0 m-left-0',
201
+ isDisabled: false,
202
+ isFieldRequired: false,
203
+ requiredIndicator: ' *',
204
+ },
205
+ {}
206
+ );
207
+ });
208
+ });
209
+
210
+ test('calls FormLabel with the correct properties when disabled', () => {
211
+ render(
212
+ <CheckboxInput
213
+ id="testCheckbox"
214
+ label="test checkbox"
215
+ isChecked={false}
216
+ onChange={() => null}
217
+ isDisabled
218
+ />
219
+ );
220
+ expect(FormLabel).toHaveBeenCalledTimes(1);
221
+ expect(FormLabel).toHaveBeenCalledWith(
222
+ {
223
+ inputId: 'testCheckbox',
224
+ helpText: undefined,
225
+ children: 'test checkbox',
226
+ className: 'm-top-xs m-right-0 m-bottom-0 m-left-0',
227
+ isDisabled: true,
228
+ isFieldRequired: false,
229
+ requiredIndicator: ' *',
230
+ },
231
+ {}
232
+ );
233
+ });
234
+
235
+ describe('Size', () => {
236
+ test('calls FormLabel with the correct properties when size is small', () => {
237
+ render(
238
+ <CheckboxInput
239
+ id="testCheckbox"
240
+ label="test checkbox"
241
+ isChecked={false}
242
+ onChange={() => null}
243
+ size="sm"
244
+ />
245
+ );
246
+ expect(FormLabel).toHaveBeenCalledTimes(1);
247
+ expect(FormLabel).toHaveBeenCalledWith(
248
+ {
249
+ inputId: 'testCheckbox',
250
+ helpText: undefined,
251
+ children: 'test checkbox',
252
+ className: 'm-top-2xs m-right-0 m-bottom-0 m-left-0',
253
+ isDisabled: false,
254
+ isFieldRequired: false,
255
+ requiredIndicator: ' *',
256
+ },
257
+ {}
258
+ );
259
+ });
260
+ test('calls FormLabel with the correct properties when size is large', () => {
261
+ render(
262
+ <CheckboxInput
263
+ id="testCheckbox"
264
+ label="test checkbox"
265
+ isChecked={false}
266
+ onChange={() => null}
267
+ size="lg"
268
+ />
269
+ );
270
+ expect(FormLabel).toHaveBeenCalledTimes(1);
271
+ expect(FormLabel).toHaveBeenCalledWith(
272
+ {
273
+ inputId: 'testCheckbox',
274
+ helpText: undefined,
275
+ children: 'test checkbox',
276
+ className: 'm-top-sm m-right-0 m-bottom-0 m-left-0',
277
+ isDisabled: false,
278
+ isFieldRequired: false,
279
+ requiredIndicator: ' *',
280
+ },
281
+ {}
282
+ );
283
+ });
284
+
285
+ const mockedHandleChange = jest.fn();
286
+ const sizes: CheckboxSize[] = ['sm', 'md', 'lg'];
287
+
288
+ const breakpoints = ['tablet', 'desktop', 'hd'];
289
+
290
+ sizes.forEach((size) => {
291
+ test(`it has a ${size} class applied to it`, () => {
292
+ render(
293
+ <CheckboxInput
294
+ isChecked={false}
295
+ id="testId"
296
+ onChange={mockedHandleChange}
297
+ size={size}
298
+ label="size test"
299
+ />
300
+ );
301
+ const checkbox = screen.getByLabelText('size test');
302
+ const checkboxParent = checkbox.closest('div');
303
+ expect(checkboxParent?.getAttribute('class')).toContain(size);
304
+ });
305
+
306
+ breakpoints.forEach((breakpoint) => {
307
+ test(`it applies responsive classes for breakpoint: ${breakpoint} and size: ${size}`, () => {
308
+ render(
309
+ <CheckboxInput
310
+ isChecked={false}
311
+ id="testId"
312
+ onChange={mockedHandleChange}
313
+ size={{ [breakpoint]: size }}
314
+ label="size test"
315
+ />
316
+ );
317
+ const checkbox = screen.getByLabelText('size test');
318
+ const checkboxParent = checkbox.closest('div');
319
+
320
+ expect(checkboxParent?.getAttribute('class')).toContain(
321
+ `size-${size}-${breakpoint}`
322
+ );
323
+ });
324
+ });
325
+ });
326
+
327
+ test('It applies responsive classes when multiple are applied', () => {
328
+ render(
329
+ <CheckboxInput
330
+ isChecked={false}
331
+ id="testId"
332
+ onChange={mockedHandleChange}
333
+ size={{
334
+ base: 'sm',
335
+ tablet: 'md',
336
+ desktop: 'lg',
337
+ hd: 'sm',
338
+ }}
339
+ label="size test"
340
+ />
341
+ );
342
+ const checkbox = screen.getByLabelText('size test');
343
+ const checkboxParent = checkbox.closest('div');
344
+
345
+ expect(checkboxParent?.getAttribute('class')).toContain('size-sm');
346
+ expect(checkboxParent?.getAttribute('class')).toContain('size-md-tablet');
347
+ expect(checkboxParent?.getAttribute('class')).toContain(
348
+ 'size-lg-desktop'
349
+ );
350
+ expect(checkboxParent?.getAttribute('class')).toContain('size-sm-hd');
351
+ });
352
+ });
353
+
354
+ describe('onChange', () => {
355
+ test('onChange event fires callback function', () => {
356
+ const mockedHandleChange = jest.fn(() => null);
357
+
358
+ const { getByLabelText } = render(
359
+ <CheckboxInput
360
+ id="testCheckbox"
361
+ label="test checkbox"
362
+ isChecked={false}
363
+ onChange={mockedHandleChange}
364
+ />
365
+ );
366
+ const checkbox = getByLabelText('test checkbox');
367
+ fireEvent.click(checkbox);
368
+ expect(mockedHandleChange).toHaveBeenCalledTimes(1);
369
+ });
370
+
371
+ test('calls onChange and passes checked value in event', () => {
372
+ let value = true;
373
+ const mockedHandleChange = jest.fn((event) => {
374
+ value = event.target.checked;
375
+ });
376
+
377
+ const { getByLabelText } = render(
378
+ <CheckboxInput
379
+ id="testCheckbox"
380
+ label="test checkbox"
381
+ onChange={mockedHandleChange}
382
+ isChecked={value}
383
+ />
384
+ );
385
+ const checkbox = getByLabelText('test checkbox');
386
+ fireEvent.click(checkbox);
387
+ expect(mockedHandleChange).toBeCalledTimes(1);
388
+ expect(value).toBe(false);
389
+ });
390
+ });
391
+
392
+ describe('onFocus', () => {
393
+ test('onFocus event fires callback function if defined', () => {
394
+ const mockedHandleFocus = jest.fn(() => null);
395
+
396
+ const { getByText, getByLabelText } = render(
397
+ <div>
398
+ <button type="button">focus</button>
399
+ <CheckboxInput
400
+ id="testCheckbox"
401
+ label="test checkbox"
402
+ isChecked={false}
403
+ onChange={() => null}
404
+ onFocus={mockedHandleFocus}
405
+ onBlur={undefined}
406
+ />
407
+ </div>
408
+ );
409
+ getByLabelText('test checkbox').focus();
410
+ getByText('focus').focus();
411
+ expect(mockedHandleFocus).toHaveBeenCalledTimes(1);
412
+ });
413
+ });
414
+
415
+ describe('onBlur', () => {
416
+ test('onBlur event fires callback function if defined', () => {
417
+ const mockedHandleBlur = jest.fn(() => null);
418
+
419
+ const { getByText, getByLabelText } = render(
420
+ <div>
421
+ <button type="button">focus</button>
422
+ <CheckboxInput
423
+ id="testCheckbox"
424
+ label="test checkbox"
425
+ isChecked={false}
426
+ onChange={() => null}
427
+ onBlur={mockedHandleBlur}
428
+ />
429
+ </div>
430
+ );
431
+ getByLabelText('test checkbox').focus();
432
+ getByText('focus').focus();
433
+ expect(mockedHandleBlur).toHaveBeenCalledTimes(1);
434
+ });
435
+ });
436
+ });