@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,54 @@
1
+ import React from 'react';
2
+ import { ResponsiveProvider } from './ResponsiveProvider';
3
+ import type { Meta } from '@storybook/react';
4
+ import { useWindowSize } from '../../hooks/useWindowSize/useWindowSize';
5
+ import { useBreakpoint } from '../../hooks/useBreakpoint/useBreakpoint';
6
+ import { Box } from '../Box/Box';
7
+
8
+ const meta: Meta<typeof ResponsiveProvider> = {
9
+ title: 'Providers/ResponsiveProvider',
10
+ component: ResponsiveProvider,
11
+ };
12
+
13
+ export default meta;
14
+
15
+ export const BasicUsage = () =>
16
+ (() => {
17
+ const App = () => {
18
+ const { innerWidth, innerHeight, outerWidth, outerHeight } =
19
+ useWindowSize();
20
+ return (
21
+ <Box gap="md">
22
+ <p>Inner Width: {innerWidth}</p>
23
+ <p>Inner Height: {innerHeight}</p>
24
+ <p>Outer Width: {outerWidth}</p>
25
+ <p>Outer Height: {outerHeight}</p>
26
+ </Box>
27
+ );
28
+ };
29
+ return (
30
+ <ResponsiveProvider>
31
+ <App />
32
+ </ResponsiveProvider>
33
+ );
34
+ })();
35
+
36
+ export const Breakpoints = () =>
37
+ (() => {
38
+ const App = () => {
39
+ const { isPhone, isTablet, isDesktop, isHd } = useBreakpoint();
40
+ return (
41
+ <Box gap="md">
42
+ <p>phone: {isPhone ? '✅' : '❌'}</p>
43
+ <p>tablet: {isTablet ? '✅' : '❌'}</p>
44
+ <p>desktop: {isDesktop ? '✅' : '❌'}</p>
45
+ <p>hd: {isHd ? '✅' : '❌'}</p>
46
+ </Box>
47
+ );
48
+ };
49
+ return (
50
+ <ResponsiveProvider>
51
+ <App />
52
+ </ResponsiveProvider>
53
+ );
54
+ })();
@@ -0,0 +1,70 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import { ResponsiveProvider } from './ResponsiveProvider';
4
+ import { useWindowSize } from '../../hooks/useWindowSize/useWindowSize';
5
+ import { useBreakpoint } from '../../hooks/useBreakpoint/useBreakpoint';
6
+
7
+ describe('Default', () => {
8
+ test('calls resize when initially mounted', async () => {
9
+ const mockEventListener = jest.spyOn(window, 'addEventListener');
10
+ mockEventListener.mockImplementation(() => {}); // eslint-disable-line
11
+
12
+ render(
13
+ <ResponsiveProvider>
14
+ <div />
15
+ </ResponsiveProvider>
16
+ );
17
+
18
+ expect(
19
+ mockEventListener.mock.calls.filter((call) => call[0] === 'resize').length
20
+ ).toEqual(1);
21
+ });
22
+ });
23
+
24
+ describe('Responsive hooks', () => {
25
+ it('registers one resize handler with useWindowSize', () => {
26
+ const mockEventListener = jest.spyOn(window, 'addEventListener');
27
+ mockEventListener.mockImplementation(() => {}); // eslint-disable-line
28
+
29
+ const Component = () => {
30
+ useWindowSize();
31
+ return <p />;
32
+ };
33
+
34
+ render(
35
+ <ResponsiveProvider>
36
+ <Component />
37
+ <Component />
38
+ <Component />
39
+ <Component />
40
+ <Component />
41
+ </ResponsiveProvider>
42
+ );
43
+ expect(
44
+ mockEventListener.mock.calls.filter((call) => call[0] === 'resize').length
45
+ ).toEqual(1);
46
+ });
47
+
48
+ it('registers one resize handler with useBreakpoint', () => {
49
+ const mockEventListener = jest.spyOn(window, 'addEventListener');
50
+ mockEventListener.mockImplementation(() => {}); // eslint-disable-line
51
+
52
+ const Component = () => {
53
+ useBreakpoint();
54
+ return <p />;
55
+ };
56
+
57
+ render(
58
+ <ResponsiveProvider>
59
+ <Component />
60
+ <Component />
61
+ <Component />
62
+ <Component />
63
+ <Component />
64
+ </ResponsiveProvider>
65
+ );
66
+ expect(
67
+ mockEventListener.mock.calls.filter((call) => call[0] === 'resize').length
68
+ ).toEqual(1);
69
+ });
70
+ });
@@ -0,0 +1,73 @@
1
+ import React, { useState, createContext } from 'react';
2
+ import { useIsomorphicLayoutEffect } from '../../hooks/useIsomorphicLayoutEffect/useIsomorphicLayouEffect';
3
+
4
+ export interface ResponsiveContextShape {
5
+ isCreated: boolean;
6
+ innerWidth?: number;
7
+ innerHeight?: number;
8
+ outerWidth?: number;
9
+ outerHeight?: number;
10
+ }
11
+
12
+ export const ResponsiveContext = createContext<ResponsiveContextShape>({
13
+ isCreated: false,
14
+ });
15
+
16
+ export interface ResponsiveProviderProps {
17
+ children?: React.ReactNode;
18
+ /**
19
+ * Time (in milliseconds) to delay execution of resize handler. Default is 50.
20
+ */
21
+ throttle?: number;
22
+ }
23
+
24
+ export const ResponsiveProvider: React.FC<ResponsiveProviderProps> = ({
25
+ children = null,
26
+ throttle = 50,
27
+ }) => {
28
+ const [innerWidth, setInnerWidth] = useState(0);
29
+ const [innerHeight, setInnerHeight] = useState(0);
30
+ const [outerWidth, setOuterWidth] = useState(0);
31
+ const [outerHeight, setOuterHeight] = useState(0);
32
+
33
+ const handleWindowResize = () => {
34
+ setInnerWidth(window?.innerWidth ?? 0);
35
+ setInnerHeight(window?.innerHeight ?? 0);
36
+ setOuterWidth(window?.outerWidth ?? 0);
37
+ setOuterHeight(window?.outerHeight ?? 0);
38
+ };
39
+
40
+ useIsomorphicLayoutEffect(() => {
41
+ // eslint-disable-line consistent-return
42
+ if (typeof window !== 'undefined') {
43
+ // Set values on render if window wasn't available for useState initialization.
44
+ handleWindowResize();
45
+
46
+ let timeoutId: any; // eslint-disable-line
47
+ const throttledResize = () => {
48
+ // prevent execution of previous setTimeout
49
+ clearTimeout(timeoutId);
50
+ // change width from the state object after throttle time has elapsed.
51
+ timeoutId = setTimeout(handleWindowResize, throttle);
52
+ };
53
+
54
+ window.addEventListener('resize', throttledResize);
55
+
56
+ return () => window.removeEventListener('resize', throttledResize);
57
+ }
58
+ }, [throttle]);
59
+
60
+ return (
61
+ <ResponsiveContext.Provider
62
+ value={{
63
+ innerWidth,
64
+ innerHeight,
65
+ outerHeight,
66
+ outerWidth,
67
+ isCreated: true,
68
+ }}
69
+ >
70
+ {children}
71
+ </ResponsiveContext.Provider>
72
+ );
73
+ };
@@ -0,0 +1,115 @@
1
+ import { Canvas, Meta, ArgTypes } from '@storybook/blocks';
2
+ import { SelectInput } from './SelectInput';
3
+ import * as Stories from './SelectInput.stories';
4
+
5
+ <Meta of={Stories} />
6
+
7
+ # SelectInput
8
+
9
+ Allows users to pick a value from a predefined list of options. Ideally, it should be used when there are 5 or more options, otherwise you should consider using a radio group instead.
10
+
11
+ _NOTE:_ This component is build on top of `react-select` and as such you can use any available prop from that component here as well. For a full list
12
+ of react-select props, [Click Here](https://react-select.com/props).
13
+
14
+ ## Props
15
+
16
+ <ArgTypes of={SelectInput} />
17
+
18
+ ## Default
19
+
20
+ All that is required to render a basic version of the SelectInput is a unique `id`, a `label`, a list of options passed to the `options` prop, a `value`, and an onchange event handler passed to the `onChange` prop.
21
+
22
+ <Canvas of={Stories.Default} />
23
+
24
+ ## Pre-Selected
25
+
26
+ Pre-select an option by passing its value to the `value` prop.
27
+
28
+ <Canvas of={Stories.PreSelected} />
29
+
30
+ ## Help Text
31
+
32
+ Use the `helpText` prop to add clarifying text beneath the input label.
33
+
34
+ <Canvas of={Stories.HelpText} />
35
+
36
+ ## Placeholder
37
+
38
+ Use the `placeholder` prop to add a custom placeholder.
39
+
40
+ <Canvas of={Stories.Placeholder} />
41
+
42
+ ## Hidden Label
43
+
44
+ Use the `hideLabel` prop to not render the label.
45
+
46
+ <Canvas of={Stories.HiddenLabel} />
47
+
48
+ ## Multi-Select
49
+
50
+ Use the `isMulti` prop to allow the selection of multiple options.
51
+
52
+ <Canvas of={Stories.MultiSelect} />
53
+
54
+ ## Multi-Select and Pre-Selected
55
+
56
+ Use the `isMulti` prop combined with passing one or more options in an array to the `value` prop to pre-select option(s).
57
+
58
+ <Canvas of={Stories.MultiSelectAndPreSelected} />
59
+
60
+ ## Autofocus
61
+
62
+ Use the `autoFocus` prop to autofocus a SelectInput.
63
+
64
+ <Canvas of={Stories.Autofocus} />
65
+
66
+ ## Required
67
+
68
+ Use the `isRequired` prop to mark the input as required.
69
+
70
+ <Canvas of={Stories.Required} />
71
+
72
+ ## Disabled
73
+
74
+ Use the `isDisabled` prop to mark the input as disabled.
75
+
76
+ <Canvas of={Stories.Disabled} />
77
+
78
+ ## Clearable
79
+
80
+ Use the `isClearable` prop to allow clearing of the input selected option. NOTE: this works by passing `null`
81
+ to the `onChange` handler.
82
+
83
+ <Canvas of={Stories.Clearable} />
84
+
85
+ ## Error
86
+
87
+ Use the `error` prop to mark the input as invalid. `error` accepts a `boolean`, `string`, or `node`. If either a `string` or `node` is passed, a validation message is displayed below it.
88
+
89
+ <Canvas of={Stories.Error} />
90
+
91
+ ## Sizes
92
+
93
+ Set the size of the input to `sm`, `md` or `lg`. `md` is the default size.
94
+ The `size` prop is also a `ResponsiveProp`, so it can be sized differently at each [breakpoint](?path=/docs/design-tokens-design-tokens--page#breakpoints) by passing an object.
95
+
96
+ <Canvas of={Stories.Sizes} />
97
+
98
+ ## With Portal
99
+
100
+ In many cases it is helpful to render the select dropdown in a portal to avoid cutoff from a smaller container.
101
+ We maintain the react-select API here where the `menuPortalTarget` prop is used. This is a ref to the element
102
+ being portaled to. In the example below we would see our dropdown menu be cutoff by the storybook story container,
103
+ if we did not portal it to the body element.
104
+
105
+ <Canvas of={Stories.WithPortal} />
106
+
107
+ ## Custom Classes
108
+
109
+ Use the `className` prop to add a custom class, or classes to an input.
110
+
111
+ <Canvas of={Stories.CustomClasses} />
112
+
113
+ ## Component Design Tokens
114
+
115
+ 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,357 @@
1
+ @import '@hyphen/hyphen-design-tokens/build/scss/variables';
2
+ // The following styles required the :global tag since they need to be applied to react-select elements for which we do not own the markup
3
+
4
+ @mixin react-select-icon {
5
+ padding: 0;
6
+ padding-right: 2px;
7
+ color: var(
8
+ --form-control-icon-color,
9
+ var(--INTERNAL_form-control-icon-color)
10
+ );
11
+
12
+ &:hover {
13
+ color: var(
14
+ --form-control-icon-color-hover,
15
+ var(--INTERNAL_form-control-icon-color-hover)
16
+ );
17
+ }
18
+ }
19
+
20
+ %react-select-icon {
21
+ @include react-select-icon;
22
+ }
23
+
24
+ .react-select-icon {
25
+ @extend %react-select-icon;
26
+ }
27
+
28
+ // stylelint-disable
29
+ @mixin size-sm {
30
+ :global(.react-select__control) {
31
+ border-radius: var(
32
+ --form-control-size-sm-border-radius,
33
+ var(--INTERNAL_form-control-size-sm-border-radius)
34
+ );
35
+ padding: 0 8px;
36
+ min-height: 32px;
37
+ }
38
+
39
+ :global(.react-select__option),
40
+ :global(.react-select__placeholder),
41
+ :global(.react-select__single-value) {
42
+ font-size: var(
43
+ --form-control-size-sm-font-size,
44
+ var(--INTERNAL_form-control-size-sm-font-size)
45
+ );
46
+ }
47
+
48
+ :global(.react-select__multi-value__label) {
49
+ font-size: var(
50
+ --form-control-size-sm-font-size,
51
+ var(--INTERNAL_form-control-size-sm-font-size)
52
+ );
53
+ }
54
+
55
+ :global(.react-select__dropdown-indicator) {
56
+ padding: 0;
57
+ }
58
+
59
+ :global(.react-select__dropdown-indicator) {
60
+ @include react-select-icon;
61
+
62
+ svg {
63
+ width: var(
64
+ --form-control-select-sm-icon-size,
65
+ var(--INTERNAL_form-control-select-sm-icon-size)
66
+ );
67
+ height: var(
68
+ --form-control-select-sm-icon-size,
69
+ var(--INTERNAL_form-control-select-sm-icon-size)
70
+ );
71
+ }
72
+ }
73
+ }
74
+
75
+ %size-sm {
76
+ @include size-sm;
77
+ }
78
+
79
+ .size-sm {
80
+ @extend %size-sm;
81
+ }
82
+
83
+ @mixin size-md {
84
+ :global(.react-select__control) {
85
+ border-radius: var(
86
+ --form-control-size-md-border-radius,
87
+ var(--INTERNAL_form-control-size-md-border-radius)
88
+ );
89
+ padding: 4px 8px;
90
+ }
91
+
92
+ :global(.react-select__single-value) {
93
+ font-size: var(
94
+ --form-control-size-md-font-size,
95
+ var(--INTERNAL_form-control-size-md-font-size)
96
+ );
97
+ }
98
+
99
+ :global(.react-select__multi-value__label) {
100
+ font-size: var(
101
+ --form-control-size-md-font-size,
102
+ var(--INTERNAL_form-control-size-md-font-size)
103
+ );
104
+ }
105
+
106
+ :global(.react-select__dropdown-indicator) {
107
+ padding: 0;
108
+ }
109
+
110
+ :global(.react-select__dropdown-indicator) {
111
+ @include react-select-icon;
112
+
113
+ svg {
114
+ width: var(
115
+ --form-control-select-md-icon-size,
116
+ var(--INTERNAL_form-control-select-md-icon-size)
117
+ );
118
+ height: var(
119
+ --form-control-select-md-icon-size,
120
+ var(--INTERNAL_form-control-select-md-icon-size)
121
+ );
122
+ }
123
+ }
124
+ }
125
+
126
+ %size-md {
127
+ @include size-md;
128
+ }
129
+
130
+ .size-md {
131
+ @extend %size-md;
132
+ }
133
+
134
+ @mixin size-lg {
135
+ :global(.react-select__control) {
136
+ padding: 9px 8px 10px;
137
+ border-radius: var(
138
+ --form-control-size-md-border-radius,
139
+ var(--INTERNAL_form-control-size-md-border-radius)
140
+ );
141
+ }
142
+
143
+ :global(.react-select__option),
144
+ :global(.react-select__placeholder),
145
+ :global(.react-select__single-value) {
146
+ font-size: var(
147
+ --form-control-size-lg-font-size,
148
+ var(--INTERNAL_form-control-size-lg-font-size)
149
+ );
150
+ }
151
+
152
+ :global(.react-select__multi-value__label) {
153
+ font-size: var(
154
+ --form-control-size-lg-font-size,
155
+ var(--INTERNAL_form-control-size-lg-font-size)
156
+ );
157
+ padding: 2px 6px 3px;
158
+ }
159
+
160
+ :global(.react-select__dropdown-indicator) {
161
+ padding: 0;
162
+ }
163
+
164
+ :global(.react-select__dropdown-indicator) {
165
+ @include react-select-icon;
166
+
167
+ svg {
168
+ width: var(
169
+ --form-control-select-md-icon-size,
170
+ var(--INTERNAL_form-control-select-md-icon-size)
171
+ );
172
+ height: var(
173
+ --form-control-select-md-icon-size,
174
+ var(--INTERNAL_form-control-select-md-icon-size)
175
+ );
176
+ }
177
+ }
178
+ }
179
+
180
+ %size-lg {
181
+ @include size-lg;
182
+ }
183
+
184
+ .size-lg {
185
+ @extend %size-lg;
186
+ }
187
+
188
+ :global(.select-input-wrapper) {
189
+ font-family: var(
190
+ --form-control-font-family,
191
+ var(--INTERNAL_form-control-font-family)
192
+ );
193
+
194
+ :global(.react-select) {
195
+ &:hover {
196
+ :global(.react-select__dropdown-indicator) {
197
+ color: var(
198
+ --form-control-border-color-focus,
199
+ var(--INTERNAL_form-control-border-color-focus)
200
+ );
201
+ }
202
+ }
203
+
204
+ :global(.react-select__control) {
205
+ line-height: var(
206
+ --form-control-line-height,
207
+ var(--INTERNAL_form-control-line-height)
208
+ );
209
+ border-color: var(
210
+ --form-control-border-color,
211
+ var(--INTERNAL_form-control-border-color)
212
+ );
213
+ background-color: var(
214
+ --form-control-background-color,
215
+ var(--INTERNAL_form-control-background-color)
216
+ );
217
+
218
+ :global(.react-select__value-container) {
219
+ padding: 0;
220
+ }
221
+
222
+ :global(.react-select__placeholder) {
223
+ color: var(
224
+ --form-control-placeholder-color,
225
+ var(--INTERNAL_form-control-placeholder-color)
226
+ );
227
+ }
228
+
229
+ :global(.react-select__clear-indicator) {
230
+ padding: 7px;
231
+ }
232
+
233
+ :global(.react-select__indicator-separator) {
234
+ display: none;
235
+ }
236
+
237
+ :global(.react-select__clear-indicator) {
238
+ @extend .react-select-icon;
239
+
240
+ margin-right: var(
241
+ --form-control-select-clear-icon-margin,
242
+ var(--INTERNAL_form-control-select-clear-icon-margin)
243
+ );
244
+ }
245
+
246
+ &:global(.react-select__control--is-focused) {
247
+ border: 1px solid var(--color-border-active);
248
+ box-shadow: var(
249
+ --form-control-box-shadow,
250
+ var(--INTERNAL_form-control-box-shadow-focus)
251
+ );
252
+ }
253
+
254
+ &:global(.react-select__control--is-disabled) {
255
+ :global(.react-select__dropdown-indicator) {
256
+ color: var(
257
+ --form-control-placeholder-color,
258
+ var(--INTERNAL_form-control-placeholder-color)
259
+ );
260
+ }
261
+ }
262
+ }
263
+
264
+ :global(.react-select__menu) {
265
+ z-index: var(--size-z-index-popover);
266
+ }
267
+
268
+ &.error {
269
+ :global(.react-select__control) {
270
+ border-color: var(
271
+ --form-control-border-color-error,
272
+ var(--INTERNAL_form-control-border-color-error)
273
+ );
274
+ background-color: var(
275
+ --form-control-background-color-error,
276
+ var(--INTERNAL_form-control-background-color-error)
277
+ );
278
+
279
+ &:global(.react-select__control--is-focused) {
280
+ outline: none;
281
+ border-color: var(
282
+ --form-control-border-color,
283
+ var(--INTERNAL_form-control-border-color)
284
+ );
285
+ background-color: var(
286
+ --form-control-background-color,
287
+ var(--INTERNAL_form-control-background-color)
288
+ );
289
+ }
290
+ }
291
+ }
292
+ }
293
+
294
+ &.size-sm {
295
+ @extend %size-sm;
296
+ }
297
+ &.size-md {
298
+ @extend %size-md;
299
+ }
300
+ &.size-lg {
301
+ @extend %size-lg;
302
+ }
303
+
304
+ @media (min-width: $size-breakpoint-tablet) {
305
+ &.size-sm-tablet {
306
+ @include size-sm;
307
+ }
308
+ &.size-md-tablet {
309
+ @include size-md;
310
+ }
311
+ &.size-lg-tablet {
312
+ @include size-lg;
313
+ }
314
+ }
315
+
316
+ @media (min-width: $size-breakpoint-desktop) {
317
+ &.size-sm-desktop {
318
+ @include size-sm;
319
+ }
320
+ &.size-md-desktop {
321
+ @include size-md;
322
+ }
323
+ &.size-lg-desktop {
324
+ @include size-lg;
325
+ }
326
+ }
327
+
328
+ @media (min-width: $size-breakpoint-hd) {
329
+ &.size-sm-hd {
330
+ @include size-sm;
331
+ }
332
+ &.size-md-hd {
333
+ @include size-md;
334
+ }
335
+ &.size-lg-hd {
336
+ @include size-lg;
337
+ }
338
+ }
339
+
340
+ &.disabled {
341
+ :global(.react-select__control--is-disabled) {
342
+ background-color: var(
343
+ --form-control-background-color-disabled,
344
+ var(--INTERNAL_form-control-background-color-disabled)
345
+ );
346
+ }
347
+ }
348
+ }
349
+ // stylelint-enable
350
+
351
+ // while we try to avoid important statements, this one is necessary to override bootstrap utilities that are currently in use by some of our teams
352
+ .select-input-label {
353
+ margin-bottom: var(
354
+ --form-control-label-margin,
355
+ var(--INTERNAL_form-control-label-margin)
356
+ ) !important;
357
+ }