@sproutsocial/seeds-react-table 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/.eslintignore +6 -0
  2. package/.eslintrc.js +4 -0
  3. package/.turbo/turbo-build.log +53 -0
  4. package/CHANGELOG.md +7 -0
  5. package/dist/TableCell-B8GMRlv7.d.mts +13 -0
  6. package/dist/TableCell-CN71R1B5.d.ts +13 -0
  7. package/dist/TableCellTypes-Cp-8r7l1.d.mts +21 -0
  8. package/dist/TableCellTypes-Cp-8r7l1.d.ts +21 -0
  9. package/dist/TableHeaderCell-DnwlruQg.d.ts +12 -0
  10. package/dist/TableHeaderCell-DsJpGb2j.d.mts +12 -0
  11. package/dist/TableHeaderCellTypes-CH_zzW6X.d.ts +25 -0
  12. package/dist/TableHeaderCellTypes-CsJQBwu2.d.mts +25 -0
  13. package/dist/TableTypes-Dg7QrcGt.d.ts +37 -0
  14. package/dist/TableTypes-jS0O3bwQ.d.mts +37 -0
  15. package/dist/esm/chunk-67DCEN4G.js +140 -0
  16. package/dist/esm/chunk-67DCEN4G.js.map +1 -0
  17. package/dist/esm/chunk-XJMS6762.js +62 -0
  18. package/dist/esm/chunk-XJMS6762.js.map +1 -0
  19. package/dist/esm/index.js +106 -0
  20. package/dist/esm/index.js.map +1 -0
  21. package/dist/esm/tableCell.js +9 -0
  22. package/dist/esm/tableCell.js.map +1 -0
  23. package/dist/esm/tableHeaderCell.js +11 -0
  24. package/dist/esm/tableHeaderCell.js.map +1 -0
  25. package/dist/esm/tableRowAccordion.js +110 -0
  26. package/dist/esm/tableRowAccordion.js.map +1 -0
  27. package/dist/index.d.mts +32 -0
  28. package/dist/index.d.ts +32 -0
  29. package/dist/index.js +327 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/tableCell.d.mts +9 -0
  32. package/dist/tableCell.d.ts +9 -0
  33. package/dist/tableCell.js +98 -0
  34. package/dist/tableCell.js.map +1 -0
  35. package/dist/tableHeaderCell.d.mts +10 -0
  36. package/dist/tableHeaderCell.d.ts +10 -0
  37. package/dist/tableHeaderCell.js +177 -0
  38. package/dist/tableHeaderCell.js.map +1 -0
  39. package/dist/tableRowAccordion.d.mts +25 -0
  40. package/dist/tableRowAccordion.d.ts +25 -0
  41. package/dist/tableRowAccordion.js +200 -0
  42. package/dist/tableRowAccordion.js.map +1 -0
  43. package/jest.config.js +9 -0
  44. package/package.json +65 -0
  45. package/src/Table.stories.tsx +403 -0
  46. package/src/Table.tsx +111 -0
  47. package/src/TableCell/TableCell.stories.tsx +30 -0
  48. package/src/TableCell/TableCell.tsx +44 -0
  49. package/src/TableCell/TableCellTypes.ts +30 -0
  50. package/src/TableCell/__tests__/TabelCell.test.tsx +36 -0
  51. package/src/TableCell/__tests__/TableCell.typetest.tsx +34 -0
  52. package/src/TableCell/index.ts +5 -0
  53. package/src/TableCell/styles.ts +16 -0
  54. package/src/TableHeaderCell/TableHeaderCell.stories.tsx +46 -0
  55. package/src/TableHeaderCell/TableHeaderCell.tsx +120 -0
  56. package/src/TableHeaderCell/TableHeaderCellTypes.ts +26 -0
  57. package/src/TableHeaderCell/__tests__/TableHeaderCell.test.tsx +28 -0
  58. package/src/TableHeaderCell/__tests__/TableHeaderCell.typetest.tsx +31 -0
  59. package/src/TableHeaderCell/constants.ts +4 -0
  60. package/src/TableHeaderCell/index.ts +6 -0
  61. package/src/TableHeaderCell/styles.ts +46 -0
  62. package/src/TableRowAccordion/TableRowAccordion.stories.tsx +63 -0
  63. package/src/TableRowAccordion/TableRowAccordion.tsx +75 -0
  64. package/src/TableRowAccordion/TableRowAccordionTypes.ts +20 -0
  65. package/src/TableRowAccordion/__tests__/TableRowAccordion.test.tsx +104 -0
  66. package/src/TableRowAccordion/__tests__/TableRowAccordion.typetest.tsx +51 -0
  67. package/src/TableRowAccordion/index.ts +5 -0
  68. package/src/TableRowAccordion/styles.ts +25 -0
  69. package/src/TableTypes.ts +54 -0
  70. package/src/__tests__/Table.test.tsx +106 -0
  71. package/src/__tests__/Table.typetest.tsx +145 -0
  72. package/src/index.ts +5 -0
  73. package/src/styles.ts +21 -0
  74. package/styled.d.ts +7 -0
  75. package/tsconfig.json +9 -0
  76. package/tsup.config.ts +17 -0
@@ -0,0 +1,36 @@
1
+ import React from "react";
2
+ import { render, screen } from "@sproutsocial/seeds-react-testing-library";
3
+ import { TableCell } from "../TableCell";
4
+
5
+ describe("TableCell", () => {
6
+ it("should render properly", () => {
7
+ render(<TableCell id="stuff" content="more stuff here" />);
8
+ expect(
9
+ screen.getByDataQaLabel({
10
+ "table-cell": "",
11
+ })
12
+ ).toBeTruthy();
13
+ expect(screen.getByText("more stuff here")).toBeInTheDocument();
14
+ });
15
+
16
+ it("renders the children if present", () => {
17
+ render(<TableCell id="test">Child</TableCell>);
18
+ expect(screen.getByText("Child")).toBeInTheDocument();
19
+ });
20
+
21
+ it("renders as td when scope is not present", () => {
22
+ render(<TableCell id="scope-test" content="this is a td" />);
23
+ const tdElement = screen.getByRole("cell");
24
+ expect(tdElement).toBeInTheDocument();
25
+ expect(tdElement.tagName).toBe("TD");
26
+ expect(tdElement).not.toHaveAttribute("scope");
27
+ });
28
+
29
+ it("renders as th when scope is present", () => {
30
+ render(<TableCell id="scope-test" scope="row" content="this is a td" />);
31
+ const thElement = screen.getByRole("rowheader");
32
+ expect(thElement).toBeInTheDocument();
33
+ expect(thElement.tagName).toBe("TH");
34
+ expect(thElement).toHaveAttribute("scope", "row");
35
+ });
36
+ });
@@ -0,0 +1,34 @@
1
+ import * as React from "react";
2
+ import { TableCell } from "../TableCell";
3
+
4
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
5
+ function TableCellTypes() {
6
+ return (
7
+ <>
8
+ <TableCell
9
+ id="bacon_smokehouse"
10
+ content="🍔 Bacon Smokehouse Burger"
11
+ color="text.body"
12
+ />
13
+ <TableCell
14
+ id="bacon_smokehouse"
15
+ content="🍔 Bacon Smokehouse Burger"
16
+ color="text.body"
17
+ width={300}
18
+ colSpan={2}
19
+ align="center"
20
+ />
21
+ <TableCell
22
+ id="bacon_smokehouse"
23
+ content="🍔 Bacon Smokehouse Burger"
24
+ color="text.body"
25
+ width={300}
26
+ colSpan={2}
27
+ align="center"
28
+ scope="row"
29
+ />
30
+ {/* @ts-expect-error - test that missing required props is rejected */}
31
+ <TableCell />
32
+ </>
33
+ );
34
+ }
@@ -0,0 +1,5 @@
1
+ import TableCell from "./TableCell";
2
+
3
+ export default TableCell;
4
+ export { TableCell };
5
+ export * from "./TableCellTypes";
@@ -0,0 +1,16 @@
1
+ import styled from "styled-components";
2
+ import { COMMON } from "@sproutsocial/seeds-react-system-props";
3
+ import type { TypeTableCellProps } from "./TableCellTypes";
4
+
5
+ const Container = styled.td<{
6
+ alignment: TypeTableCellProps["align"];
7
+ }>`
8
+ ${(props) => props.theme.typography[200]}
9
+ font-weight: ${(props) => props.theme.fontWeights.normal};
10
+ padding: ${(props) => props.theme.space[300]};
11
+ text-align: ${(props) => props.alignment};
12
+
13
+ ${COMMON}
14
+ `;
15
+
16
+ export default Container;
@@ -0,0 +1,46 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { TableHeaderCell } from "./TableHeaderCell";
4
+
5
+ const meta: Meta<typeof TableHeaderCell> = {
6
+ title: "Components/Table/TableHeaderCell",
7
+ component: TableHeaderCell,
8
+ argTypes: {
9
+ isSortable: {
10
+ control: "boolean",
11
+ },
12
+ },
13
+ args: {
14
+ content: "Food Item",
15
+ id: "1",
16
+ isSortable: undefined,
17
+ align: undefined,
18
+ width: undefined,
19
+ },
20
+ };
21
+ export default meta;
22
+
23
+ type Story = StoryObj<typeof TableHeaderCell>;
24
+
25
+ export const Default: Story = {
26
+ args: {
27
+ color: "text.headline",
28
+ },
29
+ };
30
+
31
+ export const Sortable: Story = {
32
+ args: {
33
+ ...Default.args,
34
+ isSortable: true,
35
+ },
36
+ };
37
+
38
+ export const AdditionalProps: Story = {
39
+ args: {
40
+ ...Sortable.args,
41
+ content: "Calories",
42
+ id: "2",
43
+ align: "center",
44
+ width: 100,
45
+ },
46
+ };
@@ -0,0 +1,120 @@
1
+ import * as React from "react";
2
+ import Icon, { type TypeIconName } from "@sproutsocial/seeds-react-icon";
3
+ import Container, { SortIcon, UnstyledButton } from "./styles";
4
+ import { SORT_DIRECTIONS } from "./constants";
5
+ import type { TypeTableHeaderCellProps } from "./TableHeaderCellTypes";
6
+
7
+ export class TableHeaderCell extends React.Component<TypeTableHeaderCellProps> {
8
+ static displayName: string;
9
+
10
+ getSortIcon = (
11
+ isSorted: boolean,
12
+ ariaSortDirection: "ascending" | "descending" | undefined
13
+ ) => {
14
+ const { sortDirection } = this.props;
15
+ let iconName: TypeIconName = "caret-up-down-outline";
16
+
17
+ if (isSorted && sortDirection === SORT_DIRECTIONS.ASC) {
18
+ iconName = "caret-up-solid";
19
+ } else if (isSorted && sortDirection === SORT_DIRECTIONS.DESC) {
20
+ iconName = "caret-down-solid";
21
+ }
22
+
23
+ return (
24
+ <SortIcon>
25
+ <Icon size="mini" name={iconName} aria-label={ariaSortDirection} />
26
+ </SortIcon>
27
+ );
28
+ };
29
+
30
+ // @ts-note: If this is set to an HTMLButtonElement event, then the `Container` freaks out
31
+ handleClick = (
32
+ e: React.MouseEvent<HTMLTableCellElement | HTMLButtonElement>
33
+ ) => {
34
+ const { onClick, onSort, isSortable, id } = this.props;
35
+
36
+ if (onClick || isSortable) {
37
+ e.preventDefault();
38
+ }
39
+
40
+ if (onClick) {
41
+ // @ts-note: Right now the `onClick` is incorrectly set to consume an HTMLButtonElement event
42
+ onClick(e as unknown as React.MouseEvent<HTMLButtonElement>);
43
+ return;
44
+ }
45
+
46
+ if (!isSortable || !onSort) return;
47
+ onSort(id);
48
+ };
49
+
50
+ override render() {
51
+ const {
52
+ id,
53
+ content,
54
+ colSpan,
55
+ width,
56
+ align,
57
+ isSortable,
58
+ sortId,
59
+ sortDirection,
60
+ children,
61
+ /* eslint-disable @typescript-eslint/no-unused-vars */
62
+ shouldTruncate,
63
+ onSort,
64
+ onClick,
65
+ /* eslint-enable @typescript-eslint/no-unused-vars */
66
+ color,
67
+ ...rest
68
+ } = this.props;
69
+
70
+ const isSorted = sortId === id;
71
+ const ariaSort = isSorted
72
+ ? sortDirection === SORT_DIRECTIONS.ASC
73
+ ? "ascending"
74
+ : "descending"
75
+ : undefined;
76
+
77
+ const buttonProps = isSortable
78
+ ? {
79
+ role: "button",
80
+ onClick: this.handleClick,
81
+ }
82
+ : {};
83
+
84
+ const scope = colSpan ? "colgroup" : "col";
85
+
86
+ return (
87
+ <Container
88
+ {...rest}
89
+ key={id}
90
+ alignment={align || "left"}
91
+ sortable={isSortable}
92
+ colSpan={colSpan}
93
+ scope={scope}
94
+ width={width}
95
+ onClick={this.handleClick}
96
+ data-tableheadercell-sortable={isSortable}
97
+ data-qa-table-header-cell=""
98
+ data-qa-table-header-cell-sortdirection={sortDirection}
99
+ // TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.
100
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
101
+ // @ts-ignore
102
+ color={color}
103
+ aria-sort={ariaSort}
104
+ >
105
+ {isSortable ? (
106
+ <UnstyledButton {...buttonProps}>
107
+ <div aria-live="polite" role="status">
108
+ {children || content}
109
+ {!children && this.getSortIcon(id === sortId, ariaSort)}
110
+ </div>
111
+ </UnstyledButton>
112
+ ) : (
113
+ children || content
114
+ )}
115
+ </Container>
116
+ );
117
+ }
118
+ }
119
+
120
+ export default TableHeaderCell;
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ import type { TypeTableCellProps } from "../TableCell/TableCellTypes";
3
+ import { SORT_DIRECTIONS } from "./constants";
4
+
5
+ export type TypeEnumSortDirections = keyof typeof SORT_DIRECTIONS;
6
+
7
+ export interface TypeTableHeaderCellProps
8
+ extends Omit<TypeTableCellProps, "onClick"> {
9
+ /** Legacy Deteremines if a table column is sortable (optional) */
10
+ isSortable?: boolean;
11
+
12
+ /** Truncates text into a singular line with ellipsis (optional) */
13
+ shouldTruncate?: boolean;
14
+
15
+ /** Legacy: Callback for Sorting Table Columns (optional) */
16
+ onSort?: (id: string) => void;
17
+
18
+ /** Legacy: Controls which column is being sorted (optional) */
19
+ sortId?: string;
20
+
21
+ /** Legacy: Controls the current sort direction (optional) */
22
+ sortDirection?: TypeEnumSortDirections;
23
+
24
+ /** Callback for Click Events. If Included will override onSort prop */
25
+ onClick?: (e: React.SyntheticEvent<HTMLButtonElement>) => void;
26
+ }
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { render, screen } from "@sproutsocial/seeds-react-testing-library";
3
+ import { TableHeaderCell } from "../TableHeaderCell";
4
+ describe("TableHeaderCell", () => {
5
+ it("should render properly", () => {
6
+ render(
7
+ <table>
8
+ <TableHeaderCell id="test" content="more stuff here" />
9
+ </table>
10
+ );
11
+ expect(
12
+ screen.getByDataQaLabel({
13
+ "table-header-cell": "",
14
+ })
15
+ ).toBeTruthy();
16
+ expect(screen.getByText("more stuff here")).toBeInTheDocument();
17
+ });
18
+ it("renders the children if present", () => {
19
+ render(
20
+ <table>
21
+ <TableHeaderCell id="test" content="content">
22
+ Child
23
+ </TableHeaderCell>
24
+ </table>
25
+ );
26
+ expect(screen.getByText("Child")).toBeInTheDocument();
27
+ });
28
+ });
@@ -0,0 +1,31 @@
1
+ import * as React from "react";
2
+ import { TableHeaderCell } from "../TableHeaderCell";
3
+
4
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
5
+ function TableHeaderCellTypes() {
6
+ const defaultProps = {
7
+ content: "Food Item",
8
+ id: "1",
9
+ color: "text.headline",
10
+ isSortable: undefined,
11
+ align: undefined,
12
+ width: undefined,
13
+ };
14
+
15
+ return (
16
+ <>
17
+ <TableHeaderCell {...defaultProps} />
18
+ <TableHeaderCell {...defaultProps} isSortable />
19
+ <TableHeaderCell
20
+ {...defaultProps}
21
+ isSortable
22
+ content="Calories"
23
+ id="2"
24
+ align="center"
25
+ width={100}
26
+ />
27
+ {/* @ts-expect-error - test that missing required props is rejected */}
28
+ <TableHeaderCell />
29
+ </>
30
+ );
31
+ }
@@ -0,0 +1,4 @@
1
+ export const SORT_DIRECTIONS = {
2
+ ASC: "ASC",
3
+ DESC: "DESC",
4
+ } as const;
@@ -0,0 +1,6 @@
1
+ import TableHeaderCell from "./TableHeaderCell";
2
+
3
+ export default TableHeaderCell;
4
+ export { TableHeaderCell };
5
+ export * from "./TableHeaderCellTypes";
6
+ export * from "./constants";
@@ -0,0 +1,46 @@
1
+ import styled, { css } from "styled-components";
2
+ import { COMMON } from "@sproutsocial/seeds-react-system-props";
3
+ import type { TypeTableHeaderCellProps } from "./TableHeaderCellTypes";
4
+
5
+ const Container = styled.th<{
6
+ sortable?: boolean;
7
+ alignment: TypeTableHeaderCellProps["align"];
8
+ width: TypeTableHeaderCellProps["width"];
9
+ }>`
10
+ ${(props) => props.theme.typography[100]}
11
+ font-weight: ${(props) => props.theme.fontWeights.semibold};
12
+ padding: ${(props) => props.theme.space[300]};
13
+ text-align: ${(props) => props.alignment};
14
+
15
+ ${(props) =>
16
+ props.sortable &&
17
+ css`
18
+ position: relative;
19
+ cursor: pointer;
20
+ `}
21
+
22
+ ${COMMON}
23
+ `;
24
+
25
+ export const SortIcon = styled.span`
26
+ position: absolute;
27
+ top: 50%;
28
+ transform: translateY(-50%);
29
+ font-size: 0;
30
+ padding: 0 ${(props) => props.theme.space[200]};
31
+ `;
32
+
33
+ export const UnstyledButton = styled.button`
34
+ background: none;
35
+ border: none;
36
+ color: inherit;
37
+ font: inherit;
38
+ line-height: normal;
39
+ overflow: visible;
40
+ padding: 0;
41
+ -webkit-appearance: none;
42
+ -moz-appearance: none;
43
+ cursor: pointer;
44
+ `;
45
+
46
+ export default Container;
@@ -0,0 +1,63 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import TableRowAccordion from "./TableRowAccordion";
4
+
5
+ const meta: Meta<typeof TableRowAccordion> = {
6
+ title: "Components/Table/TableRowAccordion",
7
+ component: TableRowAccordion,
8
+ };
9
+ export default meta;
10
+
11
+ type Story = StoryObj<typeof TableRowAccordion>;
12
+
13
+ export const Collapsed: Story = {
14
+ args: {
15
+ id: "1",
16
+ cells: [
17
+ {
18
+ id: "1",
19
+ content: "🍔 Bacon Smokehouse Burger",
20
+ },
21
+ {
22
+ id: "2",
23
+ content: "840",
24
+ },
25
+ {
26
+ id: "3",
27
+ content: "45g",
28
+ },
29
+ {
30
+ id: "4",
31
+ content: "62g",
32
+ },
33
+ {
34
+ id: "5",
35
+ content: "46g",
36
+ },
37
+ ],
38
+ isExpanded: false,
39
+ onToggle: () => {},
40
+ detail: (
41
+ <img
42
+ src="//i.kym-cdn.com/entries/icons/mobile/000/013/564/doge.jpg"
43
+ alt="doge"
44
+ />
45
+ ),
46
+ },
47
+ };
48
+
49
+ export const Expanded: Story = {
50
+ args: {
51
+ ...Collapsed.args,
52
+ isExpanded: true,
53
+ },
54
+ };
55
+
56
+ export const WithToggleFunction: Story = {
57
+ args: {
58
+ ...Collapsed.args,
59
+ onToggle: (id) => {
60
+ alert(`clicked with id ${id}`);
61
+ },
62
+ },
63
+ };
@@ -0,0 +1,75 @@
1
+ import * as React from "react";
2
+ import Icon from "@sproutsocial/seeds-react-icon";
3
+ import TableCell from "../TableCell";
4
+ import Container, { Detail, Trigger } from "./styles";
5
+ import type { TypeTableRowAccordionProps } from "./TableRowAccordionTypes";
6
+
7
+ /**
8
+ * The table row accordion component allows for rendering a row of tabular data along with a addtional content to be rendered inside of an accordion drawer. This component is meant to be used with the table components rowRender mentod.
9
+ */
10
+ export default class TableRowAccordion extends React.Component<TypeTableRowAccordionProps> {
11
+ handleToggle: React.MouseEventHandler<HTMLTableRowElement> = (e) => {
12
+ const { onToggle, id } = this.props;
13
+ e.stopPropagation();
14
+
15
+ if (onToggle) {
16
+ onToggle(id);
17
+ }
18
+ };
19
+
20
+ override render() {
21
+ const {
22
+ id,
23
+ cells,
24
+ detail,
25
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
26
+ onToggle,
27
+ isExpanded,
28
+ color,
29
+ ...rest
30
+ } = this.props;
31
+
32
+ return (
33
+ <Container
34
+ {...rest}
35
+ data-qa-table-row-accordion={isExpanded}
36
+ key={id}
37
+ // TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.
38
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
39
+ // @ts-ignore
40
+ color={color}
41
+ >
42
+ <tr data-tablerowaccordion-summary onClick={this.handleToggle}>
43
+ {cells.map((td) => {
44
+ return <TableCell {...td} key={td.id} />;
45
+ })}
46
+ <TableCell
47
+ id="tableRowAccordion_trigger"
48
+ content={
49
+ // TODO: This trigger needs an accessible label passed in via props
50
+ <Trigger
51
+ data-tablerowaccordion-trigger
52
+ onClick={this.handleToggle}
53
+ role="button"
54
+ >
55
+ <Icon
56
+ name={
57
+ isExpanded ? "chevron-up-outline" : "chevron-down-outline"
58
+ }
59
+ aria-hidden
60
+ />
61
+ </Trigger>
62
+ }
63
+ />
64
+ </tr>
65
+ <Detail isExpanded={isExpanded} data-tablerowaccordion-detail>
66
+ <TableCell
67
+ id="tableRowAccordion_detail"
68
+ colSpan={100}
69
+ content={detail}
70
+ />
71
+ </Detail>
72
+ </Container>
73
+ );
74
+ }
75
+ }
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ import type { TypeSystemCommonProps } from "@sproutsocial/seeds-react-system-props";
3
+ import type { TypeTableRow } from "../TableTypes";
4
+
5
+ export interface TypeTableRowAccordionProps
6
+ extends TypeTableRow,
7
+ TypeSystemCommonProps,
8
+ Omit<
9
+ React.ComponentPropsWithoutRef<"tbody">,
10
+ keyof TypeTableRow | keyof TypeSystemCommonProps
11
+ > {
12
+ /** Content to be rendered in accordion drawer */
13
+ detail: React.ReactNode;
14
+
15
+ /** Controls the display state of the accordion drawer */
16
+ isExpanded: boolean;
17
+
18
+ /** Callback for toggling the accordion drawer state */
19
+ onToggle: (id: string) => void;
20
+ }
@@ -0,0 +1,104 @@
1
+ import React from "react";
2
+ import {
3
+ render,
4
+ fireEvent,
5
+ screen,
6
+ } from "@sproutsocial/seeds-react-testing-library";
7
+ import TableRowAccordion from "../TableRowAccordion";
8
+
9
+ describe("TableRowAccordion", () => {
10
+ const props = {
11
+ id: "bacon_smokehouse_burger_row",
12
+ cells: [
13
+ {
14
+ id: "cell_1",
15
+ content: "🍔 Bacon Smokehouse Burger",
16
+ },
17
+ {
18
+ id: "cell_2",
19
+ content: "840",
20
+ },
21
+ {
22
+ id: "cell_3",
23
+ content: "45g",
24
+ },
25
+ {
26
+ id: "cell_4",
27
+ content: "62g",
28
+ },
29
+ {
30
+ id: "cell_5",
31
+ content: "46g",
32
+ },
33
+ ],
34
+ detail: (
35
+ <img
36
+ src="//i.kym-cdn.com/entries/icons/mobile/000/013/564/doge.jpg"
37
+ alt="doge"
38
+ />
39
+ ),
40
+ isExpanded: false,
41
+ onToggle: jest.fn(),
42
+ };
43
+
44
+ it("should render the table cells RTL", () => {
45
+ render(
46
+ <table>
47
+ <TableRowAccordion {...props} />
48
+ </table>
49
+ );
50
+
51
+ // we should get back a length that is one greater than length of cells we pass due to the addition of the trigger cell and detail cell
52
+ expect(
53
+ screen.getAllByDataQaLabel({
54
+ "table-cell": "",
55
+ })
56
+ ).toBeTruthy();
57
+
58
+ expect(
59
+ screen.getAllByDataQaLabel({
60
+ "table-cell": "",
61
+ }).length
62
+ ).toEqual(props.cells.length + 2);
63
+ });
64
+
65
+ it("should render the detail section closed by default", () => {
66
+ render(
67
+ <table>
68
+ <TableRowAccordion {...props} />
69
+ </table>
70
+ );
71
+
72
+ expect(
73
+ screen.getAllByDataQaLabel({
74
+ "table-row-accordion": "false",
75
+ })
76
+ ).toBeTruthy();
77
+ });
78
+
79
+ it("should render the detail section open when the isExpanded prop is set to true", () => {
80
+ render(
81
+ <table>
82
+ <TableRowAccordion {...props} isExpanded={true} />
83
+ </table>
84
+ );
85
+
86
+ expect(
87
+ screen.getAllByDataQaLabel({
88
+ "table-row-accordion": "true",
89
+ })
90
+ ).toBeTruthy();
91
+ });
92
+
93
+ it("the onToggle method should return the rows id when clicked", () => {
94
+ const callback = jest.fn();
95
+ render(
96
+ <table>
97
+ <TableRowAccordion {...props} onToggle={callback} />
98
+ </table>
99
+ );
100
+
101
+ fireEvent.click(screen.getByRole("button"));
102
+ expect(callback).toBeCalledWith(props.id);
103
+ });
104
+ });