@purpurds/table 8.3.0 → 8.4.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 +205 -35
- package/dist/drag-indicator-circle.d.ts +13 -0
- package/dist/drag-indicator-circle.d.ts.map +1 -0
- package/dist/draggable-table.d.ts +23 -0
- package/dist/draggable-table.d.ts.map +1 -0
- package/dist/empty-table.d.ts +14 -0
- package/dist/empty-table.d.ts.map +1 -0
- package/dist/loading-table-rows.d.ts +13 -0
- package/dist/loading-table-rows.d.ts.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/table-body.d.ts +2 -2
- package/dist/table-body.d.ts.map +1 -1
- package/dist/table-column-header-cell.d.ts +15 -2
- package/dist/table-column-header-cell.d.ts.map +1 -1
- package/dist/table-content.d.ts +42 -0
- package/dist/table-content.d.ts.map +1 -0
- package/dist/table-headers.d.ts +28 -0
- package/dist/table-headers.d.ts.map +1 -0
- package/dist/table-row-cell-skeleton.d.ts +1 -1
- package/dist/table-row-cell-skeleton.d.ts.map +1 -1
- package/dist/table-row-cell.d.ts +5 -2
- package/dist/table-row-cell.d.ts.map +1 -1
- package/dist/table-row.d.ts +2 -2
- package/dist/table-row.d.ts.map +1 -1
- package/dist/table-settings-drawer.d.ts +44 -11
- package/dist/table-settings-drawer.d.ts.map +1 -1
- package/dist/table.cjs.js +89 -85
- package/dist/table.cjs.js.map +1 -1
- package/dist/table.d.ts +3 -3
- package/dist/table.d.ts.map +1 -1
- package/dist/table.es.js +14397 -10195
- package/dist/table.es.js.map +1 -1
- package/dist/test-utils/helpers.d.ts +1 -0
- package/dist/test-utils/helpers.d.ts.map +1 -1
- package/dist/types.d.ts +23 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/use-drag-handle.hook.d.ts +15 -0
- package/dist/use-drag-handle.hook.d.ts.map +1 -0
- package/dist/use-drag-indicator-position.hook.d.ts +19 -0
- package/dist/use-drag-indicator-position.hook.d.ts.map +1 -0
- package/dist/use-drop-indicator.hook.d.ts +15 -0
- package/dist/use-drop-indicator.hook.d.ts.map +1 -0
- package/dist/use-element-visibility.hook.d.ts +4 -0
- package/dist/use-element-visibility.hook.d.ts.map +1 -0
- package/dist/use-table-scroll.hook.d.ts +6 -0
- package/dist/use-table-scroll.hook.d.ts.map +1 -0
- package/dist/utils/custom-keyboard-coordinates.d.ts +8 -0
- package/dist/utils/custom-keyboard-coordinates.d.ts.map +1 -0
- package/package.json +27 -23
- package/src/drag-indicator-circle.tsx +36 -0
- package/src/draggable-table.test.tsx +381 -0
- package/src/draggable-table.tsx +191 -0
- package/src/empty-table.tsx +54 -0
- package/src/loading-table-rows.tsx +41 -0
- package/src/table-body.tsx +1 -3
- package/src/table-column-header-cell.tsx +135 -64
- package/src/table-content-drag.test.tsx +505 -0
- package/src/table-content.tsx +165 -0
- package/src/table-dnd-integration.test.tsx +425 -0
- package/src/table-drag-and-drop.test.tsx +276 -0
- package/src/table-headers.tsx +118 -0
- package/src/table-row-cell-skeleton.tsx +1 -1
- package/src/table-row-cell.test.tsx +2 -1
- package/src/table-row-cell.tsx +42 -31
- package/src/table-row.tsx +1 -3
- package/src/table-settings-drawer.module.scss +165 -2
- package/src/table-settings-drawer.test.tsx +0 -99
- package/src/table-settings-drawer.tsx +359 -53
- package/src/table.module.scss +191 -30
- package/src/table.stories.tsx +60 -4
- package/src/table.test.tsx +5 -1
- package/src/table.tsx +255 -213
- package/src/test-utils/helpers.ts +2 -0
- package/src/types.ts +25 -2
- package/src/use-drag-handle.hook.tsx +60 -0
- package/src/use-drag-handle.test.tsx +380 -0
- package/src/use-drag-indicator-position.hook.ts +74 -0
- package/src/use-drop-indicator.hook.ts +46 -0
- package/src/use-element-visibility.hook.ts +28 -0
- package/src/use-table-scroll.hook.tsx +30 -0
- package/src/utils/custom-keyboard-coordinates.ts +83 -0
- package/vitest.setup.ts +1 -1
|
@@ -1,15 +1,46 @@
|
|
|
1
|
-
import React, { useId } from "react";
|
|
1
|
+
import React, { useId, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
closestCenter,
|
|
4
|
+
DndContext,
|
|
5
|
+
type DragEndEvent,
|
|
6
|
+
DragOverlay,
|
|
7
|
+
type DragStartEvent,
|
|
8
|
+
KeyboardSensor,
|
|
9
|
+
PointerSensor,
|
|
10
|
+
TouchSensor,
|
|
11
|
+
type UniqueIdentifier,
|
|
12
|
+
useSensor,
|
|
13
|
+
useSensors,
|
|
14
|
+
} from "@dnd-kit/core";
|
|
15
|
+
import { restrictToParentElement, restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
16
|
+
import {
|
|
17
|
+
arrayMove,
|
|
18
|
+
SortableContext,
|
|
19
|
+
sortableKeyboardCoordinates,
|
|
20
|
+
useSortable,
|
|
21
|
+
verticalListSortingStrategy,
|
|
22
|
+
} from "@dnd-kit/sortable";
|
|
2
23
|
import { Button } from "@purpurds/button";
|
|
3
24
|
import { Drawer } from "@purpurds/drawer";
|
|
4
25
|
import { Heading } from "@purpurds/heading";
|
|
26
|
+
import { IconArrowDown } from "@purpurds/icon/arrow-down";
|
|
27
|
+
import { IconArrowUp } from "@purpurds/icon/arrow-up";
|
|
28
|
+
import { IconDragVertical } from "@purpurds/icon/drag-vertical";
|
|
29
|
+
import { IconSorter } from "@purpurds/icon/sorter";
|
|
5
30
|
import { IconSync } from "@purpurds/icon/sync";
|
|
31
|
+
import { Paragraph } from "@purpurds/paragraph";
|
|
6
32
|
import { Toggle } from "@purpurds/toggle";
|
|
33
|
+
import {
|
|
34
|
+
purpurMotionDuration150,
|
|
35
|
+
purpurMotionEasingEaseInOut,
|
|
36
|
+
} from "@purpurds/tokens/motion/variables";
|
|
7
37
|
import { type Column, type RowData } from "@tanstack/react-table";
|
|
8
38
|
import c from "classnames/bind";
|
|
9
39
|
|
|
10
40
|
import styles from "./table-settings-drawer.module.scss";
|
|
41
|
+
import { useDropIndicator } from "./use-drop-indicator.hook";
|
|
11
42
|
|
|
12
|
-
export type TableSettingsDrawerCopyProps = {
|
|
43
|
+
export type TableSettingsDrawerCopyProps<TEnableDrag extends boolean = boolean> = {
|
|
13
44
|
title: string;
|
|
14
45
|
generalSettings: {
|
|
15
46
|
header: string;
|
|
@@ -17,18 +48,60 @@ export type TableSettingsDrawerCopyProps = {
|
|
|
17
48
|
showFilters: string;
|
|
18
49
|
lockFirstcolumn: string;
|
|
19
50
|
stickyHeader: string;
|
|
20
|
-
rowSelection?: string;
|
|
21
51
|
};
|
|
22
52
|
};
|
|
23
|
-
visibleColumns:
|
|
24
|
-
|
|
25
|
-
|
|
53
|
+
visibleColumns: TEnableDrag extends true
|
|
54
|
+
? VisibleColumnsWithColumnDragCopyProps
|
|
55
|
+
: VisibleColumnsWithoutColumnDragCopyProps;
|
|
26
56
|
buttons: {
|
|
27
57
|
closeDrawer: string;
|
|
28
58
|
resetSettings: string;
|
|
29
59
|
};
|
|
30
60
|
};
|
|
31
61
|
|
|
62
|
+
type VisibleColumnsCopyBaseProps = {
|
|
63
|
+
header: string;
|
|
64
|
+
description: string;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
type VisibleColumnsWithColumnDragCopyProps = VisibleColumnsCopyBaseProps & {
|
|
68
|
+
rearrangeDescription: string;
|
|
69
|
+
buttons: {
|
|
70
|
+
rearrange: string;
|
|
71
|
+
done: string;
|
|
72
|
+
};
|
|
73
|
+
ariaLabels: {
|
|
74
|
+
dragHandle: {
|
|
75
|
+
action: string;
|
|
76
|
+
instructions: string;
|
|
77
|
+
};
|
|
78
|
+
arrowButtons: {
|
|
79
|
+
move: string;
|
|
80
|
+
up: string;
|
|
81
|
+
down: string;
|
|
82
|
+
};
|
|
83
|
+
rearrangeButton: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type VisibleColumnsWithoutColumnDragCopyProps = VisibleColumnsCopyBaseProps & {
|
|
88
|
+
rearrangeDescription?: never;
|
|
89
|
+
buttons?: never;
|
|
90
|
+
ariaLabels?: never;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
type ColumnDragEnabledProps = {
|
|
94
|
+
enableColumnDrag: true;
|
|
95
|
+
onColumnOrderChange: (newColumnOrder: string[]) => void;
|
|
96
|
+
copy: TableSettingsDrawerCopyProps<true>;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
type ColumnDragDisabledProps = {
|
|
100
|
+
enableColumnDrag?: false;
|
|
101
|
+
onColumnOrderChange?: never;
|
|
102
|
+
copy: TableSettingsDrawerCopyProps<false>;
|
|
103
|
+
};
|
|
104
|
+
|
|
32
105
|
export type TableSettingsDrawerProps<TData> = {
|
|
33
106
|
id: string;
|
|
34
107
|
getAllColumns: () => Column<TData, unknown>[];
|
|
@@ -38,16 +111,13 @@ export type TableSettingsDrawerProps<TData> = {
|
|
|
38
111
|
setStickyFirstColumn: React.Dispatch<React.SetStateAction<boolean>>;
|
|
39
112
|
setStickyHeaders: React.Dispatch<React.SetStateAction<boolean>>;
|
|
40
113
|
columnFiltersEnabled: boolean;
|
|
41
|
-
copy: TableSettingsDrawerCopyProps;
|
|
42
114
|
isDrawerOpen: boolean;
|
|
43
115
|
showColumnFilters: boolean;
|
|
44
116
|
stickyFirstColumn: boolean;
|
|
45
117
|
stickyHeaders: boolean;
|
|
46
|
-
enableRowSelection?: boolean;
|
|
47
|
-
rowSelectionEnabled?: boolean;
|
|
48
|
-
setRowSelectionEnabled?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
49
118
|
zIndex?: number;
|
|
50
|
-
|
|
119
|
+
columnOrder?: string[];
|
|
120
|
+
} & (ColumnDragEnabledProps | ColumnDragDisabledProps);
|
|
51
121
|
|
|
52
122
|
const rootClassName = "purpur-table-settings-drawer";
|
|
53
123
|
const cx = c.bind(styles);
|
|
@@ -67,10 +137,10 @@ export const TableSettingsDrawer = <TData extends RowData>({
|
|
|
67
137
|
setShowColumnFiltersEnabled,
|
|
68
138
|
setStickyFirstColumn,
|
|
69
139
|
setStickyHeaders,
|
|
70
|
-
|
|
71
|
-
rowSelectionEnabled,
|
|
72
|
-
setRowSelectionEnabled,
|
|
140
|
+
enableColumnDrag,
|
|
73
141
|
zIndex,
|
|
142
|
+
columnOrder,
|
|
143
|
+
onColumnOrderChange,
|
|
74
144
|
}: TableSettingsDrawerProps<TData>) => {
|
|
75
145
|
return (
|
|
76
146
|
<div id={id}>
|
|
@@ -96,11 +166,22 @@ export const TableSettingsDrawer = <TData extends RowData>({
|
|
|
96
166
|
stickyFirstColumn={stickyFirstColumn}
|
|
97
167
|
stickyHeaders={stickyHeaders}
|
|
98
168
|
copy={copy.generalSettings}
|
|
99
|
-
enableRowSelection={enableRowSelection}
|
|
100
|
-
rowSelectionEnabled={rowSelectionEnabled}
|
|
101
|
-
setRowSelectionEnabled={setRowSelectionEnabled}
|
|
102
169
|
/>
|
|
103
|
-
<VisibleColumns
|
|
170
|
+
<VisibleColumns
|
|
171
|
+
getAllColumns={getAllColumns}
|
|
172
|
+
header={copy.visibleColumns.header}
|
|
173
|
+
columnOrder={columnOrder}
|
|
174
|
+
{...(enableColumnDrag
|
|
175
|
+
? {
|
|
176
|
+
enableColumnDrag: true,
|
|
177
|
+
onColumnOrderChange: onColumnOrderChange,
|
|
178
|
+
copy: copy as TableSettingsDrawerCopyProps<true>,
|
|
179
|
+
}
|
|
180
|
+
: {
|
|
181
|
+
enableColumnDrag: false,
|
|
182
|
+
copy: copy as TableSettingsDrawerCopyProps<false>,
|
|
183
|
+
})}
|
|
184
|
+
/>
|
|
104
185
|
</div>
|
|
105
186
|
</Drawer.Content>
|
|
106
187
|
</Drawer>
|
|
@@ -131,12 +212,8 @@ type GeneralSettingsProps = {
|
|
|
131
212
|
showFilters: string;
|
|
132
213
|
lockFirstcolumn: string;
|
|
133
214
|
stickyHeader: string;
|
|
134
|
-
rowSelection?: string;
|
|
135
215
|
};
|
|
136
216
|
};
|
|
137
|
-
enableRowSelection?: boolean;
|
|
138
|
-
rowSelectionEnabled?: boolean;
|
|
139
|
-
setRowSelectionEnabled?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
140
217
|
};
|
|
141
218
|
|
|
142
219
|
const GeneralSettings = ({
|
|
@@ -148,9 +225,6 @@ const GeneralSettings = ({
|
|
|
148
225
|
stickyFirstColumn,
|
|
149
226
|
stickyHeaders,
|
|
150
227
|
copy,
|
|
151
|
-
enableRowSelection,
|
|
152
|
-
rowSelectionEnabled,
|
|
153
|
-
setRowSelectionEnabled,
|
|
154
228
|
}: GeneralSettingsProps) => {
|
|
155
229
|
const uid = useId();
|
|
156
230
|
return (
|
|
@@ -182,14 +256,6 @@ const GeneralSettings = ({
|
|
|
182
256
|
label={copy.toggles.stickyHeader}
|
|
183
257
|
onChange={setStickyHeaders}
|
|
184
258
|
/>
|
|
185
|
-
{enableRowSelection && copy.toggles.rowSelection && setRowSelectionEnabled && (
|
|
186
|
-
<ToggleWrapper
|
|
187
|
-
id={`${uid}-row-selection`}
|
|
188
|
-
checked={rowSelectionEnabled || false}
|
|
189
|
-
label={copy.toggles.rowSelection}
|
|
190
|
-
onChange={setRowSelectionEnabled}
|
|
191
|
-
/>
|
|
192
|
-
)}
|
|
193
259
|
</div>
|
|
194
260
|
);
|
|
195
261
|
};
|
|
@@ -197,44 +263,254 @@ const GeneralSettings = ({
|
|
|
197
263
|
const VisibleColumns = <TData extends RowData>({
|
|
198
264
|
header,
|
|
199
265
|
getAllColumns,
|
|
266
|
+
enableColumnDrag,
|
|
267
|
+
columnOrder,
|
|
268
|
+
onColumnOrderChange,
|
|
269
|
+
copy,
|
|
200
270
|
}: {
|
|
201
271
|
header: string;
|
|
202
272
|
getAllColumns: () => Column<TData, unknown>[];
|
|
203
|
-
|
|
273
|
+
columnOrder?: string[];
|
|
274
|
+
} & (ColumnDragDisabledProps | ColumnDragEnabledProps)) => {
|
|
204
275
|
const allColumns = getAllColumns();
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
276
|
+
|
|
277
|
+
const filterAwayRowSelectionToggle = (column: Column<TData, unknown>) =>
|
|
278
|
+
column.id !== "row-selection" && column.id !== "row-toggle";
|
|
279
|
+
|
|
280
|
+
const [isRearrangeMode, setIsRearrangeMode] = useState(false);
|
|
281
|
+
const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null);
|
|
282
|
+
|
|
283
|
+
const visible = allColumns
|
|
284
|
+
.filter((column) => column.getIsVisible())
|
|
285
|
+
.filter(filterAwayRowSelectionToggle);
|
|
286
|
+
|
|
287
|
+
const sensors = useSensors(
|
|
288
|
+
useSensor(PointerSensor),
|
|
289
|
+
useSensor(TouchSensor),
|
|
290
|
+
useSensor(KeyboardSensor, {
|
|
291
|
+
coordinateGetter: sortableKeyboardCoordinates,
|
|
292
|
+
})
|
|
208
293
|
);
|
|
209
|
-
const visible = filteredColumns.filter((column) => column.getIsVisible());
|
|
210
294
|
|
|
211
|
-
const
|
|
212
|
-
|
|
295
|
+
const handleDragStart = (event: DragStartEvent) => {
|
|
296
|
+
setActiveId(event.active.id);
|
|
213
297
|
};
|
|
298
|
+
|
|
299
|
+
const handleDragEnd = (event: DragEndEvent) => {
|
|
300
|
+
const { active, over } = event;
|
|
301
|
+
|
|
302
|
+
if (over && active.id !== over.id) {
|
|
303
|
+
const currentOrder = allColumns.map((column) => column.id);
|
|
304
|
+
|
|
305
|
+
const oldIndex = currentOrder.indexOf(String(active.id));
|
|
306
|
+
const newIndex = currentOrder.indexOf(String(over.id));
|
|
307
|
+
|
|
308
|
+
if (oldIndex !== -1 && newIndex !== -1) {
|
|
309
|
+
const newOrder = [...currentOrder];
|
|
310
|
+
const [removed] = newOrder.splice(oldIndex, 1);
|
|
311
|
+
newOrder.splice(newIndex, 0, removed);
|
|
312
|
+
|
|
313
|
+
if (onColumnOrderChange) onColumnOrderChange(newOrder);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
setActiveId(null);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const moveColumn = (id: string, direction: "up" | "down") => {
|
|
321
|
+
const currentOrder = allColumns.map((column) => column.id);
|
|
322
|
+
|
|
323
|
+
const index = currentOrder.indexOf(id);
|
|
324
|
+
if (
|
|
325
|
+
(direction === "up" && index === 0) ||
|
|
326
|
+
(direction === "down" && index === currentOrder.length - 1)
|
|
327
|
+
) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const newIndex = direction === "up" ? index - 1 : index + 1;
|
|
331
|
+
const newOrder = arrayMove(currentOrder, index, newIndex);
|
|
332
|
+
if (onColumnOrderChange) onColumnOrderChange(newOrder);
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const getColumnById = (id: string) => allColumns.find((col) => col.id === id);
|
|
336
|
+
|
|
337
|
+
const isDisabled = (column: Column<TData, unknown>) =>
|
|
338
|
+
!column.getCanHide() || (visible.length === 1 && visible.includes(column));
|
|
339
|
+
|
|
214
340
|
const uid = useId();
|
|
341
|
+
|
|
342
|
+
const activeColumn = activeId ? getColumnById(String(activeId)) : null;
|
|
343
|
+
const filteredColumns = allColumns.filter(filterAwayRowSelectionToggle);
|
|
344
|
+
|
|
215
345
|
return (
|
|
216
346
|
<section
|
|
217
347
|
data-testid={`${rootTestId}-visible-columns`}
|
|
218
348
|
className={cx(`${rootClassName}__visible-columns`)}
|
|
219
349
|
aria-labelledby={`${uid}-visible-columns`}
|
|
220
350
|
>
|
|
221
|
-
<
|
|
222
|
-
{header}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
351
|
+
<div className={cx(`${rootClassName}__visible-columns-header-wrapper`)}>
|
|
352
|
+
<div className={cx(`${rootClassName}__visible-columns-header`)}>
|
|
353
|
+
<Heading id={`${uid}-visible-columns`} variant="title-100" tag="h3">
|
|
354
|
+
{header}
|
|
355
|
+
</Heading>
|
|
356
|
+
{enableColumnDrag && (
|
|
357
|
+
<Button
|
|
358
|
+
variant={isRearrangeMode ? "primary" : "tertiary-purple"}
|
|
359
|
+
onClick={() => setIsRearrangeMode((v) => !v)}
|
|
360
|
+
data-testid={`${rootTestId}-rearrange-button`}
|
|
361
|
+
aria-label={copy.visibleColumns.ariaLabels.rearrangeButton}
|
|
362
|
+
>
|
|
363
|
+
<IconSorter size="xs" />
|
|
364
|
+
{isRearrangeMode
|
|
365
|
+
? copy.visibleColumns.buttons.done
|
|
366
|
+
: copy.visibleColumns.buttons.rearrange}
|
|
367
|
+
</Button>
|
|
368
|
+
)}
|
|
369
|
+
</div>
|
|
370
|
+
<Paragraph>
|
|
371
|
+
{isRearrangeMode && enableColumnDrag
|
|
372
|
+
? copy.visibleColumns.rearrangeDescription
|
|
373
|
+
: copy.visibleColumns.description}
|
|
374
|
+
</Paragraph>
|
|
375
|
+
</div>
|
|
376
|
+
{isRearrangeMode && enableColumnDrag && columnOrder ? (
|
|
377
|
+
<div className={cx(`${rootClassName}__draggable-list`)}>
|
|
378
|
+
<DndContext
|
|
379
|
+
sensors={sensors}
|
|
380
|
+
collisionDetection={closestCenter}
|
|
381
|
+
onDragStart={handleDragStart}
|
|
382
|
+
onDragEnd={handleDragEnd}
|
|
383
|
+
modifiers={[restrictToVerticalAxis, restrictToParentElement]}
|
|
384
|
+
>
|
|
385
|
+
<SortableContext items={columnOrder} strategy={verticalListSortingStrategy}>
|
|
386
|
+
{filteredColumns.map((column, index) => {
|
|
387
|
+
return (
|
|
388
|
+
<DraggableColumnItemWithIndicator
|
|
389
|
+
key={column.id}
|
|
390
|
+
column={column}
|
|
391
|
+
moveColumn={moveColumn}
|
|
392
|
+
isFirst={index === 0}
|
|
393
|
+
isLast={index === filteredColumns.length - 1}
|
|
394
|
+
copy={copy}
|
|
395
|
+
index={index}
|
|
396
|
+
/>
|
|
397
|
+
);
|
|
398
|
+
})}
|
|
399
|
+
</SortableContext>
|
|
400
|
+
<DragOverlay
|
|
401
|
+
dropAnimation={{
|
|
402
|
+
duration: Number(purpurMotionDuration150),
|
|
403
|
+
easing: purpurMotionEasingEaseInOut,
|
|
404
|
+
}}
|
|
405
|
+
>
|
|
406
|
+
{activeColumn ? (
|
|
407
|
+
<DraggableColumnItem
|
|
408
|
+
id={activeColumn.id}
|
|
409
|
+
label={activeColumn.columnDef.header as string}
|
|
410
|
+
onMoveUp={() => {}}
|
|
411
|
+
onMoveDown={() => {}}
|
|
412
|
+
overlay
|
|
413
|
+
copy={copy}
|
|
414
|
+
/>
|
|
415
|
+
) : null}
|
|
416
|
+
</DragOverlay>
|
|
417
|
+
</DndContext>
|
|
418
|
+
</div>
|
|
419
|
+
) : (
|
|
420
|
+
filteredColumns.map((column) => (
|
|
421
|
+
<ToggleWrapper
|
|
422
|
+
key={column!.id}
|
|
423
|
+
id={column!.id}
|
|
424
|
+
checked={column!.getIsVisible()}
|
|
425
|
+
disabled={isDisabled(column!)}
|
|
426
|
+
label={column!.columnDef.header as string}
|
|
427
|
+
onChange={() => column!.toggleVisibility()}
|
|
428
|
+
/>
|
|
429
|
+
))
|
|
430
|
+
)}
|
|
234
431
|
</section>
|
|
235
432
|
);
|
|
236
433
|
};
|
|
237
434
|
|
|
435
|
+
const DraggableColumnItem = ({
|
|
436
|
+
id,
|
|
437
|
+
label,
|
|
438
|
+
onMoveUp,
|
|
439
|
+
onMoveDown,
|
|
440
|
+
isFirst,
|
|
441
|
+
isLast,
|
|
442
|
+
overlay,
|
|
443
|
+
copy,
|
|
444
|
+
dropIndicatorPosition,
|
|
445
|
+
}: {
|
|
446
|
+
id: string;
|
|
447
|
+
label: string;
|
|
448
|
+
onMoveUp?: () => void;
|
|
449
|
+
onMoveDown?: () => void;
|
|
450
|
+
isFirst?: boolean;
|
|
451
|
+
isLast?: boolean;
|
|
452
|
+
overlay?: boolean;
|
|
453
|
+
copy: TableSettingsDrawerCopyProps<true>;
|
|
454
|
+
dropIndicatorPosition?: "before" | "after" | null;
|
|
455
|
+
}) => {
|
|
456
|
+
const { attributes, listeners, setNodeRef, isDragging } = useSortable({
|
|
457
|
+
id,
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
return (
|
|
461
|
+
<div
|
|
462
|
+
ref={setNodeRef}
|
|
463
|
+
className={cx(`${rootClassName}__draggable-item`, {
|
|
464
|
+
[`${rootClassName}__draggable-item--overlay`]: overlay,
|
|
465
|
+
[`${rootClassName}__draggable-item--dragging`]: isDragging,
|
|
466
|
+
[`${rootClassName}__draggable-item--drop-indicator-before`]:
|
|
467
|
+
dropIndicatorPosition === "before",
|
|
468
|
+
[`${rootClassName}__draggable-item--drop-indicator-after`]:
|
|
469
|
+
dropIndicatorPosition === "after",
|
|
470
|
+
})}
|
|
471
|
+
>
|
|
472
|
+
<div className={cx(`${rootClassName}__draggable-item-content`)}>
|
|
473
|
+
<div
|
|
474
|
+
className={cx(`${rootClassName}__draggable-handle`, {
|
|
475
|
+
[`${rootClassName}__draggable-handle--overlay`]: overlay,
|
|
476
|
+
})}
|
|
477
|
+
{...listeners}
|
|
478
|
+
{...attributes}
|
|
479
|
+
>
|
|
480
|
+
<IconDragVertical
|
|
481
|
+
className={cx(`${rootClassName}__draggable-handle-icon`, "terre")}
|
|
482
|
+
size="sm"
|
|
483
|
+
/>
|
|
484
|
+
</div>
|
|
485
|
+
<span>{label}</span>
|
|
486
|
+
</div>
|
|
487
|
+
|
|
488
|
+
<div className={cx(`${rootClassName}__draggable-item-buttons`)}>
|
|
489
|
+
<Button
|
|
490
|
+
variant="secondary"
|
|
491
|
+
size="xs"
|
|
492
|
+
onClick={onMoveUp}
|
|
493
|
+
disabled={isFirst || overlay}
|
|
494
|
+
aria-label={`${copy.visibleColumns.ariaLabels.arrowButtons.move} ${label} ${copy.visibleColumns.ariaLabels.arrowButtons.up}`}
|
|
495
|
+
iconOnly
|
|
496
|
+
>
|
|
497
|
+
<IconArrowUp size="xs" />
|
|
498
|
+
</Button>
|
|
499
|
+
<Button
|
|
500
|
+
variant="secondary"
|
|
501
|
+
size="xs"
|
|
502
|
+
onClick={onMoveDown}
|
|
503
|
+
disabled={isLast || overlay}
|
|
504
|
+
aria-label={`${copy.visibleColumns.ariaLabels.arrowButtons.move} ${label} ${copy.visibleColumns.ariaLabels.arrowButtons.down}`}
|
|
505
|
+
iconOnly
|
|
506
|
+
>
|
|
507
|
+
<IconArrowDown size="xs" />
|
|
508
|
+
</Button>
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
511
|
+
);
|
|
512
|
+
};
|
|
513
|
+
|
|
238
514
|
const ToggleWrapper = ({
|
|
239
515
|
id,
|
|
240
516
|
checked,
|
|
@@ -259,3 +535,33 @@ const ToggleWrapper = ({
|
|
|
259
535
|
data-testid={`${rootTestId}-toggle`}
|
|
260
536
|
/>
|
|
261
537
|
);
|
|
538
|
+
|
|
539
|
+
const DraggableColumnItemWithIndicator = <TData extends RowData>({
|
|
540
|
+
column,
|
|
541
|
+
moveColumn,
|
|
542
|
+
isFirst,
|
|
543
|
+
isLast,
|
|
544
|
+
copy,
|
|
545
|
+
}: {
|
|
546
|
+
column: Column<TData, unknown>;
|
|
547
|
+
moveColumn: (id: string, direction: "up" | "down") => void;
|
|
548
|
+
isFirst: boolean;
|
|
549
|
+
isLast: boolean;
|
|
550
|
+
copy: TableSettingsDrawerCopyProps<true>;
|
|
551
|
+
index: number;
|
|
552
|
+
}) => {
|
|
553
|
+
const dropIndicatorPosition = useDropIndicator({ itemId: column.id, enableDrag: true });
|
|
554
|
+
|
|
555
|
+
return (
|
|
556
|
+
<DraggableColumnItem
|
|
557
|
+
id={column.id}
|
|
558
|
+
label={column.columnDef.header as string}
|
|
559
|
+
onMoveUp={() => moveColumn(column.id, "up")}
|
|
560
|
+
onMoveDown={() => moveColumn(column.id, "down")}
|
|
561
|
+
isFirst={isFirst}
|
|
562
|
+
isLast={isLast}
|
|
563
|
+
copy={copy}
|
|
564
|
+
dropIndicatorPosition={dropIndicatorPosition}
|
|
565
|
+
/>
|
|
566
|
+
);
|
|
567
|
+
};
|