@indico-data/design-system 2.51.0 → 2.51.2

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 (34) hide show
  1. package/lib/components/index.d.ts +1 -0
  2. package/lib/components/tanstackTable/TankstackTable.types.d.ts +7 -2
  3. package/lib/components/tanstackTable/TanstackTable.stories.d.ts +1 -0
  4. package/lib/components/tanstackTable/TanstakTable.d.ts +1 -1
  5. package/lib/components/tanstackTable/components/TableBody/TableBody.d.ts +5 -6
  6. package/lib/components/tanstackTable/components/TablePagination/TablePagination.d.ts +1 -1
  7. package/lib/components/tanstackTable/index.d.ts +1 -1
  8. package/lib/components/tanstackTable/useTanstackTable.d.ts +0 -2
  9. package/lib/index.css +33 -18
  10. package/lib/index.d.ts +9 -3
  11. package/lib/index.esm.css +33 -18
  12. package/lib/index.esm.js +22 -45
  13. package/lib/index.esm.js.map +1 -1
  14. package/lib/index.js +22 -45
  15. package/lib/index.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/components/index.ts +1 -0
  18. package/src/components/tanstackTable/TankstackTable.types.ts +7 -2
  19. package/src/components/tanstackTable/TanstackTable.stories.tsx +34 -10
  20. package/src/components/tanstackTable/TanstakTable.tsx +8 -9
  21. package/src/components/tanstackTable/__tests__/TanstackTable.test.tsx +3 -17
  22. package/src/components/tanstackTable/components/ActionBar/ActionBar.scss +1 -1
  23. package/src/components/tanstackTable/components/ActionBar/ActionBar.tsx +0 -8
  24. package/src/components/tanstackTable/components/ActionBar/__tests__/ActionBar.test.tsx +0 -22
  25. package/src/components/tanstackTable/components/TableBody/TableBody.tsx +12 -22
  26. package/src/components/tanstackTable/components/TablePagination/TablePagination.tsx +2 -2
  27. package/src/components/tanstackTable/helpers.ts +1 -1
  28. package/src/components/tanstackTable/index.ts +1 -1
  29. package/src/components/tanstackTable/mock-data/table-configuration.tsx +4 -1
  30. package/src/components/tanstackTable/styles/table.scss +36 -22
  31. package/src/components/tanstackTable/tanstack-table.d.ts +1 -0
  32. package/src/components/tanstackTable/useTanstackTable.tsx +0 -3
  33. package/src/index.ts +7 -0
  34. package/src/stylesAndAnimations/utilityClasses/UtilityClassesTable.tsx +16 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indico-data/design-system",
3
- "version": "2.51.0",
3
+ "version": "2.51.2",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "main": "lib/index.js",
@@ -21,3 +21,4 @@ export { InputDateRangePicker } from './forms/date/inputDateRangePicker';
21
21
  export { Modal } from './modal';
22
22
  export { Badge } from './badge';
23
23
  export { Pagination } from './pagination';
24
+ export { TanstackTable } from './tanstackTable';
@@ -3,7 +3,7 @@ import { Row, ColumnDef } from '@tanstack/react-table';
3
3
  export type WithPaginationProps = {
4
4
  rowsPerPage: number;
5
5
  rowCount: number;
6
- onChangePage: (page: number, perPage: number) => void;
6
+ onChangePage: (page: number) => void;
7
7
  currentPage: number;
8
8
  totalEntriesText?: string;
9
9
  showPagination: true;
@@ -12,7 +12,7 @@ export type WithPaginationProps = {
12
12
  export type WithoutPaginationProps = {
13
13
  rowsPerPage?: number;
14
14
  rowCount?: number;
15
- onChangePage?: (page: number, perPage: number) => void;
15
+ onChangePage?: (page: number) => void;
16
16
  currentPage?: number;
17
17
  totalEntriesText?: string;
18
18
  showPagination?: false;
@@ -36,4 +36,9 @@ export type Props<T extends object> = {
36
36
  isLoading?: boolean;
37
37
  defaultPinnedColumns?: string[];
38
38
  onClickRow?: ((row: Row<T>) => void) | null;
39
+ onRowClick?: (row: T) => void;
40
+ activeRows?: string[];
41
+ rowSelection?: Record<string, boolean>;
42
+ onRowSelectionChange?: (updater: Record<string, boolean>) => void;
43
+ onSelectAllChange?: (isSelected: boolean) => void;
39
44
  } & PaginationProps;
@@ -5,7 +5,7 @@ import { people, Person } from './mock-data/mock-data';
5
5
  import { columns } from './mock-data/table-configuration';
6
6
  import { ColumnDef, Row } from '@tanstack/react-table';
7
7
  import { Button } from '../button';
8
-
8
+ import { useState } from 'react';
9
9
  const meta: Meta = {
10
10
  title: 'Layout/Tanstack Table',
11
11
  component: TanstackTable,
@@ -182,13 +182,7 @@ const meta: Meta = {
182
182
  },
183
183
  },
184
184
  },
185
- decorators: [
186
- (Story) => (
187
- <div style={{ width: '100%', height: '500px', overflow: 'hidden' }}>
188
- <Story />
189
- </div>
190
- ),
191
- ],
185
+ decorators: [(Story) => <Story />],
192
186
  };
193
187
 
194
188
  export default meta;
@@ -199,10 +193,23 @@ export const Default: Story = {};
199
193
 
200
194
  export const WithRowClick: Story = {
201
195
  args: {
202
- onClickRow: (row: Row<Person>) => {
203
- console.log(row);
196
+ onRowClick: (row: any) => {
197
+ return row.original;
204
198
  },
205
199
  },
200
+
201
+ render: (args) => {
202
+ const [clickedItem, setClickedItem] = useState<Person | undefined>(undefined);
203
+ return (
204
+ <div style={{ width: '700px', height: '500px', overflow: 'hidden' }}>
205
+ <TanstackTable<Person>
206
+ {...args}
207
+ activeRows={clickedItem ? [clickedItem.id as string] : []}
208
+ onRowClick={(row) => setClickedItem(row as any)}
209
+ />
210
+ </div>
211
+ );
212
+ },
206
213
  };
207
214
 
208
215
  export const PinnedColumns: Story = {
@@ -258,3 +265,20 @@ export const WithPagination: Story = {
258
265
  onChangePage: () => {},
259
266
  },
260
267
  };
268
+
269
+ export const WithRowSelection: Story = {
270
+ args: {
271
+ showPagination: true,
272
+ rowCount: people.length,
273
+ currentPage: 1,
274
+ rowsPerPage: 20,
275
+ onChangePage: () => {},
276
+ },
277
+ render: (args) => {
278
+ return (
279
+ <div style={{ width: '700px', height: '500px', overflow: 'hidden' }}>
280
+ <TanstackTable<Person> {...args} />
281
+ </div>
282
+ );
283
+ },
284
+ };
@@ -29,25 +29,24 @@ export function TanstackTable<T extends object>({
29
29
  showPagination = true,
30
30
  isLoading = false,
31
31
  defaultPinnedColumns,
32
- onClickRow = null,
32
+ onRowClick,
33
+ activeRows = [],
33
34
  actionBarClassName,
35
+ ...rest
34
36
  }: Props<T & { id: string }>) {
35
37
  const {
36
38
  columns,
37
39
  defaultData,
38
40
  windowWidth,
39
- rowSelection,
41
+ rowSelection, // This refers to the checkboxes.
40
42
  setRowSelection,
41
43
  formattedColumns,
42
44
  setFormattedColumns,
43
- isClickedRow,
44
- setIsClickedRow,
45
45
  } = useTanstackTable({
46
46
  defaultColumns,
47
47
  });
48
48
 
49
49
  const thRefs = useRef<Record<string, HTMLTableCellElement | null>>({});
50
-
51
50
  // Sets formattedColumns with correct column widths
52
51
  useEffect(() => {
53
52
  const updatedColumns: ColumnDef<T & { id: string }>[] = [];
@@ -64,6 +63,7 @@ export function TanstackTable<T extends object>({
64
63
  }, [data, columns, windowWidth]);
65
64
 
66
65
  const table = useReactTable({
66
+ ...rest,
67
67
  data: data ?? defaultData,
68
68
  columns: formattedColumns,
69
69
  state: {
@@ -73,7 +73,7 @@ export function TanstackTable<T extends object>({
73
73
  onRowSelectionChange: setRowSelection,
74
74
  getCoreRowModel: getCoreRowModel(),
75
75
  manualPagination: true,
76
- debugTable: true,
76
+ getRowId: (row) => row?.id,
77
77
  initialState: {
78
78
  columnPinning: {
79
79
  left: defaultPinnedColumns,
@@ -116,11 +116,10 @@ export function TanstackTable<T extends object>({
116
116
  return (
117
117
  <TableBody<T & { id: string }>
118
118
  table={table}
119
- onClickRow={onClickRow}
119
+ onRowClick={onRowClick}
120
120
  isLoading={isLoading}
121
121
  columnsLength={columns.length}
122
- isClickedRow={isClickedRow}
123
- setIsClickedRow={setIsClickedRow}
122
+ activeRows={activeRows}
124
123
  />
125
124
  );
126
125
  };
@@ -30,27 +30,13 @@ describe('Tanstack Table Component', () => {
30
30
 
31
31
  test('handles click on checkbox to select row', () => {
32
32
  render(<TanstackTable columns={columns} data={data} enableRowSelection={true} />);
33
- const indexRow = 0;
34
- const firstCheckbox = screen.getByTestId(`checkbox-${indexRow}`);
33
+ const firstCheckbox = screen.getByTestId(`checkbox-${data[0].id}`);
35
34
  fireEvent.click(firstCheckbox);
36
- const firstRow = screen.getByText(data[indexRow].name).closest('tr');
35
+ const firstRow = screen.getByText(data[0].name).closest('tr');
37
36
  expect(firstRow).toHaveClass('is-selected');
38
37
  });
39
38
 
40
- test('handles click on a row with onClickRow property', () => {
41
- const onClickRow = jest.fn();
42
- render(
43
- <TanstackTable
44
- columns={columns}
45
- data={data}
46
- enableRowSelection={true}
47
- onClickRow={onClickRow}
48
- />,
49
- );
50
- const firstRow = screen.getByText(data[0].name);
51
- fireEvent.click(firstRow);
52
- expect(onClickRow).toHaveBeenCalled();
53
- });
39
+ it.todo('handles click on a row with onClickRow property');
54
40
 
55
41
  test('renders pagination when showPagination is true', () => {
56
42
  render(
@@ -4,7 +4,7 @@
4
4
  left: 50%;
5
5
  transform: translateX(-50%);
6
6
  z-index: 90;
7
-
7
+ box-shadow: 3px 1px 15px 0 rgba(0, 0, 0, 0.85);
8
8
  &__container {
9
9
  display: flex;
10
10
  align-items: center;
@@ -27,18 +27,10 @@ export function ActionBar<T extends object>({
27
27
  });
28
28
  };
29
29
 
30
- const getSelectedItemsText = () => {
31
- if (selectedItems.length === 1) return '1 item selected';
32
- return `${selectedItems.length} items selected`;
33
- };
34
-
35
30
  return (
36
31
  <Card className={classNames('tanstack-table__action-bar', className)}>
37
32
  {children ?? (
38
33
  <div className="tanstack-table__action-bar__container">
39
- <div className="tanstack-table__action-bar__text-container">
40
- <span>{getSelectedItemsText()}</span>
41
- </div>
42
34
  {TableActions && (
43
35
  <div className="tanstack-table__action-bar__button-container">
44
36
  <TableActions selectedItems={selectedItems} unselectRows={unselectRows} />
@@ -14,28 +14,6 @@ const createDummyTable = (rows: DummyRow[]): Table<any> =>
14
14
  }) as Table<any>;
15
15
 
16
16
  describe('ActionBar', () => {
17
- it('renders correct text for one selected row', () => {
18
- const dummyRows: DummyRow[] = [
19
- { getIsSelected: () => true, toggleSelected: jest.fn() },
20
- { getIsSelected: () => false, toggleSelected: jest.fn() },
21
- ];
22
- const dummyTable = createDummyTable(dummyRows);
23
-
24
- render(<ActionBar table={dummyTable} />);
25
- expect(screen.getByText('1 item selected')).toBeDefined();
26
- });
27
-
28
- it('renders correct text for multiple selected rows', () => {
29
- const dummyRows: DummyRow[] = [
30
- { getIsSelected: () => true, toggleSelected: jest.fn() },
31
- { getIsSelected: () => true, toggleSelected: jest.fn() },
32
- ];
33
- const dummyTable = createDummyTable(dummyRows);
34
-
35
- render(<ActionBar table={dummyTable} />);
36
- expect(screen.getByText('2 items selected')).toBeDefined();
37
- });
38
-
39
17
  it('renders correct when use a children prop', () => {
40
18
  const dummyRows: DummyRow[] = [
41
19
  { getIsSelected: () => true, toggleSelected: jest.fn() },
@@ -7,45 +7,29 @@ import { Dispatch, SetStateAction } from 'react';
7
7
 
8
8
  export type Props<T> = {
9
9
  table: Table<T>;
10
- onClickRow?: ((row: Row<T>) => void) | null;
10
+ onRowClick?: ((row: T & { id: string }) => void) | null | undefined;
11
11
  isLoading: boolean;
12
12
  columnsLength: number;
13
- isClickedRow: string[];
14
- setIsClickedRow: Dispatch<SetStateAction<string[]>>;
13
+ activeRows: string[];
15
14
  };
16
15
 
17
16
  export const TableBody = <T,>({
18
17
  table,
19
- onClickRow,
18
+ onRowClick,
20
19
  isLoading,
21
20
  columnsLength,
22
- isClickedRow,
23
- setIsClickedRow,
21
+ activeRows,
24
22
  }: Props<T>) => {
25
- const toggleRow = (id: string) => {
26
- if (isClickedRow.includes(id)) {
27
- setIsClickedRow((state) => state.filter((item) => item !== id));
28
- } else {
29
- setIsClickedRow((state) => [...state, id]);
30
- }
31
- };
32
-
33
23
  return (
34
24
  <>
35
25
  {table.getRowModel().rows.map((row) => (
36
26
  <tr
37
27
  className={classNames('tanstack-table__tbody__tr', {
38
28
  'is-selected': row.getIsSelected(),
39
- 'show-hover': !!onClickRow,
40
- 'is-clicked': isClickedRow.includes(row.id),
29
+ 'show-hover': !!onRowClick,
30
+ 'is-clicked': activeRows.includes(row.id), // Checkbox Is clicked
41
31
  })}
42
32
  key={row.id}
43
- onClick={() => {
44
- if (!!onClickRow) {
45
- toggleRow(row.id);
46
- onClickRow(row);
47
- }
48
- }}
49
33
  >
50
34
  {row.getVisibleCells().map((cell) => {
51
35
  const { columnDef } = cell.column;
@@ -63,6 +47,12 @@ export const TableBody = <T,>({
63
47
  cell.column.getSize(),
64
48
  ),
65
49
  }}
50
+ onClick={() => {
51
+ // if the cell is not preventRowSelection, then we can click the row
52
+ if (!columnDef.meta?.styles?.cell?.preventRowSelection) {
53
+ onRowClick?.(row as any);
54
+ }
55
+ }}
66
56
  >
67
57
  {flexRender(columnDef.cell, cell.getContext())}
68
58
  </td>
@@ -4,7 +4,7 @@ import { Row, Col } from '../../../grid';
4
4
  interface TablePaginationProps {
5
5
  rowsPerPage: number;
6
6
  rowCount: number;
7
- onChangePage: (page: number, perPage: number) => void;
7
+ onChangePage: (page: number) => void;
8
8
  currentPage: number;
9
9
  totalEntriesText?: string;
10
10
  }
@@ -36,7 +36,7 @@ export const TablePagination = ({
36
36
  data-testid="table-pagination-component"
37
37
  totalPages={totalPages}
38
38
  currentPage={currentPage}
39
- onChange={(page) => onChangePage(page, rowsPerPage)}
39
+ onChange={(page) => onChangePage(page)}
40
40
  />
41
41
  </Col>
42
42
  </Row>
@@ -8,7 +8,7 @@ const getCommonPinningStyles = <T>(column: Column<T>): CSSProperties => {
8
8
  return {
9
9
  boxShadow: isLastLeftPinnedColumn ? '-4px 0 4px -4px gray inset' : undefined,
10
10
  left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,
11
- position: isPinned ? 'sticky' : 'relative',
11
+ position: isPinned ? 'sticky' : 'initial',
12
12
  zIndex: isPinned ? 1 : 0,
13
13
  };
14
14
  };
@@ -1,2 +1,2 @@
1
- export type { ColumnDef } from '@tanstack/react-table';
1
+ export type { ColumnDef, Row, Table } from '@tanstack/react-table';
2
2
  export { TanstackTable } from './TanstakTable';
@@ -53,6 +53,7 @@ export const columns = [
53
53
  header: ({ table }) => (
54
54
  <CheckboxContainer>
55
55
  <Checkbox
56
+ data-testid="select-all-checkbox"
56
57
  name="select-all"
57
58
  id="select-all"
58
59
  label=""
@@ -69,7 +70,9 @@ export const columns = [
69
70
  />
70
71
  </CheckboxContainer>
71
72
  ),
72
- cell: ({ row }) => (
73
+ cell: (
74
+ { row }, // todo - look at
75
+ ) => (
73
76
  <CheckboxContainer>
74
77
  <Checkbox
75
78
  name="select"
@@ -5,16 +5,28 @@
5
5
  @import '../components/NoResults/NoResults.scss';
6
6
 
7
7
  .tanstack-table__outer-container {
8
- display: flex;
9
- flex-direction: column;
10
- width: 100%;
11
- height: 100%;
8
+ .tanstack-table__column--is-pinned {
9
+ opacity: 1;
10
+ }
11
+
12
+ .tanstack-table__column--is-not-pinned {
13
+ opacity: 0.3;
14
+ }
12
15
 
13
16
  .tanstack-table__container {
14
- position: relative;
15
- display: block;
16
- overflow: auto;
17
- height: 100%;
17
+ height: calc(100vh - 70px);
18
+ grid-template-rows: auto 1fr auto;
19
+ grid-template-columns: 1fr;
20
+ display: grid;
21
+ grid-template-rows: auto 1fr auto;
22
+ grid-template-columns: 1fr;
23
+ overflow-x: auto;
24
+ overflow-y: auto;
25
+ background-color: var(--pf-tanstack-table-background-color);
26
+ border-radius: var(--pf-rounded-lg);
27
+ border-left: var(--pf-border-sm) solid var(--pf-tanstack-table-border-color);
28
+ border-right: var(--pf-border-sm) solid var(--pf-tanstack-table-border-color);
29
+ border-bottom: var(--pf-border-sm) solid var(--pf-tanstack-table-border-color);
18
30
 
19
31
  // Webkit scrollbar styles
20
32
  &::-webkit-scrollbar {
@@ -61,7 +73,7 @@
61
73
  &__thead {
62
74
  position: sticky;
63
75
  top: 0;
64
- z-index: 100;
76
+ z-index: 3;
65
77
  box-sizing: border-box;
66
78
 
67
79
  background-color: var(--pf-tanstack-table-background-color);
@@ -69,11 +81,11 @@
69
81
  tr:first-child {
70
82
  th {
71
83
  &:first-child {
72
- border-top-left-radius: var(--pf-rounded-lg);
84
+ border-left: none;
73
85
  }
74
86
 
75
87
  &:last-child {
76
- border-top-right-radius: var(--pf-rounded-lg);
88
+ border-right: none;
77
89
  }
78
90
  }
79
91
  }
@@ -101,27 +113,25 @@
101
113
  text-align: left;
102
114
 
103
115
  &:first-child {
104
- border-left: var(--pf-border-sm) solid var(--pf-tanstack-table-border-color);
116
+ border-left: none;
117
+ }
118
+
119
+ &:last-child {
120
+ border-right: none;
105
121
  }
106
122
  }
107
123
  }
108
124
 
109
125
  &__tbody {
110
126
  tr:last-child {
111
- td {
112
- &:first-child {
113
- border-bottom-left-radius: var(--pf-rounded-lg);
114
- }
115
-
116
- &:last-child {
117
- border-bottom-right-radius: var(--pf-rounded-lg);
118
- }
119
- }
127
+ border-bottom: none;
120
128
  }
121
129
 
122
130
  &__tr {
123
131
  background: transparent;
124
132
  width: 100%;
133
+ border-left: none;
134
+ border-right: none;
125
135
 
126
136
  &.is-selected {
127
137
  td {
@@ -166,7 +176,11 @@
166
176
  text-align: left;
167
177
 
168
178
  &:first-child {
169
- border-left: var(--pf-border-sm) solid var(--pf-tanstack-table-border-color);
179
+ border-left: none;
180
+ }
181
+
182
+ &:last-child {
183
+ border-right: none;
170
184
  }
171
185
  }
172
186
  }
@@ -12,6 +12,7 @@ declare module '@tanstack/react-table' {
12
12
  cell?: {
13
13
  hasNoPadding?: boolean;
14
14
  textAlign?: 'left' | 'center' | 'right';
15
+ preventRowSelection?: boolean;
15
16
  };
16
17
  };
17
18
  }
@@ -13,7 +13,6 @@ export function useTanstackTable<T>({ defaultColumns }: Props<T>) {
13
13
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);
14
14
  const [rowSelection, setRowSelection] = useState({});
15
15
  const [formattedColumns, setFormattedColumns] = useState<ColumnDef<T>[]>(columns);
16
- const [isClickedRow, setIsClickedRow] = useState<string[]>([]);
17
16
 
18
17
  // Tracks changes to browser width to allow for updating of column widths
19
18
  useEffect(() => {
@@ -36,7 +35,5 @@ export function useTanstackTable<T>({ defaultColumns }: Props<T>) {
36
35
  windowWidth,
37
36
  formattedColumns,
38
37
  setFormattedColumns,
39
- isClickedRow,
40
- setIsClickedRow,
41
38
  };
42
39
  }
package/src/index.ts CHANGED
@@ -32,3 +32,10 @@ export { TanstackTable } from './components/tanstackTable';
32
32
 
33
33
  // Utilities
34
34
  export { registerFontAwesomeIcons } from './setup/setupIcons';
35
+
36
+ // Types
37
+ export type {
38
+ ColumnDef,
39
+ Row as TanstackTableRowType,
40
+ Table as TanstackTableType,
41
+ } from '@tanstack/react-table';
@@ -101,8 +101,15 @@ export const UtilityClassesTable = () => {
101
101
 
102
102
  <Table
103
103
  columns={[
104
- { name: 'Class Name', selector: (row) => row.className, sortable: true, width: '225px' },
105
104
  {
105
+ id: 'className',
106
+ name: 'Class Name',
107
+ selector: (row) => row.className,
108
+ sortable: true,
109
+ width: '225px',
110
+ },
111
+ {
112
+ id: 'cssApplied',
106
113
  name: 'CSS Applied',
107
114
  selector: (row) => formatCss(row.css),
108
115
  sortable: true,
@@ -119,6 +126,7 @@ export const UtilityClassesTable = () => {
119
126
  ),
120
127
  },
121
128
  {
129
+ id: 'resolvedCss',
122
130
  name: 'Resolved CSS',
123
131
  selector: (row) => formatCss(row.resolvedCss || ''),
124
132
  sortable: true,
@@ -134,7 +142,13 @@ export const UtilityClassesTable = () => {
134
142
  </pre>
135
143
  ),
136
144
  },
137
- { name: 'Category', selector: (row) => row.category, sortable: true, width: '114px' },
145
+ {
146
+ id: 'category',
147
+ name: 'Category',
148
+ selector: (row) => row.category,
149
+ sortable: true,
150
+ width: '114px',
151
+ },
138
152
  ]}
139
153
  data={filteredData}
140
154
  dense