@indico-data/design-system 2.50.0 → 2.51.1
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/lib/components/tanstackTable/TankstackTable.types.d.ts +45 -0
- package/lib/components/tanstackTable/TanstackTable.stories.d.ts +16 -0
- package/lib/components/tanstackTable/TanstakTable.d.ts +4 -0
- package/lib/components/tanstackTable/__tests__/TanstackTable.test.d.ts +1 -0
- package/lib/components/tanstackTable/__tests__/__mocks__/test-mock-data.d.ts +8 -0
- package/lib/components/tanstackTable/components/ActionBar/ActionBar.d.ts +17 -0
- package/lib/components/tanstackTable/components/ActionBar/ActionBar.stories.d.ts +10 -0
- package/lib/components/tanstackTable/components/ActionBar/__tests__/ActionBar.test.d.ts +1 -0
- package/lib/components/tanstackTable/components/ActionBar/index.d.ts +1 -0
- package/lib/components/tanstackTable/components/NoResults/NoResults.d.ts +7 -0
- package/lib/components/tanstackTable/components/NoResults/__tests__/NoResult.test.d.ts +1 -0
- package/lib/components/tanstackTable/components/NoResults/index.d.ts +1 -0
- package/lib/components/tanstackTable/components/TableBody/TableBody.d.ts +11 -0
- package/lib/components/tanstackTable/components/TableBody/index.d.ts +1 -0
- package/lib/components/tanstackTable/components/TableHeader/TableHeader.d.ts +6 -0
- package/lib/components/tanstackTable/components/TableHeader/index.d.ts +1 -0
- package/lib/components/tanstackTable/components/TablePagination/TablePagination.d.ts +9 -0
- package/lib/components/tanstackTable/components/TablePagination/__tests__/TablePagination.test.d.ts +1 -0
- package/lib/components/tanstackTable/components/TablePagination/index.d.ts +1 -0
- package/lib/components/tanstackTable/docs/pinnedColumns/PinnedColumn.stories.d.ts +7 -0
- package/lib/components/tanstackTable/docs/withRowClick/WithRowClick.stories.d.ts +7 -0
- package/lib/components/tanstackTable/helpers.d.ts +830 -0
- package/lib/components/tanstackTable/index.d.ts +2 -0
- package/lib/components/tanstackTable/mock-data/mock-data.d.ts +14 -0
- package/lib/components/tanstackTable/mock-data/table-configuration.d.ts +3 -0
- package/lib/components/tanstackTable/useTanstackTable.d.ts +14 -0
- package/lib/index.css +262 -0
- package/lib/index.d.ts +67 -17
- package/lib/index.esm.css +262 -0
- package/lib/index.esm.js +20432 -56
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +20432 -55
- package/lib/index.js.map +1 -1
- package/package.json +2 -1
- package/src/components/tanstackTable/TankstackTable.types.ts +44 -0
- package/src/components/tanstackTable/TanstackTable.mdx +122 -0
- package/src/components/tanstackTable/TanstackTable.stories.tsx +284 -0
- package/src/components/tanstackTable/TanstakTable.tsx +156 -0
- package/src/components/tanstackTable/__tests__/TanstackTable.test.tsx +73 -0
- package/src/components/tanstackTable/__tests__/__mocks__/test-mock-data.tsx +83 -0
- package/src/components/tanstackTable/components/ActionBar/ActionBar.mdx +10 -0
- package/src/components/tanstackTable/components/ActionBar/ActionBar.scss +30 -0
- package/src/components/tanstackTable/components/ActionBar/ActionBar.stories.tsx +98 -0
- package/src/components/tanstackTable/components/ActionBar/ActionBar.tsx +43 -0
- package/src/components/tanstackTable/components/ActionBar/__tests__/ActionBar.test.tsx +65 -0
- package/src/components/tanstackTable/components/ActionBar/index.ts +1 -0
- package/src/components/tanstackTable/components/NoResults/NoResults.scss +24 -0
- package/src/components/tanstackTable/components/NoResults/NoResults.tsx +22 -0
- package/src/components/tanstackTable/components/NoResults/__tests__/NoResult.test.tsx +25 -0
- package/src/components/tanstackTable/components/NoResults/index.ts +1 -0
- package/src/components/tanstackTable/components/TableBody/TableBody.tsx +77 -0
- package/src/components/tanstackTable/components/TableBody/index.ts +1 -0
- package/src/components/tanstackTable/components/TableHeader/TableHeader.tsx +49 -0
- package/src/components/tanstackTable/components/TableHeader/index.ts +1 -0
- package/src/components/tanstackTable/components/TablePagination/TablePagination.tsx +45 -0
- package/src/components/tanstackTable/components/TablePagination/__tests__/TablePagination.test.tsx +18 -0
- package/src/components/tanstackTable/components/TablePagination/index.ts +1 -0
- package/src/components/tanstackTable/docs/pinnedColumns/PinnedColumn.mdx +34 -0
- package/src/components/tanstackTable/docs/pinnedColumns/PinnedColumn.stories.tsx +40 -0
- package/src/components/tanstackTable/docs/withRowClick/WithRowClick.mdx +48 -0
- package/src/components/tanstackTable/docs/withRowClick/WithRowClick.stories.tsx +32 -0
- package/src/components/tanstackTable/helpers.ts +45 -0
- package/src/components/tanstackTable/index.ts +2 -0
- package/src/components/tanstackTable/mock-data/mock-data.ts +256 -0
- package/src/components/tanstackTable/mock-data/table-configuration.tsx +222 -0
- package/src/components/tanstackTable/styles/_variables.scss +35 -0
- package/src/components/tanstackTable/styles/table.scss +218 -0
- package/src/components/tanstackTable/styles/test.scss +19 -0
- package/src/components/tanstackTable/tanstack-table.d.ts +19 -0
- package/src/components/tanstackTable/useTanstackTable.tsx +39 -0
- package/src/index.ts +1 -0
- package/src/legacy/components/loading-indicators/CirclePulse/CirclePulse.tsx +1 -0
- package/src/styles/index.scss +1 -0
- package/src/stylesAndAnimations/utilityClasses/UtilityClassesTable.tsx +16 -2
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { TanstackTable } from '../../TanstakTable';
|
|
4
|
+
import { people, Person } from '../../mock-data/mock-data';
|
|
5
|
+
import { columns } from '../../mock-data/table-configuration';
|
|
6
|
+
import { ColumnDef } from '@tanstack/react-table';
|
|
7
|
+
|
|
8
|
+
const meta: Meta = {
|
|
9
|
+
title: 'Layout/Tanstack Table/Pinned Columns',
|
|
10
|
+
component: TanstackTable,
|
|
11
|
+
args: {
|
|
12
|
+
data: people as (Person & { id: string })[],
|
|
13
|
+
columns: columns as ColumnDef<Person & { id: string }>[],
|
|
14
|
+
defaultPinnedColumns: ['select'],
|
|
15
|
+
onClickRow: null,
|
|
16
|
+
},
|
|
17
|
+
decorators: [
|
|
18
|
+
(Story) => (
|
|
19
|
+
<div style={{ width: '100%', height: '500px', overflow: 'hidden' }}>
|
|
20
|
+
<Story />
|
|
21
|
+
</div>
|
|
22
|
+
),
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default meta;
|
|
27
|
+
|
|
28
|
+
type Story = StoryObj<typeof TanstackTable<Person>>;
|
|
29
|
+
|
|
30
|
+
export const PinnedColumns: Story = {
|
|
31
|
+
args: {
|
|
32
|
+
defaultPinnedColumns: ['select', 'firstName', 'lastName'],
|
|
33
|
+
actionBarClassName: 'tanstack-table__action-bar-test',
|
|
34
|
+
},
|
|
35
|
+
render: (args) => (
|
|
36
|
+
<div style={{ width: '700px', height: '500px', overflow: 'hidden' }}>
|
|
37
|
+
<TanstackTable<Person> {...args} />
|
|
38
|
+
</div>
|
|
39
|
+
),
|
|
40
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Canvas, Meta, Controls } from '@storybook/blocks';
|
|
2
|
+
import * as TableStories from './WithRowClick.stories';
|
|
3
|
+
|
|
4
|
+
<Meta title="Layout/Tanstack Table/With Row Click" name="TanstackTable" />
|
|
5
|
+
|
|
6
|
+
<Canvas of={TableStories.WithRowClick} />
|
|
7
|
+
|
|
8
|
+
# Tanstack Table With Row Click
|
|
9
|
+
|
|
10
|
+
When a row is clicked, the component first checks if an onClickRow callback is provided. If it exists, it performs two actions:
|
|
11
|
+
|
|
12
|
+
Toggle Row Behavior:
|
|
13
|
+
The toggleRow function is called with the row's ID. This function checks if the row's ID is already in the isClickedRow state array. If it is, the ID is removed; if not, it's added. This toggles the row's "clicked" state, which is then used to conditionally apply the is-clicked CSS class for visual feedback.
|
|
14
|
+
|
|
15
|
+
Row Click Callback:
|
|
16
|
+
After toggling the row's state, the onClickRow function is invoked with the clicked row as its argument, allowing you to perform additional custom actions when a row is clicked.
|
|
17
|
+
|
|
18
|
+
Here's a simplified flow of the behavior:
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
onClick={() => {
|
|
22
|
+
if (!!onClickRow) {
|
|
23
|
+
toggleRow(row.id); // Toggle the row's clicked state
|
|
24
|
+
onClickRow(row); // Execute additional actions for the clicked row
|
|
25
|
+
}
|
|
26
|
+
}}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This design makes it easy to both track and visually indicate which rows have been interacted with, while also providing a hook for further custom behavior via the onClickRow callback.
|
|
30
|
+
|
|
31
|
+
The 'is-selected' class is added when the row is selected (via row.getIsSelected()), resulting in a specific background for selected rows. The 'show-hover' class is applied if the onClickRow function is provided, enabling a distinct hover effect that indicates interactivity. Finally, the 'is-clicked' class is added when the row has been clicked (i.e., its ID is included in isClickedRow), which changes the background to visually differentiate clicked rows from both hovered and selected ones.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
<tr
|
|
35
|
+
className={classNames('tanstack-table__tbody__tr', {
|
|
36
|
+
'is-selected': row.getIsSelected(),
|
|
37
|
+
'show-hover': !!onClickRow,
|
|
38
|
+
'is-clicked': isClickedRow.includes(row.id),
|
|
39
|
+
})}
|
|
40
|
+
key={row.id}
|
|
41
|
+
onClick={() => {
|
|
42
|
+
if (!!onClickRow) {
|
|
43
|
+
toggleRow(row.id);
|
|
44
|
+
onClickRow(row);
|
|
45
|
+
}
|
|
46
|
+
}}
|
|
47
|
+
>
|
|
48
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { TanstackTable } from '../../TanstakTable';
|
|
4
|
+
import { people, Person } from '../../mock-data/mock-data';
|
|
5
|
+
import { columns } from '../../mock-data/table-configuration';
|
|
6
|
+
import { ColumnDef, Row } from '@tanstack/react-table';
|
|
7
|
+
|
|
8
|
+
const meta: Meta = {
|
|
9
|
+
title: 'Layout/Tanstack Table/With Row Click',
|
|
10
|
+
component: TanstackTable,
|
|
11
|
+
args: {
|
|
12
|
+
data: people as (Person & { id: string })[],
|
|
13
|
+
columns: columns as ColumnDef<Person & { id: string }>[],
|
|
14
|
+
defaultPinnedColumns: ['select'],
|
|
15
|
+
onClickRow: (row: Row<Person>) => {
|
|
16
|
+
console.log(row);
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
decorators: [
|
|
20
|
+
(Story) => (
|
|
21
|
+
<div style={{ width: '100%', height: '500px', overflow: 'hidden' }}>
|
|
22
|
+
<Story />
|
|
23
|
+
</div>
|
|
24
|
+
),
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default meta;
|
|
29
|
+
|
|
30
|
+
type Story = StoryObj<typeof TanstackTable<Person>>;
|
|
31
|
+
|
|
32
|
+
export const WithRowClick: Story = {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Column } from '@tanstack/react-table';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
// Sets style attributes for pinned columns
|
|
5
|
+
const getCommonPinningStyles = <T>(column: Column<T>): CSSProperties => {
|
|
6
|
+
const isPinned = column.getIsPinned();
|
|
7
|
+
const isLastLeftPinnedColumn = isPinned === 'left' && column.getIsLastColumn('left');
|
|
8
|
+
return {
|
|
9
|
+
boxShadow: isLastLeftPinnedColumn ? '-4px 0 4px -4px gray inset' : undefined,
|
|
10
|
+
left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,
|
|
11
|
+
position: isPinned ? 'sticky' : 'initial',
|
|
12
|
+
zIndex: isPinned ? 1 : 0,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const getThStyles = <T>(column: Column<T>) => {
|
|
17
|
+
const styles = { ...getCommonPinningStyles(column) };
|
|
18
|
+
|
|
19
|
+
if (column.columnDef.meta?.styles?.definedColumnSize) {
|
|
20
|
+
styles.width = column.getSize();
|
|
21
|
+
styles.maxWidth = column.getSize();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return styles;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const getTdStyles = <T>(
|
|
28
|
+
column: Column<T>,
|
|
29
|
+
textAlign?: 'left' | 'center' | 'right',
|
|
30
|
+
hasDefinedColumnSize?: boolean,
|
|
31
|
+
width?: number,
|
|
32
|
+
) => {
|
|
33
|
+
const styles: CSSProperties = { ...getCommonPinningStyles(column) };
|
|
34
|
+
|
|
35
|
+
if (textAlign) {
|
|
36
|
+
styles.textAlign = textAlign;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (hasDefinedColumnSize) {
|
|
40
|
+
styles.width = width;
|
|
41
|
+
styles.maxWidth = width;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return styles;
|
|
45
|
+
};
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
export type Person = {
|
|
2
|
+
firstName: string;
|
|
3
|
+
lastName: string;
|
|
4
|
+
age: number;
|
|
5
|
+
visits: number;
|
|
6
|
+
progress: number;
|
|
7
|
+
status: 'relationship' | 'complicated' | 'single';
|
|
8
|
+
subRows?: Person[];
|
|
9
|
+
id: string;
|
|
10
|
+
country: string;
|
|
11
|
+
city: string;
|
|
12
|
+
civility: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const people: Person[] = [
|
|
16
|
+
{
|
|
17
|
+
firstName: 'John',
|
|
18
|
+
lastName: 'Doe',
|
|
19
|
+
age: 28,
|
|
20
|
+
visits: 10,
|
|
21
|
+
progress: 75,
|
|
22
|
+
status: 'single',
|
|
23
|
+
id: '1',
|
|
24
|
+
country: 'USA',
|
|
25
|
+
city: 'New York',
|
|
26
|
+
civility: 'Mr.',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
firstName: 'Jane',
|
|
30
|
+
lastName: 'Smith',
|
|
31
|
+
age: 32,
|
|
32
|
+
visits: 15,
|
|
33
|
+
progress: 50,
|
|
34
|
+
status: 'relationship',
|
|
35
|
+
id: '2',
|
|
36
|
+
country: 'USA',
|
|
37
|
+
city: 'Los Angeles',
|
|
38
|
+
civility: 'Ms.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
firstName: 'Alice',
|
|
42
|
+
lastName: 'Johnson',
|
|
43
|
+
age: 24,
|
|
44
|
+
visits: 5,
|
|
45
|
+
progress: 90,
|
|
46
|
+
status: 'single',
|
|
47
|
+
id: '3',
|
|
48
|
+
country: 'Canada',
|
|
49
|
+
city: 'Toronto',
|
|
50
|
+
civility: 'Ms.',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
firstName: 'Bob',
|
|
54
|
+
lastName: 'Brown',
|
|
55
|
+
age: 40,
|
|
56
|
+
visits: 20,
|
|
57
|
+
progress: 30,
|
|
58
|
+
status: 'complicated',
|
|
59
|
+
id: '4',
|
|
60
|
+
country: 'UK',
|
|
61
|
+
city: 'London',
|
|
62
|
+
civility: 'Mr.',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
firstName: 'Charlie',
|
|
66
|
+
lastName: 'Davis',
|
|
67
|
+
age: 35,
|
|
68
|
+
visits: 8,
|
|
69
|
+
progress: 60,
|
|
70
|
+
status: 'relationship',
|
|
71
|
+
id: '5',
|
|
72
|
+
country: 'Australia',
|
|
73
|
+
city: 'Sydney',
|
|
74
|
+
civility: 'Mr.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
firstName: 'Emily',
|
|
78
|
+
lastName: 'Wilson',
|
|
79
|
+
age: 27,
|
|
80
|
+
visits: 12,
|
|
81
|
+
progress: 80,
|
|
82
|
+
status: 'single',
|
|
83
|
+
id: '6',
|
|
84
|
+
country: 'USA',
|
|
85
|
+
city: 'Chicago',
|
|
86
|
+
civility: 'Ms.',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
firstName: 'David',
|
|
90
|
+
lastName: 'Martinez',
|
|
91
|
+
age: 45,
|
|
92
|
+
visits: 25,
|
|
93
|
+
progress: 40,
|
|
94
|
+
status: 'complicated',
|
|
95
|
+
id: '7',
|
|
96
|
+
country: 'Mexico',
|
|
97
|
+
city: 'Mexico City',
|
|
98
|
+
civility: 'Mr.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
firstName: 'Sophia',
|
|
102
|
+
lastName: 'Garcia',
|
|
103
|
+
age: 30,
|
|
104
|
+
visits: 18,
|
|
105
|
+
progress: 70,
|
|
106
|
+
status: 'relationship',
|
|
107
|
+
id: '8',
|
|
108
|
+
country: 'Spain',
|
|
109
|
+
city: 'Madrid',
|
|
110
|
+
civility: 'Ms.',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
firstName: 'Liam',
|
|
114
|
+
lastName: 'Rodriguez',
|
|
115
|
+
age: 22,
|
|
116
|
+
visits: 7,
|
|
117
|
+
progress: 85,
|
|
118
|
+
status: 'single',
|
|
119
|
+
id: '9',
|
|
120
|
+
country: 'USA',
|
|
121
|
+
city: 'Boston',
|
|
122
|
+
civility: 'Mr.',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
firstName: 'Olivia',
|
|
126
|
+
lastName: 'Lee',
|
|
127
|
+
age: 29,
|
|
128
|
+
visits: 11,
|
|
129
|
+
progress: 65,
|
|
130
|
+
status: 'complicated',
|
|
131
|
+
id: '10',
|
|
132
|
+
country: 'Canada',
|
|
133
|
+
city: 'Vancouver',
|
|
134
|
+
civility: 'Ms.',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
firstName: 'Noah',
|
|
138
|
+
lastName: 'Walker',
|
|
139
|
+
age: 33,
|
|
140
|
+
visits: 9,
|
|
141
|
+
progress: 55,
|
|
142
|
+
status: 'relationship',
|
|
143
|
+
id: '11',
|
|
144
|
+
country: 'USA',
|
|
145
|
+
city: 'San Francisco',
|
|
146
|
+
civility: 'Mr.',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
firstName: 'Ava',
|
|
150
|
+
lastName: 'Hall',
|
|
151
|
+
age: 26,
|
|
152
|
+
visits: 14,
|
|
153
|
+
progress: 95,
|
|
154
|
+
status: 'single',
|
|
155
|
+
id: '12',
|
|
156
|
+
country: 'UK',
|
|
157
|
+
city: 'Manchester',
|
|
158
|
+
civility: 'Ms.',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
firstName: 'Ethan',
|
|
162
|
+
lastName: 'Allen',
|
|
163
|
+
age: 38,
|
|
164
|
+
visits: 21,
|
|
165
|
+
progress: 45,
|
|
166
|
+
status: 'complicated',
|
|
167
|
+
id: '13',
|
|
168
|
+
country: 'USA',
|
|
169
|
+
city: 'Houston',
|
|
170
|
+
civility: 'Mr.',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
firstName: 'Mia',
|
|
174
|
+
lastName: 'Young',
|
|
175
|
+
age: 31,
|
|
176
|
+
visits: 16,
|
|
177
|
+
progress: 50,
|
|
178
|
+
status: 'relationship',
|
|
179
|
+
id: '14',
|
|
180
|
+
country: 'Australia',
|
|
181
|
+
city: 'Melbourne',
|
|
182
|
+
civility: 'Ms.',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
firstName: 'William',
|
|
186
|
+
lastName: 'Hernandez',
|
|
187
|
+
age: 42,
|
|
188
|
+
visits: 19,
|
|
189
|
+
progress: 35,
|
|
190
|
+
status: 'complicated',
|
|
191
|
+
id: '15',
|
|
192
|
+
country: 'USA',
|
|
193
|
+
city: 'Phoenix',
|
|
194
|
+
civility: 'Mr.',
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
firstName: 'Isabella',
|
|
198
|
+
lastName: 'King',
|
|
199
|
+
age: 23,
|
|
200
|
+
visits: 6,
|
|
201
|
+
progress: 88,
|
|
202
|
+
status: 'single',
|
|
203
|
+
id: '16',
|
|
204
|
+
country: 'Canada',
|
|
205
|
+
city: 'Ottawa',
|
|
206
|
+
civility: 'Ms.',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
firstName: 'James',
|
|
210
|
+
lastName: 'Wright',
|
|
211
|
+
age: 37,
|
|
212
|
+
visits: 17,
|
|
213
|
+
progress: 60,
|
|
214
|
+
status: 'relationship',
|
|
215
|
+
id: '17',
|
|
216
|
+
country: 'UK',
|
|
217
|
+
city: 'Birmingham',
|
|
218
|
+
civility: 'Mr.',
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
firstName: 'Amelia',
|
|
222
|
+
lastName: 'Lopez',
|
|
223
|
+
age: 34,
|
|
224
|
+
visits: 13,
|
|
225
|
+
progress: 72,
|
|
226
|
+
status: 'complicated',
|
|
227
|
+
id: '18',
|
|
228
|
+
country: 'Spain',
|
|
229
|
+
city: 'Barcelona',
|
|
230
|
+
civility: 'Ms.',
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
firstName: 'Benjamin',
|
|
234
|
+
lastName: 'Hill',
|
|
235
|
+
age: 29,
|
|
236
|
+
visits: 10,
|
|
237
|
+
progress: 80,
|
|
238
|
+
status: 'relationship',
|
|
239
|
+
id: '19',
|
|
240
|
+
country: 'USA',
|
|
241
|
+
city: 'Seattle',
|
|
242
|
+
civility: 'Mr.',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
firstName: 'Charlotte',
|
|
246
|
+
lastName: 'Scott',
|
|
247
|
+
age: 28,
|
|
248
|
+
visits: 8,
|
|
249
|
+
progress: 65,
|
|
250
|
+
status: 'single',
|
|
251
|
+
id: '20',
|
|
252
|
+
country: 'USA',
|
|
253
|
+
city: 'Austin',
|
|
254
|
+
civility: 'Ms.',
|
|
255
|
+
},
|
|
256
|
+
];
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { ColumnDef } from '@tanstack/react-table';
|
|
2
|
+
import { Person } from './mock-data';
|
|
3
|
+
import { Checkbox } from '@/components/forms/checkbox/Checkbox';
|
|
4
|
+
import { Button } from '@/components/button';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
|
|
7
|
+
const PinHeaderColumns = ({
|
|
8
|
+
content,
|
|
9
|
+
onPinClick,
|
|
10
|
+
isPinned,
|
|
11
|
+
}: {
|
|
12
|
+
content: string;
|
|
13
|
+
onPinClick: () => void;
|
|
14
|
+
isPinned: boolean;
|
|
15
|
+
}) => {
|
|
16
|
+
return (
|
|
17
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
18
|
+
{onPinClick ? (
|
|
19
|
+
<Button
|
|
20
|
+
data-testid={`sticky-header-pin-button`}
|
|
21
|
+
variant="link"
|
|
22
|
+
size="sm"
|
|
23
|
+
iconLeft="pin"
|
|
24
|
+
onClick={onPinClick}
|
|
25
|
+
ariaLabel={isPinned ? 'Unpin column' : 'Pin column'}
|
|
26
|
+
className={`tanstack-table__column--${isPinned ? 'is-pinned' : 'is-not-pinned'} pa-0`}
|
|
27
|
+
/>
|
|
28
|
+
) : null}
|
|
29
|
+
<span>{content}</span>{' '}
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const CheckboxContainer = styled.div`
|
|
35
|
+
padding: 14px;
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
export const columns = [
|
|
39
|
+
{
|
|
40
|
+
id: 'select',
|
|
41
|
+
size: 48,
|
|
42
|
+
meta: {
|
|
43
|
+
styles: {
|
|
44
|
+
definedColumnSize: true,
|
|
45
|
+
header: {
|
|
46
|
+
hasNoPadding: true,
|
|
47
|
+
},
|
|
48
|
+
cell: {
|
|
49
|
+
hasNoPadding: true,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
header: ({ table }) => (
|
|
54
|
+
<CheckboxContainer>
|
|
55
|
+
<Checkbox
|
|
56
|
+
data-testid="select-all-checkbox"
|
|
57
|
+
name="select-all"
|
|
58
|
+
id="select-all"
|
|
59
|
+
label=""
|
|
60
|
+
isChecked={table.getIsAllPageRowsSelected()}
|
|
61
|
+
onChange={() => {
|
|
62
|
+
table
|
|
63
|
+
.getRowModel()
|
|
64
|
+
.rows.forEach((row) =>
|
|
65
|
+
row.toggleSelected(!table.getRowModel().rows[0].getIsSelected()),
|
|
66
|
+
);
|
|
67
|
+
}}
|
|
68
|
+
isDisabled={false}
|
|
69
|
+
aria-label="select-rows-header"
|
|
70
|
+
/>
|
|
71
|
+
</CheckboxContainer>
|
|
72
|
+
),
|
|
73
|
+
cell: (
|
|
74
|
+
{ row }, // todo - look at
|
|
75
|
+
) => (
|
|
76
|
+
<CheckboxContainer>
|
|
77
|
+
<Checkbox
|
|
78
|
+
name="select"
|
|
79
|
+
id={row.id}
|
|
80
|
+
label=""
|
|
81
|
+
aria-label={`checkbox-${row.id}`}
|
|
82
|
+
isChecked={row.getIsSelected()}
|
|
83
|
+
isDisabled={!row.getCanSelect()}
|
|
84
|
+
onChange={row.getToggleSelectedHandler()}
|
|
85
|
+
/>
|
|
86
|
+
</CheckboxContainer>
|
|
87
|
+
),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'firstName',
|
|
91
|
+
accessorKey: 'firstName',
|
|
92
|
+
header: ({ header }) => (
|
|
93
|
+
<PinHeaderColumns
|
|
94
|
+
content="First Name"
|
|
95
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
96
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
97
|
+
/>
|
|
98
|
+
),
|
|
99
|
+
cell: (info) => info.getValue(),
|
|
100
|
+
footer: (props) => props.column.id,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
accessorFn: (row) => row.lastName,
|
|
104
|
+
id: 'lastName',
|
|
105
|
+
cell: (info) => info.getValue(),
|
|
106
|
+
header: ({ header }) => (
|
|
107
|
+
<PinHeaderColumns
|
|
108
|
+
content="Last Name"
|
|
109
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
110
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
111
|
+
/>
|
|
112
|
+
),
|
|
113
|
+
footer: (props) => props.column.id,
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
{
|
|
117
|
+
id: 'age',
|
|
118
|
+
accessorKey: 'age',
|
|
119
|
+
header: ({ header }) => (
|
|
120
|
+
<PinHeaderColumns
|
|
121
|
+
content="Age"
|
|
122
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
123
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
124
|
+
/>
|
|
125
|
+
),
|
|
126
|
+
meta: {
|
|
127
|
+
styles: {
|
|
128
|
+
cell: {
|
|
129
|
+
textAlign: 'right',
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
footer: (props) => props.column.id,
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
{
|
|
137
|
+
id: 'visits',
|
|
138
|
+
accessorKey: 'visits',
|
|
139
|
+
header: ({ header }) => (
|
|
140
|
+
<PinHeaderColumns
|
|
141
|
+
content="Visits"
|
|
142
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
143
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
144
|
+
/>
|
|
145
|
+
),
|
|
146
|
+
meta: {
|
|
147
|
+
styles: {
|
|
148
|
+
cell: {
|
|
149
|
+
textAlign: 'right',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
footer: (props) => props.column.id,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: 'status',
|
|
157
|
+
accessorKey: 'status',
|
|
158
|
+
header: ({ header }) => (
|
|
159
|
+
<PinHeaderColumns
|
|
160
|
+
content="Status"
|
|
161
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
162
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
163
|
+
/>
|
|
164
|
+
),
|
|
165
|
+
footer: (props) => props.column.id,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
id: 'progress',
|
|
169
|
+
accessorKey: 'progress',
|
|
170
|
+
header: ({ header }) => (
|
|
171
|
+
<PinHeaderColumns
|
|
172
|
+
content="Profile Progress"
|
|
173
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
174
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
175
|
+
/>
|
|
176
|
+
),
|
|
177
|
+
meta: {
|
|
178
|
+
styles: {
|
|
179
|
+
cell: {
|
|
180
|
+
textAlign: 'center',
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
footer: (props) => props.column.id,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: 'country',
|
|
188
|
+
accessorKey: 'country',
|
|
189
|
+
header: ({ header }) => (
|
|
190
|
+
<PinHeaderColumns
|
|
191
|
+
content="Country"
|
|
192
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
193
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
194
|
+
/>
|
|
195
|
+
),
|
|
196
|
+
footer: (props) => props.column.id,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: 'city',
|
|
200
|
+
accessorKey: 'city',
|
|
201
|
+
header: ({ header }) => (
|
|
202
|
+
<PinHeaderColumns
|
|
203
|
+
content="City"
|
|
204
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
205
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
206
|
+
/>
|
|
207
|
+
),
|
|
208
|
+
footer: (props) => props.column.id,
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
id: 'civility',
|
|
212
|
+
accessorKey: 'civility',
|
|
213
|
+
header: ({ header }) => (
|
|
214
|
+
<PinHeaderColumns
|
|
215
|
+
content="Civility"
|
|
216
|
+
onPinClick={() => header.column.pin(header.column.getIsPinned() ? false : 'left')}
|
|
217
|
+
isPinned={header.column.getIsPinned() === 'left' ? true : false}
|
|
218
|
+
/>
|
|
219
|
+
),
|
|
220
|
+
footer: (props) => props.column.id,
|
|
221
|
+
},
|
|
222
|
+
] as ColumnDef<Person>[];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Light Theme Specific Variables
|
|
2
|
+
|
|
3
|
+
:root [data-theme='light'] {
|
|
4
|
+
--pf-tanstack-table-background-color: var(--pf-white-color);
|
|
5
|
+
--pf-tanstack-table-font-color: var(--pf-gray-color);
|
|
6
|
+
--pf-tanstack-table-border-color: var(--pf-gray-color-200);
|
|
7
|
+
--pf-tanstack-table-stripe-color: var(--pf-gray-color-100);
|
|
8
|
+
--pf-tanstack-table-hover-color: var(--pf-gray-color-200);
|
|
9
|
+
--pf-tanstack-table-disabled-color: var(--pf-gray-color-300);
|
|
10
|
+
--pf-tanstack-table-checked-color: var(--pf-secondary-color-950);
|
|
11
|
+
--pf-tanstack-table-clicked-color: var(--pf-secondary-color-100);
|
|
12
|
+
--pf-tanstack-table-highlighted-color: var(--pf-gray-color-200);
|
|
13
|
+
--pf-tanstack-table-highlighted-box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2),
|
|
14
|
+
0 8px 16px rgba(0, 0, 0, 0.2);
|
|
15
|
+
--pf-tanstack-table-font-size: var(--pf-font-size-body2);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Dark Theme Specific Variables
|
|
19
|
+
:root [data-theme='dark'],
|
|
20
|
+
:root {
|
|
21
|
+
--pf-tanstack-table-background-color: var(--pf-primary-color-800);
|
|
22
|
+
--pf-tanstack-table-font-color: var(--pf-white-color);
|
|
23
|
+
--pf-tanstack-table-border-color: var(--pf-tertiary-color-800);
|
|
24
|
+
--pf-tanstack-table-stripe-color: var(--pf-primary-color-700);
|
|
25
|
+
--pf-tanstack-table-hover-color: var(--pf-primary-color-600);
|
|
26
|
+
--pf-tanstack-table-disabled-color: var(--pf-gray-color-900);
|
|
27
|
+
--pf-tanstack-table-disabled-button-color: var(--pf-primary-color-100);
|
|
28
|
+
--pf-tanstack-table-checked-color: var(--pf-secondary-color-950);
|
|
29
|
+
--pf-tanstack-table-clicked-color: var(--pf-primary-color);
|
|
30
|
+
--pf-tanstack-table-highlighted-color: var(--pf-primary-color);
|
|
31
|
+
--pf-tanstack-table-highlighted-box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4),
|
|
32
|
+
0 8px 16px rgba(0, 0, 0, 0.3);
|
|
33
|
+
--pf-tanstack-table-font-size: var(--pf-font-size-body2);
|
|
34
|
+
--pf-tanstack-table-pagination-background-color: var(--pf-primary-color-700);
|
|
35
|
+
}
|