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

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 (78) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/components/DatePicker/DatePicker.d.ts +1 -1
  3. package/dist/components/Fieldset/Fieldset.d.ts +1 -3
  4. package/dist/components/Form/Form.d.ts +13 -12
  5. package/dist/components/Form/FormTypes.d.ts +2 -2
  6. package/dist/components/HorizontalRule/HorizontalRule.d.ts +1 -1
  7. package/dist/components/RadioGroup/RadioGroup.d.ts +3 -3
  8. package/dist/components/SearchBar/SearchBar.d.ts +5 -5
  9. package/dist/components/Table/Table.d.ts +9 -3
  10. package/dist/components/Template/Template.d.ts +23 -4
  11. package/dist/design-system-react-components.cjs.development.js +197 -89
  12. package/dist/design-system-react-components.cjs.development.js.map +1 -1
  13. package/dist/design-system-react-components.cjs.production.min.js +1 -1
  14. package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
  15. package/dist/design-system-react-components.esm.js +186 -91
  16. package/dist/design-system-react-components.esm.js.map +1 -1
  17. package/dist/index.d.ts +4 -4
  18. package/dist/resources.scss +0 -2
  19. package/dist/theme/components/breadcrumb.d.ts +1 -1
  20. package/dist/theme/components/customTable.d.ts +12 -3
  21. package/package.json +40 -36
  22. package/src/components/Accordion/Accordion.stories.mdx +1 -1
  23. package/src/components/Accordion/Accordion.test.tsx +45 -1
  24. package/src/components/Accordion/Accordion.tsx +20 -8
  25. package/src/components/Accordion/__snapshots__/Accordion.test.tsx.snap +243 -0
  26. package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +13 -2
  27. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +15 -0
  28. package/src/components/Breadcrumbs/Breadcrumbs.tsx +9 -3
  29. package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +5 -5
  30. package/src/components/Card/Card.stories.mdx +1 -1
  31. package/src/components/Card/Card.tsx +4 -1
  32. package/src/components/Chakra/Flex.stories.mdx +113 -0
  33. package/src/components/DatePicker/DatePicker.stories.mdx +1 -1
  34. package/src/components/DatePicker/DatePicker.test.tsx +6 -6
  35. package/src/components/DatePicker/DatePicker.tsx +3 -4
  36. package/src/components/Fieldset/Fieldset.stories.mdx +1 -1
  37. package/src/components/Fieldset/Fieldset.tsx +2 -4
  38. package/src/components/Form/Form.stories.mdx +34 -16
  39. package/src/components/Form/Form.test.tsx +92 -3
  40. package/src/components/Form/Form.tsx +25 -21
  41. package/src/components/Form/FormTypes.tsx +2 -2
  42. package/src/components/Form/__snapshots__/Form.test.tsx.snap +0 -1
  43. package/src/components/Hero/Hero.stories.mdx +1 -1
  44. package/src/components/HorizontalRule/HorizontalRule.stories.mdx +3 -2
  45. package/src/components/HorizontalRule/HorizontalRule.tsx +2 -2
  46. package/src/components/HorizontalRule/__snapshots__/HorizontalRule.test.tsx.snap +4 -4
  47. package/src/components/List/List.stories.mdx +1 -1
  48. package/src/components/List/List.tsx +1 -1
  49. package/src/components/Pagination/Pagination.stories.mdx +1 -1
  50. package/src/components/Pagination/Pagination.tsx +2 -2
  51. package/src/components/Radio/__snapshots__/Radio.test.tsx.snap +5 -5
  52. package/src/components/RadioGroup/RadioGroup.stories.mdx +1 -1
  53. package/src/components/RadioGroup/RadioGroup.test.tsx +13 -11
  54. package/src/components/RadioGroup/RadioGroup.tsx +88 -89
  55. package/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap +18 -18
  56. package/src/components/SearchBar/SearchBar.Test.tsx +106 -28
  57. package/src/components/SearchBar/SearchBar.stories.mdx +7 -4
  58. package/src/components/SearchBar/SearchBar.tsx +19 -20
  59. package/src/components/Select/Select.test.tsx +89 -0
  60. package/src/components/Select/Select.tsx +7 -1
  61. package/src/components/Select/__snapshots__/Select.test.tsx.snap +545 -0
  62. package/src/components/Slider/__snapshots__/Slider.test.tsx.snap +7 -0
  63. package/src/components/Table/Table.stories.mdx +118 -19
  64. package/src/components/Table/Table.test.tsx +80 -3
  65. package/src/components/Table/Table.tsx +26 -16
  66. package/src/components/Table/__snapshots__/Table.test.tsx.snap +1179 -0
  67. package/src/components/Tabs/Tabs.stories.mdx +1 -1
  68. package/src/components/Tabs/Tabs.test.tsx +21 -5
  69. package/src/components/Tabs/Tabs.tsx +33 -18
  70. package/src/components/Tabs/__snapshots__/Tabs.test.tsx.snap +195 -0
  71. package/src/components/Template/Template.stories.mdx +79 -4
  72. package/src/components/Template/Template.test.tsx +65 -3
  73. package/src/components/Template/Template.tsx +58 -8
  74. package/src/components/Template/__snapshots__/Template.test.tsx.snap +93 -0
  75. package/src/index.ts +8 -2
  76. package/src/theme/components/breadcrumb.ts +1 -1
  77. package/src/theme/components/customTable.ts +16 -3
  78. package/src/utils/componentCategories.ts +1 -0
@@ -4,17 +4,13 @@ import {
4
4
  Canvas,
5
5
  ArgsTable,
6
6
  Description,
7
- } from "@storybook/addon-docs/blocks";
7
+ } from "@storybook/addon-docs";
8
8
  import { withDesign } from "storybook-addon-designs";
9
9
 
10
10
  import Table from "./Table";
11
11
  import DSProvider from "../../theme/provider";
12
12
  import { getCategory } from "../../utils/componentCategories";
13
13
 
14
- <Description of={Table} />
15
-
16
- The `Table` component is used to organize and display tabular data in rows and columns.
17
-
18
14
  <Meta
19
15
  title={getCategory("Table")}
20
16
  component={Table}
@@ -22,45 +18,148 @@ The `Table` component is used to organize and display tabular data in rows and c
22
18
  parameters={{
23
19
  design: {
24
20
  type: "figma",
25
- url:
26
- "https://www.figma.com/file/qShodlfNCJHb8n03IFyApM/Main?node-id=46780%3A27675",
21
+ url: "https://www.figma.com/file/qShodlfNCJHb8n03IFyApM/Main?node-id=46780%3A27675",
27
22
  },
28
23
  jest: ["Table.test.tsx"],
29
24
  }}
30
25
  argTypes={{
31
- columnHeaders: [],
26
+ columnHeaders: { control: { disable: true } },
32
27
  columnHeadersBackgroundColor: { control: { type: "color" } },
33
- columnHeadersTextColor: {control: {type: "color"}},
34
- id: {control: false},
28
+ columnHeadersTextColor: { control: { type: "color" } },
29
+ id: { control: false },
35
30
  tableData: { control: false },
36
31
  }}
37
32
  />
38
33
 
39
-
40
34
  # Table
41
35
 
42
36
  | Component Version | DS Version |
43
37
  | ----------------- | ---------- |
44
38
  | Added | `0.25.9` |
45
- | Latest | `0.25.9` |
39
+ | Latest | `0.25.10` |
46
40
 
47
41
  <Description of={Table} />
48
42
 
43
+ export const columnHeaders = [
44
+ "First Name",
45
+ "Last Name",
46
+ "Nick Name",
47
+ "Address1",
48
+ "City",
49
+ "State",
50
+ "Zipcode",
51
+ ];
52
+ export const tableData = [
53
+ ["Tom", "Nook", "Tanukichi", "Main Street", "New York", "NY", "23458"],
54
+ ["Isabelle", "-", "Shizue", "Walnut Street", "New York", "NY", "23458"],
55
+ ["K.K.", "Slider", "Totakeke", "Niper Place", "New York", "NY", "98765"],
56
+ [
57
+ "Sonny",
58
+ "Resetti",
59
+ "Risetto san",
60
+ "Village Road",
61
+ "New York",
62
+ "NY",
63
+ "09873",
64
+ ],
65
+ ];
66
+
49
67
  <Canvas withToolbar>
50
68
  <Story
51
69
  name="Table"
52
70
  args={{
53
- columnHeaders: ["First Name", "Last Name", "Nick Name", "Address1", "City", "Zipcode", "State"],
54
- tableData: [ ["Tom", "Nook", "Tanukichi", "Main Street", "New York", "23458", "NY" ], [ "Isabelle", "-", "Shizue", "Walnut Street", "New York", "23458", "NY"], [ "K.K.", "Slider", "Totakeke", "Niper Place", "New York", "98765", "NY"], [ "Sonny", "Resetti", "Risetto san", "Village Road", "New York", "09873", "NY" ], ],
55
- useRowHeaders: false,
71
+ className: undefined,
72
+ columnHeaders,
73
+ columnHeadersBackgroundColor: undefined,
74
+ columnHeadersTextColor: undefined,
75
+ id: undefined,
56
76
  showRowDividers: false,
77
+ tableData,
78
+ titleText: undefined,
79
+ useRowHeaders: false,
57
80
  }}
58
81
  >
59
- {(args) => (
60
- <Table {...args}>
61
- </Table>
62
- )}
82
+ {(args) => <Table {...args}></Table>}
63
83
  </Story>
64
84
  </Canvas>
65
85
 
66
86
  <ArgsTable story="Table" />
87
+
88
+ ## Accessibility
89
+
90
+ - The HTML for the `Table` element is structured with proper semantic use of the
91
+ `table`, `caption`, `thead`, `tbody`, `tr`, and `td` HTML elements.
92
+ - When titles are added through the `titleText` prop, the `caption` element will
93
+ be rendered on the page.
94
+ - The first row and/or the first cell in a `tr` row can be headers. Each `th`
95
+ header cell has an appropriate scope attribute set to either `scope="col"` or
96
+ `scope="row"`. For example, every `th` cell in a `thead` `tr` row will have
97
+ `scope="col"`. Every `th` cell in a `tbody` `tr` row will have `scope="row"`.
98
+ These headers are visually different from the data. Use the `useRowHeaders`
99
+ prop to render the first cell in every row as a header.
100
+
101
+ ## With a title
102
+
103
+ Use the `titleText` prop to add a title to the table.
104
+
105
+ <Canvas>
106
+ <DSProvider>
107
+ <Table
108
+ columnHeaders={columnHeaders}
109
+ id="title-table"
110
+ tableData={tableData}
111
+ titleText="Table with a title"
112
+ />
113
+ </DSProvider>
114
+ </Canvas>
115
+
116
+ ## With Row Dividers
117
+
118
+ Use the `showRowDividers` prop to render a divider between each row.
119
+
120
+ <Canvas>
121
+ <DSProvider>
122
+ <Table
123
+ columnHeaders={columnHeaders}
124
+ id="showRowDividers-table"
125
+ showRowDividers
126
+ tableData={tableData}
127
+ />
128
+ </DSProvider>
129
+ </Canvas>
130
+
131
+ ## With Row Headers
132
+
133
+ Use the `useRowHeaders` prop to render the first cell in every row as a header.
134
+ Notice that they turn bold.
135
+
136
+ <Canvas>
137
+ <DSProvider>
138
+ <Table
139
+ columnHeaders={columnHeaders}
140
+ id="rowHeaders-table"
141
+ tableData={tableData}
142
+ useRowHeaders
143
+ />
144
+ </DSProvider>
145
+ </Canvas>
146
+
147
+ ## With Custom Header Colors
148
+
149
+ It's possible to customize the header colors by using the `columnHeadersBackgroundColor`
150
+ and `columnHeadersTextColor` props. Note that the colors need to have sufficient
151
+ color contrast.
152
+
153
+ <Canvas>
154
+ <DSProvider>
155
+ <Table
156
+ columnHeaders={columnHeaders}
157
+ columnHeadersBackgroundColor="var(--nypl-colors-ui-link-secondary)"
158
+ columnHeadersTextColor="var(--nypl-colors-ui-white)"
159
+ id="rowHeaders-table"
160
+ showRowDividers
161
+ tableData={tableData}
162
+ useRowHeaders
163
+ />
164
+ </DSProvider>
165
+ </Canvas>
@@ -1,6 +1,8 @@
1
1
  import * as React from "react";
2
2
  import { render, screen } from "@testing-library/react";
3
3
  import { axe } from "jest-axe";
4
+ import renderer from "react-test-renderer";
5
+
4
6
  import Table from "./Table";
5
7
 
6
8
  export const columnHeaders = [
@@ -43,10 +45,30 @@ describe("Table Accessibility", () => {
43
45
  });
44
46
 
45
47
  describe("Table", () => {
46
- it("Renders table data", () => {
48
+ it("renders a caption", () => {
49
+ render(<Table tableData={tableData} titleText="this is the caption" />);
50
+ expect(screen.getByText("this is the caption")).toBeInTheDocument();
51
+ });
52
+
53
+ it("renders a table header", () => {
54
+ render(
55
+ <Table
56
+ columnHeaders={columnHeaders}
57
+ tableData={tableData}
58
+ titleText="this is the caption"
59
+ />
60
+ );
61
+
62
+ expect(screen.getByText("First Name")).toBeInTheDocument();
63
+ expect(screen.getByText("Last Name")).toBeInTheDocument();
64
+ expect(screen.getByText("Nick Name")).toBeInTheDocument();
65
+ });
66
+
67
+ it("renders table data", () => {
47
68
  render(<Table tableData={tableData} columnHeaders={columnHeaders} />);
69
+
48
70
  expect(screen.getByText("Tom")).toBeInTheDocument();
49
- expect(screen.getByText("First Name")).toBeInTheDocument();
71
+ expect(screen.getByText("Nook")).toBeInTheDocument();
50
72
  expect(screen.getByText("Village Road")).toBeInTheDocument();
51
73
  });
52
74
 
@@ -54,7 +76,62 @@ describe("Table", () => {
54
76
  const warn = jest.spyOn(console, "warn");
55
77
  render(<Table tableData={[]} />);
56
78
  expect(warn).toHaveBeenCalledWith(
57
- "Table data should be two dimensional array."
79
+ "Table: data should be two dimensional array."
58
80
  );
59
81
  });
82
+
83
+ it("renders the UI snapshot correctly", () => {
84
+ const basic = renderer
85
+ .create(<Table id="basic" tableData={tableData} />)
86
+ .toJSON();
87
+ const withCaption = renderer
88
+ .create(
89
+ <Table
90
+ id="withCaption"
91
+ tableData={tableData}
92
+ titleText="this is the caption"
93
+ />
94
+ )
95
+ .toJSON();
96
+ const withHeaders = renderer
97
+ .create(
98
+ <Table
99
+ columnHeaders={columnHeaders}
100
+ id="withHeaders"
101
+ tableData={tableData}
102
+ titleText="this is the caption"
103
+ />
104
+ )
105
+ .toJSON();
106
+ const withRowHeaders = renderer
107
+ .create(
108
+ <Table
109
+ columnHeaders={columnHeaders}
110
+ id="withHeaders"
111
+ tableData={tableData}
112
+ titleText="this is the caption"
113
+ useRowHeaders
114
+ />
115
+ )
116
+ .toJSON();
117
+ const withCustomHeaderColors = renderer
118
+ .create(
119
+ <Table
120
+ columnHeadersBackgroundColor="var(--nypl-colors-ui-link-primary)"
121
+ columnHeadersTextColor="var(--nypl-colors-ui-white)"
122
+ columnHeaders={columnHeaders}
123
+ id="withHeaders"
124
+ tableData={tableData}
125
+ titleText="this is the caption"
126
+ useRowHeaders
127
+ />
128
+ )
129
+ .toJSON();
130
+
131
+ expect(basic).toMatchSnapshot();
132
+ expect(withCaption).toMatchSnapshot();
133
+ expect(withHeaders).toMatchSnapshot();
134
+ expect(withRowHeaders).toMatchSnapshot();
135
+ expect(withCustomHeaderColors).toMatchSnapshot();
136
+ });
60
137
  });
@@ -1,12 +1,12 @@
1
1
  import * as React from "react";
2
2
  import {
3
3
  Table as ChakraTable,
4
- Thead as ChakraTHead,
4
+ TableCaption as ChakraTableCaption,
5
5
  Tbody as ChakraTbody,
6
- Tr as ChakraTr,
7
- Th as ChakraTh,
6
+ Thead as ChakraTHead,
8
7
  Td as ChakraTd,
9
- TableCaption as ChakraTableCaption,
8
+ Th as ChakraTh,
9
+ Tr as ChakraTr,
10
10
  useMultiStyleConfig,
11
11
  } from "@chakra-ui/react";
12
12
 
@@ -23,16 +23,22 @@ export interface TableProps {
23
23
  columnHeadersTextColor?: string;
24
24
  /** ID that other components can cross reference for accessibility purposes. */
25
25
  id?: string;
26
- /** If true, the first cell of each row in the `Table` component will be visually styled as a header. The default value is false */
27
- useRowHeaders?: boolean;
28
- /** If true, a border will be displayed between each row in the `Table` component. The default value is false. */
26
+ /** If true, a border will be displayed between each row in the `Table`
27
+ * component. The default value is false. */
29
28
  showRowDividers?: boolean;
30
29
  /** Two-dimensional array used to populate the table rows. */
31
30
  tableData: string[][];
32
31
  /** Displays `Table` title element. */
33
32
  titleText?: string;
33
+ /** If true, the first cell of each row in the `Table` component will be
34
+ * visually styled as a header. The default value is false */
35
+ useRowHeaders?: boolean;
34
36
  }
35
37
 
38
+ /**
39
+ * Basic `Table` component used to organize and display tabular data in
40
+ * rows and columns.
41
+ */
36
42
  function Table(props: React.PropsWithChildren<TableProps>) {
37
43
  const {
38
44
  className,
@@ -40,10 +46,10 @@ function Table(props: React.PropsWithChildren<TableProps>) {
40
46
  columnHeadersBackgroundColor,
41
47
  columnHeadersTextColor,
42
48
  id = generateUUID(),
43
- useRowHeaders = false,
44
49
  showRowDividers = false,
45
50
  tableData,
46
51
  titleText,
52
+ useRowHeaders = false,
47
53
  } = props;
48
54
 
49
55
  const customColors = {};
@@ -58,11 +64,15 @@ function Table(props: React.PropsWithChildren<TableProps>) {
58
64
  useRowHeaders,
59
65
  });
60
66
 
61
- const columnHeadersElems = columnHeaders && (
67
+ const tableCaption = titleText && (
68
+ <ChakraTableCaption>{titleText}</ChakraTableCaption>
69
+ );
70
+
71
+ const columnHeadersElems = columnHeaders?.length > 0 && (
62
72
  <ChakraTHead>
63
73
  <ChakraTr>
64
74
  {columnHeaders.map((child, key) => (
65
- <ChakraTh scope="col" key={key} sx={customColors}>
75
+ <ChakraTh key={key} scope="col" sx={customColors}>
66
76
  {child}
67
77
  </ChakraTh>
68
78
  ))}
@@ -70,14 +80,18 @@ function Table(props: React.PropsWithChildren<TableProps>) {
70
80
  </ChakraTHead>
71
81
  );
72
82
 
83
+ /**
84
+ * This renders a normal `tbody` DOM element structure if the `tableData`
85
+ * passed is a two-dimensional array. This is to render the appropriate
86
+ * row and column structure for a table.
87
+ */
73
88
  const tableBodyElems = () => {
74
- /** tableData value should be two dimensional array */
75
89
  if (
76
90
  !Array.isArray(tableData) ||
77
91
  tableData.length <= 0 ||
78
92
  tableData[0].constructor !== Array
79
93
  ) {
80
- console.warn(`Table data should be two dimensional array.`);
94
+ console.warn("Table: data should be two dimensional array.");
81
95
  return null;
82
96
  }
83
97
 
@@ -100,10 +114,6 @@ function Table(props: React.PropsWithChildren<TableProps>) {
100
114
  );
101
115
  };
102
116
 
103
- const tableCaption = titleText && (
104
- <ChakraTableCaption>{titleText}</ChakraTableCaption>
105
- );
106
-
107
117
  return (
108
118
  <ChakraTable id={id} sx={styles} className={className}>
109
119
  {tableCaption}