kelt-ui-kit-react 1.8.2 → 1.8.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.
Files changed (245) hide show
  1. package/.github/workflows/publish.yml +31 -0
  2. package/dist/_core/type/generiqueType.d.ts +4 -0
  3. package/dist/badge/Badge.d.ts +3 -1
  4. package/dist/button/button.interface.d.ts +1 -1
  5. package/dist/dataTable/DataTable.d.ts +17 -3
  6. package/dist/dataTable/dataTable.interface.d.ts +21 -3
  7. package/dist/dataTable/dataTableActions/DataTableAction.d.ts +2 -2
  8. package/dist/dataTable/dataTableColumn/DataTableColumn.d.ts +13 -7
  9. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.d.ts +10 -0
  10. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.d.ts +9 -0
  11. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.d.ts +9 -0
  12. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.d.ts +13 -0
  13. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.d.ts +9 -0
  14. package/dist/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.d.ts +11 -0
  15. package/dist/dataTable/dataTableFilters/DataTableFilters.d.ts +7 -0
  16. package/dist/dataTable/dataTableLoading/DataTableLoading.d.ts +1 -3
  17. package/dist/dataTable/dataTableRow/DataTableRow.d.ts +5 -3
  18. package/dist/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.d.ts +12 -0
  19. package/dist/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.d.ts +11 -0
  20. package/dist/expands/expand/expand.d.ts +1 -1
  21. package/dist/form/form.enum.d.ts +1 -0
  22. package/dist/form/input/Input.d.ts +3 -0
  23. package/dist/form/inputNumber/InputNumber.d.ts +0 -2
  24. package/dist/icon/Icon.d.ts +1 -1
  25. package/dist/icon/icon.interface.d.ts +1 -0
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.js +3652 -2836
  28. package/dist/overlayPanel/OverlayPanel.d.ts +3 -1
  29. package/dist/select/Select.d.ts +4 -1
  30. package/dist/select/selectOption.interface.d.ts +1 -0
  31. package/dist/style.css +1 -1
  32. package/dist/tabs/Tabs.d.ts +2 -1
  33. package/kelt-ui-kit-react-1.6.9.tgz +0 -0
  34. package/package/README.md +46 -0
  35. package/package/index.html +20 -0
  36. package/package/package.json +56 -0
  37. package/package/public/favicon.ico +0 -0
  38. package/package/public/index.html +18 -0
  39. package/package/public/logo192.png +0 -0
  40. package/package/public/logo512.png +0 -0
  41. package/package/public/manifest.json +25 -0
  42. package/package/public/robots.txt +3 -0
  43. package/package/src/App.css +11 -0
  44. package/package/src/App.menu.tsx +249 -0
  45. package/package/src/App.routes.tsx +16 -0
  46. package/package/src/App.tsx +30 -0
  47. package/package/src/_core/hooks/HistoryProvider.tsx +25 -0
  48. package/package/src/_core/hooks/ImageChecker.tsx +26 -0
  49. package/package/src/_core/hooks/imageExist.tsx +9 -0
  50. package/package/src/_core/hooks/isEAN13.tsx +16 -0
  51. package/package/src/_core/hooks/objectToQueryParams.tsx +32 -0
  52. package/package/src/_core/hooks/useCurrency.tsx +18 -0
  53. package/package/src/_core/hooks/useDateutils.ts +64 -0
  54. package/package/src/_core/hooks/useIsMobile.ts +18 -0
  55. package/package/src/_core/hooks/useToken.tsx +19 -0
  56. package/package/src/_core/hooks/useValidate.tsx +18 -0
  57. package/package/src/_core/hooks/widgetSupport.tsx +39 -0
  58. package/package/src/action/Action.view.tsx +21 -0
  59. package/package/src/action/ButtonAction.tsx +32 -0
  60. package/package/src/action/action.css +20 -0
  61. package/package/src/badge/Badge.tsx +34 -0
  62. package/package/src/badge/Badge.view.tsx +15 -0
  63. package/package/src/badge/badge.css +55 -0
  64. package/package/src/button/Button.tsx +46 -0
  65. package/package/src/button/Button.view.tsx +85 -0
  66. package/package/src/button/button.css +53 -0
  67. package/package/src/button/button.interface.tsx +21 -0
  68. package/package/src/button/buttonActions/ButtonActions.tsx +104 -0
  69. package/package/src/button/buttonFile/ButtonFile.tsx +59 -0
  70. package/package/src/button/buttonFile/ButtonFile.view.tsx +70 -0
  71. package/package/src/button/buttonFilters/ButtonFilters.tsx +102 -0
  72. package/package/src/button/buttonFilters/buttonFilters.css +22 -0
  73. package/package/src/card/Card.tsx +125 -0
  74. package/package/src/card/Card.view.tsx +73 -0
  75. package/package/src/card/card.css +145 -0
  76. package/package/src/card/card.interface.tsx +9 -0
  77. package/package/src/card/cardAction/CardAction.tsx +135 -0
  78. package/package/src/card/cardAction/cardAction.css +10 -0
  79. package/package/src/card/cardAction.interface.tsx +10 -0
  80. package/package/src/card/hook/useCardInteractions.tsx +30 -0
  81. package/package/src/carousel/Carousel.css +44 -0
  82. package/package/src/carousel/Carousel.tsx +115 -0
  83. package/package/src/carousel/Carousel.view.tsx +13 -0
  84. package/package/src/damier/Damier.tsx +64 -0
  85. package/package/src/damier/Damier.view.tsx +31 -0
  86. package/package/src/damier/damier.css +50 -0
  87. package/package/src/damier/damierCell/DamierCell.tsx +18 -0
  88. package/package/src/damier/damierCell/damierCell.interface.tsx +5 -0
  89. package/package/src/dataTable/DataTable.tsx +259 -0
  90. package/package/src/dataTable/DataTable.view.tsx +62 -0
  91. package/package/src/dataTable/dataTable.css +30 -0
  92. package/package/src/dataTable/dataTable.interface.ts +30 -0
  93. package/package/src/dataTable/dataTableActions/DataTableAction.tsx +44 -0
  94. package/package/src/dataTable/dataTableColumn/DataTableColumn.tsx +27 -0
  95. package/package/src/dataTable/dataTableLoading/DataTableLoading.tsx +21 -0
  96. package/package/src/dataTable/dataTableRow/DataTableRow.tsx +54 -0
  97. package/package/src/datePicker/DatePicker.tsx +110 -0
  98. package/package/src/datePicker/DatePicker.view.tsx +9 -0
  99. package/package/src/datePicker/datePicker.css +77 -0
  100. package/package/src/expands/Expands.tsx +42 -0
  101. package/package/src/expands/Expands.view.tsx +90 -0
  102. package/package/src/expands/expand/expand.interface.tsx +8 -0
  103. package/package/src/expands/expand/expand.tsx +75 -0
  104. package/package/src/expands/expands.css +97 -0
  105. package/package/src/filAriane/FilAriane.tsx +57 -0
  106. package/package/src/filAriane/FilAriane.view.tsx +28 -0
  107. package/package/src/filAriane/filAriane.css +23 -0
  108. package/package/src/filAriane/filAriane.interface.tsx +6 -0
  109. package/package/src/form/Form.tsx +279 -0
  110. package/package/src/form/Form.view.tsx +59 -0
  111. package/package/src/form/form.css +62 -0
  112. package/package/src/form/form.enum.ts +13 -0
  113. package/package/src/form/form.interface.tsx +37 -0
  114. package/package/src/form/input/Input.tsx +106 -0
  115. package/package/src/form/input/input.css +26 -0
  116. package/package/src/form/inputNumber/InputNumber.tsx +132 -0
  117. package/package/src/form/inputNumber/InputNumber.view.tsx +15 -0
  118. package/package/src/form/inputPrice/InputPrice.tsx +42 -0
  119. package/package/src/form/inputPrice/InputPrice.view.tsx +15 -0
  120. package/package/src/form/textArea/TextArea.tsx +59 -0
  121. package/package/src/form/textArea/TextArea.view.tsx +34 -0
  122. package/package/src/form/textArea/textArea.css +9 -0
  123. package/package/src/grid/Grid.tsx +21 -0
  124. package/package/src/grid/Grid.view.tsx +24 -0
  125. package/package/src/grid/col/Col.tsx +15 -0
  126. package/package/src/grid/col/colStyled/ColStyled.tsx +41 -0
  127. package/package/src/grid/container/Container.tsx +8 -0
  128. package/package/src/grid/container/container.css +5 -0
  129. package/package/src/grid/grid.interface.tsx +7 -0
  130. package/package/src/grid/row/Row.tsx +12 -0
  131. package/package/src/grid/row/row.css +18 -0
  132. package/package/src/header/Header.tsx +62 -0
  133. package/package/src/header/Header.view.tsx +5 -0
  134. package/package/src/header/header.css +26 -0
  135. package/package/src/header/header.interface.tsx +10 -0
  136. package/package/src/home/Home.tsx +3 -0
  137. package/package/src/icon/Icon.tsx +6 -0
  138. package/package/src/icon/Icons.view.tsx +29 -0
  139. package/package/src/icon/icon.css +20 -0
  140. package/package/src/icon/icon.interface.tsx +6 -0
  141. package/package/src/icon/iconSize.enum.ts +7 -0
  142. package/package/src/index.css +502 -0
  143. package/package/src/index.ts +58 -0
  144. package/package/src/loader/Loader.tsx +37 -0
  145. package/package/src/loader/Loader.view.tsx +20 -0
  146. package/package/src/loader/loader.css +30 -0
  147. package/package/src/logo.svg +1 -0
  148. package/package/src/main.tsx +10 -0
  149. package/package/src/menus/Menus.tsx +42 -0
  150. package/package/src/menus/Menus.view.tsx +39 -0
  151. package/package/src/menus/menu/Menu.tsx +17 -0
  152. package/package/src/menus/menu/menu.interface.tsx +9 -0
  153. package/package/src/menus/menus.css +47 -0
  154. package/package/src/message/Message.tsx +30 -0
  155. package/package/src/message/Message.view.tsx +22 -0
  156. package/package/src/message/message.css +29 -0
  157. package/package/src/modal/Modal.tsx +59 -0
  158. package/package/src/modal/Modal.view.tsx +26 -0
  159. package/package/src/modal/modal.css +71 -0
  160. package/package/src/notFound/NotFound.tsx +3 -0
  161. package/package/src/overlayPanel/OverlayPanel.tsx +195 -0
  162. package/package/src/overlayPanel/OverlayPanel.view.tsx +25 -0
  163. package/package/src/overlayPanel/overlay.context.tsx +28 -0
  164. package/package/src/overlayPanel/overlayPanel.css +35 -0
  165. package/package/src/overlayPanel/overlayPanelStyled/OverlayPanelStyled.tsx +18 -0
  166. package/package/src/pdfViewer/PdfViewer.tsx +73 -0
  167. package/package/src/pdfViewer/PdfViewer.view.tsx +5 -0
  168. package/package/src/quantity/Quantity.tsx +103 -0
  169. package/package/src/quantity/Quantity.view.tsx +0 -0
  170. package/package/src/quantity/quantity.css +26 -0
  171. package/package/src/search/Search.tsx +161 -0
  172. package/package/src/search/Search.view.tsx +14 -0
  173. package/package/src/search/search.css +59 -0
  174. package/package/src/select/Select.tsx +103 -0
  175. package/package/src/select/Select.view.tsx +71 -0
  176. package/package/src/select/select.css +69 -0
  177. package/package/src/select/selectOption.interface.ts +4 -0
  178. package/package/src/sidebar/Sidebar.tsx +208 -0
  179. package/package/src/sidebar/Sidebar.view.tsx +17 -0
  180. package/package/src/sidebar/sidebar.css +104 -0
  181. package/package/src/sidebarData/SidebarData.tsx +19 -0
  182. package/package/src/sidebarData/SidebarData.view.tsx +19 -0
  183. package/package/src/sidebarData/sidebarData.css +27 -0
  184. package/package/src/tabs/Tabs.tsx +90 -0
  185. package/package/src/tabs/Tabs.view.tsx +20 -0
  186. package/package/src/tabs/tabs.css +24 -0
  187. package/package/src/toaster/Toaster.tsx +55 -0
  188. package/package/src/toaster/Toaster.view.tsx +24 -0
  189. package/package/src/toaster/store/useToasterStore.tsx +41 -0
  190. package/package/src/toaster/toaster.css +87 -0
  191. package/package/tsconfig.json +28 -0
  192. package/package/vite.config.ts +20 -0
  193. package/package/vite.config.ts.timestamp-1733262892554-a13dfef6e8a29.mjs +24 -0
  194. package/package/vite.config.ts.timestamp-1757847121745-e5a5bf54b81b.mjs +28 -0
  195. package/package/vite.config.ts.timestamp-1759742478362-4ac5c5a7db34b.mjs +28 -0
  196. package/package.json +1 -1
  197. package/src/_core/type/generiqueType.tsx +4 -0
  198. package/src/badge/Badge.tsx +9 -1
  199. package/src/badge/badge.css +4 -0
  200. package/src/button/Button.tsx +1 -1
  201. package/src/button/button.interface.tsx +1 -1
  202. package/src/card/card.css +23 -3
  203. package/src/card/cardAction/CardAction.tsx +4 -4
  204. package/src/dataTable/DataTable.tsx +670 -45
  205. package/src/dataTable/DataTable.view.tsx +47 -14
  206. package/src/dataTable/dataTable.css +153 -5
  207. package/src/dataTable/dataTable.interface.ts +21 -3
  208. package/src/dataTable/dataTableActions/DataTableAction.tsx +2 -2
  209. package/src/dataTable/dataTableColumn/DataTableColumn.tsx +64 -14
  210. package/src/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.tsx +36 -0
  211. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilter.css +0 -0
  212. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.tsx +39 -0
  213. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.tsx +80 -0
  214. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.tsx +89 -0
  215. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.tsx +37 -0
  216. package/src/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.tsx +42 -0
  217. package/src/dataTable/dataTableFilters/DataTableFilters.tsx +91 -0
  218. package/src/dataTable/dataTableFilters/dataTableFilters.css +16 -0
  219. package/src/dataTable/dataTableLoading/DataTableLoading.tsx +4 -15
  220. package/src/dataTable/dataTableRow/DataTableRow.tsx +60 -33
  221. package/src/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.tsx +80 -0
  222. package/src/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.tsx +123 -0
  223. package/src/expands/Expands.tsx +2 -16
  224. package/src/expands/expand/expand.tsx +6 -18
  225. package/src/form/Form.tsx +13 -12
  226. package/src/form/form.css +13 -2
  227. package/src/form/form.enum.ts +1 -0
  228. package/src/form/input/Input.tsx +61 -7
  229. package/src/form/input/input.css +23 -1
  230. package/src/form/inputNumber/InputNumber.tsx +6 -11
  231. package/src/form/inputPrice/InputPrice.tsx +2 -4
  232. package/src/icon/Icon.tsx +6 -2
  233. package/src/icon/icon.interface.tsx +1 -0
  234. package/src/index.ts +2 -0
  235. package/src/overlayPanel/OverlayPanel.tsx +23 -10
  236. package/src/overlayPanel/overlay.context.tsx +6 -4
  237. package/src/overlayPanel/overlayPanel.css +10 -1
  238. package/src/select/Select.tsx +134 -38
  239. package/src/select/select.css +65 -14
  240. package/src/select/selectOption.interface.ts +1 -0
  241. package/src/sidebar/Sidebar.tsx +9 -80
  242. package/src/sidebar/sidebar.css +1 -18
  243. package/src/tabs/Tabs.tsx +19 -1
  244. package/vite.config.ts.timestamp-1757847121745-e5a5bf54b81b.mjs +28 -28
  245. package/vite.config.ts.timestamp-1759742478362-4ac5c5a7db34b.mjs +28 -28
@@ -0,0 +1,259 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { TypeInputEnum } from "../form/form.enum";
3
+ import { Input } from "../form/input/Input";
4
+ import { Loader } from "../loader/Loader";
5
+ import "./dataTable.css";
6
+ import {
7
+ dataTableActionsInterface,
8
+ dataTableColumnsInterface,
9
+ } from "./dataTable.interface";
10
+ import { DataTableAction } from "./dataTableActions/DataTableAction";
11
+ import { DataTableColumn } from "./dataTableColumn/DataTableColumn";
12
+ import { DataTableLoading } from "./dataTableLoading/DataTableLoading";
13
+ import { DataTableRow } from "./dataTableRow/DataTableRow";
14
+ export type DataTableProps<T> = {
15
+ id: string;
16
+ name?: string;
17
+ className?: string;
18
+ children?: JSX.Element;
19
+ element?: JSX.Element;
20
+ data: T[];
21
+ emptyMessage?: string;
22
+ actions?: dataTableActionsInterface<T>[];
23
+ columns: dataTableColumnsInterface<T>[];
24
+ loading?: boolean;
25
+ onRowClick?: (row: any) => void;
26
+ onColumnClick?: (column: any) => void;
27
+ onLoadMore?: () => void;
28
+ hasMore?: boolean; // pour savoir s'il reste des données à charger
29
+ onSelectionChange?: (selectedRows: T[]) => void;
30
+ hideToggleAll?: boolean;
31
+ limitSelect?: number;
32
+ getRowId?: (row: T) => string | number;
33
+ };
34
+ export function DataTable<T>(props: DataTableProps<T>) {
35
+ const {
36
+ id,
37
+ name,
38
+ className,
39
+ children,
40
+ element,
41
+ data = [],
42
+ actions = [],
43
+ columns = [],
44
+ loading,
45
+ onRowClick,
46
+ onColumnClick,
47
+ onLoadMore,
48
+ emptyMessage,
49
+ hasMore,
50
+ onSelectionChange,
51
+ hideToggleAll = false,
52
+ limitSelect = undefined,
53
+ getRowId,
54
+ } = props;
55
+
56
+ const loaderRef = useRef<HTMLDivElement | null>(null);
57
+ const [selectedRowIds, setSelectedRowIds] = useState<Set<string | number>>(
58
+ new Set()
59
+ );
60
+ const toggleSelectAll = useCallback(() => {
61
+ if (selectedRowIds.size === data.length) {
62
+ setSelectedRowIds(new Set());
63
+ onSelectionChange?.([]);
64
+ } else {
65
+ let allIds = data.map((d) =>
66
+ getRowId ? getRowId(d) : (d as any).id ?? d
67
+ );
68
+
69
+ if (limitSelect && allIds.length > limitSelect) {
70
+ allIds = allIds.slice(0, limitSelect);
71
+ }
72
+
73
+ const newSelection = new Set(allIds);
74
+ setSelectedRowIds(newSelection);
75
+ onSelectionChange?.(
76
+ data.filter((d) =>
77
+ newSelection.has(getRowId ? getRowId(d) : (d as any).id ?? d)
78
+ )
79
+ );
80
+ }
81
+ }, [data, onSelectionChange, limitSelect, getRowId, selectedRowIds.size]);
82
+
83
+ const handleClickRow = useCallback(
84
+ (e: React.MouseEvent, row: T) => {
85
+ e.stopPropagation();
86
+ if (onRowClick) {
87
+ onRowClick?.(row);
88
+ }
89
+ },
90
+ [onRowClick]
91
+ );
92
+ const toggleRow = useCallback(
93
+ (e: React.ChangeEvent<HTMLInputElement>, row: T) => {
94
+ e.stopPropagation();
95
+ const rowId = getRowId ? getRowId(row) : (row as any).id ?? row;
96
+ const newSelection = new Set(selectedRowIds);
97
+
98
+ if (newSelection.has(rowId)) {
99
+ newSelection.delete(rowId);
100
+ } else {
101
+ if (limitSelect && newSelection.size >= limitSelect) {
102
+ // 🚫 limite atteinte
103
+ return;
104
+ }
105
+ newSelection.add(rowId);
106
+ }
107
+
108
+ setSelectedRowIds(newSelection);
109
+ const selectedItems = data.filter((d) =>
110
+ newSelection.has(getRowId ? getRowId(d) : (d as any).id ?? d)
111
+ );
112
+ onSelectionChange?.(selectedItems);
113
+ },
114
+ [data, getRowId, limitSelect, onSelectionChange, selectedRowIds]
115
+ );
116
+ useEffect(() => {
117
+ if (!onLoadMore || !hasMore) return;
118
+
119
+ const observer = new IntersectionObserver(
120
+ (entries) => {
121
+ if (entries[0].isIntersecting) {
122
+ onLoadMore();
123
+ }
124
+ },
125
+ {
126
+ root: null,
127
+ rootMargin: "0px",
128
+ threshold: 1.0,
129
+ }
130
+ );
131
+
132
+ if (loaderRef.current) {
133
+ observer.observe(loaderRef.current);
134
+ }
135
+
136
+ return () => {
137
+ if (loaderRef.current) {
138
+ observer.unobserve(loaderRef.current);
139
+ }
140
+ };
141
+ }, [onLoadMore, hasMore]);
142
+ return (
143
+ <div className="data-table-container">
144
+ {name && <h2 className="mb-2">{name}</h2>}
145
+ {element}
146
+ <table className={`data-table ${className ? className : ""}`} id={id}>
147
+ <thead>
148
+ <tr>
149
+ {onSelectionChange && (
150
+ <th
151
+ className={`select-cell ${hideToggleAll ? "hidden" : ""}`}
152
+ style={{ width: "20px", textAlign: "center" }}
153
+ >
154
+ <Input
155
+ id={`select-th-${id}`}
156
+ name={`select-th-${id}`}
157
+ type={TypeInputEnum.CHECKBOX}
158
+ checked={
159
+ data.length > 0 && selectedRowIds.size === data.length
160
+ }
161
+ onChange={toggleSelectAll}
162
+ />
163
+ </th>
164
+ )}
165
+ {columns.map((column, idx) => (
166
+ <DataTableColumn
167
+ key={idx}
168
+ column={column}
169
+ idx={idx}
170
+ onColumnClick={onColumnClick}
171
+ />
172
+ ))}
173
+ {actions.length > 0 && (
174
+ <th
175
+ style={{
176
+ width: "200px",
177
+ }}
178
+ align="right"
179
+ key={"actions"}
180
+ ></th>
181
+ )}
182
+ </tr>
183
+ </thead>
184
+ <tbody>
185
+ {loading ? (
186
+ <tr>
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>
195
+ </tr>
196
+ ) : (
197
+ <></>
198
+ )}
199
+ {!loading &&
200
+ data.map((row, rowIndex) => (
201
+ <tr key={rowIndex} onClick={(e) => handleClickRow?.(e, row)}>
202
+ {onSelectionChange && (
203
+ <td className="select-cell" style={{ textAlign: "center" }}>
204
+ <Input
205
+ id={`select-row-${rowIndex}`}
206
+ name={`select-row-${rowIndex}`}
207
+ type={TypeInputEnum.CHECKBOX}
208
+ disabled={
209
+ limitSelect !== undefined &&
210
+ selectedRowIds.size >= limitSelect &&
211
+ !selectedRowIds.has(
212
+ getRowId ? getRowId(row) : (row as any).id ?? row
213
+ )
214
+ }
215
+ checked={selectedRowIds.has(
216
+ getRowId ? getRowId(row) : (row as any).id ?? row
217
+ )}
218
+ onChange={(e) => toggleRow(e, row)} // empêche le clic de déclencher onRowClick
219
+ />
220
+ </td>
221
+ )}
222
+ {columns.map((column, idx) => (
223
+ <DataTableRow column={column} idx={idx} row={row} key={idx} />
224
+ ))}
225
+ {actions.length > 0 && (
226
+ <td align="right">
227
+ <div className="d-flex align-items-center justify-content-end">
228
+ {actions.map((action, index) => (
229
+ <DataTableAction
230
+ key={index}
231
+ action={action}
232
+ row={row}
233
+ index={index}
234
+ />
235
+ ))}
236
+ </div>
237
+ </td>
238
+ )}
239
+ </tr>
240
+ ))}
241
+ {!loading && data.length === 0 && (
242
+ <DataTableLoading
243
+ columns={columns}
244
+ actions={actions}
245
+ emptyMessage={emptyMessage}
246
+ />
247
+ )}
248
+ </tbody>
249
+ </table>
250
+
251
+ {children}
252
+ {hasMore && (
253
+ <div ref={loaderRef} className="infinite-scroll-loader">
254
+ <Loader display={true} />
255
+ </div>
256
+ )}
257
+ </div>
258
+ );
259
+ }
@@ -0,0 +1,62 @@
1
+ import { useMemo } from "react";
2
+ import { DataTable } from "./DataTable";
3
+ import { dataTableActionsInterface } from "./dataTable.interface";
4
+
5
+ export const DataTableView = () => {
6
+ const dataTableColumns = useMemo(() => {
7
+ return [
8
+ { id: "id", label: "ID", minWidth: 50, type: "number" },
9
+ {
10
+ id: "name",
11
+ label: "Name",
12
+ minWidth: 100,
13
+ editable: true,
14
+ type: "text",
15
+ },
16
+ { id: "age", label: "Age", minWidth: 50, type: "number" },
17
+ ];
18
+ }, []);
19
+ const data = useMemo(() => {
20
+ return [
21
+ { id: 1, name: "John Doe", age: 28 },
22
+ { id: 2, name: "Jane Smith", age: 34 },
23
+ { id: 3, name: "Alice Johnson", age: 45 },
24
+ ];
25
+ }, []);
26
+ const actions: dataTableActionsInterface<{
27
+ id: number;
28
+ name: string;
29
+ age: number;
30
+ }>[] = useMemo(() => {
31
+ return [
32
+ {
33
+ id: "edit",
34
+ label: "Edit",
35
+ type: "button",
36
+ onClick: (row: any) => {
37
+ console.log("Edit action clicked for row:", row);
38
+ },
39
+ },
40
+ {
41
+ id: "delete",
42
+ label: "Delete",
43
+ type: "button",
44
+ onClick: (row: any) => {
45
+ console.log("Delete action clicked for row:", row);
46
+ },
47
+ },
48
+ ];
49
+ }, []);
50
+ return (
51
+ <DataTable
52
+ data={data}
53
+ actions={actions}
54
+ columns={dataTableColumns}
55
+ id="datatable-example"
56
+ name={"DataTable"}
57
+ onSelectionChange={(selectedRows) => {
58
+ console.log("Selected Rows: ", selectedRows);
59
+ }}
60
+ />
61
+ );
62
+ };
@@ -0,0 +1,30 @@
1
+ .data-table-container {
2
+ overflow: auto;
3
+ .data-table {
4
+ width: 100%;
5
+ border-spacing: 5px;
6
+ font-size: 14px;
7
+ color: #333;
8
+ .select-cell {
9
+ min-width: 40px !important;
10
+ .input-container {
11
+ min-width: 20px;
12
+ input {
13
+ min-width: 20px;
14
+ width: 20px;
15
+ cursor: pointer;
16
+ }
17
+ }
18
+ }
19
+ thead {
20
+ margin-bottom: 1rem;
21
+ position: sticky;
22
+ top: 0;
23
+ background-color: #fff;
24
+ th {
25
+ color: #bdbaba;
26
+ min-width: 100px;
27
+ }
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,30 @@
1
+ import { HTMLInputTypeAttribute } from "react";
2
+
3
+ export interface dataTableColumnsInterface<T> {
4
+ id: string;
5
+ label: string;
6
+ minWidth?: number;
7
+ maxWidth?: number;
8
+ width?: number;
9
+ align?: "right" | "left" | "center";
10
+ format?: (value: any) => string;
11
+ sortable?: boolean;
12
+ filterable?: boolean;
13
+ filterValue?: string;
14
+ editable?: boolean;
15
+ options?: { label: string; value: string }[];
16
+ onEdit?: (value: any, row: T) => void;
17
+ onRowStyle?: (row: T) => React.CSSProperties;
18
+ type: HTMLInputTypeAttribute | "select";
19
+ }
20
+ export interface dataTableActionsInterface<T> {
21
+ id: string;
22
+ label: string;
23
+ type: "button" | "link" | "icon";
24
+ classIcon?: string;
25
+ onClick: (row: T) => void;
26
+ shouldDisplay?: (row: T) => boolean;
27
+ disabled?: boolean;
28
+ labelButton?: (row: T) => string;
29
+ visible?: boolean;
30
+ }
@@ -0,0 +1,44 @@
1
+ import { Button } from "../../button/Button";
2
+ import { Icon } from "../../icon/Icon";
3
+ import { dataTableActionsInterface } from "../dataTable.interface";
4
+ type DataTableActionProps = {
5
+ action: dataTableActionsInterface<any>;
6
+ row: any;
7
+ index?: number;
8
+ };
9
+ export const DataTableAction = ({
10
+ action,
11
+ row,
12
+ index,
13
+ }: DataTableActionProps) => {
14
+ let title = action.label;
15
+ const display = action.shouldDisplay ? action.shouldDisplay(row) : true;
16
+ if (!display) return null;
17
+ if (action.labelButton) {
18
+ title = action.labelButton ? action.labelButton(row) : action.label;
19
+ }
20
+ return (
21
+ <>
22
+ {action.type === "button" && (
23
+ <Button
24
+ title={title}
25
+ key={`button-action-${action.id}-${index}`}
26
+ onClick={() => action.onClick(row)}
27
+ disabled={action.disabled}
28
+ className={`data-table-action button--tertiary mr-2 w-100 ${
29
+ action.classIcon ? action.classIcon : ""
30
+ }`}
31
+ />
32
+ )}
33
+ {action.type === "icon" && (
34
+ <div
35
+ key={`icon-action-${action.id}-${index}`}
36
+ className={`mr-2 `}
37
+ onClick={() => action.onClick(row)}
38
+ >
39
+ <Icon classIcon={action.classIcon ?? ""} key={action.id} />
40
+ </div>
41
+ )}
42
+ </>
43
+ );
44
+ };
@@ -0,0 +1,27 @@
1
+ import { dataTableColumnsInterface } from "../dataTable.interface";
2
+
3
+ type DataTableColumnProps = {
4
+ column: dataTableColumnsInterface<any>;
5
+ idx: number;
6
+ onColumnClick?: (column: dataTableColumnsInterface<any>) => void;
7
+ };
8
+ export const DataTableColumn = ({
9
+ column,
10
+ idx,
11
+ onColumnClick,
12
+ }: DataTableColumnProps) => {
13
+ return (
14
+ <th
15
+ key={`colonne-${column.id}-${idx}`}
16
+ style={{
17
+ minWidth: column.minWidth,
18
+ maxWidth: column.maxWidth,
19
+ width: column.width,
20
+ textAlign: column.align || "left",
21
+ }}
22
+ onClick={() => onColumnClick?.(column)}
23
+ >
24
+ {column.label}
25
+ </th>
26
+ );
27
+ };
@@ -0,0 +1,21 @@
1
+ type DataTableLoadingProps = {
2
+ columns: any[];
3
+ actions: any[];
4
+ emptyMessage?: string;
5
+ };
6
+ export const DataTableLoading = ({
7
+ columns,
8
+ actions,
9
+ emptyMessage,
10
+ }: DataTableLoadingProps) => {
11
+ return (
12
+ <tr>
13
+ <td
14
+ align="center"
15
+ colSpan={columns.length + (actions.length > 0 ? 1 : 0)}
16
+ >
17
+ <div className="mt-3">{emptyMessage || "Aucune donnée disponible"}</div>
18
+ </td>
19
+ </tr>
20
+ );
21
+ };
@@ -0,0 +1,54 @@
1
+ import { Select } from "../../select/Select";
2
+ import { dataTableColumnsInterface } from "../dataTable.interface";
3
+
4
+ type DataTableRowProps = {
5
+ column: dataTableColumnsInterface<any>;
6
+ idx: number;
7
+ row: any;
8
+ };
9
+ export const DataTableRow = ({ column, idx, row }: DataTableRowProps) => {
10
+ const value = (row as any)[column.id]; // On utilise [column.id] pour accéder aux bonnes propriétés
11
+ const style = column.onRowStyle ? column.onRowStyle(row) : {};
12
+ return (
13
+ <td
14
+ style={{
15
+ minWidth: column.minWidth,
16
+ textAlign: column.align || "left",
17
+ maxWidth: column.maxWidth,
18
+ width: column.width,
19
+ ...style,
20
+ }}
21
+ key={`row-${column.id}-${idx}`}
22
+ >
23
+ {column.editable ? (
24
+ column.type === "select" ? (
25
+ <Select
26
+ options={column.options ?? []}
27
+ value={value}
28
+ onChange={(e) => {
29
+ if (column.onEdit) {
30
+ column.onEdit(e, row);
31
+ }
32
+ }}
33
+ />
34
+ ) : (
35
+ <input
36
+ type={column.type}
37
+ value={value}
38
+ step="0.01"
39
+ style={{ textAlign: column.align || "left" }}
40
+ onChange={(e) => {
41
+ if (column.onEdit) {
42
+ column.onEdit(e.target.value, row);
43
+ }
44
+ }}
45
+ />
46
+ )
47
+ ) : column.format ? (
48
+ column.format(value)
49
+ ) : (
50
+ value
51
+ )}
52
+ </td>
53
+ );
54
+ };
@@ -0,0 +1,110 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import Calendar from "react-calendar";
3
+ import { Value } from "react-calendar/dist/cjs/shared/types";
4
+ import { Icon } from "../icon/Icon";
5
+ import { IconSizeEnum } from "../icon/iconSize.enum";
6
+ import "./datePicker.css"; // Assuming you have some styles for the DatePicker
7
+ export type DatePickerProps = {
8
+ value?: Value;
9
+ maxDate?: Date;
10
+ onChange?: (date: Value) => void;
11
+ children?: React.ReactNode;
12
+ };
13
+ export const DatePicker = ({
14
+ value,
15
+ onChange,
16
+ maxDate,
17
+ children,
18
+ }: DatePickerProps) => {
19
+ const [dateCalendar, setDateCalendar] = useState<Value>(value ?? new Date());
20
+ const [showCalendar, setShowCalendar] = useState(false);
21
+
22
+ const calendarRef = useRef<HTMLDivElement>(null);
23
+
24
+ const handleChange = useCallback(
25
+ (val: Value) => {
26
+ setDateCalendar(val);
27
+ if (onChange) {
28
+ onChange(val);
29
+ }
30
+ setShowCalendar(false);
31
+ },
32
+ [onChange]
33
+ );
34
+
35
+ const toggleCalendar = () => setShowCalendar(!showCalendar);
36
+
37
+ const handleClickOutside = useCallback((event: MouseEvent) => {
38
+ if (
39
+ calendarRef.current &&
40
+ !calendarRef.current.contains(event.target as Node)
41
+ ) {
42
+ setShowCalendar(false);
43
+ }
44
+ }, []);
45
+
46
+ useEffect(() => {
47
+ if (showCalendar) {
48
+ document.addEventListener("mousedown", handleClickOutside);
49
+ } else {
50
+ document.removeEventListener("mousedown", handleClickOutside);
51
+ }
52
+
53
+ // Nettoyage
54
+ return () => {
55
+ document.removeEventListener("mousedown", handleClickOutside);
56
+ };
57
+ }, [showCalendar, handleClickOutside]);
58
+ const [currentMonth, setCurrentMonth] = useState<Value>();
59
+
60
+ const handleActiveStartDateChange = ({
61
+ activeStartDate,
62
+ }: {
63
+ activeStartDate: Value;
64
+ }) => {
65
+ setCurrentMonth(activeStartDate);
66
+ };
67
+ return (
68
+ <div>
69
+ <div className="calendar" ref={calendarRef}>
70
+ {children && <div onClick={toggleCalendar}>{children}</div>}
71
+ {!children && (
72
+ <button className="calendar-button" onClick={toggleCalendar}>
73
+ <Icon
74
+ classIcon=" bi-calendar4-event"
75
+ size={IconSizeEnum.EXTRA_LARGE}
76
+ />
77
+ </button>
78
+ )}
79
+ {showCalendar && (
80
+ <div className="calendar-popup">
81
+ <div
82
+ onClick={() => setShowCalendar(false)}
83
+ className="calendar-popup-close"
84
+ >
85
+ <Icon
86
+ classIcon="bi-x-lg close-icon"
87
+ size={IconSizeEnum.EXTRA_SMALL}
88
+ />
89
+ </div>
90
+ <Calendar
91
+ onActiveStartDateChange={handleActiveStartDateChange}
92
+ maxDate={maxDate ?? new Date()}
93
+ onChange={handleChange}
94
+ value={dateCalendar}
95
+ tileClassName={({ date: day, view }) => {
96
+ if (view === "month" && (currentMonth as Date)) {
97
+ const curr = currentMonth as Date;
98
+ return day.getMonth() !== curr?.getMonth()
99
+ ? "out-of-month"
100
+ : null;
101
+ }
102
+ return null;
103
+ }}
104
+ />
105
+ </div>
106
+ )}
107
+ </div>
108
+ </div>
109
+ );
110
+ };
@@ -0,0 +1,9 @@
1
+ import { DatePicker } from "./DatePicker";
2
+
3
+ export const DatePickerView = () => {
4
+ return (
5
+ <div>
6
+ <DatePicker />
7
+ </div>
8
+ );
9
+ };