@nypl/design-system-react-components 0.25.13 → 0.27.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 (305) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +10 -10
  3. package/dist/components/Accordion/Accordion.d.ts +1 -1
  4. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +1 -1
  5. package/dist/components/Button/Button.d.ts +2 -2
  6. package/dist/components/Card/Card.d.ts +11 -9
  7. package/dist/components/Checkbox/Checkbox.d.ts +2 -2
  8. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +5 -4
  9. package/dist/components/ComponentWrapper/ComponentWrapper.d.ts +1 -1
  10. package/dist/components/DatePicker/DatePicker.d.ts +5 -6
  11. package/dist/components/Fieldset/Fieldset.d.ts +5 -6
  12. package/dist/components/Form/Form.d.ts +6 -6
  13. package/dist/components/Grid/GridTypes.d.ts +7 -7
  14. package/dist/components/Grid/SimpleGrid.d.ts +1 -1
  15. package/dist/components/Heading/Heading.d.ts +1 -1
  16. package/dist/components/HelperErrorText/HelperErrorText.d.ts +9 -8
  17. package/dist/components/Hero/Hero.d.ts +2 -1
  18. package/dist/components/HorizontalRule/HorizontalRule.d.ts +2 -10
  19. package/dist/components/Icons/Icon.d.ts +2 -1
  20. package/dist/components/Image/Image.d.ts +2 -2
  21. package/dist/components/Label/Label.d.ts +7 -4
  22. package/dist/components/Link/Link.d.ts +1 -1
  23. package/dist/components/List/List.d.ts +11 -11
  24. package/dist/components/List/ListTypes.d.ts +1 -1
  25. package/dist/components/Logo/Logo.d.ts +2 -1
  26. package/dist/components/Logo/LogoSvgs.d.ts +2 -0
  27. package/dist/components/Logo/LogoTypes.d.ts +2 -0
  28. package/dist/components/Modal/Modal.d.ts +28 -8
  29. package/dist/components/Notification/Notification.d.ts +4 -4
  30. package/dist/components/Pagination/Pagination.d.ts +2 -2
  31. package/dist/components/ProgressIndicator/ProgressIndicator.d.ts +3 -3
  32. package/dist/components/Radio/Radio.d.ts +4 -6
  33. package/dist/components/RadioGroup/RadioGroup.d.ts +12 -6
  34. package/dist/components/SearchBar/SearchBar.d.ts +4 -4
  35. package/dist/components/Select/Select.d.ts +10 -6
  36. package/dist/components/Select/SelectTypes.d.ts +4 -0
  37. package/dist/components/SkeletonLoader/SkeletonLoader.d.ts +4 -3
  38. package/dist/components/Slider/Slider.d.ts +6 -4
  39. package/dist/components/StatusBadge/StatusBadge.d.ts +5 -1
  40. package/dist/components/StructuredContent/StructuredContent.d.ts +2 -2
  41. package/dist/components/Table/Table.d.ts +1 -1
  42. package/dist/components/Tabs/Tabs.d.ts +4 -3
  43. package/dist/components/Template/Template.d.ts +4 -3
  44. package/dist/components/Text/Text.d.ts +1 -1
  45. package/dist/components/TextInput/TextInput.d.ts +5 -5
  46. package/dist/components/Toggle/Toggle.d.ts +3 -4
  47. package/dist/components/VideoPlayer/VideoPlayer.d.ts +2 -1
  48. package/dist/design-system-react-components.cjs.development.js +1767 -1180
  49. package/dist/design-system-react-components.cjs.development.js.map +1 -1
  50. package/dist/design-system-react-components.cjs.production.min.js +1 -1
  51. package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
  52. package/dist/design-system-react-components.esm.js +1774 -1188
  53. package/dist/design-system-react-components.esm.js.map +1 -1
  54. package/dist/hooks/useCarouselStyles.d.ts +3 -2
  55. package/dist/hooks/useNYPLTheme.d.ts +12 -0
  56. package/dist/index.d.ts +5 -2
  57. package/dist/styles.css +1 -1
  58. package/dist/theme/components/button.d.ts +10 -2
  59. package/dist/theme/components/card.d.ts +42 -22
  60. package/dist/theme/components/checkbox.d.ts +5 -4
  61. package/dist/theme/components/checkboxGroup.d.ts +1 -1
  62. package/dist/theme/components/componentWrapper.d.ts +2 -2
  63. package/dist/theme/components/customTable.d.ts +84 -1
  64. package/dist/theme/components/fieldset.d.ts +4 -14
  65. package/dist/theme/components/global.d.ts +23 -17
  66. package/dist/theme/components/heading.d.ts +53 -0
  67. package/dist/theme/components/helperErrorText.d.ts +1 -0
  68. package/dist/theme/components/hero.d.ts +20 -14
  69. package/dist/theme/components/label.d.ts +9 -10
  70. package/dist/theme/components/list.d.ts +99 -9
  71. package/dist/theme/components/radio.d.ts +6 -4
  72. package/dist/theme/components/radioGroup.d.ts +1 -1
  73. package/dist/theme/components/select.d.ts +28 -5
  74. package/dist/theme/components/skeletonLoader.d.ts +2 -2
  75. package/dist/theme/components/slider.d.ts +6 -3
  76. package/dist/theme/components/structuredContent.d.ts +197 -0
  77. package/dist/theme/components/textInput.d.ts +18 -6
  78. package/dist/theme/components/toggle.d.ts +7 -4
  79. package/dist/theme/foundations/global.d.ts +2 -0
  80. package/dist/theme/foundations/radii.d.ts +1 -0
  81. package/dist/theme/foundations/spacing.d.ts +46 -43
  82. package/package.json +17 -19
  83. package/src/components/Accordion/Accordion.stories.mdx +9 -9
  84. package/src/components/Accordion/Accordion.test.tsx +21 -0
  85. package/src/components/Accordion/Accordion.tsx +13 -9
  86. package/src/components/Accordion/__snapshots__/Accordion.test.tsx.snap +276 -27
  87. package/src/components/Autosuggest/Autosuggest.stories.mdx +4 -3
  88. package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +21 -5
  89. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +52 -31
  90. package/src/components/Breadcrumbs/Breadcrumbs.tsx +8 -7
  91. package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +211 -12
  92. package/src/components/Button/Button.stories.mdx +87 -23
  93. package/src/components/Button/Button.test.tsx +25 -0
  94. package/src/components/Button/Button.tsx +18 -7
  95. package/src/components/Button/__snapshots__/Button.test.tsx.snap +27 -7
  96. package/src/components/Card/Card.stories.mdx +287 -194
  97. package/src/components/Card/Card.test.tsx +102 -0
  98. package/src/components/Card/Card.tsx +73 -32
  99. package/src/components/Card/__snapshots__/Card.test.tsx.snap +196 -36
  100. package/src/components/Chakra/Grid.stories.mdx +4 -4
  101. package/src/components/Checkbox/Checkbox.stories.mdx +62 -10
  102. package/src/components/Checkbox/Checkbox.test.tsx +32 -9
  103. package/src/components/Checkbox/Checkbox.tsx +20 -15
  104. package/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +134 -7
  105. package/src/components/CheckboxGroup/CheckboxGroup.stories.mdx +65 -17
  106. package/src/components/CheckboxGroup/CheckboxGroup.test.tsx +137 -81
  107. package/src/components/CheckboxGroup/CheckboxGroup.tsx +31 -21
  108. package/src/components/CheckboxGroup/__snapshots__/CheckboxGroup.test.tsx.snap +332 -97
  109. package/src/components/ComponentWrapper/ComponentWrapper.test.tsx +12 -0
  110. package/src/components/ComponentWrapper/ComponentWrapper.tsx +39 -41
  111. package/src/components/ComponentWrapper/__snapshots__/ComponentWrapper.test.tsx.snap +47 -34
  112. package/src/components/DatePicker/DatePicker.stories.mdx +63 -27
  113. package/src/components/DatePicker/DatePicker.test.tsx +89 -13
  114. package/src/components/DatePicker/DatePicker.tsx +62 -56
  115. package/src/components/DatePicker/_DatePicker.scss +71 -13
  116. package/src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap +250 -206
  117. package/src/components/Fieldset/Fieldset.stories.mdx +33 -3
  118. package/src/components/Fieldset/Fieldset.test.tsx +58 -28
  119. package/src/components/Fieldset/Fieldset.tsx +35 -30
  120. package/src/components/Fieldset/__snapshots__/Fieldset.test.tsx.snap +40 -19
  121. package/src/components/Form/Form.stories.mdx +72 -39
  122. package/src/components/Form/Form.test.tsx +58 -15
  123. package/src/components/Form/Form.tsx +89 -67
  124. package/src/components/Form/__snapshots__/Form.test.tsx.snap +83 -5
  125. package/src/components/Grid/GridTypes.tsx +7 -7
  126. package/src/components/Grid/SimpleGrid.stories.mdx +34 -6
  127. package/src/components/Grid/SimpleGrid.test.tsx +9 -0
  128. package/src/components/Grid/SimpleGrid.tsx +29 -20
  129. package/src/components/Grid/__snapshots__/SimpleGrid.test.tsx.snap +16 -1
  130. package/src/components/Heading/Heading.stories.mdx +36 -3
  131. package/src/components/Heading/Heading.test.tsx +10 -0
  132. package/src/components/Heading/Heading.tsx +56 -50
  133. package/src/components/Heading/__snapshots__/Heading.test.tsx.snap +26 -7
  134. package/src/components/HelperErrorText/HelperErrorText.stories.mdx +64 -42
  135. package/src/components/HelperErrorText/HelperErrorText.test.tsx +15 -0
  136. package/src/components/HelperErrorText/HelperErrorText.tsx +40 -35
  137. package/src/components/HelperErrorText/__snapshots__/HelperErrorText.test.tsx.snap +35 -4
  138. package/src/components/Hero/Hero.stories.mdx +125 -95
  139. package/src/components/Hero/Hero.test.tsx +33 -0
  140. package/src/components/Hero/Hero.tsx +135 -126
  141. package/src/components/Hero/__snapshots__/Hero.test.tsx.snap +89 -17
  142. package/src/components/HorizontalRule/HorizontalRule.stories.mdx +26 -4
  143. package/src/components/HorizontalRule/HorizontalRule.test.tsx +9 -19
  144. package/src/components/HorizontalRule/HorizontalRule.tsx +9 -26
  145. package/src/components/HorizontalRule/__snapshots__/HorizontalRule.test.tsx.snap +18 -5
  146. package/src/components/Icons/Icon.stories.mdx +31 -6
  147. package/src/components/Icons/Icon.test.tsx +38 -0
  148. package/src/components/Icons/Icon.tsx +93 -76
  149. package/src/components/Icons/__snapshots__/Icon.test.tsx.snap +129 -0
  150. package/src/components/Image/Image.stories.mdx +29 -5
  151. package/src/components/Image/Image.test.tsx +8 -0
  152. package/src/components/Image/Image.tsx +38 -26
  153. package/src/components/Image/__snapshots__/Image.test.tsx.snap +24 -8
  154. package/src/components/Label/Label.stories.mdx +42 -20
  155. package/src/components/Label/Label.test.tsx +42 -17
  156. package/src/components/Label/Label.tsx +22 -13
  157. package/src/components/Label/__snapshots__/Label.test.tsx.snap +19 -15
  158. package/src/components/Link/Link.stories.mdx +25 -15
  159. package/src/components/Link/Link.test.tsx +21 -22
  160. package/src/components/Link/Link.tsx +8 -8
  161. package/src/components/Link/__snapshots__/Link.test.tsx.snap +37 -11
  162. package/src/components/List/List.stories.mdx +75 -40
  163. package/src/components/List/List.test.tsx +67 -19
  164. package/src/components/List/List.tsx +38 -25
  165. package/src/components/List/ListTypes.tsx +1 -1
  166. package/src/components/List/__snapshots__/List.test.tsx.snap +110 -8
  167. package/src/components/Logo/Logo.stories.mdx +30 -6
  168. package/src/components/Logo/Logo.test.tsx +17 -0
  169. package/src/components/Logo/Logo.tsx +18 -6
  170. package/src/components/Logo/LogoSvgs.tsx +4 -0
  171. package/src/components/Logo/LogoTypes.tsx +2 -0
  172. package/src/components/Logo/__snapshots__/Logo.test.tsx.snap +73 -2
  173. package/src/components/Modal/Modal.stories.mdx +256 -136
  174. package/src/components/Modal/Modal.test.tsx +151 -9
  175. package/src/components/Modal/Modal.tsx +140 -20
  176. package/src/components/Modal/__snapshots__/Modal.test.tsx.snap +25 -0
  177. package/src/components/Notification/Notification.stories.mdx +25 -1
  178. package/src/components/Notification/Notification.test.tsx +23 -0
  179. package/src/components/Notification/Notification.tsx +46 -44
  180. package/src/components/Notification/__snapshots__/Notification.test.tsx.snap +158 -29
  181. package/src/components/Pagination/Pagination.stories.mdx +25 -6
  182. package/src/components/Pagination/Pagination.test.tsx +25 -0
  183. package/src/components/Pagination/Pagination.tsx +6 -6
  184. package/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap +244 -27
  185. package/src/components/Placeholder/Placeholder.tsx +3 -1
  186. package/src/components/ProgressIndicator/ProgressIndicator.stories.mdx +76 -10
  187. package/src/components/ProgressIndicator/ProgressIndicator.test.tsx +81 -11
  188. package/src/components/ProgressIndicator/ProgressIndicator.tsx +17 -9
  189. package/src/components/ProgressIndicator/__snapshots__/ProgressIndicator.test.tsx.snap +101 -14
  190. package/src/components/Radio/Radio.stories.mdx +64 -12
  191. package/src/components/Radio/Radio.test.tsx +28 -8
  192. package/src/components/Radio/Radio.tsx +66 -63
  193. package/src/components/Radio/__snapshots__/Radio.test.tsx.snap +103 -6
  194. package/src/components/RadioGroup/RadioGroup.stories.mdx +224 -89
  195. package/src/components/RadioGroup/RadioGroup.test.tsx +122 -62
  196. package/src/components/RadioGroup/RadioGroup.tsx +106 -100
  197. package/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap +1236 -1020
  198. package/src/components/SearchBar/SearchBar.stories.mdx +101 -36
  199. package/src/components/SearchBar/{SearchBar.Test.tsx → SearchBar.test.tsx} +46 -4
  200. package/src/components/SearchBar/SearchBar.tsx +17 -8
  201. package/src/components/SearchBar/__snapshots__/SearchBar.test.tsx.snap +1039 -0
  202. package/src/components/Select/Select.stories.mdx +128 -49
  203. package/src/components/Select/Select.test.tsx +63 -16
  204. package/src/components/Select/Select.tsx +131 -92
  205. package/src/components/Select/SelectTypes.tsx +5 -0
  206. package/src/components/Select/__snapshots__/Select.test.tsx.snap +765 -425
  207. package/src/components/SkeletonLoader/SkeletonLoader.stories.mdx +42 -10
  208. package/src/components/SkeletonLoader/SkeletonLoader.test.tsx +8 -0
  209. package/src/components/SkeletonLoader/SkeletonLoader.tsx +76 -72
  210. package/src/components/SkeletonLoader/__snapshots__/SkeletonLoader.test.tsx.snap +169 -10
  211. package/src/components/Slider/Slider.stories.mdx +91 -42
  212. package/src/components/Slider/Slider.test.tsx +65 -17
  213. package/src/components/Slider/Slider.tsx +26 -19
  214. package/src/components/Slider/__snapshots__/Slider.test.tsx.snap +403 -226
  215. package/src/components/StatusBadge/StatusBadge.stories.mdx +19 -1
  216. package/src/components/StatusBadge/StatusBadge.test.tsx +16 -0
  217. package/src/components/StatusBadge/StatusBadge.tsx +25 -20
  218. package/src/components/StatusBadge/__snapshots__/StatusBadge.test.tsx.snap +22 -3
  219. package/src/components/StructuredContent/StructuredContent.stories.mdx +131 -12
  220. package/src/components/StructuredContent/StructuredContent.test.tsx +34 -0
  221. package/src/components/StructuredContent/StructuredContent.tsx +80 -75
  222. package/src/components/StructuredContent/__snapshots__/StructuredContent.test.tsx.snap +102 -17
  223. package/src/components/StyleGuide/Bidirectionality.stories.mdx +5 -5
  224. package/src/components/StyleGuide/Breakpoints.stories.mdx +6 -6
  225. package/src/components/StyleGuide/Buttons.stories.mdx +2 -12
  226. package/src/components/StyleGuide/ColorCard.tsx +1 -1
  227. package/src/components/StyleGuide/Colors.stories.mdx +1 -2
  228. package/src/components/StyleGuide/DesignTokens.stories.mdx +56 -26
  229. package/src/components/StyleGuide/Forms.stories.mdx +27 -12
  230. package/src/components/StyleGuide/Iconography.stories.mdx +2 -12
  231. package/src/components/StyleGuide/Spacing.stories.mdx +80 -41
  232. package/src/components/StyleGuide/Typography.stories.mdx +30 -21
  233. package/src/components/Table/Table.stories.mdx +38 -11
  234. package/src/components/Table/Table.test.tsx +15 -0
  235. package/src/components/Table/Table.tsx +7 -7
  236. package/src/components/Table/__snapshots__/Table.test.tsx.snap +408 -5
  237. package/src/components/Tabs/Tabs.stories.mdx +52 -3
  238. package/src/components/Tabs/Tabs.test.tsx +16 -0
  239. package/src/components/Tabs/Tabs.tsx +10 -6
  240. package/src/components/Tabs/__snapshots__/Tabs.test.tsx.snap +394 -5
  241. package/src/components/Template/Template.stories.mdx +47 -43
  242. package/src/components/Template/Template.test.tsx +33 -0
  243. package/src/components/Template/Template.tsx +65 -60
  244. package/src/components/Template/__snapshots__/Template.test.tsx.snap +191 -20
  245. package/src/components/Text/Text.stories.mdx +20 -1
  246. package/src/components/Text/Text.test.tsx +12 -0
  247. package/src/components/Text/Text.tsx +6 -4
  248. package/src/components/Text/__snapshots__/Text.test.tsx.snap +21 -4
  249. package/src/components/TextInput/TextInput.stories.mdx +65 -19
  250. package/src/components/TextInput/TextInput.test.tsx +42 -28
  251. package/src/components/TextInput/TextInput.tsx +121 -113
  252. package/src/components/TextInput/__snapshots__/TextInput.test.tsx.snap +96 -73
  253. package/src/components/Toggle/Toggle.stories.mdx +80 -22
  254. package/src/components/Toggle/Toggle.test.tsx +27 -9
  255. package/src/components/Toggle/Toggle.tsx +22 -18
  256. package/src/components/Toggle/__snapshots__/Toggle.test.tsx.snap +128 -5
  257. package/src/components/VideoPlayer/VideoPlayer.stories.mdx +52 -4
  258. package/src/components/VideoPlayer/VideoPlayer.test.tsx +23 -0
  259. package/src/components/VideoPlayer/VideoPlayer.tsx +133 -126
  260. package/src/components/VideoPlayer/__snapshots__/VideoPlayer.test.tsx.snap +81 -39
  261. package/src/docs/Chakra.stories.mdx +50 -9
  262. package/src/docs/Welcome.stories.mdx +160 -41
  263. package/src/hooks/useCarouselStyles.stories.mdx +22 -2
  264. package/src/hooks/useCarouselStyles.ts +3 -2
  265. package/src/hooks/useNYPLTheme.stories.mdx +101 -0
  266. package/src/hooks/useNYPLTheme.ts +30 -6
  267. package/src/hooks/useWindowSize.stories.mdx +23 -0
  268. package/src/index.ts +5 -2
  269. package/src/styles/base/_place-holder.scss +1 -1
  270. package/src/styles.scss +0 -1
  271. package/src/theme/components/button.ts +15 -7
  272. package/src/theme/components/card.ts +30 -19
  273. package/src/theme/components/checkbox.ts +10 -8
  274. package/src/theme/components/checkboxGroup.ts +1 -1
  275. package/src/theme/components/componentWrapper.ts +2 -2
  276. package/src/theme/components/customTable.ts +39 -31
  277. package/src/theme/components/fieldset.ts +1 -2
  278. package/src/theme/components/global.ts +25 -20
  279. package/src/theme/components/heading.ts +1 -1
  280. package/src/theme/components/helperErrorText.ts +1 -0
  281. package/src/theme/components/hero.ts +13 -15
  282. package/src/theme/components/label.ts +4 -3
  283. package/src/theme/components/list.ts +73 -66
  284. package/src/theme/components/notification.ts +2 -2
  285. package/src/theme/components/radio.ts +9 -9
  286. package/src/theme/components/radioGroup.ts +1 -1
  287. package/src/theme/components/select.ts +31 -22
  288. package/src/theme/components/skeletonLoader.ts +3 -3
  289. package/src/theme/components/slider.ts +8 -7
  290. package/src/theme/components/statusBadge.ts +2 -2
  291. package/src/theme/components/structuredContent.ts +66 -1
  292. package/src/theme/components/tabs.ts +2 -2
  293. package/src/theme/components/template.ts +9 -9
  294. package/src/theme/components/textInput.ts +13 -12
  295. package/src/theme/components/toggle.ts +17 -10
  296. package/src/theme/components/videoPlayer.ts +1 -1
  297. package/src/theme/foundations/colors.ts +1 -1
  298. package/src/theme/foundations/radii.ts +1 -0
  299. package/src/theme/foundations/spacing.ts +70 -22
  300. package/src/theme/foundations/typography.ts +2 -2
  301. package/src/utils/componentCategories.ts +1 -2
  302. package/dist/components/SearchBar/SearchBar.Test.d.ts +0 -1
  303. package/dist/helpers/generateUUID.d.ts +0 -1
  304. package/src/components/Modal/_Modal.scss +0 -18
  305. package/src/helpers/generateUUID.tsx +0 -5
@@ -41,7 +41,7 @@ export const enumValues = getStorybookEnumValues(
41
41
  ref: { table: { disable: true } },
42
42
  showHelperInvalidText: { table: { defaultValue: { summary: true } } },
43
43
  showLabel: { table: { defaultValue: { summary: true } } },
44
- showOptReqLabel: { table: { defaultValue: { summary: true } } },
44
+ showRequiredLabel: { table: { defaultValue: { summary: true } } },
45
45
  step: { table: { defaultValue: { summary: 1 } } },
46
46
  textInputType: {
47
47
  control: false,
@@ -61,7 +61,18 @@ export const enumValues = getStorybookEnumValues(
61
61
  | Component Version | DS Version |
62
62
  | ----------------- | ---------- |
63
63
  | Added | `0.22.0` |
64
- | Latest | `0.25.13` |
64
+ | Latest | `0.26.0` |
65
+
66
+ ## Table of Contents
67
+
68
+ - [Overview](#overview)
69
+ - [Component Props](#component-props)
70
+ - [Accessibility](#accessibility)
71
+ - [Labelling Variations](#labelling-variations)
72
+ - [HTML in Helper Text](#html-in-helper-text)
73
+ - [Textarea](#textarea)
74
+
75
+ ## Overview
65
76
 
66
77
  <Description of={TextInput} />
67
78
 
@@ -71,6 +82,8 @@ prop, regardless of the label visibility. Additionally, while the `id` prop is
71
82
  optional, a unique `id` attribute is necessary for accessibility. If the prop
72
83
  is left blank, a value will be generated for you.
73
84
 
85
+ ## Component Props
86
+
74
87
  <Canvas withToolbar>
75
88
  <Story
76
89
  name="TextInput with Controls"
@@ -91,7 +104,7 @@ is left blank, a value will be generated for you.
91
104
  placeholder: "e.g. blue, green, etc.",
92
105
  showHelperInvalidText: true,
93
106
  showLabel: true,
94
- showOptReqLabel: true,
107
+ showRequiredLabel: true,
95
108
  step: 1,
96
109
  type: "TextInputTypes.text",
97
110
  value: undefined,
@@ -104,43 +117,71 @@ is left blank, a value will be generated for you.
104
117
 
105
118
  <ArgsTable story="TextInput with Controls" />
106
119
 
120
+ ## Accessibility
121
+
122
+ The `TextInput` component renders an HTML `<input>` element which is accessible
123
+ via keyboard and screen reader. The `aria-required` and `required` attributes are
124
+ set with the `isRequired` prop. The `aria-disabled` and `disabled` attributes are
125
+ set with the `isDisabled` prop. The `aria-invalid` is set with the `isInvalid`
126
+ prop.
127
+
128
+ Internally, a `Label` is associated with the `<input>` element. When `showLabel`
129
+ is set to false, the `<input>` element's `aria-label` attribute is set to the
130
+ required `labelText` value.
131
+
132
+ When the `type` prop is set to `TextInputTypes.textarea`, the `<textarea>` element
133
+ is rendered instead of the `<input>` element. This element follows all the same
134
+ accessibility rules described above.
135
+
136
+ Resources:
137
+
138
+ - [MDN input: The Input (Form Input) element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)
139
+ - [MDN textarea: The Textarea element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)
140
+ - [Chakra UI Input](https://chakra-ui.com/docs/components/form/input)
141
+ - [Chakra UI Textarea](https://chakra-ui.com/docs/components/form/textarea)
142
+
107
143
  ## Labelling Variations
108
144
 
109
145
  A TextInput can be rendered with or without visible labels. When `showLabel` is
110
146
  set to `false`, an `aria-label` attribute is added to the input/textarea element
111
147
  to maintain accessibility. If the component needs to be required, the
112
- `showOptReqLabel` prop can be used to show or hide the "Required"/"Optional"
113
- text within the `label` element.
148
+ `showRequiredLabel` prop can be used to show or hide the "(Required)" text
149
+ within the `label` element.
114
150
 
115
151
  <Canvas withToolbar>
116
152
  <Story name="Labelling Variations">
117
153
  <VStack align="stretch" spacing={12}>
118
154
  <TextInput
155
+ helperText="Choose wisely!"
156
+ id="textInput-1"
119
157
  labelText="What is your favorite color?"
120
158
  placeholder="i.e. blue, green, etc."
121
- helperText="Choose wisely!"
122
159
  />
123
160
  <TextInput
161
+ id="textInput-2"
124
162
  labelText="What is your favorite color?"
125
163
  placeholder="i.e. blue, green, etc."
126
164
  showLabel={false}
127
165
  />
128
166
  <TextInput
167
+ id="textInput-3"
168
+ isRequired
129
169
  labelText="What is your favorite color?"
130
170
  placeholder="i.e. blue, green, etc."
131
- isRequired
132
171
  />
133
172
  <TextInput
173
+ id="textInput-4"
174
+ isRequired
134
175
  labelText="What is your favorite color?"
135
176
  placeholder="i.e. blue, green, etc."
136
- showOptReqLabel={false}
137
- isRequired
177
+ showRequiredLabel={false}
138
178
  />
139
179
  <TextInput
180
+ helperText="Choose wisely!"
181
+ id="textInput-5"
140
182
  labelText="What is your favorite color?"
141
- showLabel={false}
142
183
  placeholder="i.e. blue, green, etc."
143
- helperText="Choose wisely!"
184
+ showLabel={false}
144
185
  />
145
186
  </VStack>
146
187
  </Story>
@@ -151,11 +192,12 @@ text within the `label` element.
151
192
  <Canvas>
152
193
  <DSProvider>
153
194
  <TextInput
154
- labelText="What is your favorite color?"
155
- placeholder="i.e. blue, green, etc."
156
195
  helperText="Choose wisely!"
196
+ id="errored"
157
197
  invalidText="This is error text :("
158
198
  isInvalid
199
+ labelText="What is your favorite color?"
200
+ placeholder="i.e. blue, green, etc."
159
201
  />
160
202
  </DSProvider>
161
203
  </Canvas>
@@ -165,10 +207,11 @@ text within the `label` element.
165
207
  <Canvas>
166
208
  <DSProvider>
167
209
  <TextInput
168
- labelText="What is your favorite color?"
169
- placeholder="i.e. blue, green, etc."
170
210
  helperText="Choose wisely!"
211
+ id="disabled"
171
212
  isDisabled
213
+ labelText="What is your favorite color?"
214
+ placeholder="i.e. blue, green, etc."
172
215
  />
173
216
  </DSProvider>
174
217
  </Canvas>
@@ -186,19 +229,21 @@ helperText={<>Choose <b>wisely!</b></>}
186
229
  <Canvas>
187
230
  <DSProvider>
188
231
  <TextInput
232
+ helperText="Choose <b>wisely!</b>"
233
+ id="string"
189
234
  labelText="What is your favorite color?"
190
235
  placeholder="i.e. blue, green, etc."
191
- helperText="Choose <b>wisely!</b>"
192
236
  />
193
237
  <br />
194
238
  <TextInput
195
- labelText="What is your favorite color?"
196
- placeholder="i.e. blue, green, etc."
197
239
  helperText={
198
240
  <>
199
241
  Choose <b>wisely!</b>
200
242
  </>
201
243
  }
244
+ id="jsx"
245
+ labelText="What is your favorite color?"
246
+ placeholder="i.e. blue, green, etc."
202
247
  />
203
248
  </DSProvider>
204
249
  </Canvas>
@@ -214,6 +259,7 @@ All the variations described above are available for the `textarea` option.
214
259
  name="Textarea"
215
260
  args={{
216
261
  helperText: "Let it all out.",
262
+ id: "textarea",
217
263
  invalidText: "This is error text :(",
218
264
  isDisabled: false,
219
265
  isInvalid: false,
@@ -221,7 +267,7 @@ All the variations described above are available for the `textarea` option.
221
267
  labelText: "In less than 500 words, describe your favorite color?",
222
268
  placeholder: "Essay question...",
223
269
  showLabel: true,
224
- showOptReqLabel: true,
270
+ showRequiredLabel: true,
225
271
  type: TextInputTypes.textarea,
226
272
  }}
227
273
  argTypes={{
@@ -6,12 +6,12 @@ import userEvent from "@testing-library/user-event";
6
6
 
7
7
  import TextInput from "./TextInput";
8
8
  import { TextInputTypes } from "./TextInputTypes";
9
- import * as generateUUID from "../../helpers/generateUUID";
10
9
 
11
10
  describe("TextInput Accessibility", () => {
12
11
  it("passes axe accessibility test for the input element", async () => {
13
12
  const { container } = render(
14
13
  <TextInput
14
+ id="textInput"
15
15
  isRequired
16
16
  labelText="Custom input label"
17
17
  onChange={jest.fn()}
@@ -25,6 +25,7 @@ describe("TextInput Accessibility", () => {
25
25
  it("passes axe accessibility test for the textarea element", async () => {
26
26
  const { container } = render(
27
27
  <TextInput
28
+ id="textInput"
28
29
  isRequired
29
30
  labelText="Custom textarea label"
30
31
  onChange={jest.fn()}
@@ -70,24 +71,7 @@ describe("TextInput", () => {
70
71
  expect(screen.getByText(/Required/i)).toBeInTheDocument();
71
72
  });
72
73
 
73
- it("renders 'Optional' along with the label text", () => {
74
- utils.rerender(
75
- <TextInput
76
- attributes={{ onFocus: focusHandler }}
77
- id="myTextInput"
78
- isRequired={false}
79
- labelText="Custom Input Label"
80
- onChange={changeHandler}
81
- placeholder="Input Placeholder"
82
- type={TextInputTypes.text}
83
- />
84
- );
85
-
86
- expect(screen.getByText("Custom Input Label")).toBeInTheDocument();
87
- expect(screen.getByText(/Optional/i)).toBeInTheDocument();
88
- });
89
-
90
- it("does not render 'Required' along with the label text", () => {
74
+ it("does not render '(Required)' along with the label text", () => {
91
75
  utils.rerender(
92
76
  <TextInput
93
77
  attributes={{ onFocus: focusHandler }}
@@ -96,7 +80,7 @@ describe("TextInput", () => {
96
80
  labelText="Custom Input Label"
97
81
  onChange={changeHandler}
98
82
  placeholder="Input Placeholder"
99
- showOptReqLabel={false}
83
+ showRequiredLabel={false}
100
84
  type={TextInputTypes.text}
101
85
  />
102
86
  );
@@ -136,16 +120,26 @@ describe("TextInput", () => {
136
120
  // Called 5 times because "Hello" has length of 5.
137
121
  expect(changeHandler).toHaveBeenCalledTimes(5);
138
122
  });
123
+
124
+ it("logs a warning when there is no `id` passed", () => {
125
+ const warn = jest.spyOn(console, "warn");
126
+ render(
127
+ // @ts-ignore: Typescript complains when a required prop is not passed, but
128
+ // here we don't want to pass the required prop to make sure the warning appears.
129
+ <TextInput labelText="Custom Input Label" />
130
+ );
131
+ expect(warn).toHaveBeenCalledWith(
132
+ "NYPL Reservoir TextInput: This component's required `id` prop was not passed."
133
+ );
134
+ });
139
135
  });
140
136
 
141
137
  describe("Renders TextInput with auto-generated ID, hidden label and visible helper text", () => {
142
- let generateUUIDSpy;
143
-
144
138
  beforeEach(() => {
145
- generateUUIDSpy = jest.spyOn(generateUUID, "default");
146
139
  render(
147
140
  <TextInput
148
141
  helperText="Custom Helper Text"
142
+ id="textInput"
149
143
  isRequired
150
144
  labelText="Custom Input Label"
151
145
  placeholder="Input Placeholder"
@@ -159,11 +153,6 @@ describe("Renders TextInput with auto-generated ID, hidden label and visible hel
159
153
  expect(screen.getByLabelText(/Custom Input Label/i)).toBeInTheDocument();
160
154
  });
161
155
 
162
- it("calls a UUID generation method if no ID is passed as a prop", () => {
163
- // Called twice for the `TextInput` and the SVG icon components.
164
- expect(generateUUIDSpy).toHaveBeenCalledTimes(2);
165
- });
166
-
167
156
  it("does not renders Label component", () => {
168
157
  expect(screen.queryByText(/Custom Input Label/i)).not.toBeInTheDocument();
169
158
  });
@@ -441,6 +430,29 @@ describe("UI Snapshots", () => {
441
430
  />
442
431
  )
443
432
  .toJSON();
433
+ const withChakraProps = renderer
434
+ .create(
435
+ <TextInput
436
+ id="chakra"
437
+ labelText="Custom Input Label"
438
+ placeholder="Input Placeholder"
439
+ type={TextInputTypes.text}
440
+ p="20px"
441
+ color="ui.error.primary"
442
+ />
443
+ )
444
+ .toJSON();
445
+ const withOtherProps = renderer
446
+ .create(
447
+ <TextInput
448
+ id="props"
449
+ labelText="Custom Input Label"
450
+ placeholder="Input Placeholder"
451
+ type={TextInputTypes.text}
452
+ data-testid="props"
453
+ />
454
+ )
455
+ .toJSON();
444
456
 
445
457
  expect(required).toMatchSnapshot();
446
458
  expect(optional).toMatchSnapshot();
@@ -448,6 +460,8 @@ describe("UI Snapshots", () => {
448
460
  expect(withHelperText).toMatchSnapshot();
449
461
  expect(errorState).toMatchSnapshot();
450
462
  expect(disabledState).toMatchSnapshot();
463
+ expect(withChakraProps).toMatchSnapshot();
464
+ expect(withOtherProps).toMatchSnapshot();
451
465
  });
452
466
 
453
467
  it("renders the textarea UI snapshot correctly", () => {
@@ -1,10 +1,11 @@
1
- import * as React from "react";
2
1
  import {
3
2
  Box,
3
+ chakra,
4
4
  Input as ChakraInput,
5
5
  Textarea as ChakraTextarea,
6
6
  useMultiStyleConfig,
7
7
  } from "@chakra-ui/react";
8
+ import * as React from "react";
8
9
 
9
10
  import {
10
11
  TextInputTypes,
@@ -15,7 +16,6 @@ import Label from "../Label/Label";
15
16
  import HelperErrorText, {
16
17
  HelperErrorTextType,
17
18
  } from "../HelperErrorText/HelperErrorText";
18
- import generateUUID from "../../helpers/generateUUID";
19
19
 
20
20
  export interface InputProps {
21
21
  /** Optionally pass in additional Chakra-based styles. */
@@ -29,7 +29,7 @@ export interface InputProps {
29
29
  /** Populates the HelperErrorText for the standard state */
30
30
  helperText?: HelperErrorTextType;
31
31
  /** ID that other components can cross reference for accessibility purposes */
32
- id?: string;
32
+ id: string;
33
33
  /** Populates the HelperErrorText for the error state */
34
34
  invalidText?: HelperErrorTextType;
35
35
  /** Adds the `disabled` and `aria-disabled` prop to the input when true */
@@ -56,9 +56,9 @@ export interface InputProps {
56
56
  /** Offers the ability to show the label onscreen or hide it. Refer to the
57
57
  * `labelText` property for more information. */
58
58
  showLabel?: boolean;
59
- /** Offers the ability to show the "Required"/"Optional" label onscreen or
60
- * hide it. True by default. */
61
- showOptReqLabel?: boolean;
59
+ /** Whether or not to display the "(Required)" text in the label text.
60
+ * True by default. */
61
+ showRequiredLabel?: boolean;
62
62
  /** The amount to increase or decrease when using the number type. */
63
63
  step?: number;
64
64
  /** FOR INTERNAL DS USE ONLY: the input variant to display. */
@@ -80,122 +80,130 @@ export type TextInputRefType = HTMLInputElement & HTMLTextAreaElement;
80
80
  * element. All types will render an accessible `Label` component and an
81
81
  * optional `HelperErrorText` component.
82
82
  */
83
- const TextInput = React.forwardRef<TextInputRefType, InputProps>(
84
- (props, ref: React.Ref<TextInputRefType>) => {
85
- const {
86
- additionalStyles = {},
87
- attributes = {},
88
- className,
89
- defaultValue,
90
- helperText,
91
- id = generateUUID(),
92
- invalidText,
93
- isDisabled = false,
94
- isInvalid = false,
95
- isRequired = false,
96
- labelText,
97
- name,
98
- onChange,
99
- placeholder,
100
- showHelperInvalidText = true,
101
- showLabel = true,
102
- showOptReqLabel = true,
103
- step = 1,
104
- textInputType = TextInputVariants.Default,
105
- type = TextInputTypes.text,
106
- value,
107
- } = props;
108
- const styles = useMultiStyleConfig("TextInput", { variant: textInputType });
109
- const finalStyles = { ...styles, ...additionalStyles };
110
- const isTextArea = type === TextInputTypes.textarea;
111
- const isHidden = type === TextInputTypes.hidden;
112
- const optReqFlag = isRequired ? "Required" : "Optional";
113
- const finalInvalidText = invalidText
114
- ? invalidText
115
- : "There is an error related to this field.";
116
- let footnote: HelperErrorTextType = isInvalid
117
- ? finalInvalidText
118
- : helperText;
119
- let fieldOutput;
120
- let options;
83
+ export const TextInput = chakra(
84
+ React.forwardRef<TextInputRefType, InputProps>(
85
+ (props, ref: React.Ref<TextInputRefType>) => {
86
+ const {
87
+ additionalStyles = {},
88
+ attributes = {},
89
+ className,
90
+ defaultValue,
91
+ helperText,
92
+ id,
93
+ invalidText,
94
+ isDisabled = false,
95
+ isInvalid = false,
96
+ isRequired = false,
97
+ labelText,
98
+ name,
99
+ onChange,
100
+ placeholder,
101
+ showHelperInvalidText = true,
102
+ showLabel = true,
103
+ showRequiredLabel = true,
104
+ step = 1,
105
+ textInputType = TextInputVariants.Default,
106
+ type = TextInputTypes.text,
107
+ value,
108
+ ...rest
109
+ } = props;
110
+ const styles = useMultiStyleConfig("TextInput", {
111
+ variant: textInputType,
112
+ });
113
+ const finalStyles = { ...styles, ...additionalStyles };
114
+ const isTextArea = type === TextInputTypes.textarea;
115
+ const isHidden = type === TextInputTypes.hidden;
116
+ const finalInvalidText = invalidText
117
+ ? invalidText
118
+ : "There is an error related to this field.";
119
+ let footnote: HelperErrorTextType = isInvalid
120
+ ? finalInvalidText
121
+ : helperText;
122
+ let fieldOutput;
123
+ let options;
121
124
 
122
- if (!showLabel) {
123
- attributes["aria-label"] =
124
- labelText && footnote ? `${labelText} - ${footnote}` : labelText;
125
- } else if (helperText) {
126
- attributes["aria-describedby"] = `${id}-helperText`;
127
- }
125
+ if (!id) {
126
+ console.warn(
127
+ "NYPL Reservoir TextInput: This component's required `id` prop was not passed."
128
+ );
129
+ }
128
130
 
129
- if (
130
- type === TextInputTypes.tel ||
131
- type === TextInputTypes.url ||
132
- type === TextInputTypes.email
133
- ) {
134
- const example = TextInputFormats[type];
135
- footnote = (
136
- <>
137
- Ex: {example}
138
- <br />
139
- {footnote}
140
- </>
141
- );
142
- }
131
+ if (!showLabel) {
132
+ attributes["aria-label"] =
133
+ labelText && footnote ? `${labelText} - ${footnote}` : labelText;
134
+ } else if (helperText) {
135
+ attributes["aria-describedby"] = `${id}-helperText`;
136
+ }
143
137
 
144
- // When the type is "hidden", the input element needs fewer attributes.
145
- options = isHidden
146
- ? { id, "aria-hidden": isHidden, name, onChange, ref }
147
- : {
148
- "aria-required": isRequired,
149
- defaultValue,
150
- id,
151
- isDisabled,
152
- isRequired,
153
- isInvalid,
154
- placeholder,
155
- name,
156
- onChange,
157
- ref,
158
- // The `step` attribute is useful for the number type.
159
- step: type === TextInputTypes.number ? step : null,
160
- ...attributes,
161
- };
162
- // For `input` and `textarea`, all attributes are the same but `input`
163
- // also needs `type` and `value` to render correctly.
164
- if (!isTextArea) {
165
- options = { type, value, ...options } as any;
166
- fieldOutput = <ChakraInput {...options} __css={finalStyles.input} />;
167
- } else {
168
- fieldOutput = (
169
- <ChakraTextarea {...options} __css={finalStyles.textarea}>
170
- {value}
171
- </ChakraTextarea>
172
- );
173
- }
138
+ if (
139
+ type === TextInputTypes.tel ||
140
+ type === TextInputTypes.url ||
141
+ type === TextInputTypes.email
142
+ ) {
143
+ const example = TextInputFormats[type];
144
+ footnote = (
145
+ <>
146
+ Ex: {example}
147
+ <br />
148
+ {footnote}
149
+ </>
150
+ );
151
+ }
152
+
153
+ // When the type is "hidden", the input element needs fewer attributes.
154
+ options = isHidden
155
+ ? { id, "aria-hidden": isHidden, name, onChange, ref }
156
+ : {
157
+ "aria-required": isRequired,
158
+ defaultValue,
159
+ id,
160
+ isDisabled,
161
+ isRequired,
162
+ isInvalid,
163
+ placeholder,
164
+ name,
165
+ onChange,
166
+ ref,
167
+ // The `step` attribute is useful for the number type.
168
+ step: type === TextInputTypes.number ? step : null,
169
+ ...attributes,
170
+ };
171
+ // For `input` and `textarea`, all attributes are the same but `input`
172
+ // also needs `type` and `value` to render correctly.
173
+ if (!isTextArea) {
174
+ options = { type, value, ...options } as any;
175
+ fieldOutput = <ChakraInput {...options} __css={finalStyles.input} />;
176
+ } else {
177
+ fieldOutput = (
178
+ <ChakraTextarea {...options} __css={finalStyles.textarea}>
179
+ {value}
180
+ </ChakraTextarea>
181
+ );
182
+ }
174
183
 
175
- return (
176
- <Box __css={finalStyles} className={className}>
177
- {labelText && showLabel && !isHidden && (
178
- <Label
179
- htmlFor={id}
180
- optReqFlag={showOptReqLabel && optReqFlag}
181
- id={`${id}-label`}
182
- >
183
- {labelText}
184
- </Label>
185
- )}
186
- {fieldOutput}
187
- {footnote && showHelperInvalidText && !isHidden && (
188
- <Box __css={finalStyles.helper} aria-disabled={isDisabled}>
184
+ return (
185
+ <Box __css={finalStyles} className={className} {...rest}>
186
+ {labelText && showLabel && !isHidden && (
187
+ <Label
188
+ htmlFor={id}
189
+ id={`${id}-label`}
190
+ isRequired={showRequiredLabel && isRequired}
191
+ >
192
+ {labelText}
193
+ </Label>
194
+ )}
195
+ {fieldOutput}
196
+ {footnote && showHelperInvalidText && !isHidden && (
189
197
  <HelperErrorText
190
198
  id={`${id}-helperText`}
191
199
  isInvalid={isInvalid}
192
200
  text={footnote}
193
201
  />
194
- </Box>
195
- )}
196
- </Box>
197
- );
198
- }
202
+ )}
203
+ </Box>
204
+ );
205
+ }
206
+ )
199
207
  );
200
208
 
201
209
  export default TextInput;