kelt-ui-kit-react 1.9.0 → 1.9.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.
- package/dist/dataTable/DataTable.d.ts +5 -0
- package/dist/dataTable/dataTable.interface.d.ts +1 -0
- package/dist/dataTable/dataTableRow/DataTableRow.d.ts +3 -1
- package/dist/index.js +5543 -50
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/dataTable/DataTable.tsx +242 -4
- package/src/dataTable/DataTable.view.tsx +9 -1
- package/src/dataTable/dataTable.css +57 -0
- package/src/dataTable/dataTable.interface.ts +1 -0
- package/src/dataTable/dataTableRow/DataTableRow.tsx +17 -1
- package/dist/App.js +0 -22
- package/dist/App.menu.js +0 -251
- package/dist/App.routes.js +0 -8
- package/dist/_core/hooks/HistoryProvider.js +0 -29
- package/dist/_core/hooks/ImageChecker.js +0 -68
- package/dist/_core/hooks/imageExist.js +0 -5
- package/dist/_core/hooks/isEAN13.js +0 -10
- package/dist/_core/hooks/objectToQueryParams.js +0 -28
- package/dist/_core/hooks/useCurrency.js +0 -12
- package/dist/_core/hooks/useDateutils.js +0 -59
- package/dist/_core/hooks/useIsMobile.js +0 -13
- package/dist/_core/hooks/useToken.js +0 -17
- package/dist/_core/hooks/useValidate.js +0 -15
- package/dist/_core/hooks/widgetSupport.js +0 -18
- package/dist/action/Action.view.js +0 -22
- package/dist/action/ButtonAction.js +0 -25
- package/dist/badge/Badge.js +0 -25
- package/dist/badge/Badge.view.js +0 -5
- package/dist/button/Button.js +0 -25
- package/dist/button/Button.view.js +0 -74
- package/dist/button/button.interface.js +0 -1
- package/dist/button/buttonActions/ButtonActions.js +0 -55
- package/dist/button/buttonFile/ButtonFile.js +0 -37
- package/dist/button/buttonFile/ButtonFile.view.js +0 -35
- package/dist/button/buttonFilters/ButtonFilters.js +0 -47
- package/dist/card/Card.js +0 -57
- package/dist/card/Card.view.js +0 -60
- package/dist/card/card.interface.js +0 -1
- package/dist/card/cardAction/CardAction.js +0 -66
- package/dist/card/cardAction.interface.js +0 -1
- package/dist/card/hook/useCardInteractions.js +0 -25
- package/dist/carousel/Carousel.js +0 -67
- package/dist/carousel/Carousel.view.js +0 -16
- package/dist/damier/Damier.js +0 -48
- package/dist/damier/Damier.view.js +0 -22
- package/dist/damier/damierCell/DamierCell.js +0 -21
- package/dist/damier/damierCell/damierCell.interface.js +0 -1
- package/dist/dataTable/DataTable.js +0 -117
- package/dist/dataTable/DataTable.view.js +0 -48
- package/dist/dataTable/dataTable.interface.js +0 -1
- package/dist/dataTable/dataTableActions/DataTableAction.js +0 -26
- package/dist/dataTable/dataTableColumn/DataTableColumn.js +0 -21
- package/dist/dataTable/dataTableLoading/DataTableLoading.js +0 -16
- package/dist/dataTable/dataTableRow/DataTableRow.js +0 -39
- package/dist/datePicker/DatePicker.js +0 -64
- package/dist/datePicker/DatePicker.view.js +0 -5
- package/dist/expands/Expands.js +0 -28
- package/dist/expands/Expands.view.js +0 -67
- package/dist/expands/expand/expand.interface.js +0 -1
- package/dist/expands/expand/expand.js +0 -40
- package/dist/filAriane/FilAriane.js +0 -28
- package/dist/filAriane/FilAriane.view.js +0 -28
- package/dist/filAriane/filAriane.interface.js +0 -1
- package/dist/form/Form.js +0 -135
- package/dist/form/Form.view.js +0 -50
- package/dist/form/form.enum.js +0 -14
- package/dist/form/form.interface.js +0 -1
- package/dist/form/input/Input.js +0 -26
- package/dist/form/inputNumber/InputNumber.js +0 -57
- package/dist/form/inputNumber/InputNumber.view.js +0 -7
- package/dist/form/inputPrice/InputPrice.js +0 -36
- package/dist/form/inputPrice/InputPrice.view.js +0 -7
- package/dist/form/textArea/TextArea.js +0 -18
- package/dist/form/textArea/TextArea.view.js +0 -15
- package/dist/grid/Grid.js +0 -19
- package/dist/grid/Grid.view.js +0 -22
- package/dist/grid/col/Col.js +0 -17
- package/dist/grid/col/colStyled/ColStyled.js +0 -26
- package/dist/grid/container/Container.js +0 -17
- package/dist/grid/grid.interface.js +0 -1
- package/dist/grid/row/Row.js +0 -17
- package/dist/header/Header.js +0 -26
- package/dist/header/Header.view.js +0 -5
- package/dist/header/header.interface.js +0 -1
- package/dist/home/Home.js +0 -4
- package/dist/icon/Icon.js +0 -6
- package/dist/icon/Icons.view.js +0 -27
- package/dist/icon/icon.interface.js +0 -1
- package/dist/icon/iconSize.enum.js +0 -8
- package/dist/loader/Loader.js +0 -20
- package/dist/loader/Loader.view.js +0 -9
- package/dist/main.js +0 -7
- package/dist/menus/Menus.js +0 -23
- package/dist/menus/Menus.view.js +0 -48
- package/dist/menus/menu/Menu.js +0 -15
- package/dist/menus/menu/menu.interface.js +0 -1
- package/dist/message/Message.js +0 -33
- package/dist/message/Message.view.js +0 -11
- package/dist/modal/Modal.js +0 -27
- package/dist/modal/Modal.view.js +0 -22
- package/dist/notFound/NotFound.js +0 -4
- package/dist/overlayPanel/OverlayPanel.js +0 -132
- package/dist/overlayPanel/OverlayPanel.view.js +0 -20
- package/dist/overlayPanel/overlay.context.js +0 -26
- package/dist/overlayPanel/overlayPanelStyled/OverlayPanelStyled.js +0 -13
- package/dist/pdfViewer/PdfViewer.js +0 -71
- package/dist/pdfViewer/PdfViewer.view.js +0 -5
- package/dist/quantity/Quantity.js +0 -60
- package/dist/quantity/Quantity.view.js +0 -1
- package/dist/search/Search.js +0 -80
- package/dist/search/Search.view.js +0 -8
- package/dist/select/Select.js +0 -41
- package/dist/select/Select.view.js +0 -75
- package/dist/select/selectOption.interface.js +0 -1
- package/dist/sidebar/Sidebar.js +0 -132
- package/dist/sidebar/Sidebar.view.js +0 -11
- package/dist/sidebarData/SidebarData.js +0 -17
- package/dist/sidebarData/SidebarData.view.js +0 -14
- package/dist/tabs/Tabs.js +0 -41
- package/dist/tabs/Tabs.view.js +0 -26
- package/dist/toaster/Toaster.js +0 -37
- package/dist/toaster/Toaster.view.js +0 -16
- package/dist/toaster/store/useToasterStore.js +0 -22
- package/vite.config.ts.timestamp-1787675603363-8ddae73d076bd.mjs +0 -28
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
2
3
|
import { TypeInputEnum } from "../form/form.enum";
|
|
3
4
|
import { Input } from "../form/input/Input";
|
|
5
|
+
import { Icon } from "../icon/Icon";
|
|
4
6
|
import { Loader } from "../loader/Loader";
|
|
5
7
|
import "./dataTable.css";
|
|
6
8
|
import {
|
|
@@ -20,6 +22,10 @@ export type DataTableProps<T> = {
|
|
|
20
22
|
data: T[];
|
|
21
23
|
emptyMessage?: string;
|
|
22
24
|
actions?: dataTableActionsInterface<T>[];
|
|
25
|
+
footerAction?: (props: {
|
|
26
|
+
close: () => void;
|
|
27
|
+
selectedRows: T[];
|
|
28
|
+
}) => JSX.Element;
|
|
23
29
|
columns: dataTableColumnsInterface<T>[];
|
|
24
30
|
loading?: boolean;
|
|
25
31
|
onRowClick?: (row: any) => void;
|
|
@@ -27,6 +33,7 @@ export type DataTableProps<T> = {
|
|
|
27
33
|
onLoadMore?: () => void;
|
|
28
34
|
hasMore?: boolean; // pour savoir s'il reste des données à charger
|
|
29
35
|
onSelectionChange?: (selectedRows: T[]) => void;
|
|
36
|
+
autoFocusFirstEditable?: boolean;
|
|
30
37
|
hideToggleAll?: boolean;
|
|
31
38
|
limitSelect?: number;
|
|
32
39
|
getRowId?: (row: T) => string | number;
|
|
@@ -40,6 +47,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
40
47
|
element,
|
|
41
48
|
data = [],
|
|
42
49
|
actions = [],
|
|
50
|
+
footerAction,
|
|
43
51
|
columns = [],
|
|
44
52
|
loading,
|
|
45
53
|
onRowClick,
|
|
@@ -48,16 +56,40 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
48
56
|
emptyMessage,
|
|
49
57
|
hasMore,
|
|
50
58
|
onSelectionChange,
|
|
59
|
+
autoFocusFirstEditable = false,
|
|
51
60
|
hideToggleAll = false,
|
|
52
61
|
limitSelect = undefined,
|
|
53
62
|
getRowId,
|
|
54
63
|
} = props;
|
|
55
64
|
|
|
56
65
|
const loaderRef = useRef<HTMLDivElement | null>(null);
|
|
66
|
+
const footerActionRef = useRef<HTMLDivElement | null>(null);
|
|
67
|
+
const hasAutoFocusedRef = useRef(false);
|
|
68
|
+
const [isFooterActionVisible, setIsFooterActionVisible] = useState(false);
|
|
69
|
+
const [footerActionOffset, setFooterActionOffset] = useState(0);
|
|
57
70
|
const [selectedRowIds, setSelectedRowIds] = useState<Set<string | number>>(
|
|
58
71
|
new Set(),
|
|
59
72
|
);
|
|
60
73
|
|
|
74
|
+
const focusEditableElement = useCallback((element: HTMLElement | null) => {
|
|
75
|
+
if (!element) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
element.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
80
|
+
|
|
81
|
+
requestAnimationFrame(() => {
|
|
82
|
+
element.focus();
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
element instanceof HTMLInputElement ||
|
|
86
|
+
element instanceof HTMLTextAreaElement
|
|
87
|
+
) {
|
|
88
|
+
element.select();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
61
93
|
const isInteractiveClick = useCallback((target: EventTarget | null) => {
|
|
62
94
|
const element =
|
|
63
95
|
target instanceof Element
|
|
@@ -81,6 +113,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
81
113
|
if (selectedRowIds.size === data.length) {
|
|
82
114
|
setSelectedRowIds(new Set());
|
|
83
115
|
onSelectionChange?.([]);
|
|
116
|
+
setIsFooterActionVisible(false);
|
|
84
117
|
} else {
|
|
85
118
|
let allIds = data.map((d) =>
|
|
86
119
|
getRowId ? getRowId(d) : ((d as any).id ?? d),
|
|
@@ -92,6 +125,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
92
125
|
|
|
93
126
|
const newSelection = new Set(allIds);
|
|
94
127
|
setSelectedRowIds(newSelection);
|
|
128
|
+
setIsFooterActionVisible(true);
|
|
95
129
|
onSelectionChange?.(
|
|
96
130
|
data.filter((d) =>
|
|
97
131
|
newSelection.has(getRowId ? getRowId(d) : ((d as any).id ?? d)),
|
|
@@ -100,6 +134,86 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
100
134
|
}
|
|
101
135
|
}, [data, onSelectionChange, limitSelect, getRowId, selectedRowIds.size]);
|
|
102
136
|
|
|
137
|
+
const focusNextColumn = useCallback(
|
|
138
|
+
(columnIndex: number, rowIndex: number) => {
|
|
139
|
+
if (typeof document === "undefined") {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const table = document.getElementById(id);
|
|
144
|
+
const eligibleColumnIndexes = columns.reduce<number[]>(
|
|
145
|
+
(indexes, column, idx) => {
|
|
146
|
+
if (
|
|
147
|
+
column.editable &&
|
|
148
|
+
column.enterToNextColumn &&
|
|
149
|
+
column.type !== "select" &&
|
|
150
|
+
column.type !== "image"
|
|
151
|
+
) {
|
|
152
|
+
indexes.push(idx);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return indexes;
|
|
156
|
+
},
|
|
157
|
+
[],
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
if (!table || eligibleColumnIndexes.length === 0) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const currentEligibleIndex = eligibleColumnIndexes.indexOf(columnIndex);
|
|
165
|
+
|
|
166
|
+
if (currentEligibleIndex === -1) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const editableCells = data.flatMap((_, currentRowIndex) =>
|
|
171
|
+
eligibleColumnIndexes.map((currentColumnIndex) => ({
|
|
172
|
+
rowIndex: currentRowIndex,
|
|
173
|
+
columnIndex: currentColumnIndex,
|
|
174
|
+
})),
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const currentCellIndex = editableCells.findIndex(
|
|
178
|
+
(cell) => cell.rowIndex === rowIndex && cell.columnIndex === columnIndex,
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
if (currentCellIndex === -1) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const focusableSelector =
|
|
186
|
+
'input:not([disabled]), textarea:not([disabled]), [contenteditable="true"]';
|
|
187
|
+
let nextInput: HTMLElement | null = null;
|
|
188
|
+
|
|
189
|
+
for (let offset = 1; offset <= editableCells.length; offset += 1) {
|
|
190
|
+
const nextCell =
|
|
191
|
+
editableCells[(currentCellIndex + offset) % editableCells.length];
|
|
192
|
+
const cell = table.querySelector(
|
|
193
|
+
`tbody td[data-row-index="${nextCell.rowIndex}"][data-column-index="${nextCell.columnIndex}"]`,
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
if (!(cell instanceof HTMLElement)) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const focusableElement = cell.querySelector<HTMLElement>(focusableSelector);
|
|
201
|
+
|
|
202
|
+
if (focusableElement) {
|
|
203
|
+
nextInput = focusableElement;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (!nextInput) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
focusEditableElement(nextInput);
|
|
213
|
+
},
|
|
214
|
+
[columns, data, focusEditableElement, id],
|
|
215
|
+
);
|
|
216
|
+
|
|
103
217
|
const handleClickRow = useCallback(
|
|
104
218
|
(e: React.MouseEvent, row: T) => {
|
|
105
219
|
e.stopPropagation();
|
|
@@ -139,6 +253,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
139
253
|
}
|
|
140
254
|
|
|
141
255
|
setSelectedRowIds(newSelection);
|
|
256
|
+
setIsFooterActionVisible(newSelection.size > 0);
|
|
142
257
|
const selectedItems = data.filter((d) =>
|
|
143
258
|
newSelection.has(getRowId ? getRowId(d) : ((d as any).id ?? d)),
|
|
144
259
|
);
|
|
@@ -146,6 +261,88 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
146
261
|
},
|
|
147
262
|
[data, getRowId, limitSelect, onSelectionChange, selectedRowIds],
|
|
148
263
|
);
|
|
264
|
+
const showFooterAction = Boolean(footerAction && isFooterActionVisible);
|
|
265
|
+
const closeFooterAction = useCallback(() => {
|
|
266
|
+
setIsFooterActionVisible(false);
|
|
267
|
+
}, []);
|
|
268
|
+
const selectedRows = data.filter((d) =>
|
|
269
|
+
selectedRowIds.has(getRowId ? getRowId(d) : ((d as any).id ?? d)),
|
|
270
|
+
);
|
|
271
|
+
useEffect(() => {
|
|
272
|
+
if (loading || !autoFocusFirstEditable || data.length === 0) {
|
|
273
|
+
hasAutoFocusedRef.current = false;
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (hasAutoFocusedRef.current) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const firstEditableColumnIndex = columns.findIndex(
|
|
282
|
+
(column) =>
|
|
283
|
+
column.editable &&
|
|
284
|
+
column.enterToNextColumn &&
|
|
285
|
+
column.type !== "select" &&
|
|
286
|
+
column.type !== "image",
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
if (firstEditableColumnIndex === -1) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const table = document.getElementById(id);
|
|
294
|
+
const firstCell = table?.querySelector(
|
|
295
|
+
`tbody td[data-row-index="0"][data-column-index="${firstEditableColumnIndex}"]`,
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
if (!(firstCell instanceof HTMLElement)) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const firstInput = firstCell.querySelector<HTMLElement>(
|
|
303
|
+
'input:not([disabled]), textarea:not([disabled]), [contenteditable="true"]',
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
if (!firstInput) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
hasAutoFocusedRef.current = true;
|
|
311
|
+
focusEditableElement(firstInput);
|
|
312
|
+
}, [autoFocusFirstEditable, columns, data.length, focusEditableElement, id, loading]);
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
if (!showFooterAction) {
|
|
315
|
+
setFooterActionOffset(0);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const footerActionElement = footerActionRef.current;
|
|
320
|
+
|
|
321
|
+
if (!footerActionElement) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const updateFooterActionOffset = () => {
|
|
326
|
+
const { height } = footerActionElement.getBoundingClientRect();
|
|
327
|
+
setFooterActionOffset(Math.ceil(height) + 16);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
updateFooterActionOffset();
|
|
331
|
+
|
|
332
|
+
if (typeof ResizeObserver === "undefined") {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
337
|
+
updateFooterActionOffset();
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
resizeObserver.observe(footerActionElement);
|
|
341
|
+
|
|
342
|
+
return () => {
|
|
343
|
+
resizeObserver.disconnect();
|
|
344
|
+
};
|
|
345
|
+
}, [showFooterAction]);
|
|
149
346
|
useEffect(() => {
|
|
150
347
|
if (!onLoadMore || !hasMore) return;
|
|
151
348
|
|
|
@@ -173,7 +370,12 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
173
370
|
};
|
|
174
371
|
}, [onLoadMore, hasMore]);
|
|
175
372
|
return (
|
|
176
|
-
<div
|
|
373
|
+
<div
|
|
374
|
+
className={`data-table-container ${showFooterAction ? "data-table-container--with-footer-action" : ""}`}
|
|
375
|
+
style={
|
|
376
|
+
showFooterAction ? { paddingBottom: `${footerActionOffset}px` } : undefined
|
|
377
|
+
}
|
|
378
|
+
>
|
|
177
379
|
{name && <h2 className="mb-2">{name}</h2>}
|
|
178
380
|
{element}
|
|
179
381
|
<table className={`data-table ${className ? className : ""}`} id={id}>
|
|
@@ -234,13 +436,17 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
234
436
|
<tr
|
|
235
437
|
key={rowIndex}
|
|
236
438
|
className={rowIndex % 2 === 0 ? "even" : "odd"}
|
|
439
|
+
data-row-index={rowIndex}
|
|
237
440
|
onClick={(e) => handleClickRow?.(e, row)}
|
|
238
441
|
>
|
|
239
442
|
{onSelectionChange && (
|
|
240
443
|
<td
|
|
241
444
|
className="select-cell"
|
|
242
445
|
style={{ textAlign: "center" }}
|
|
243
|
-
onClick={(e) =>
|
|
446
|
+
onClick={(e) => {
|
|
447
|
+
e.stopPropagation();
|
|
448
|
+
setIsFooterActionVisible(true);
|
|
449
|
+
}}
|
|
244
450
|
>
|
|
245
451
|
<Input
|
|
246
452
|
id={`select-row-${rowIndex}`}
|
|
@@ -256,12 +462,19 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
256
462
|
checked={selectedRowIds.has(
|
|
257
463
|
getRowId ? getRowId(row) : ((row as any).id ?? row),
|
|
258
464
|
)}
|
|
259
|
-
onChange={(e) => toggleRow(e, row)}
|
|
465
|
+
onChange={(e) => toggleRow(e, row)}
|
|
260
466
|
/>
|
|
261
467
|
</td>
|
|
262
468
|
)}
|
|
263
469
|
{columns.map((column, idx) => (
|
|
264
|
-
<DataTableRow
|
|
470
|
+
<DataTableRow
|
|
471
|
+
column={column}
|
|
472
|
+
idx={idx}
|
|
473
|
+
row={row}
|
|
474
|
+
rowIndex={rowIndex}
|
|
475
|
+
key={idx}
|
|
476
|
+
onEnterNextColumn={focusNextColumn}
|
|
477
|
+
/>
|
|
265
478
|
))}
|
|
266
479
|
{actions.length > 0 && (
|
|
267
480
|
<td align="right" onClick={(e) => e.stopPropagation()}>
|
|
@@ -289,6 +502,31 @@ export function DataTable<T>(props: DataTableProps<T>) {
|
|
|
289
502
|
</tbody>
|
|
290
503
|
</table>
|
|
291
504
|
|
|
505
|
+
{showFooterAction &&
|
|
506
|
+
typeof document !== "undefined" &&
|
|
507
|
+
createPortal(
|
|
508
|
+
<div
|
|
509
|
+
ref={footerActionRef}
|
|
510
|
+
className="data-table-footer-action"
|
|
511
|
+
data-footer-action="true"
|
|
512
|
+
>
|
|
513
|
+
<div className="data-table-footer-action__content">
|
|
514
|
+
<div
|
|
515
|
+
className="data-table-footer-action__close"
|
|
516
|
+
aria-label="Fermer les actions"
|
|
517
|
+
onClick={closeFooterAction}
|
|
518
|
+
>
|
|
519
|
+
<Icon classIcon={"bi-x"} />
|
|
520
|
+
</div>
|
|
521
|
+
{footerAction?.({
|
|
522
|
+
close: closeFooterAction,
|
|
523
|
+
selectedRows,
|
|
524
|
+
})}
|
|
525
|
+
</div>
|
|
526
|
+
</div>,
|
|
527
|
+
document.body,
|
|
528
|
+
)}
|
|
529
|
+
|
|
292
530
|
{children}
|
|
293
531
|
{hasMore && (
|
|
294
532
|
<div ref={loaderRef} className="infinite-scroll-loader">
|
|
@@ -11,9 +11,17 @@ export const DataTableView = () => {
|
|
|
11
11
|
label: "Name",
|
|
12
12
|
minWidth: 100,
|
|
13
13
|
editable: true,
|
|
14
|
+
enterToNextColumn: true,
|
|
14
15
|
type: "text",
|
|
15
16
|
},
|
|
16
|
-
{
|
|
17
|
+
{
|
|
18
|
+
id: "age",
|
|
19
|
+
label: "Age",
|
|
20
|
+
minWidth: 50,
|
|
21
|
+
editable: true,
|
|
22
|
+
enterToNextColumn: true,
|
|
23
|
+
type: "number",
|
|
24
|
+
},
|
|
17
25
|
];
|
|
18
26
|
}, []);
|
|
19
27
|
const data = useMemo(() => {
|
|
@@ -1,5 +1,55 @@
|
|
|
1
|
+
.data-table-footer-action {
|
|
2
|
+
position: fixed;
|
|
3
|
+
left: 5px;
|
|
4
|
+
right: 5px;
|
|
5
|
+
bottom: 5px;
|
|
6
|
+
border-radius: 4px;
|
|
7
|
+
z-index: 1000;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
background: #fff;
|
|
10
|
+
border-top: 1px solid #e5e5e5;
|
|
11
|
+
box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.18);
|
|
12
|
+
animation: data-table-footer-action-enter 180ms ease-out;
|
|
13
|
+
|
|
14
|
+
& .data-table-footer-action__content {
|
|
15
|
+
position: relative;
|
|
16
|
+
padding: 0.75rem 1rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
& .data-table-footer-action__close {
|
|
20
|
+
position: absolute;
|
|
21
|
+
top: 5px;
|
|
22
|
+
right: 5px;
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
|
|
25
|
+
.bi {
|
|
26
|
+
color: #333;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@keyframes data-table-footer-action-enter {
|
|
35
|
+
from {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transform: translateY(100%);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
to {
|
|
41
|
+
opacity: 1;
|
|
42
|
+
transform: translateY(0);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
1
46
|
.data-table-container {
|
|
2
47
|
overflow: auto;
|
|
48
|
+
position: relative;
|
|
49
|
+
|
|
50
|
+
&.data-table-container--with-footer-action {
|
|
51
|
+
scroll-padding-bottom: 80px;
|
|
52
|
+
}
|
|
3
53
|
|
|
4
54
|
.data-table {
|
|
5
55
|
width: 100%;
|
|
@@ -21,15 +71,22 @@
|
|
|
21
71
|
}
|
|
22
72
|
}
|
|
23
73
|
|
|
74
|
+
|
|
24
75
|
thead {
|
|
25
76
|
margin-bottom: 1rem;
|
|
26
77
|
position: sticky;
|
|
27
78
|
top: 0;
|
|
79
|
+
z-index: 1;
|
|
28
80
|
background-color: #fff;
|
|
29
81
|
|
|
30
82
|
th {
|
|
83
|
+
position: sticky;
|
|
84
|
+
top: 0;
|
|
85
|
+
z-index: 2;
|
|
86
|
+
background-color: #fff;
|
|
31
87
|
color: #bdbaba;
|
|
32
88
|
min-width: 100px;
|
|
89
|
+
padding: .5rem;
|
|
33
90
|
}
|
|
34
91
|
}
|
|
35
92
|
|
|
@@ -12,6 +12,7 @@ export interface dataTableColumnsInterface<T> {
|
|
|
12
12
|
filterable?: boolean;
|
|
13
13
|
filterValue?: string;
|
|
14
14
|
editable?: boolean;
|
|
15
|
+
enterToNextColumn?: boolean;
|
|
15
16
|
options?: { label: string; value: string }[];
|
|
16
17
|
onEdit?: (value: any, row: T) => void;
|
|
17
18
|
onDisable?: (row: T) => boolean;
|
|
@@ -5,9 +5,17 @@ import { dataTableColumnsInterface } from "../dataTable.interface";
|
|
|
5
5
|
type DataTableRowProps = {
|
|
6
6
|
column: dataTableColumnsInterface<any>;
|
|
7
7
|
idx: number;
|
|
8
|
+
rowIndex: number;
|
|
8
9
|
row: any;
|
|
10
|
+
onEnterNextColumn?: (columnIndex: number, rowIndex: number) => void;
|
|
9
11
|
};
|
|
10
|
-
export const DataTableRow = ({
|
|
12
|
+
export const DataTableRow = ({
|
|
13
|
+
column,
|
|
14
|
+
idx,
|
|
15
|
+
rowIndex,
|
|
16
|
+
row,
|
|
17
|
+
onEnterNextColumn,
|
|
18
|
+
}: DataTableRowProps) => {
|
|
11
19
|
const value = (row as any)[column.id]; // On utilise [column.id] pour accéder aux bonnes propriétés
|
|
12
20
|
const style = column.onRowStyle ? column.onRowStyle(row) : {};
|
|
13
21
|
const isDisabled = column.onDisable?.(row) ?? false;
|
|
@@ -15,6 +23,8 @@ export const DataTableRow = ({ column, idx, row }: DataTableRowProps) => {
|
|
|
15
23
|
return (
|
|
16
24
|
<td
|
|
17
25
|
className={`${isDisabled ? "disabled" : ""}`}
|
|
26
|
+
data-column-index={idx}
|
|
27
|
+
data-row-index={rowIndex}
|
|
18
28
|
style={{
|
|
19
29
|
minWidth: column.minWidth,
|
|
20
30
|
textAlign: column.align || "left",
|
|
@@ -64,6 +74,12 @@ export const DataTableRow = ({ column, idx, row }: DataTableRowProps) => {
|
|
|
64
74
|
width: column.width,
|
|
65
75
|
}}
|
|
66
76
|
onClick={(e) => e.stopPropagation()}
|
|
77
|
+
onKeyDown={(e) => {
|
|
78
|
+
if (e.key === "Enter" && column.enterToNextColumn) {
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
onEnterNextColumn?.(idx, rowIndex);
|
|
81
|
+
}
|
|
82
|
+
}}
|
|
67
83
|
onChange={(e) => {
|
|
68
84
|
if (column.onEdit) {
|
|
69
85
|
column.onEdit(e.target.value, row);
|
package/dist/App.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
-
import { StrictMode } from "react";
|
|
14
|
-
import { BrowserRouter as Router } from "react-router-dom";
|
|
15
|
-
import "./App.css";
|
|
16
|
-
import { AppMenu } from "./App.menu";
|
|
17
|
-
import { AppRoutes } from "./App.routes";
|
|
18
|
-
import { Header } from "./header/Header";
|
|
19
|
-
import { OverlayProvider } from "./overlayPanel/overlay.context";
|
|
20
|
-
import { Toaster } from "./toaster/Toaster";
|
|
21
|
-
var App = function () { return (_jsx(StrictMode, { children: _jsx(OverlayProvider, { children: _jsx(Router, { children: _jsxs("div", __assign({ className: "main-layout" }, { children: [_jsx(Toaster, {}), _jsx(Header, { showBackNavigation: true }), _jsxs("div", __assign({ className: "d-flex h-100" }, { children: [_jsx(AppMenu, {}), _jsx("div", __assign({ className: "main-layout-content" }, { children: _jsx(AppRoutes, {}) }))] }))] })) }) }) })); };
|
|
22
|
-
export default App;
|