@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.
- package/.eslintignore +6 -0
- package/.eslintrc.js +4 -0
- package/.turbo/turbo-build.log +53 -0
- package/CHANGELOG.md +7 -0
- package/dist/TableCell-B8GMRlv7.d.mts +13 -0
- package/dist/TableCell-CN71R1B5.d.ts +13 -0
- package/dist/TableCellTypes-Cp-8r7l1.d.mts +21 -0
- package/dist/TableCellTypes-Cp-8r7l1.d.ts +21 -0
- package/dist/TableHeaderCell-DnwlruQg.d.ts +12 -0
- package/dist/TableHeaderCell-DsJpGb2j.d.mts +12 -0
- package/dist/TableHeaderCellTypes-CH_zzW6X.d.ts +25 -0
- package/dist/TableHeaderCellTypes-CsJQBwu2.d.mts +25 -0
- package/dist/TableTypes-Dg7QrcGt.d.ts +37 -0
- package/dist/TableTypes-jS0O3bwQ.d.mts +37 -0
- package/dist/esm/chunk-67DCEN4G.js +140 -0
- package/dist/esm/chunk-67DCEN4G.js.map +1 -0
- package/dist/esm/chunk-XJMS6762.js +62 -0
- package/dist/esm/chunk-XJMS6762.js.map +1 -0
- package/dist/esm/index.js +106 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/tableCell.js +9 -0
- package/dist/esm/tableCell.js.map +1 -0
- package/dist/esm/tableHeaderCell.js +11 -0
- package/dist/esm/tableHeaderCell.js.map +1 -0
- package/dist/esm/tableRowAccordion.js +110 -0
- package/dist/esm/tableRowAccordion.js.map +1 -0
- package/dist/index.d.mts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +327 -0
- package/dist/index.js.map +1 -0
- package/dist/tableCell.d.mts +9 -0
- package/dist/tableCell.d.ts +9 -0
- package/dist/tableCell.js +98 -0
- package/dist/tableCell.js.map +1 -0
- package/dist/tableHeaderCell.d.mts +10 -0
- package/dist/tableHeaderCell.d.ts +10 -0
- package/dist/tableHeaderCell.js +177 -0
- package/dist/tableHeaderCell.js.map +1 -0
- package/dist/tableRowAccordion.d.mts +25 -0
- package/dist/tableRowAccordion.d.ts +25 -0
- package/dist/tableRowAccordion.js +200 -0
- package/dist/tableRowAccordion.js.map +1 -0
- package/jest.config.js +9 -0
- package/package.json +65 -0
- package/src/Table.stories.tsx +403 -0
- package/src/Table.tsx +111 -0
- package/src/TableCell/TableCell.stories.tsx +30 -0
- package/src/TableCell/TableCell.tsx +44 -0
- package/src/TableCell/TableCellTypes.ts +30 -0
- package/src/TableCell/__tests__/TabelCell.test.tsx +36 -0
- package/src/TableCell/__tests__/TableCell.typetest.tsx +34 -0
- package/src/TableCell/index.ts +5 -0
- package/src/TableCell/styles.ts +16 -0
- package/src/TableHeaderCell/TableHeaderCell.stories.tsx +46 -0
- package/src/TableHeaderCell/TableHeaderCell.tsx +120 -0
- package/src/TableHeaderCell/TableHeaderCellTypes.ts +26 -0
- package/src/TableHeaderCell/__tests__/TableHeaderCell.test.tsx +28 -0
- package/src/TableHeaderCell/__tests__/TableHeaderCell.typetest.tsx +31 -0
- package/src/TableHeaderCell/constants.ts +4 -0
- package/src/TableHeaderCell/index.ts +6 -0
- package/src/TableHeaderCell/styles.ts +46 -0
- package/src/TableRowAccordion/TableRowAccordion.stories.tsx +63 -0
- package/src/TableRowAccordion/TableRowAccordion.tsx +75 -0
- package/src/TableRowAccordion/TableRowAccordionTypes.ts +20 -0
- package/src/TableRowAccordion/__tests__/TableRowAccordion.test.tsx +104 -0
- package/src/TableRowAccordion/__tests__/TableRowAccordion.typetest.tsx +51 -0
- package/src/TableRowAccordion/index.ts +5 -0
- package/src/TableRowAccordion/styles.ts +25 -0
- package/src/TableTypes.ts +54 -0
- package/src/__tests__/Table.test.tsx +106 -0
- package/src/__tests__/Table.typetest.tsx +145 -0
- package/src/index.ts +5 -0
- package/src/styles.ts +21 -0
- package/styled.d.ts +7 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +17 -0
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sproutsocial/seeds-react-table",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Seeds React Table",
|
|
5
|
+
"author": "Sprout Social, Inc.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/esm/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/esm/index.js",
|
|
13
|
+
"require": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./TableCell": {
|
|
17
|
+
"import": "./dist/esm/tableCell.js",
|
|
18
|
+
"require": "./dist/tableCell.js",
|
|
19
|
+
"types": "./dist/tableCell.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./TableHeaderCell": {
|
|
22
|
+
"import": "./dist/esm/tableHeaderCell.js",
|
|
23
|
+
"require": "./dist/tableHeaderCell.js",
|
|
24
|
+
"types": "./dist/tableHeaderCell.d.ts"
|
|
25
|
+
},
|
|
26
|
+
"./TableRowAccordion": {
|
|
27
|
+
"import": "./dist/esm/tableRowAccordion.js",
|
|
28
|
+
"require": "./dist/tableRowAccordion.js",
|
|
29
|
+
"types": "./dist/tableRowAccordion.d.ts"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup --dts",
|
|
34
|
+
"build:debug": "tsup --dts --metafile",
|
|
35
|
+
"dev": "tsup --watch --dts",
|
|
36
|
+
"clean": "rm -rf .turbo dist",
|
|
37
|
+
"clean:modules": "rm -rf node_modules",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"test": "jest",
|
|
40
|
+
"test:watch": "jest --watch --coverage=false"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@sproutsocial/seeds-react-theme": "*",
|
|
44
|
+
"@sproutsocial/seeds-react-system-props": "*",
|
|
45
|
+
"@sproutsocial/seeds-react-icon": "*"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/react": "^18.0.0",
|
|
49
|
+
"@types/styled-components": "^5.1.26",
|
|
50
|
+
"@sproutsocial/eslint-config-seeds": "*",
|
|
51
|
+
"react": "^18.0.0",
|
|
52
|
+
"styled-components": "^5.2.3",
|
|
53
|
+
"tsup": "^8.0.2",
|
|
54
|
+
"typescript": "^5.6.2",
|
|
55
|
+
"@sproutsocial/seeds-tsconfig": "*",
|
|
56
|
+
"@sproutsocial/seeds-testing": "*",
|
|
57
|
+
"@sproutsocial/seeds-react-testing-library": "*"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"styled-components": "^5.2.3"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=18"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { Table } from "./Table";
|
|
4
|
+
import { TableRowAccordion } from "./TableRowAccordion";
|
|
5
|
+
import { SORT_DIRECTIONS } from "./TableHeaderCell";
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Table> = {
|
|
8
|
+
title: "Components/Table/Table",
|
|
9
|
+
component: Table,
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Table>;
|
|
14
|
+
|
|
15
|
+
export const Default: Story = {
|
|
16
|
+
render: () => {
|
|
17
|
+
const [rows, setRows] = useState([
|
|
18
|
+
{
|
|
19
|
+
cells: [
|
|
20
|
+
{
|
|
21
|
+
content: "🍔 Bacon Smokehouse Burger",
|
|
22
|
+
id: "1",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
content: "840",
|
|
26
|
+
id: "2",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
content: "45g",
|
|
30
|
+
id: "3",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
content: "62g",
|
|
34
|
+
id: "4",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
content: "46g",
|
|
38
|
+
id: "5",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
id: "1",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
cells: [
|
|
45
|
+
{
|
|
46
|
+
content: "🍔 Big Mac",
|
|
47
|
+
id: "1",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
content: "540",
|
|
51
|
+
id: "2",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
content: "28g",
|
|
55
|
+
id: "3",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
content: "46g",
|
|
59
|
+
id: "4",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
content: "25g",
|
|
63
|
+
id: "5",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
id: "2",
|
|
67
|
+
},
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
const [sortDirection, setSortDirection] = useState<"ASC" | "DESC">(
|
|
71
|
+
SORT_DIRECTIONS.ASC
|
|
72
|
+
);
|
|
73
|
+
const [sortId, setSortId] = useState("2");
|
|
74
|
+
|
|
75
|
+
const onSort = (id: string) => {
|
|
76
|
+
const sortedRows = [...rows].sort((a, b) => {
|
|
77
|
+
const aContent = a.cells.find((cell) => cell.id === id)?.content;
|
|
78
|
+
const bContent = b.cells.find((cell) => cell.id === id)?.content;
|
|
79
|
+
|
|
80
|
+
if (aContent && bContent) {
|
|
81
|
+
if (sortDirection === SORT_DIRECTIONS.ASC) {
|
|
82
|
+
return aContent.localeCompare(bContent);
|
|
83
|
+
} else {
|
|
84
|
+
return bContent.localeCompare(aContent);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return 0;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
setRows(sortedRows);
|
|
92
|
+
setSortDirection(
|
|
93
|
+
sortDirection === SORT_DIRECTIONS.ASC
|
|
94
|
+
? SORT_DIRECTIONS.DESC
|
|
95
|
+
: SORT_DIRECTIONS.ASC
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
setSortId(id);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<Table
|
|
103
|
+
head={[
|
|
104
|
+
{
|
|
105
|
+
content: "Food Item",
|
|
106
|
+
id: "1",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
content: "Calories",
|
|
110
|
+
id: "2",
|
|
111
|
+
isSortable: true,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
content: "Total Fat: (69% DV*)",
|
|
115
|
+
id: "3",
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
content: "Total Carbs: (21% DV*)",
|
|
119
|
+
id: "4",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
content: "Protein",
|
|
123
|
+
id: "5",
|
|
124
|
+
},
|
|
125
|
+
]}
|
|
126
|
+
rows={rows}
|
|
127
|
+
onSort={onSort}
|
|
128
|
+
sortDirection={sortDirection}
|
|
129
|
+
sortId={sortId}
|
|
130
|
+
/>
|
|
131
|
+
);
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export const ColumnSpan: Story = {
|
|
136
|
+
render: () => (
|
|
137
|
+
<Table
|
|
138
|
+
head={[
|
|
139
|
+
{
|
|
140
|
+
colSpan: 2,
|
|
141
|
+
content: "Header",
|
|
142
|
+
id: "1",
|
|
143
|
+
},
|
|
144
|
+
]}
|
|
145
|
+
rows={[
|
|
146
|
+
{
|
|
147
|
+
cells: [
|
|
148
|
+
{
|
|
149
|
+
content: "Column 1",
|
|
150
|
+
id: "1",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
content: "Column 2",
|
|
154
|
+
id: "2",
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
id: "1",
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
cells: [
|
|
161
|
+
{
|
|
162
|
+
colSpan: 2,
|
|
163
|
+
content: "This is a footer for the table.",
|
|
164
|
+
id: "1",
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
id: "2",
|
|
168
|
+
},
|
|
169
|
+
]}
|
|
170
|
+
/>
|
|
171
|
+
),
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const ColumnWidth: Story = {
|
|
175
|
+
render: () => (
|
|
176
|
+
<Table
|
|
177
|
+
head={[
|
|
178
|
+
{
|
|
179
|
+
content: "Food Item",
|
|
180
|
+
id: "1",
|
|
181
|
+
width: 200,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
align: "center",
|
|
185
|
+
content: "Calories",
|
|
186
|
+
id: "2",
|
|
187
|
+
isSortable: true,
|
|
188
|
+
width: 100,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
content: "Description",
|
|
192
|
+
id: "3",
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
align: "right",
|
|
196
|
+
content: "Protein",
|
|
197
|
+
id: "4",
|
|
198
|
+
width: 100,
|
|
199
|
+
},
|
|
200
|
+
]}
|
|
201
|
+
rows={[
|
|
202
|
+
{
|
|
203
|
+
cells: [
|
|
204
|
+
{
|
|
205
|
+
content: "🍔 Bacon Smokehouse Burger",
|
|
206
|
+
id: "1",
|
|
207
|
+
width: 200,
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
align: "center",
|
|
211
|
+
content: "840",
|
|
212
|
+
id: "2",
|
|
213
|
+
width: 100,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
content:
|
|
217
|
+
"A burger made with unexpected flavor combinations, including crispy Applewood smoked bacon, smoky bacon-onion sauce, real white cheddar, mild sweet mustard sauce and in-house fried onion strings.",
|
|
218
|
+
id: "3",
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
align: "right",
|
|
222
|
+
content: "46g",
|
|
223
|
+
id: "4",
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
id: "1",
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
cells: [
|
|
230
|
+
{
|
|
231
|
+
content: "🍔 Big Mac",
|
|
232
|
+
id: "1",
|
|
233
|
+
width: 200,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
align: "center",
|
|
237
|
+
content: "540",
|
|
238
|
+
id: "2",
|
|
239
|
+
width: 100,
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
content:
|
|
243
|
+
"Mouthwatering perfection starts with two 100% pure beef patties and Big Mac® sauce sandwiched between a sesame seed bun.",
|
|
244
|
+
id: "3",
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
align: "right",
|
|
248
|
+
content: "25g",
|
|
249
|
+
id: "4",
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
id: "2",
|
|
253
|
+
},
|
|
254
|
+
]}
|
|
255
|
+
/>
|
|
256
|
+
),
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export const CustomRowRendering: Story = {
|
|
260
|
+
render: () => (
|
|
261
|
+
<Table
|
|
262
|
+
head={[
|
|
263
|
+
{
|
|
264
|
+
id: "1",
|
|
265
|
+
content: "Food Item",
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
id: "2",
|
|
269
|
+
content: "Calories",
|
|
270
|
+
isSortable: true,
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
id: "3",
|
|
274
|
+
content: "Total Fat: (69% DV*)",
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
id: "4",
|
|
278
|
+
content: "Total Carbs: (21% DV*)",
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
id: "5",
|
|
282
|
+
content: "Protein",
|
|
283
|
+
},
|
|
284
|
+
]}
|
|
285
|
+
rows={[
|
|
286
|
+
{
|
|
287
|
+
id: "baconsmokehouse",
|
|
288
|
+
cells: [
|
|
289
|
+
{
|
|
290
|
+
id: "1",
|
|
291
|
+
content: "🍔 Bacon Smokehouse Burger",
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
id: "2",
|
|
295
|
+
content: "840",
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
id: "3",
|
|
299
|
+
content: "45g",
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: "4",
|
|
303
|
+
content: "62g",
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
id: "5",
|
|
307
|
+
content: "46g",
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
id: "Big-Mac",
|
|
313
|
+
cells: [
|
|
314
|
+
{
|
|
315
|
+
id: "1",
|
|
316
|
+
content: "🍔 Big Mac",
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
id: "2",
|
|
320
|
+
content: "540",
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
id: "3",
|
|
324
|
+
content: "28g",
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
id: "4",
|
|
328
|
+
content: "46g",
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
id: "5",
|
|
332
|
+
content: "25g",
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
},
|
|
336
|
+
]}
|
|
337
|
+
rowRender={(row) => {
|
|
338
|
+
return (
|
|
339
|
+
<TableRowAccordion
|
|
340
|
+
key={row.id}
|
|
341
|
+
id={row.id}
|
|
342
|
+
cells={row.cells}
|
|
343
|
+
isExpanded={row.id === "baconsmokehouse"}
|
|
344
|
+
onToggle={(id) => alert(`Toggled ID #${id}`)}
|
|
345
|
+
detail={
|
|
346
|
+
row.id === "baconsmokehouse" ? (
|
|
347
|
+
<img
|
|
348
|
+
width="100%"
|
|
349
|
+
src="http://static01.nyt.com/images/2015/10/24/arts/24drakeart2/24drakeart2-master675.jpg"
|
|
350
|
+
alt="doge"
|
|
351
|
+
/>
|
|
352
|
+
) : (
|
|
353
|
+
<img
|
|
354
|
+
width="100%"
|
|
355
|
+
src="http://static01.nyt.com/images/2015/10/24/arts/24drakeart2/24drakeart2-master675.jpg"
|
|
356
|
+
alt="doge"
|
|
357
|
+
/>
|
|
358
|
+
)
|
|
359
|
+
}
|
|
360
|
+
/>
|
|
361
|
+
);
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
364
|
+
),
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
export const StaticTable: Story = {
|
|
368
|
+
render: () => {
|
|
369
|
+
const columns = ["Name", "Squad", "Favorite Color"];
|
|
370
|
+
const rows = [
|
|
371
|
+
{
|
|
372
|
+
name: "Mike R",
|
|
373
|
+
squad: "People and Community",
|
|
374
|
+
favoriteColor: "Green",
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: "Travis W",
|
|
378
|
+
squad: "Listening",
|
|
379
|
+
favoriteColor: "Blue",
|
|
380
|
+
},
|
|
381
|
+
];
|
|
382
|
+
return (
|
|
383
|
+
<Table>
|
|
384
|
+
<Table.TableHead>
|
|
385
|
+
<Table.TableRow>
|
|
386
|
+
{columns.map((c) => (
|
|
387
|
+
<Table.HeaderCell id={c.toLowerCase()}>{c} </Table.HeaderCell>
|
|
388
|
+
))}
|
|
389
|
+
</Table.TableRow>
|
|
390
|
+
</Table.TableHead>
|
|
391
|
+
<Table.TableBody>
|
|
392
|
+
{rows.map((r, i) => (
|
|
393
|
+
<Table.TableRow>
|
|
394
|
+
<Table.Cell id={`row-${i}-name`}>{r.name} </Table.Cell>
|
|
395
|
+
<Table.Cell id={`row-${i}-squad`}>{r.squad} </Table.Cell>
|
|
396
|
+
<Table.Cell id={`row-${i}-color`}>{r.favoriteColor} </Table.Cell>
|
|
397
|
+
</Table.TableRow>
|
|
398
|
+
))}
|
|
399
|
+
</Table.TableBody>
|
|
400
|
+
</Table>
|
|
401
|
+
);
|
|
402
|
+
},
|
|
403
|
+
};
|
package/src/Table.tsx
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import TableCell from "./TableCell";
|
|
3
|
+
import TableHeaderCell from "./TableHeaderCell";
|
|
4
|
+
import Container from "./styles";
|
|
5
|
+
import type {
|
|
6
|
+
TypePassthroughProps,
|
|
7
|
+
TypeTableProps,
|
|
8
|
+
TypeTableRow,
|
|
9
|
+
} from "./TableTypes";
|
|
10
|
+
|
|
11
|
+
const renderTableRow = (row: TypeTableRow) => {
|
|
12
|
+
return (
|
|
13
|
+
<tbody key={row.id} data-qa-table-row="">
|
|
14
|
+
<tr>
|
|
15
|
+
{row.cells.map((td) => {
|
|
16
|
+
return <TableCell {...td} key={td.id} />;
|
|
17
|
+
})}
|
|
18
|
+
</tr>
|
|
19
|
+
</tbody>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The table component assist in rendering tablular data.
|
|
25
|
+
*/
|
|
26
|
+
export const Table = ({
|
|
27
|
+
head = [],
|
|
28
|
+
rows = [],
|
|
29
|
+
onSort,
|
|
30
|
+
sortId,
|
|
31
|
+
sortDirection,
|
|
32
|
+
rowRender,
|
|
33
|
+
children,
|
|
34
|
+
color,
|
|
35
|
+
...rest
|
|
36
|
+
}: TypeTableProps) => {
|
|
37
|
+
if (children) {
|
|
38
|
+
return (
|
|
39
|
+
<Container {...rest} data-qa-table="">
|
|
40
|
+
{children}
|
|
41
|
+
</Container>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Container
|
|
47
|
+
{...rest}
|
|
48
|
+
data-qa-table=""
|
|
49
|
+
// TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
color={color}
|
|
53
|
+
>
|
|
54
|
+
<colgroup>
|
|
55
|
+
{head.map(({ id, colSpan = 1 }) => (
|
|
56
|
+
<col key={id} span={colSpan} />
|
|
57
|
+
))}
|
|
58
|
+
</colgroup>
|
|
59
|
+
{head.length > 0 && (
|
|
60
|
+
<thead data-qa-table-header="">
|
|
61
|
+
<tr>
|
|
62
|
+
{head.map(({ color, ...th }) => {
|
|
63
|
+
return (
|
|
64
|
+
<TableHeaderCell
|
|
65
|
+
{...th}
|
|
66
|
+
key={th.id}
|
|
67
|
+
onSort={onSort}
|
|
68
|
+
sortId={sortId}
|
|
69
|
+
sortDirection={sortDirection}
|
|
70
|
+
// TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
color={color}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
})}
|
|
77
|
+
</tr>
|
|
78
|
+
</thead>
|
|
79
|
+
)}
|
|
80
|
+
{rows.map((row) => {
|
|
81
|
+
return rowRender ? rowRender(row) : renderTableRow(row);
|
|
82
|
+
})}
|
|
83
|
+
</Container>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const TableHead = ({ children, ...props }: TypePassthroughProps) => (
|
|
88
|
+
<thead {...props}>{children}</thead>
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
export const TableBody = ({ children, ...props }: TypePassthroughProps) => (
|
|
92
|
+
<tbody {...props}>{children}</tbody>
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
export const TableRow = ({ children, ...props }: TypePassthroughProps) => (
|
|
96
|
+
<tr {...props}>{children}</tr>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
TableHead.displayName = "Table.TableHead";
|
|
100
|
+
TableBody.displayName = "Table.TableBody";
|
|
101
|
+
TableRow.displayName = "Table.TableRow";
|
|
102
|
+
TableHeaderCell.displayName = "Table.HeaderCell";
|
|
103
|
+
TableCell.displayName = "Table.Cell";
|
|
104
|
+
|
|
105
|
+
Table.TableHead = TableHead;
|
|
106
|
+
Table.TableBody = TableBody;
|
|
107
|
+
Table.TableRow = TableRow;
|
|
108
|
+
Table.HeaderCell = TableHeaderCell;
|
|
109
|
+
Table.Cell = TableCell;
|
|
110
|
+
|
|
111
|
+
export default Table;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { TableCell } from "./TableCell";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof TableCell> = {
|
|
6
|
+
title: "Components/Table/TableCell",
|
|
7
|
+
component: TableCell,
|
|
8
|
+
args: {
|
|
9
|
+
content: "🍔 Bacon Smokehouse Burger",
|
|
10
|
+
id: "bacon_smokehouse",
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj<typeof TableCell>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
args: {
|
|
19
|
+
color: "text.body",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const AdditionalProps: Story = {
|
|
24
|
+
args: {
|
|
25
|
+
...Default.args,
|
|
26
|
+
width: 300,
|
|
27
|
+
colSpan: 2,
|
|
28
|
+
align: "center",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Container from "./styles";
|
|
3
|
+
import type { TypeTableCellProps } from "./TableCellTypes";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The table cell component is for rendering table cells and is meant to be used with the table component.
|
|
7
|
+
*/
|
|
8
|
+
export class TableCell extends React.Component<TypeTableCellProps> {
|
|
9
|
+
static displayName: string;
|
|
10
|
+
override render() {
|
|
11
|
+
const {
|
|
12
|
+
id,
|
|
13
|
+
content,
|
|
14
|
+
colSpan,
|
|
15
|
+
width,
|
|
16
|
+
align,
|
|
17
|
+
scope,
|
|
18
|
+
children,
|
|
19
|
+
color,
|
|
20
|
+
...rest
|
|
21
|
+
} = this.props;
|
|
22
|
+
return (
|
|
23
|
+
<Container
|
|
24
|
+
{...rest}
|
|
25
|
+
// If the `scope` property is passed we must render the element as a <th>
|
|
26
|
+
as={scope ? "th" : "td"}
|
|
27
|
+
scope={scope ? scope : undefined}
|
|
28
|
+
alignment={align || "left"}
|
|
29
|
+
key={id}
|
|
30
|
+
colSpan={colSpan}
|
|
31
|
+
width={width}
|
|
32
|
+
data-qa-table-cell=""
|
|
33
|
+
// TODO: fix this type since `color` should be valid here. TS can't resolve the correct type.
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
color={color}
|
|
37
|
+
>
|
|
38
|
+
{children || content}
|
|
39
|
+
</Container>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default TableCell;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { TypeSystemCommonProps } from "@sproutsocial/seeds-react-system-props";
|
|
3
|
+
|
|
4
|
+
export interface TypeTableCellProps
|
|
5
|
+
extends TypeSystemCommonProps,
|
|
6
|
+
Omit<
|
|
7
|
+
React.ComponentPropsWithoutRef<"td">,
|
|
8
|
+
keyof TypeSystemCommonProps | "content"
|
|
9
|
+
> {
|
|
10
|
+
/** Table Cell Id */
|
|
11
|
+
id: string;
|
|
12
|
+
|
|
13
|
+
/** Content is deprecated. Please use children instead. Content to be render */
|
|
14
|
+
content?: React.ReactNode;
|
|
15
|
+
|
|
16
|
+
/** Controls the colSpan attribute (optional) */
|
|
17
|
+
colSpan?: number;
|
|
18
|
+
|
|
19
|
+
/** Controls the width attribute (optional) */
|
|
20
|
+
width?: number;
|
|
21
|
+
|
|
22
|
+
/** Controls the CSS text-align property (optional) */
|
|
23
|
+
align?: "left" | "right" | "center" | "justify";
|
|
24
|
+
|
|
25
|
+
/** Controls the scope attribute. If set, will change the element from a <td> to a <th>. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th#scope (optional) */
|
|
26
|
+
scope?: "row" | "col" | "rowGroup" | "colGroup";
|
|
27
|
+
|
|
28
|
+
/** Children to be rendered */
|
|
29
|
+
children?: React.ReactNode;
|
|
30
|
+
}
|