@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,37 @@
1
+ import React, { FC } from 'react';
2
+ import {
3
+ FormikTouched,
4
+ FormikErrors,
5
+ FormikValues,
6
+ FieldAttributes,
7
+ getIn,
8
+ } from 'formik';
9
+ import { TimePicker, TimePickerProps } from '../../TimePicker/TimePicker';
10
+
11
+ export interface FormikTimePickerProps
12
+ extends Omit<TimePickerProps, 'onChange'> {
13
+ field: FieldAttributes<HTMLSelectElement>;
14
+ form: {
15
+ touched: FormikTouched<FormikValues>;
16
+ errors: FormikErrors<FormikValues>;
17
+ };
18
+ onChange?: TimePickerProps['onChange'];
19
+ }
20
+
21
+ export const FormikTimePicker: FC<FormikTimePickerProps> = ({
22
+ field: { name, onBlur, onChange: formikOnChange, value },
23
+ form: { touched, errors },
24
+ options,
25
+ onChange,
26
+ ...props
27
+ }) => (
28
+ <TimePicker
29
+ {...props}
30
+ name={name}
31
+ onBlur={onBlur}
32
+ onChange={onChange ?? formikOnChange}
33
+ value={value}
34
+ error={getIn(touched, name) && getIn(errors, name)}
35
+ options={options}
36
+ />
37
+ );
@@ -0,0 +1,175 @@
1
+ import React from 'react';
2
+ import { render, fireEvent, screen, waitFor } from '@testing-library/react';
3
+ import { Formik, Form, Field, FormikValues, getIn, setIn } from 'formik';
4
+ import { FormikTimePickerNative } from './FormikTimePickerNative';
5
+
6
+ const testLabelName = 'test select';
7
+
8
+ const handleValidation = (testValueKey: string) => (values: FormikValues) =>
9
+ getIn(values, testValueKey)?.length > 1
10
+ ? {}
11
+ : setIn({}, testValueKey, 'input is required');
12
+
13
+ const renderForm = (
14
+ initialValue: any, // eslint-disable-line
15
+ props: {
16
+ placeholder?: string;
17
+ hideLabel?: boolean;
18
+ isRequired?: unknown;
19
+ isDisabled?: boolean;
20
+ onChange?: jest.Mock<void, [React.ChangeEvent<HTMLSelectElement>]>; // eslint-disable-line
21
+ interval?: number;
22
+ },
23
+ testValueKey = testLabelName
24
+ ) => (
25
+ <Formik
26
+ initialValues={{
27
+ [testLabelName]: initialValue,
28
+ }}
29
+ validate={props.isRequired ? handleValidation(testValueKey) : undefined} // eslint-disable-line
30
+ onSubmit={() => {}} // eslint-disable-line
31
+ >
32
+ {() => (
33
+ <Form noValidate>
34
+ <Field
35
+ label={testValueKey}
36
+ name={testValueKey}
37
+ id={testValueKey}
38
+ component={FormikTimePickerNative}
39
+ {...props}
40
+ />
41
+ <button type="submit">submit</button>
42
+ </Form>
43
+ )}
44
+ </Formik>
45
+ );
46
+
47
+ describe('FormikTimePickerNative', () => {
48
+ describe('States', () => {
49
+ describe('Hidden label, with a placeholder', () => {
50
+ test('it renders input without a visual label, and with a placeholder', () => {
51
+ render(
52
+ renderForm(undefined, {
53
+ placeholder: 'Test Placeholder',
54
+ hideLabel: true,
55
+ })
56
+ );
57
+ expect(screen.queryByText(testLabelName)).toBeNull();
58
+ expect(screen.getByText('Test Placeholder')).toBeInTheDocument();
59
+ });
60
+ });
61
+
62
+ describe('No Aria-labelledby', () => {
63
+ test('does not assign "aria-labelledby" attribute when a label is hidden', () => {
64
+ render(renderForm(undefined, { hideLabel: true }));
65
+ const inputElement = screen.getByLabelText(testLabelName);
66
+ expect(inputElement).not.toHaveAttribute('aria-labelledby');
67
+ });
68
+ });
69
+
70
+ describe('With a label, and no custom placeholder', () => {
71
+ test('it renders input with a label, and with a default placeholder', () => {
72
+ render(renderForm(undefined, {}));
73
+
74
+ expect(screen.getByLabelText(testLabelName)).toBeInTheDocument();
75
+ expect(screen.getByText('HH:MM')).toBeInTheDocument();
76
+ });
77
+
78
+ test('assigns the "aria-labelledby" attribute and renders label with correct id, when label is provided', () => {
79
+ render(renderForm(undefined, {}));
80
+ const inputElement = screen.getByLabelText(testLabelName);
81
+ expect(inputElement).toHaveAttribute(
82
+ 'aria-labelledby',
83
+ `${testLabelName}Label`
84
+ );
85
+ expect(
86
+ document.getElementById(`${testLabelName}Label`)
87
+ ).toBeInTheDocument();
88
+ });
89
+ });
90
+
91
+ describe('Single select, pre-selected', () => {
92
+ test('it renders with value pre-selected', () => {
93
+ render(renderForm('2020-10-23T04:30:00.120Z', {}));
94
+
95
+ expect(screen.getByText('12:00 AM')).toBeInTheDocument();
96
+ });
97
+ });
98
+
99
+ describe('Is Required', () => {
100
+ test('it sets aria-required on the input', () => {
101
+ render(renderForm(undefined, { isRequired: true }));
102
+ const inputElement = screen.getByLabelText(testLabelName);
103
+ expect(inputElement).toHaveAttribute('aria-required', 'true');
104
+ });
105
+ });
106
+
107
+ describe('Is Disabled', () => {
108
+ test('it disables the input', () => {
109
+ render(renderForm(undefined, { isDisabled: true }));
110
+
111
+ expect(screen.getByLabelText(testLabelName)).toBeDisabled();
112
+ });
113
+ });
114
+
115
+ describe('Is Invalid, with a helpful message', () => {
116
+ test('it renders the helpful message', async () => {
117
+ const { getByText } = render(
118
+ renderForm(undefined, { isRequired: true })
119
+ );
120
+ const submitButton = getByText('submit');
121
+
122
+ fireEvent.click(submitButton);
123
+ await waitFor(() =>
124
+ expect(screen.getByText('input is required')).toBeInTheDocument()
125
+ );
126
+ });
127
+
128
+ test('it renders the error message from nested object', async () => {
129
+ const { getByText } = render(
130
+ renderForm(
131
+ { outer: { nested: [] } },
132
+ { isRequired: true },
133
+ `${testLabelName}.outer.nested`
134
+ )
135
+ );
136
+ const submitButton = getByText('submit');
137
+
138
+ fireEvent.click(submitButton);
139
+ await waitFor(() =>
140
+ expect(screen.getByText('input is required')).toBeInTheDocument()
141
+ );
142
+ });
143
+ });
144
+ });
145
+
146
+ describe('Callback Handling', () => {
147
+ describe('onChange', () => {
148
+ test("Custom onChange event fires callback function, overwriting Formik's onChange", async () => {
149
+ let value: string | undefined;
150
+ const mockedHandleChange = jest.fn((event) => {
151
+ event.persist();
152
+ });
153
+
154
+ const { getByLabelText } = render(
155
+ renderForm(value, { onChange: mockedHandleChange })
156
+ );
157
+ const selectInput = getByLabelText(testLabelName);
158
+ fireEvent.change(selectInput, { target: { value: 'hello' } });
159
+ expect(mockedHandleChange).toHaveBeenCalledTimes(1);
160
+ });
161
+
162
+ test('it fires onChange callback on change', async () => {
163
+ const mockedHandleChange = jest.fn();
164
+
165
+ const { getByLabelText } = render(
166
+ renderForm(undefined, { onChange: mockedHandleChange })
167
+ );
168
+
169
+ await fireEvent.change(getByLabelText(testLabelName));
170
+
171
+ expect(mockedHandleChange).toBeCalledTimes(1);
172
+ });
173
+ });
174
+ });
175
+ });
@@ -0,0 +1,38 @@
1
+ import React, { FC } from 'react';
2
+ import {
3
+ FormikTouched,
4
+ FormikErrors,
5
+ FormikValues,
6
+ FieldAttributes,
7
+ getIn,
8
+ } from 'formik';
9
+ import {
10
+ TimePickerNative,
11
+ TimePickerNativeProps,
12
+ } from '../../TimePickerNative/TimePickerNative';
13
+
14
+ export interface FormikTimePickerNativeProps
15
+ extends Omit<TimePickerNativeProps, 'onChange'> {
16
+ field: FieldAttributes<HTMLTextAreaElement>;
17
+ form: {
18
+ touched: FormikTouched<FormikValues>;
19
+ errors: FormikErrors<FormikValues>;
20
+ };
21
+ onChange: TimePickerNativeProps['onChange'];
22
+ }
23
+
24
+ export const FormikTimePickerNative: FC<FormikTimePickerNativeProps> = ({
25
+ field: { name, onBlur, onChange: formikOnChange, value },
26
+ form: { touched, errors },
27
+ onChange,
28
+ ...props
29
+ }) => (
30
+ <TimePickerNative
31
+ {...props}
32
+ name={name}
33
+ onBlur={onBlur}
34
+ onChange={onChange ?? formikOnChange}
35
+ value={value}
36
+ error={getIn(touched, name) && getIn(errors, name)}
37
+ />
38
+ );
@@ -0,0 +1,172 @@
1
+ import React from 'react';
2
+ import {
3
+ render,
4
+ fireEvent,
5
+ screen,
6
+ waitFor,
7
+ act,
8
+ } from '@testing-library/react';
9
+ import { Formik, Form, Field, getIn, setIn, FormikValues } from 'formik';
10
+ import { FormikToggle } from './FormikToggle';
11
+
12
+ const testLabelName = 'test checkbox';
13
+
14
+ const handleValidation = (testValueKey: string) => (values: FormikValues) =>
15
+ getIn(values, testValueKey)
16
+ ? {}
17
+ : setIn({}, testValueKey, 'Checkbox is required');
18
+
19
+ const renderForm = (
20
+ initialValue: any,
21
+ props: any,
22
+ testValueKey = testLabelName
23
+ ) => (
24
+ <Formik
25
+ initialValues={{
26
+ [testLabelName]: initialValue,
27
+ }}
28
+ onSubmit={props.handleSubmit} // eslint-disable-line
29
+ validate={props.isRequired ? handleValidation(testValueKey) : undefined} // eslint-disable-line
30
+ >
31
+ {() => (
32
+ <Form noValidate>
33
+ <Field
34
+ label={testValueKey}
35
+ name={testValueKey}
36
+ id={testValueKey}
37
+ component={FormikToggle}
38
+ {...props}
39
+ />
40
+ <button type="submit">submit</button>
41
+ </Form>
42
+ )}
43
+ </Formik>
44
+ );
45
+
46
+ describe('CheckboxInput', () => {
47
+ describe('States', () => {
48
+ describe('With default props', () => {
49
+ test('renders not disabled, checked, or invalid by default', () => {
50
+ const { getByLabelText } = render(renderForm(false, {}));
51
+ const checkbox = getByLabelText(testLabelName) as HTMLInputElement;
52
+
53
+ expect(checkbox.checked).toBe(false);
54
+ expect(checkbox.disabled).toBe(false);
55
+ expect(checkbox.getAttribute('aria-invalid')).toBe('false');
56
+ });
57
+ });
58
+
59
+ describe('With initial value true', () => {
60
+ test('input is rendered checked when instantiated with isChecked true', () => {
61
+ const { getByLabelText } = render(renderForm(true, {}));
62
+ const checkbox = getByLabelText(testLabelName) as HTMLInputElement;
63
+ expect(checkbox.checked).toEqual(true);
64
+ });
65
+ });
66
+
67
+ describe('With initial value false', () => {
68
+ test('input is rendered unchecked when instantiated with isChecked false', () => {
69
+ const { getByLabelText } = render(renderForm(false, {}));
70
+ const checkbox = getByLabelText(testLabelName) as HTMLInputElement;
71
+ expect(checkbox.checked).toEqual(false);
72
+ });
73
+ });
74
+
75
+ describe('Disabled', () => {
76
+ test('input is rendered with the disabled attrbute when isDisabled is true', () => {
77
+ const { getByLabelText } = render(
78
+ renderForm(false, { isDisabled: true })
79
+ );
80
+ const checkbox = getByLabelText(testLabelName);
81
+ expect(checkbox).toBeDisabled();
82
+ });
83
+ });
84
+
85
+ describe('Correctly supplies aria-labelledby', () => {
86
+ test('assigns the "aria-labelledby" attribute and renders label with correct id, when label is provided', () => {
87
+ const { getByLabelText } = render(renderForm(false, {}));
88
+ expect(getByLabelText(testLabelName)).toHaveAttribute(
89
+ 'aria-labelledby',
90
+ `${testLabelName}Label`
91
+ );
92
+ expect(
93
+ document.getElementById(`${testLabelName}Label`)
94
+ ).toBeInTheDocument();
95
+ });
96
+ });
97
+
98
+ describe('With Error', () => {
99
+ test('correctly renders the checkbox with an error message underneath', async () => {
100
+ const { getByText } = render(renderForm(false, { isRequired: true }));
101
+ const submitButton = getByText('submit');
102
+
103
+ fireEvent.click(submitButton);
104
+ await waitFor(() =>
105
+ expect(screen.getByText('Checkbox is required')).toBeInTheDocument()
106
+ );
107
+ });
108
+
109
+ test('correctly renders the toggle with an error message from nested object', async () => {
110
+ const { getByText } = render(
111
+ renderForm(
112
+ { outer: { nested: false } },
113
+ { isRequired: true },
114
+ `${testLabelName}.outer.nested`
115
+ )
116
+ );
117
+ const submitButton = getByText('submit');
118
+
119
+ fireEvent.click(submitButton);
120
+ await waitFor(() =>
121
+ expect(screen.getByText('Checkbox is required')).toBeInTheDocument()
122
+ );
123
+ });
124
+ });
125
+ });
126
+
127
+ describe('Callback Handling', () => {
128
+ describe('onChange', () => {
129
+ test("Custom onChange event fires callback function, overwriting Formik's onChange", () => {
130
+ let value = false;
131
+ const mockedHandleChange = jest.fn((event) => {
132
+ value = event.target.checked;
133
+ });
134
+
135
+ const { getByLabelText } = render(
136
+ renderForm(value, { onChange: mockedHandleChange })
137
+ );
138
+ const checkbox = getByLabelText(testLabelName);
139
+
140
+ act(() => {
141
+ fireEvent.click(checkbox);
142
+ });
143
+
144
+ expect(mockedHandleChange).toHaveBeenCalledTimes(1);
145
+ expect(value).toBe(true);
146
+ });
147
+
148
+ test('Standard Formik onChange modifies the target value', async () => {
149
+ const { getByLabelText, getByText, queryByText } = render(
150
+ renderForm(false, { isRequired: true })
151
+ );
152
+ const submitButton = getByText('submit');
153
+ const checkbox = getByLabelText(testLabelName) as HTMLInputElement;
154
+ expect(checkbox.checked).toBe(false);
155
+
156
+ fireEvent.click(submitButton);
157
+ // expect(mockedHandleSubmit).toHaveBeenCalledTimes(0);
158
+ await waitFor(() =>
159
+ expect(getByText('Checkbox is required')).toBeInTheDocument()
160
+ );
161
+
162
+ act(() => {
163
+ fireEvent.click(checkbox);
164
+ });
165
+ expect(checkbox.checked).toBe(true);
166
+ await waitFor(() =>
167
+ expect(queryByText('Checkbox is required')).not.toBeInTheDocument()
168
+ );
169
+ });
170
+ });
171
+ });
172
+ });
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import {
3
+ FormikTouched,
4
+ FormikErrors,
5
+ FieldAttributes,
6
+ FormikValues,
7
+ getIn,
8
+ } from 'formik';
9
+ import { Toggle } from '../../Toggle/Toggle';
10
+
11
+ export interface FormikToggleProps {
12
+ field: FieldAttributes<HTMLTextAreaElement>;
13
+ form: {
14
+ touched: FormikTouched<FormikValues>;
15
+ errors: FormikErrors<FormikValues>;
16
+ };
17
+ id: string;
18
+ label: string;
19
+ }
20
+
21
+ export const FormikToggle: React.FC<FormikToggleProps> = ({
22
+ field: {
23
+ name,
24
+ onBlur, // eslint-disable-line no-unused-vars
25
+ onChange, // eslint-disable-line no-unused-vars
26
+ value,
27
+ },
28
+ form: { touched, errors },
29
+ ...props
30
+ }) => (
31
+ <Toggle
32
+ error={getIn(touched, name) && getIn(errors, name)}
33
+ isChecked={value}
34
+ onBlur={onBlur}
35
+ onChange={onChange} // eslint-disable-line
36
+ {...props}
37
+ />
38
+ );
@@ -0,0 +1,19 @@
1
+ export type HEADING_LEVELS_TYPE = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
2
+
3
+ export const HEADING_LEVELS: HEADING_LEVELS_TYPE[] = [
4
+ 'h1',
5
+ 'h2',
6
+ 'h3',
7
+ 'h4',
8
+ 'h5',
9
+ 'h6',
10
+ ]; // eslint-disable-line import/prefer-default-export
11
+
12
+ export const HEADING_DEFAULT_SIZE_MAP = {
13
+ h1: '3xl',
14
+ h2: '2xl',
15
+ h3: 'xl',
16
+ h4: 'lg',
17
+ h5: 'md',
18
+ h6: 'sm',
19
+ };
@@ -0,0 +1,35 @@
1
+ import { Heading } from './Heading';
2
+
3
+ import { Canvas, Meta, ArgTypes } from '@storybook/blocks';
4
+
5
+ import * as Stories from './Heading.stories';
6
+
7
+ <Meta of={Stories} />
8
+
9
+ # Heading
10
+
11
+ Use `Headings` as labels for pages or sections of a page that make up an interface. `Headings` can label an entire page, or sections of related content.
12
+ The `Heading` component allows you to specify an appropriate semantic element (h1-h6) and independently set its size so that it is appropriate for the surrounding content.
13
+ If no size is specified, a default size will be applied.
14
+
15
+ ## Props
16
+
17
+ <Canvas of={Stories.Levels} />
18
+
19
+ <ArgTypes of={Heading} />
20
+
21
+ ## Sizes
22
+
23
+ The default size of the Heading can overridden as so that it's appropriate for its surrounding context.
24
+
25
+ <Canvas of={Stories.Sizes} />
26
+
27
+ The `size` prop accepts an object where the properties correspond to [breakpoint tokens](?path=/docs/foundation-design-tokens--docs#breakpoints).
28
+
29
+ <Canvas of={Stories.ResponsiveSizes} />
30
+
31
+ ## Colors
32
+
33
+ The variant of the heading is inherited from its parent, but can be set to brand variant as well.
34
+
35
+ <Canvas of={Stories.Colors} />
@@ -0,0 +1,5 @@
1
+ .heading {
2
+ line-height: var(--size-line-height-heading);
3
+ font-family: var(--assets-font-family-brand);
4
+ font-weight: var(--size-font-weight-semibold);
5
+ }
@@ -0,0 +1,90 @@
1
+ import { Heading } from './Heading';
2
+ import type { Meta } from '@storybook/react';
3
+ import React from 'react';
4
+
5
+ const meta: Meta<typeof Heading> = {
6
+ title: 'Components/Heading',
7
+ component: Heading,
8
+ };
9
+
10
+ export default meta;
11
+
12
+ export const Levels = () => (
13
+ <>
14
+ <Heading as="h1">h1 Heading</Heading>
15
+ <Heading as="h2">h2 Heading</Heading>
16
+ <Heading as="h3">h3 Heading</Heading>
17
+ <Heading as="h4">h4 Heading</Heading>
18
+ <Heading as="h5">h5 Heading</Heading>
19
+ <Heading as="h6">h6 Heading</Heading>
20
+ </>
21
+ );
22
+
23
+ export const Sizes = () => (
24
+ <>
25
+ <Heading as="h3" size="sm">
26
+ sm 16px
27
+ </Heading>
28
+ <Heading as="h3" size="md">
29
+ md 20px
30
+ </Heading>
31
+ <Heading as="h3" size="lg">
32
+ lg 24px
33
+ </Heading>
34
+ <Heading as="h3" size="xl">
35
+ xl 32px
36
+ </Heading>
37
+ <Heading as="h3" size="2xl">
38
+ 2xl 40px
39
+ </Heading>
40
+ <Heading as="h3" size="3xl">
41
+ 3xl 48px
42
+ </Heading>
43
+ <Heading as="h3" size="4xl">
44
+ 4xl 56px
45
+ </Heading>
46
+ <Heading as="h3" size="5xl">
47
+ 5xl 64px
48
+ </Heading>
49
+ <Heading as="h3" size="6xl">
50
+ 6xl 72px
51
+ </Heading>
52
+ </>
53
+ );
54
+
55
+ export const ResponsiveSizes = () => (
56
+ <>
57
+ <Heading
58
+ as="h3"
59
+ size={{ base: 'sm', tablet: 'lg', desktop: 'xl', hd: '3xl' }}
60
+ >
61
+ New Developer Operations Platform
62
+ </Heading>
63
+ </>
64
+ );
65
+
66
+ export const Colors = () => (
67
+ <>
68
+ <Heading as="h3" color="base">
69
+ base
70
+ </Heading>
71
+ <Heading as="h3" color="secondary">
72
+ secondary
73
+ </Heading>
74
+ <Heading as="h3" color="inverse">
75
+ inverse
76
+ </Heading>
77
+ <Heading as="h3" color="disabled">
78
+ disabled
79
+ </Heading>
80
+ <Heading as="h3" color="success">
81
+ success
82
+ </Heading>
83
+ <Heading as="h3" color="warn">
84
+ warn
85
+ </Heading>
86
+ <Heading as="h3" color="danger">
87
+ danger
88
+ </Heading>
89
+ </>
90
+ );
@@ -0,0 +1,67 @@
1
+ //import '@testing-library/jest-dom';
2
+
3
+ import { FONT_COLOR_OPTIONS, HEADING_SIZE_OPTIONS } from '../../lib/tokens';
4
+ import { render, screen } from '@testing-library/react';
5
+
6
+ import { HEADING_LEVELS } from './Heading.constants';
7
+ import { Heading } from './Heading';
8
+ import React from 'react';
9
+ import { v4 as uuid } from 'uuid';
10
+
11
+ const headingComponentLevels = HEADING_LEVELS.map((level) => (
12
+ <Heading as={level} key={uuid()}>
13
+ {level}
14
+ </Heading>
15
+ ));
16
+
17
+ const headingComponentSizes = HEADING_SIZE_OPTIONS.map((fontSize) => (
18
+ <Heading size={fontSize} key={uuid()}>
19
+ {fontSize}
20
+ </Heading>
21
+ ));
22
+
23
+ const headingComponentColors = FONT_COLOR_OPTIONS.map((color) => (
24
+ <Heading color={color} key={uuid()}>
25
+ {color}
26
+ </Heading>
27
+ ));
28
+
29
+ describe('Heading', () => {
30
+ test('it adds className', () => {
31
+ render(<Heading className="test-class">Hello World</Heading>);
32
+ expect(screen.getByText('Hello World').classList).toContain('test-class');
33
+ });
34
+
35
+ describe('Levels', () => {
36
+ headingComponentLevels.forEach((headingComponent, index) => {
37
+ test(`it renders the specified html heading ${HEADING_LEVELS[index]}`, () => {
38
+ render(headingComponent);
39
+ expect(
40
+ document.getElementsByTagName(HEADING_LEVELS[index])[0]
41
+ ).toBeInTheDocument();
42
+ });
43
+ });
44
+ });
45
+
46
+ describe('Sizes', () => {
47
+ headingComponentSizes.forEach((headingComponent, index) => {
48
+ test(`it renders the specified size ${HEADING_SIZE_OPTIONS[index]}`, () => {
49
+ render(headingComponent);
50
+ expect(
51
+ screen.getByText(HEADING_SIZE_OPTIONS[index]).classList
52
+ ).toContain(`heading-${HEADING_SIZE_OPTIONS[index]}`);
53
+ });
54
+ });
55
+ });
56
+
57
+ describe('Colors', () => {
58
+ headingComponentColors.forEach((headingComponent, index) => {
59
+ test(`it renders the specified variant ${FONT_COLOR_OPTIONS[index]}`, () => {
60
+ render(headingComponent);
61
+ expect(screen.getByText(FONT_COLOR_OPTIONS[index]).classList).toContain(
62
+ `font-color-${FONT_COLOR_OPTIONS[index]}`
63
+ );
64
+ });
65
+ });
66
+ });
67
+ });