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,37 @@
1
+ import { useState } from "react";
2
+
3
+ import { Input } from "../../../../form/input/Input";
4
+
5
+ type DataTableColumnFilterStringProps = {
6
+ id: string;
7
+ name: string;
8
+ label: string;
9
+ onChange: (value: string) => void;
10
+ currentValue?: string;
11
+ };
12
+ export const DataTableColumnFilterString = ({
13
+ id,
14
+ name,
15
+ label,
16
+ onChange,
17
+ currentValue,
18
+ }: DataTableColumnFilterStringProps) => {
19
+ const [selectedValue, setSelectedValue] = useState<string>(
20
+ currentValue ?? "",
21
+ );
22
+ const handleChange = (value: string) => {
23
+ setSelectedValue(value);
24
+ onChange(value);
25
+ };
26
+ return (
27
+ <div>
28
+ <p>{label}</p>
29
+ <Input
30
+ id={id}
31
+ name={name}
32
+ value={selectedValue}
33
+ onChange={(e) => handleChange(e.target.value)}
34
+ />
35
+ </div>
36
+ );
37
+ };
@@ -0,0 +1,42 @@
1
+ import { Icon } from "../../../icon/Icon";
2
+ import { DataTableSortDirection } from "../../DataTable";
3
+ import { DataTableColumnsInterface } from "../../dataTable.interface";
4
+
5
+ type DataTableColumnSortProps<T> = {
6
+ className?: string;
7
+ column: DataTableColumnsInterface<T>;
8
+ sortDirection?: DataTableSortDirection | null;
9
+ onToggleSort?: (column: DataTableColumnsInterface<T>) => void;
10
+ };
11
+
12
+ export const DataTableColumnSort = <T,>({
13
+ className,
14
+ column,
15
+ sortDirection,
16
+ onToggleSort,
17
+ }: DataTableColumnSortProps<T>) => {
18
+ const iconClass =
19
+ sortDirection === "asc"
20
+ ? "bi-sort-up"
21
+ : sortDirection === "desc"
22
+ ? "bi-sort-down"
23
+ : "bi-arrow-down-up";
24
+
25
+ return (
26
+ <div
27
+ className={`data-table-column-sort ${sortDirection ? "active" : ""} ${className ?? ""}`}
28
+ >
29
+ <span>
30
+ <Icon
31
+ onClick={(e) => {
32
+ e.stopPropagation();
33
+ onToggleSort?.(column);
34
+ }}
35
+ classIcon={`${iconClass} cursor-pointer ${
36
+ sortDirection ? "data-table-column-sort-active" : ""
37
+ }`}
38
+ />
39
+ </span>
40
+ </div>
41
+ );
42
+ };
@@ -0,0 +1,91 @@
1
+ import { Badge } from "../../badge/Badge";
2
+ import { Icon } from "../../icon/Icon";
3
+ import {
4
+ DataTableDateRangeFilterValue,
5
+ DataTableFilterState,
6
+ } from "../DataTable";
7
+ import "./dataTableFilters.css";
8
+ export type DataTableFiltersProps = {
9
+ currentFilters: DataTableFilterState;
10
+ setCurrentFilters: React.Dispatch<React.SetStateAction<DataTableFilterState>>;
11
+ };
12
+ export const DataTableFilters = ({
13
+ currentFilters,
14
+ setCurrentFilters,
15
+ }: DataTableFiltersProps) => {
16
+ const isDateRangeFilterValue = (
17
+ value: DataTableFilterState[string],
18
+ ): value is DataTableDateRangeFilterValue => {
19
+ return (
20
+ typeof value === "object" &&
21
+ value !== null &&
22
+ "startDate" in value &&
23
+ "endDate" in value
24
+ );
25
+ };
26
+
27
+ const getDisplayValue = (value: DataTableFilterState[string]) => {
28
+ if (isDateRangeFilterValue(value)) {
29
+ if (value.startDate && value.endDate) {
30
+ return `${value.startDate} - ${value.endDate}`;
31
+ }
32
+
33
+ if (value.startDate) {
34
+ return `a partir de ${value.startDate}`;
35
+ }
36
+
37
+ if (value.endDate) {
38
+ return `jusqu'au ${value.endDate}`;
39
+ }
40
+
41
+ return "";
42
+ }
43
+
44
+ return String(value ?? "");
45
+ };
46
+
47
+ const generateColor = (str: string): string => {
48
+ let hash = 0;
49
+ for (let i = 0; i < str.length; i++) {
50
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
51
+ }
52
+
53
+ const hue = hash % 360;
54
+ return `hsl(${hue}, 80%, 30%)`;
55
+ };
56
+
57
+ const removeFilters = (key: string) => {
58
+ setCurrentFilters((prev: any) => {
59
+ const { [key]: _removed, ...rest } = prev;
60
+ return rest;
61
+ });
62
+ };
63
+ if (!currentFilters || Object.keys(currentFilters).length === 0) {
64
+ return null;
65
+ }
66
+
67
+ return (
68
+ <div className="badge-filters">
69
+ {Object.keys(currentFilters).map((key) => {
70
+ const value = getDisplayValue(currentFilters[key]);
71
+ const displayValue =
72
+ value.length > 20 ? value.substring(0, 20) + "..." : value;
73
+
74
+ return (
75
+ <Badge
76
+ onRemove={() => removeFilters(key)}
77
+ className="mr-2"
78
+ title={`${key} : ${displayValue}`}
79
+ color={generateColor(key)}
80
+ key={key}
81
+ />
82
+ );
83
+ })}
84
+
85
+ <Icon
86
+ classIcon="bi-x badge-filters-clear"
87
+ onClick={() => setCurrentFilters({})}
88
+ />
89
+ </div>
90
+ );
91
+ };
@@ -0,0 +1,16 @@
1
+ .badge-filters {
2
+ border-radius: 4px;
3
+ padding: 0.25rem;
4
+ border: 1px solid #dedede;
5
+ width: fit-content;
6
+ display: flex;
7
+ align-items: center;
8
+ position: sticky;
9
+ left: 0;
10
+ .badge-filters-clear {
11
+ padding: 0.05rem;
12
+ border: 1px solid #dedede;
13
+ border-radius: 4px;
14
+ cursor: pointer;
15
+ }
16
+ }
@@ -1,21 +1,10 @@
1
1
  type DataTableLoadingProps = {
2
- columns: any[];
3
- actions: any[];
4
2
  emptyMessage?: string;
5
3
  };
6
- export const DataTableLoading = ({
7
- columns,
8
- actions,
9
- emptyMessage,
10
- }: DataTableLoadingProps) => {
4
+ export const DataTableLoading = ({ emptyMessage }: DataTableLoadingProps) => {
11
5
  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>
6
+ <div className="data-table-empty-state-content mt-3">
7
+ {emptyMessage || "Aucune donnée disponible"}
8
+ </div>
20
9
  );
21
10
  };
@@ -1,53 +1,80 @@
1
- import { Select } from "../../select/Select";
2
- import { dataTableColumnsInterface } from "../dataTable.interface";
1
+ import { useRef, useState } from "react";
2
+ import { DataTableColumnsInterface } from "../dataTable.interface";
3
+ import { DataTableRowOverlay } from "./dataTableRowOverlay/DataTableRowOverlay";
4
+ import { DataTableRowValue } from "./dataTableRowValue/DataTableRowValue";
3
5
 
4
6
  type DataTableRowProps = {
5
- column: dataTableColumnsInterface<any>;
7
+ column: DataTableColumnsInterface<any>;
6
8
  idx: number;
7
9
  row: any;
10
+ onEditColumnByOverlay?: (row: any) => void;
11
+ stickyLeft?: number;
8
12
  };
9
- export const DataTableRow = ({ column, idx, row }: DataTableRowProps) => {
13
+ export const DataTableRow = ({
14
+ column,
15
+ idx,
16
+ row,
17
+ onEditColumnByOverlay,
18
+ stickyLeft,
19
+ }: DataTableRowProps) => {
10
20
  const value = (row as any)[column.id]; // On utilise [column.id] pour accéder aux bonnes propriétés
11
21
  const style = column.onRowStyle ? column.onRowStyle(row) : {};
22
+ const isSticky = stickyLeft !== undefined;
23
+ const [openClickCell, setOpenClickCell] = useState(false);
24
+ const refRow = useRef<HTMLTableCellElement>(null);
25
+ const onClickRenderCell = (e: React.MouseEvent<HTMLTableCellElement>) => {
26
+ console.log("Cell clicked with value:", value, "in row:", row);
27
+ if (column.openClickCell) {
28
+ if (column.handleClickCell) {
29
+ column.handleClickCell(e, row);
30
+ }
31
+ e.stopPropagation();
32
+ setOpenClickCell((prev) => !prev);
33
+ }
34
+ };
12
35
  return (
13
36
  <td
37
+ ref={refRow}
14
38
  style={{
15
39
  minWidth: column.minWidth,
16
- textAlign: column.align || "left",
40
+ textAlign: column.alignText ? column.alignText : column.align || "left",
17
41
  maxWidth: column.maxWidth,
18
42
  width: column.width,
43
+ ...(column.openClickCell || column.renderClickCellComponent
44
+ ? { cursor: "pointer" }
45
+ : {}),
46
+ ...(isSticky
47
+ ? {
48
+ position: "sticky",
49
+ left: stickyLeft,
50
+ zIndex: 2,
51
+ backgroundColor: "#fff",
52
+ }
53
+ : {}),
19
54
  ...style,
20
55
  }}
56
+ onClick={onClickRenderCell}
21
57
  key={`row-${column.id}-${idx}`}
58
+ className={isSticky ? "data-table-sticky-cell" : ""}
22
59
  >
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
60
+ {column.renderComponent ? column.renderComponent(value, row) : null}
61
+ {!column.renderComponent && (
62
+ <DataTableRowValue
63
+ editable={column.onEditable?.(value, row) ?? column.editable ?? false}
64
+ column={column}
65
+ value={value}
66
+ row={row}
67
+ />
68
+ )}
69
+ {openClickCell && column.displayOverlay && refRow.current && (
70
+ <DataTableRowOverlay
71
+ refRow={refRow}
72
+ column={column}
73
+ row={row}
74
+ value={value}
75
+ onEditColumnByOverlay={onEditColumnByOverlay}
76
+ onClose={() => setOpenClickCell(false)}
77
+ />
51
78
  )}
52
79
  </td>
53
80
  );
@@ -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
+ };
@@ -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={onChangeExpand}
36
- currentExpand={currentExpand}
21
+ onChange={props.onChange}
22
+ currentExpand={props.currentItem}
37
23
  />
38
24
  ))}
39
25
  </div>
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useState } from "react";
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: (item: ExpandInterface) => void;
10
+ onChange?: (item: ExpandInterface) => void;
11
11
  };
12
12
  export const Expand = ({
13
13
  currentExpand,
@@ -16,29 +16,17 @@ export const Expand = ({
16
16
  showArrow = true,
17
17
  onChange,
18
18
  }: ExpandProps): JSX.Element => {
19
- const [active, setActive] = useState<boolean>(false);
20
- useEffect(() => {
21
- if (item && currentExpand) {
22
- if (currentExpand.id === item.id) {
23
- if (!active) {
24
- setActive(true);
25
- }
26
- } else {
27
- setActive(false);
28
- }
29
- } else {
30
- setActive(false);
31
- }
32
- }, [currentExpand, setActive, item]);
33
-
19
+ const active = currentExpand?.id === item.id;
20
+ console.log("render expand", item.title, "active", active);
34
21
  const handleChange = useCallback(
35
22
  (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
36
23
  e.stopPropagation();
37
24
  if (onChange) {
25
+ console.log("expand", item);
38
26
  onChange(item);
39
27
  }
40
28
  },
41
- [onChange, item]
29
+ [onChange, item],
42
30
  );
43
31
  return (
44
32
  <div