@purpurds/table 8.5.2 → 8.7.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.
- package/dist/LICENSE.txt +16 -16
- package/dist/styles.css +1 -1
- package/dist/table-content.d.ts +16 -27
- package/dist/table-content.d.ts.map +1 -1
- package/dist/table-settings-drawer.d.ts +4 -1
- package/dist/table-settings-drawer.d.ts.map +1 -1
- package/dist/table.cjs.js +65 -65
- package/dist/table.cjs.js.map +1 -1
- package/dist/table.d.ts.map +1 -1
- package/dist/table.es.js +3320 -3407
- package/dist/table.es.js.map +1 -1
- package/dist/test-utils/helpers.d.ts +39 -0
- package/dist/test-utils/helpers.d.ts.map +1 -1
- package/package.json +23 -23
- package/src/cell-types/date-cell.tsx +1 -1
- package/src/table-content-drag.test.tsx +43 -430
- package/src/table-content.tsx +62 -118
- package/src/table-settings-drawer.module.scss +1 -1
- package/src/table-settings-drawer.test.tsx +62 -0
- package/src/table-settings-drawer.tsx +17 -7
- package/src/table.stories.tsx +16 -1
- package/src/table.tsx +91 -135
- package/src/test-utils/helpers.ts +40 -0
|
@@ -108,6 +108,45 @@ export declare const copy: {
|
|
|
108
108
|
description: string;
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
|
+
settingsDrawerWithColumnDrag: {
|
|
112
|
+
buttons: {
|
|
113
|
+
closeDrawer: string;
|
|
114
|
+
resetSettings: string;
|
|
115
|
+
};
|
|
116
|
+
generalSettings: {
|
|
117
|
+
header: string;
|
|
118
|
+
toggles: {
|
|
119
|
+
lockFirstcolumn: string;
|
|
120
|
+
showFilters: string;
|
|
121
|
+
stickyHeader: string;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
title: string;
|
|
125
|
+
visibleColumns: {
|
|
126
|
+
header: string;
|
|
127
|
+
description: string;
|
|
128
|
+
rearrangeDescription: string;
|
|
129
|
+
buttons: {
|
|
130
|
+
rearrange: string;
|
|
131
|
+
done: string;
|
|
132
|
+
};
|
|
133
|
+
ariaLabels: {
|
|
134
|
+
dragHandle: {
|
|
135
|
+
action: string;
|
|
136
|
+
instructions: string;
|
|
137
|
+
};
|
|
138
|
+
arrowButtons: {
|
|
139
|
+
move: string;
|
|
140
|
+
up: string;
|
|
141
|
+
down: string;
|
|
142
|
+
};
|
|
143
|
+
buttons: {
|
|
144
|
+
rearrange: string;
|
|
145
|
+
done: string;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
};
|
|
111
150
|
sortingAriaLabels: {
|
|
112
151
|
asc: string;
|
|
113
152
|
default: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/test-utils/helpers.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,GAAI,OAAO,WAAW,KAAG,WAIjD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,WAAW,KAAG,WAIjD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,OAAO,WAAW,EAClB,cAAc,MAAM,KACnB,WAKF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,gBAAgB,EACvB,OAAO,MAAM,EACb,cAAc,MAAM,KACnB,oBAQF,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,gBAAgB,EAAE,cAAS,KAAG,mBAEpE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,gBAAgB,EAAE,OAAO,MAAM,KAAG,mBAExE,CAAC;AAGF,eAAO,MAAM,0BAA0B,GACrC,OAAO,gBAAgB,EACvB,OAAO,MAAM,KACZ,iBAEF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,OAAO,gBAAgB,EACvB,OAAO,MAAM,KACZ,iBAEF,CAAC;AAGF,eAAO,MAAM,4BAA4B,GACvC,OAAO,gBAAgB,EACvB,cAAS,KACR,iBAEF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,OAAO,gBAAgB,EAAE,QAAQ,MAAM,gBAG9E,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,OAAO,gBAAgB,EACvB,QAAQ,MAAM,EACd,aAAa,MAAM,kBAOpB,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,OAAO,gBAAgB,EAAE,QAAQ,MAAM,gBAGjF,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,OAAO,gBAAgB,EACvB,QAAQ,MAAM,EACd,aAAa,MAAM,kBAIpB,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCA6CQ,MAAM;;;CAGnC,CAAC;AAEF,eAAO,MAAM,IAAI
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/test-utils/helpers.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,GAAI,OAAO,WAAW,KAAG,WAIjD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,WAAW,KAAG,WAIjD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,OAAO,WAAW,EAClB,cAAc,MAAM,KACnB,WAKF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,gBAAgB,EACvB,OAAO,MAAM,EACb,cAAc,MAAM,KACnB,oBAQF,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,gBAAgB,EAAE,cAAS,KAAG,mBAEpE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,gBAAgB,EAAE,OAAO,MAAM,KAAG,mBAExE,CAAC;AAGF,eAAO,MAAM,0BAA0B,GACrC,OAAO,gBAAgB,EACvB,OAAO,MAAM,KACZ,iBAEF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,OAAO,gBAAgB,EACvB,OAAO,MAAM,KACZ,iBAEF,CAAC;AAGF,eAAO,MAAM,4BAA4B,GACvC,OAAO,gBAAgB,EACvB,cAAS,KACR,iBAEF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,OAAO,gBAAgB,EAAE,QAAQ,MAAM,gBAG9E,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,OAAO,gBAAgB,EACvB,QAAQ,MAAM,EACd,aAAa,MAAM,kBAOpB,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,OAAO,gBAAgB,EAAE,QAAQ,MAAM,gBAGjF,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,OAAO,gBAAgB,EACvB,QAAQ,MAAM,EACd,aAAa,MAAM,kBAIpB,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCA6CQ,MAAM;;;CAGnC,CAAC;AAEF,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqHhB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@purpurds/table",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.0",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"main": "./dist/table.cjs.js",
|
|
6
6
|
"types": "./dist/table.d.ts",
|
|
@@ -21,22 +21,22 @@
|
|
|
21
21
|
"@dnd-kit/utilities": "~3.2.2",
|
|
22
22
|
"@tanstack/react-table": "~8.21.2",
|
|
23
23
|
"classnames": "~2.5.0",
|
|
24
|
-
"@purpurds/
|
|
25
|
-
"@purpurds/
|
|
26
|
-
"@purpurds/
|
|
27
|
-
"@purpurds/
|
|
28
|
-
"@purpurds/
|
|
29
|
-
"@purpurds/
|
|
30
|
-
"@purpurds/
|
|
31
|
-
"@purpurds/link": "8.
|
|
32
|
-
"@purpurds/
|
|
33
|
-
"@purpurds/
|
|
34
|
-
"@purpurds/
|
|
35
|
-
"@purpurds/
|
|
36
|
-
"@purpurds/
|
|
37
|
-
"@purpurds/
|
|
38
|
-
"@purpurds/
|
|
39
|
-
"@purpurds/
|
|
24
|
+
"@purpurds/badge": "8.7.0",
|
|
25
|
+
"@purpurds/button": "8.7.0",
|
|
26
|
+
"@purpurds/cta-link": "8.7.0",
|
|
27
|
+
"@purpurds/drawer": "8.7.0",
|
|
28
|
+
"@purpurds/heading": "8.7.0",
|
|
29
|
+
"@purpurds/icon": "8.7.0",
|
|
30
|
+
"@purpurds/paragraph": "8.7.0",
|
|
31
|
+
"@purpurds/link": "8.7.0",
|
|
32
|
+
"@purpurds/select": "8.7.0",
|
|
33
|
+
"@purpurds/skeleton": "8.7.0",
|
|
34
|
+
"@purpurds/text-field": "8.7.0",
|
|
35
|
+
"@purpurds/checkbox": "8.7.0",
|
|
36
|
+
"@purpurds/visually-hidden": "8.7.0",
|
|
37
|
+
"@purpurds/tooltip": "8.7.0",
|
|
38
|
+
"@purpurds/tokens": "8.7.0",
|
|
39
|
+
"@purpurds/toggle": "8.7.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@rushstack/eslint-patch": "~1.10.0",
|
|
@@ -60,13 +60,13 @@
|
|
|
60
60
|
"vitest-axe": "~0.1.0",
|
|
61
61
|
"vitest-canvas-mock": "~0.3.3",
|
|
62
62
|
"vitest": "^3.1.2",
|
|
63
|
-
"@purpurds/autocomplete": "8.
|
|
63
|
+
"@purpurds/autocomplete": "8.7.0",
|
|
64
64
|
"@purpurds/component-rig": "1.0.0",
|
|
65
|
-
"@purpurds/
|
|
66
|
-
"@purpurds/
|
|
67
|
-
"@purpurds/listbox": "8.
|
|
68
|
-
"@purpurds/
|
|
69
|
-
"@purpurds/
|
|
65
|
+
"@purpurds/label": "8.7.0",
|
|
66
|
+
"@purpurds/illustrative-icon": "8.7.0",
|
|
67
|
+
"@purpurds/listbox": "8.7.0",
|
|
68
|
+
"@purpurds/grid": "8.7.0",
|
|
69
|
+
"@purpurds/pagination": "8.7.0"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build:dev": "vite",
|
|
@@ -18,7 +18,7 @@ export const DateCell = <TData extends RowData>({ cell }: DateCellProps<TData>)
|
|
|
18
18
|
return <EmptyCell />;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const showTime = cell.column.columnDef.meta?.showTime
|
|
21
|
+
const showTime = cell.column.columnDef.meta?.showTime ?? true;
|
|
22
22
|
|
|
23
23
|
const dateObj = new Date(dateString);
|
|
24
24
|
const date = dateObj.toLocaleDateString("sv-SE");
|
|
@@ -2,14 +2,12 @@ import React from "react";
|
|
|
2
2
|
import { render, screen } from "@testing-library/react";
|
|
3
3
|
import { axe } from "vitest-axe";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { TableContent } from "./table-content";
|
|
6
6
|
|
|
7
|
-
// Mock tanstack table
|
|
8
7
|
const mockTanstackTable = {
|
|
9
8
|
getVisibleLeafColumns: vi.fn(() => [{ id: "col1" }, { id: "col2" }]),
|
|
10
|
-
} as unknown as Parameters<typeof
|
|
9
|
+
} as unknown as Parameters<typeof TableContent>[0]["tanstackTable"];
|
|
11
10
|
|
|
12
|
-
// Mock row data
|
|
13
11
|
const mockTableRows = [
|
|
14
12
|
{
|
|
15
13
|
id: "row1",
|
|
@@ -39,467 +37,82 @@ const mockTableRows = [
|
|
|
39
37
|
},
|
|
40
38
|
],
|
|
41
39
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
getIsLastColumn: () => false,
|
|
52
|
-
columnDef: { meta: { cellType: "default" } },
|
|
53
|
-
},
|
|
54
|
-
getValue: () => "Value 3",
|
|
55
|
-
getContext: () => ({ getValue: () => "Value 3" }),
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
id: "cell4",
|
|
59
|
-
column: {
|
|
60
|
-
id: "col2",
|
|
61
|
-
getIsFirstColumn: () => false,
|
|
62
|
-
getIsLastColumn: () => true,
|
|
63
|
-
columnDef: { meta: { cellType: "default" } },
|
|
64
|
-
},
|
|
65
|
-
getValue: () => "Value 4",
|
|
66
|
-
getContext: () => ({ getValue: () => "Value 4" }),
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
] as unknown as Parameters<typeof NormalTableContent>[0]["tableRows"];
|
|
71
|
-
|
|
72
|
-
const mockRenderTableHeaders = () => (
|
|
73
|
-
<tr>
|
|
74
|
-
<th>Header 1</th>
|
|
75
|
-
<th>Header 2</th>
|
|
76
|
-
</tr>
|
|
40
|
+
] as unknown as Parameters<typeof TableContent>[0]["tableRows"];
|
|
41
|
+
|
|
42
|
+
const mockTableHeader = (
|
|
43
|
+
<thead>
|
|
44
|
+
<tr>
|
|
45
|
+
<th>Header 1</th>
|
|
46
|
+
<th>Header 2</th>
|
|
47
|
+
</tr>
|
|
48
|
+
</thead>
|
|
77
49
|
);
|
|
78
50
|
|
|
79
|
-
describe("Table Content
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
activeId: null,
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
it("should render table with drag disabled by default", () => {
|
|
96
|
-
render(<NormalTableContent {...defaultProps} />);
|
|
97
|
-
|
|
98
|
-
const table = screen.getByRole("table");
|
|
99
|
-
expect(table).toBeInTheDocument();
|
|
100
|
-
expect(table.className).toContain("purpur-table__table");
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it("should render table with drag enabled", () => {
|
|
104
|
-
render(<NormalTableContent {...defaultProps} enableColumnDrag={true} />);
|
|
51
|
+
describe("Table Content with unified component", () => {
|
|
52
|
+
const defaultProps = {
|
|
53
|
+
tanstackTable: mockTanstackTable,
|
|
54
|
+
tableRows: mockTableRows,
|
|
55
|
+
fullWidth: false,
|
|
56
|
+
tableHeader: mockTableHeader,
|
|
57
|
+
stickyFirstColumn: false,
|
|
58
|
+
getStickyColumn: () => false,
|
|
59
|
+
isScrolled: false,
|
|
60
|
+
showBorder: () => false,
|
|
61
|
+
enableColumnDrag: false,
|
|
62
|
+
activeId: null,
|
|
63
|
+
};
|
|
105
64
|
|
|
65
|
+
describe("NormalTableContent", () => {
|
|
66
|
+
it("should render table", () => {
|
|
67
|
+
render(<TableContent {...defaultProps} />);
|
|
106
68
|
const table = screen.getByRole("table");
|
|
107
69
|
expect(table).toBeInTheDocument();
|
|
108
70
|
});
|
|
109
71
|
|
|
110
72
|
it("should apply full width class when fullWidth is true", () => {
|
|
111
|
-
render(<
|
|
112
|
-
|
|
73
|
+
render(<TableContent {...defaultProps} fullWidth={true} />);
|
|
113
74
|
const table = screen.getByRole("table");
|
|
114
75
|
expect(table.className).toContain("purpur-table__table--full-width");
|
|
115
76
|
});
|
|
116
77
|
|
|
117
|
-
it("should
|
|
118
|
-
render(<
|
|
119
|
-
|
|
120
|
-
const rows = screen.getAllByRole("row");
|
|
121
|
-
// Should have header row + data rows
|
|
122
|
-
expect(rows.length).toBeGreaterThan(mockTableRows.length);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it("should pass enableColumnDrag prop to table cells", () => {
|
|
126
|
-
render(<NormalTableContent {...defaultProps} enableColumnDrag={true} />);
|
|
127
|
-
|
|
128
|
-
// All cells should receive the enableColumnDrag prop
|
|
129
|
-
const table = screen.getByRole("table");
|
|
130
|
-
expect(table).toBeInTheDocument();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it("should pass draggingActive prop to cells when activeId matches", () => {
|
|
134
|
-
render(<NormalTableContent {...defaultProps} enableColumnDrag={true} activeId="col1" />);
|
|
135
|
-
|
|
136
|
-
const table = screen.getByRole("table");
|
|
137
|
-
expect(table).toBeInTheDocument();
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it("should handle sticky columns with drag enabled", () => {
|
|
141
|
-
render(
|
|
142
|
-
<NormalTableContent
|
|
143
|
-
{...defaultProps}
|
|
144
|
-
stickyFirstColumn={true}
|
|
145
|
-
getStickyColumn={(index) => index === 0}
|
|
146
|
-
enableColumnDrag={true}
|
|
147
|
-
/>
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
const table = screen.getByRole("table");
|
|
151
|
-
expect(table).toBeInTheDocument();
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it("should handle scrolled state with drag enabled", () => {
|
|
155
|
-
render(<NormalTableContent {...defaultProps} isScrolled={true} enableColumnDrag={true} />);
|
|
156
|
-
|
|
157
|
-
const table = screen.getByRole("table");
|
|
158
|
-
expect(table).toBeInTheDocument();
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it("should handle border showing with drag enabled", () => {
|
|
162
|
-
render(
|
|
163
|
-
<NormalTableContent
|
|
164
|
-
{...defaultProps}
|
|
165
|
-
showBorder={(index) => index === 0}
|
|
166
|
-
enableColumnDrag={true}
|
|
167
|
-
/>
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
const table = screen.getByRole("table");
|
|
171
|
-
expect(table).toBeInTheDocument();
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it("should be accessible with drag enabled", async () => {
|
|
175
|
-
const { container } = render(
|
|
176
|
-
<NormalTableContent {...defaultProps} enableColumnDrag={true} />
|
|
177
|
-
);
|
|
178
|
-
|
|
78
|
+
it("should be accessible", async () => {
|
|
79
|
+
const { container } = render(<TableContent {...defaultProps} />);
|
|
179
80
|
const results = await axe(container);
|
|
180
81
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
181
82
|
// @ts-ignore
|
|
182
83
|
expect(results).toHaveNoViolations();
|
|
183
84
|
});
|
|
184
|
-
|
|
185
|
-
it("should handle empty table rows", () => {
|
|
186
|
-
render(<NormalTableContent {...defaultProps} tableRows={[]} enableColumnDrag={true} />);
|
|
187
|
-
|
|
188
|
-
const table = screen.getByRole("table");
|
|
189
|
-
expect(table).toBeInTheDocument();
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it("should handle selected rows with drag enabled", () => {
|
|
193
|
-
const selectedRows = mockTableRows.map(
|
|
194
|
-
(row: Parameters<typeof NormalTableContent>[0]["tableRows"][0]) => ({
|
|
195
|
-
...row,
|
|
196
|
-
getIsSelected: () => true,
|
|
197
|
-
})
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
render(
|
|
201
|
-
<NormalTableContent {...defaultProps} tableRows={selectedRows} enableColumnDrag={true} />
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
const table = screen.getByRole("table");
|
|
205
|
-
expect(table).toBeInTheDocument();
|
|
206
|
-
});
|
|
207
85
|
});
|
|
208
86
|
|
|
209
|
-
describe("
|
|
210
|
-
|
|
211
|
-
tanstackTable: mockTanstackTable,
|
|
212
|
-
tableRows: [],
|
|
213
|
-
showColumnFiltersEnabled: false,
|
|
214
|
-
fullWidth: false,
|
|
215
|
-
renderTableHeaders: mockRenderTableHeaders,
|
|
216
|
-
skeletonRows: 5,
|
|
217
|
-
getStickyColumn: () => false,
|
|
218
|
-
stickyFirstColumn: false,
|
|
219
|
-
isScrolled: false,
|
|
220
|
-
showBorder: () => false,
|
|
221
|
-
getColumnWidths: () => ["100px", "150px"],
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
it("should render loading table with drag context support", () => {
|
|
225
|
-
render(<LoadingTableContent {...defaultProps} />);
|
|
226
|
-
|
|
227
|
-
const table = screen.getByRole("table");
|
|
228
|
-
expect(table).toBeInTheDocument();
|
|
229
|
-
expect(table.className).toContain("purpur-table__table");
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("should apply full width class when fullWidth is true", () => {
|
|
233
|
-
render(<LoadingTableContent {...defaultProps} fullWidth={true} />);
|
|
234
|
-
|
|
235
|
-
const table = screen.getByRole("table");
|
|
236
|
-
expect(table.className).toContain("purpur-table__table--full-width");
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it("should render with column filters enabled", () => {
|
|
240
|
-
render(<LoadingTableContent {...defaultProps} showColumnFiltersEnabled={true} />);
|
|
241
|
-
|
|
242
|
-
const table = screen.getByRole("table");
|
|
243
|
-
expect(table).toBeInTheDocument();
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it("should handle sticky columns in loading state", () => {
|
|
87
|
+
describe("Loading state", () => {
|
|
88
|
+
it("should render loading state", () => {
|
|
247
89
|
render(
|
|
248
|
-
<
|
|
90
|
+
<TableContent
|
|
249
91
|
{...defaultProps}
|
|
250
|
-
|
|
251
|
-
|
|
92
|
+
loading={true}
|
|
93
|
+
skeletonRows={5}
|
|
94
|
+
getColumnWidths={() => []}
|
|
252
95
|
/>
|
|
253
96
|
);
|
|
254
|
-
|
|
255
|
-
const table = screen.getByRole("table");
|
|
256
|
-
expect(table).toBeInTheDocument();
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it("should handle scrolled state in loading", () => {
|
|
260
|
-
render(<LoadingTableContent {...defaultProps} isScrolled={true} />);
|
|
261
|
-
|
|
262
|
-
const table = screen.getByRole("table");
|
|
263
|
-
expect(table).toBeInTheDocument();
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it("should pass correct skeleton row count", () => {
|
|
267
|
-
const skeletonRows = 3;
|
|
268
|
-
render(<LoadingTableContent {...defaultProps} skeletonRows={skeletonRows} />);
|
|
269
|
-
|
|
270
97
|
const table = screen.getByRole("table");
|
|
271
98
|
expect(table).toBeInTheDocument();
|
|
272
99
|
});
|
|
273
|
-
|
|
274
|
-
it("should pass column widths to loading rows", () => {
|
|
275
|
-
const columnWidths = ["120px", "180px", "200px"];
|
|
276
|
-
render(<LoadingTableContent {...defaultProps} getColumnWidths={() => columnWidths} />);
|
|
277
|
-
|
|
278
|
-
const table = screen.getByRole("table");
|
|
279
|
-
expect(table).toBeInTheDocument();
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
it("should be accessible in loading state", async () => {
|
|
283
|
-
const { container } = render(<LoadingTableContent {...defaultProps} />);
|
|
284
|
-
|
|
285
|
-
const results = await axe(container);
|
|
286
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
287
|
-
// @ts-ignore
|
|
288
|
-
expect(results).toHaveNoViolations();
|
|
289
|
-
});
|
|
290
100
|
});
|
|
291
101
|
|
|
292
|
-
describe("
|
|
293
|
-
|
|
294
|
-
tanstackTable: mockTanstackTable,
|
|
295
|
-
tableRows: [],
|
|
296
|
-
showColumnFiltersEnabled: false,
|
|
297
|
-
fullWidth: false,
|
|
298
|
-
renderTableHeaders: mockRenderTableHeaders,
|
|
299
|
-
variant: "primary" as const,
|
|
300
|
-
emptyTableHeadingTag: "h2" as const,
|
|
301
|
-
emptyTableCopy: {
|
|
302
|
-
title: "No data available",
|
|
303
|
-
description: "There are no items to display in this table.",
|
|
304
|
-
},
|
|
305
|
-
emptyTableIcon: <div data-testid="empty-icon">Empty Icon</div>,
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
it("should render empty table with drag context support", () => {
|
|
309
|
-
render(<EmptyTableContent {...defaultProps} />);
|
|
310
|
-
|
|
311
|
-
const table = screen.getByRole("table");
|
|
312
|
-
expect(table).toBeInTheDocument();
|
|
313
|
-
expect(table.className).toContain("purpur-table__table");
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it("should apply full width class when fullWidth is true", () => {
|
|
317
|
-
render(<EmptyTableContent {...defaultProps} fullWidth={true} />);
|
|
318
|
-
|
|
319
|
-
const table = screen.getByRole("table");
|
|
320
|
-
expect(table.className).toContain("purpur-table__table--full-width");
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
it("should render with column filters enabled", () => {
|
|
324
|
-
render(<EmptyTableContent {...defaultProps} showColumnFiltersEnabled={true} />);
|
|
325
|
-
|
|
326
|
-
const table = screen.getByRole("table");
|
|
327
|
-
expect(table).toBeInTheDocument();
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
it("should display empty table content", () => {
|
|
331
|
-
render(<EmptyTableContent {...defaultProps} />);
|
|
332
|
-
|
|
333
|
-
expect(screen.getByText(defaultProps.emptyTableCopy.title)).toBeInTheDocument();
|
|
334
|
-
expect(screen.getByText(defaultProps.emptyTableCopy.description)).toBeInTheDocument();
|
|
335
|
-
expect(screen.getByTestId("empty-icon")).toBeInTheDocument();
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
it("should handle different variants", () => {
|
|
339
|
-
const variants = ["primary", "secondary"] as const;
|
|
340
|
-
|
|
341
|
-
variants.forEach((variant) => {
|
|
342
|
-
const { unmount } = render(<EmptyTableContent {...defaultProps} variant={variant} />);
|
|
343
|
-
|
|
344
|
-
const table = screen.getByRole("table");
|
|
345
|
-
expect(table).toBeInTheDocument();
|
|
346
|
-
|
|
347
|
-
unmount();
|
|
348
|
-
});
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
it("should handle different heading tags", () => {
|
|
352
|
-
const headingTags = ["h1", "h2", "h3", "h4", "h5", "h6"] as const;
|
|
353
|
-
|
|
354
|
-
headingTags.forEach((tag) => {
|
|
355
|
-
const { unmount } = render(
|
|
356
|
-
<EmptyTableContent {...defaultProps} emptyTableHeadingTag={tag} />
|
|
357
|
-
);
|
|
358
|
-
|
|
359
|
-
const table = screen.getByRole("table");
|
|
360
|
-
expect(table).toBeInTheDocument();
|
|
361
|
-
|
|
362
|
-
unmount();
|
|
363
|
-
});
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
it("should handle missing icon", () => {
|
|
367
|
-
render(<EmptyTableContent {...defaultProps} emptyTableIcon={undefined} />);
|
|
368
|
-
|
|
369
|
-
const table = screen.getByRole("table");
|
|
370
|
-
expect(table).toBeInTheDocument();
|
|
371
|
-
expect(screen.queryByTestId("empty-icon")).not.toBeInTheDocument();
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
it("should calculate correct colSpan from tanstack table", () => {
|
|
375
|
-
const mockTableWithMoreColumns = {
|
|
376
|
-
getVisibleLeafColumns: vi.fn(() => [
|
|
377
|
-
{ id: "col1" },
|
|
378
|
-
{ id: "col2" },
|
|
379
|
-
{ id: "col3" },
|
|
380
|
-
{ id: "col4" },
|
|
381
|
-
]),
|
|
382
|
-
} as unknown as Parameters<typeof EmptyTableContent>[0]["tanstackTable"];
|
|
383
|
-
|
|
384
|
-
render(<EmptyTableContent {...defaultProps} tanstackTable={mockTableWithMoreColumns} />);
|
|
385
|
-
|
|
386
|
-
const table = screen.getByRole("table");
|
|
387
|
-
expect(table).toBeInTheDocument();
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
it("should be accessible in empty state", async () => {
|
|
391
|
-
const { container } = render(<EmptyTableContent {...defaultProps} />);
|
|
392
|
-
|
|
393
|
-
const results = await axe(container);
|
|
394
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
395
|
-
// @ts-ignore
|
|
396
|
-
expect(results).toHaveNoViolations();
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
it("should handle empty copy strings", () => {
|
|
102
|
+
describe("Empty state", () => {
|
|
103
|
+
it("should render empty state", () => {
|
|
400
104
|
render(
|
|
401
|
-
<
|
|
105
|
+
<TableContent
|
|
402
106
|
{...defaultProps}
|
|
403
|
-
emptyTableCopy={{
|
|
404
|
-
title: "",
|
|
405
|
-
description: "",
|
|
406
|
-
}}
|
|
407
|
-
/>
|
|
408
|
-
);
|
|
409
|
-
|
|
410
|
-
const table = screen.getByRole("table");
|
|
411
|
-
expect(table).toBeInTheDocument();
|
|
412
|
-
});
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
describe("Integration between content types", () => {
|
|
416
|
-
it("should maintain consistent table structure across all content types", () => {
|
|
417
|
-
const baseProps = {
|
|
418
|
-
tanstackTable: mockTanstackTable,
|
|
419
|
-
showColumnFiltersEnabled: false,
|
|
420
|
-
fullWidth: true,
|
|
421
|
-
renderTableHeaders: mockRenderTableHeaders,
|
|
422
|
-
};
|
|
423
|
-
|
|
424
|
-
// Normal content
|
|
425
|
-
const { container: normalContainer, unmount: unmountNormal } = render(
|
|
426
|
-
<NormalTableContent
|
|
427
|
-
{...baseProps}
|
|
428
|
-
tableRows={mockTableRows}
|
|
429
|
-
stickyFirstColumn={false}
|
|
430
|
-
getStickyColumn={() => false}
|
|
431
|
-
isScrolled={false}
|
|
432
|
-
showBorder={() => false}
|
|
433
|
-
enableColumnDrag={false}
|
|
434
|
-
activeId={null}
|
|
435
|
-
/>
|
|
436
|
-
);
|
|
437
|
-
|
|
438
|
-
const normalTable = normalContainer.querySelector("table");
|
|
439
|
-
expect(normalTable?.className).toContain("purpur-table__table");
|
|
440
|
-
expect(normalTable?.className).toContain("purpur-table__table--full-width");
|
|
441
|
-
unmountNormal();
|
|
442
|
-
|
|
443
|
-
// Loading content
|
|
444
|
-
const { container: loadingContainer, unmount: unmountLoading } = render(
|
|
445
|
-
<LoadingTableContent
|
|
446
|
-
{...baseProps}
|
|
447
|
-
tableRows={[]}
|
|
448
|
-
skeletonRows={5}
|
|
449
|
-
getStickyColumn={() => false}
|
|
450
|
-
stickyFirstColumn={false}
|
|
451
|
-
isScrolled={false}
|
|
452
|
-
showBorder={() => false}
|
|
453
|
-
getColumnWidths={() => []}
|
|
454
|
-
/>
|
|
455
|
-
);
|
|
456
|
-
|
|
457
|
-
const loadingTable = loadingContainer.querySelector("table");
|
|
458
|
-
expect(loadingTable?.className).toContain("purpur-table__table");
|
|
459
|
-
expect(loadingTable?.className).toContain("purpur-table__table--full-width");
|
|
460
|
-
unmountLoading();
|
|
461
|
-
|
|
462
|
-
// Empty content
|
|
463
|
-
const { container: emptyContainer, unmount: unmountEmpty } = render(
|
|
464
|
-
<EmptyTableContent
|
|
465
|
-
{...baseProps}
|
|
466
107
|
tableRows={[]}
|
|
108
|
+
isEmptyTable={true}
|
|
467
109
|
variant="primary"
|
|
468
110
|
emptyTableHeadingTag="h2"
|
|
469
|
-
emptyTableCopy={{
|
|
470
|
-
title: "Empty",
|
|
471
|
-
description: "No data",
|
|
472
|
-
}}
|
|
111
|
+
emptyTableCopy={{ title: "Empty", description: "No data" }}
|
|
473
112
|
/>
|
|
474
113
|
);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
expect(emptyTable?.className).toContain("purpur-table__table");
|
|
478
|
-
expect(emptyTable?.className).toContain("purpur-table__table--full-width");
|
|
479
|
-
unmountEmpty();
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
it("should handle drag and drop props consistently", () => {
|
|
483
|
-
// Test that drag-related props don't break any content type
|
|
484
|
-
expect(() => {
|
|
485
|
-
render(
|
|
486
|
-
<div>
|
|
487
|
-
<NormalTableContent
|
|
488
|
-
tanstackTable={mockTanstackTable}
|
|
489
|
-
tableRows={mockTableRows}
|
|
490
|
-
showColumnFiltersEnabled={false}
|
|
491
|
-
fullWidth={false}
|
|
492
|
-
renderTableHeaders={mockRenderTableHeaders}
|
|
493
|
-
stickyFirstColumn={false}
|
|
494
|
-
getStickyColumn={() => false}
|
|
495
|
-
isScrolled={false}
|
|
496
|
-
showBorder={() => false}
|
|
497
|
-
enableColumnDrag={true}
|
|
498
|
-
activeId="col1"
|
|
499
|
-
/>
|
|
500
|
-
</div>
|
|
501
|
-
);
|
|
502
|
-
}).not.toThrow();
|
|
114
|
+
const table = screen.getByRole("table");
|
|
115
|
+
expect(table).toBeInTheDocument();
|
|
503
116
|
});
|
|
504
117
|
});
|
|
505
118
|
});
|