allaw-ui 3.6.8 → 3.7.0

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.
@@ -8,6 +8,10 @@ interface ImageConfig {
8
8
  className?: string;
9
9
  style?: React.CSSProperties;
10
10
  }
11
+ interface CustomContentConfig {
12
+ component: React.ComponentType<any>;
13
+ props?: Record<string, unknown>;
14
+ }
11
15
  export interface ModalProps {
12
16
  show: boolean;
13
17
  title: string;
@@ -19,6 +23,12 @@ export interface ModalProps {
19
23
  isDanger?: boolean;
20
24
  confirmIconName?: string;
21
25
  imageConfig?: ImageConfig;
26
+ children?: React.ReactNode;
27
+ customContent?: CustomContentConfig;
28
+ renderContent?: (modalProps: {
29
+ isOpen: boolean;
30
+ onClose: () => void;
31
+ }) => React.ReactNode;
22
32
  verticalOffset?: {
23
33
  top?: number;
24
34
  bottom?: number;
@@ -17,7 +17,7 @@ import SecondaryButton from "../../atoms/buttons/SecondaryButton";
17
17
  import Heading from "../../atoms/typography/Heading";
18
18
  import Paragraph from "../../atoms/typography/Paragraph";
19
19
  var Modal = function (_a) {
20
- var show = _a.show, title = _a.title, description = _a.description, confirmLabel = _a.confirmLabel, cancelLabel = _a.cancelLabel, onConfirm = _a.onConfirm, onCancel = _a.onCancel, _b = _a.isDanger, isDanger = _b === void 0 ? false : _b, _c = _a.confirmIconName, confirmIconName = _c === void 0 ? "allaw-icon-check" : _c, imageConfig = _a.imageConfig, verticalOffset = _a.verticalOffset, horizontalOffset = _a.horizontalOffset;
20
+ var show = _a.show, title = _a.title, description = _a.description, confirmLabel = _a.confirmLabel, cancelLabel = _a.cancelLabel, onConfirm = _a.onConfirm, onCancel = _a.onCancel, _b = _a.isDanger, isDanger = _b === void 0 ? false : _b, _c = _a.confirmIconName, confirmIconName = _c === void 0 ? "allaw-icon-check" : _c, imageConfig = _a.imageConfig, children = _a.children, customContent = _a.customContent, renderContent = _a.renderContent, verticalOffset = _a.verticalOffset, horizontalOffset = _a.horizontalOffset;
21
21
  var _d = useState(false), isVisible = _d[0], setIsVisible = _d[1];
22
22
  var _e = useState(false), imgError = _e[0], setImgError = _e[1];
23
23
  var portalContainerRef = useRef(null);
@@ -68,6 +68,23 @@ var Modal = function (_a) {
68
68
  var handleImageError = function () {
69
69
  setImgError(true);
70
70
  };
71
+ var renderModalContent = function () {
72
+ return (React.createElement(React.Fragment, null,
73
+ React.createElement("div", { className: style.modalHeadingWrapper },
74
+ React.createElement(Heading, { text: title, variant: "h4", color: "noir", align: "left" })),
75
+ React.createElement("div", { className: style.modalParagraphWrapper },
76
+ React.createElement(Paragraph, { text: description, variant: "medium", size: "default", className: style.modalParagraph })),
77
+ renderContent && (React.createElement("div", { className: style.modalCustomWrapper }, renderContent({ isOpen: show, onClose: onCancel }))),
78
+ !renderContent && customContent && (React.createElement("div", { className: style.modalCustomWrapper },
79
+ React.createElement(customContent.component, __assign({}, (customContent.props || {}))))),
80
+ !renderContent && !customContent && children && (React.createElement("div", { className: style.modalCustomWrapper }, children)),
81
+ !renderContent &&
82
+ !customContent &&
83
+ !children &&
84
+ imageConfig &&
85
+ !imgError && (React.createElement("div", { className: "".concat(style.modalImageWrapper, " ").concat(imageConfig.className || ""), style: __assign({ padding: imageConfig.padding }, imageConfig.style) },
86
+ React.createElement("img", { src: imageConfig.url, alt: imageConfig.alt || "", width: imageConfig.width, height: imageConfig.height, onError: handleImageError, className: style.modalImage })))));
87
+ };
71
88
  if (!show || !isVisible || !portalContainerRef.current)
72
89
  return null;
73
90
  var modalContent = (React.createElement("div", { className: "".concat(style.modalOverlay, " ").concat(isVisible ? style.visible : "", " ").concat(show ? style.modal : ""), onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, style: {
@@ -83,12 +100,7 @@ var Modal = function (_a) {
83
100
  : undefined,
84
101
  } },
85
102
  React.createElement("div", { className: "".concat(style.modalContent, " ").concat(show ? style.modal : ""), ref: modalContentRef },
86
- React.createElement("div", { className: style.modalHeadingWrapper },
87
- React.createElement(Heading, { text: title, variant: "h4", color: "noir", align: "left" })),
88
- React.createElement("div", { className: style.modalParagraphWrapper },
89
- React.createElement(Paragraph, { text: description, variant: "medium", size: "default", className: style.modalParagraph })),
90
- imageConfig && !imgError && (React.createElement("div", { className: "".concat(style.modalImageWrapper, " ").concat(imageConfig.className || ""), style: __assign({ padding: imageConfig.padding }, imageConfig.style) },
91
- React.createElement("img", { src: imageConfig.url, alt: imageConfig.alt || "", width: imageConfig.width, height: imageConfig.height, onError: handleImageError, className: style.modalImage }))),
103
+ renderModalContent(),
92
104
  React.createElement("div", { className: style.modalButtons },
93
105
  cancelLabel && (React.createElement(SecondaryButton, { label: cancelLabel, onClick: onCancel, startIconName: "allaw-icon-close", startIcon: true })),
94
106
  React.createElement(PrimaryButton, { label: confirmLabel, variant: isDanger ? "warning" : "default", onClick: onConfirm, startIconName: confirmIconName, startIcon: true })))));
@@ -286,6 +286,11 @@
286
286
  border-radius: 8px;
287
287
  }
288
288
 
289
+ .modalCustomWrapper {
290
+ width: 100%;
291
+ margin-bottom: 2.5rem;
292
+ }
293
+
289
294
  .modalParagraph {
290
295
  text-align: left;
291
296
  }
@@ -3,68 +3,89 @@ declare namespace _default {
3
3
  export { Modal as component };
4
4
  export let tags: string[];
5
5
  export namespace argTypes {
6
- export namespace verticalOffset {
7
- namespace control {
8
- let type: string;
9
- }
6
+ export namespace children {
7
+ let control: boolean;
10
8
  let description: string;
11
9
  }
12
- export namespace horizontalOffset {
10
+ export namespace customContent {
13
11
  export namespace control_1 {
14
- let type_1: string;
15
- export { type_1 as type };
12
+ let type: string;
16
13
  }
17
14
  export { control_1 as control };
18
15
  let description_1: string;
19
16
  export { description_1 as description };
20
17
  }
21
- export namespace show {
22
- let control_2: string;
18
+ export namespace renderContent {
19
+ let control_2: boolean;
23
20
  export { control_2 as control };
24
21
  let description_2: string;
25
22
  export { description_2 as description };
26
23
  }
27
- export namespace title_1 {
28
- let control_3: string;
24
+ export namespace verticalOffset {
25
+ export namespace control_3 {
26
+ let type_1: string;
27
+ export { type_1 as type };
28
+ }
29
29
  export { control_3 as control };
30
30
  let description_3: string;
31
31
  export { description_3 as description };
32
32
  }
33
- export { title_1 as title };
34
- export namespace description_4 {
35
- let control_4: string;
33
+ export namespace horizontalOffset {
34
+ export namespace control_4 {
35
+ let type_2: string;
36
+ export { type_2 as type };
37
+ }
36
38
  export { control_4 as control };
37
- let description_5: string;
38
- export { description_5 as description };
39
+ let description_4: string;
40
+ export { description_4 as description };
39
41
  }
40
- export { description_4 as description };
41
- export namespace confirmLabel {
42
+ export namespace show {
42
43
  let control_5: string;
43
44
  export { control_5 as control };
44
- let description_6: string;
45
- export { description_6 as description };
45
+ let description_5: string;
46
+ export { description_5 as description };
46
47
  }
47
- export namespace cancelLabel {
48
+ export namespace title_1 {
48
49
  let control_6: string;
49
50
  export { control_6 as control };
50
- let description_7: string;
51
- export { description_7 as description };
51
+ let description_6: string;
52
+ export { description_6 as description };
52
53
  }
53
- export namespace imageConfig {
54
- export namespace control_7 {
55
- let type_2: string;
56
- export { type_2 as type };
57
- }
54
+ export { title_1 as title };
55
+ export namespace description_7 {
56
+ let control_7: string;
58
57
  export { control_7 as control };
59
58
  let description_8: string;
60
59
  export { description_8 as description };
61
60
  }
62
- export namespace isDanger {
61
+ export { description_7 as description };
62
+ export namespace confirmLabel {
63
63
  let control_8: string;
64
64
  export { control_8 as control };
65
65
  let description_9: string;
66
66
  export { description_9 as description };
67
67
  }
68
+ export namespace cancelLabel {
69
+ let control_9: string;
70
+ export { control_9 as control };
71
+ let description_10: string;
72
+ export { description_10 as description };
73
+ }
74
+ export namespace imageConfig {
75
+ export namespace control_10 {
76
+ let type_3: string;
77
+ export { type_3 as type };
78
+ }
79
+ export { control_10 as control };
80
+ let description_11: string;
81
+ export { description_11 as description };
82
+ }
83
+ export namespace isDanger {
84
+ let control_11: string;
85
+ export { control_11 as control };
86
+ let description_12: string;
87
+ export { description_12 as description };
88
+ }
68
89
  }
69
90
  export namespace parameters {
70
91
  namespace backgrounds {
@@ -79,6 +100,9 @@ declare namespace _default {
79
100
  }
80
101
  export default _default;
81
102
  export const Default: any;
103
+ export const WithChildren: any;
104
+ export const WithCustomContent: any;
105
+ export const WithRenderContent: any;
82
106
  export const DangerModal: any;
83
107
  export const WithLargeOffset: any;
84
108
  export const WithImageConfig: any;
@@ -14,11 +14,46 @@ import React, { useState } from "react";
14
14
  import { action } from "@storybook/addon-actions";
15
15
  import Modal from "./Modal";
16
16
  import "../../../styles/global.css";
17
+ // Composant d'exemple pour démontrer les nouvelles fonctionnalités
18
+ var CustomFormComponent = function (_a) {
19
+ var title = _a.title, onSubmit = _a.onSubmit, _b = _a.initialValue, initialValue = _b === void 0 ? "" : _b;
20
+ var _c = useState(initialValue), value = _c[0], setValue = _c[1];
21
+ return (React.createElement("div", { style: { textAlign: "center" } },
22
+ React.createElement("h3", { style: { marginBottom: "1rem", color: "#1f2937" } }, title),
23
+ React.createElement("div", { style: { marginBottom: "1rem" } },
24
+ React.createElement("input", { type: "text", value: value, onChange: function (e) { return setValue(e.target.value); }, placeholder: "Saisissez votre texte...", style: {
25
+ width: "100%",
26
+ padding: "0.75rem",
27
+ border: "1px solid #d1d5db",
28
+ borderRadius: "0.375rem",
29
+ fontSize: "1rem",
30
+ } })),
31
+ React.createElement("button", { onClick: function () { return onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(value); }, disabled: !value.trim(), style: {
32
+ padding: "0.5rem 1rem",
33
+ backgroundColor: value.trim() ? "#3b82f6" : "#9ca3af",
34
+ color: "white",
35
+ border: "none",
36
+ borderRadius: "0.375rem",
37
+ cursor: value.trim() ? "pointer" : "not-allowed",
38
+ } }, "Valider la saisie")));
39
+ };
17
40
  export default {
18
41
  title: "Components/Molecules/Modal",
19
42
  component: Modal,
20
43
  tags: ["autodocs"],
21
44
  argTypes: {
45
+ children: {
46
+ control: false,
47
+ description: "Contenu React à afficher dans la modal (ReactNode)",
48
+ },
49
+ customContent: {
50
+ control: { type: "object" },
51
+ description: "Composant personnalisé avec ses props { component, props }",
52
+ },
53
+ renderContent: {
54
+ control: false,
55
+ description: "Fonction de rendu (modalProps) => ReactNode",
56
+ },
22
57
  verticalOffset: {
23
58
  control: { type: "object" },
24
59
  description: "Décalage vertical du modal (en px) pour éviter les barres de navigation",
@@ -102,6 +137,75 @@ Default.args = {
102
137
  },
103
138
  },
104
139
  };
140
+ // Nouvelle story : Modal avec children
141
+ export var WithChildren = Template.bind({});
142
+ WithChildren.args = {
143
+ show: false,
144
+ confirmLabel: "Valider",
145
+ cancelLabel: "Annuler",
146
+ children: (React.createElement("div", { style: { textAlign: "center", padding: "2rem" } },
147
+ React.createElement("h2", { style: { color: "#1f2937", marginBottom: "1rem" } }, "Contenu personnalis\u00E9"),
148
+ React.createElement("p", { style: { color: "#6b7280", marginBottom: "1.5rem" } },
149
+ "Ce contenu est pass\u00E9 via la prop ",
150
+ React.createElement("code", null, "children")),
151
+ React.createElement("div", { style: {
152
+ padding: "1rem",
153
+ backgroundColor: "#f3f4f6",
154
+ borderRadius: "0.5rem",
155
+ border: "2px dashed #9ca3af",
156
+ } },
157
+ React.createElement("span", { style: { fontSize: "2rem" } }, "\uD83C\uDF89"),
158
+ React.createElement("p", { style: { margin: "0.5rem 0 0 0", fontWeight: "bold" } }, "Succ\u00E8s !")))),
159
+ };
160
+ // Nouvelle story : Modal avec customContent
161
+ export var WithCustomContent = Template.bind({});
162
+ WithCustomContent.args = {
163
+ show: false,
164
+ confirmLabel: "Valider",
165
+ cancelLabel: "Annuler",
166
+ customContent: {
167
+ component: CustomFormComponent,
168
+ props: {
169
+ title: "Formulaire personnalisé",
170
+ initialValue: "Valeur initiale",
171
+ onSubmit: function (value) { return action("Form submitted")(value); },
172
+ },
173
+ },
174
+ };
175
+ // Nouvelle story : Modal avec renderContent
176
+ export var WithRenderContent = Template.bind({});
177
+ WithRenderContent.args = {
178
+ show: false,
179
+ confirmLabel: "Fermer",
180
+ cancelLabel: undefined,
181
+ renderContent: function (_a) {
182
+ var isOpen = _a.isOpen, onClose = _a.onClose;
183
+ return (React.createElement("div", { style: { textAlign: "center" } },
184
+ React.createElement("h2", { style: { color: "#dc2626", marginBottom: "1rem" } }, "\u26A0\uFE0F Attention"),
185
+ React.createElement("p", { style: { marginBottom: "1rem" } },
186
+ "Modal \u00E9tat : ",
187
+ isOpen ? "Ouverte" : "Fermée"),
188
+ React.createElement("div", { style: {
189
+ padding: "1rem",
190
+ backgroundColor: "#fef2f2",
191
+ border: "1px solid #fecaca",
192
+ borderRadius: "0.5rem",
193
+ marginBottom: "1rem",
194
+ } },
195
+ React.createElement("p", { style: { margin: 0, fontSize: "0.875rem", color: "#991b1b" } }, "Cette action est irr\u00E9versible et supprimera d\u00E9finitivement vos donn\u00E9es.")),
196
+ React.createElement("button", { onClick: function () {
197
+ action("Internal action")();
198
+ onClose();
199
+ }, style: {
200
+ padding: "0.5rem 1rem",
201
+ backgroundColor: "#dc2626",
202
+ color: "white",
203
+ border: "none",
204
+ borderRadius: "0.375rem",
205
+ cursor: "pointer",
206
+ } }, "Action dangereuse")));
207
+ },
208
+ };
105
209
  export var DangerModal = Template.bind({});
106
210
  DangerModal.args = __assign(__assign({}, Default.args), { title: "Attention", description: "Cette action est irréversible. Voulez-vous continuer ?", confirmLabel: "Supprimer", isDanger: true });
107
211
  export var WithLargeOffset = Template.bind({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allaw-ui",
3
- "version": "3.6.8",
3
+ "version": "3.7.0",
4
4
  "description": "Composants UI pour l'application Allaw",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",