allaw-ui 3.6.8 → 3.6.9
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.
- package/dist/components/molecules/modal/Modal.d.ts +10 -0
- package/dist/components/molecules/modal/Modal.js +22 -7
- package/dist/components/molecules/modal/Modal.module.css +5 -0
- package/dist/components/molecules/modal/Modal.stories.d.ts +53 -29
- package/dist/components/molecules/modal/Modal.stories.js +104 -0
- package/package.json +1 -1
|
@@ -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,26 @@ var Modal = function (_a) {
|
|
|
68
68
|
var handleImageError = function () {
|
|
69
69
|
setImgError(true);
|
|
70
70
|
};
|
|
71
|
+
var renderModalContent = function () {
|
|
72
|
+
if (renderContent) {
|
|
73
|
+
return (React.createElement("div", { className: style.modalCustomWrapper }, renderContent({ isOpen: show, onClose: onCancel })));
|
|
74
|
+
}
|
|
75
|
+
if (customContent) {
|
|
76
|
+
var Component = customContent.component, _a = customContent.props, props = _a === void 0 ? {} : _a;
|
|
77
|
+
return (React.createElement("div", { className: style.modalCustomWrapper },
|
|
78
|
+
React.createElement(Component, __assign({}, props))));
|
|
79
|
+
}
|
|
80
|
+
if (children) {
|
|
81
|
+
return React.createElement("div", { className: style.modalCustomWrapper }, children);
|
|
82
|
+
}
|
|
83
|
+
return (React.createElement(React.Fragment, null,
|
|
84
|
+
React.createElement("div", { className: style.modalHeadingWrapper },
|
|
85
|
+
React.createElement(Heading, { text: title, variant: "h4", color: "noir", align: "left" })),
|
|
86
|
+
React.createElement("div", { className: style.modalParagraphWrapper },
|
|
87
|
+
React.createElement(Paragraph, { text: description, variant: "medium", size: "default", className: style.modalParagraph })),
|
|
88
|
+
imageConfig && !imgError && (React.createElement("div", { className: "".concat(style.modalImageWrapper, " ").concat(imageConfig.className || ""), style: __assign({ padding: imageConfig.padding }, imageConfig.style) },
|
|
89
|
+
React.createElement("img", { src: imageConfig.url, alt: imageConfig.alt || "", width: imageConfig.width, height: imageConfig.height, onError: handleImageError, className: style.modalImage })))));
|
|
90
|
+
};
|
|
71
91
|
if (!show || !isVisible || !portalContainerRef.current)
|
|
72
92
|
return null;
|
|
73
93
|
var modalContent = (React.createElement("div", { className: "".concat(style.modalOverlay, " ").concat(isVisible ? style.visible : "", " ").concat(show ? style.modal : ""), onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, style: {
|
|
@@ -83,12 +103,7 @@ var Modal = function (_a) {
|
|
|
83
103
|
: undefined,
|
|
84
104
|
} },
|
|
85
105
|
React.createElement("div", { className: "".concat(style.modalContent, " ").concat(show ? style.modal : ""), ref: modalContentRef },
|
|
86
|
-
|
|
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 }))),
|
|
106
|
+
renderModalContent(),
|
|
92
107
|
React.createElement("div", { className: style.modalButtons },
|
|
93
108
|
cancelLabel && (React.createElement(SecondaryButton, { label: cancelLabel, onClick: onCancel, startIconName: "allaw-icon-close", startIcon: true })),
|
|
94
109
|
React.createElement(PrimaryButton, { label: confirmLabel, variant: isDanger ? "warning" : "default", onClick: onConfirm, startIconName: confirmIconName, startIcon: true })))));
|
|
@@ -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
|
|
7
|
-
|
|
8
|
-
let type: string;
|
|
9
|
-
}
|
|
6
|
+
export namespace children {
|
|
7
|
+
let control: boolean;
|
|
10
8
|
let description: string;
|
|
11
9
|
}
|
|
12
|
-
export namespace
|
|
10
|
+
export namespace customContent {
|
|
13
11
|
export namespace control_1 {
|
|
14
|
-
let
|
|
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
|
|
22
|
-
let control_2:
|
|
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
|
|
28
|
-
|
|
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
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
38
|
-
export {
|
|
39
|
+
let description_4: string;
|
|
40
|
+
export { description_4 as description };
|
|
39
41
|
}
|
|
40
|
-
export
|
|
41
|
-
export namespace confirmLabel {
|
|
42
|
+
export namespace show {
|
|
42
43
|
let control_5: string;
|
|
43
44
|
export { control_5 as control };
|
|
44
|
-
let
|
|
45
|
-
export {
|
|
45
|
+
let description_5: string;
|
|
46
|
+
export { description_5 as description };
|
|
46
47
|
}
|
|
47
|
-
export namespace
|
|
48
|
+
export namespace title_1 {
|
|
48
49
|
let control_6: string;
|
|
49
50
|
export { control_6 as control };
|
|
50
|
-
let
|
|
51
|
-
export {
|
|
51
|
+
let description_6: string;
|
|
52
|
+
export { description_6 as description };
|
|
52
53
|
}
|
|
53
|
-
export
|
|
54
|
-
|
|
55
|
-
|
|
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
|
|
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({});
|