kelt-ui-kit-react 1.8.3 → 1.8.4

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.
Files changed (243) hide show
  1. package/dist/badge/Badge.d.ts +1 -3
  2. package/dist/button/button.interface.d.ts +1 -1
  3. package/dist/dataTable/DataTable.d.ts +3 -17
  4. package/dist/dataTable/dataTable.interface.d.ts +3 -21
  5. package/dist/dataTable/dataTableActions/DataTableAction.d.ts +2 -2
  6. package/dist/dataTable/dataTableColumn/DataTableColumn.d.ts +7 -13
  7. package/dist/dataTable/dataTableLoading/DataTableLoading.d.ts +3 -1
  8. package/dist/dataTable/dataTableRow/DataTableRow.d.ts +3 -5
  9. package/dist/expands/expand/expand.d.ts +1 -1
  10. package/dist/form/form.enum.d.ts +0 -1
  11. package/dist/form/input/Input.d.ts +0 -3
  12. package/dist/form/inputNumber/InputNumber.d.ts +2 -0
  13. package/dist/icon/Icon.d.ts +1 -1
  14. package/dist/icon/icon.interface.d.ts +0 -1
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.js +2836 -3652
  17. package/dist/overlayPanel/OverlayPanel.d.ts +1 -3
  18. package/dist/select/Select.d.ts +1 -4
  19. package/dist/select/selectOption.interface.d.ts +0 -1
  20. package/dist/style.css +1 -1
  21. package/dist/tabs/Tabs.d.ts +1 -2
  22. package/package.json +1 -1
  23. package/src/badge/Badge.tsx +1 -9
  24. package/src/badge/badge.css +0 -4
  25. package/src/button/Button.tsx +1 -1
  26. package/src/button/button.interface.tsx +1 -1
  27. package/src/card/card.css +3 -23
  28. package/src/card/cardAction/CardAction.tsx +4 -4
  29. package/src/damier/damier.css +3 -2
  30. package/src/dataTable/DataTable.tsx +45 -670
  31. package/src/dataTable/DataTable.view.tsx +14 -47
  32. package/src/dataTable/dataTable.css +5 -153
  33. package/src/dataTable/dataTable.interface.ts +3 -21
  34. package/src/dataTable/dataTableActions/DataTableAction.tsx +2 -2
  35. package/src/dataTable/dataTableColumn/DataTableColumn.tsx +14 -64
  36. package/src/dataTable/dataTableLoading/DataTableLoading.tsx +15 -4
  37. package/src/dataTable/dataTableRow/DataTableRow.tsx +33 -60
  38. package/src/expands/Expands.tsx +16 -2
  39. package/src/expands/expand/expand.tsx +18 -6
  40. package/src/form/Form.tsx +12 -13
  41. package/src/form/form.css +2 -13
  42. package/src/form/form.enum.ts +0 -1
  43. package/src/form/input/Input.tsx +7 -61
  44. package/src/form/input/input.css +1 -23
  45. package/src/form/inputNumber/InputNumber.tsx +11 -6
  46. package/src/form/inputPrice/InputPrice.tsx +4 -2
  47. package/src/icon/Icon.tsx +2 -6
  48. package/src/icon/icon.interface.tsx +0 -1
  49. package/src/index.ts +0 -2
  50. package/src/overlayPanel/OverlayPanel.tsx +10 -23
  51. package/src/overlayPanel/overlay.context.tsx +4 -6
  52. package/src/overlayPanel/overlayPanel.css +1 -10
  53. package/src/select/Select.tsx +38 -134
  54. package/src/select/select.css +14 -65
  55. package/src/select/selectOption.interface.ts +0 -1
  56. package/src/sidebar/Sidebar.tsx +80 -9
  57. package/src/sidebar/sidebar.css +18 -1
  58. package/src/tabs/Tabs.tsx +1 -19
  59. package/dist/_core/type/generiqueType.d.ts +0 -4
  60. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.d.ts +0 -10
  61. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.d.ts +0 -9
  62. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.d.ts +0 -9
  63. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.d.ts +0 -13
  64. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.d.ts +0 -9
  65. package/dist/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.d.ts +0 -11
  66. package/dist/dataTable/dataTableFilters/DataTableFilters.d.ts +0 -7
  67. package/dist/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.d.ts +0 -12
  68. package/dist/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.d.ts +0 -11
  69. package/kelt-ui-kit-react-1.6.9.tgz +0 -0
  70. package/package/README.md +0 -46
  71. package/package/index.html +0 -20
  72. package/package/package.json +0 -56
  73. package/package/public/favicon.ico +0 -0
  74. package/package/public/index.html +0 -18
  75. package/package/public/logo192.png +0 -0
  76. package/package/public/logo512.png +0 -0
  77. package/package/public/manifest.json +0 -25
  78. package/package/public/robots.txt +0 -3
  79. package/package/src/App.css +0 -11
  80. package/package/src/App.menu.tsx +0 -249
  81. package/package/src/App.routes.tsx +0 -16
  82. package/package/src/App.tsx +0 -30
  83. package/package/src/_core/hooks/HistoryProvider.tsx +0 -25
  84. package/package/src/_core/hooks/ImageChecker.tsx +0 -26
  85. package/package/src/_core/hooks/imageExist.tsx +0 -9
  86. package/package/src/_core/hooks/isEAN13.tsx +0 -16
  87. package/package/src/_core/hooks/objectToQueryParams.tsx +0 -32
  88. package/package/src/_core/hooks/useCurrency.tsx +0 -18
  89. package/package/src/_core/hooks/useDateutils.ts +0 -64
  90. package/package/src/_core/hooks/useIsMobile.ts +0 -18
  91. package/package/src/_core/hooks/useToken.tsx +0 -19
  92. package/package/src/_core/hooks/useValidate.tsx +0 -18
  93. package/package/src/_core/hooks/widgetSupport.tsx +0 -39
  94. package/package/src/action/Action.view.tsx +0 -21
  95. package/package/src/action/ButtonAction.tsx +0 -32
  96. package/package/src/action/action.css +0 -20
  97. package/package/src/badge/Badge.tsx +0 -34
  98. package/package/src/badge/Badge.view.tsx +0 -15
  99. package/package/src/badge/badge.css +0 -55
  100. package/package/src/button/Button.tsx +0 -46
  101. package/package/src/button/Button.view.tsx +0 -85
  102. package/package/src/button/button.css +0 -53
  103. package/package/src/button/button.interface.tsx +0 -21
  104. package/package/src/button/buttonActions/ButtonActions.tsx +0 -104
  105. package/package/src/button/buttonFile/ButtonFile.tsx +0 -59
  106. package/package/src/button/buttonFile/ButtonFile.view.tsx +0 -70
  107. package/package/src/button/buttonFilters/ButtonFilters.tsx +0 -102
  108. package/package/src/button/buttonFilters/buttonFilters.css +0 -22
  109. package/package/src/card/Card.tsx +0 -125
  110. package/package/src/card/Card.view.tsx +0 -73
  111. package/package/src/card/card.css +0 -145
  112. package/package/src/card/card.interface.tsx +0 -9
  113. package/package/src/card/cardAction/CardAction.tsx +0 -135
  114. package/package/src/card/cardAction/cardAction.css +0 -10
  115. package/package/src/card/cardAction.interface.tsx +0 -10
  116. package/package/src/card/hook/useCardInteractions.tsx +0 -30
  117. package/package/src/carousel/Carousel.css +0 -44
  118. package/package/src/carousel/Carousel.tsx +0 -115
  119. package/package/src/carousel/Carousel.view.tsx +0 -13
  120. package/package/src/damier/Damier.tsx +0 -64
  121. package/package/src/damier/Damier.view.tsx +0 -31
  122. package/package/src/damier/damier.css +0 -50
  123. package/package/src/damier/damierCell/DamierCell.tsx +0 -18
  124. package/package/src/damier/damierCell/damierCell.interface.tsx +0 -5
  125. package/package/src/dataTable/DataTable.tsx +0 -259
  126. package/package/src/dataTable/DataTable.view.tsx +0 -62
  127. package/package/src/dataTable/dataTable.css +0 -30
  128. package/package/src/dataTable/dataTable.interface.ts +0 -30
  129. package/package/src/dataTable/dataTableActions/DataTableAction.tsx +0 -44
  130. package/package/src/dataTable/dataTableColumn/DataTableColumn.tsx +0 -27
  131. package/package/src/dataTable/dataTableLoading/DataTableLoading.tsx +0 -21
  132. package/package/src/dataTable/dataTableRow/DataTableRow.tsx +0 -54
  133. package/package/src/datePicker/DatePicker.tsx +0 -110
  134. package/package/src/datePicker/DatePicker.view.tsx +0 -9
  135. package/package/src/datePicker/datePicker.css +0 -77
  136. package/package/src/expands/Expands.tsx +0 -42
  137. package/package/src/expands/Expands.view.tsx +0 -90
  138. package/package/src/expands/expand/expand.interface.tsx +0 -8
  139. package/package/src/expands/expand/expand.tsx +0 -75
  140. package/package/src/expands/expands.css +0 -97
  141. package/package/src/filAriane/FilAriane.tsx +0 -57
  142. package/package/src/filAriane/FilAriane.view.tsx +0 -28
  143. package/package/src/filAriane/filAriane.css +0 -23
  144. package/package/src/filAriane/filAriane.interface.tsx +0 -6
  145. package/package/src/form/Form.tsx +0 -279
  146. package/package/src/form/Form.view.tsx +0 -59
  147. package/package/src/form/form.css +0 -62
  148. package/package/src/form/form.enum.ts +0 -13
  149. package/package/src/form/form.interface.tsx +0 -37
  150. package/package/src/form/input/Input.tsx +0 -106
  151. package/package/src/form/input/input.css +0 -26
  152. package/package/src/form/inputNumber/InputNumber.tsx +0 -132
  153. package/package/src/form/inputNumber/InputNumber.view.tsx +0 -15
  154. package/package/src/form/inputPrice/InputPrice.tsx +0 -42
  155. package/package/src/form/inputPrice/InputPrice.view.tsx +0 -15
  156. package/package/src/form/textArea/TextArea.tsx +0 -59
  157. package/package/src/form/textArea/TextArea.view.tsx +0 -34
  158. package/package/src/form/textArea/textArea.css +0 -9
  159. package/package/src/grid/Grid.tsx +0 -21
  160. package/package/src/grid/Grid.view.tsx +0 -24
  161. package/package/src/grid/col/Col.tsx +0 -15
  162. package/package/src/grid/col/colStyled/ColStyled.tsx +0 -41
  163. package/package/src/grid/container/Container.tsx +0 -8
  164. package/package/src/grid/container/container.css +0 -5
  165. package/package/src/grid/grid.interface.tsx +0 -7
  166. package/package/src/grid/row/Row.tsx +0 -12
  167. package/package/src/grid/row/row.css +0 -18
  168. package/package/src/header/Header.tsx +0 -62
  169. package/package/src/header/Header.view.tsx +0 -5
  170. package/package/src/header/header.css +0 -26
  171. package/package/src/header/header.interface.tsx +0 -10
  172. package/package/src/home/Home.tsx +0 -3
  173. package/package/src/icon/Icon.tsx +0 -6
  174. package/package/src/icon/Icons.view.tsx +0 -29
  175. package/package/src/icon/icon.css +0 -20
  176. package/package/src/icon/icon.interface.tsx +0 -6
  177. package/package/src/icon/iconSize.enum.ts +0 -7
  178. package/package/src/index.css +0 -502
  179. package/package/src/index.ts +0 -58
  180. package/package/src/loader/Loader.tsx +0 -37
  181. package/package/src/loader/Loader.view.tsx +0 -20
  182. package/package/src/loader/loader.css +0 -30
  183. package/package/src/logo.svg +0 -1
  184. package/package/src/main.tsx +0 -10
  185. package/package/src/menus/Menus.tsx +0 -42
  186. package/package/src/menus/Menus.view.tsx +0 -39
  187. package/package/src/menus/menu/Menu.tsx +0 -17
  188. package/package/src/menus/menu/menu.interface.tsx +0 -9
  189. package/package/src/menus/menus.css +0 -47
  190. package/package/src/message/Message.tsx +0 -30
  191. package/package/src/message/Message.view.tsx +0 -22
  192. package/package/src/message/message.css +0 -29
  193. package/package/src/modal/Modal.tsx +0 -59
  194. package/package/src/modal/Modal.view.tsx +0 -26
  195. package/package/src/modal/modal.css +0 -71
  196. package/package/src/notFound/NotFound.tsx +0 -3
  197. package/package/src/overlayPanel/OverlayPanel.tsx +0 -195
  198. package/package/src/overlayPanel/OverlayPanel.view.tsx +0 -25
  199. package/package/src/overlayPanel/overlay.context.tsx +0 -28
  200. package/package/src/overlayPanel/overlayPanel.css +0 -35
  201. package/package/src/overlayPanel/overlayPanelStyled/OverlayPanelStyled.tsx +0 -18
  202. package/package/src/pdfViewer/PdfViewer.tsx +0 -73
  203. package/package/src/pdfViewer/PdfViewer.view.tsx +0 -5
  204. package/package/src/quantity/Quantity.tsx +0 -103
  205. package/package/src/quantity/Quantity.view.tsx +0 -0
  206. package/package/src/quantity/quantity.css +0 -26
  207. package/package/src/search/Search.tsx +0 -161
  208. package/package/src/search/Search.view.tsx +0 -14
  209. package/package/src/search/search.css +0 -59
  210. package/package/src/select/Select.tsx +0 -103
  211. package/package/src/select/Select.view.tsx +0 -71
  212. package/package/src/select/select.css +0 -69
  213. package/package/src/select/selectOption.interface.ts +0 -4
  214. package/package/src/sidebar/Sidebar.tsx +0 -208
  215. package/package/src/sidebar/Sidebar.view.tsx +0 -17
  216. package/package/src/sidebar/sidebar.css +0 -104
  217. package/package/src/sidebarData/SidebarData.tsx +0 -19
  218. package/package/src/sidebarData/SidebarData.view.tsx +0 -19
  219. package/package/src/sidebarData/sidebarData.css +0 -27
  220. package/package/src/tabs/Tabs.tsx +0 -90
  221. package/package/src/tabs/Tabs.view.tsx +0 -20
  222. package/package/src/tabs/tabs.css +0 -24
  223. package/package/src/toaster/Toaster.tsx +0 -55
  224. package/package/src/toaster/Toaster.view.tsx +0 -24
  225. package/package/src/toaster/store/useToasterStore.tsx +0 -41
  226. package/package/src/toaster/toaster.css +0 -87
  227. package/package/tsconfig.json +0 -28
  228. package/package/vite.config.ts +0 -20
  229. package/package/vite.config.ts.timestamp-1733262892554-a13dfef6e8a29.mjs +0 -24
  230. package/package/vite.config.ts.timestamp-1757847121745-e5a5bf54b81b.mjs +0 -28
  231. package/package/vite.config.ts.timestamp-1759742478362-4ac5c5a7db34b.mjs +0 -28
  232. package/src/_core/type/generiqueType.tsx +0 -4
  233. package/src/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.tsx +0 -36
  234. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilter.css +0 -0
  235. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.tsx +0 -39
  236. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.tsx +0 -80
  237. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.tsx +0 -89
  238. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.tsx +0 -37
  239. package/src/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.tsx +0 -42
  240. package/src/dataTable/dataTableFilters/DataTableFilters.tsx +0 -91
  241. package/src/dataTable/dataTableFilters/dataTableFilters.css +0 -16
  242. package/src/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.tsx +0 -80
  243. package/src/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.tsx +0 -123
@@ -1,62 +1,16 @@
1
- import {
2
- useCallback,
3
- useDeferredValue,
4
- useEffect,
5
- useLayoutEffect,
6
- useMemo,
7
- useRef,
8
- useState,
9
- } from "react";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
10
2
  import { TypeInputEnum } from "../form/form.enum";
11
3
  import { Input } from "../form/input/Input";
12
4
  import { Loader } from "../loader/Loader";
13
- import { Select } from "../select/Select";
14
5
  import "./dataTable.css";
15
6
  import {
16
- DataTableActionsInterface,
17
- DataTableColumnsInterface,
7
+ dataTableActionsInterface,
8
+ dataTableColumnsInterface,
18
9
  } from "./dataTable.interface";
19
10
  import { DataTableAction } from "./dataTableActions/DataTableAction";
20
11
  import { DataTableColumn } from "./dataTableColumn/DataTableColumn";
21
- import { DataTableColumnFilter } from "./dataTableColumn/dataTableColumnFilter/DataTableColumnFilter";
22
- import { DataTableColumnFilterDateRange } from "./dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange";
23
- import { DataTableColumnSort } from "./dataTableColumn/dataTableColumnSort/DataTableColumnSort";
24
- import { DataTableFilters } from "./dataTableFilters/DataTableFilters";
25
12
  import { DataTableLoading } from "./dataTableLoading/DataTableLoading";
26
13
  import { DataTableRow } from "./dataTableRow/DataTableRow";
27
- export type DataTableDateRangeFilterValue = {
28
- startDate: string;
29
- endDate: string;
30
- };
31
-
32
- export type FilterValue =
33
- | string
34
- | number
35
- | boolean
36
- | string[]
37
- | DataTableDateRangeFilterValue
38
- | null;
39
- export type DataTableFilterState = Record<string, FilterValue>;
40
- export type DataTableSortDirection = "asc" | "desc";
41
- export type DataTableSortState = {
42
- key: string;
43
- direction: DataTableSortDirection;
44
- };
45
- const DEFAULT_FILTER_COLUMN_WIDTH = 100;
46
- const SELECTION_COLUMN_WIDTH = 40;
47
- const DEFAULT_FILTER_ROW_STICKY_HEIGHT = 44;
48
-
49
- const isDateRangeFilterValue = (
50
- value: FilterValue | undefined,
51
- ): value is DataTableDateRangeFilterValue => {
52
- return (
53
- typeof value === "object" &&
54
- value !== null &&
55
- "startDate" in value &&
56
- "endDate" in value
57
- );
58
- };
59
-
60
14
  export type DataTableProps<T> = {
61
15
  id: string;
62
16
  name?: string;
@@ -65,14 +19,11 @@ export type DataTableProps<T> = {
65
19
  element?: JSX.Element;
66
20
  data: T[];
67
21
  emptyMessage?: string;
68
- actions?: DataTableActionsInterface<T>[];
69
- columns: DataTableColumnsInterface<T>[];
70
- onFiltersChange?: (next: DataTableFilterState) => void;
71
- onSortChange?: (next: DataTableSortState | null) => void;
22
+ actions?: dataTableActionsInterface<T>[];
23
+ columns: dataTableColumnsInterface<T>[];
72
24
  loading?: boolean;
73
25
  onRowClick?: (row: any) => void;
74
26
  onColumnClick?: (column: any) => void;
75
- onEditColumnByOverlay?: (row: T) => void;
76
27
  onLoadMore?: () => void;
77
28
  hasMore?: boolean; // pour savoir s'il reste des données à charger
78
29
  onSelectionChange?: (selectedRows: T[]) => void;
@@ -94,166 +45,25 @@ export function DataTable<T>(props: DataTableProps<T>) {
94
45
  onRowClick,
95
46
  onColumnClick,
96
47
  onLoadMore,
97
- onEditColumnByOverlay,
98
48
  emptyMessage,
99
49
  hasMore,
100
50
  onSelectionChange,
101
- onFiltersChange,
102
- onSortChange,
103
51
  hideToggleAll = false,
104
52
  limitSelect = undefined,
105
53
  getRowId,
106
54
  } = props;
107
- const [currentFilters, setCurrentFilters] = useState<DataTableFilterState>(
108
- {},
109
- );
110
- const [visibleFilterColumns, setVisibleFilterColumns] = useState<Set<string>>(
111
- new Set(),
112
- );
113
- const [focusFilterKey, setFocusFilterKey] = useState<string | null>(null);
114
- const [currentSort, setCurrentSort] = useState<DataTableSortState | null>(
115
- null,
116
- );
117
-
118
- const getFilterKey = useCallback(
119
- (column: DataTableColumnsInterface<T>) => column.name ?? column.id,
120
- [],
121
- );
122
-
123
- const toggleColumnFilterVisibility = useCallback(
124
- (column: DataTableColumnsInterface<T>) => {
125
- if (!column.filterable) return;
126
- const key = getFilterKey(column);
127
- setVisibleFilterColumns((prev) => {
128
- const next = new Set(prev);
129
- if (next.has(key)) {
130
- next.delete(key);
131
- setFocusFilterKey(null);
132
- } else {
133
- next.add(key);
134
- setFocusFilterKey(key);
135
- }
136
- return next;
137
- });
138
- },
139
- [getFilterKey],
140
- );
141
-
142
- const toggleColumnSort = useCallback(
143
- (column: DataTableColumnsInterface<T>) => {
144
- if (!column.sortable) return;
145
- const key = getFilterKey(column);
146
-
147
- setCurrentSort((prev) => {
148
- if (!prev || prev.key !== key) {
149
- return { key, direction: "asc" };
150
- }
151
-
152
- if (prev.direction === "asc") {
153
- return { key, direction: "desc" };
154
- }
155
-
156
- return null;
157
- });
158
- },
159
- [getFilterKey],
160
- );
161
-
162
- const updateFilterValue = useCallback((key: string, value: string) => {
163
- setCurrentFilters((prev) => {
164
- if (!value) {
165
- if (!(key in prev)) {
166
- return prev;
167
- }
168
- const { [key]: _removed, ...rest } = prev;
169
- return rest;
170
- }
171
-
172
- if (prev[key] === value) {
173
- return prev;
174
- }
175
-
176
- return { ...prev, [key]: value };
177
- });
178
- }, []);
179
-
180
- const updateDateRangeFilterValue = useCallback(
181
- (key: string, startDate: string, endDate: string) => {
182
- setCurrentFilters((prev) => {
183
- if (!startDate && !endDate) {
184
- if (!(key in prev)) {
185
- return prev;
186
- }
187
- const { [key]: _removed, ...rest } = prev;
188
- return rest;
189
- }
190
-
191
- const previousValue = prev[key];
192
- if (
193
- isDateRangeFilterValue(previousValue) &&
194
- previousValue.startDate === startDate &&
195
- previousValue.endDate === endDate
196
- ) {
197
- return prev;
198
- }
199
55
 
200
- return {
201
- ...prev,
202
- [key]: {
203
- startDate,
204
- endDate,
205
- },
206
- };
207
- });
208
- },
209
- [],
210
- );
211
-
212
- const onFiltersChangeRef = useRef(onFiltersChange);
213
- const deferredFilters = useDeferredValue(currentFilters);
214
- useEffect(() => {
215
- onFiltersChangeRef.current = onFiltersChange;
216
- }, [onFiltersChange]);
217
-
218
- useEffect(() => {
219
- if (onFiltersChangeRef.current) {
220
- onFiltersChangeRef.current(deferredFilters);
221
- }
222
- }, [deferredFilters]);
223
- const onSortChangeRef = useRef(onSortChange);
224
- useEffect(() => {
225
- onSortChangeRef.current = onSortChange;
226
- }, [onSortChange]);
227
-
228
- useEffect(() => {
229
- if (onSortChangeRef.current) {
230
- onSortChangeRef.current(currentSort);
231
- }
232
- }, [currentSort]);
233
-
234
- const getColumnValue = useCallback(
235
- (row: T, column: DataTableColumnsInterface<T>) => {
236
- return (row as any)[column.id];
237
- },
238
- [],
239
- );
240
56
  const loaderRef = useRef<HTMLDivElement | null>(null);
241
57
  const [selectedRowIds, setSelectedRowIds] = useState<Set<string | number>>(
242
- new Set(),
58
+ new Set()
243
59
  );
244
- const filterRowRef = useRef<HTMLTableRowElement | null>(null);
245
- const headerRowRef = useRef<HTMLTableRowElement | null>(null);
246
- const [filterRowHeight, setFilterRowHeight] = useState(
247
- DEFAULT_FILTER_ROW_STICKY_HEIGHT,
248
- );
249
- const [headerRowHeight, setHeaderRowHeight] = useState(0);
250
60
  const toggleSelectAll = useCallback(() => {
251
61
  if (selectedRowIds.size === data.length) {
252
62
  setSelectedRowIds(new Set());
253
63
  onSelectionChange?.([]);
254
64
  } else {
255
65
  let allIds = data.map((d) =>
256
- getRowId ? getRowId(d) : ((d as any).id ?? d),
66
+ getRowId ? getRowId(d) : (d as any).id ?? d
257
67
  );
258
68
 
259
69
  if (limitSelect && allIds.length > limitSelect) {
@@ -264,8 +74,8 @@ export function DataTable<T>(props: DataTableProps<T>) {
264
74
  setSelectedRowIds(newSelection);
265
75
  onSelectionChange?.(
266
76
  data.filter((d) =>
267
- newSelection.has(getRowId ? getRowId(d) : ((d as any).id ?? d)),
268
- ),
77
+ newSelection.has(getRowId ? getRowId(d) : (d as any).id ?? d)
78
+ )
269
79
  );
270
80
  }
271
81
  }, [data, onSelectionChange, limitSelect, getRowId, selectedRowIds.size]);
@@ -277,12 +87,12 @@ export function DataTable<T>(props: DataTableProps<T>) {
277
87
  onRowClick?.(row);
278
88
  }
279
89
  },
280
- [onRowClick],
90
+ [onRowClick]
281
91
  );
282
92
  const toggleRow = useCallback(
283
93
  (e: React.ChangeEvent<HTMLInputElement>, row: T) => {
284
94
  e.stopPropagation();
285
- const rowId = getRowId ? getRowId(row) : ((row as any).id ?? row);
95
+ const rowId = getRowId ? getRowId(row) : (row as any).id ?? row;
286
96
  const newSelection = new Set(selectedRowIds);
287
97
 
288
98
  if (newSelection.has(rowId)) {
@@ -297,11 +107,11 @@ export function DataTable<T>(props: DataTableProps<T>) {
297
107
 
298
108
  setSelectedRowIds(newSelection);
299
109
  const selectedItems = data.filter((d) =>
300
- newSelection.has(getRowId ? getRowId(d) : ((d as any).id ?? d)),
110
+ newSelection.has(getRowId ? getRowId(d) : (d as any).id ?? d)
301
111
  );
302
112
  onSelectionChange?.(selectedItems);
303
113
  },
304
- [data, getRowId, limitSelect, onSelectionChange, selectedRowIds],
114
+ [data, getRowId, limitSelect, onSelectionChange, selectedRowIds]
305
115
  );
306
116
  useEffect(() => {
307
117
  if (!onLoadMore || !hasMore) return;
@@ -316,7 +126,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
316
126
  root: null,
317
127
  rootMargin: "0px",
318
128
  threshold: 1.0,
319
- },
129
+ }
320
130
  );
321
131
 
322
132
  if (loaderRef.current) {
@@ -329,357 +139,17 @@ export function DataTable<T>(props: DataTableProps<T>) {
329
139
  }
330
140
  };
331
141
  }, [onLoadMore, hasMore]);
332
- const hasNestedColumns = columns.some((col) => col.children?.length);
333
-
334
- const flatColumns = columns.flatMap((col) =>
335
- col.children?.length ? col.children : [col],
336
- );
337
-
338
- const stickyColumnsLeftByKey = useMemo(() => {
339
- const offsets = new Map<string, number>();
340
- const hasSelectionColumn = !!onSelectionChange;
341
- let currentLeft = hasSelectionColumn ? SELECTION_COLUMN_WIDTH : 0;
342
-
343
- flatColumns.forEach((column) => {
344
- const key = getFilterKey(column);
345
- const width =
346
- column.width ??
347
- column.minWidth ??
348
- column.maxWidth ??
349
- DEFAULT_FILTER_COLUMN_WIDTH;
350
-
351
- if (column.sticky) {
352
- offsets.set(key, currentLeft);
353
- currentLeft += width;
354
- }
355
- });
356
-
357
- return offsets;
358
- }, [flatColumns, getFilterKey, onSelectionChange]);
359
-
360
- const hasStickyColumns = stickyColumnsLeftByKey.size > 0;
361
-
362
- const sortedData = useMemo(() => {
363
- if (!currentSort) {
364
- return data;
365
- }
366
-
367
- const sortedColumn = flatColumns.find(
368
- (column) => getFilterKey(column) === currentSort.key,
369
- );
370
-
371
- if (!sortedColumn) {
372
- return data;
373
- }
374
-
375
- const factor = currentSort.direction === "asc" ? 1 : -1;
376
- const isDateColumn = sortedColumn.type === TypeInputEnum.DATE;
377
-
378
- const normalizeDate = (value: unknown): number | null => {
379
- if (value instanceof Date) {
380
- return value.getTime();
381
- }
382
-
383
- if (typeof value === "string" || typeof value === "number") {
384
- const timestamp = new Date(value).getTime();
385
- return Number.isNaN(timestamp) ? null : timestamp;
386
- }
387
-
388
- return null;
389
- };
390
-
391
- const compareValues = (left: unknown, right: unknown): number => {
392
- if (left == null && right == null) {
393
- return 0;
394
- }
395
-
396
- if (left == null) {
397
- return 1;
398
- }
399
-
400
- if (right == null) {
401
- return -1;
402
- }
403
-
404
- if (typeof left === "number" && typeof right === "number") {
405
- return left - right;
406
- }
407
-
408
- if (typeof left === "boolean" && typeof right === "boolean") {
409
- return Number(left) - Number(right);
410
- }
411
-
412
- if (isDateColumn) {
413
- const leftDate = normalizeDate(left);
414
- const rightDate = normalizeDate(right);
415
-
416
- if (leftDate !== null && rightDate !== null) {
417
- return leftDate - rightDate;
418
- }
419
- }
420
-
421
- return String(left).localeCompare(String(right), undefined, {
422
- numeric: true,
423
- sensitivity: "base",
424
- });
425
- };
426
-
427
- return [...data].sort((leftRow, rightRow) => {
428
- const leftValue = getColumnValue(leftRow, sortedColumn);
429
- const rightValue = getColumnValue(rightRow, sortedColumn);
430
- return factor * compareValues(leftValue, rightValue);
431
- });
432
- }, [currentSort, data, flatColumns, getColumnValue, getFilterKey]);
433
-
434
- const hasVisibleFilterInputs = visibleFilterColumns.size > 0;
435
- const headerStickyTop = hasVisibleFilterInputs ? filterRowHeight : 0;
436
- const groupedHeaderStickyTop = headerStickyTop + headerRowHeight;
437
-
438
- useLayoutEffect(() => {
439
- if (!hasVisibleFilterInputs) {
440
- setFilterRowHeight(DEFAULT_FILTER_ROW_STICKY_HEIGHT);
441
- return;
442
- }
443
-
444
- const updateFilterRowHeight = () => {
445
- const measuredHeight =
446
- filterRowRef.current?.getBoundingClientRect().height ??
447
- DEFAULT_FILTER_ROW_STICKY_HEIGHT;
448
- setFilterRowHeight((prev) =>
449
- Math.abs(prev - measuredHeight) < 0.1 ? prev : measuredHeight,
450
- );
451
- };
452
-
453
- updateFilterRowHeight();
454
-
455
- if (typeof ResizeObserver !== "undefined" && filterRowRef.current) {
456
- const resizeObserver = new ResizeObserver(updateFilterRowHeight);
457
- resizeObserver.observe(filterRowRef.current);
458
- return () => resizeObserver.disconnect();
459
- }
460
-
461
- window.addEventListener("resize", updateFilterRowHeight);
462
- return () => {
463
- window.removeEventListener("resize", updateFilterRowHeight);
464
- };
465
- }, [hasVisibleFilterInputs]);
466
-
467
- useLayoutEffect(() => {
468
- const updateHeaderRowHeight = () => {
469
- const measuredHeight =
470
- headerRowRef.current?.getBoundingClientRect().height ?? 0;
471
- setHeaderRowHeight((prev) =>
472
- Math.abs(prev - measuredHeight) < 0.1 ? prev : measuredHeight,
473
- );
474
- };
475
-
476
- updateHeaderRowHeight();
477
-
478
- if (typeof ResizeObserver !== "undefined" && headerRowRef.current) {
479
- const resizeObserver = new ResizeObserver(updateHeaderRowHeight);
480
- resizeObserver.observe(headerRowRef.current);
481
- return () => resizeObserver.disconnect();
482
- }
483
-
484
- window.addEventListener("resize", updateHeaderRowHeight);
485
- return () => {
486
- window.removeEventListener("resize", updateHeaderRowHeight);
487
- };
488
- }, [columns.length, hasVisibleFilterInputs]);
489
-
490
- const filterRowCells = useMemo(
491
- () =>
492
- flatColumns.map((column, idx) => {
493
- const key = getFilterKey(column);
494
- const isVisible = visibleFilterColumns.has(key);
495
- const currentFilterValue = currentFilters[key];
496
- const currentValue = isDateRangeFilterValue(currentFilterValue)
497
- ? ""
498
- : String(currentFilterValue ?? "");
499
- const currentDateRangeValue = isDateRangeFilterValue(currentFilterValue)
500
- ? currentFilterValue
501
- : { startDate: "", endDate: "" };
502
- const shouldAutoFocus = focusFilterKey === key && isVisible;
503
- const columnWidth = column.width ?? DEFAULT_FILTER_COLUMN_WIDTH;
504
- const stickyLeft = stickyColumnsLeftByKey.get(key);
505
- const isSticky = stickyLeft !== undefined;
506
-
507
- const onTextDateChange = (e: React.ChangeEvent<HTMLInputElement>) =>
508
- updateFilterValue(key, e.target.value);
509
-
510
- const onEnumSelectMultipleChange = (values: string[]) =>
511
- updateFilterValue(key, values.join(","));
512
-
513
- return (
514
- <th
515
- key={`filter-${column.id}-${idx}`}
516
- className={`filter-row-cell ${
517
- isSticky ? "data-table-sticky-cell" : ""
518
- }`.trim()}
519
- style={{
520
- width: columnWidth,
521
- minWidth: columnWidth,
522
- maxWidth: columnWidth,
523
- position: "sticky",
524
- top: 0,
525
- zIndex: isSticky ? 14 : 13,
526
- backgroundColor: "rgb(249, 251, 252)",
527
- ...(isSticky
528
- ? {
529
- left: stickyLeft,
530
- }
531
- : {}),
532
- }}
533
- >
534
- {isVisible && column.filterable && (
535
- <div className="data-table-filter-input-wrapper">
536
- {column.filterType === TypeInputEnum.DATE ? (
537
- <Input
538
- id={`${id}-filter-date-${column.id}`}
539
- name={`${id}-filter-date-${column.id}`}
540
- type={TypeInputEnum.DATE}
541
- value={currentValue}
542
- autoFocus={shouldAutoFocus}
543
- disabledDebounce={true}
544
- showClearButton
545
- onChange={onTextDateChange}
546
- onClick={(e) => e.stopPropagation()}
547
- className="data-table-filter-input"
548
- />
549
- ) : column.filterType === TypeInputEnum.DATERANGE ? (
550
- <DataTableColumnFilterDateRange
551
- id={`${id}-filter-date-range-${column.id}`}
552
- name={`${id}-filter-date-range-${column.id}`}
553
- currentStartValue={currentDateRangeValue.startDate}
554
- currentEndValue={currentDateRangeValue.endDate}
555
- onChange={(startDate, endDate) =>
556
- updateDateRangeFilterValue(key, startDate, endDate)
557
- }
558
- />
559
- ) : column.filterType === TypeInputEnum.RADIO ||
560
- column.filterType === TypeInputEnum.CHECKBOX ? (
561
- <div onClick={(e) => e.stopPropagation()}>
562
- <Select
563
- id={`${id}-filter-${column.id}`}
564
- options={column.filterDataEnum ?? []}
565
- multiple={true}
566
- showOptions={shouldAutoFocus}
567
- value={currentValue.split(",").filter(Boolean)}
568
- onChangeMultiple={onEnumSelectMultipleChange}
569
- placeholder={`Filtrer ${column.label}`}
570
- className="data-table-filter-select"
571
- />
572
- </div>
573
- ) : (
574
- <Input
575
- id={`${id}-filter-text-${column.id}`}
576
- name={`${id}-filter-text-${column.id}`}
577
- type={TypeInputEnum.TEXT}
578
- value={currentValue}
579
- showClearButton
580
- autoFocus={shouldAutoFocus}
581
- disabledDebounce={true}
582
- onChange={onTextDateChange}
583
- onClick={(e) => e.stopPropagation()}
584
- className="data-table-filter-input"
585
- placeholder={`Filtrer ${column.label}`}
586
- />
587
- )}
588
- </div>
589
- )}
590
- </th>
591
- );
592
- }),
593
- [
594
- currentFilters,
595
- flatColumns,
596
- focusFilterKey,
597
- getFilterKey,
598
- id,
599
- stickyColumnsLeftByKey,
600
- updateDateRangeFilterValue,
601
- updateFilterValue,
602
- visibleFilterColumns,
603
- ],
604
- );
605
142
  return (
606
143
  <div className="data-table-container">
607
144
  {name && <h2 className="mb-2">{name}</h2>}
608
145
  {element}
609
- {currentFilters && (
610
- <DataTableFilters
611
- currentFilters={currentFilters}
612
- setCurrentFilters={setCurrentFilters}
613
- />
614
- )}
615
146
  <table className={`data-table ${className ? className : ""}`} id={id}>
616
- <colgroup>
617
- {onSelectionChange && <col style={{ width: 20 }} />}
618
- {flatColumns.map((column, idx) => (
619
- <col
620
- key={`col-${column.id}-${idx}`}
621
- style={{
622
- width: column.width,
623
- minWidth: column.minWidth,
624
- maxWidth: column.maxWidth,
625
- }}
626
- />
627
- ))}
628
- {actions.length > 0 && <col style={{ width: 200 }} />}
629
- </colgroup>
630
147
  <thead>
631
- {hasVisibleFilterInputs && (
632
- <tr className="data-table-filter-row" ref={filterRowRef}>
633
- {onSelectionChange && (
634
- <th
635
- className={`select-cell ${
636
- hasStickyColumns ? "data-table-sticky-cell" : ""
637
- }`}
638
- style={{
639
- position: "sticky",
640
- top: 0,
641
- zIndex: hasStickyColumns ? 14 : 13,
642
- backgroundColor: "#f9fbfc",
643
- ...(hasStickyColumns
644
- ? {
645
- left: 0,
646
- }
647
- : {}),
648
- }}
649
- ></th>
650
- )}
651
- {filterRowCells}
652
- {actions.length > 0 && (
653
- <th
654
- style={{
655
- position: "sticky",
656
- top: 0,
657
- zIndex: 13,
658
- backgroundColor: "#f9fbfc",
659
- }}
660
- ></th>
661
- )}
662
- </tr>
663
- )}
664
- <tr className="data-table-header-row" ref={headerRowRef}>
148
+ <tr>
665
149
  {onSelectionChange && (
666
150
  <th
667
- className={`select-cell ${hideToggleAll ? "hidden" : ""} ${
668
- hasStickyColumns ? "data-table-sticky-cell" : ""
669
- }`.trim()}
670
- style={{
671
- width: "20px",
672
- textAlign: "center",
673
- top: headerStickyTop,
674
- ...(hasStickyColumns
675
- ? {
676
- position: "sticky",
677
- left: 0,
678
- zIndex: 6,
679
- backgroundColor: "#fff",
680
- }
681
- : {}),
682
- }}
151
+ className={`select-cell ${hideToggleAll ? "hidden" : ""}`}
152
+ style={{ width: "20px", textAlign: "center" }}
683
153
  >
684
154
  <Input
685
155
  id={`select-th-${id}`}
@@ -692,128 +162,45 @@ export function DataTable<T>(props: DataTableProps<T>) {
692
162
  />
693
163
  </th>
694
164
  )}
695
-
696
165
  {columns.map((column, idx) => (
697
- <DataTableColumn<T>
166
+ <DataTableColumn
698
167
  key={idx}
699
- hasNestedColumns={hasNestedColumns}
700
168
  column={column}
701
169
  idx={idx}
702
170
  onColumnClick={onColumnClick}
703
- isFilterVisible={visibleFilterColumns.has(getFilterKey(column))}
704
- onToggleFilterVisibility={toggleColumnFilterVisibility}
705
- currentSortDirection={
706
- currentSort?.key === getFilterKey(column)
707
- ? currentSort.direction
708
- : null
709
- }
710
- onToggleSort={toggleColumnSort}
711
- stickyLeft={stickyColumnsLeftByKey.get(getFilterKey(column))}
712
- stickyTop={headerStickyTop}
713
171
  />
714
172
  ))}
715
173
  {actions.length > 0 && (
716
174
  <th
717
175
  style={{
718
176
  width: "200px",
719
- top: headerStickyTop,
720
177
  }}
721
178
  align="right"
722
179
  key={"actions"}
723
- rowSpan={hasNestedColumns ? 2 : 1}
724
180
  ></th>
725
181
  )}
726
182
  </tr>
727
- {hasNestedColumns && (
183
+ </thead>
184
+ <tbody>
185
+ {loading ? (
728
186
  <tr>
729
- {columns.flatMap(
730
- (col, idx) =>
731
- col.children?.map(
732
- (
733
- child: DataTableColumnsInterface<any>,
734
- childIdx: number,
735
- ) => (
736
- <th
737
- key={`${idx}-${childIdx}`}
738
- style={{
739
- minWidth: child.minWidth,
740
- maxWidth: child.maxWidth,
741
- width: child.width,
742
- textAlign: child.align ?? "left",
743
- position: "sticky",
744
- top: groupedHeaderStickyTop,
745
- zIndex: 11,
746
- backgroundColor: "#f9fbfc",
747
- ...(stickyColumnsLeftByKey.has(getFilterKey(child))
748
- ? {
749
- left: stickyColumnsLeftByKey.get(
750
- getFilterKey(child),
751
- ),
752
- zIndex: 12,
753
- }
754
- : {}),
755
- }}
756
- className={
757
- stickyColumnsLeftByKey.has(getFilterKey(child))
758
- ? "data-table-sticky-cell"
759
- : undefined
760
- }
761
- onClick={() => onColumnClick?.(child)}
762
- >
763
- <div className="d-flex align-items-center">
764
- <div className="flex-1">{child.label}</div>
765
- {child.filterable && (
766
- <DataTableColumnFilter
767
- column={child}
768
- isFilterVisible={visibleFilterColumns.has(
769
- getFilterKey(child),
770
- )}
771
- onToggleVisibility={toggleColumnFilterVisibility}
772
- />
773
- )}
774
- {child.sortable && (
775
- <DataTableColumnSort
776
- column={child}
777
- sortDirection={
778
- currentSort?.key === getFilterKey(child)
779
- ? currentSort.direction
780
- : null
781
- }
782
- onToggleSort={toggleColumnSort}
783
- />
784
- )}
785
- </div>
786
- </th>
787
- ),
788
- ) ?? [],
789
- )}
187
+ <td
188
+ align="center"
189
+ colSpan={columns.length + (actions.length > 0 ? 1 : 0)}
190
+ >
191
+ <div className="mt-3">
192
+ <Loader display={loading} />
193
+ </div>
194
+ </td>
790
195
  </tr>
196
+ ) : (
197
+ <></>
791
198
  )}
792
- </thead>
793
- <tbody>
794
199
  {!loading &&
795
- sortedData.map((row, rowIndex) => (
796
- <tr
797
- key={getRowId ? getRowId(row) : ((row as any).id ?? rowIndex)}
798
- onClick={(e) => handleClickRow?.(e, row)}
799
- >
200
+ data.map((row, rowIndex) => (
201
+ <tr key={rowIndex} onClick={(e) => handleClickRow?.(e, row)}>
800
202
  {onSelectionChange && (
801
- <td
802
- className={`select-cell ${
803
- hasStickyColumns ? "data-table-sticky-cell" : ""
804
- }`.trim()}
805
- style={{
806
- textAlign: "center",
807
- ...(hasStickyColumns
808
- ? {
809
- position: "sticky",
810
- left: 0,
811
- zIndex: 3,
812
- backgroundColor: "#fff",
813
- }
814
- : {}),
815
- }}
816
- >
203
+ <td className="select-cell" style={{ textAlign: "center" }}>
817
204
  <Input
818
205
  id={`select-row-${rowIndex}`}
819
206
  name={`select-row-${rowIndex}`}
@@ -822,27 +209,18 @@ export function DataTable<T>(props: DataTableProps<T>) {
822
209
  limitSelect !== undefined &&
823
210
  selectedRowIds.size >= limitSelect &&
824
211
  !selectedRowIds.has(
825
- getRowId ? getRowId(row) : ((row as any).id ?? row),
212
+ getRowId ? getRowId(row) : (row as any).id ?? row
826
213
  )
827
214
  }
828
215
  checked={selectedRowIds.has(
829
- getRowId ? getRowId(row) : ((row as any).id ?? row),
216
+ getRowId ? getRowId(row) : (row as any).id ?? row
830
217
  )}
831
218
  onChange={(e) => toggleRow(e, row)} // empêche le clic de déclencher onRowClick
832
219
  />
833
220
  </td>
834
221
  )}
835
- {flatColumns.map((column, idx) => (
836
- <DataTableRow
837
- onEditColumnByOverlay={onEditColumnByOverlay}
838
- column={column}
839
- idx={idx}
840
- row={row}
841
- key={idx}
842
- stickyLeft={stickyColumnsLeftByKey.get(
843
- getFilterKey(column),
844
- )}
845
- />
222
+ {columns.map((column, idx) => (
223
+ <DataTableRow column={column} idx={idx} row={row} key={idx} />
846
224
  ))}
847
225
  {actions.length > 0 && (
848
226
  <td align="right">
@@ -860,19 +238,16 @@ export function DataTable<T>(props: DataTableProps<T>) {
860
238
  )}
861
239
  </tr>
862
240
  ))}
241
+ {!loading && data.length === 0 && (
242
+ <DataTableLoading
243
+ columns={columns}
244
+ actions={actions}
245
+ emptyMessage={emptyMessage}
246
+ />
247
+ )}
863
248
  </tbody>
864
249
  </table>
865
250
 
866
- {loading && (
867
- <div className="data-table-empty-state-content mt-3">
868
- <Loader display={true} />
869
- </div>
870
- )}
871
-
872
- {!loading && data.length === 0 && (
873
- <DataTableLoading emptyMessage={emptyMessage} />
874
- )}
875
-
876
251
  {children}
877
252
  {hasMore && (
878
253
  <div ref={loaderRef} className="infinite-scroll-loader">