@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,71 @@
1
+ import React from 'react';
2
+ import { Box, BoxProps } from '../../Box/Box';
3
+ import { Icon } from '../../Icon/Icon';
4
+ import { FontColor } from '../../../types';
5
+ import { CheckboxProps } from './Checkbox'; // eslint-disable-line import/no-cycle
6
+
7
+ export interface CheckboxIconProps extends BoxProps {
8
+ /**
9
+ * Custom className to be applied to root node of component.
10
+ */
11
+ className?: string;
12
+ /**
13
+ * Whether the input is in an error state. The icon will visually change accordingly.
14
+ */
15
+ error?: CheckboxProps['error'];
16
+ /**
17
+ * The checkbox input "checked" attribute.
18
+ */
19
+ isChecked?: CheckboxProps['isChecked'];
20
+ /**
21
+ * If the input should be disabled and not focusable.
22
+ */
23
+ isDisabled?: CheckboxProps['isDisabled'];
24
+ /**
25
+ * Whether the checkbox is rendered in an indeterminate state.
26
+ * NOTE: this change is only visual and it does not affect the checked or unchecked state of the checkbox.
27
+ */
28
+ isIndeterminate?: CheckboxProps['isIndeterminate'];
29
+ }
30
+
31
+ export const CheckboxIcon: React.FC<CheckboxIconProps> = ({
32
+ className = undefined,
33
+ error = null,
34
+ isChecked = false,
35
+ isDisabled = false,
36
+ isIndeterminate = false,
37
+ ...restProps
38
+ }) => {
39
+ let color: FontColor = 'base';
40
+ let name:
41
+ | 'checkbox-btn'
42
+ | 'checkbox-btn-checked'
43
+ | 'checkbox-btn-indeterminate' = 'checkbox-btn';
44
+
45
+ if (isChecked) name = 'checkbox-btn-checked';
46
+ else name = 'checkbox-btn';
47
+
48
+ if (isIndeterminate) name = 'checkbox-btn-indeterminate';
49
+
50
+ if (isChecked && isDisabled) {
51
+ color = 'disabled';
52
+ } else if (isChecked && !isDisabled) {
53
+ color = 'base';
54
+ } else if (isDisabled) {
55
+ color = 'disabled';
56
+ }
57
+
58
+ if (error) color = 'danger';
59
+ if (isDisabled && error) color = 'danger-disabled';
60
+
61
+ return (
62
+ <Box
63
+ className={className}
64
+ display="inline-block"
65
+ color={color}
66
+ {...restProps}
67
+ >
68
+ <Icon name={name} />
69
+ </Box>
70
+ );
71
+ };
@@ -0,0 +1,61 @@
1
+ import { Canvas, Meta, ArgTypes } from '@storybook/blocks';
2
+ import { DateInput } from './DateInput';
3
+ import * as Stories from './DateInput.stories';
4
+
5
+ <Meta of={Stories} />
6
+
7
+ # DateInput
8
+
9
+ Use a DateInput to allow users to select a date close to today and place that date in an input field.
10
+ Avoid using this component if the user needs to enter a date that is many years in the past (i.e. birthday) or future.
11
+ For entering these types of dates we recommend using the `TextInput` component with a `date` mask. See an example here:
12
+ [TextInput Date Example](?path=/docs/components-textinput-overview--with-date-mask)
13
+
14
+ <Canvas isExpanded of={Stories.Basic} />
15
+
16
+ ## Props
17
+
18
+ <ArgTypes of={DateInput} />
19
+
20
+ ## Default
21
+
22
+ The DateInput is composed of 3 components. Each can be tailored based on their props. They are:
23
+
24
+ 1. [DatePicker](?path=/docs/components-datepicker-overview--basic-example)
25
+ 2. [Popover](?path=/docs/components-popover-overview--demo)
26
+ 3. [TextInput](?path=/docs/components-textinput-overview--default-story)
27
+
28
+ The `DateInput` uses sensible defaults for these to allow for very straightforward ergonomics that allow users to
29
+ select dates with minimal work.
30
+
31
+ <Canvas of={Stories.Default} />
32
+
33
+ ## Date Range
34
+
35
+ <Canvas of={Stories.DateRange} />
36
+
37
+ ## With Min/Max dates
38
+
39
+ <Canvas of={Stories.WithMinAndMaxDates} />
40
+
41
+ ## Custom Date Format
42
+
43
+ You can manipulate the format on the input field by using the `dateFormat` and `dateOptions`
44
+ props. Under the hood our component uses the [date-fns `format` function](https://date-fns.org/v2.16.1/docs/format)
45
+ to generate a string based on these options.
46
+
47
+ <Canvas of={Stories.CustomDateFormat} />
48
+
49
+ ## On using onBlur event with DateInput
50
+
51
+ The input is technically blurred whenever the calendar popover is interacted but as far as the user
52
+ is concerned they are still interacting with the DateInput. Please keep this in mind when
53
+ triggering form validation after an onBlur event.
54
+
55
+ Make sure to pass the `onBlur` prop to the input via `textInputProps`.
56
+
57
+ <Canvas of={Stories.InputBlurEvent} />
58
+
59
+ ## Component Design Tokens
60
+
61
+ This component shares component design tokens with all form controls. For a complete list of tokens, see the [Theming Form Controls documentation](/docs/theming-form-controls--custom-theme-form).
@@ -0,0 +1,168 @@
1
+ import React, { useState } from 'react';
2
+ import type { Meta } from '@storybook/react';
3
+ import { DateInput } from './DateInput';
4
+ import { Box } from '../Box/Box';
5
+
6
+ const meta: Meta<typeof DateInput> = {
7
+ title: 'Components/DateInput',
8
+ component: DateInput,
9
+ };
10
+
11
+ export default meta;
12
+
13
+ export const Basic = () => (
14
+ <DateInput
15
+ datePickerProps={{
16
+ onChange() {},
17
+ }}
18
+ textInputProps={{
19
+ id: 'exampleDateInput',
20
+ name: 'selectDate',
21
+ label: 'Select a Date',
22
+ placeholder: 'e.g. 11/02/2020',
23
+ }}
24
+ />
25
+ );
26
+
27
+ export const Default = () => {
28
+ const [selectedDate, setSelectedDate] = useState<Date | null | [Date, Date]>(
29
+ null
30
+ );
31
+ const handleClear = () => {
32
+ setSelectedDate(null);
33
+ };
34
+
35
+ return (
36
+ <DateInput
37
+ datePickerProps={{
38
+ selected: selectedDate as Date,
39
+ onChange: setSelectedDate,
40
+ }}
41
+ textInputProps={{
42
+ placeholder: 'e.g. 11/02/2020',
43
+ onClear: handleClear,
44
+ id: 'defaultDatePicker',
45
+ name: 'selectDate',
46
+ label: 'Select Date',
47
+ }}
48
+ />
49
+ );
50
+ };
51
+
52
+ export const DateRange = () => {
53
+ const [startDate, setStartDate] = useState<Date | [Date, Date] | null>(null);
54
+ const [endDate, setEndDate] = useState<Date | [Date, Date] | null>(null);
55
+ const setDate = ([startDate, endDate]: [Date, Date]) => {
56
+ setStartDate(startDate);
57
+ setEndDate(endDate);
58
+ };
59
+ const handleClear = () => {
60
+ setStartDate(null);
61
+ setEndDate(null);
62
+ };
63
+
64
+ return (
65
+ <DateInput
66
+ datePickerProps={{
67
+ // @ts-ignore - Type compatibility with onChange.
68
+ onChange: setDate,
69
+ selected: startDate as Date,
70
+ selectsRange: true,
71
+ startDate: startDate as Date,
72
+ endDate: endDate as Date,
73
+ }}
74
+ textInputProps={{
75
+ onClear: handleClear,
76
+ id: 'myDateRangePicker',
77
+ name: 'myDateRangePicker',
78
+ label: 'Select Date Range',
79
+ }}
80
+ />
81
+ );
82
+ };
83
+
84
+ export const WithMinAndMaxDates = () => {
85
+ const [selectedDate, setSelectedDate] = useState<Date | [Date, Date] | null>(
86
+ null
87
+ );
88
+ const handleClear = () => {
89
+ setSelectedDate(null);
90
+ };
91
+ const min = new Date(2022, 6, 18);
92
+ min.setDate(min.getDate() - 10);
93
+ const max = new Date(2022, 6, 18);
94
+ max.setDate(max.getDate() + 100);
95
+ return (
96
+ <DateInput
97
+ datePickerProps={{
98
+ selected: selectedDate as Date,
99
+ maxDate: max,
100
+ minDate: min,
101
+ onChange: setSelectedDate,
102
+ }}
103
+ textInputProps={{
104
+ placeholder: 'e.g. 11/02/2020',
105
+ onClear: handleClear,
106
+ id: 'defaultDatePicker',
107
+ name: 'selectDate',
108
+ label: 'Select Date',
109
+ }}
110
+ />
111
+ );
112
+ };
113
+
114
+ export const CustomDateFormat = () => {
115
+ const [selectedDate, setSelectedDate] = useState<Date | null | [Date, Date]>(
116
+ new Date('2020, 11, 3')
117
+ );
118
+ const handleClear = () => {
119
+ setSelectedDate(null);
120
+ };
121
+ return (
122
+ <Box gap="md">
123
+ <DateInput
124
+ dateFormat={'MMMM dd, yyyy'}
125
+ datePickerProps={{
126
+ selected: selectedDate as Date,
127
+ onChange: setSelectedDate,
128
+ }}
129
+ textInputProps={{
130
+ onClear: handleClear,
131
+ id: 'withCustomDateFormat',
132
+ name: 'selectDate',
133
+ label: 'Select Date',
134
+ }}
135
+ />
136
+ <Box>
137
+ <p>
138
+ Selected Date (as ISO String):{' '}
139
+ {selectedDate ? (selectedDate as Date).toISOString() : null}
140
+ </p>
141
+ </Box>
142
+ </Box>
143
+ );
144
+ };
145
+
146
+ export const InputBlurEvent = () => {
147
+ const [selectedDate, setSelectedDate] = useState<Date | [Date, Date] | null>(
148
+ new Date('2020, 11, 3')
149
+ );
150
+ const handleTextInputBlur = () => {
151
+ alert('TextInput Blur Event');
152
+ };
153
+ return (
154
+ <DateInput
155
+ dateFormat={'MMMM dd, yyyy'}
156
+ datePickerProps={{
157
+ selected: selectedDate as Date,
158
+ onChange: setSelectedDate,
159
+ }}
160
+ textInputProps={{
161
+ id: 'withCustomDateFormat',
162
+ name: 'selectDate',
163
+ label: 'Select Date',
164
+ onBlur: handleTextInputBlur,
165
+ }}
166
+ />
167
+ );
168
+ };
@@ -0,0 +1,258 @@
1
+ import React from 'react';
2
+ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
+ import { DateInput } from './DateInput';
4
+
5
+ describe('DateInput', () => {
6
+ describe('Default', () => {
7
+ it('renders a DateInput component with defaults', () => {
8
+ render(
9
+ <DateInput
10
+ textInputProps={{
11
+ id: 'myInput',
12
+ label: 'Select Date',
13
+ }}
14
+ datePickerProps={{
15
+ onChange: () => null,
16
+ }}
17
+ />
18
+ );
19
+
20
+ const input = screen.getByLabelText('Select Date');
21
+ expect(input).toBeInTheDocument();
22
+ });
23
+ });
24
+
25
+ describe('Popover', () => {
26
+ it('opens the Popover when the input is clicked', async () => {
27
+ render(
28
+ <DateInput
29
+ dateFormat="yyyy/MM/dd"
30
+ textInputProps={{
31
+ id: 'myInput',
32
+ label: 'Select Date',
33
+ }}
34
+ datePickerProps={{
35
+ onChange: () => null,
36
+ }}
37
+ />
38
+ );
39
+
40
+ const input = screen.getByLabelText('Select Date');
41
+ expect(input).toBeInTheDocument();
42
+
43
+ fireEvent.click(input);
44
+
45
+ const popoverContainer = screen.getByLabelText('Popover');
46
+ await waitFor(() =>
47
+ expect(popoverContainer).toHaveAttribute(
48
+ 'data-popper-placement',
49
+ 'bottom'
50
+ )
51
+ );
52
+ });
53
+
54
+ it('closes popover when user clicks outside', async () => {
55
+ const { container } = render(
56
+ <DateInput
57
+ dateFormat="yyyy/MM/dd"
58
+ textInputProps={{
59
+ id: 'myInput',
60
+ label: 'Select Date',
61
+ }}
62
+ datePickerProps={{
63
+ onChange: () => null,
64
+ }}
65
+ />
66
+ );
67
+
68
+ const input = screen.getByLabelText('Select Date');
69
+ fireEvent.click(input);
70
+
71
+ const popoverContainer = screen.getByLabelText('Popover');
72
+ await waitFor(() =>
73
+ expect(popoverContainer).toHaveAttribute(
74
+ 'data-popper-placement',
75
+ 'bottom'
76
+ )
77
+ );
78
+
79
+ fireEvent.click(container);
80
+ const popover = screen.queryByRole('dialog');
81
+ expect(popover).toBeNull();
82
+ });
83
+
84
+ it('closes popover when user selects a value NOT in a range', async () => {
85
+ const date = new Date(1995, 11, 14);
86
+
87
+ render(
88
+ <DateInput
89
+ dateFormat="yyyy/MM/dd"
90
+ textInputProps={{
91
+ id: 'myInput',
92
+ label: 'Select Date',
93
+ }}
94
+ datePickerProps={{
95
+ openToDate: date,
96
+ selected: null,
97
+ onChange: () => null,
98
+ }}
99
+ />
100
+ );
101
+
102
+ const input = screen.getByLabelText('Select Date');
103
+ fireEvent.click(input);
104
+
105
+ const popoverContainer = screen.getByLabelText('Popover');
106
+ await waitFor(() =>
107
+ expect(popoverContainer).toHaveAttribute(
108
+ 'data-popper-placement',
109
+ 'bottom'
110
+ )
111
+ );
112
+ const dateButton = screen.getByText('14');
113
+ await waitFor(() => {
114
+ fireEvent.click(dateButton);
115
+ });
116
+
117
+ const popover = screen.queryByRole('dialog');
118
+ await waitFor(() => {
119
+ expect(popover).toBeNull();
120
+ });
121
+ });
122
+
123
+ it('keeps popover open while user is selecting a Date range', async () => {
124
+ const date = new Date(1995, 11, 14);
125
+
126
+ render(
127
+ <DateInput
128
+ dateFormat="yyyy/MM/dd"
129
+ textInputProps={{
130
+ id: 'myInput',
131
+ label: 'Select Date',
132
+ }}
133
+ datePickerProps={{
134
+ openToDate: date,
135
+ selected: null,
136
+ onChange: () => null,
137
+ selectsRange: true,
138
+ }}
139
+ />
140
+ );
141
+
142
+ const input = screen.getByLabelText('Select Date');
143
+ fireEvent.click(input);
144
+
145
+ const popoverContainer = screen.getByLabelText('Popover');
146
+ await waitFor(() =>
147
+ expect(popoverContainer).toHaveAttribute(
148
+ 'data-popper-placement',
149
+ 'bottom'
150
+ )
151
+ );
152
+ const dateButton = screen.getByText('14');
153
+ await waitFor(() => {
154
+ fireEvent.click(dateButton);
155
+ });
156
+
157
+ const popover = screen.getByLabelText('Popover');
158
+ await waitFor(() => {
159
+ expect(popover).toHaveAttribute('data-popper-placement', 'bottom');
160
+ });
161
+ });
162
+ });
163
+
164
+ describe('Date Formatting', () => {
165
+ it('formats the date when a format is passed', async () => {
166
+ const date = new Date(1995, 11, 14);
167
+ render(
168
+ <DateInput
169
+ dateFormat="yyyy/MM/dd"
170
+ textInputProps={{
171
+ id: 'myInput',
172
+ label: 'Select Date',
173
+ }}
174
+ datePickerProps={{
175
+ onChange: () => null,
176
+ openToDate: date,
177
+ selected: date,
178
+ }}
179
+ />
180
+ );
181
+
182
+ const input = screen.getByLabelText('Select Date');
183
+ expect(input).toBeInTheDocument();
184
+ expect(input).toHaveAttribute('value', '1995/12/14');
185
+ });
186
+
187
+ it('formats both dates when range is being selected', async () => {
188
+ const dateOne = new Date(1995, 11, 14);
189
+ const dateTwo = new Date(1995, 11, 16);
190
+ render(
191
+ <DateInput
192
+ dateFormat="yyyy/MM/dd"
193
+ textInputProps={{
194
+ id: 'myInput',
195
+ label: 'Select Date',
196
+ }}
197
+ datePickerProps={{
198
+ onChange: () => null,
199
+ openToDate: dateOne,
200
+ startDate: dateOne,
201
+ endDate: dateTwo,
202
+ selectsRange: true,
203
+ }}
204
+ />
205
+ );
206
+
207
+ const input = screen.getByLabelText('Select Date');
208
+ expect(input).toBeInTheDocument();
209
+ expect(input).toHaveAttribute('value', '1995/12/14 - 1995/12/16');
210
+ });
211
+
212
+ it('formats one date if selecting range', async () => {
213
+ const dateOne = null;
214
+ const dateTwo = new Date(1995, 11, 16);
215
+ const { rerender } = render(
216
+ <DateInput
217
+ dateFormat="yyyy/MM/dd"
218
+ textInputProps={{
219
+ id: 'myInput',
220
+ label: 'Select Date',
221
+ }}
222
+ datePickerProps={{
223
+ onChange: () => null,
224
+ openToDate: dateTwo,
225
+ startDate: dateOne,
226
+ endDate: dateTwo,
227
+ selectsRange: true,
228
+ }}
229
+ />
230
+ );
231
+
232
+ const input = screen.getByLabelText('Select Date');
233
+ expect(input).toBeInTheDocument();
234
+ expect(input).toHaveAttribute('value', ' - 1995/12/16');
235
+
236
+ rerender(
237
+ <DateInput
238
+ dateFormat="yyyy/MM/dd"
239
+ textInputProps={{
240
+ id: 'myInput',
241
+ label: 'Select Date',
242
+ }}
243
+ datePickerProps={{
244
+ onChange: () => null,
245
+ openToDate: dateTwo,
246
+ startDate: dateTwo,
247
+ endDate: dateOne,
248
+ selectsRange: true,
249
+ }}
250
+ />
251
+ );
252
+
253
+ const inputTwo = screen.getByLabelText('Select Date');
254
+ expect(inputTwo).toBeInTheDocument();
255
+ expect(inputTwo).toHaveAttribute('value', '1995/12/16 - ');
256
+ });
257
+ });
258
+ });