@nypl/design-system-react-components 0.25.12 → 0.25.13

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 (194) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/dist/components/Accordion/Accordion.d.ts +5 -3
  3. package/dist/components/Accordion/AccordionTypes.d.ts +5 -0
  4. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +3 -3
  5. package/dist/components/Breadcrumbs/BreadcrumbsTypes.d.ts +1 -1
  6. package/dist/components/Card/Card.d.ts +11 -20
  7. package/dist/components/Checkbox/Checkbox.d.ts +1 -1
  8. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +4 -2
  9. package/dist/components/Heading/Heading.d.ts +4 -4
  10. package/dist/components/Heading/HeadingTypes.d.ts +1 -1
  11. package/dist/components/Hero/Hero.d.ts +7 -4
  12. package/dist/components/Icons/IconTypes.d.ts +1 -0
  13. package/dist/components/Image/Image.d.ts +25 -7
  14. package/dist/components/Image/ImageTypes.d.ts +4 -4
  15. package/dist/components/Logo/LogoTypes.d.ts +2 -2
  16. package/dist/components/Notification/Notification.d.ts +4 -4
  17. package/dist/components/Radio/Radio.d.ts +1 -1
  18. package/dist/components/RadioGroup/RadioGroup.d.ts +4 -2
  19. package/dist/components/Select/Select.d.ts +2 -2
  20. package/dist/components/SkeletonLoader/SkeletonLoader.d.ts +4 -3
  21. package/dist/components/SkeletonLoader/SkeletonLoaderTypes.d.ts +0 -4
  22. package/dist/components/StructuredContent/StructuredContent.d.ts +9 -22
  23. package/dist/components/Tabs/Tabs.d.ts +3 -3
  24. package/dist/components/Template/Template.d.ts +13 -5
  25. package/dist/components/Text/Text.d.ts +3 -3
  26. package/dist/components/Text/TextTypes.d.ts +1 -1
  27. package/dist/components/TextInput/TextInput.d.ts +2 -2
  28. package/dist/components/Toggle/Toggle.d.ts +6 -7
  29. package/dist/components/Toggle/{ToggleSizes.d.ts → ToggleTypes.d.ts} +1 -1
  30. package/dist/design-system-react-components.cjs.development.js +505 -422
  31. package/dist/design-system-react-components.cjs.development.js.map +1 -1
  32. package/dist/design-system-react-components.cjs.production.min.js +1 -1
  33. package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
  34. package/dist/design-system-react-components.esm.js +514 -435
  35. package/dist/design-system-react-components.esm.js.map +1 -1
  36. package/dist/helpers/enums.d.ts +4 -0
  37. package/dist/index.d.ts +7 -8
  38. package/dist/theme/components/accordion.d.ts +7 -12
  39. package/dist/theme/components/breadcrumb.d.ts +3 -0
  40. package/dist/theme/components/card.d.ts +4 -4
  41. package/dist/theme/components/checkbox.d.ts +1 -0
  42. package/dist/theme/components/checkboxGroup.d.ts +3 -1
  43. package/dist/theme/components/global.d.ts +2 -1
  44. package/dist/theme/components/hero.d.ts +1 -1
  45. package/dist/theme/components/image.d.ts +1 -1
  46. package/dist/theme/components/notification.d.ts +4 -4
  47. package/dist/theme/components/pagination.d.ts +2 -5
  48. package/dist/theme/components/radio.d.ts +1 -0
  49. package/dist/theme/components/radioGroup.d.ts +3 -1
  50. package/dist/theme/components/select.d.ts +3 -0
  51. package/dist/theme/components/toggle.d.ts +13 -1
  52. package/package.json +1 -1
  53. package/src/components/AccessibilityGuide/SkipNavigation.stories.mdx +34 -0
  54. package/src/components/Accordion/Accordion.stories.mdx +150 -66
  55. package/src/components/Accordion/Accordion.test.tsx +44 -17
  56. package/src/components/Accordion/Accordion.tsx +50 -20
  57. package/src/components/Accordion/AccordionTypes.tsx +5 -0
  58. package/src/components/Accordion/__snapshots__/Accordion.test.tsx.snap +244 -2
  59. package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +17 -15
  60. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +6 -6
  61. package/src/components/Breadcrumbs/Breadcrumbs.tsx +6 -6
  62. package/src/components/Breadcrumbs/BreadcrumbsTypes.tsx +1 -1
  63. package/src/components/Card/Card.stories.mdx +236 -165
  64. package/src/components/Card/Card.test.tsx +36 -18
  65. package/src/components/Card/Card.tsx +84 -59
  66. package/src/components/Card/__snapshots__/Card.test.tsx.snap +25 -65
  67. package/src/components/Chakra/Center.stories.mdx +2 -2
  68. package/src/components/Checkbox/Checkbox.stories.mdx +13 -1
  69. package/src/components/Checkbox/Checkbox.test.tsx +58 -2
  70. package/src/components/Checkbox/Checkbox.tsx +6 -1
  71. package/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +76 -0
  72. package/src/components/CheckboxGroup/CheckboxGroup.stories.mdx +73 -9
  73. package/src/components/CheckboxGroup/CheckboxGroup.test.tsx +79 -9
  74. package/src/components/CheckboxGroup/CheckboxGroup.tsx +10 -7
  75. package/src/components/CheckboxGroup/__snapshots__/CheckboxGroup.test.tsx.snap +169 -0
  76. package/src/components/ComponentWrapper/ComponentWrapper.tsx +1 -1
  77. package/src/components/DatePicker/DatePicker.test.tsx +5 -2
  78. package/src/components/DatePicker/DatePicker.tsx +5 -2
  79. package/src/components/Form/Form.stories.mdx +47 -9
  80. package/src/components/Form/Form.test.tsx +1 -1
  81. package/src/components/Form/Form.tsx +3 -1
  82. package/src/components/Grid/SimpleGrid.stories.mdx +53 -35
  83. package/src/components/Grid/SimpleGrid.test.tsx +15 -9
  84. package/src/components/Heading/Heading.stories.mdx +21 -23
  85. package/src/components/Heading/Heading.test.tsx +7 -7
  86. package/src/components/Heading/Heading.tsx +10 -14
  87. package/src/components/Heading/HeadingTypes.tsx +1 -1
  88. package/src/components/Heading/__snapshots__/Heading.test.tsx.snap +1 -1
  89. package/src/components/Hero/Hero.stories.mdx +27 -27
  90. package/src/components/Hero/Hero.test.tsx +113 -58
  91. package/src/components/Hero/Hero.tsx +43 -20
  92. package/src/components/HorizontalRule/HorizontalRule.test.tsx +6 -4
  93. package/src/components/HorizontalRule/HorizontalRule.tsx +3 -2
  94. package/src/components/Icons/Icon.stories.mdx +50 -18
  95. package/src/components/Icons/Icon.test.tsx +13 -2
  96. package/src/components/Icons/Icon.tsx +11 -6
  97. package/src/components/Icons/IconTypes.tsx +1 -0
  98. package/src/components/Image/Image.stories.mdx +133 -68
  99. package/src/components/Image/Image.test.tsx +32 -48
  100. package/src/components/Image/Image.tsx +46 -26
  101. package/src/components/Image/ImageTypes.ts +4 -4
  102. package/src/components/Image/__snapshots__/Image.test.tsx.snap +60 -13
  103. package/src/components/Link/Link.tsx +8 -1
  104. package/src/components/List/List.stories.mdx +1 -1
  105. package/src/components/List/List.test.tsx +7 -4
  106. package/src/components/List/List.tsx +7 -4
  107. package/src/components/Logo/Logo.stories.mdx +13 -13
  108. package/src/components/Logo/Logo.test.tsx +12 -2
  109. package/src/components/Logo/Logo.tsx +10 -5
  110. package/src/components/Logo/LogoTypes.tsx +1 -1
  111. package/src/components/Notification/Notification.stories.mdx +5 -5
  112. package/src/components/Notification/Notification.tsx +10 -10
  113. package/src/components/Pagination/Pagination.stories.mdx +4 -3
  114. package/src/components/Pagination/Pagination.test.tsx +30 -2
  115. package/src/components/Pagination/Pagination.tsx +6 -3
  116. package/src/components/ProgressIndicator/ProgressIndicator.stories.mdx +1 -1
  117. package/src/components/ProgressIndicator/ProgressIndicator.test.tsx +6 -2
  118. package/src/components/ProgressIndicator/ProgressIndicator.tsx +3 -1
  119. package/src/components/Radio/Radio.stories.mdx +13 -1
  120. package/src/components/Radio/Radio.test.tsx +56 -2
  121. package/src/components/Radio/Radio.tsx +6 -1
  122. package/src/components/Radio/__snapshots__/Radio.test.tsx.snap +61 -0
  123. package/src/components/RadioGroup/RadioGroup.stories.mdx +73 -9
  124. package/src/components/RadioGroup/RadioGroup.test.tsx +72 -7
  125. package/src/components/RadioGroup/RadioGroup.tsx +10 -7
  126. package/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap +140 -0
  127. package/src/components/SearchBar/SearchBar.stories.mdx +1 -1
  128. package/src/components/SearchBar/SearchBar.tsx +3 -3
  129. package/src/components/Select/Select.stories.mdx +26 -16
  130. package/src/components/Select/Select.test.tsx +1 -36
  131. package/src/components/Select/Select.tsx +4 -16
  132. package/src/components/SkeletonLoader/SkeletonLoader.stories.mdx +12 -14
  133. package/src/components/SkeletonLoader/SkeletonLoader.test.tsx +6 -8
  134. package/src/components/SkeletonLoader/SkeletonLoader.tsx +5 -7
  135. package/src/components/SkeletonLoader/SkeletonLoaderTypes.tsx +0 -5
  136. package/src/components/Slider/Slider.stories.mdx +41 -8
  137. package/src/components/Slider/Slider.tsx +4 -4
  138. package/src/components/StatusBadge/StatusBadge.test.tsx +3 -1
  139. package/src/components/StatusBadge/StatusBadge.tsx +1 -1
  140. package/src/components/StructuredContent/StructuredContent.stories.mdx +103 -54
  141. package/src/components/StructuredContent/StructuredContent.test.tsx +129 -102
  142. package/src/components/StructuredContent/StructuredContent.tsx +43 -53
  143. package/src/components/StyleGuide/ColorCard.tsx +3 -3
  144. package/src/components/StyleGuide/Typography.stories.mdx +17 -12
  145. package/src/components/Table/Table.test.tsx +1 -1
  146. package/src/components/Table/Table.tsx +3 -1
  147. package/src/components/Tabs/Tabs.stories.mdx +8 -8
  148. package/src/components/Tabs/Tabs.test.tsx +13 -11
  149. package/src/components/Tabs/Tabs.tsx +18 -15
  150. package/src/components/Template/Template.stories.mdx +62 -25
  151. package/src/components/Template/Template.test.tsx +35 -5
  152. package/src/components/Template/Template.tsx +26 -13
  153. package/src/components/Template/__snapshots__/Template.test.tsx.snap +4 -2
  154. package/src/components/Text/Text.stories.mdx +13 -15
  155. package/src/components/Text/Text.test.tsx +6 -15
  156. package/src/components/Text/Text.tsx +7 -12
  157. package/src/components/Text/TextTypes.tsx +1 -1
  158. package/src/components/TextInput/TextInput.stories.mdx +9 -9
  159. package/src/components/TextInput/TextInput.test.tsx +28 -27
  160. package/src/components/TextInput/TextInput.tsx +4 -4
  161. package/src/components/Toggle/Toggle.stories.mdx +12 -22
  162. package/src/components/Toggle/Toggle.test.tsx +15 -2
  163. package/src/components/Toggle/Toggle.tsx +8 -9
  164. package/src/components/Toggle/{ToggleSizes.tsx → ToggleTypes.tsx} +1 -1
  165. package/src/components/Toggle/__snapshots__/Toggle.test.tsx.snap +64 -0
  166. package/src/components/VideoPlayer/VideoPlayer.test.tsx +18 -6
  167. package/src/components/VideoPlayer/VideoPlayer.tsx +14 -7
  168. package/src/docs/{Intro.stories.mdx → Welcome.stories.mdx} +5 -9
  169. package/src/{components/Card/CardTypes.tsx → helpers/enums.ts} +2 -2
  170. package/src/hooks/tests/useNYPLTheme.test.tsx +1 -1
  171. package/src/hooks/useCarouselStyles.stories.mdx +10 -0
  172. package/src/hooks/useNYPLTheme.ts +1 -1
  173. package/src/index.ts +7 -14
  174. package/src/theme/components/accordion.ts +7 -12
  175. package/src/theme/components/breadcrumb.ts +3 -0
  176. package/src/theme/components/card.ts +29 -20
  177. package/src/theme/components/checkboxGroup.ts +3 -1
  178. package/src/theme/components/global.ts +4 -3
  179. package/src/theme/components/hero.ts +1 -1
  180. package/src/theme/components/icon.ts +5 -2
  181. package/src/theme/components/image.ts +1 -1
  182. package/src/theme/components/list.ts +1 -1
  183. package/src/theme/components/notification.ts +5 -5
  184. package/src/theme/components/pagination.ts +2 -5
  185. package/src/theme/components/progressIndicator.ts +3 -3
  186. package/src/theme/components/radioGroup.ts +3 -1
  187. package/src/theme/components/select.ts +6 -0
  188. package/src/theme/components/toggle.ts +26 -3
  189. package/src/utils/componentCategories.ts +27 -19
  190. package/dist/components/Card/CardTypes.d.ts +0 -4
  191. package/dist/components/CheckboxGroup/CheckboxGroupLayoutTypes.d.ts +0 -4
  192. package/dist/components/RadioGroup/RadioGroupLayoutTypes.d.ts +0 -4
  193. package/src/components/CheckboxGroup/CheckboxGroupLayoutTypes.tsx +0 -4
  194. package/src/components/RadioGroup/RadioGroupLayoutTypes.tsx +0 -4
@@ -13,12 +13,12 @@ import generateUUID from "../../helpers/generateUUID";
13
13
  interface BaseProps {
14
14
  /** Optional prop to control text alignment in `NotificationContent` */
15
15
  alignText?: boolean;
16
- /** Optional prop to control horizontal alignment of the `Notification` content */
17
- centered?: boolean;
18
16
  /** Optional custom `Icon` that will override the default `Icon`. */
19
17
  icon?: JSX.Element;
20
18
  /** ID that other components can cross reference for accessibility purposes. */
21
19
  id?: string;
20
+ /** Optional prop to control horizontal alignment of the `Notification` content */
21
+ isCentered?: boolean;
22
22
  /** Optional prop to control the coloring of the `Notification` text and the
23
23
  * visibility of an applicable icon. */
24
24
  notificationType?: NotificationTypes;
@@ -27,7 +27,7 @@ interface BaseProps {
27
27
  // Used for `NotificationHeading` and `Notification`
28
28
  type BasePropsWithoutAlignText = Omit<BaseProps, "alignText">;
29
29
  // Used for `NotificationContent`
30
- type BasePropsWithoutCentered = Omit<BaseProps, "centered">;
30
+ type BasePropsWithoutIsCentered = Omit<BaseProps, "isCentered">;
31
31
 
32
32
  export interface NotificationProps extends BasePropsWithoutAlignText {
33
33
  /** Label used to describe the `Notification`'s aside HTML element. */
@@ -55,10 +55,10 @@ export interface NotificationProps extends BasePropsWithoutAlignText {
55
55
  export function NotificationHeading(
56
56
  props: React.PropsWithChildren<BasePropsWithoutAlignText>
57
57
  ) {
58
- const { centered, children, icon, id, notificationType } = props;
58
+ const { children, icon, id, isCentered, notificationType } = props;
59
59
  const styles = useMultiStyleConfig("NotificationHeading", {
60
- centered,
61
60
  icon,
61
+ isCentered,
62
62
  notificationType,
63
63
  });
64
64
  return (
@@ -79,7 +79,7 @@ export function NotificationHeading(
79
79
  * NotificationContent child-component.
80
80
  */
81
81
  export function NotificationContent(
82
- props: React.PropsWithChildren<BasePropsWithoutCentered>
82
+ props: React.PropsWithChildren<BasePropsWithoutIsCentered>
83
83
  ) {
84
84
  const { alignText, children, icon, notificationType } = props;
85
85
  const styles = useMultiStyleConfig("NotificationContent", {
@@ -102,11 +102,11 @@ export function NotificationContent(
102
102
  export default function Notification(props: NotificationProps) {
103
103
  const {
104
104
  ariaLabel,
105
- centered = false,
106
105
  className,
107
106
  dismissible = false,
108
107
  icon,
109
108
  id = generateUUID(),
109
+ isCentered = false,
110
110
  noMargin = false,
111
111
  notificationContent,
112
112
  notificationHeading,
@@ -116,8 +116,8 @@ export default function Notification(props: NotificationProps) {
116
116
  const [isOpen, setIsOpen] = useState(true);
117
117
  const handleClose = () => setIsOpen(false);
118
118
  const styles = useMultiStyleConfig("Notification", {
119
- centered,
120
119
  dismissible,
120
+ isCentered,
121
121
  noMargin,
122
122
  notificationType,
123
123
  });
@@ -182,16 +182,16 @@ export default function Notification(props: NotificationProps) {
182
182
  const iconElem = iconElement();
183
183
  const childHeading = notificationHeading && (
184
184
  <NotificationHeading
185
- centered={centered}
186
185
  icon={iconElem}
187
186
  id={id}
187
+ isCentered={isCentered}
188
188
  notificationType={notificationType}
189
189
  >
190
190
  {notificationHeading}
191
191
  </NotificationHeading>
192
192
  );
193
193
  // Specific alignment styles for the content.
194
- const alignText = childHeading && showIcon && (!!icon || !centered);
194
+ const alignText = childHeading && showIcon && (!!icon || !isCentered);
195
195
  const childContent = (
196
196
  <NotificationContent
197
197
  alignText={alignText}
@@ -1,4 +1,5 @@
1
1
  import { useState } from "react";
2
+ import { VStack } from "@chakra-ui/react";
2
3
  import {
3
4
  ArgsTable,
4
5
  Canvas,
@@ -43,7 +44,7 @@ export const hrefProps = getStorybookHrefProps(10);
43
44
  | Component Version | DS Version |
44
45
  | ----------------- | ---------- |
45
46
  | Added | `0.0.10` |
46
- | Latest | `0.25.12` |
47
+ | Latest | `0.25.13` |
47
48
 
48
49
  <Description of={Pagination} />
49
50
 
@@ -144,7 +145,7 @@ export function CurrentPagePaginationExample() {
144
145
  const handleClick = () => setPage(1);
145
146
  const handleSelection = (selectedPage) => setPage(selectedPage);
146
147
  return (
147
- <>
148
+ <VStack align="start" spacing={6}>
148
149
  <Pagination
149
150
  pageCount={10}
150
151
  currentPage={page}
@@ -153,7 +154,7 @@ export function CurrentPagePaginationExample() {
153
154
  <Button type="button" buttonType="primary" onClick={handleClick}>
154
155
  Go to Page 1
155
156
  </Button>
156
- </>
157
+ </VStack>
157
158
  );
158
159
  }
159
160
 
@@ -205,6 +205,31 @@ describe("Pagination", () => {
205
205
  });
206
206
 
207
207
  describe("Behavior", () => {
208
+ it("navigates to the appropriate page when the Next or Previous links are clicked", () => {
209
+ const onPageChange = (page: number) => (currentPage = page);
210
+ let currentPage = 3;
211
+
212
+ render(
213
+ <Pagination
214
+ pageCount={5}
215
+ initialPage={currentPage}
216
+ onPageChange={onPageChange}
217
+ />
218
+ );
219
+
220
+ let links = screen.getAllByRole("link");
221
+
222
+ // Previous link
223
+ userEvent.click(links[0]);
224
+ expect(currentPage).toEqual(2);
225
+
226
+ links = screen.getAllByRole("link");
227
+
228
+ // Next link
229
+ userEvent.click(links[links.length - 1]);
230
+ expect(currentPage).toEqual(3);
231
+ });
232
+
208
233
  it("updates the links href value when getPageHref is used", () => {
209
234
  const getPageHref = (page: number) => `?page=${page}`;
210
235
  render(
@@ -348,7 +373,9 @@ describe("Pagination", () => {
348
373
  />
349
374
  );
350
375
  expect(warn).toHaveBeenCalledWith(
351
- "NYPL Reservoir Pagination: Props for both `getPageHref` and `onPageChange` are passed. Will default to using `getPageHref`."
376
+ "NYPL Reservoir Pagination: Props for both `getPageHref` and " +
377
+ "`onPageChange` are passed. The component will default to using " +
378
+ "`getPageHref`."
352
379
  );
353
380
  });
354
381
 
@@ -359,7 +386,8 @@ describe("Pagination", () => {
359
386
  <Pagination pageCount={10} currentPage={2} getPageHref={getPageHref} />
360
387
  );
361
388
  expect(warn).toHaveBeenCalledWith(
362
- "NYPL Reservoir Pagination: The `currentPage` prop does not work with the `getPageHref` prop. Use `currentPage` with `onPageChange` instead."
389
+ "NYPL Reservoir Pagination: The `currentPage` prop does not work with " +
390
+ "the `getPageHref` prop. Use `currentPage` with `onPageChange` instead."
363
391
  );
364
392
  });
365
393
  });
@@ -64,13 +64,16 @@ const Pagination: React.FC<PaginationProps> = (props: PaginationProps) => {
64
64
  }
65
65
  if (getPageHref && onPageChange) {
66
66
  console.warn(
67
- "NYPL Reservoir Pagination: Props for both `getPageHref` and `onPageChange` are passed. Will default to using `getPageHref`."
67
+ "NYPL Reservoir Pagination: Props for both `getPageHref` and " +
68
+ "`onPageChange` are passed. The component will default to using " +
69
+ "`getPageHref`."
68
70
  );
69
71
  }
70
72
 
71
73
  if (getPageHref && currentPage) {
72
74
  console.warn(
73
- "NYPL Reservoir Pagination: The `currentPage` prop does not work with the `getPageHref` prop. Use `currentPage` with `onPageChange` instead."
75
+ "NYPL Reservoir Pagination: The `currentPage` prop does not work with " +
76
+ "the `getPageHref` prop. Use `currentPage` with `onPageChange` instead."
74
77
  );
75
78
  }
76
79
 
@@ -96,7 +99,7 @@ const Pagination: React.FC<PaginationProps> = (props: PaginationProps) => {
96
99
  // Select the next page.
97
100
  const nextPage = (e: Event) => {
98
101
  if (selectedPage < pageCount) {
99
- handlePageClick(e, previousPageNumber);
102
+ handlePageClick(e, nextPageNumber);
100
103
  }
101
104
  };
102
105
  /**
@@ -71,7 +71,7 @@ export const typesEnumValues = getStorybookEnumValues(
71
71
  | Component Version | DS Version |
72
72
  | ----------------- | ---------- |
73
73
  | Added | `0.25.4` |
74
- | Latest | `0.25.8` |
74
+ | Latest | `0.25.12` |
75
75
 
76
76
  <Description of={ProgressIndicator} />
77
77
 
@@ -120,7 +120,9 @@ describe("ProgressIndicator", () => {
120
120
  render(<ProgressIndicator labelText="Linear" value={-20} />);
121
121
 
122
122
  expect(warn).toHaveBeenCalledWith(
123
- "ProgressIndicator: pass in a `value` between 0 and 100. Defaulting to 0."
123
+ "NYPL Reservoir ProgressIndicator: An invalid value was passed for the" +
124
+ " `value` prop, so 0 will be used. A valid value should be a number" +
125
+ " between 0 and 100."
124
126
  );
125
127
  });
126
128
 
@@ -129,7 +131,9 @@ describe("ProgressIndicator", () => {
129
131
  render(<ProgressIndicator labelText="Linear" value={150} />);
130
132
 
131
133
  expect(warn).toHaveBeenCalledWith(
132
- "ProgressIndicator: pass in a `value` between 0 and 100. Defaulting to 0."
134
+ "NYPL Reservoir ProgressIndicator: An invalid value was passed for the" +
135
+ " `value` prop, so 0 will be used. A valid value should be a number" +
136
+ " between 0 and 100."
133
137
  );
134
138
  });
135
139
 
@@ -60,7 +60,9 @@ const ProgressIndicator: React.FC<ProgressIndicatorProps> = (
60
60
  let finalValue = value;
61
61
  if (finalValue < 0 || finalValue > 100) {
62
62
  console.warn(
63
- "ProgressIndicator: pass in a `value` between 0 and 100. Defaulting to 0."
63
+ "NYPL Reservoir ProgressIndicator: An invalid value was passed for the" +
64
+ " `value` prop, so 0 will be used. A valid value should be a number" +
65
+ " between 0 and 100."
64
66
  );
65
67
  finalValue = 0;
66
68
  }
@@ -53,7 +53,7 @@ import DSProvider from "../../theme/provider";
53
53
  | Component Version | DS Version |
54
54
  | ----------------- | ---------- |
55
55
  | Added | `0.22.0` |
56
- | Latest | `0.25.12` |
56
+ | Latest | `0.25.13` |
57
57
 
58
58
  <Description of={Radio} />
59
59
 
@@ -150,3 +150,15 @@ component will handle all the states and data management.
150
150
  />
151
151
  </DSProvider>
152
152
  </Canvas>
153
+
154
+ ## With JSX Element Label
155
+
156
+ This is useful when you want to add dynamic content to the label or add
157
+ a layout to the label. View the `RadioGroup` documentation for this
158
+ usage.
159
+
160
+ <Canvas>
161
+ <DSProvider>
162
+ <Radio labelText={<span>Arts</span>} name="jsxElementLabel" />
163
+ </DSProvider>
164
+ </Canvas>
@@ -1,16 +1,33 @@
1
+ import { Flex, Spacer } from "@chakra-ui/react";
1
2
  import * as React from "react";
2
3
  import { render, screen } from "@testing-library/react";
3
4
  import { axe } from "jest-axe";
4
5
  import renderer from "react-test-renderer";
5
6
 
6
- import * as generateUUID from "../../helpers/generateUUID";
7
7
  import Radio from "./Radio";
8
+ import * as generateUUID from "../../helpers/generateUUID";
8
9
 
9
10
  describe("Radio Accessibility", () => {
10
- it("passes axe accessibility", async () => {
11
+ it("passes axe accessibility test with string label", async () => {
11
12
  const { container } = render(<Radio id="inputID" labelText="Test Label" />);
12
13
  expect(await axe(container)).toHaveNoViolations();
13
14
  });
15
+
16
+ it("passes axe accessibility test with jsx label", async () => {
17
+ const { container } = render(
18
+ <Radio
19
+ id="jsxLabel"
20
+ labelText={
21
+ <Flex>
22
+ <span>Arts</span>
23
+ <Spacer />
24
+ <span>4</span>
25
+ </Flex>
26
+ }
27
+ />
28
+ );
29
+ expect(await axe(container)).toHaveNoViolations();
30
+ });
14
31
  });
15
32
 
16
33
  describe("Radio Button", () => {
@@ -147,6 +164,27 @@ describe("Radio Button", () => {
147
164
  expect(screen.queryByText("There is an error!")).not.toBeInTheDocument();
148
165
  });
149
166
 
167
+ it("logs a warning if `labelText` is not a string and `showLabel` is false", () => {
168
+ const warn = jest.spyOn(console, "warn");
169
+ render(
170
+ <Radio
171
+ value="arts"
172
+ labelText={
173
+ <Flex>
174
+ <span>Arts</span>
175
+ <Spacer />
176
+ <span>4</span>
177
+ </Flex>
178
+ }
179
+ showLabel={false}
180
+ />
181
+ );
182
+
183
+ expect(warn).toHaveBeenCalledWith(
184
+ "NYPL Reservoir Radio: `labelText` must be a string when `showLabel` is false."
185
+ );
186
+ });
187
+
150
188
  it("renders the UI snapshot correctly", () => {
151
189
  const primary = renderer
152
190
  .create(<Radio id="inputID" labelText="Test Label" />)
@@ -163,11 +201,27 @@ describe("Radio Button", () => {
163
201
  const isDisabled = renderer
164
202
  .create(<Radio id="radio-disabled" labelText="Test Label" isDisabled />)
165
203
  .toJSON();
204
+ const withJSXLabel = renderer
205
+ .create(
206
+ <Radio
207
+ id="jsxLabel"
208
+ labelText={
209
+ <Flex>
210
+ <span>Arts</span>
211
+ <Spacer />
212
+ <span>4</span>
213
+ </Flex>
214
+ }
215
+ value="arts"
216
+ />
217
+ )
218
+ .toJSON();
166
219
 
167
220
  expect(primary).toMatchSnapshot();
168
221
  expect(isChecked).toMatchSnapshot();
169
222
  expect(isRequired).toMatchSnapshot();
170
223
  expect(isInvalid).toMatchSnapshot();
171
224
  expect(isDisabled).toMatchSnapshot();
225
+ expect(withJSXLabel).toMatchSnapshot();
172
226
  });
173
227
  });
@@ -38,7 +38,7 @@ export interface RadioProps {
38
38
  /** The radio button's label. This will serve as the text content for the
39
39
  * `<label>` element if `showlabel` is true, or an "aria-label" if `showLabel`
40
40
  * is false. */
41
- labelText: string;
41
+ labelText: string | JSX.Element;
42
42
  /** Used to reference the input element in forms. */
43
43
  name?: string;
44
44
  /** Should be passed along with `isChecked` for controlled components. */
@@ -74,6 +74,11 @@ const Radio = React.forwardRef<HTMLInputElement, RadioProps>((props, ref?) => {
74
74
  const attributes = {};
75
75
 
76
76
  if (!showLabel) {
77
+ if (typeof labelText !== "string") {
78
+ console.warn(
79
+ "NYPL Reservoir Radio: `labelText` must be a string when `showLabel` is false."
80
+ );
81
+ }
77
82
  attributes["aria-label"] =
78
83
  labelText && footnote ? `${labelText} - ${footnote}` : labelText;
79
84
  } else {
@@ -251,3 +251,64 @@ exports[`Radio Button renders the UI snapshot correctly 5`] = `
251
251
  </span>
252
252
  </label>
253
253
  `;
254
+
255
+ exports[`Radio Button renders the UI snapshot correctly 6`] = `
256
+ <label
257
+ className="chakra-radio css-13p0l12"
258
+ >
259
+ <input
260
+ checked={false}
261
+ className="chakra-radio__input"
262
+ disabled={false}
263
+ id="jsxLabel"
264
+ onBlur={[Function]}
265
+ onChange={[Function]}
266
+ onFocus={[Function]}
267
+ onKeyDown={[Function]}
268
+ onKeyUp={[Function]}
269
+ required={false}
270
+ style={
271
+ Object {
272
+ "border": "0px",
273
+ "clip": "rect(0px, 0px, 0px, 0px)",
274
+ "height": "1px",
275
+ "margin": "-1px",
276
+ "overflow": "hidden",
277
+ "padding": "0px",
278
+ "position": "absolute",
279
+ "whiteSpace": "nowrap",
280
+ "width": "1px",
281
+ }
282
+ }
283
+ type="radio"
284
+ value="arts"
285
+ />
286
+ <span
287
+ aria-hidden={true}
288
+ className="css-ssalds"
289
+ onMouseDown={[Function]}
290
+ onMouseEnter={[Function]}
291
+ onMouseLeave={[Function]}
292
+ onMouseUp={[Function]}
293
+ />
294
+ <span
295
+ className="chakra-radio__label css-1y8kf23"
296
+ onMouseDown={[Function]}
297
+ onTouchStart={[Function]}
298
+ >
299
+ <div
300
+ className="css-k008qs"
301
+ >
302
+ <span>
303
+ Arts
304
+ </span>
305
+ <div
306
+ className="css-17xejub"
307
+ />
308
+ <span>
309
+ 4
310
+ </span>
311
+ </div>
312
+ </span>
313
+ </label>
314
+ `;
@@ -1,3 +1,4 @@
1
+ import { Flex, Spacer } from "@chakra-ui/react";
1
2
  import {
2
3
  ArgsTable,
3
4
  Canvas,
@@ -9,15 +10,12 @@ import { withDesign } from "storybook-addon-designs";
9
10
 
10
11
  import Radio from "../Radio/Radio";
11
12
  import RadioGroup, { onChangeDefault } from "./RadioGroup";
12
- import { RadioGroupLayoutTypes } from "./RadioGroupLayoutTypes";
13
+ import { LayoutTypes } from "../../helpers/enums";
13
14
  import { getCategory } from "../../utils/componentCategories";
14
15
  import DSProvider from "../../theme/provider";
15
16
  import { getStorybookEnumValues } from "../../utils/utils";
16
17
 
17
- export const enumValues = getStorybookEnumValues(
18
- RadioGroupLayoutTypes,
19
- "RadioGroupLayoutTypes"
20
- );
18
+ export const enumValues = getStorybookEnumValues(LayoutTypes, "LayoutTypes");
21
19
 
22
20
  <Meta
23
21
  title={getCategory("RadioGroup")}
@@ -37,6 +35,9 @@ export const enumValues = getStorybookEnumValues(
37
35
  isDisabled: {
38
36
  table: { defaultValue: { summary: false } },
39
37
  },
38
+ isFullWidth: {
39
+ table: { defaultValue: { summary: false } },
40
+ },
40
41
  isInvalid: {
41
42
  table: { defaultValue: { summary: false } },
42
43
  },
@@ -45,7 +46,7 @@ export const enumValues = getStorybookEnumValues(
45
46
  },
46
47
  layout: {
47
48
  control: { type: "select" },
48
- table: { defaultValue: { summary: "RadioGroupLayoutTypes.Column" } },
49
+ table: { defaultValue: { summary: "LayoutTypes.Column" } },
49
50
  options: enumValues.options,
50
51
  },
51
52
  key: { table: { disable: true } },
@@ -68,7 +69,7 @@ export const enumValues = getStorybookEnumValues(
68
69
  | Component Version | DS Version |
69
70
  | ----------------- | ---------- |
70
71
  | Added | `0.25.0` |
71
- | Latest | `0.25.10` |
72
+ | Latest | `0.25.13` |
72
73
 
73
74
  <Description of={RadioGroup} />
74
75
 
@@ -82,10 +83,11 @@ export const enumValues = getStorybookEnumValues(
82
83
  id: "radioGroup-id",
83
84
  invalidText: "error!",
84
85
  isDisabled: false,
86
+ isFullWidth: false,
85
87
  isInvalid: false,
86
88
  isRequired: false,
87
89
  labelText: "Standard Radio Group",
88
- layout: "RadioGroupLayoutTypes.Column",
90
+ layout: "LayoutTypes.Column",
89
91
  name: "radio-story",
90
92
  onChange: undefined,
91
93
  optReqFlag: true,
@@ -127,7 +129,7 @@ a row.
127
129
  <RadioGroup
128
130
  labelText="Row"
129
131
  name="row-example"
130
- layout={RadioGroupLayoutTypes.Row}
132
+ layout={LayoutTypes.Row}
131
133
  optReqFlag={false}
132
134
  >
133
135
  <Radio value="2" labelText="Radio 2" />
@@ -176,6 +178,68 @@ a row.
176
178
  </DSProvider>
177
179
  </Canvas>
178
180
 
181
+ ## With JSX Element labels
182
+
183
+ React elements can be passed to the `labelText` prop of the `Radio` component.
184
+ This is useful if you need to pass information as part of the label. For example,
185
+ if a `Radio` label needs to display how many items that option has, it can be
186
+ displayed with the help of the `Flex` and `Spacer` components.
187
+
188
+ Note: the width of `RadioGroup` is _not_ set to full width by default. In
189
+ order to make this work, pass in the `isFullWidth` prop.
190
+
191
+ <Canvas>
192
+ <DSProvider>
193
+ <RadioGroup
194
+ labelText="Radio Group"
195
+ name="radio-example"
196
+ optReqFlag={false}
197
+ isFullWidth
198
+ >
199
+ <Radio
200
+ labelText={
201
+ <Flex>
202
+ <span>Arts</span>
203
+ <Spacer />
204
+ <span>4</span>
205
+ </Flex>
206
+ }
207
+ value="arts"
208
+ />
209
+ <Radio
210
+ labelText={
211
+ <Flex>
212
+ <span>English</span>
213
+ <Spacer />
214
+ <span>23</span>
215
+ </Flex>
216
+ }
217
+ value="English"
218
+ />
219
+ <Radio
220
+ labelText={
221
+ <Flex>
222
+ <span>Science</span>
223
+ <Spacer />
224
+ <span>10</span>
225
+ </Flex>
226
+ }
227
+ value="Science"
228
+ />
229
+ <Radio
230
+ labelText={
231
+ <Flex>
232
+ <span>Math</span>
233
+ <Spacer />
234
+ <span>3</span>
235
+ </Flex>
236
+ }
237
+ value="Math"
238
+ />
239
+ </RadioGroup>
240
+ </DSProvider>
241
+ </Canvas>
242
+
179
243
  ## Getting Radio Data Values
180
244
 
181
245
  ### Controlled Component using `name` and `onChange` props