kelt-ui-kit-react 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +46 -46
  2. package/dist/App.d.ts +2 -3
  3. package/dist/App.menu.d.ts +10 -10
  4. package/dist/App.routes.d.ts +1 -1
  5. package/dist/_core/hooks/ImageChecker.d.ts +5 -6
  6. package/dist/_core/hooks/useIsMobile.d.ts +1 -1
  7. package/dist/action/Action.view.d.ts +1 -1
  8. package/dist/action/ButtonAction.d.ts +8 -9
  9. package/dist/badge/Badge.d.ts +8 -9
  10. package/dist/badge/Badge.view.d.ts +1 -1
  11. package/dist/button/Button.d.ts +1 -2
  12. package/dist/button/Button.view.d.ts +1 -1
  13. package/dist/button/button.interface.d.ts +17 -18
  14. package/dist/button/buttonActions/ButtonActions.d.ts +10 -11
  15. package/dist/card/Card.d.ts +12 -13
  16. package/dist/card/Card.view.d.ts +1 -1
  17. package/dist/card/card.interface.d.ts +10 -10
  18. package/dist/card/cardAction/CardAction.d.ts +13 -14
  19. package/dist/card/cardAction.interface.d.ts +8 -9
  20. package/dist/card/hook/useCardInteractions.d.ts +8 -8
  21. package/dist/carousel/Carousel.d.ts +14 -15
  22. package/dist/carousel/Carousel.view.d.ts +1 -1
  23. package/dist/damier/Damier.d.ts +9 -10
  24. package/dist/damier/Damier.view.d.ts +1 -1
  25. package/dist/damier/damierCell/DamierCell.d.ts +6 -7
  26. package/dist/damier/damierCell/damierCell.interface.d.ts +6 -6
  27. package/dist/dataTable/DataTable.d.ts +17 -16
  28. package/dist/dataTable/DataTable.view.d.ts +1 -1
  29. package/dist/dataTable/dataTable.interface.d.ts +30 -31
  30. package/dist/datePicker/DatePicker.d.ts +7 -8
  31. package/dist/datePicker/DatePicker.view.d.ts +1 -1
  32. package/dist/expands/Expands.d.ts +9 -10
  33. package/dist/expands/Expands.view.d.ts +1 -1
  34. package/dist/expands/expand/expand.d.ts +8 -9
  35. package/dist/expands/expand/expand.interface.d.ts +9 -9
  36. package/dist/filAriane/FilAriane.d.ts +8 -9
  37. package/dist/filAriane/FilAriane.view.d.ts +1 -1
  38. package/dist/filAriane/filAriane.interface.d.ts +6 -6
  39. package/dist/form/Form.d.ts +23 -24
  40. package/dist/form/Form.view.d.ts +1 -1
  41. package/dist/form/form.enum.d.ts +11 -11
  42. package/dist/form/form.interface.d.ts +29 -30
  43. package/dist/form/textArea/TextArea.d.ts +12 -13
  44. package/dist/form/textArea/TextArea.view.d.ts +1 -1
  45. package/dist/grid/Grid.d.ts +7 -8
  46. package/dist/grid/Grid.view.d.ts +1 -1
  47. package/dist/grid/col/Col.d.ts +10 -10
  48. package/dist/grid/col/colStyled/ColStyled.d.ts +9 -9
  49. package/dist/grid/container/Container.d.ts +5 -6
  50. package/dist/grid/grid.interface.d.ts +8 -8
  51. package/dist/grid/row/Row.d.ts +7 -8
  52. package/dist/header/Header.d.ts +1 -2
  53. package/dist/header/Header.view.d.ts +1 -1
  54. package/dist/header/header.interface.d.ts +9 -9
  55. package/dist/home/Home.d.ts +1 -1
  56. package/dist/icon/Icon.d.ts +1 -2
  57. package/dist/icon/Icons.view.d.ts +1 -1
  58. package/dist/icon/icon.interface.d.ts +4 -5
  59. package/dist/icon/iconSize.enum.d.ts +7 -7
  60. package/dist/index.d.ts +31 -32
  61. package/dist/index.html +18 -18
  62. package/dist/index.js +902 -885
  63. package/dist/loader/Loader.d.ts +7 -8
  64. package/dist/loader/Loader.view.d.ts +1 -1
  65. package/dist/main.d.ts +0 -1
  66. package/dist/manifest.json +25 -25
  67. package/dist/menus/Menus.d.ts +5 -6
  68. package/dist/menus/Menus.view.d.ts +1 -1
  69. package/dist/menus/menu/Menu.d.ts +6 -7
  70. package/dist/menus/menu/menu.interface.d.ts +10 -10
  71. package/dist/modal/Modal.d.ts +12 -13
  72. package/dist/modal/Modal.view.d.ts +1 -1
  73. package/dist/notFound/NotFound.d.ts +1 -1
  74. package/dist/overlayPanel/OverlayPanel.d.ts +18 -19
  75. package/dist/overlayPanel/OverlayPanel.view.d.ts +1 -1
  76. package/dist/overlayPanel/overlay.context.d.ts +9 -10
  77. package/dist/overlayPanel/overlayPanelStyled/OverlayPanelStyled.d.ts +7 -7
  78. package/dist/quantity/Quantity.d.ts +10 -11
  79. package/dist/robots.txt +3 -3
  80. package/dist/search/Search.d.ts +21 -22
  81. package/dist/search/Search.view.d.ts +1 -1
  82. package/dist/select/Select.d.ts +13 -14
  83. package/dist/select/Select.view.d.ts +1 -1
  84. package/dist/select/selectOption.interface.d.ts +4 -4
  85. package/dist/sidebar/Sidebar.d.ts +12 -13
  86. package/dist/sidebar/Sidebar.view.d.ts +1 -1
  87. package/dist/sidebarData/SidebarData.d.ts +6 -7
  88. package/dist/sidebarData/SidebarData.view.d.ts +1 -1
  89. package/dist/style.css +1 -1
  90. package/dist/toaster/Toaster.d.ts +1 -2
  91. package/dist/toaster/Toaster.view.d.ts +1 -1
  92. package/dist/toaster/store/useToasterStore.d.ts +18 -18
  93. package/index.html +19 -19
  94. package/package.json +55 -55
  95. package/public/index.html +18 -18
  96. package/public/manifest.json +25 -25
  97. package/public/robots.txt +3 -3
  98. package/src/App.css +11 -11
  99. package/src/App.menu.tsx +209 -209
  100. package/src/App.routes.tsx +16 -16
  101. package/src/App.tsx +28 -28
  102. package/src/_core/hooks/ImageChecker.tsx +26 -26
  103. package/src/_core/hooks/useIsMobile.ts +18 -18
  104. package/src/action/Action.view.tsx +21 -21
  105. package/src/action/ButtonAction.tsx +32 -32
  106. package/src/action/action.css +20 -20
  107. package/src/badge/Badge.tsx +34 -34
  108. package/src/badge/Badge.view.tsx +15 -15
  109. package/src/badge/badge.css +55 -55
  110. package/src/button/Button.tsx +44 -44
  111. package/src/button/Button.view.tsx +61 -61
  112. package/src/button/button.css +53 -53
  113. package/src/button/button.interface.tsx +20 -20
  114. package/src/button/buttonActions/ButtonActions.tsx +101 -101
  115. package/src/card/Card.tsx +125 -125
  116. package/src/card/Card.view.tsx +73 -73
  117. package/src/card/card.css +145 -145
  118. package/src/card/card.interface.tsx +9 -9
  119. package/src/card/cardAction/CardAction.tsx +135 -135
  120. package/src/card/cardAction/cardAction.css +10 -10
  121. package/src/card/cardAction.interface.tsx +10 -10
  122. package/src/card/hook/useCardInteractions.tsx +30 -30
  123. package/src/carousel/Carousel.css +44 -44
  124. package/src/carousel/Carousel.tsx +115 -115
  125. package/src/carousel/Carousel.view.tsx +13 -13
  126. package/src/damier/Damier.tsx +55 -55
  127. package/src/damier/Damier.view.tsx +31 -31
  128. package/src/damier/damier.css +44 -44
  129. package/src/damier/damierCell/DamierCell.tsx +18 -18
  130. package/src/damier/damierCell/damierCell.interface.tsx +5 -5
  131. package/src/dataTable/DataTable.tsx +236 -202
  132. package/src/dataTable/DataTable.view.tsx +59 -59
  133. package/src/dataTable/dataTable.css +16 -14
  134. package/src/dataTable/dataTable.interface.ts +29 -29
  135. package/src/datePicker/DatePicker.tsx +110 -110
  136. package/src/datePicker/DatePicker.view.tsx +9 -9
  137. package/src/datePicker/datePicker.css +77 -77
  138. package/src/expands/Expands.tsx +42 -42
  139. package/src/expands/Expands.view.tsx +90 -90
  140. package/src/expands/expand/expand.interface.tsx +8 -8
  141. package/src/expands/expand/expand.tsx +75 -75
  142. package/src/expands/expands.css +97 -97
  143. package/src/filAriane/FilAriane.tsx +57 -57
  144. package/src/filAriane/FilAriane.view.tsx +28 -28
  145. package/src/filAriane/filAriane.css +22 -22
  146. package/src/filAriane/filAriane.interface.tsx +6 -6
  147. package/src/form/Form.tsx +175 -175
  148. package/src/form/Form.view.tsx +47 -47
  149. package/src/form/form.css +37 -37
  150. package/src/form/form.enum.ts +11 -11
  151. package/src/form/form.interface.tsx +31 -31
  152. package/src/form/textArea/TextArea.tsx +53 -53
  153. package/src/form/textArea/TextArea.view.tsx +34 -34
  154. package/src/form/textArea/textArea.css +9 -9
  155. package/src/grid/Grid.tsx +21 -21
  156. package/src/grid/Grid.view.tsx +24 -24
  157. package/src/grid/col/Col.tsx +15 -15
  158. package/src/grid/col/colStyled/ColStyled.tsx +41 -41
  159. package/src/grid/container/Container.tsx +8 -8
  160. package/src/grid/container/container.css +5 -5
  161. package/src/grid/grid.interface.tsx +7 -7
  162. package/src/grid/row/Row.tsx +12 -12
  163. package/src/grid/row/row.css +18 -18
  164. package/src/header/Header.tsx +51 -51
  165. package/src/header/Header.view.tsx +5 -5
  166. package/src/header/header.css +26 -26
  167. package/src/header/header.interface.tsx +8 -8
  168. package/src/home/Home.tsx +3 -3
  169. package/src/icon/Icon.tsx +6 -6
  170. package/src/icon/Icons.view.tsx +29 -29
  171. package/src/icon/icon.css +20 -20
  172. package/src/icon/icon.interface.tsx +6 -6
  173. package/src/icon/iconSize.enum.ts +7 -7
  174. package/src/index.css +502 -502
  175. package/src/index.ts +33 -33
  176. package/src/loader/Loader.tsx +37 -37
  177. package/src/loader/Loader.view.tsx +20 -20
  178. package/src/loader/loader.css +30 -30
  179. package/src/main.tsx +10 -10
  180. package/src/menus/Menus.tsx +42 -42
  181. package/src/menus/Menus.view.tsx +39 -39
  182. package/src/menus/menu/Menu.tsx +17 -17
  183. package/src/menus/menu/menu.interface.tsx +9 -9
  184. package/src/menus/menus.css +47 -47
  185. package/src/modal/Modal.tsx +53 -53
  186. package/src/modal/Modal.view.tsx +25 -25
  187. package/src/modal/modal.css +69 -65
  188. package/src/notFound/NotFound.tsx +3 -3
  189. package/src/overlayPanel/OverlayPanel.tsx +189 -189
  190. package/src/overlayPanel/OverlayPanel.view.tsx +25 -25
  191. package/src/overlayPanel/overlay.context.tsx +28 -28
  192. package/src/overlayPanel/overlayPanel.css +35 -35
  193. package/src/overlayPanel/overlayPanelStyled/OverlayPanelStyled.tsx +18 -18
  194. package/src/quantity/Quantity.tsx +103 -103
  195. package/src/quantity/quantity.css +26 -26
  196. package/src/search/Search.tsx +161 -161
  197. package/src/search/Search.view.tsx +14 -14
  198. package/src/search/search.css +59 -59
  199. package/src/select/Select.tsx +53 -53
  200. package/src/select/Select.view.tsx +71 -71
  201. package/src/select/select.css +51 -51
  202. package/src/select/selectOption.interface.ts +4 -4
  203. package/src/sidebar/Sidebar.tsx +111 -111
  204. package/src/sidebar/Sidebar.view.tsx +17 -17
  205. package/src/sidebar/sidebar.css +87 -87
  206. package/src/sidebarData/SidebarData.tsx +19 -19
  207. package/src/sidebarData/SidebarData.view.tsx +19 -19
  208. package/src/sidebarData/sidebarData.css +27 -27
  209. package/src/toaster/Toaster.tsx +47 -47
  210. package/src/toaster/Toaster.view.tsx +3 -3
  211. package/src/toaster/store/useToasterStore.tsx +39 -39
  212. package/src/toaster/toaster.css +57 -57
  213. package/tsconfig.json +28 -28
  214. package/vite.config.ts +20 -20
  215. package/vite.config.ts.timestamp-1733262892554-a13dfef6e8a29.mjs +24 -24
@@ -1,71 +1,71 @@
1
- import { useMemo } from "react";
2
- import { Select } from "./Select";
3
-
4
- export const SelectView = () => {
5
- const selectData = useMemo(() => {
6
- return [
7
- {
8
- id: "select",
9
- title: "Select",
10
- className: "select-component",
11
- options: [
12
- { value: "option1", label: "Option 1" },
13
- { value: "option2", label: "Option 2" },
14
- { value: "option3", label: "Option 3" },
15
- ],
16
- },
17
- {
18
- id: "select-disabled",
19
- title: "Select Disabled",
20
- className: "select-component",
21
- disabled: true,
22
- options: [
23
- { value: "option1", label: "Option 1" },
24
- { value: "option2", label: "Option 2" },
25
- { value: "option3", label: "Option 3" },
26
- ],
27
- },
28
- {
29
- id: "select-placeholder",
30
- title: "Select Placeholder",
31
- className: "select-component",
32
- placeholder: "Select an option",
33
- options: [
34
- { value: "option1", label: "Option 1" },
35
- { value: "option2", label: "Option 2" },
36
- { value: "option3", label: "Option 3" },
37
- ],
38
- },
39
- {
40
- id: "select-default-value",
41
- title: "Select Default Value",
42
- className: "select-component",
43
- defaultValue: "option2",
44
- options: [
45
- { value: "option1", label: "Option 1" },
46
- { value: "option2", label: "Option 2" },
47
- { value: "option3", label: "Option 3" },
48
- ],
49
- },
50
- {
51
- id: "select-value",
52
- title: "Select Value",
53
- className: "select-component",
54
- value: "option3",
55
- options: [
56
- { value: "option1", label: "Option 1" },
57
- { value: "option2", label: "Option 2" },
58
- { value: "option3", label: "Option 3" },
59
- ],
60
- },
61
- ];
62
- }, []);
63
-
64
- return (
65
- <>
66
- {selectData.map((data) => (
67
- <Select {...data} />
68
- ))}
69
- </>
70
- );
71
- };
1
+ import { useMemo } from "react";
2
+ import { Select } from "./Select";
3
+
4
+ export const SelectView = () => {
5
+ const selectData = useMemo(() => {
6
+ return [
7
+ {
8
+ id: "select",
9
+ title: "Select",
10
+ className: "select-component",
11
+ options: [
12
+ { value: "option1", label: "Option 1" },
13
+ { value: "option2", label: "Option 2" },
14
+ { value: "option3", label: "Option 3" },
15
+ ],
16
+ },
17
+ {
18
+ id: "select-disabled",
19
+ title: "Select Disabled",
20
+ className: "select-component",
21
+ disabled: true,
22
+ options: [
23
+ { value: "option1", label: "Option 1" },
24
+ { value: "option2", label: "Option 2" },
25
+ { value: "option3", label: "Option 3" },
26
+ ],
27
+ },
28
+ {
29
+ id: "select-placeholder",
30
+ title: "Select Placeholder",
31
+ className: "select-component",
32
+ placeholder: "Select an option",
33
+ options: [
34
+ { value: "option1", label: "Option 1" },
35
+ { value: "option2", label: "Option 2" },
36
+ { value: "option3", label: "Option 3" },
37
+ ],
38
+ },
39
+ {
40
+ id: "select-default-value",
41
+ title: "Select Default Value",
42
+ className: "select-component",
43
+ defaultValue: "option2",
44
+ options: [
45
+ { value: "option1", label: "Option 1" },
46
+ { value: "option2", label: "Option 2" },
47
+ { value: "option3", label: "Option 3" },
48
+ ],
49
+ },
50
+ {
51
+ id: "select-value",
52
+ title: "Select Value",
53
+ className: "select-component",
54
+ value: "option3",
55
+ options: [
56
+ { value: "option1", label: "Option 1" },
57
+ { value: "option2", label: "Option 2" },
58
+ { value: "option3", label: "Option 3" },
59
+ ],
60
+ },
61
+ ];
62
+ }, []);
63
+
64
+ return (
65
+ <>
66
+ {selectData.map((data) => (
67
+ <Select {...data} />
68
+ ))}
69
+ </>
70
+ );
71
+ };
@@ -1,51 +1,51 @@
1
- .select-container {
2
- position: relative;
3
- &::after,
4
- &::before {
5
- --size: 0.3rem;
6
- content: "";
7
- position: absolute;
8
- right: 1rem;
9
- pointer-events: none;
10
- }
11
-
12
- &::before {
13
- border-left: var(--size) solid transparent;
14
- border-right: var(--size) solid transparent;
15
- border-bottom: var(--size) solid black;
16
- top: 40%;
17
- }
18
-
19
- &::after {
20
- border-left: var(--size) solid transparent;
21
- border-right: var(--size) solid transparent;
22
- border-top: var(--size) solid black;
23
- top: 55%;
24
- }
25
- .select-container-label {
26
- font-weight: bold;
27
- color: #333;
28
- margin-bottom: 2px;
29
- }
30
- .select-container-select {
31
- appearance: none;
32
- width: 100%;
33
- font-size: 1rem;
34
- padding: 0.675em 6em 0.675em 1em;
35
- background-color: #fff;
36
- border: 1px solid #caced1;
37
- border-radius: 0.25rem;
38
- color: #000;
39
- cursor: pointer;
40
- &:disabled {
41
- background-color: #e9ecef;
42
- color: #6c757d;
43
- cursor: not-allowed;
44
- }
45
- &:focus {
46
- border-color: #007bff;
47
- outline: none;
48
- background-color: #fff;
49
- }
50
- }
51
- }
1
+ .select-container {
2
+ position: relative;
3
+ &::after,
4
+ &::before {
5
+ --size: 0.3rem;
6
+ content: "";
7
+ position: absolute;
8
+ right: 1rem;
9
+ pointer-events: none;
10
+ }
11
+
12
+ &::before {
13
+ border-left: var(--size) solid transparent;
14
+ border-right: var(--size) solid transparent;
15
+ border-bottom: var(--size) solid black;
16
+ top: 40%;
17
+ }
18
+
19
+ &::after {
20
+ border-left: var(--size) solid transparent;
21
+ border-right: var(--size) solid transparent;
22
+ border-top: var(--size) solid black;
23
+ top: 55%;
24
+ }
25
+ .select-container-label {
26
+ font-weight: bold;
27
+ color: #333;
28
+ margin-bottom: 2px;
29
+ }
30
+ .select-container-select {
31
+ appearance: none;
32
+ width: 100%;
33
+ font-size: 1rem;
34
+ padding: 0.675em 6em 0.675em 1em;
35
+ background-color: #fff;
36
+ border: 1px solid #caced1;
37
+ border-radius: 0.25rem;
38
+ color: #000;
39
+ cursor: pointer;
40
+ &:disabled {
41
+ background-color: #e9ecef;
42
+ color: #6c757d;
43
+ cursor: not-allowed;
44
+ }
45
+ &:focus {
46
+ border-color: #007bff;
47
+ outline: none;
48
+ background-color: #fff;
49
+ }
50
+ }
51
+ }
@@ -1,4 +1,4 @@
1
- export interface SelectOptionInterface {
2
- value: string;
3
- label: string;
4
- }
1
+ export interface SelectOptionInterface {
2
+ value: string;
3
+ label: string;
4
+ }
@@ -1,111 +1,111 @@
1
- import { useCallback, useEffect, useRef, useState } from "react";
2
- import ReactDOM from "react-dom";
3
- import { Icon } from "../icon/Icon";
4
- import "./sidebar.css";
5
-
6
- export interface SidebarProps {
7
- id?: string;
8
- open?: boolean;
9
- title?: string;
10
- children?: React.ReactNode;
11
- className?: string;
12
- width?: string;
13
- displayOverlay?: boolean;
14
- closeOnClickOutside?: boolean;
15
- onClose?: (close: boolean) => void;
16
- }
17
-
18
- export const Sidebar = ({
19
- open,
20
- children,
21
- title,
22
- onClose,
23
- className,
24
- id,
25
- width,
26
- closeOnClickOutside = true,
27
- displayOverlay = true,
28
- }: SidebarProps): JSX.Element => {
29
- const [isOpen, setIsOpen] = useState(open || false);
30
- const sidebarRef = useRef<HTMLDivElement | null>(null);
31
- const rootRef = useRef<HTMLDivElement | null>(null);
32
-
33
- // Créer le conteneur une seule fois
34
- useEffect(() => {
35
- if (!rootRef.current) {
36
- rootRef.current = document.createElement("div");
37
- rootRef.current.id = `sidebar-root-${id || crypto.randomUUID()}`;
38
- document.body.appendChild(rootRef.current);
39
- }
40
-
41
- return () => {
42
- // Nettoyage lors du démontage
43
- if (rootRef.current && rootRef.current.parentNode) {
44
- document.body.removeChild(rootRef.current);
45
- rootRef.current = null;
46
- }
47
- };
48
- }, [id]);
49
-
50
- // Synchroniser l'état `isOpen` avec la prop `open`
51
- useEffect(() => {
52
- setIsOpen(open || false);
53
- }, [open]);
54
-
55
- const toggleSidebar = useCallback(() => {
56
- setIsOpen(false);
57
- if (onClose) {
58
- onClose(false);
59
- }
60
- }, [onClose]);
61
-
62
- const handleClickOutside = useCallback(
63
- (event: MouseEvent) => {
64
- if (!closeOnClickOutside) return;
65
- if (
66
- sidebarRef.current &&
67
- !sidebarRef.current.contains(event.target as Node)
68
- ) {
69
- toggleSidebar();
70
- }
71
- },
72
- [toggleSidebar, closeOnClickOutside]
73
- );
74
-
75
- useEffect(() => {
76
- if (isOpen) {
77
- document.addEventListener("mousedown", handleClickOutside);
78
- } else {
79
- document.removeEventListener("mousedown", handleClickOutside);
80
- }
81
-
82
- return () => {
83
- document.removeEventListener("mousedown", handleClickOutside);
84
- };
85
- }, [isOpen, handleClickOutside]);
86
-
87
- if (!rootRef.current) {
88
- return <></>; // Ne pas tenter de rendre si le conteneur n'existe pas
89
- }
90
-
91
- return ReactDOM.createPortal(
92
- <>
93
- {isOpen && displayOverlay && <div className="overlay"></div>}
94
- <div
95
- ref={sidebarRef}
96
- style={width ? { width: width } : {}}
97
- className={`sidebar ${isOpen ? "open" : "closed"} ${className ?? ""}`}
98
- >
99
- <div className="sidebar-header">
100
- {title && <h2 className="flex-1">{title}</h2>}
101
- <button className="toggle-btn" onClick={toggleSidebar}>
102
- <Icon classIcon="bi-x-lg" />
103
- </button>
104
- </div>
105
-
106
- {children && children}
107
- </div>
108
- </>,
109
- rootRef.current
110
- );
111
- };
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import ReactDOM from "react-dom";
3
+ import { Icon } from "../icon/Icon";
4
+ import "./sidebar.css";
5
+
6
+ export interface SidebarProps {
7
+ id?: string;
8
+ open?: boolean;
9
+ title?: string;
10
+ children?: React.ReactNode;
11
+ className?: string;
12
+ width?: string;
13
+ displayOverlay?: boolean;
14
+ closeOnClickOutside?: boolean;
15
+ onClose?: (close: boolean) => void;
16
+ }
17
+
18
+ export const Sidebar = ({
19
+ open,
20
+ children,
21
+ title,
22
+ onClose,
23
+ className,
24
+ id,
25
+ width,
26
+ closeOnClickOutside = true,
27
+ displayOverlay = true,
28
+ }: SidebarProps): JSX.Element => {
29
+ const [isOpen, setIsOpen] = useState(open || false);
30
+ const sidebarRef = useRef<HTMLDivElement | null>(null);
31
+ const rootRef = useRef<HTMLDivElement | null>(null);
32
+
33
+ // Créer le conteneur une seule fois
34
+ useEffect(() => {
35
+ if (!rootRef.current) {
36
+ rootRef.current = document.createElement("div");
37
+ rootRef.current.id = `sidebar-root-${id || crypto.randomUUID()}`;
38
+ document.body.appendChild(rootRef.current);
39
+ }
40
+
41
+ return () => {
42
+ // Nettoyage lors du démontage
43
+ if (rootRef.current && rootRef.current.parentNode) {
44
+ document.body.removeChild(rootRef.current);
45
+ rootRef.current = null;
46
+ }
47
+ };
48
+ }, [id]);
49
+
50
+ // Synchroniser l'état `isOpen` avec la prop `open`
51
+ useEffect(() => {
52
+ setIsOpen(open || false);
53
+ }, [open]);
54
+
55
+ const toggleSidebar = useCallback(() => {
56
+ setIsOpen(false);
57
+ if (onClose) {
58
+ onClose(false);
59
+ }
60
+ }, [onClose]);
61
+
62
+ const handleClickOutside = useCallback(
63
+ (event: MouseEvent) => {
64
+ if (!closeOnClickOutside) return;
65
+ if (
66
+ sidebarRef.current &&
67
+ !sidebarRef.current.contains(event.target as Node)
68
+ ) {
69
+ toggleSidebar();
70
+ }
71
+ },
72
+ [toggleSidebar, closeOnClickOutside]
73
+ );
74
+
75
+ useEffect(() => {
76
+ if (isOpen) {
77
+ document.addEventListener("mousedown", handleClickOutside);
78
+ } else {
79
+ document.removeEventListener("mousedown", handleClickOutside);
80
+ }
81
+
82
+ return () => {
83
+ document.removeEventListener("mousedown", handleClickOutside);
84
+ };
85
+ }, [isOpen, handleClickOutside]);
86
+
87
+ if (!rootRef.current) {
88
+ return <></>; // Ne pas tenter de rendre si le conteneur n'existe pas
89
+ }
90
+
91
+ return ReactDOM.createPortal(
92
+ <>
93
+ {isOpen && displayOverlay && <div className="overlay"></div>}
94
+ <div
95
+ ref={sidebarRef}
96
+ style={width ? { width: width } : {}}
97
+ className={`sidebar ${isOpen ? "open" : "closed"} ${className ?? ""}`}
98
+ >
99
+ <div className="sidebar-header">
100
+ {title && <h2 className="flex-1">{title}</h2>}
101
+ <button className="toggle-btn" onClick={toggleSidebar}>
102
+ <Icon classIcon="bi-x-lg" />
103
+ </button>
104
+ </div>
105
+
106
+ {children && children}
107
+ </div>
108
+ </>,
109
+ rootRef.current
110
+ );
111
+ };
@@ -1,17 +1,17 @@
1
- import { useCallback, useState } from "react";
2
- import { Button } from "../button/Button";
3
- import { Sidebar } from "./Sidebar";
4
-
5
- export const SidebarView = () => {
6
- const [isOpen, setIsOpen] = useState(false);
7
- const onClick = useCallback(() => {
8
- setIsOpen(true);
9
- }, [setIsOpen]);
10
-
11
- return (
12
- <>
13
- <Button title={"open me"} onClick={onClick}></Button>
14
- <Sidebar onClose={setIsOpen} title="Menu" open={isOpen} />
15
- </>
16
- );
17
- };
1
+ import { useCallback, useState } from "react";
2
+ import { Button } from "../button/Button";
3
+ import { Sidebar } from "./Sidebar";
4
+
5
+ export const SidebarView = () => {
6
+ const [isOpen, setIsOpen] = useState(false);
7
+ const onClick = useCallback(() => {
8
+ setIsOpen(true);
9
+ }, [setIsOpen]);
10
+
11
+ return (
12
+ <>
13
+ <Button title={"open me"} onClick={onClick}></Button>
14
+ <Sidebar onClose={setIsOpen} title="Menu" open={isOpen} />
15
+ </>
16
+ );
17
+ };