@dmsi/wedgekit-react 0.0.207 → 0.0.209
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/{chunk-WNQ53SVY.js → chunk-E6Y7ZHQX.js} +45 -1
- package/dist/{chunk-WXHRJSDG.js → chunk-ERW3AMED.js} +1 -1
- package/dist/{chunk-2JRZCC2K.js → chunk-JITZWSPR.js} +3 -3
- package/dist/{chunk-WE55TGZZ.js → chunk-NIHZMIOL.js} +1 -1
- package/dist/{chunk-RXPS5GVE.js → chunk-Q3TNALWH.js} +17 -26
- package/dist/{chunk-M3433XEJ.js → chunk-T3F37S6Z.js} +15 -1
- package/dist/{chunk-2B5T4NCT.js → chunk-UKSJPFN2.js} +2 -2
- package/dist/components/DataGridCell.cjs +814 -824
- package/dist/components/DataGridCell.js +7 -6
- package/dist/components/DateInput.cjs +23 -23
- package/dist/components/DateInput.js +4 -4
- package/dist/components/DateRangeInput.cjs +23 -23
- package/dist/components/DateRangeInput.js +4 -4
- package/dist/components/Menu.cjs +38 -35
- package/dist/components/Menu.js +6 -4
- package/dist/components/MenuOption.cjs +7 -4
- package/dist/components/MenuOption.js +5 -2
- package/dist/components/Modal.cjs +15 -12
- package/dist/components/Modal.js +5 -3
- package/dist/components/NestedMenu.cjs +9 -6
- package/dist/components/NestedMenu.js +5 -2
- package/dist/components/PDFViewer.cjs +22 -19
- package/dist/components/PDFViewer.js +5 -3
- package/dist/components/ProjectBar.cjs +3 -0
- package/dist/components/ProjectBar.js +4 -1
- package/dist/components/Time.js +2 -1
- package/dist/components/index.cjs +963 -905
- package/dist/components/index.js +70 -45
- package/dist/components/useMenuSystem.cjs +22 -19
- package/dist/components/useMenuSystem.js +5 -2
- package/dist/hooks/index.cjs +66 -2
- package/dist/hooks/index.js +8 -3
- package/dist/utils/index.cjs +25 -0
- package/dist/utils/index.js +3 -1
- package/package.json +1 -1
- package/src/components/DataGrid/TableBody/TableBodyRow.tsx +0 -4
- package/src/components/DataGrid/TableBody/index.tsx +14 -3
- package/src/components/DataGrid/index.tsx +58 -35
- package/src/components/DataGridCell.tsx +11 -17
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useTableLayout.ts +68 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/mergeObjectArrays.ts +18 -0
- package/src/utils.ts +1 -0
- /package/dist/{chunk-6LN6QT6M.js → chunk-VXWSAIB5.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useInfiniteScroll } from "../../hooks";
|
|
3
|
+
import { useInfiniteScroll, useTableLayout } from "../../hooks";
|
|
4
4
|
import { componentGap, componentPadding } from "../../classNames";
|
|
5
5
|
import {
|
|
6
6
|
Button,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
Select,
|
|
16
16
|
Subheader,
|
|
17
17
|
} from "..";
|
|
18
|
-
import React, { useCallback, useId, useState } from "react";
|
|
18
|
+
import React, { useCallback, useEffect, useId, useState } from "react";
|
|
19
19
|
import {
|
|
20
20
|
ColumnFiltersState,
|
|
21
21
|
flexRender,
|
|
@@ -81,15 +81,35 @@ export function DataGrid<T extends Record<string, unknown>>({
|
|
|
81
81
|
predeterminedRightPins = [],
|
|
82
82
|
useMenuDefaultMinWidth,
|
|
83
83
|
}: DataGridProps<T>) {
|
|
84
|
-
const [columnOrder, setColumnOrder] = useState<string[]>(() =>
|
|
85
|
-
columns.map((c) => c.id!),
|
|
86
|
-
);
|
|
87
84
|
const [localSorting, setLocalSorting] = useState<SortingState>([]);
|
|
88
85
|
const [localColumnFilters, setLocalColumnFilters] =
|
|
89
86
|
useState<ColumnFiltersState>([]);
|
|
90
87
|
const [localRowSelection, setLocalRowSelection] = useState<
|
|
91
88
|
Record<string, boolean>
|
|
92
89
|
>({});
|
|
90
|
+
const {
|
|
91
|
+
columns: tableColumns,
|
|
92
|
+
setColumns: setTableColumns,
|
|
93
|
+
layoutSignal,
|
|
94
|
+
} = useTableLayout<T>(columns, id ?? testid);
|
|
95
|
+
const [columnOrder, setColumnOrder] = useState<string[]>(
|
|
96
|
+
tableColumns.map((c) => c.id!),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const [columnVisibility, setColumnVisibility] = useState<
|
|
100
|
+
Record<string, boolean>
|
|
101
|
+
>(
|
|
102
|
+
Object.fromEntries(
|
|
103
|
+
tableColumns
|
|
104
|
+
.filter((column) => !!column.id)
|
|
105
|
+
.map((column) => [column.id, column.meta?.visible ?? true]),
|
|
106
|
+
),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
setColumnOrder(tableColumns.map((c) => c.id!));
|
|
111
|
+
resetColumnVisibility();
|
|
112
|
+
}, [layoutSignal]);
|
|
93
113
|
|
|
94
114
|
const sortingState = pagination
|
|
95
115
|
? (externalSorting ?? localSorting)
|
|
@@ -149,39 +169,35 @@ export function DataGrid<T extends Record<string, unknown>>({
|
|
|
149
169
|
const dndId = useId();
|
|
150
170
|
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
151
171
|
|
|
152
|
-
const [columnVisibility, setColumnVisibility] = useState<
|
|
153
|
-
Record<string, boolean>
|
|
154
|
-
>(() => {
|
|
155
|
-
const initialVisibility: Record<string, boolean> = {};
|
|
156
|
-
columns.forEach((column) => {
|
|
157
|
-
if (column.id) {
|
|
158
|
-
initialVisibility[column.id] = column.meta?.visible ?? true;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
return initialVisibility;
|
|
162
|
-
});
|
|
163
|
-
|
|
164
172
|
const toggleColumnVisibility = useCallback(
|
|
165
173
|
(columnId: string, isVisible: boolean) => {
|
|
166
|
-
|
|
174
|
+
setTableColumns((prev) => {
|
|
175
|
+
const persistedIndex = prev.findIndex((col) => col.id === columnId);
|
|
176
|
+
if (persistedIndex !== -1) {
|
|
177
|
+
prev[persistedIndex].meta = {
|
|
178
|
+
...prev[persistedIndex].meta,
|
|
179
|
+
visible: isVisible,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return [...prev];
|
|
183
|
+
// @ts-expect-error Internal usage only
|
|
184
|
+
}, true);
|
|
167
185
|
},
|
|
168
|
-
[
|
|
186
|
+
[setTableColumns],
|
|
169
187
|
);
|
|
170
188
|
|
|
171
189
|
const resetColumnVisibility = useCallback(() => {
|
|
172
|
-
setColumnVisibility(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
});
|
|
181
|
-
}, [columns]);
|
|
190
|
+
setColumnVisibility(
|
|
191
|
+
Object.fromEntries(
|
|
192
|
+
tableColumns
|
|
193
|
+
.filter((column) => !!column.id)
|
|
194
|
+
.map((column) => [column.id, column.meta?.visible ?? true]),
|
|
195
|
+
),
|
|
196
|
+
);
|
|
197
|
+
}, [tableColumns]);
|
|
182
198
|
|
|
183
199
|
const table = useReactTable<T>({
|
|
184
|
-
columns,
|
|
200
|
+
columns: tableColumns,
|
|
185
201
|
data,
|
|
186
202
|
getCoreRowModel: getCoreRowModel(),
|
|
187
203
|
getSortedRowModel: getSortedRowModel(),
|
|
@@ -278,7 +294,15 @@ export function DataGrid<T extends Record<string, unknown>>({
|
|
|
278
294
|
setColumnOrder((prev) => {
|
|
279
295
|
const oldIndex = prev.indexOf(active.id as string);
|
|
280
296
|
const newIndex = prev.indexOf(over.id as string);
|
|
281
|
-
|
|
297
|
+
const newOrder = arrayMove(prev, oldIndex, newIndex);
|
|
298
|
+
setTableColumns((prev) => {
|
|
299
|
+
// Mirror columnOrder's string = id
|
|
300
|
+
const res = newOrder
|
|
301
|
+
.map((id) => prev.find((col) => col.id === id)!)
|
|
302
|
+
.filter(Boolean);
|
|
303
|
+
return res;
|
|
304
|
+
});
|
|
305
|
+
return newOrder;
|
|
282
306
|
});
|
|
283
307
|
}
|
|
284
308
|
};
|
|
@@ -377,9 +401,6 @@ export function DataGrid<T extends Record<string, unknown>>({
|
|
|
377
401
|
}
|
|
378
402
|
|
|
379
403
|
if (typeof header.column.columnDef.header === "string") {
|
|
380
|
-
const customHeaderWidth =
|
|
381
|
-
header.column.columnDef.meta?.headerWidth;
|
|
382
|
-
|
|
383
404
|
const cellValue = table
|
|
384
405
|
.getRowModel()
|
|
385
406
|
.rows[0]?.getValue(header.column.id);
|
|
@@ -396,7 +417,7 @@ export function DataGrid<T extends Record<string, unknown>>({
|
|
|
396
417
|
header={header}
|
|
397
418
|
locked={header.column.columnDef.meta?.locked}
|
|
398
419
|
center={centerHeader}
|
|
399
|
-
width={
|
|
420
|
+
// width={`${header.column.getSize()}px`}
|
|
400
421
|
className={clsx(
|
|
401
422
|
header.column.getCanSort()
|
|
402
423
|
? "cursor-pointer"
|
|
@@ -670,3 +691,5 @@ function adaptTableStateSetter<T>(
|
|
|
670
691
|
}
|
|
671
692
|
|
|
672
693
|
export type { ColumnDef } from "@tanstack/react-table";
|
|
694
|
+
|
|
695
|
+
export default DataGrid;
|
|
@@ -14,20 +14,20 @@ import clsx from "clsx";
|
|
|
14
14
|
import {
|
|
15
15
|
ComponentProps,
|
|
16
16
|
CSSProperties,
|
|
17
|
-
memo,
|
|
18
17
|
PropsWithChildren,
|
|
19
18
|
RefObject,
|
|
20
19
|
useEffect,
|
|
21
20
|
useRef,
|
|
22
21
|
useState,
|
|
22
|
+
memo,
|
|
23
23
|
} from "react";
|
|
24
24
|
import { componentPadding, paddingUsingComponentGap } from "../classNames";
|
|
25
|
-
import {
|
|
25
|
+
import { MenuOption } from "./MenuOption";
|
|
26
|
+
import { Menu } from "./Menu";
|
|
26
27
|
import { Icon } from "./Icon";
|
|
27
28
|
import { Search } from "./Search";
|
|
28
|
-
import { Menu } from "./Menu";
|
|
29
|
-
import { MenuOption } from "./MenuOption";
|
|
30
29
|
import { useSubMenuSystem } from "./useMenuSystem";
|
|
30
|
+
import type { AsProps } from "../types";
|
|
31
31
|
|
|
32
32
|
type Tags = "td" | "th";
|
|
33
33
|
|
|
@@ -44,6 +44,7 @@ type DataGridCellProps = PropsWithChildren<{
|
|
|
44
44
|
warning?: boolean;
|
|
45
45
|
center?: boolean;
|
|
46
46
|
width?: string;
|
|
47
|
+
minWidth?: string;
|
|
47
48
|
}>;
|
|
48
49
|
|
|
49
50
|
export const DataGridCell = memo(
|
|
@@ -63,6 +64,7 @@ export const DataGridCell = memo(
|
|
|
63
64
|
warning,
|
|
64
65
|
center,
|
|
65
66
|
width,
|
|
67
|
+
minWidth,
|
|
66
68
|
testid,
|
|
67
69
|
...props
|
|
68
70
|
}: AsProps<Tags> & DataGridCellProps) => {
|
|
@@ -171,7 +173,7 @@ export const DataGridCell = memo(
|
|
|
171
173
|
id={id}
|
|
172
174
|
data-testid={testid}
|
|
173
175
|
className={clsx("flex h-10", !width && "flex-1")}
|
|
174
|
-
style={{ width }}
|
|
176
|
+
style={{ width, minWidth }}
|
|
175
177
|
{...props}
|
|
176
178
|
data-theme={type === "header" && !locked ? "brand" : undefined}
|
|
177
179
|
>
|
|
@@ -260,7 +262,7 @@ export function DataCellHeader<T>({
|
|
|
260
262
|
const style: CSSProperties = {
|
|
261
263
|
position: "relative",
|
|
262
264
|
whiteSpace: "nowrap",
|
|
263
|
-
|
|
265
|
+
minWidth: header.column.getSize(),
|
|
264
266
|
"--color-text-primary-normal": "var(--color-text-brand-primary-normal)",
|
|
265
267
|
"--color-icon-on-action-primary-normal":
|
|
266
268
|
"var(--color-text-brand-primary-normal)",
|
|
@@ -277,6 +279,7 @@ export function DataCellHeader<T>({
|
|
|
277
279
|
type="header"
|
|
278
280
|
component="header"
|
|
279
281
|
style={style}
|
|
282
|
+
minWidth={`${header.column.getSize()}px`}
|
|
280
283
|
onClick={header.column.getToggleSortingHandler()}
|
|
281
284
|
onRightClick={() => setShowMenu(!showMenu)}
|
|
282
285
|
{...props}
|
|
@@ -470,7 +473,6 @@ export function DraggableCellHeader<T extends Record<string, any>>({
|
|
|
470
473
|
transition: "width transform 0.2s ease-in-out",
|
|
471
474
|
whiteSpace: "nowrap",
|
|
472
475
|
zIndex: isDragging ? 1 : 0,
|
|
473
|
-
width: header.column.columnDef.meta?.headerWidth ?? header.column.getSize(),
|
|
474
476
|
"--color-text-primary-normal": "var(--color-action-000)",
|
|
475
477
|
"--color-icon-on-action-primary-normal": "var(--color-action-000)",
|
|
476
478
|
userSelect: "none",
|
|
@@ -510,20 +512,12 @@ export function DragAlongCell<T extends RowData, TValue>({
|
|
|
510
512
|
position: "relative",
|
|
511
513
|
transform: CSS.Translate.toString(transform),
|
|
512
514
|
transition: "width transform 0.2s ease-in-out",
|
|
513
|
-
|
|
515
|
+
minWidth: cell.column.getSize(),
|
|
514
516
|
zIndex: isDragging ? 1 : 0,
|
|
515
517
|
};
|
|
516
518
|
|
|
517
519
|
return (
|
|
518
|
-
<DataGridCell
|
|
519
|
-
style={style}
|
|
520
|
-
ref={setNodeRef}
|
|
521
|
-
width={
|
|
522
|
-
(cell.column.columnDef.meta?.headerWidth as string | undefined) ??
|
|
523
|
-
`${cell.column.getSize()}px`
|
|
524
|
-
}
|
|
525
|
-
{...props}
|
|
526
|
-
>
|
|
520
|
+
<DataGridCell style={style} ref={setNodeRef} {...props}>
|
|
527
521
|
{children}
|
|
528
522
|
</DataGridCell>
|
|
529
523
|
);
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeObjectArrays } from "../utils";
|
|
4
|
+
import { ColumnDef } from "@dmsi/wedgekit-react/components";
|
|
5
|
+
import { useState, useEffect, SetStateAction, useCallback } from "react";
|
|
6
|
+
export type PersistedTableLayout<T> = {
|
|
7
|
+
columns: ColumnDef<T>[];
|
|
8
|
+
setColumns: (setter: SetStateAction<ColumnDef<T>[]>) => ColumnDef<T>[] | null;
|
|
9
|
+
layoutSignal: number;
|
|
10
|
+
isReady: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Custom hook to manage table layout persistence.
|
|
15
|
+
* @template T The type of the objects in the arrays.
|
|
16
|
+
* @param key {string}
|
|
17
|
+
* @param initialColumns {() => Array<ColumnDef<T>>}
|
|
18
|
+
* @param dependencyArr {unknown[]}
|
|
19
|
+
* @returns {{ columns: ColumnDef<T>[]; setColumns: React.Dispatch<React.SetStateAction<ColumnDef<T>[]>> }}
|
|
20
|
+
*/
|
|
21
|
+
export function useTableLayout<T>(
|
|
22
|
+
initialColumns: Array<ColumnDef<T>>,
|
|
23
|
+
key?: string,
|
|
24
|
+
): PersistedTableLayout<T> {
|
|
25
|
+
const [columns, setColumns] = useState<ColumnDef<T>[]>(initialColumns);
|
|
26
|
+
const [isReady, setIsReady] = useState(false);
|
|
27
|
+
const [layoutSignal, setLayoutSignal] = useState(0);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!key) return setIsReady(true);
|
|
31
|
+
const savedLayout = localStorage.getItem(`${key}-tableLayout`);
|
|
32
|
+
if (savedLayout) {
|
|
33
|
+
setColumns(
|
|
34
|
+
mergeObjectArrays<ColumnDef<T>>(
|
|
35
|
+
initialColumns,
|
|
36
|
+
JSON.parse(savedLayout),
|
|
37
|
+
),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
if (!savedLayout) handleSaveLayout(initialColumns, true);
|
|
41
|
+
setLayoutSignal((prev) => prev + 1);
|
|
42
|
+
setIsReady(true);
|
|
43
|
+
|
|
44
|
+
// Load the layout from local storage on init
|
|
45
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
}, []);
|
|
47
|
+
|
|
48
|
+
const handleSaveLayout = useCallback(
|
|
49
|
+
(setter: React.SetStateAction<ColumnDef<T>[]>, _internal?: boolean) => {
|
|
50
|
+
if (!isReady && !_internal) return null;
|
|
51
|
+
// get value from passed setter
|
|
52
|
+
const newColumns =
|
|
53
|
+
typeof setter === "function" ? setter(columns) : setter;
|
|
54
|
+
if (JSON.stringify(newColumns) === JSON.stringify(columns) && !_internal)
|
|
55
|
+
return null;
|
|
56
|
+
if (key) {
|
|
57
|
+
localStorage.setItem(`${key}-tableLayout`, JSON.stringify(newColumns));
|
|
58
|
+
}
|
|
59
|
+
setColumns(newColumns);
|
|
60
|
+
setLayoutSignal((prev) => prev + 1);
|
|
61
|
+
|
|
62
|
+
return newColumns;
|
|
63
|
+
},
|
|
64
|
+
[columns, isReady, key],
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return { columns, setColumns: handleSaveLayout, layoutSignal, isReady };
|
|
68
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges two arrays of objects element-wise.
|
|
3
|
+
*
|
|
4
|
+
* @template T The type of the objects in the arrays.
|
|
5
|
+
* @param {T[]} arr1 The first array.
|
|
6
|
+
* @param {T[]} arr2 The second array.
|
|
7
|
+
* @returns {T[]} A new array containing the merged objects.
|
|
8
|
+
*/
|
|
9
|
+
export function mergeObjectArrays<T extends object>(arr1: T[], arr2: T[]): T[] {
|
|
10
|
+
const maxLength = Math.max(arr1.length, arr2.length);
|
|
11
|
+
|
|
12
|
+
// Create a new array with a length equal to the longer of the two arrays.
|
|
13
|
+
// For each index, merge the objects from arr1 and arr2.
|
|
14
|
+
return Array.from(
|
|
15
|
+
{ length: maxLength },
|
|
16
|
+
(_, i) => ({ ...(arr1[i] || {}), ...(arr2[i] || {}) }) as T,
|
|
17
|
+
);
|
|
18
|
+
}
|
package/src/utils.ts
CHANGED
|
File without changes
|