@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,192 @@
1
+ import React, { FC, Key, KeyboardEvent, MouseEvent, ReactNode } from 'react';
2
+ import classNames from 'classnames';
3
+ import { Box } from '../../../Box/Box';
4
+ import { Icon } from '../../../Icon/Icon';
5
+ import { Column, EventWithColumnKey } from '../../../../types';
6
+ import styles from './TableHeaderCell.module.scss';
7
+
8
+ export interface TableHeaderCellProps {
9
+ /**
10
+ * Title to display for the column.
11
+ */
12
+ column: Column;
13
+ /**
14
+ * Text alignment for all table cells. Can be superseded by passing the same prop into the `Column` object
15
+ * for a specific column.
16
+ */
17
+ align?: 'left' | 'right' | 'center';
18
+ /**
19
+ * Custom class to apply to the `<th>` element.
20
+ */
21
+ className?: string;
22
+ /**
23
+ * Key of corresponding data value in the table.
24
+ */
25
+ dataKey?: Key;
26
+ /**
27
+ * Remove borders around th elements.
28
+ */
29
+ isBorderless?: boolean;
30
+ /**
31
+ * Determines if table header cells should render as compact (less padding);
32
+ */
33
+ isCompact?: boolean;
34
+ /**
35
+ * If table scrolls vertically, header will remain stuck to the top of the table, and not scroll away.
36
+ */
37
+ hasStickyHeader?: boolean;
38
+ /**
39
+ * Boolean to mark if a column is sortable. This will show the sorting icons. Use
40
+ * in conjunction with the `sortDirection` prop to determine which icon is shown.
41
+ */
42
+ isSortable?: boolean;
43
+ /**
44
+ * Callback function to execute when a sortable column's header is clicked.
45
+ * Column can be sorted without providing an onSort method, it means that the arrows
46
+ * will not be clickable, but they will still represent the sort state
47
+ * of a column as determined by the `sortDirection` prop.
48
+ */
49
+ onSort?: (event: EventWithColumnKey) => void;
50
+ /**
51
+ * The key of the sorted column and its sort direction.
52
+ */
53
+ sortedColumn?: {
54
+ dataKey: string | undefined;
55
+ sortDirection: 'none' | 'ascending' | 'descending' | undefined;
56
+ };
57
+ /**
58
+ * Will stick to either the left or right side of a table during horizontal scroll.
59
+ */
60
+ sticky?: 'left' | 'right';
61
+ /**
62
+ * Whether the text should be cut off with ellipsis if it exceeds the width of the column.
63
+ */
64
+ truncateOverflow?: boolean;
65
+ /**
66
+ * Width of the column, if using the `useFixedWidthColumns` prop is set to true.
67
+ */
68
+ width?: number;
69
+ }
70
+
71
+ // eslint-disable-line import/prefer-default-export
72
+ export const TableHeaderCell: FC<TableHeaderCellProps> = ({
73
+ column,
74
+ align = 'left',
75
+ className = undefined,
76
+ dataKey = undefined,
77
+ isBorderless = false,
78
+ isCompact = false,
79
+ hasStickyHeader = false,
80
+ isSortable = false,
81
+ onSort = undefined,
82
+ sortedColumn = undefined,
83
+ sticky = undefined,
84
+ truncateOverflow = false,
85
+ width = undefined,
86
+ }) => {
87
+ const isColumnSorted = (columnDataKey: Key | undefined): boolean =>
88
+ !!sortedColumn && sortedColumn.dataKey === columnDataKey;
89
+
90
+ const getSortDirection = ():
91
+ | 'ascending'
92
+ | 'descending'
93
+ | 'none'
94
+ | undefined =>
95
+ sortedColumn && isColumnSorted(column.dataKey)
96
+ ? sortedColumn.sortDirection
97
+ : 'none';
98
+
99
+ const renderIcon = (): ReactNode => {
100
+ const renderArrows = (): ReactNode => {
101
+ if (getSortDirection() === 'ascending') {
102
+ return (
103
+ <Icon
104
+ name="caret-sm-up"
105
+ data-testid="tableHeaderCellSortAsc-testid"
106
+ />
107
+ );
108
+ }
109
+ if (getSortDirection() === 'descending') {
110
+ return (
111
+ <Icon
112
+ name="caret-sm-down"
113
+ data-testid="tableHeaderCellSortDesc-testid"
114
+ />
115
+ );
116
+ }
117
+
118
+ return (
119
+ <Box
120
+ display="inline-block"
121
+ width="12px"
122
+ height="12px"
123
+ aria-hidden="true"
124
+ data-testid="tableHeaderCellSortNone-testid"
125
+ />
126
+ );
127
+ };
128
+
129
+ return <span className={styles['sort-icon']}>{renderArrows()}</span>;
130
+ };
131
+
132
+ const handleKeyPress = (
133
+ event: KeyboardEvent<HTMLTableHeaderCellElement>
134
+ ): void => {
135
+ if (!onSort || !isSortable) return;
136
+
137
+ const enterKey = 13;
138
+ const spaceKey = 32;
139
+
140
+ if (event.keyCode === enterKey || event.keyCode === spaceKey) {
141
+ const eventWithKey: EventWithColumnKey = { ...event, sortedKey: dataKey };
142
+ onSort(eventWithKey);
143
+ }
144
+ };
145
+
146
+ const handleSort = (event: MouseEvent<HTMLTableHeaderCellElement>): void => {
147
+ if (!onSort || !isSortable) return;
148
+
149
+ const eventWithKey: EventWithColumnKey = { ...event, sortedKey: dataKey };
150
+ onSort(eventWithKey);
151
+ };
152
+
153
+ const tableHeaderClasses = classNames(
154
+ styles['table-header-cell'],
155
+ {
156
+ [styles.sortable]: isSortable,
157
+ [styles.compact]: isCompact,
158
+ [styles.truncated]: truncateOverflow,
159
+ [styles.borderless]: isBorderless,
160
+ [styles['sticky-header']]: hasStickyHeader,
161
+ [styles['sticky-column']]: sticky === 'left' || sticky === 'right',
162
+ [styles['sticky-column-left']]: sticky === 'left',
163
+ [styles['sticky-column-right']]: sticky === 'right',
164
+ [styles['align-right']]: align === 'right',
165
+ [styles['align-center']]: align === 'center',
166
+ },
167
+ className
168
+ );
169
+
170
+ return (
171
+ <Box
172
+ as="th"
173
+ display="table-cell"
174
+ className={tableHeaderClasses}
175
+ width={`${width}px`}
176
+ aria-sort={
177
+ sortedColumn && isColumnSorted(column.dataKey)
178
+ ? sortedColumn.sortDirection
179
+ : 'none'
180
+ }
181
+ tabIndex={isSortable ? 0 : undefined}
182
+ onClick={handleSort}
183
+ onKeyDown={handleKeyPress}
184
+ scope="col"
185
+ >
186
+ <div className={styles.heading}>
187
+ {column.heading}
188
+ {isSortable && renderIcon()}
189
+ </div>
190
+ </Box>
191
+ );
192
+ };
@@ -0,0 +1,5 @@
1
+ .table-row {
2
+ &.hoverable {
3
+ background-color: var(--table-row-hover-background);
4
+ }
5
+ }
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { TableRow } from './TableRow';
4
+
5
+ const row = { id: 1, flavor: 'vanilla' };
6
+ const rowIndex = 1;
7
+ const columns = [
8
+ { heading: 'ID', dataKey: 'id' },
9
+ { heading: 'Flavor', dataKey: 'flavor' },
10
+ ];
11
+
12
+ describe('TableRow', () => {
13
+ describe('States', () => {
14
+ test('It renders with a custom class is passed as prop', () => {
15
+ render(
16
+ <TableRow
17
+ row={row}
18
+ rowIndex={rowIndex}
19
+ columns={columns}
20
+ className="my-custom-class"
21
+ />
22
+ );
23
+
24
+ const tableRow = screen.getByRole('row');
25
+ expect(tableRow).toHaveClass('my-custom-class');
26
+ });
27
+
28
+ test('It renders with a custom cell class (function) is passed as prop', () => {
29
+ const func = jest.fn().mockReturnValue('my-custom-class');
30
+ const customClassCell = [
31
+ { heading: 'ID', dataKey: 'id', cellClassName: func },
32
+ ];
33
+ render(
34
+ <TableRow row={row} rowIndex={rowIndex} columns={customClassCell} />
35
+ );
36
+ expect(func).toHaveBeenCalledWith(customClassCell[0], row, rowIndex);
37
+ const element = document.getElementsByClassName('my-custom-class')[0];
38
+ expect(element).toBeInTheDocument();
39
+ });
40
+
41
+ test('It renders with a custom cell class (string) is passed as prop', () => {
42
+ const customClassCell = [
43
+ { heading: 'ID', dataKey: 'id', cellClassName: 'string-class' },
44
+ ];
45
+ render(
46
+ <TableRow row={row} rowIndex={rowIndex} columns={customClassCell} />
47
+ );
48
+ const element = document.getElementsByClassName('string-class')[0];
49
+ expect(element).toBeInTheDocument();
50
+ });
51
+ });
52
+ });
@@ -0,0 +1,155 @@
1
+ import React, { FC, ReactNode } from 'react';
2
+ import classNames from 'classnames';
3
+ import styles from './TableRow.module.scss';
4
+ import { Column, EventWithColumnKey, Row } from '../../../../types';
5
+ import { getColumnKeys } from '../../../../lib/getColumnKeys';
6
+ import TableBodyCell from '../../TableBody/TableBodyCell/TableBodyCell';
7
+ import { TableHeaderCell } from '../../TableHead/TableHeaderCell/TableHeaderCell';
8
+
9
+ export interface TableRowProps {
10
+ /**
11
+ * The table columns to be rendered
12
+ */
13
+ columns: Column[];
14
+ /**
15
+ * Text alignment for all table cells. Can be superseded by passing the same prop into the `Column` object
16
+ * for a specific column.
17
+ */
18
+ align?: 'left' | 'right' | 'center';
19
+ /**
20
+ * Custom class to be applied to `<tr>` element.
21
+ */
22
+ className?: string;
23
+ /**
24
+ * A global placeholder for empty cells. Note: can be overwriten by
25
+ * the same attribute passed for an individual column config object.
26
+ */
27
+ emptyCellPlaceholder?: string | number | undefined;
28
+ /**
29
+ * Whether the table has borders or not.
30
+ */
31
+ isBorderless?: boolean;
32
+ /**
33
+ * Whether the table rows have smaller padding
34
+ */
35
+ isCompact?: boolean;
36
+ /**
37
+ * If table scrolls vertically, header will remain stuck to the top of the table, and not scroll away.
38
+ */
39
+ hasStickyHeader?: boolean;
40
+ /**
41
+ * Determine whether row is hoverable
42
+ */
43
+ isHoverable?: boolean;
44
+ /**
45
+ * Whether the row is inside the table head (thead).
46
+ */
47
+ isTableHead?: boolean;
48
+ /**
49
+ * Callback function to fire on sorting one of the table headers.
50
+ */
51
+ onSort?: (event: EventWithColumnKey) => void;
52
+ /**
53
+ * The specific row to be rendered.
54
+ */
55
+ row?: Row;
56
+ /**
57
+ * The unique key to identify a React node for each row.
58
+ */
59
+ rowIndex?: number;
60
+ /**
61
+ * The key of the sorted column and its sort direction.
62
+ */
63
+ sortedColumn?: {
64
+ dataKey: string | undefined;
65
+ sortDirection: 'none' | 'ascending' | 'descending' | undefined;
66
+ };
67
+ /**
68
+ * Truncate overflow inside column based on column width. Can be overwritten on specific columns,
69
+ * by passing `truncateOverflow` value on a specific Column
70
+ */
71
+ truncateOverflow?: boolean;
72
+ }
73
+
74
+ export const TableRow: FC<TableRowProps> = ({
75
+ columns,
76
+ align = 'left',
77
+ className = '',
78
+ emptyCellPlaceholder = '',
79
+ isBorderless = false,
80
+ isCompact = false,
81
+ hasStickyHeader = false,
82
+ isHoverable = false,
83
+ isTableHead = false,
84
+ onSort = undefined,
85
+ sortedColumn = undefined,
86
+ row = undefined,
87
+ rowIndex = undefined,
88
+ truncateOverflow = false,
89
+ }) => {
90
+ const tableRowClasses = classNames(
91
+ styles['table-row'],
92
+ { [styles.hoverable]: isHoverable },
93
+ className
94
+ );
95
+
96
+ const renderCellContent = (column: Column): ReactNode => {
97
+ if (column.render) {
98
+ const cellValue = column.dataKey && row ? row[column.dataKey] : undefined;
99
+ return column.render(cellValue, row, rowIndex);
100
+ }
101
+
102
+ return column.dataKey && row ? row[column.dataKey] : null;
103
+ };
104
+
105
+ const getCellClassName = (column: Column): string | undefined => {
106
+ if (column.cellClassName) {
107
+ if (typeof column.cellClassName === 'function') {
108
+ return column.cellClassName(column, row, rowIndex);
109
+ }
110
+ return column.cellClassName;
111
+ }
112
+ return undefined;
113
+ };
114
+
115
+ return (
116
+ <tr className={tableRowClasses}>
117
+ {Object.values(columns).map((column, columnIndex) =>
118
+ isTableHead ? (
119
+ <TableHeaderCell
120
+ column={column}
121
+ align={column.align || align}
122
+ key={getColumnKeys(columns)[columnIndex]}
123
+ dataKey={column.dataKey}
124
+ className={column.headerClassName}
125
+ isSortable={column.isSortable}
126
+ onSort={onSort}
127
+ isBorderless={isBorderless}
128
+ isCompact={isCompact}
129
+ sortedColumn={sortedColumn}
130
+ truncateOverflow={column.truncateOverflow || truncateOverflow}
131
+ width={column.width}
132
+ hasStickyHeader={hasStickyHeader}
133
+ sticky={column.sticky}
134
+ />
135
+ ) : (
136
+ <TableBodyCell
137
+ align={column.align || align}
138
+ className={getCellClassName(column)}
139
+ emptyCellPlaceholder={
140
+ column.emptyCellPlaceholder || emptyCellPlaceholder
141
+ }
142
+ truncateOverflow={column.truncateOverflow || truncateOverflow}
143
+ key={getColumnKeys(columns)[columnIndex]}
144
+ isBorderless={isBorderless}
145
+ isCompact={isCompact}
146
+ width={column.width}
147
+ sticky={column.sticky}
148
+ >
149
+ {renderCellContent(column)}
150
+ </TableBodyCell>
151
+ )
152
+ )}
153
+ </tr>
154
+ );
155
+ };
@@ -0,0 +1,96 @@
1
+ import { Canvas, Meta, ArgTypes } from '@storybook/blocks';
2
+ import { TextInput } from './TextInput';
3
+ import * as Stories from './TextInput.stories';
4
+
5
+ <Meta of={Stories} />
6
+
7
+ # TextInput
8
+
9
+ Use TextInput to render a single-line text input. Masks can also be applied to custom format the input; currently supported masks include Credit Card and Phone.
10
+
11
+ <Canvas isExpanded of={Stories.Basic} />
12
+
13
+ ## Props
14
+
15
+ <ArgTypes of={TextInput} />
16
+
17
+ ## Examples
18
+
19
+ All that is required to render a basic version of the TextInput is a unique `id`, `label`, `value`, and an onchange event handler passed to the `onChange` prop.
20
+
21
+ <Canvas of={Stories.Examples} />
22
+
23
+ ## Required
24
+
25
+ Use the `isRequired` prop to set the `required` and `aria-required` on the underlying input element.
26
+
27
+ <Canvas of={Stories.Required} />
28
+
29
+ You can remove or customize the required indicator using the `requiredIndicator` prop.
30
+
31
+ <Canvas of={Stories.CustomRequiredIndicator} />
32
+
33
+ ## With Help Text
34
+
35
+ Use the `helpText` prop to add clarifying text beneath the input label.
36
+
37
+ <Canvas of={Stories.WithHelpText} />
38
+
39
+ ## Placeholder
40
+
41
+ Use the `placeholder` prop to add a custom placeholder.
42
+
43
+ <Canvas of={Stories.Placeholder} />
44
+
45
+ ## Autofocus
46
+
47
+ Use the `autoFocus` prop to autofocus the input.
48
+
49
+ <Canvas of={Stories.Autofocus} />
50
+
51
+ ## Hidden Label
52
+
53
+ Use the `hideLabel` prop to not render the label.
54
+
55
+ <Canvas of={Stories.HiddenLabel} />
56
+
57
+ ## Prefix and Suffix
58
+
59
+ All that is required to render a basic version of the TextInput is a unique `id`, `label`, `value`, and an onchange event handler passed to the `onChange` prop.
60
+
61
+ <Canvas of={Stories.PrefixAndSuffix} />
62
+
63
+ ## Disabled
64
+
65
+ Use the `isDisabled` prop to mark the input as disabled.
66
+
67
+ <Canvas of={Stories.Disabled} />
68
+
69
+ ## Clearable
70
+
71
+ Use the `onClear` prop to display a clear icon (x) when the input has a value. `onClear` will fire
72
+ a callback function when the clear icon is clicked, which can then be handled to clear the value.
73
+
74
+ <Canvas of={Stories.Clearable} />
75
+
76
+ ## Sizes
77
+
78
+ Set the `size` of the input to `sm`, `md` or `lg`. 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.
79
+
80
+ <Canvas of={Stories.Sizes} />
81
+
82
+ ## Max Length
83
+
84
+ Use the `maxLength` prop to limit the number of characters that can be entered into an input.
85
+
86
+ <Canvas of={Stories.MaxLength} />
87
+
88
+ ## Validation Error
89
+
90
+ Use the `error` prop to mark the input as invalid. `error` accepts a `boolean`, `string`, or `node`.
91
+
92
+ <Canvas of={Stories.ValidationError} />
93
+
94
+ ## Component Design Tokens
95
+
96
+ 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).