@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
@@ -19,8 +19,10 @@ describe("Card Accessibility", () => {
19
19
  const { container } = render(
20
20
  <Card
21
21
  id="cardID"
22
- imageSrc="https://placeimg.com/400/200/arch"
23
- imageAlt="Alt text"
22
+ imageProps={{
23
+ alt: "Alt text",
24
+ src: "https://placeimg.com/400/200/arch",
25
+ }}
24
26
  >
25
27
  <CardHeading level={HeadingLevels.Three} id="heading1">
26
28
  The Card Heading
@@ -45,8 +47,10 @@ describe("Card Accessibility", () => {
45
47
  const { container } = render(
46
48
  <Card
47
49
  id="cardID"
48
- imageSrc="https://placeimg.com/400/200/arch"
49
- imageAlt="Alt text"
50
+ imageProps={{
51
+ alt: "Alt text",
52
+ src: "https://placeimg.com/400/200/arch",
53
+ }}
50
54
  mainActionLink="http://nypl.org"
51
55
  >
52
56
  <CardHeading level={HeadingLevels.Three} id="heading1">
@@ -73,8 +77,10 @@ describe("Card", () => {
73
77
  const regularCard = (
74
78
  <Card
75
79
  id="regularCard"
76
- imageSrc="https://placeimg.com/400/200/arch"
77
- imageAlt="Alt text"
80
+ imageProps={{
81
+ alt: "Alt text",
82
+ src: "https://placeimg.com/400/200/arch",
83
+ }}
78
84
  >
79
85
  <CardHeading level={HeadingLevels.Three} id="heading1">
80
86
  The Card Heading
@@ -96,8 +102,10 @@ describe("Card", () => {
96
102
  <Card
97
103
  className="edition-card"
98
104
  id="cardWithExtendedStyles"
99
- imageAlt="Alt text"
100
- imageSrc="https://placeimg.com/300/400/arch"
105
+ imageProps={{
106
+ alt: "Alt text",
107
+ src: "https://placeimg.com/300/400/arch",
108
+ }}
101
109
  >
102
110
  <CardHeading id="editioncardheading1" level={HeadingLevels.Two}>
103
111
  The Card Heading
@@ -130,8 +138,10 @@ describe("Card", () => {
130
138
  <Card
131
139
  className="edition-card"
132
140
  id="cardWithNoCTAs"
133
- imageAlt="Alt text"
134
- imageSrc="https://placeimg.com/300/400/arch"
141
+ imageProps={{
142
+ alt: "Alt text",
143
+ src: "https://placeimg.com/300/400/arch",
144
+ }}
135
145
  >
136
146
  <CardHeading id="editioncardheading1" level={HeadingLevels.Two}>
137
147
  The Card Heading
@@ -147,8 +157,10 @@ describe("Card", () => {
147
157
  <Card
148
158
  className="edition-card"
149
159
  id="cardWithNoContent"
150
- imageAlt="Alt text"
151
- imageSrc="https://placeimg.com/300/400/arch"
160
+ imageProps={{
161
+ alt: "Alt text",
162
+ src: "https://placeimg.com/300/400/arch",
163
+ }}
152
164
  >
153
165
  <CardHeading
154
166
  id="editioncardheading1"
@@ -202,8 +214,10 @@ describe("Card", () => {
202
214
  const cardFullClick = () => (
203
215
  <Card
204
216
  id="fullclick"
205
- imageAlt="Alt text"
206
- imageSrc="https://placeimg.com/400/200/arch"
217
+ imageProps={{
218
+ alt: "Alt text",
219
+ src: "https://placeimg.com/400/200/arch",
220
+ }}
207
221
  mainActionLink="http://nypl.org"
208
222
  >
209
223
  <CardHeading level={HeadingLevels.Three} id="heading1">
@@ -225,8 +239,10 @@ describe("Card", () => {
225
239
  const cardImageComponentAndRatio = () => (
226
240
  <Card
227
241
  id="fullclick"
228
- imageComponent={<Image alt="" src="https://placeimg.com/400/200/arch" />}
229
- imageAspectRatio={ImageRatios.ThreeByTwo}
242
+ imageProps={{
243
+ aspectRatio: ImageRatios.ThreeByTwo,
244
+ component: <Image alt="" src="https://placeimg.com/400/200/arch" />,
245
+ }}
230
246
  >
231
247
  <CardHeading level={HeadingLevels.Three} id="heading1">
232
248
  The Card Heading
@@ -303,11 +319,13 @@ describe("Card", () => {
303
319
  );
304
320
  });
305
321
 
306
- it("Logs a warning when both `imageComponent` and `imageAspectRatio` are passed", () => {
322
+ it("Logs a warning when both `imageProps.component` and `imageProps.aspectRatio` are passed", () => {
307
323
  const warn = jest.spyOn(console, "warn");
308
324
  render(cardImageComponentAndRatio());
309
325
  expect(warn).toHaveBeenCalledWith(
310
- "Both `imageComponent` and `imageAspectRatio` are set but `imageAspectRatio` will be ignored in favor of the aspect ratio on `imageComponent`."
326
+ "NYPL Reservoir Card: Both the `imageProps.component` and `imageProps.aspectRatio` " +
327
+ "props were set but `imageProps.aspectRatio` will be ignored in favor " +
328
+ "of the aspect ratio on `imageProps.component` prop."
311
329
  );
312
330
  });
313
331
 
@@ -7,18 +7,19 @@ import {
7
7
  useStyleConfig,
8
8
  } from "@chakra-ui/react";
9
9
 
10
- import { CardLayouts } from "./CardTypes";
10
+ import { LayoutTypes } from "../../helpers/enums";
11
11
  import Heading from "../Heading/Heading";
12
- import Image, { ImageProps } from "../Image/Image";
12
+ import Image, { ComponentImageProps, ImageProps } from "../Image/Image";
13
13
  import { ImageRatios, ImageSizes } from "../Image/ImageTypes";
14
+ import useWindowSize from "../../hooks/useWindowSize";
14
15
  import generateUUID from "../../helpers/generateUUID";
15
16
 
16
17
  interface CardBaseProps {
17
18
  /** Optional value to control the alignment of the text and elements. */
18
- center?: boolean;
19
+ isCentered?: boolean;
19
20
  /** Optional value to render the layout in a row or column.
20
- * Default is `CardLayouts.Column`. */
21
- layout?: CardLayouts;
21
+ * Default is `LayoutTypes.Column`. */
22
+ layout?: LayoutTypes;
22
23
  }
23
24
 
24
25
  interface CardLinkBoxProps {
@@ -26,6 +27,12 @@ interface CardLinkBoxProps {
26
27
  mainActionLink?: string;
27
28
  }
28
29
 
30
+ // Used internally only for the `imageProps` prop for the `Card` component.
31
+ interface CardImageProps extends ComponentImageProps {
32
+ /** Optional boolean value to control the position of the `CardImage`. */
33
+ isAtEnd?: boolean;
34
+ }
35
+
29
36
  interface CardActionsProps extends CardBaseProps {
30
37
  /** Optional boolean value to control visibility of border on the bottom edge
31
38
  * of the card actions element */
@@ -35,9 +42,10 @@ interface CardActionsProps extends CardBaseProps {
35
42
  topBorder?: boolean;
36
43
  }
37
44
 
38
- interface CardImageProps extends CardBaseProps, ImageProps {
45
+ /** Used only internally for the `CardImage` component. */
46
+ interface CardImageComponentProps extends CardBaseProps, ImageProps {
39
47
  /** Optional boolean value to control the position of the `CardImage`. */
40
- imageAtEnd?: boolean;
48
+ isAtEnd?: boolean;
41
49
  }
42
50
 
43
51
  export interface CardProps extends CardBaseProps, CardLinkBoxProps {
@@ -52,21 +60,8 @@ export interface CardProps extends CardBaseProps, CardLinkBoxProps {
52
60
  foregroundColor?: string;
53
61
  /** ID that other components can cross reference for accessibility purposes. */
54
62
  id?: string;
55
- /** Text description of the image; to follow best practices for accessibility,
56
- * this prop should not be left blank if `imageSrc` is passed. */
57
- imageAlt?: string;
58
- /** Optional value to control the aspect ratio of the `CardImage`; default
59
- * value is `ImageRatios.Square`. */
60
- imageAspectRatio?: ImageRatios;
61
- /** Optional boolean value to control the position of the `CardImage`. */
62
- imageAtEnd?: boolean;
63
- /** Custom image component used in place of DS `Image` component. */
64
- imageComponent?: JSX.Element;
65
- /** Optional value to control the size of the `CardImage`. Default value is
66
- * `ImageSizes.Default`. */
67
- imageSize?: ImageSizes;
68
- /** The path to the image displayed within the `Card` component. */
69
- imageSrc?: string;
63
+ /** Object used to create and render the `Image` component. */
64
+ imageProps?: CardImageProps;
70
65
  }
71
66
 
72
67
  /**
@@ -74,31 +69,37 @@ export interface CardProps extends CardBaseProps, CardLinkBoxProps {
74
69
  * renders an `Image` component but with overriding styles specific to the
75
70
  * `Card` component.
76
71
  */
77
- function CardImage(props: React.ComponentProps<"img"> & CardImageProps) {
72
+ function CardImage(
73
+ props: React.ComponentProps<"img"> & CardImageComponentProps
74
+ ) {
78
75
  const {
79
76
  alt,
80
- center,
77
+ aspectRatio,
78
+ caption,
81
79
  component,
82
- imageSize,
83
- imageAspectRatio,
84
- src,
85
- imageAtEnd,
80
+ credit,
81
+ isAtEnd,
82
+ isCentered,
86
83
  layout,
84
+ size,
85
+ src,
87
86
  } = props;
88
87
  // Additional styles to add to the `Image` component.
89
88
  const styles = useStyleConfig("CardImage", {
90
- center,
91
- imageAtEnd,
92
- imageSize,
89
+ imageIsAtEnd: isAtEnd,
90
+ isCentered,
91
+ size,
93
92
  layout,
94
93
  });
95
94
  return (
96
95
  <Box __css={styles}>
97
96
  <Image
98
97
  alt={alt}
98
+ caption={caption}
99
99
  component={component}
100
- imageAspectRatio={imageAspectRatio}
101
- imageSize={imageSize}
100
+ credit={credit}
101
+ aspectRatio={aspectRatio}
102
+ size={size}
102
103
  src={src}
103
104
  />
104
105
  </Box>
@@ -117,12 +118,12 @@ export function CardContent(props: React.PropsWithChildren<{}>) {
117
118
 
118
119
  // CardActions child-component
119
120
  export function CardActions(props: React.PropsWithChildren<CardActionsProps>) {
120
- const { bottomBorder, children, topBorder, center, layout } = props;
121
+ const { bottomBorder, children, isCentered, layout, topBorder } = props;
121
122
  const styles = useStyleConfig("CardActions", {
122
123
  bottomBorder,
123
- topBorder,
124
- center,
124
+ isCentered,
125
125
  layout,
126
+ topBorder,
126
127
  });
127
128
 
128
129
  return children && <Box __css={styles}>{children}</Box>;
@@ -166,42 +167,64 @@ export default function Card(props: React.PropsWithChildren<CardProps>) {
166
167
  const {
167
168
  backgroundColor,
168
169
  border,
169
- center = false,
170
170
  children,
171
171
  className,
172
172
  foregroundColor,
173
173
  id = generateUUID(),
174
- imageAlt = "",
175
- imageAspectRatio = ImageRatios.Square,
176
- imageAtEnd,
177
- imageComponent,
178
- imageSize = ImageSizes.Default,
179
- imageSrc,
180
- layout = CardLayouts.Column,
174
+ imageProps = {
175
+ alt: "",
176
+ aspectRatio: ImageRatios.Square,
177
+ caption: undefined,
178
+ component: undefined,
179
+ credit: undefined,
180
+ isAtEnd: false,
181
+ size: ImageSizes.Default,
182
+ src: "",
183
+ },
184
+ isCentered = false,
185
+ layout = LayoutTypes.Column,
181
186
  mainActionLink,
182
187
  } = props;
183
- const hasImage = imageSrc || imageComponent;
184
- const finalImageAspectRatio = imageComponent
188
+ const hasImage = imageProps.src || imageProps.component;
189
+ const [finalImageSize, setFinalImageSize] = React.useState<ImageSizes>(
190
+ imageProps.size
191
+ );
192
+ const finalImageAspectRatio = imageProps.component
185
193
  ? ImageRatios.Original
186
- : imageAspectRatio;
194
+ : imageProps.aspectRatio;
187
195
  const customColors = {};
188
196
  const cardContents = [];
197
+ const windowDimensions = useWindowSize();
189
198
  let cardHeadingCount = 0;
190
199
 
191
- if (imageComponent && imageAspectRatio !== ImageRatios.Square) {
200
+ if (imageProps.component && imageProps.aspectRatio !== ImageRatios.Square) {
192
201
  console.warn(
193
- "Both `imageComponent` and `imageAspectRatio` are set but `imageAspectRatio` will be ignored in favor of the aspect ratio on `imageComponent`."
202
+ "NYPL Reservoir Card: Both the `imageProps.component` and `imageProps.aspectRatio` " +
203
+ "props were set but `imageProps.aspectRatio` will be ignored in favor " +
204
+ "of the aspect ratio on `imageProps.component` prop."
194
205
  );
195
206
  }
196
207
 
208
+ // The `Card`'s image should always display as 100% width on mobile. To
209
+ // achieve this, we set the size to `ImageSizes.Default` only when the
210
+ // viewport is less than "600px". Otherwise, we set the size to
211
+ // the value passed in via `imageSize`.
212
+ React.useEffect(() => {
213
+ if (windowDimensions.width < 600) {
214
+ setFinalImageSize(ImageSizes.Default);
215
+ } else {
216
+ setFinalImageSize(imageProps.size);
217
+ }
218
+ }, [windowDimensions.width, imageProps.size]);
219
+
197
220
  backgroundColor && (customColors["backgroundColor"] = backgroundColor);
198
221
  foregroundColor && (customColors["color"] = foregroundColor);
199
222
 
200
223
  const styles = useMultiStyleConfig("Card", {
201
224
  border,
202
- center,
203
225
  hasImage,
204
- imageAtEnd,
226
+ imageIsAtEnd: imageProps.isAtEnd,
227
+ isCentered,
205
228
  layout,
206
229
  mainActionLink,
207
230
  });
@@ -227,7 +250,7 @@ export default function Card(props: React.PropsWithChildren<CardProps>) {
227
250
  ...child.props.additionalStyles,
228
251
  },
229
252
  key,
230
- center,
253
+ isCentered,
231
254
  // Override the child text with the potential `CardLinkOverlay`.
232
255
  children: newChildren,
233
256
  layout,
@@ -240,7 +263,7 @@ export default function Card(props: React.PropsWithChildren<CardProps>) {
240
263
  child.type === CardActions ||
241
264
  child.props.mdxType === "CardActions"
242
265
  ) {
243
- const elem = React.cloneElement(child, { key, center, layout });
266
+ const elem = React.cloneElement(child, { key, isCentered, layout });
244
267
  cardContents.push(elem);
245
268
  }
246
269
  });
@@ -257,13 +280,15 @@ export default function Card(props: React.PropsWithChildren<CardProps>) {
257
280
  >
258
281
  {hasImage && (
259
282
  <CardImage
260
- src={imageSrc ? imageSrc : null}
261
- component={imageComponent}
262
- alt={imageAlt}
263
- imageSize={imageSize}
264
- imageAspectRatio={finalImageAspectRatio}
265
- imageAtEnd={imageAtEnd}
283
+ alt={imageProps.alt}
284
+ aspectRatio={finalImageAspectRatio}
285
+ caption={imageProps.caption}
286
+ component={imageProps.component}
287
+ credit={imageProps.credit}
288
+ isAtEnd={imageProps.isAtEnd}
266
289
  layout={layout}
290
+ size={finalImageSize}
291
+ src={imageProps.src ? imageProps.src : undefined}
267
292
  />
268
293
  )}
269
294
  <Box className="card-body" __css={styles.body}>
@@ -8,19 +8,11 @@ exports[`Card Renders the UI snapshot correctly 1`] = `
8
8
  <div
9
9
  className="css-0"
10
10
  >
11
- <div
12
- className="the-wrap css-0"
13
- >
14
- <div
15
- className="the-crop css-0"
16
- >
17
- <img
18
- alt="Alt text"
19
- className="css-0"
20
- src="https://placeimg.com/400/200/arch"
21
- />
22
- </div>
23
- </div>
11
+ <img
12
+ alt="Alt text"
13
+ className="css-0"
14
+ src="https://placeimg.com/400/200/arch"
15
+ />
24
16
  </div>
25
17
  <div
26
18
  className="card-body css-0"
@@ -61,19 +53,11 @@ exports[`Card Renders the UI snapshot correctly 2`] = `
61
53
  <div
62
54
  className="css-0"
63
55
  >
64
- <div
65
- className="the-wrap css-0"
66
- >
67
- <div
68
- className="the-crop css-0"
69
- >
70
- <img
71
- alt="Alt text"
72
- className="css-0"
73
- src="https://placeimg.com/300/400/arch"
74
- />
75
- </div>
76
- </div>
56
+ <img
57
+ alt="Alt text"
58
+ className="css-0"
59
+ src="https://placeimg.com/300/400/arch"
60
+ />
77
61
  </div>
78
62
  <div
79
63
  className="card-body css-0"
@@ -163,19 +147,11 @@ exports[`Card Renders the UI snapshot correctly 3`] = `
163
147
  <div
164
148
  className="css-0"
165
149
  >
166
- <div
167
- className="the-wrap css-0"
168
- >
169
- <div
170
- className="the-crop css-0"
171
- >
172
- <img
173
- alt="Alt text"
174
- className="css-0"
175
- src="https://placeimg.com/300/400/arch"
176
- />
177
- </div>
178
- </div>
150
+ <img
151
+ alt="Alt text"
152
+ className="css-0"
153
+ src="https://placeimg.com/300/400/arch"
154
+ />
179
155
  </div>
180
156
  <div
181
157
  className="card-body css-0"
@@ -211,19 +187,11 @@ exports[`Card Renders the UI snapshot correctly 4`] = `
211
187
  <div
212
188
  className="css-0"
213
189
  >
214
- <div
215
- className="the-wrap css-0"
216
- >
217
- <div
218
- className="the-crop css-0"
219
- >
220
- <img
221
- alt="Alt text"
222
- className="css-0"
223
- src="https://placeimg.com/300/400/arch"
224
- />
225
- </div>
226
- </div>
190
+ <img
191
+ alt="Alt text"
192
+ className="css-0"
193
+ src="https://placeimg.com/300/400/arch"
194
+ />
227
195
  </div>
228
196
  <div
229
197
  className="card-body css-0"
@@ -396,19 +364,11 @@ exports[`Card Renders the UI snapshot correctly 6`] = `
396
364
  <div
397
365
  className="css-0"
398
366
  >
399
- <div
400
- className="the-wrap css-0"
401
- >
402
- <div
403
- className="the-crop css-0"
404
- >
405
- <img
406
- alt="Alt text"
407
- className="css-0"
408
- src="https://placeimg.com/400/200/arch"
409
- />
410
- </div>
411
- </div>
367
+ <img
368
+ alt="Alt text"
369
+ className="css-0"
370
+ src="https://placeimg.com/400/200/arch"
371
+ />
412
372
  </div>
413
373
  <div
414
374
  className="card-body css-0"
@@ -53,9 +53,9 @@ guide on the Chakra UI site.
53
53
  <DSProvider>
54
54
  <Center border="1px solid" borderColor="var(--nypl-colors-ui-gray-medium)">
55
55
  <Image
56
- src="https://placeimg.com/300/400/arch"
57
56
  alt="Centered Image"
58
- imageSize={ImageSizes.Medium}
57
+ size={ImageSizes.Medium}
58
+ src="https://placeimg.com/300/400/arch"
59
59
  />
60
60
  </Center>
61
61
  </DSProvider>
@@ -57,7 +57,7 @@ import DSProvider from "../../theme/provider";
57
57
  | Component Version | DS Version |
58
58
  | ----------------- | ---------- |
59
59
  | Added | `0.1.0` |
60
- | Latest | `0.25.12` |
60
+ | Latest | `0.25.13` |
61
61
 
62
62
  <Description of={Checkbox} />
63
63
 
@@ -177,3 +177,15 @@ now be controlled and removed by the parent component in order to remove this st
177
177
  />
178
178
  </DSProvider>
179
179
  </Canvas>
180
+
181
+ ## With JSX Element Label
182
+
183
+ This is useful when you want to add dynamic content to the label or add
184
+ a layout to the label. View the `CheckboxGroup` documentation for this
185
+ usage.
186
+
187
+ <Canvas>
188
+ <DSProvider>
189
+ <Checkbox labelText={<span>Arts</span>} name="jsxElementLabel" />
190
+ </DSProvider>
191
+ </Canvas>
@@ -1,13 +1,15 @@
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 userEvent from "@testing-library/user-event";
4
5
  import { axe } from "jest-axe";
5
6
  import renderer from "react-test-renderer";
6
- import * as generateUUID from "../../helpers/generateUUID";
7
+
7
8
  import Checkbox from "./Checkbox";
9
+ import * as generateUUID from "../../helpers/generateUUID";
8
10
 
9
11
  describe("Checkbox Accessibility", () => {
10
- it("Passes axe accessibility test", async () => {
12
+ it("passes axe accessibility test with string label", async () => {
11
13
  const { container } = render(
12
14
  <Checkbox
13
15
  id="inputID"
@@ -18,6 +20,23 @@ describe("Checkbox Accessibility", () => {
18
20
  );
19
21
  expect(await axe(container)).toHaveNoViolations();
20
22
  });
23
+
24
+ it("passes axe accessibility test with jsx label", async () => {
25
+ const { container } = render(
26
+ <Checkbox
27
+ id="jsxLabel"
28
+ labelText={
29
+ <Flex>
30
+ <span>Arts</span>
31
+ <Spacer />
32
+ <span>4</span>
33
+ </Flex>
34
+ }
35
+ value="arts"
36
+ />
37
+ );
38
+ expect(await axe(container)).toHaveNoViolations();
39
+ });
21
40
  });
22
41
 
23
42
  describe("Checkbox", () => {
@@ -195,6 +214,27 @@ describe("Checkbox", () => {
195
214
  expect(changeHandler).toHaveBeenCalledTimes(1);
196
215
  });
197
216
 
217
+ it("logs a warning if `labelText` is not a string and `showLabel` is false", () => {
218
+ const warn = jest.spyOn(console, "warn");
219
+ render(
220
+ <Checkbox
221
+ value="arts"
222
+ labelText={
223
+ <Flex>
224
+ <span>Arts</span>
225
+ <Spacer />
226
+ <span>4</span>
227
+ </Flex>
228
+ }
229
+ showLabel={false}
230
+ />
231
+ );
232
+
233
+ expect(warn).toHaveBeenCalledWith(
234
+ "NYPL Reservoir Checkbox: `labelText` must be a string when `showLabel` is false."
235
+ );
236
+ });
237
+
198
238
  it("Renders the UI snapshot correctly", () => {
199
239
  const primary = renderer
200
240
  .create(<Checkbox id="inputID" labelText="Test Label" />)
@@ -229,6 +269,21 @@ describe("Checkbox", () => {
229
269
  <Checkbox id="checkbox-disabled" labelText="Test Label" isDisabled />
230
270
  )
231
271
  .toJSON();
272
+ const withJSXLabel = renderer
273
+ .create(
274
+ <Checkbox
275
+ id="jsxLabel"
276
+ labelText={
277
+ <Flex>
278
+ <span>Arts</span>
279
+ <Spacer />
280
+ <span>4</span>
281
+ </Flex>
282
+ }
283
+ value="arts"
284
+ />
285
+ )
286
+ .toJSON();
232
287
 
233
288
  expect(primary).toMatchSnapshot();
234
289
  expect(isChecked).toMatchSnapshot();
@@ -236,5 +291,6 @@ describe("Checkbox", () => {
236
291
  expect(isRequired).toMatchSnapshot();
237
292
  expect(isInvalid).toMatchSnapshot();
238
293
  expect(isDisabled).toMatchSnapshot();
294
+ expect(withJSXLabel).toMatchSnapshot();
239
295
  });
240
296
  });
@@ -38,7 +38,7 @@ export interface CheckboxProps {
38
38
  isRequired?: boolean;
39
39
  /** The checkbox's label. This will serve as the text content for a `<label>`
40
40
  * element if `showlabel` is true, or an "aria-label" if `showLabel` is false. */
41
- labelText: string;
41
+ labelText: string | JSX.Element;
42
42
  /** The name prop indicates into which group of checkboxes this checkbox
43
43
  * belongs. If none is specified, 'default' will be used */
44
44
  name?: string;
@@ -99,6 +99,11 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
99
99
  const icon = !isIndeterminate ? <CheckboxIcon /> : undefined;
100
100
 
101
101
  if (!showLabel) {
102
+ if (typeof labelText !== "string") {
103
+ console.warn(
104
+ "NYPL Reservoir Checkbox: `labelText` must be a string when `showLabel` is false."
105
+ );
106
+ }
102
107
  ariaAttributes["aria-label"] =
103
108
  labelText && footnote ? `${labelText} - ${footnote}` : labelText;
104
109
  } else {