kelt-ui-kit-react 2.0.2 → 2.0.3
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 +0 -26
- package/dist/_core/type/generiqueType.d.ts +4 -0
- package/dist/badge/Badge.d.ts +3 -1
- package/dist/button/Button.d.ts +1 -1
- package/dist/button/button.interface.d.ts +1 -2
- package/dist/dataTable/DataTable.d.ts +17 -14
- package/dist/dataTable/dataTable.interface.d.ts +24 -19
- package/dist/dataTable/dataTableActions/DataTableAction.d.ts +3 -5
- package/dist/dataTable/dataTableColumn/DataTableColumn.d.ts +13 -7
- package/dist/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.d.ts +10 -0
- package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.d.ts +9 -0
- package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.d.ts +9 -0
- package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.d.ts +13 -0
- package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.d.ts +9 -0
- package/dist/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.d.ts +11 -0
- package/dist/dataTable/dataTableFilters/DataTableFilters.d.ts +7 -0
- package/dist/dataTable/dataTableLoading/DataTableLoading.d.ts +1 -3
- package/dist/dataTable/dataTableRow/DataTableRow.d.ts +5 -6
- package/dist/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.d.ts +12 -0
- package/dist/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.d.ts +11 -0
- package/dist/expands/expand/expand.d.ts +1 -1
- package/dist/form/Form.d.ts +2 -4
- package/dist/form/form.enum.d.ts +2 -3
- package/dist/form/form.interface.d.ts +2 -19
- package/dist/form/input/Input.d.ts +3 -0
- package/dist/form/inputNumber/InputNumber.d.ts +0 -2
- package/dist/grid/col/Col.d.ts +6 -3
- package/dist/grid/col/colStyled/ColStyled.d.ts +5 -7
- package/dist/grid/grid.interface.d.ts +5 -9
- package/dist/header/Header.d.ts +1 -1
- package/dist/header/header.interface.d.ts +1 -2
- package/dist/icon/Icon.d.ts +1 -1
- package/dist/icon/icon.interface.d.ts +1 -0
- package/dist/index.d.ts +1 -5
- package/dist/index.js +3606 -3543
- package/dist/menus/menu/Menu.d.ts +0 -1
- package/dist/overlayPanel/OverlayPanel.d.ts +4 -2
- package/dist/overlayPanel/overlayPanelStyled/OverlayPanelStyled.d.ts +2 -0
- package/dist/select/Select.d.ts +6 -2
- package/dist/select/selectOption.interface.d.ts +1 -0
- package/dist/style.css +1 -1
- package/dist/tabs/Tabs.d.ts +2 -1
- package/dist/toaster/store/useToasterStore.d.ts +0 -1
- package/index.html +2 -1
- package/package/package.json +56 -0
- package/package/src/sidebar/Sidebar.tsx +208 -0
- package/package/src/sidebar/sidebar.css +104 -0
- package/package.json +1 -1
- package/src/App.menu.tsx +0 -8
- package/src/_core/type/generiqueType.tsx +4 -0
- package/src/badge/Badge.tsx +9 -1
- package/src/badge/badge.css +4 -0
- package/src/button/Button.tsx +1 -3
- package/src/button/button.css +2 -2
- package/src/button/button.interface.tsx +1 -2
- package/src/card/card.css +25 -5
- package/src/card/cardAction/CardAction.tsx +4 -4
- package/src/damier/Damier.tsx +7 -16
- package/src/damier/damier.css +4 -11
- package/src/dataTable/DataTable.tsx +685 -542
- package/src/dataTable/DataTable.view.tsx +48 -24
- package/src/dataTable/dataTable.css +134 -159
- package/src/dataTable/dataTable.interface.ts +25 -19
- package/src/dataTable/dataTableActions/DataTableAction.tsx +14 -25
- package/src/dataTable/dataTableColumn/DataTableColumn.tsx +64 -14
- package/src/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.tsx +36 -0
- package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilter.css +0 -0
- package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.tsx +39 -0
- package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.tsx +80 -0
- package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.tsx +89 -0
- package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.tsx +37 -0
- package/src/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.tsx +42 -0
- package/src/dataTable/dataTableFilters/DataTableFilters.tsx +91 -0
- package/src/dataTable/dataTableFilters/dataTableFilters.css +16 -0
- package/src/dataTable/dataTableLoading/DataTableLoading.tsx +4 -15
- package/src/dataTable/dataTableRow/DataTableRow.tsx +64 -180
- package/src/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.tsx +80 -0
- package/src/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.tsx +123 -0
- package/src/expands/Expands.tsx +2 -16
- package/src/expands/expand/expand.tsx +5 -122
- package/src/expands/expands.css +3 -8
- package/src/form/Form.tsx +93 -258
- package/src/form/Form.view.tsx +1 -9
- package/src/form/form.css +1 -51
- package/src/form/form.enum.ts +1 -2
- package/src/form/form.interface.tsx +2 -28
- package/src/form/input/Input.tsx +61 -7
- package/src/form/input/input.css +23 -1
- package/src/form/inputNumber/InputNumber.tsx +6 -11
- package/src/form/inputPrice/InputPrice.tsx +2 -4
- package/src/grid/col/Col.tsx +7 -5
- package/src/grid/col/colStyled/ColStyled.tsx +7 -21
- package/src/grid/grid.interface.tsx +5 -11
- package/src/grid/row/row.css +2 -2
- package/src/header/Header.tsx +2 -4
- package/src/header/header.css +0 -17
- package/src/header/header.interface.tsx +1 -2
- package/src/icon/Icon.tsx +6 -2
- package/src/icon/icon.interface.tsx +1 -0
- package/src/index.css +12 -58
- package/src/index.ts +2 -12
- package/src/menus/Menus.tsx +0 -1
- package/src/menus/menu/Menu.tsx +1 -2
- package/src/overlayPanel/OverlayPanel.tsx +71 -18
- package/src/overlayPanel/overlay.context.tsx +6 -4
- package/src/overlayPanel/overlayPanel.css +10 -1
- package/src/overlayPanel/overlayPanelStyled/OverlayPanelStyled.tsx +7 -2
- package/src/select/Select.tsx +178 -41
- package/src/select/select.css +94 -13
- package/src/select/selectOption.interface.ts +1 -0
- package/src/sidebar/Sidebar.tsx +5 -107
- package/src/sidebar/sidebar.css +1 -18
- package/src/tabs/Tabs.tsx +20 -1
- package/src/tabs/tabs.css +3 -9
- package/src/toaster/Toaster.tsx +2 -7
- package/src/toaster/Toaster.view.tsx +0 -1
- package/src/toaster/store/useToasterStore.tsx +0 -2
- package/src/toaster/toaster.css +2 -7
- package/dist/addressSearch/AddressSearch.d.ts +0 -20
- package/dist/addressSearch/AddressSearch.view.d.ts +0 -1
- package/dist/geocoding/GeocodingService.d.ts +0 -13
- package/dist/geocoding/geocoding.interface.d.ts +0 -20
- package/src/addressSearch/AddressSearch.tsx +0 -246
- package/src/addressSearch/AddressSearch.view.tsx +0 -52
- package/src/addressSearch/addressSearch.css +0 -133
- package/src/geocoding/GeocodingService.ts +0 -89
- package/src/geocoding/geocoding.interface.ts +0 -25
|
@@ -1,208 +1,92 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
import { DataTableColumnsInterface } from "../dataTable.interface";
|
|
3
|
+
import { DataTableRowOverlay } from "./dataTableRowOverlay/DataTableRowOverlay";
|
|
4
|
+
import { DataTableRowValue } from "./dataTableRowValue/DataTableRowValue";
|
|
4
5
|
|
|
5
6
|
type DataTableRowProps = {
|
|
6
|
-
column:
|
|
7
|
+
column: DataTableColumnsInterface<any>;
|
|
7
8
|
idx: number;
|
|
8
|
-
rowIndex: number;
|
|
9
9
|
row: any;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
onEditColumnByOverlay?: (row: any) => void;
|
|
11
|
+
stickyLeft?: number;
|
|
12
12
|
};
|
|
13
13
|
export const DataTableRow = ({
|
|
14
14
|
column,
|
|
15
15
|
idx,
|
|
16
|
-
rowIndex,
|
|
17
16
|
row,
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
onEditColumnByOverlay,
|
|
18
|
+
stickyLeft,
|
|
20
19
|
}: DataTableRowProps) => {
|
|
21
20
|
const value = (row as any)[column.id]; // On utilise [column.id] pour accéder aux bonnes propriétés
|
|
22
21
|
const style = column.onRowStyle ? column.onRowStyle(row) : {};
|
|
23
22
|
const isDisabled = column.onDisable?.(row) ?? false;
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
? column.stepControls(row)
|
|
31
|
-
: (column.stepControls ??
|
|
32
|
-
(typeof column.withStepControls === "function"
|
|
33
|
-
? column.withStepControls(row)
|
|
34
|
-
: column.withStepControls)))),
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
const handleStep = (direction: "plus" | "minus", e: React.MouseEvent) => {
|
|
38
|
-
e.stopPropagation();
|
|
39
|
-
if (isDisabled) return;
|
|
40
|
-
const currentNum = Number(value) || 0;
|
|
41
|
-
const step = column.step ?? 1;
|
|
42
|
-
let newNum = direction === "plus" ? currentNum + step : currentNum - step;
|
|
43
|
-
if (column.min !== undefined && newNum < column.min) {
|
|
44
|
-
newNum = column.min;
|
|
45
|
-
}
|
|
46
|
-
if (column.max !== undefined && newNum > column.max) {
|
|
47
|
-
newNum = column.max;
|
|
23
|
+
const isSticky = stickyLeft !== undefined;
|
|
24
|
+
const [openClickCell, setOpenClickCell] = useState(false);
|
|
25
|
+
const refRow = useRef<HTMLTableCellElement>(null);
|
|
26
|
+
const onClickRenderCell = (e: React.MouseEvent<HTMLTableCellElement>) => {
|
|
27
|
+
if (isDisabled) {
|
|
28
|
+
return;
|
|
48
29
|
}
|
|
49
|
-
|
|
50
|
-
if (column.
|
|
51
|
-
column.
|
|
30
|
+
console.log("Cell clicked with value:", value, "in row:", row);
|
|
31
|
+
if (column.openClickCell) {
|
|
32
|
+
if (column.handleClickCell) {
|
|
33
|
+
column.handleClickCell(e, row);
|
|
34
|
+
}
|
|
35
|
+
e.stopPropagation();
|
|
36
|
+
setOpenClickCell((prev) => !prev);
|
|
52
37
|
}
|
|
53
38
|
};
|
|
54
|
-
|
|
55
|
-
const Container = container === "card" ? "div" : "td";
|
|
56
|
-
|
|
57
39
|
return (
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
data-column-index={idx}
|
|
61
|
-
data-row-index={rowIndex}
|
|
40
|
+
<td
|
|
41
|
+
ref={refRow}
|
|
62
42
|
style={{
|
|
63
43
|
minWidth: column.minWidth,
|
|
64
|
-
textAlign: column.align || "left",
|
|
44
|
+
textAlign: column.alignText ? column.alignText : column.align || "left",
|
|
65
45
|
maxWidth: column.maxWidth,
|
|
66
46
|
width: column.width,
|
|
47
|
+
...(!isDisabled &&
|
|
48
|
+
(column.openClickCell || column.renderClickCellComponent)
|
|
49
|
+
? { cursor: "pointer" }
|
|
50
|
+
: {}),
|
|
51
|
+
...(isSticky
|
|
52
|
+
? {
|
|
53
|
+
position: "sticky",
|
|
54
|
+
left: stickyLeft,
|
|
55
|
+
zIndex: 2,
|
|
56
|
+
backgroundColor: "#fff",
|
|
57
|
+
}
|
|
58
|
+
: {}),
|
|
67
59
|
...style,
|
|
68
60
|
}}
|
|
61
|
+
onClick={onClickRenderCell}
|
|
69
62
|
key={`row-${column.id}-${idx}`}
|
|
63
|
+
className={isSticky ? "data-table-sticky-cell" : ""}
|
|
70
64
|
>
|
|
71
|
-
{column.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
column.type === "select" ? (
|
|
83
|
-
<div onClick={(e) => e.stopPropagation()}>
|
|
84
|
-
<Select
|
|
85
|
-
style={{
|
|
86
|
-
minWidth: column.minWidth,
|
|
87
|
-
maxWidth: column.maxWidth,
|
|
88
|
-
width: column.width,
|
|
89
|
-
}}
|
|
90
|
-
options={column.options ?? []}
|
|
91
|
-
value={value}
|
|
92
|
-
onChange={(e) => {
|
|
93
|
-
if (column.onEdit) {
|
|
94
|
-
column.onEdit(e, row);
|
|
95
|
-
}
|
|
96
|
-
}}
|
|
97
|
-
/>
|
|
98
|
-
</div>
|
|
99
|
-
) : (
|
|
100
|
-
hasStepButtons ? (
|
|
101
|
-
<div
|
|
102
|
-
className="data-table-input-number-wrapper"
|
|
103
|
-
style={{
|
|
104
|
-
display: "inline-flex",
|
|
105
|
-
alignItems: "center",
|
|
106
|
-
gap: "4px",
|
|
107
|
-
justifyContent:
|
|
108
|
-
column.align === "right"
|
|
109
|
-
? "flex-end"
|
|
110
|
-
: column.align === "center"
|
|
111
|
-
? "center"
|
|
112
|
-
: "flex-start",
|
|
113
|
-
}}
|
|
114
|
-
onClick={(e) => e.stopPropagation()}
|
|
115
|
-
>
|
|
116
|
-
<button
|
|
117
|
-
type="button"
|
|
118
|
-
className="data-table-step-btn data-table-step-btn--minus"
|
|
119
|
-
disabled={
|
|
120
|
-
isDisabled ||
|
|
121
|
-
(column.min !== undefined && Number(value) <= column.min)
|
|
122
|
-
}
|
|
123
|
-
onClick={(e) => handleStep("minus", e)}
|
|
124
|
-
>
|
|
125
|
-
<Icon classIcon="bi-dash-lg" />
|
|
126
|
-
</button>
|
|
127
|
-
<input
|
|
128
|
-
type={column.type}
|
|
129
|
-
value={value}
|
|
130
|
-
step={column.step ?? "0.01"}
|
|
131
|
-
min={column.min}
|
|
132
|
-
max={column.max}
|
|
133
|
-
disabled={isDisabled}
|
|
134
|
-
style={{
|
|
135
|
-
textAlign: column.align || "center",
|
|
136
|
-
minWidth: column.minWidth,
|
|
137
|
-
maxWidth: column.maxWidth,
|
|
138
|
-
width: column.width,
|
|
139
|
-
}}
|
|
140
|
-
onClick={(e) => e.stopPropagation()}
|
|
141
|
-
onKeyDown={(e) => {
|
|
142
|
-
if (e.key === "Enter") {
|
|
143
|
-
if (column.onEnter) {
|
|
144
|
-
column.onEnter(e.currentTarget.value, row);
|
|
145
|
-
}
|
|
146
|
-
if (column.enterToNextColumn) {
|
|
147
|
-
e.preventDefault();
|
|
148
|
-
onEnterNextColumn?.(idx, rowIndex);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}}
|
|
152
|
-
onChange={(e) => {
|
|
153
|
-
if (column.onEdit) {
|
|
154
|
-
column.onEdit(e.target.value, row);
|
|
155
|
-
}
|
|
156
|
-
}}
|
|
157
|
-
/>
|
|
158
|
-
<button
|
|
159
|
-
type="button"
|
|
160
|
-
className="data-table-step-btn data-table-step-btn--plus"
|
|
161
|
-
disabled={
|
|
162
|
-
isDisabled ||
|
|
163
|
-
(column.max !== undefined && Number(value) >= column.max)
|
|
164
|
-
}
|
|
165
|
-
onClick={(e) => handleStep("plus", e)}
|
|
166
|
-
>
|
|
167
|
-
<Icon classIcon="bi-plus-lg" />
|
|
168
|
-
</button>
|
|
169
|
-
</div>
|
|
170
|
-
) : (
|
|
171
|
-
<input
|
|
172
|
-
type={column.type}
|
|
173
|
-
value={value}
|
|
174
|
-
step="0.01"
|
|
175
|
-
style={{
|
|
176
|
-
textAlign: column.align || "left",
|
|
177
|
-
minWidth: column.minWidth,
|
|
178
|
-
maxWidth: column.maxWidth,
|
|
179
|
-
width: column.width,
|
|
180
|
-
}}
|
|
181
|
-
onClick={(e) => e.stopPropagation()}
|
|
182
|
-
onKeyDown={(e) => {
|
|
183
|
-
if (e.key === "Enter") {
|
|
184
|
-
if (column.onEnter) {
|
|
185
|
-
column.onEnter(e.currentTarget.value, row);
|
|
186
|
-
}
|
|
187
|
-
if (column.enterToNextColumn) {
|
|
188
|
-
e.preventDefault();
|
|
189
|
-
onEnterNextColumn?.(idx, rowIndex);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}}
|
|
193
|
-
onChange={(e) => {
|
|
194
|
-
if (column.onEdit) {
|
|
195
|
-
column.onEdit(e.target.value, row);
|
|
196
|
-
}
|
|
197
|
-
}}
|
|
198
|
-
/>
|
|
199
|
-
)
|
|
200
|
-
)
|
|
201
|
-
) : column.format ? (
|
|
202
|
-
column.format(value)
|
|
203
|
-
) : (
|
|
204
|
-
value
|
|
65
|
+
{column.renderComponent ? column.renderComponent(value, row) : null}
|
|
66
|
+
{!column.renderComponent && (
|
|
67
|
+
<DataTableRowValue
|
|
68
|
+
editable={
|
|
69
|
+
!isDisabled &&
|
|
70
|
+
(column.onEditable?.(value, row) ?? column.editable ?? false)
|
|
71
|
+
}
|
|
72
|
+
column={column}
|
|
73
|
+
value={value}
|
|
74
|
+
row={row}
|
|
75
|
+
/>
|
|
205
76
|
)}
|
|
206
|
-
|
|
77
|
+
{openClickCell &&
|
|
78
|
+
!isDisabled &&
|
|
79
|
+
column.displayOverlay &&
|
|
80
|
+
refRow.current && (
|
|
81
|
+
<DataTableRowOverlay
|
|
82
|
+
refRow={refRow}
|
|
83
|
+
column={column}
|
|
84
|
+
row={row}
|
|
85
|
+
value={value}
|
|
86
|
+
onEditColumnByOverlay={onEditColumnByOverlay}
|
|
87
|
+
onClose={() => setOpenClickCell(false)}
|
|
88
|
+
/>
|
|
89
|
+
)}
|
|
90
|
+
</td>
|
|
207
91
|
);
|
|
208
92
|
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
import { Button } from "../../../button/Button";
|
|
3
|
+
import { OverlayPanel } from "../../../overlayPanel/OverlayPanel";
|
|
4
|
+
import { DataTableColumnsInterface } from "../../dataTable.interface";
|
|
5
|
+
import { DataTableRowValue } from "../dataTableRowValue/DataTableRowValue";
|
|
6
|
+
|
|
7
|
+
type DataTableRowOverlayProps = {
|
|
8
|
+
row: any;
|
|
9
|
+
column: DataTableColumnsInterface<any>;
|
|
10
|
+
value: string;
|
|
11
|
+
refRow: React.RefObject<HTMLTableCellElement>;
|
|
12
|
+
onClose?: (close: boolean) => void;
|
|
13
|
+
onEditColumnByOverlay?: (newRow: any) => void;
|
|
14
|
+
};
|
|
15
|
+
export const DataTableRowOverlay = ({
|
|
16
|
+
row,
|
|
17
|
+
refRow,
|
|
18
|
+
value,
|
|
19
|
+
onClose,
|
|
20
|
+
column,
|
|
21
|
+
onEditColumnByOverlay,
|
|
22
|
+
}: DataTableRowOverlayProps) => {
|
|
23
|
+
const [inputValue, setInputValue] = useState(value);
|
|
24
|
+
const formRef = useRef<HTMLFormElement>(null);
|
|
25
|
+
|
|
26
|
+
const onChange = (newValue: any) => {
|
|
27
|
+
setInputValue(newValue);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
if (onEditColumnByOverlay) {
|
|
33
|
+
const newRow = { ...row, [column.id]: inputValue };
|
|
34
|
+
onEditColumnByOverlay(newRow);
|
|
35
|
+
}
|
|
36
|
+
if (onClose) {
|
|
37
|
+
onClose(true);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleButtonClick = (
|
|
42
|
+
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
|
43
|
+
) => {
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
formRef.current?.requestSubmit();
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const handleClose = () => {
|
|
49
|
+
if (onClose) {
|
|
50
|
+
onClose(true);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<OverlayPanel
|
|
56
|
+
show={true}
|
|
57
|
+
position="bottomLeft"
|
|
58
|
+
closeOverlay={handleClose}
|
|
59
|
+
referenceElement={refRow?.current ?? undefined}
|
|
60
|
+
children={
|
|
61
|
+
<div className="d-flex flex-column pt-3">
|
|
62
|
+
<form onSubmit={onSubmit} ref={formRef}>
|
|
63
|
+
<DataTableRowValue
|
|
64
|
+
editable={true}
|
|
65
|
+
column={column}
|
|
66
|
+
value={inputValue}
|
|
67
|
+
row={row}
|
|
68
|
+
onChange={onChange}
|
|
69
|
+
/>
|
|
70
|
+
{onEditColumnByOverlay && (
|
|
71
|
+
<div className="d-flex justify-content-end mt-2">
|
|
72
|
+
<Button title="Valider" onClick={handleButtonClick} />
|
|
73
|
+
</div>
|
|
74
|
+
)}
|
|
75
|
+
</form>
|
|
76
|
+
</div>
|
|
77
|
+
}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { Select } from "../../../select/Select";
|
|
3
|
+
import { DataTableColumnsInterface } from "../../dataTable.interface";
|
|
4
|
+
|
|
5
|
+
type DataTableRowValueProps = {
|
|
6
|
+
column: DataTableColumnsInterface<any>;
|
|
7
|
+
value: any;
|
|
8
|
+
row: any;
|
|
9
|
+
editable?: boolean;
|
|
10
|
+
onChange?: (value: any) => void;
|
|
11
|
+
};
|
|
12
|
+
export const DataTableRowValue = ({
|
|
13
|
+
column,
|
|
14
|
+
row,
|
|
15
|
+
value,
|
|
16
|
+
editable,
|
|
17
|
+
onChange,
|
|
18
|
+
}: DataTableRowValueProps) => {
|
|
19
|
+
const [draftValue, setDraftValue] = useState(value ?? "");
|
|
20
|
+
const editOnEnter = column.onEditTrigger === "enter";
|
|
21
|
+
const skipNextBlurCommit = useRef(false);
|
|
22
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
23
|
+
const wasEditableRef = useRef(false);
|
|
24
|
+
|
|
25
|
+
const selectInputText = () => {
|
|
26
|
+
try {
|
|
27
|
+
inputRef.current?.select();
|
|
28
|
+
} catch {
|
|
29
|
+
// Some input types (e.g. date) may not support text selection.
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const commitValue = (nextValue: any) => {
|
|
34
|
+
if (column.onEdit) {
|
|
35
|
+
column.onEdit(nextValue, row);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
setDraftValue(value ?? "");
|
|
41
|
+
}, [value]);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (editable && !wasEditableRef.current) {
|
|
45
|
+
inputRef.current?.focus();
|
|
46
|
+
selectInputText();
|
|
47
|
+
}
|
|
48
|
+
wasEditableRef.current = !!editable;
|
|
49
|
+
}, [editable]);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<>
|
|
53
|
+
{editable ? (
|
|
54
|
+
column.type === "select" ? (
|
|
55
|
+
<Select
|
|
56
|
+
options={column.options ?? []}
|
|
57
|
+
value={value}
|
|
58
|
+
onChange={(e) => {
|
|
59
|
+
if (onChange) {
|
|
60
|
+
onChange(e);
|
|
61
|
+
}
|
|
62
|
+
if (column.onChange) {
|
|
63
|
+
column.onChange(e, row);
|
|
64
|
+
}
|
|
65
|
+
if (column.onEdit) {
|
|
66
|
+
column.onEdit(e, row);
|
|
67
|
+
}
|
|
68
|
+
}}
|
|
69
|
+
/>
|
|
70
|
+
) : (
|
|
71
|
+
<input
|
|
72
|
+
ref={inputRef}
|
|
73
|
+
type={column.type}
|
|
74
|
+
value={editOnEnter ? draftValue : value}
|
|
75
|
+
step="0.01"
|
|
76
|
+
style={{
|
|
77
|
+
textAlign: column.alignText
|
|
78
|
+
? column.alignText
|
|
79
|
+
: column.align || "left",
|
|
80
|
+
}}
|
|
81
|
+
onFocus={selectInputText}
|
|
82
|
+
onChange={(e) => {
|
|
83
|
+
const nextValue = e.target.value;
|
|
84
|
+
if (onChange) {
|
|
85
|
+
onChange(nextValue);
|
|
86
|
+
}
|
|
87
|
+
if (column.onChange) {
|
|
88
|
+
column.onChange(nextValue, row);
|
|
89
|
+
}
|
|
90
|
+
if (editOnEnter) {
|
|
91
|
+
setDraftValue(nextValue);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
commitValue(nextValue);
|
|
95
|
+
}}
|
|
96
|
+
onKeyDown={(e) => {
|
|
97
|
+
if (editOnEnter && e.key === "Enter") {
|
|
98
|
+
skipNextBlurCommit.current = true;
|
|
99
|
+
commitValue(draftValue);
|
|
100
|
+
}
|
|
101
|
+
}}
|
|
102
|
+
onBlur={() => {
|
|
103
|
+
if (!editOnEnter) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (skipNextBlurCommit.current) {
|
|
107
|
+
skipNextBlurCommit.current = false;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (draftValue !== value) {
|
|
111
|
+
commitValue(draftValue);
|
|
112
|
+
}
|
|
113
|
+
}}
|
|
114
|
+
/>
|
|
115
|
+
)
|
|
116
|
+
) : column.format ? (
|
|
117
|
+
column.format(value)
|
|
118
|
+
) : (
|
|
119
|
+
value
|
|
120
|
+
)}
|
|
121
|
+
</>
|
|
122
|
+
);
|
|
123
|
+
};
|
package/src/expands/Expands.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from "react";
|
|
2
1
|
import { Expand } from "./expand/expand";
|
|
3
2
|
import { ExpandInterface } from "./expand/expand.interface";
|
|
4
3
|
import "./expands.css";
|
|
@@ -12,19 +11,6 @@ type ExpandProps = {
|
|
|
12
11
|
};
|
|
13
12
|
|
|
14
13
|
export const Expands = (props: ExpandProps) => {
|
|
15
|
-
const [currentExpand, setCurrentExpand] = useState<ExpandInterface>();
|
|
16
|
-
const onChangeExpand = useCallback(
|
|
17
|
-
(item: ExpandInterface) => {
|
|
18
|
-
if (props.onChange) {
|
|
19
|
-
props.onChange(item);
|
|
20
|
-
}
|
|
21
|
-
setCurrentExpand(item);
|
|
22
|
-
},
|
|
23
|
-
[setCurrentExpand, props.onChange]
|
|
24
|
-
);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
setCurrentExpand(props.currentItem);
|
|
27
|
-
}, [props.currentItem, setCurrentExpand, document.activeElement]);
|
|
28
14
|
return (
|
|
29
15
|
<div className={`expands ${props.className || ""}`}>
|
|
30
16
|
{props.items.map((item: ExpandInterface) => (
|
|
@@ -32,8 +18,8 @@ export const Expands = (props: ExpandProps) => {
|
|
|
32
18
|
key={item.id}
|
|
33
19
|
item={item}
|
|
34
20
|
showArrow={props.showArrow}
|
|
35
|
-
onChange={
|
|
36
|
-
currentExpand={
|
|
21
|
+
onChange={props.onChange}
|
|
22
|
+
currentExpand={props.currentItem}
|
|
37
23
|
/>
|
|
38
24
|
))}
|
|
39
25
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback
|
|
1
|
+
import { useCallback } from "react";
|
|
2
2
|
import { Icon } from "../../icon/Icon";
|
|
3
3
|
import { ExpandInterface } from "./expand.interface";
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ export type ExpandProps = {
|
|
|
7
7
|
item: ExpandInterface;
|
|
8
8
|
className?: string;
|
|
9
9
|
showArrow?: boolean;
|
|
10
|
-
onChange
|
|
10
|
+
onChange?: (item: ExpandInterface) => void;
|
|
11
11
|
};
|
|
12
12
|
export const Expand = ({
|
|
13
13
|
currentExpand,
|
|
@@ -16,128 +16,13 @@ export const Expand = ({
|
|
|
16
16
|
showArrow = true,
|
|
17
17
|
onChange,
|
|
18
18
|
}: ExpandProps): JSX.Element => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (item && currentExpand) {
|
|
24
|
-
if (currentExpand.id === item.id) {
|
|
25
|
-
if (!active) {
|
|
26
|
-
setActive(true);
|
|
27
|
-
}
|
|
28
|
-
} else {
|
|
29
|
-
setActive(false);
|
|
30
|
-
}
|
|
31
|
-
} else {
|
|
32
|
-
setActive(false);
|
|
33
|
-
}
|
|
34
|
-
}, [currentExpand, setActive, item, active]);
|
|
35
|
-
|
|
36
|
-
const scrollToHeader = useCallback(() => {
|
|
37
|
-
const expandElement = expandRef.current;
|
|
38
|
-
if (!expandElement) return;
|
|
39
|
-
|
|
40
|
-
let scrollParent: HTMLElement | null = expandElement.parentElement;
|
|
41
|
-
while (scrollParent) {
|
|
42
|
-
const style = window.getComputedStyle(scrollParent);
|
|
43
|
-
const isScrollable =
|
|
44
|
-
/(auto|scroll)/.test(style.overflow + style.overflowY) &&
|
|
45
|
-
scrollParent.scrollHeight > scrollParent.clientHeight;
|
|
46
|
-
|
|
47
|
-
if (isScrollable) {
|
|
48
|
-
const parentRect = scrollParent.getBoundingClientRect();
|
|
49
|
-
const targetRect = expandElement.getBoundingClientRect();
|
|
50
|
-
const offsetTop =
|
|
51
|
-
targetRect.top - parentRect.top + scrollParent.scrollTop;
|
|
52
|
-
|
|
53
|
-
scrollParent.scrollTo({
|
|
54
|
-
top: offsetTop,
|
|
55
|
-
behavior: "smooth",
|
|
56
|
-
});
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
scrollParent = scrollParent.parentElement;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const header =
|
|
63
|
-
expandElement.querySelector<HTMLElement>(".expand-header") ||
|
|
64
|
-
expandElement;
|
|
65
|
-
header.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
66
|
-
}, []);
|
|
67
|
-
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
if (active) {
|
|
70
|
-
const timer1 = setTimeout(() => {
|
|
71
|
-
scrollToHeader();
|
|
72
|
-
}, 100);
|
|
73
|
-
const timer2 = setTimeout(() => {
|
|
74
|
-
scrollToHeader();
|
|
75
|
-
}, 350);
|
|
76
|
-
return () => {
|
|
77
|
-
clearTimeout(timer1);
|
|
78
|
-
clearTimeout(timer2);
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
}, [active, scrollToHeader]);
|
|
82
|
-
|
|
83
|
-
const handleFocusCapture = useCallback(
|
|
84
|
-
(e: React.FocusEvent<HTMLDivElement>) => {
|
|
85
|
-
const target = e.target as HTMLElement;
|
|
86
|
-
if (
|
|
87
|
-
active &&
|
|
88
|
-
(target.tagName === "INPUT" ||
|
|
89
|
-
target.tagName === "TEXTAREA" ||
|
|
90
|
-
target.tagName === "SELECT")
|
|
91
|
-
) {
|
|
92
|
-
const expandElement = expandRef.current;
|
|
93
|
-
if (!expandElement) return;
|
|
94
|
-
|
|
95
|
-
const performScroll = () => {
|
|
96
|
-
let scrollParent: HTMLElement | null = expandElement.parentElement;
|
|
97
|
-
while (scrollParent) {
|
|
98
|
-
const style = window.getComputedStyle(scrollParent);
|
|
99
|
-
const isScrollable =
|
|
100
|
-
/(auto|scroll)/.test(style.overflow + style.overflowY) &&
|
|
101
|
-
scrollParent.scrollHeight > scrollParent.clientHeight;
|
|
102
|
-
|
|
103
|
-
if (isScrollable) {
|
|
104
|
-
const parentRect = scrollParent.getBoundingClientRect();
|
|
105
|
-
const headerRect = expandElement.getBoundingClientRect();
|
|
106
|
-
const headerOffsetTop =
|
|
107
|
-
headerRect.top - parentRect.top + scrollParent.scrollTop;
|
|
108
|
-
|
|
109
|
-
// Si on a déjà scrollé vers ou au-delà du header, on ne remonte JAMAIS au header
|
|
110
|
-
if (scrollParent.scrollTop >= headerOffsetTop - 10) {
|
|
111
|
-
const targetRect = target.getBoundingClientRect();
|
|
112
|
-
if (targetRect.bottom > parentRect.bottom) {
|
|
113
|
-
target.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
114
|
-
}
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Si on n'a pas encore scrollé jusqu'au header, on y va
|
|
119
|
-
scrollParent.scrollTo({
|
|
120
|
-
top: headerOffsetTop,
|
|
121
|
-
behavior: "smooth",
|
|
122
|
-
});
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
scrollParent = scrollParent.parentElement;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
performScroll();
|
|
130
|
-
// Répéter après l'ouverture du clavier virtuel (spécifique tablettes / mobiles Android)
|
|
131
|
-
setTimeout(performScroll, 300);
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
[active],
|
|
135
|
-
);
|
|
136
|
-
|
|
19
|
+
const active = currentExpand?.id === item.id;
|
|
20
|
+
console.log("render expand", item.title, "active", active);
|
|
137
21
|
const handleChange = useCallback(
|
|
138
22
|
(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
|
139
23
|
e.stopPropagation();
|
|
140
24
|
if (onChange) {
|
|
25
|
+
console.log("expand", item);
|
|
141
26
|
onChange(item);
|
|
142
27
|
}
|
|
143
28
|
},
|
|
@@ -145,9 +30,7 @@ export const Expand = ({
|
|
|
145
30
|
);
|
|
146
31
|
return (
|
|
147
32
|
<div
|
|
148
|
-
ref={expandRef}
|
|
149
33
|
onClick={handleChange}
|
|
150
|
-
onFocusCapture={handleFocusCapture}
|
|
151
34
|
className={`expand ${active ? "expand--active" : ""} ${className ?? ""}`}
|
|
152
35
|
>
|
|
153
36
|
<div className={`expand-header`}>
|