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

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 (163) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +4 -16
  3. package/dist/components/Breadcrumbs/BreadcrumbsTypes.d.ts +1 -0
  4. package/dist/components/DatePicker/DatePicker.d.ts +1 -1
  5. package/dist/components/Fieldset/Fieldset.d.ts +1 -3
  6. package/dist/components/Form/Form.d.ts +13 -12
  7. package/dist/components/Form/FormTypes.d.ts +2 -2
  8. package/dist/components/HorizontalRule/HorizontalRule.d.ts +1 -1
  9. package/dist/components/Icons/IconTypes.d.ts +9 -7
  10. package/dist/components/List/List.d.ts +1 -1
  11. package/dist/components/Logo/LogoSvgs.d.ts +23 -1
  12. package/dist/components/Logo/LogoTypes.d.ts +23 -1
  13. package/dist/components/Notification/Notification.d.ts +2 -0
  14. package/dist/components/Pagination/Pagination.d.ts +6 -2
  15. package/dist/components/RadioGroup/RadioGroup.d.ts +3 -3
  16. package/dist/components/SearchBar/SearchBar.d.ts +6 -6
  17. package/dist/components/Select/Select.d.ts +4 -0
  18. package/dist/components/Table/Table.d.ts +9 -3
  19. package/dist/components/Template/Template.d.ts +24 -5
  20. package/dist/design-system-react-components.cjs.development.js +2063 -548
  21. package/dist/design-system-react-components.cjs.development.js.map +1 -1
  22. package/dist/design-system-react-components.cjs.production.min.js +1 -1
  23. package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
  24. package/dist/design-system-react-components.esm.js +2056 -554
  25. package/dist/design-system-react-components.esm.js.map +1 -1
  26. package/dist/index.d.ts +4 -4
  27. package/dist/resources.scss +0 -2
  28. package/dist/styles.css +1 -1
  29. package/dist/theme/components/breadcrumb.d.ts +4 -1
  30. package/dist/theme/components/checkbox.d.ts +0 -2
  31. package/dist/theme/components/customTable.d.ts +12 -3
  32. package/dist/theme/components/fieldset.d.ts +2 -0
  33. package/dist/theme/components/global.d.ts +15 -14
  34. package/dist/theme/components/globalMixins.d.ts +8 -8
  35. package/dist/theme/components/list.d.ts +6 -0
  36. package/dist/theme/components/notification.d.ts +16 -4
  37. package/dist/theme/components/radio.d.ts +3 -2
  38. package/dist/theme/components/searchBar.d.ts +4 -0
  39. package/dist/theme/components/select.d.ts +2 -9
  40. package/dist/theme/components/slider.d.ts +8 -4
  41. package/dist/theme/components/structuredContent.d.ts +9 -9
  42. package/dist/theme/components/textInput.d.ts +10 -12
  43. package/dist/theme/components/toggle.d.ts +6 -2
  44. package/dist/theme/foundations/global.d.ts +31 -3
  45. package/dist/utils/utils.d.ts +10 -0
  46. package/package.json +40 -36
  47. package/src/components/Accordion/Accordion.stories.mdx +1 -1
  48. package/src/components/Accordion/Accordion.test.tsx +45 -1
  49. package/src/components/Accordion/Accordion.tsx +20 -8
  50. package/src/components/Accordion/__snapshots__/Accordion.test.tsx.snap +243 -0
  51. package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +30 -2
  52. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +25 -0
  53. package/src/components/Breadcrumbs/Breadcrumbs.tsx +9 -3
  54. package/src/components/Breadcrumbs/BreadcrumbsTypes.tsx +1 -0
  55. package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +104 -5
  56. package/src/components/Card/Card.stories.mdx +1 -1
  57. package/src/components/Card/Card.tsx +4 -1
  58. package/src/components/Card/__snapshots__/Card.test.tsx.snap +1 -1
  59. package/src/components/Chakra/Flex.stories.mdx +113 -0
  60. package/src/components/Checkbox/Checkbox.stories.mdx +1 -1
  61. package/src/components/Checkbox/Checkbox.tsx +1 -0
  62. package/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +6 -6
  63. package/src/components/CheckboxGroup/CheckboxGroup.stories.mdx +1 -1
  64. package/src/components/CheckboxGroup/__snapshots__/CheckboxGroup.test.tsx.snap +18 -18
  65. package/src/components/DatePicker/DatePicker.stories.mdx +1 -1
  66. package/src/components/DatePicker/DatePicker.test.tsx +6 -6
  67. package/src/components/DatePicker/DatePicker.tsx +12 -10
  68. package/src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap +28 -20
  69. package/src/components/Fieldset/Fieldset.stories.mdx +1 -1
  70. package/src/components/Fieldset/Fieldset.tsx +2 -4
  71. package/src/components/Form/Form.stories.mdx +34 -16
  72. package/src/components/Form/Form.test.tsx +92 -3
  73. package/src/components/Form/Form.tsx +25 -21
  74. package/src/components/Form/FormTypes.tsx +2 -2
  75. package/src/components/Form/__snapshots__/Form.test.tsx.snap +0 -1
  76. package/src/components/HelperErrorText/HelperErrorText.stories.mdx +1 -1
  77. package/src/components/Hero/Hero.stories.mdx +1 -1
  78. package/src/components/HorizontalRule/HorizontalRule.stories.mdx +3 -2
  79. package/src/components/HorizontalRule/HorizontalRule.tsx +2 -2
  80. package/src/components/HorizontalRule/__snapshots__/HorizontalRule.test.tsx.snap +4 -4
  81. package/src/components/Icons/Icon.stories.mdx +1 -1
  82. package/src/components/Icons/Icon.test.tsx +1 -1
  83. package/src/components/Icons/Icon.tsx +1 -1
  84. package/src/components/Icons/IconTypes.tsx +8 -6
  85. package/src/components/List/List.stories.mdx +24 -5
  86. package/src/components/List/List.test.tsx +1 -1
  87. package/src/components/List/List.tsx +2 -2
  88. package/src/components/List/__snapshots__/List.test.tsx.snap +3 -1
  89. package/src/components/Logo/Logo.stories.mdx +7 -5
  90. package/src/components/Logo/LogoSvgs.tsx +45 -1
  91. package/src/components/Logo/LogoTypes.tsx +22 -0
  92. package/src/components/Notification/Notification.stories.mdx +73 -1
  93. package/src/components/Notification/Notification.test.tsx +64 -5
  94. package/src/components/Notification/Notification.tsx +21 -11
  95. package/src/components/Notification/__snapshots__/Notification.test.tsx.snap +103 -8
  96. package/src/components/Pagination/Pagination.stories.mdx +54 -12
  97. package/src/components/Pagination/Pagination.test.tsx +63 -5
  98. package/src/components/Pagination/Pagination.tsx +46 -24
  99. package/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap +3 -3
  100. package/src/components/Radio/Radio.stories.mdx +1 -1
  101. package/src/components/Radio/Radio.tsx +1 -0
  102. package/src/components/Radio/__snapshots__/Radio.test.tsx.snap +5 -5
  103. package/src/components/RadioGroup/RadioGroup.stories.mdx +1 -1
  104. package/src/components/RadioGroup/RadioGroup.test.tsx +13 -11
  105. package/src/components/RadioGroup/RadioGroup.tsx +88 -89
  106. package/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap +18 -18
  107. package/src/components/SearchBar/SearchBar.Test.tsx +124 -28
  108. package/src/components/SearchBar/SearchBar.stories.mdx +9 -6
  109. package/src/components/SearchBar/SearchBar.tsx +24 -23
  110. package/src/components/Select/Select.stories.mdx +1 -1
  111. package/src/components/Select/Select.test.tsx +89 -0
  112. package/src/components/Select/Select.tsx +11 -2
  113. package/src/components/Select/__snapshots__/Select.test.tsx.snap +545 -0
  114. package/src/components/Slider/Slider.stories.mdx +1 -1
  115. package/src/components/Slider/Slider.tsx +4 -1
  116. package/src/components/Slider/__snapshots__/Slider.test.tsx.snap +7 -0
  117. package/src/components/StructuredContent/StructuredContent.stories.mdx +1 -1
  118. package/src/components/StyleGuide/Bidirectionality.stories.mdx +4 -4
  119. package/src/components/StyleGuide/Colors.stories.mdx +33 -18
  120. package/src/components/Table/Table.stories.mdx +118 -19
  121. package/src/components/Table/Table.test.tsx +80 -3
  122. package/src/components/Table/Table.tsx +26 -16
  123. package/src/components/Table/__snapshots__/Table.test.tsx.snap +1179 -0
  124. package/src/components/Tabs/Tabs.stories.mdx +1 -1
  125. package/src/components/Tabs/Tabs.test.tsx +21 -5
  126. package/src/components/Tabs/Tabs.tsx +35 -20
  127. package/src/components/Tabs/__snapshots__/Tabs.test.tsx.snap +195 -0
  128. package/src/components/Template/Template.stories.mdx +79 -4
  129. package/src/components/Template/Template.test.tsx +65 -3
  130. package/src/components/Template/Template.tsx +60 -14
  131. package/src/components/Template/__snapshots__/Template.test.tsx.snap +94 -1
  132. package/src/components/TextInput/TextInput.stories.mdx +1 -1
  133. package/src/components/Toggle/Toggle.stories.mdx +1 -1
  134. package/src/components/Toggle/Toggle.tsx +2 -1
  135. package/src/components/Toggle/__snapshots__/Toggle.test.tsx.snap +4 -4
  136. package/src/docs/Chakra.stories.mdx +1 -1
  137. package/src/index.ts +8 -2
  138. package/src/styles/base/_place-holder.scss +2 -0
  139. package/src/styles.scss +0 -2
  140. package/src/theme/components/breadcrumb.ts +5 -1
  141. package/src/theme/components/checkbox.ts +3 -7
  142. package/src/theme/components/customTable.ts +16 -3
  143. package/src/theme/components/fieldset.ts +2 -0
  144. package/src/theme/components/global.ts +19 -16
  145. package/src/theme/components/globalMixins.ts +8 -8
  146. package/src/theme/components/list.ts +6 -2
  147. package/src/theme/components/notification.ts +21 -8
  148. package/src/theme/components/radio.ts +3 -6
  149. package/src/theme/components/searchBar.ts +4 -0
  150. package/src/theme/components/select.ts +3 -3
  151. package/src/theme/components/slider.ts +12 -9
  152. package/src/theme/components/structuredContent.ts +26 -6
  153. package/src/theme/components/textInput.ts +3 -2
  154. package/src/theme/components/toggle.ts +42 -38
  155. package/src/theme/foundations/colors.ts +19 -12
  156. package/src/theme/foundations/global.ts +17 -5
  157. package/src/theme/foundations/typography.ts +2 -2
  158. package/src/utils/componentCategories.ts +2 -1
  159. package/src/utils/utils.ts +28 -0
  160. package/dist/components/Pagination/Pagination.stories.d.ts +0 -13
  161. package/src/components/Pagination/Pagination.stories.tsx +0 -54
  162. package/src/styles/base/_03-base.scss +0 -25
  163. package/src/styles/base/_04-focus.scss +0 -22
@@ -10,7 +10,7 @@ const fishArray = ["Mahi-mahi", "Golden trout", "Rainbowfish", "Suckerfish"];
10
10
  const fishDefinitions = [
11
11
  {
12
12
  term: "Mahi-mahi",
13
- definition: "The mahi-mahi is an ocean fish known...",
13
+ definition: <p>The mahi-mahi is an ocean fish known...</p>,
14
14
  },
15
15
  {
16
16
  term: "Golden trout",
@@ -8,7 +8,7 @@ import generateUUID from "../../helpers/generateUUID";
8
8
 
9
9
  interface DefinitionProps {
10
10
  term: string;
11
- definition: string;
11
+ definition: string | JSX.Element;
12
12
  }
13
13
  export interface ListProps {
14
14
  /** Optionally pass in additional Chakra-based styles. */
@@ -98,7 +98,7 @@ export default function List(props: React.PropsWithChildren<ListProps>) {
98
98
  */
99
99
  const checkListChildrenError = (listType: ListTypes) => {
100
100
  React.Children.map(children, (child: React.ReactElement) => {
101
- if (child?.type !== "li" && child?.props?.mdxType !== "li") {
101
+ if (child && child?.type !== "li" && child?.props?.mdxType !== "li") {
102
102
  console.warn(
103
103
  `Direct children of \`List\` (${listType}) should be \`<li>\`s.`
104
104
  );
@@ -96,7 +96,9 @@ exports[`List Renders the UI snapshot correctly 5`] = `
96
96
  Mahi-mahi
97
97
  </dt>
98
98
  <dd>
99
- The mahi-mahi is an ocean fish known...
99
+ <p>
100
+ The mahi-mahi is an ocean fish known...
101
+ </p>
100
102
  </dd>
101
103
  <dt>
102
104
  Golden trout
@@ -57,7 +57,7 @@ export const sizesEnumValues = getStorybookEnumValues(LogoSizes, "LogoSizes");
57
57
  | Component Version | DS Version |
58
58
  | ----------------- | ---------- |
59
59
  | Added | `0.25.9` |
60
- | Latest | `0.25.9` |
60
+ | Latest | `0.25.12` |
61
61
 
62
62
  <Description of={Logo} />
63
63
 
@@ -77,11 +77,13 @@ export const sizesEnumValues = getStorybookEnumValues(LogoSizes, "LogoSizes");
77
77
  {(args) => (
78
78
  <div
79
79
  style={
80
- args.name.indexOf("White") !== -1
80
+ args.name.indexOf("White") !== -1 ||
81
+ args.name.indexOf("Negative") !== -1
81
82
  ? {
82
83
  backgroundColor: "var(--nypl-colors-ui-gray-xdark)",
83
84
  display: "inline-block",
84
85
  padding: "var(--nypl-space-l)",
86
+ width: "100%",
85
87
  }
86
88
  : undefined
87
89
  }
@@ -104,11 +106,11 @@ export const logoRow = (logo, opts = {}) => {
104
106
  const styles = { textAlign: "center" };
105
107
  const { size = LogoSizes.Large, displayValue } = opts;
106
108
  let key = logo;
107
- if (logo.indexOf("White") !== -1) {
109
+ if (logo.indexOf("White") !== -1 || logo.indexOf("Negative") !== -1) {
108
110
  styles.backgroundColor = "var(--nypl-colors-ui-gray-xdark)";
109
- styles.paddingBottom = "32px";
110
- styles.paddingTop = "32px";
111
111
  styles.color = "var(--nypl-colors-ui-white)";
112
+ styles.paddingBottom = "var(--nypl-space-l)";
113
+ styles.paddingTop = "var(--nypl-space-l)";
112
114
  }
113
115
  if (size !== LogoSizes.Large) {
114
116
  key += `-${size}`;
@@ -1,34 +1,78 @@
1
1
  /* eslint-disable camelcase */
2
2
  import logo_bpl_black from "../../../icons/svg/logo_bpl_black.svg";
3
+ import logo_bpl_white from "../../../icons/svg/logo_bpl_white.svg";
4
+ import logo_clever_color from "../../../icons/svg/logo_clever_color.svg";
5
+ import logo_clever_white from "../../../icons/svg/logo_clever_white.svg";
6
+ import logo_firstbook_color from "../../../icons/svg/logo_firstbook_color.svg";
7
+ import logo_firstbook_color_negative from "../../../icons/svg/logo_firstbook_color_negative.svg";
3
8
  import logo_lpa_color from "../../../icons/svg/logo_lpa_color.svg";
9
+ import logo_lpa_black from "../../../icons/svg/logo_lpa_black.svg";
4
10
  import logo_lpa_white from "../../../icons/svg/logo_lpa_white.svg";
11
+ import logo_mln_black from "../../../icons/svg/logo_mln_black.svg";
12
+ import logo_mln_white from "../../../icons/svg/logo_mln_white.svg";
5
13
  import logo_nypl_full_black from "../../../icons/svg/logo_nypl_full_black.svg";
6
14
  import logo_nypl_full_white from "../../../icons/svg/logo_nypl_full_white.svg";
7
15
  import logo_nypl_lion_black from "../../../icons/svg/logo_nypl_lion_black.svg";
8
16
  import logo_nypl_lion_white from "../../../icons/svg/logo_nypl_lion_white.svg";
17
+ import logo_openebooks_color from "../../../icons/svg/logo_openebooks_color.svg";
18
+ import logo_openebooks_negative from "../../../icons/svg/logo_openebooks_negative.svg";
19
+ import logo_openebooks_wtext_color from "../../../icons/svg/logo_openebooks_wtext_color.svg";
20
+ import logo_openebooks_wtext_negative from "../../../icons/svg/logo_openebooks_wtext_negative.svg";
9
21
  import logo_qpl_alt_black from "../../../icons/svg/logo_qpl_alt_black.svg";
22
+ import logo_qpl_alt_white from "../../../icons/svg/logo_qpl_alt_white.svg";
23
+ import logo_qpl_black from "../../../icons/svg/logo_qpl_black.svg";
10
24
  import logo_qpl_color from "../../../icons/svg/logo_qpl_color.svg";
25
+ import logo_qpl_white from "../../../icons/svg/logo_qpl_white.svg";
26
+ import logo_schomburg_black from "../../../icons/svg/logo_schomburg_black.svg";
27
+ import logo_schomburg_circle_black from "../../../icons/svg/logo_schomburg_circle_black.svg";
11
28
  import logo_schomburg_circle_color from "../../../icons/svg/logo_schomburg_circle_color.svg";
29
+ import logo_schomburg_circle_white from "../../../icons/svg/logo_schomburg_circle_white.svg";
12
30
  import logo_schomburg_color from "../../../icons/svg/logo_schomburg_color.svg";
31
+ import logo_schomburg_white from "../../../icons/svg/logo_schomburg_white.svg";
13
32
  import logo_simplye_black from "../../../icons/svg/logo_simplye_black.svg";
33
+ import logo_simplye_white from "../../../icons/svg/logo_simplye_white.svg";
14
34
  import logo_simplye_color from "../../../icons/svg/logo_simplye_color.svg";
15
35
  import logo_snfl_black from "../../../icons/svg/logo_snfl_black.svg";
16
36
  import logo_snfl_white from "../../../icons/svg/logo_snfl_white.svg";
37
+ import logo_treasures_color from "../../../icons/svg/logo_treasures_color.svg";
38
+ import logo_treasures_color_negative from "../../../icons/svg/logo_treasures_color_negative.svg";
17
39
 
18
40
  export default {
19
41
  logo_bpl_black,
42
+ logo_bpl_white,
43
+ logo_clever_color,
44
+ logo_clever_white,
45
+ logo_firstbook_color,
46
+ logo_firstbook_color_negative,
47
+ logo_lpa_black,
20
48
  logo_lpa_color,
21
49
  logo_lpa_white,
50
+ logo_mln_black,
51
+ logo_mln_white,
22
52
  logo_nypl_full_black,
23
53
  logo_nypl_full_white,
24
- logo_nypl_lion_white,
25
54
  logo_nypl_lion_black,
55
+ logo_nypl_lion_white,
56
+ logo_openebooks_color,
57
+ logo_openebooks_negative,
58
+ logo_openebooks_wtext_color,
59
+ logo_openebooks_wtext_negative,
26
60
  logo_qpl_alt_black,
61
+ logo_qpl_alt_white,
62
+ logo_qpl_black,
27
63
  logo_qpl_color,
64
+ logo_qpl_white,
65
+ logo_schomburg_black,
66
+ logo_schomburg_circle_black,
28
67
  logo_schomburg_circle_color,
68
+ logo_schomburg_circle_white,
29
69
  logo_schomburg_color,
70
+ logo_schomburg_white,
30
71
  logo_simplye_black,
72
+ logo_simplye_white,
31
73
  logo_simplye_color,
32
74
  logo_snfl_black,
33
75
  logo_snfl_white,
76
+ logo_treasures_color,
77
+ logo_treasures_color_negative,
34
78
  };
@@ -15,18 +15,40 @@ export enum LogoSizes {
15
15
 
16
16
  export enum LogoNames {
17
17
  BrooklynPublicLibraryBlack = "logo_bpl_black",
18
+ BrooklynPublicLibraryWhite = "logo_bpl_white",
19
+ CleverColor = "logo_clever_color",
20
+ CleverWhite = "logo_clever_white",
21
+ FirstBookColor = "logo_firstbook_color",
22
+ FirstBookColorNegative = "logo_firstbook_color_negative",
18
23
  LPAColor = "logo_lpa_color",
24
+ LPABlack = "logo_lpa_black",
19
25
  LPAWhite = "logo_lpa_white",
26
+ MyLibraryNYCBlack = "logo_mln_black",
27
+ MyLibraryNYCWhite = "logo_mln_white",
20
28
  NYPLBlack = "logo_nypl_full_black",
21
29
  NYPLWhite = "logo_nypl_full_white",
22
30
  NYPLLionBlack = "logo_nypl_lion_black",
23
31
  NYPLLionWhite = "logo_nypl_lion_white",
32
+ OpenEBooksColor = "logo_openebooks_color",
33
+ OpenEBooksNegative = "logo_openebooks_negative",
34
+ OpenEBooksWithTextColor = "logo_openebooks_wtext_color",
35
+ OpenEBooksWithTextNegative = "logo_openebooks_wtext_negative",
24
36
  QueensPublicLibraryColor = "logo_qpl_color",
37
+ QueensPublicLibraryBlack = "logo_qpl_black",
38
+ QueensPublicLibraryWhite = "logo_qpl_white",
25
39
  QueensPublicLibraryAltBlack = "logo_qpl_alt_black",
40
+ QueensPublicLibraryAltWhite = "logo_qpl_alt_white",
26
41
  SchomburgColor = "logo_schomburg_color",
42
+ SchomburgBlack = "logo_schomburg_black",
43
+ SchomburgWhite = "logo_schomburg_white",
27
44
  SchomburgCircleColor = "logo_schomburg_circle_color",
45
+ SchomburgCircleBlack = "logo_schomburg_circle_black",
46
+ SchomburgCircleWhite = "logo_schomburg_circle_white",
28
47
  SimplyEColor = "logo_simplye_color",
29
48
  SimplyEBlack = "logo_simplye_black",
49
+ SimplyEWhite = "logo_simplye_white",
30
50
  SNFLBlack = "logo_snfl_black",
31
51
  SNFLWhite = "logo_snfl_white",
52
+ TreasuresColor = "logo_treasures_color",
53
+ TreasuresColorNegative = "logo_treasures_color_negative",
32
54
  }
@@ -9,6 +9,7 @@ import { withDesign } from "storybook-addon-designs";
9
9
 
10
10
  import Icon from "../Icons/Icon";
11
11
  import { IconColors, IconNames } from "../Icons/IconTypes";
12
+ import Link from "../Link/Link";
12
13
  import Notification from "./Notification";
13
14
  import { NotificationTypes } from "./NotificationTypes";
14
15
  import { getCategory } from "../../utils/componentCategories";
@@ -44,6 +45,7 @@ export const enumValues = getStorybookEnumValues(
44
45
  noMargin: {
45
46
  table: { defaultValue: { summary: false } },
46
47
  },
48
+ notificationContent: { control: false },
47
49
  notificationType: {
48
50
  control: { type: "select" },
49
51
  table: { defaultValue: { summary: "NotificationTypes.Standard" } },
@@ -57,7 +59,7 @@ export const enumValues = getStorybookEnumValues(
57
59
  | Component Version | DS Version |
58
60
  | ----------------- | ---------- |
59
61
  | Added | `0.23.2` |
60
- | Latest | `0.25.9` |
62
+ | Latest | `0.25.12` |
61
63
 
62
64
  <Description of={Notification} />
63
65
 
@@ -72,6 +74,7 @@ within a parent element.
72
74
  <Story
73
75
  name="Notification with Controls"
74
76
  args={{
77
+ ariaLabel: "Notification label",
75
78
  centered: false,
76
79
  className: undefined,
77
80
  dismissible: false,
@@ -89,6 +92,7 @@ within a parent element.
89
92
  nisi erat porttitor ligula.
90
93
  </>
91
94
  ),
95
+ notificationType: "NotificationTypes.Standard",
92
96
  showIcon: true,
93
97
  }}
94
98
  >
@@ -105,6 +109,20 @@ within a parent element.
105
109
 
106
110
  <ArgsTable story="Notification with Controls" />
107
111
 
112
+ ## Accessibility
113
+
114
+ The `Notification` component renders with an HTML `aside` element as its wrapper.
115
+ This is an HTML landmark element that is similar to adding an attribute of
116
+ `role="complementary"`. For accessibility purposes, landmark elements should not
117
+ be rendered inside other landmark elements such as the `header` and `footer`
118
+ landmark elements. Adding a `Notification` component inside an HTML `main` landmark
119
+ element is acceptable.
120
+
121
+ Icons rendered in the `Notification` component are decorative by default which
122
+ means that they are hidden to screen readers. Since the "X" close icon inside the
123
+ dismissible button is decorative and because there is no discernible text inside
124
+ the button, an `aria-label` attribute is added to the button.
125
+
108
126
  ## Variants
109
127
 
110
128
  ### With NotificationHeading
@@ -253,6 +271,34 @@ The `Notification` icon can be hidden with the `showIcon` prop set to `false`.
253
271
  </DSProvider>
254
272
  </Canvas>
255
273
 
274
+ ### With HTML content
275
+
276
+ The `notificationContent` prop can accept HTML.
277
+
278
+ <Canvas>
279
+ <DSProvider>
280
+ <Notification
281
+ notificationHeading="Standard Notification with HTML content"
282
+ notificationContent={
283
+ <>
284
+ <p>
285
+ Cras mattis consectetur purus sit amet fermentum. Maecenas faucibus
286
+ mollis interdum.
287
+ </p>
288
+ <p>
289
+ Morbi leo risus, porta ac consectetur ac, vestibulum at eros.{" "}
290
+ <b>
291
+ Cum sociis natoque penatibus et magnis dis parturient montes,
292
+ nascetur ridiculus mus
293
+ </b>
294
+ . <Link href="#">This is a link</Link>.
295
+ </p>
296
+ </>
297
+ }
298
+ />
299
+ </DSProvider>
300
+ </Canvas>
301
+
256
302
  ## Custom Icon
257
303
 
258
304
  The default icon can be overridden by using the `icon` prop to pass a custom `Icon` component.
@@ -278,3 +324,29 @@ The default icon can be overridden by using the `icon` prop to pass a custom `Ic
278
324
  />
279
325
  </Story>
280
326
  </Canvas>
327
+
328
+ ## Dismissible
329
+
330
+ A dismissible `Notification` component can be created by setting the
331
+ `dismissible` prop to `true`. Once the "X" close icon on the upper right is
332
+ clicked, the `Notification` will be removed from the DOM, therefore it only
333
+ appears once.
334
+
335
+ <Canvas>
336
+ <Story name="Dismissible">
337
+ <Notification
338
+ dismissible
339
+ notificationHeading="Dismissible Notification"
340
+ notificationContent={
341
+ <>
342
+ This is a dismissible Notification with an X icon. Cras mattis
343
+ consectetur purus sit amet fermentum. Maecenas faucibus mollis
344
+ interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at
345
+ eros. Cum sociis natoque penatibus et magnis dis parturient montes,
346
+ nascetur ridiculus mus.
347
+ </>
348
+ }
349
+ notificationType={NotificationTypes.Announcement}
350
+ />
351
+ </Story>
352
+ </Canvas>
@@ -41,6 +41,18 @@ describe("Notification Accessibility", () => {
41
41
  );
42
42
  expect(await axe(container)).toHaveNoViolations();
43
43
  });
44
+
45
+ it("passes axe accessibility test for the dismissible type", async () => {
46
+ const { container } = render(
47
+ <Notification
48
+ dismissible
49
+ id="notificationID"
50
+ notificationContent={<>Notification content.</>}
51
+ notificationHeading="Notification Heading"
52
+ />
53
+ );
54
+ expect(await axe(container)).toHaveNoViolations();
55
+ });
44
56
  });
45
57
 
46
58
  describe("Notification", () => {
@@ -48,6 +60,7 @@ describe("Notification", () => {
48
60
  beforeEach(() => {
49
61
  utils = render(
50
62
  <Notification
63
+ ariaLabel="Notification label"
51
64
  id="notificationID"
52
65
  notificationContent={<>Notification content.</>}
53
66
  notificationHeading="Notification Heading"
@@ -64,8 +77,12 @@ describe("Notification", () => {
64
77
  });
65
78
 
66
79
  it("renders with an Icon", () => {
67
- // The Icon's role is "img".
68
- expect(screen.queryByRole("img")).toBeInTheDocument();
80
+ // Since the icon has aria-hidden set to true, we can't get it
81
+ // by its "img" role.
82
+ const icon = utils.container.querySelector(
83
+ "#notificationID-notification-icon"
84
+ );
85
+ expect(icon).toBeInTheDocument();
69
86
  });
70
87
 
71
88
  it("does not render an Icon", () => {
@@ -77,8 +94,10 @@ describe("Notification", () => {
77
94
  showIcon={false}
78
95
  />
79
96
  );
80
- // The Icon's role is "img".
81
- expect(screen.queryByRole("img")).not.toBeInTheDocument();
97
+ const icon = utils.container.querySelector(
98
+ "#notificationID-notification-icon"
99
+ );
100
+ expect(icon).not.toBeInTheDocument();
82
101
  });
83
102
 
84
103
  it("renders a custom Icon component", () => {
@@ -98,7 +117,11 @@ describe("Notification", () => {
98
117
  notificationHeading="Notification Heading"
99
118
  />
100
119
  );
101
- expect(utils.container.querySelector(".custom-icon")).toBeInTheDocument();
120
+
121
+ const customIcon = utils.container.querySelector(
122
+ "#notificationID-custom-notification-icon"
123
+ );
124
+ expect(customIcon).toBeInTheDocument();
102
125
  });
103
126
 
104
127
  it("renders the announcement Notification type", () => {
@@ -133,6 +156,31 @@ describe("Notification", () => {
133
156
  );
134
157
  });
135
158
 
159
+ it("renders with an aria-label attribute", () => {
160
+ expect(screen.getByRole("complementary")).toHaveAttribute(
161
+ "aria-label",
162
+ "Notification label"
163
+ );
164
+ });
165
+
166
+ it("renders a dismissible icon", () => {
167
+ utils.rerender(
168
+ <Notification
169
+ dismissible
170
+ id="notificationID"
171
+ notificationContent={<>Notification content.</>}
172
+ notificationHeading="Notification Heading"
173
+ notificationType={NotificationTypes.Standard}
174
+ />
175
+ );
176
+
177
+ const dismissibleIcon = utils.container.querySelector(
178
+ "#notificationID-dismissible-notification-icon"
179
+ );
180
+ expect(dismissibleIcon).toBeInTheDocument();
181
+ expect(screen.getByTitle("Notification close icon")).toBeInTheDocument();
182
+ });
183
+
136
184
  it("renders the UI snapshot correctly", () => {
137
185
  const standard = renderer
138
186
  .create(
@@ -190,11 +238,22 @@ describe("Notification", () => {
190
238
  />
191
239
  )
192
240
  .toJSON();
241
+ const dismissible = renderer
242
+ .create(
243
+ <Notification
244
+ dismissible
245
+ id="notificationID7"
246
+ notificationContent={<>Notification content.</>}
247
+ />
248
+ )
249
+ .toJSON();
250
+
193
251
  expect(standard).toMatchSnapshot();
194
252
  expect(announcement).toMatchSnapshot();
195
253
  expect(warning).toMatchSnapshot();
196
254
  expect(withoutHeading).toMatchSnapshot();
197
255
  expect(withoutAnIcon).toMatchSnapshot();
198
256
  expect(withoutHeadingAndIcon).toMatchSnapshot();
257
+ expect(dismissible).toMatchSnapshot();
199
258
  });
200
259
  });
@@ -30,6 +30,8 @@ type BasePropsWithoutAlignText = Omit<BaseProps, "alignText">;
30
30
  type BasePropsWithoutCentered = Omit<BaseProps, "centered">;
31
31
 
32
32
  export interface NotificationProps extends BasePropsWithoutAlignText {
33
+ /** Label used to describe the `Notification`'s aside HTML element. */
34
+ ariaLabel?: string;
33
35
  /** Additional `className` to add. */
34
36
  className?: string;
35
37
  /** Optional prop to control whether a `Notification` can be dismissed
@@ -99,6 +101,7 @@ export function NotificationContent(
99
101
  */
100
102
  export default function Notification(props: NotificationProps) {
101
103
  const {
104
+ ariaLabel,
102
105
  centered = false,
103
106
  className,
104
107
  dismissible = false,
@@ -114,15 +117,14 @@ export default function Notification(props: NotificationProps) {
114
117
  const handleClose = () => setIsOpen(false);
115
118
  const styles = useMultiStyleConfig("Notification", {
116
119
  centered,
120
+ dismissible,
117
121
  noMargin,
118
122
  notificationType,
119
- showIcon,
120
123
  });
121
124
  const iconElement = () => {
122
125
  const baseIconProps = {
123
- decorative: false,
124
- size: IconSizes.Large,
125
126
  additionalStyles: styles.icon,
127
+ size: IconSizes.Large,
126
128
  };
127
129
  // If the icon should not display, return null.
128
130
  if (!showIcon) {
@@ -136,16 +138,19 @@ export default function Notification(props: NotificationProps) {
136
138
  });
137
139
  const iconProps = {
138
140
  [NotificationTypes.Announcement]: {
139
- name: IconNames.SpeakerNotes,
140
141
  color: IconColors.SectionResearchSecondary,
142
+ name: IconNames.SpeakerNotes,
143
+ title: "Notification announcement icon",
141
144
  },
142
145
  [NotificationTypes.Standard]: {
143
- name: IconNames.AlertNotificationImportant,
144
146
  color: IconColors.UiBlack,
147
+ name: IconNames.AlertNotificationImportant,
148
+ title: "Notification standard icon",
145
149
  },
146
150
  [NotificationTypes.Warning]: {
147
- name: IconNames.ErrorFilled,
148
151
  color: IconColors.BrandPrimary,
152
+ name: IconNames.ErrorFilled,
153
+ title: "Notification warning icon",
149
154
  },
150
155
  };
151
156
  return (
@@ -158,15 +163,19 @@ export default function Notification(props: NotificationProps) {
158
163
  };
159
164
  const dismissibleButton = dismissible && (
160
165
  <Button
166
+ additionalStyles={styles.dismissibleButton}
167
+ attributes={{
168
+ "aria-label": "Close the notification",
169
+ }}
161
170
  buttonType={ButtonTypes.Link}
171
+ id={`${id}-notification-dismissible-button`}
162
172
  onClick={handleClose}
163
- additionalStyles={styles.dismissibleButton}
164
173
  >
165
174
  <Icon
166
- id={`${id}-notification-dismissible-icon`}
167
- decorative={false}
175
+ id={`${id}-dismissible-notification-icon`}
168
176
  name={IconNames.Close}
169
177
  size={IconSizes.Large}
178
+ title="Notification close icon"
170
179
  />
171
180
  </Button>
172
181
  );
@@ -199,11 +208,12 @@ export default function Notification(props: NotificationProps) {
199
208
  }
200
209
  return (
201
210
  <Box
211
+ aria-label={ariaLabel}
202
212
  as="aside"
203
- id={id}
204
213
  className={className}
205
- __css={styles}
206
214
  data-type={notificationType}
215
+ id={id}
216
+ __css={styles}
207
217
  >
208
218
  <Box __css={styles.container}>
209
219
  {childHeading}