@mkt-loitd/react-table-grid-custom 1.0.2 → 1.0.7
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/README.md +95 -115
- package/dist/index.css +97 -0
- package/dist/index.d.mts +134 -5
- package/dist/index.d.ts +134 -5
- package/dist/index.js +385 -233
- package/dist/index.mjs +378 -227
- package/package.json +8 -4
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
// src/ReactTableGridCustom.tsx
|
|
2
|
-
import { Checkbox
|
|
2
|
+
import { Checkbox } from "@mantine/core";
|
|
3
|
+
import { get, orderBy } from "lodash";
|
|
4
|
+
import {
|
|
5
|
+
memo,
|
|
6
|
+
useCallback,
|
|
7
|
+
useEffect,
|
|
8
|
+
useMemo as useMemo2,
|
|
9
|
+
useRef,
|
|
10
|
+
useState
|
|
11
|
+
} from "react";
|
|
12
|
+
import {
|
|
13
|
+
DataGrid,
|
|
14
|
+
SelectColumn
|
|
15
|
+
} from "react-data-grid";
|
|
16
|
+
import "react-data-grid/lib/styles.css";
|
|
17
|
+
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
3
18
|
|
|
4
19
|
// src/helpers/table.ts
|
|
5
20
|
var calculatorTotalPage = ({ total = 0, pageSize = 0 }) => {
|
|
@@ -27,65 +42,20 @@ function cn(...inputs) {
|
|
|
27
42
|
return twMerge(clsx(inputs));
|
|
28
43
|
}
|
|
29
44
|
|
|
30
|
-
// src/
|
|
31
|
-
import { get, orderBy } from "lodash";
|
|
32
|
-
import { memo, useCallback, useEffect, useMemo as useMemo3, useRef, useState } from "react";
|
|
33
|
-
import { DataGrid, SelectColumn } from "react-data-grid";
|
|
34
|
-
import "react-data-grid/lib/styles.css";
|
|
35
|
-
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
36
|
-
|
|
37
|
-
// src/component/ComboboxCustom.tsx
|
|
38
|
-
import { Combobox, Input, InputBase, useCombobox } from "@mantine/core";
|
|
45
|
+
// src/hooks/useTranslationTable.ts
|
|
39
46
|
import { useMemo } from "react";
|
|
40
|
-
import {
|
|
41
|
-
var
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Combobox.Option,
|
|
48
|
-
{
|
|
49
|
-
className: "page_size-table",
|
|
50
|
-
value: item,
|
|
51
|
-
disabled: item === value,
|
|
52
|
-
children: item
|
|
53
|
-
},
|
|
54
|
-
item
|
|
55
|
-
));
|
|
56
|
-
}, [options, value]);
|
|
57
|
-
return /* @__PURE__ */ jsxs(
|
|
58
|
-
Combobox,
|
|
59
|
-
{
|
|
60
|
-
size: "sm",
|
|
61
|
-
store: combobox,
|
|
62
|
-
onOptionSubmit: (val) => {
|
|
63
|
-
onChange && onChange(val);
|
|
64
|
-
combobox.closeDropdown();
|
|
65
|
-
},
|
|
66
|
-
children: [
|
|
67
|
-
/* @__PURE__ */ jsx(Combobox.Target, { children: /* @__PURE__ */ jsx(
|
|
68
|
-
InputBase,
|
|
69
|
-
{
|
|
70
|
-
component: "button",
|
|
71
|
-
type: "button",
|
|
72
|
-
pointer: true,
|
|
73
|
-
rightSectionPointerEvents: "none",
|
|
74
|
-
onClick: () => combobox.toggleDropdown(),
|
|
75
|
-
className: "w-[70px]",
|
|
76
|
-
classNames: { input: "custom_input_table" },
|
|
77
|
-
children: value || /* @__PURE__ */ jsx(Input.Placeholder, { children: "Pick value" })
|
|
78
|
-
}
|
|
79
|
-
) }),
|
|
80
|
-
/* @__PURE__ */ jsx(Combobox.Dropdown, { className: "w-[70px]", children: /* @__PURE__ */ jsx(Combobox.Options, { children: newOptions }) })
|
|
81
|
-
]
|
|
82
|
-
}
|
|
83
|
-
);
|
|
47
|
+
import { useTranslation } from "react-i18next";
|
|
48
|
+
var useTranslationTable = (column) => {
|
|
49
|
+
const { i18n, t } = useTranslation();
|
|
50
|
+
const columnTranslation = useMemo(() => {
|
|
51
|
+
return column.map((item) => ({ ...item, name: t(`${item == null ? void 0 : item.name}`) }));
|
|
52
|
+
}, [i18n == null ? void 0 : i18n.language, column]);
|
|
53
|
+
return columnTranslation;
|
|
84
54
|
};
|
|
85
|
-
var
|
|
55
|
+
var useTranslationTable_default = useTranslationTable;
|
|
86
56
|
|
|
87
57
|
// src/component/Icons.tsx
|
|
88
|
-
import { jsx
|
|
58
|
+
import { jsx } from "react/jsx-runtime";
|
|
89
59
|
var LoadingIcon = ({
|
|
90
60
|
isSpin = false,
|
|
91
61
|
h = 30,
|
|
@@ -93,7 +63,7 @@ var LoadingIcon = ({
|
|
|
93
63
|
size = 30,
|
|
94
64
|
className
|
|
95
65
|
}) => {
|
|
96
|
-
return /* @__PURE__ */
|
|
66
|
+
return /* @__PURE__ */ jsx(
|
|
97
67
|
"svg",
|
|
98
68
|
{
|
|
99
69
|
className: `${isSpin ? "animate-spin" : ""} ${className != null ? className : ""}`,
|
|
@@ -104,7 +74,7 @@ var LoadingIcon = ({
|
|
|
104
74
|
height: size || h,
|
|
105
75
|
fill: "currentColor",
|
|
106
76
|
"aria-hidden": "true",
|
|
107
|
-
children: /* @__PURE__ */
|
|
77
|
+
children: /* @__PURE__ */ jsx("path", { d: "M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" })
|
|
108
78
|
}
|
|
109
79
|
);
|
|
110
80
|
};
|
|
@@ -114,7 +84,7 @@ var ArrowIcon = ({
|
|
|
114
84
|
size,
|
|
115
85
|
className
|
|
116
86
|
}) => {
|
|
117
|
-
return /* @__PURE__ */
|
|
87
|
+
return /* @__PURE__ */ jsx(
|
|
118
88
|
"svg",
|
|
119
89
|
{
|
|
120
90
|
className,
|
|
@@ -125,7 +95,7 @@ var ArrowIcon = ({
|
|
|
125
95
|
height: size != null ? size : h,
|
|
126
96
|
width: size != null ? size : w,
|
|
127
97
|
xmlns: "http://www.w3.org/2000/svg",
|
|
128
|
-
children: /* @__PURE__ */
|
|
98
|
+
children: /* @__PURE__ */ jsx(
|
|
129
99
|
"path",
|
|
130
100
|
{
|
|
131
101
|
fillRule: "evenodd",
|
|
@@ -137,35 +107,23 @@ var ArrowIcon = ({
|
|
|
137
107
|
};
|
|
138
108
|
|
|
139
109
|
// src/component/RenderSortStatus.tsx
|
|
140
|
-
import { Fragment, jsx as
|
|
110
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
141
111
|
var RenderSortStatus = ({ sortDirection, priority }) => {
|
|
142
|
-
return /* @__PURE__ */
|
|
143
|
-
sortDirection !== void 0 && /* @__PURE__ */
|
|
112
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
113
|
+
sortDirection !== void 0 && /* @__PURE__ */ jsx2(
|
|
144
114
|
ArrowIcon,
|
|
145
115
|
{
|
|
146
116
|
className: cn(sortDirection === "DESC" && "-rotate-180", "transition-transform"),
|
|
147
117
|
size: 20
|
|
148
118
|
}
|
|
149
119
|
),
|
|
150
|
-
/* @__PURE__ */
|
|
120
|
+
/* @__PURE__ */ jsx2("span", { children: priority })
|
|
151
121
|
] });
|
|
152
122
|
};
|
|
153
123
|
var RenderSortStatus_default = RenderSortStatus;
|
|
154
124
|
|
|
155
|
-
// src/hooks/useTranslationTable.ts
|
|
156
|
-
import { useMemo as useMemo2 } from "react";
|
|
157
|
-
import { useTranslation } from "react-i18next";
|
|
158
|
-
var useTranslationTable = (column) => {
|
|
159
|
-
const { i18n, t } = useTranslation();
|
|
160
|
-
const columnTranslation = useMemo2(() => {
|
|
161
|
-
return column.map((item) => ({ ...item, name: t(`${item == null ? void 0 : item.name}`) }));
|
|
162
|
-
}, [i18n == null ? void 0 : i18n.language, column]);
|
|
163
|
-
return columnTranslation;
|
|
164
|
-
};
|
|
165
|
-
var useTranslationTable_default = useTranslationTable;
|
|
166
|
-
|
|
167
125
|
// src/ReactTableGridCustom.tsx
|
|
168
|
-
import { jsx as
|
|
126
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
169
127
|
var ReactTableGridCustomInner = ({
|
|
170
128
|
classNamePaginationTable,
|
|
171
129
|
classNameWapperTable,
|
|
@@ -188,192 +146,129 @@ var ReactTableGridCustomInner = ({
|
|
|
188
146
|
...spread
|
|
189
147
|
}) => {
|
|
190
148
|
const { t } = useTranslation2();
|
|
191
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
192
149
|
const tableRef = useRef(null);
|
|
150
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
193
151
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
194
152
|
const [sortColumns, setSortColumns] = useState([]);
|
|
195
153
|
const isSelectRow = selectedRows !== void 0;
|
|
196
|
-
const maxPage =
|
|
197
|
-
() => !hiddenPagination ? calculatorTotalPage({
|
|
198
|
-
total,
|
|
199
|
-
pageSize
|
|
200
|
-
}) : 0,
|
|
154
|
+
const maxPage = useMemo2(
|
|
155
|
+
() => !hiddenPagination ? calculatorTotalPage({ total, pageSize }) : 0,
|
|
201
156
|
[pageSize, total, hiddenPagination]
|
|
202
157
|
);
|
|
203
|
-
const toInPagination =
|
|
204
|
-
|
|
205
|
-
from
|
|
206
|
-
to: 0
|
|
207
|
-
};
|
|
208
|
-
if (!hiddenPaginationText && pageSize && page) {
|
|
209
|
-
const from = STT(
|
|
210
|
-
{
|
|
211
|
-
page,
|
|
212
|
-
pageSize
|
|
213
|
-
},
|
|
214
|
-
0
|
|
215
|
-
);
|
|
158
|
+
const toInPagination = useMemo2(() => {
|
|
159
|
+
if (!hiddenPaginationText && page && pageSize) {
|
|
160
|
+
const from = STT({ page, pageSize }, 0);
|
|
216
161
|
return {
|
|
217
162
|
from,
|
|
218
|
-
to: maxPage === page ? total : page * pageSize
|
|
163
|
+
to: maxPage === page ? total != null ? total : 0 : page * pageSize
|
|
219
164
|
};
|
|
220
165
|
}
|
|
221
|
-
return
|
|
222
|
-
}, [
|
|
223
|
-
const columnTranslation = useTranslationTable_default(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
newCol.width = 200;
|
|
239
|
-
return newCol;
|
|
240
|
-
});
|
|
241
|
-
const totalMaxWidth = columnsCustom.reduce((sum, col) => {
|
|
242
|
-
var _a;
|
|
243
|
-
return sum + ("width" in col ? Number((_a = col == null ? void 0 : col.width) != null ? _a : 200) : 0);
|
|
244
|
-
}, 0);
|
|
245
|
-
if (totalMaxWidth < adjustedContainerWidth && columnsCustom.length > 0) {
|
|
246
|
-
const evenWidth = Math.floor(adjustedContainerWidth / columnsCustom.length);
|
|
247
|
-
columnsCustom = columnsCustom.map((col) => {
|
|
248
|
-
const newCol = { ...col };
|
|
249
|
-
delete newCol.maxWidth;
|
|
250
|
-
newCol.width = evenWidth;
|
|
251
|
-
return newCol;
|
|
252
|
-
});
|
|
253
|
-
}
|
|
166
|
+
return { from: 0, to: 0 };
|
|
167
|
+
}, [page, pageSize, hiddenPaginationText, maxPage, total]);
|
|
168
|
+
const columnTranslation = useTranslationTable_default(
|
|
169
|
+
columns
|
|
170
|
+
);
|
|
171
|
+
const newColumns = useMemo2(() => {
|
|
172
|
+
let cols = [
|
|
173
|
+
...columnTranslation
|
|
174
|
+
];
|
|
175
|
+
const adjustedWidth = containerWidth - 45;
|
|
176
|
+
cols = cols.map(
|
|
177
|
+
(col) => "key" in col ? {
|
|
178
|
+
...col,
|
|
179
|
+
width: 200,
|
|
180
|
+
maxWidth: void 0
|
|
181
|
+
} : col
|
|
182
|
+
);
|
|
254
183
|
if (isSelectRow) {
|
|
255
|
-
|
|
184
|
+
cols.unshift(SelectColumn);
|
|
256
185
|
}
|
|
257
|
-
if (!hiddenSTT
|
|
258
|
-
|
|
186
|
+
if (!hiddenSTT) {
|
|
187
|
+
const sttColumn = {
|
|
259
188
|
key: "index",
|
|
260
189
|
name: "STT",
|
|
261
190
|
width: 80,
|
|
262
191
|
renderCell: ({ rowIdx }) => STT({ page, pageSize }, rowIdx)
|
|
263
|
-
}
|
|
192
|
+
};
|
|
193
|
+
cols.unshift(sttColumn);
|
|
264
194
|
}
|
|
265
|
-
return
|
|
266
|
-
}, [
|
|
267
|
-
|
|
268
|
-
|
|
195
|
+
return cols;
|
|
196
|
+
}, [
|
|
197
|
+
columnTranslation,
|
|
198
|
+
containerWidth,
|
|
199
|
+
hiddenSTT,
|
|
200
|
+
isSelectRow,
|
|
201
|
+
page,
|
|
202
|
+
pageSize
|
|
203
|
+
]);
|
|
204
|
+
const customRowKeyGetter = useCallback(
|
|
205
|
+
(row) => {
|
|
269
206
|
if (typeof rowKeyGetter === "function") {
|
|
270
207
|
return rowKeyGetter(row);
|
|
271
208
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}, [rowKeyGetter]);
|
|
275
|
-
const handlePageChange = useCallback(
|
|
276
|
-
(page2) => {
|
|
277
|
-
if (onChange) {
|
|
278
|
-
onChange(page2);
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
if (setConfigPagination) {
|
|
282
|
-
setConfigPagination((prev) => ({ ...prev, page: page2 }));
|
|
209
|
+
if (typeof rowKeyGetter === "string") {
|
|
210
|
+
return get(row, rowKeyGetter);
|
|
283
211
|
}
|
|
212
|
+
throw new Error(
|
|
213
|
+
"rowKeyGetter must be a string or a function"
|
|
214
|
+
);
|
|
284
215
|
},
|
|
285
|
-
[
|
|
216
|
+
[rowKeyGetter]
|
|
286
217
|
);
|
|
287
|
-
const sortedRows =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const
|
|
292
|
-
|
|
218
|
+
const sortedRows = useMemo2(() => {
|
|
219
|
+
if (!sortColumns.length) return data;
|
|
220
|
+
const { columnKey, direction } = sortColumns[0];
|
|
221
|
+
if (!direction) return data;
|
|
222
|
+
const order = direction === "ASC" ? "asc" : "desc";
|
|
223
|
+
const iteratee = typeof columnKey === "string" ? columnKey : String(columnKey);
|
|
224
|
+
return orderBy(data, [iteratee], [order]);
|
|
293
225
|
}, [data, sortColumns]);
|
|
294
226
|
useEffect(() => {
|
|
295
|
-
|
|
296
|
-
|
|
227
|
+
var _a;
|
|
228
|
+
setIsLoading(false);
|
|
229
|
+
if ((_a = tableRef.current) == null ? void 0 : _a.element) {
|
|
230
|
+
setContainerWidth(tableRef.current.element.offsetWidth);
|
|
297
231
|
}
|
|
298
|
-
}, [
|
|
299
|
-
return /* @__PURE__ */
|
|
232
|
+
}, []);
|
|
233
|
+
return /* @__PURE__ */ jsxs2(
|
|
300
234
|
"div",
|
|
301
235
|
{
|
|
302
236
|
className: cn(
|
|
303
|
-
"wapper_table flex
|
|
237
|
+
"wapper_table flex flex-col h-full min-h-0",
|
|
304
238
|
classNameWapperTable
|
|
305
239
|
),
|
|
306
240
|
children: [
|
|
307
|
-
/* @__PURE__ */
|
|
308
|
-
|
|
309
|
-
DataGrid,
|
|
310
|
-
{
|
|
311
|
-
ref: tableRef,
|
|
312
|
-
"aria-rowcount": sortedRows == null ? void 0 : sortedRows.length,
|
|
313
|
-
selectedRows,
|
|
314
|
-
rows: sortedRows,
|
|
315
|
-
rowKeyGetter: rowKeyGetter && isSelectRow ? customRowKeyGetter : void 0,
|
|
316
|
-
columns: newColumns,
|
|
317
|
-
renderers: {
|
|
318
|
-
renderSortStatus: RenderSortStatus_default,
|
|
319
|
-
renderCheckbox({ onChange: onChange2, checked, ...spread2 }) {
|
|
320
|
-
const handleChange = (e) => {
|
|
321
|
-
onChange2(e.target.checked, e.nativeEvent.shiftKey);
|
|
322
|
-
};
|
|
323
|
-
return /* @__PURE__ */ jsx4(Checkbox, { color: "indigo", checked: !!checked, onChange: handleChange, ...spread2 });
|
|
324
|
-
}
|
|
325
|
-
},
|
|
326
|
-
className: "fill-grid flex-1 h-full min-h-0",
|
|
327
|
-
defaultColumnOptions: {
|
|
328
|
-
// minWidth: 200,
|
|
329
|
-
// maxWidth: 200,
|
|
330
|
-
renderCell: ({ column, row }) => {
|
|
331
|
-
const value = get(row, column.key);
|
|
332
|
-
return [null, void 0, ""].includes(value) ? "-" : value;
|
|
333
|
-
}
|
|
334
|
-
},
|
|
335
|
-
sortColumns,
|
|
336
|
-
onSortColumnsChange: setSortColumns,
|
|
337
|
-
...spread
|
|
338
|
-
}
|
|
339
|
-
),
|
|
340
|
-
total === 0 && TableLogo && /* @__PURE__ */ jsx4("div", { className: "no_result absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 select-none", children: /* @__PURE__ */ jsx4("div", { className: "flex flex-col justify-center", children: /* @__PURE__ */ jsx4("img", { src: TableLogo, alt: "", className: "size-32" }) }) })
|
|
341
|
-
] }),
|
|
342
|
-
!hiddenPagination && /* @__PURE__ */ jsxs3(
|
|
343
|
-
"div",
|
|
241
|
+
/* @__PURE__ */ jsx3(
|
|
242
|
+
DataGrid,
|
|
344
243
|
{
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
244
|
+
ref: tableRef,
|
|
245
|
+
rows: sortedRows,
|
|
246
|
+
columns: newColumns,
|
|
247
|
+
selectedRows,
|
|
248
|
+
rowKeyGetter: isSelectRow ? customRowKeyGetter : void 0,
|
|
249
|
+
sortColumns,
|
|
250
|
+
onSortColumnsChange: setSortColumns,
|
|
251
|
+
renderers: {
|
|
252
|
+
renderSortStatus: RenderSortStatus_default,
|
|
253
|
+
renderCheckbox({ onChange: onChange2, checked, ...props }) {
|
|
254
|
+
return /* @__PURE__ */ jsx3(
|
|
255
|
+
Checkbox,
|
|
256
|
+
{
|
|
257
|
+
...props,
|
|
258
|
+
checked: !!checked,
|
|
259
|
+
onChange: (e) => {
|
|
260
|
+
const nativeEvent = e.nativeEvent;
|
|
261
|
+
const shiftKey = nativeEvent instanceof MouseEvent ? nativeEvent.shiftKey : false;
|
|
262
|
+
onChange2(e.target.checked, shiftKey);
|
|
359
263
|
}
|
|
360
264
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
{
|
|
366
|
-
color: "indigo",
|
|
367
|
-
total: maxPage,
|
|
368
|
-
size: "sm",
|
|
369
|
-
value: page,
|
|
370
|
-
onChange: handlePageChange
|
|
371
|
-
}
|
|
372
|
-
)
|
|
373
|
-
]
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
...spread
|
|
374
269
|
}
|
|
375
270
|
),
|
|
376
|
-
(fetching || isLoading) && /* @__PURE__ */
|
|
271
|
+
(fetching || isLoading) && /* @__PURE__ */ jsx3("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx3(LoadingIcon, { isSpin: true }) })
|
|
377
272
|
]
|
|
378
273
|
}
|
|
379
274
|
);
|
|
@@ -381,6 +276,262 @@ var ReactTableGridCustomInner = ({
|
|
|
381
276
|
var ReactTableGridCustom = memo(
|
|
382
277
|
ReactTableGridCustomInner
|
|
383
278
|
);
|
|
279
|
+
|
|
280
|
+
// src/component/TableStyleContextWapper.tsx
|
|
281
|
+
import { memo as memo2, useId as useId2 } from "react";
|
|
282
|
+
|
|
283
|
+
// src/component/ui/ContextMenu/ContextMenu.tsx
|
|
284
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
285
|
+
import { createPortal } from "react-dom";
|
|
286
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
287
|
+
var ContextMenu = ({ selector, children, zIndex = 40 }) => {
|
|
288
|
+
const menuRef = useRef2(null);
|
|
289
|
+
const closeMenu = useCallback2(() => {
|
|
290
|
+
const contextMenuElem = menuRef.current;
|
|
291
|
+
const elementParent = document.querySelector(selector);
|
|
292
|
+
if (contextMenuElem && contextMenuElem.classList.contains("shadow-menu")) {
|
|
293
|
+
contextMenuElem.classList.remove("shadow-menu");
|
|
294
|
+
contextMenuElem.style.opacity = "0";
|
|
295
|
+
contextMenuElem.style.visibility = "hidden";
|
|
296
|
+
}
|
|
297
|
+
if (elementParent) {
|
|
298
|
+
elementParent.style.removeProperty("overflow");
|
|
299
|
+
}
|
|
300
|
+
}, [menuRef.current]);
|
|
301
|
+
useEffect2(() => {
|
|
302
|
+
const elementParent = document.querySelector(selector);
|
|
303
|
+
if (elementParent) {
|
|
304
|
+
const clickMenu = (e) => {
|
|
305
|
+
const contextMenuElem = menuRef.current;
|
|
306
|
+
if (contextMenuElem) {
|
|
307
|
+
contextMenuElem.style.opacity = "1";
|
|
308
|
+
contextMenuElem.style.visibility = "visible";
|
|
309
|
+
const { width: widthContextMenu, height: heightContextMenu } = contextMenuElem.getBoundingClientRect();
|
|
310
|
+
elementParent.style.overflow = "hidden";
|
|
311
|
+
const maxWidth = window.innerWidth;
|
|
312
|
+
const maxHeight = window.innerHeight;
|
|
313
|
+
const remainingLeft = maxWidth - e.clientX;
|
|
314
|
+
const isLeft = remainingLeft >= widthContextMenu;
|
|
315
|
+
const showTop = heightContextMenu + e.clientY <= maxHeight;
|
|
316
|
+
const showBottom = e.clientY - heightContextMenu >= 0;
|
|
317
|
+
const isCenter = !(showTop || showBottom);
|
|
318
|
+
isCenter;
|
|
319
|
+
const styleOrigin = {
|
|
320
|
+
x: "left",
|
|
321
|
+
y: "top"
|
|
322
|
+
};
|
|
323
|
+
if (isLeft) {
|
|
324
|
+
contextMenuElem.style.left = `${e.clientX}px`;
|
|
325
|
+
styleOrigin.x = "left";
|
|
326
|
+
} else {
|
|
327
|
+
contextMenuElem.style.left = `${e.clientX - widthContextMenu}px`;
|
|
328
|
+
styleOrigin.x = "right";
|
|
329
|
+
}
|
|
330
|
+
if (showTop) {
|
|
331
|
+
contextMenuElem.style.top = `${e.clientY}px`;
|
|
332
|
+
styleOrigin.y = "top";
|
|
333
|
+
} else if (showBottom) {
|
|
334
|
+
contextMenuElem.style.top = `${e.clientY - heightContextMenu}px`;
|
|
335
|
+
styleOrigin.y = "bottom";
|
|
336
|
+
} else {
|
|
337
|
+
const HalfHeight = heightContextMenu / 2;
|
|
338
|
+
const calculatorTop = HalfHeight + e.clientY;
|
|
339
|
+
const showTopCenter = calculatorTop <= maxHeight;
|
|
340
|
+
const calculatorBottom = e.clientY - HalfHeight;
|
|
341
|
+
const showBottom2 = calculatorBottom >= 0;
|
|
342
|
+
let topNew = calculatorBottom;
|
|
343
|
+
if (!showBottom2 && showTopCenter) {
|
|
344
|
+
topNew = topNew - calculatorBottom;
|
|
345
|
+
} else if (!showTopCenter && showBottom2) {
|
|
346
|
+
const ts = calculatorTop - maxHeight;
|
|
347
|
+
topNew = topNew - ts;
|
|
348
|
+
}
|
|
349
|
+
contextMenuElem.style.top = `${topNew}px`;
|
|
350
|
+
styleOrigin.y = "center";
|
|
351
|
+
}
|
|
352
|
+
contextMenuElem.style.transformOrigin = `${styleOrigin.y} ${styleOrigin.x}`;
|
|
353
|
+
if (!contextMenuElem.classList.contains("shadow-menu")) {
|
|
354
|
+
contextMenuElem.classList.add("shadow-menu");
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
elementParent.addEventListener("contextmenu", clickMenu);
|
|
359
|
+
window.addEventListener("click", closeMenu);
|
|
360
|
+
return () => {
|
|
361
|
+
elementParent.removeEventListener("contextmenu", clickMenu);
|
|
362
|
+
window.removeEventListener("click", closeMenu);
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
return () => {
|
|
366
|
+
};
|
|
367
|
+
}, []);
|
|
368
|
+
return createPortal(
|
|
369
|
+
/* @__PURE__ */ jsx4(
|
|
370
|
+
"div",
|
|
371
|
+
{
|
|
372
|
+
className: "fixed z-40 w-fit",
|
|
373
|
+
ref: menuRef,
|
|
374
|
+
style: { opacity: 0, visibility: "hidden", zIndex },
|
|
375
|
+
children
|
|
376
|
+
}
|
|
377
|
+
),
|
|
378
|
+
document.body
|
|
379
|
+
);
|
|
380
|
+
};
|
|
381
|
+
var ContextMenu_default = ContextMenu;
|
|
382
|
+
|
|
383
|
+
// src/component/ui/ContextMenu/RenderContextMenu.tsx
|
|
384
|
+
import { Fragment as Fragment2, useState as useState2 } from "react";
|
|
385
|
+
|
|
386
|
+
// src/component/ui/ContextMenu/ContextMenuItem.tsx
|
|
387
|
+
import { useTranslation as useTranslation3 } from "react-i18next";
|
|
388
|
+
import { MdKeyboardArrowRight } from "react-icons/md";
|
|
389
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
390
|
+
var ContextMenuItem = ({
|
|
391
|
+
currentValue,
|
|
392
|
+
expandValue,
|
|
393
|
+
valueClickItem,
|
|
394
|
+
show,
|
|
395
|
+
isArrow
|
|
396
|
+
}) => {
|
|
397
|
+
const { t } = useTranslation3();
|
|
398
|
+
const Icon = currentValue.Icon;
|
|
399
|
+
return /* @__PURE__ */ jsxs3(
|
|
400
|
+
"div",
|
|
401
|
+
{
|
|
402
|
+
className: `cursor-pointer p-2 flex items-center space-x-2 relative ${show ? "bg-[#555] text-white" : "hover:bg-[#555] hover:text-white"}`,
|
|
403
|
+
onClick: () => {
|
|
404
|
+
var _a;
|
|
405
|
+
expandValue && valueClickItem && (currentValue == null ? void 0 : currentValue.onClick) && ((_a = currentValue == null ? void 0 : currentValue.onClick) == null ? void 0 : _a.call(currentValue, valueClickItem, expandValue));
|
|
406
|
+
},
|
|
407
|
+
children: [
|
|
408
|
+
/* @__PURE__ */ jsx5(Icon, { size: 20 }),
|
|
409
|
+
/* @__PURE__ */ jsx5("span", { className: "text-sm flex-1", children: t(`${currentValue.action}`) }),
|
|
410
|
+
isArrow && /* @__PURE__ */ jsx5(MdKeyboardArrowRight, { size: 20 })
|
|
411
|
+
]
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
};
|
|
415
|
+
var ContextMenuItem_default = ContextMenuItem;
|
|
416
|
+
|
|
417
|
+
// src/component/ui/ContextMenu/DropdownContextChild.tsx
|
|
418
|
+
import Tippy from "@tippyjs/react";
|
|
419
|
+
import { useId, useRef as useRef3 } from "react";
|
|
420
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
421
|
+
var DropdownContextChild = ({ button, children, ...rest }) => {
|
|
422
|
+
const id = useId();
|
|
423
|
+
const instanceRef = useRef3(null);
|
|
424
|
+
return /* @__PURE__ */ jsx6(
|
|
425
|
+
Tippy,
|
|
426
|
+
{
|
|
427
|
+
theme: "drop-down",
|
|
428
|
+
className: "!bg-transparent !text-inherit !border-r-0 [&>*]:!p-0",
|
|
429
|
+
appendTo: document.body,
|
|
430
|
+
arrow: false,
|
|
431
|
+
placement: "auto",
|
|
432
|
+
interactive: true,
|
|
433
|
+
allowHTML: true,
|
|
434
|
+
content: children,
|
|
435
|
+
...rest,
|
|
436
|
+
children: /* @__PURE__ */ jsx6(
|
|
437
|
+
"div",
|
|
438
|
+
{
|
|
439
|
+
id: `div-${id}`,
|
|
440
|
+
onClick: () => {
|
|
441
|
+
var _a;
|
|
442
|
+
(_a = instanceRef == null ? void 0 : instanceRef.current) == null ? void 0 : _a.show();
|
|
443
|
+
},
|
|
444
|
+
children: button
|
|
445
|
+
}
|
|
446
|
+
)
|
|
447
|
+
}
|
|
448
|
+
);
|
|
449
|
+
};
|
|
450
|
+
var DropdownContextChild_default = DropdownContextChild;
|
|
451
|
+
|
|
452
|
+
// src/component/ui/ContextMenu/RenderContextMenu.tsx
|
|
453
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
454
|
+
var RenderContextMenu = ({
|
|
455
|
+
renderData,
|
|
456
|
+
valueClickItem,
|
|
457
|
+
expandValue = {}
|
|
458
|
+
}) => {
|
|
459
|
+
return /* @__PURE__ */ jsx7("div", { className: "bg-white shadow-submenu p-1 min-w-[250px] border", children: renderData == null ? void 0 : renderData.map((menuAction, index) => {
|
|
460
|
+
const [isShow, setIsShow] = useState2(false);
|
|
461
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
462
|
+
!(menuAction == null ? void 0 : menuAction.children) && /* @__PURE__ */ jsx7(
|
|
463
|
+
ContextMenuItem_default,
|
|
464
|
+
{
|
|
465
|
+
currentValue: menuAction,
|
|
466
|
+
expandValue,
|
|
467
|
+
valueClickItem
|
|
468
|
+
}
|
|
469
|
+
),
|
|
470
|
+
(menuAction == null ? void 0 : menuAction.children) && /* @__PURE__ */ jsx7(
|
|
471
|
+
DropdownContextChild_default,
|
|
472
|
+
{
|
|
473
|
+
appendTo: "parent",
|
|
474
|
+
placement: "right",
|
|
475
|
+
offset: [0, 5],
|
|
476
|
+
onShow: () => setIsShow(true),
|
|
477
|
+
onHide: () => setIsShow(false),
|
|
478
|
+
button: /* @__PURE__ */ jsx7(
|
|
479
|
+
ContextMenuItem_default,
|
|
480
|
+
{
|
|
481
|
+
currentValue: menuAction,
|
|
482
|
+
expandValue,
|
|
483
|
+
valueClickItem,
|
|
484
|
+
show: isShow,
|
|
485
|
+
isArrow: true
|
|
486
|
+
}
|
|
487
|
+
),
|
|
488
|
+
children: /* @__PURE__ */ jsx7("div", { className: "dropdown-context-child absolute -top-[20px] -left-1", children: /* @__PURE__ */ jsx7(
|
|
489
|
+
RenderContextMenu,
|
|
490
|
+
{
|
|
491
|
+
renderData: menuAction == null ? void 0 : menuAction.children,
|
|
492
|
+
expandValue,
|
|
493
|
+
valueClickItem
|
|
494
|
+
}
|
|
495
|
+
) })
|
|
496
|
+
}
|
|
497
|
+
)
|
|
498
|
+
] }, index);
|
|
499
|
+
}) });
|
|
500
|
+
};
|
|
501
|
+
var RenderContextMenu_default = RenderContextMenu;
|
|
502
|
+
|
|
503
|
+
// src/component/TableStyleContextWapper.tsx
|
|
504
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
505
|
+
var TableStyleContextMenuWapper = ({
|
|
506
|
+
children,
|
|
507
|
+
contextMenuProps,
|
|
508
|
+
clsTablecustom,
|
|
509
|
+
renderContext
|
|
510
|
+
}) => {
|
|
511
|
+
const idWapper = useId2();
|
|
512
|
+
return /* @__PURE__ */ jsxs5(
|
|
513
|
+
"div",
|
|
514
|
+
{
|
|
515
|
+
id: `wapper_menu_context-${idWapper}`,
|
|
516
|
+
className: `border border-[#dedede] rounded-xl overflow-hidden bg-white flex-1 h-full flex flex-col min-h-[360px] ${clsTablecustom != null ? clsTablecustom : ""}`,
|
|
517
|
+
children: [
|
|
518
|
+
(renderContext == null ? void 0 : renderContext.renderData) && /* @__PURE__ */ jsx8(
|
|
519
|
+
ContextMenu_default,
|
|
520
|
+
{
|
|
521
|
+
selector: `[id="wapper_menu_context-${idWapper}"] .rdg`,
|
|
522
|
+
...contextMenuProps,
|
|
523
|
+
children: /* @__PURE__ */ jsx8(RenderContextMenu_default, { ...renderContext })
|
|
524
|
+
}
|
|
525
|
+
),
|
|
526
|
+
children
|
|
527
|
+
]
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
};
|
|
531
|
+
var TableStyleContextWapper = memo2(
|
|
532
|
+
TableStyleContextMenuWapper
|
|
533
|
+
);
|
|
384
534
|
export {
|
|
385
|
-
ReactTableGridCustom
|
|
535
|
+
ReactTableGridCustom,
|
|
536
|
+
TableStyleContextWapper
|
|
386
537
|
};
|