Skip to content

Commit 1d0075a

Browse files
abderrahman-fawzy-acn-axaAbderrahman FAWZY DEV
andauthored
[AXA.fr] [Espace Client] [Organisme] Evolutions du composant Modal #824 (#1184)
* feat(apollo): added useHasScroll hook * feat(apollo,look&feel): évolution du composant modal * feat(apollo,look&feel): ajout des tests du composant modal * feat(apollo): ajout des stories du composant modal * feat(look&feel): suppression du code du composant modal et réexportation d'apollo * feat(look&feel): encapsulation des stories du composant modal dans son folder * style(apollo,look&feel): defined overlay color in modal lf css * revert "feat(look&feel): suppression du code du composant modal et réexportation d'apollo" This reverts commit e5280d2. * feat(look&feel): mention du composant en deprecated et suggestion d'utiliser la version apollo * feat(apollo,look&feel): retours pr * revert "feat(look&feel): encapsulation des stories du composant modal dans son folder" This reverts commit 3b28b94. * feat(look&feel): ajout des stories de la modal venant d'apollo * style(apollo,look&feel): modification du préfixe af-modal* par af-apollo-modal* pour éviter l'entremêlement des styles apollo et look-and-feel * style(apollo,look&feel): retour sur la config legacy de color-function-notation * feat(look&feel): retour pr story * test(apollo): corrected failing build * feat(apollo): fixed errors in modal stories * feat(look&feel): fixed errors in modal stories and importing modal from apollo/lf * test(apollo): fixed modal test * feat(apollo,look&feel): retour pr sur les stories et tests * feat(apollo,look&feel): reduction du temps de transition de la modal --------- Co-authored-by: Abderrahman FAWZY DEV <[email protected]>
1 parent f52dacc commit 1d0075a

40 files changed

+1564
-164
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { Canvas, Controls, Meta } from "@storybook/addon-docs";
2+
import * as ModalStories from "./Modal.stories.tsx";
3+
import * as ModalCoreStories from "./ModalCore.stories.tsx";
4+
5+
<Meta of={ModalStories} name="Docs" />
6+
7+
# Modal
8+
9+
1. [ModalCore](#modalcore)
10+
2. [Modal](#modal)
11+
12+
The ModalCore is the component to use if you want to fully configure your modal.
13+
14+
With the `ModalCoreHeader` you can configure the header of the modal.
15+
16+
With the `ModalCoreBody` you can configure the body of the modal.
17+
18+
And with the `ModalCoreFooter` you can configure the footer of the modal.
19+
20+
You need to pass a `ref` to the `Modal` component in order to call the `showModal` function when you want to open the modal and the `close` function for closing it.
21+
22+
## ModalCore
23+
24+
Example of usage of ModalCore component :
25+
26+
```tsx
27+
import { useRef } from "react";
28+
29+
export const YourComponent = () => {
30+
const ref = useRef<HTMLDialogElement>(null);
31+
32+
return (
33+
<>
34+
<ButtonClient onClick={() => ref.current?.showModal()}>
35+
Open the modal
36+
</ButtonClient>
37+
38+
<ModalCore
39+
onCancel={() => {}}
40+
onClose={() => {}}
41+
onSubmit={() => {}}
42+
title="Modal title"
43+
ref={ref}
44+
>
45+
<ModalCoreHeader
46+
headingProps={{
47+
children: "Modal title",
48+
}}
49+
iconProps={{ src: iconSrc }}
50+
onClose={() => {}}
51+
/>
52+
<ModalCoreBody>
53+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
54+
consectetur urna a tellus semper, id elementum ligula fermentum. In
55+
semper quis mi eu commodo. Vivamus in metus eros. Sed ut pellentesque
56+
purus. Maecenas congue ornare massa quis porttitor. Nullam ut diam
57+
dapibus, consequat libero eget, faucibus nibh. Etiam imperdiet metus
58+
at nulla fermentum semper. In ipsum urna, tempus vel lorem vel,
59+
venenatis malesuada dui. Cras massa ipsum, accumsan et scelerisque ut,
60+
vulputate at elit.
61+
</ModalCoreBody>
62+
<ModalCoreFooter
63+
primaryButtonProps={{
64+
children: "Valider",
65+
}}
66+
secondaryButtonProps={{
67+
children: "Annuler",
68+
}}
69+
/>
70+
</ModalCore>
71+
</>
72+
);
73+
};
74+
```
75+
76+
<Canvas of={ModalCoreStories.ModalCore} />
77+
78+
<Controls of={ModalCoreStories.ModalCore} />
79+
80+
## Modal
81+
82+
Example of usage of Modal component :
83+
84+
```tsx
85+
import { useRef } from "react";
86+
87+
export const YourComponent = () => {
88+
const ref = useRef<HTMLDialogElement>(null);
89+
90+
return (
91+
<>
92+
<button type="button" onClick={() => ref.current?.showModal()}>
93+
Open modal
94+
</button>
95+
96+
<Modal
97+
ref={ref}
98+
headingProps={{
99+
firstSubtitle: "Modal subtitle",
100+
}}
101+
icon={iconSrc}
102+
iconProps={{
103+
variant: "primary",
104+
}}
105+
onCancel={() => {}}
106+
onClose={() => {}}
107+
primaryButtonProps={{
108+
children: "Submit",
109+
onClick: () => {},
110+
}}
111+
secondaryButtonProps={{
112+
children: "Cancel",
113+
onClick: () => {},
114+
}}
115+
title="Modal title"
116+
>
117+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
118+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
119+
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
120+
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
121+
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
122+
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
123+
mollit anim id est laborum. Curabitur pretium tincidunt lacus. Nulla
124+
gravida orci a odio. Nullam varius, turpis et commodo pharetra, est eros
125+
bibendum elit, nec luctus magna felis sollicitudin mauris
126+
</Modal>
127+
</>
128+
);
129+
};
130+
```
131+
132+
<Canvas of={ModalStories.Playground} />
133+
134+
<Controls of={ModalStories.Playground} />
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import "./Modal.story.scss";
2+
3+
import { Button, Modal } from "@axa-fr/design-system-apollo-react";
4+
import bank from "@material-symbols/svg-700/rounded/account_balance.svg";
5+
import { action } from "@storybook/addon-actions";
6+
import type { Meta, StoryObj } from "@storybook/react";
7+
import { fn } from "@storybook/test";
8+
import { ComponentPropsWithRef, useLayoutEffect, useRef } from "react";
9+
10+
const meta: Meta<typeof Modal> = {
11+
title: "Components/Modal",
12+
component: Modal,
13+
parameters: {
14+
layout: "fullscreen",
15+
viewport: { defaultViewport: "desktop" },
16+
},
17+
args: {
18+
onClose: fn(),
19+
onCancel: fn(),
20+
},
21+
};
22+
export default meta;
23+
24+
type ModalStory = StoryObj<ComponentPropsWithRef<typeof Modal>>;
25+
26+
export const ModalContent: ModalStory = {
27+
name: "Modal",
28+
decorators: [
29+
(Story, { args: { open, ...args } }) => {
30+
const modalRef = useRef<HTMLDialogElement>(null);
31+
32+
useLayoutEffect(() => {
33+
if (open) {
34+
modalRef.current?.showModal();
35+
return;
36+
}
37+
38+
modalRef.current?.close();
39+
}, [open]);
40+
41+
return <Story args={{ ...args, ref: modalRef }} />;
42+
},
43+
],
44+
args: {
45+
open: true,
46+
title: "Modal title",
47+
headingProps: {
48+
firstSubtitle: "Modal subtitle",
49+
},
50+
icon: bank,
51+
iconProps: { variant: "primary" },
52+
children:
53+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam varius, turpis et commodo pharetra, est eros bibendum elit, nec luctus magna felis sollicitudin mauris",
54+
secondaryButtonProps: {
55+
children: "Cancel",
56+
onClick: action("[Cancel] onClick"),
57+
},
58+
primaryButtonProps: {
59+
children: "Submit",
60+
onClick: action("[Submit] onClick"),
61+
},
62+
},
63+
};
64+
65+
export const Playground: ModalStory = {
66+
decorators: [
67+
(Story, { args: { secondaryButtonProps = {}, ...args } }) => {
68+
const ref = useRef<HTMLDialogElement>(null);
69+
70+
const onClose = () => {
71+
args.onClose?.();
72+
ref.current?.close();
73+
};
74+
75+
const onClickSecondaryButton: React.MouseEventHandler<
76+
HTMLButtonElement
77+
> = (e) => {
78+
secondaryButtonProps.onClick?.(e);
79+
ref.current?.close();
80+
};
81+
82+
return (
83+
<>
84+
<div className="button-wrapper">
85+
<Button onClick={() => ref.current?.showModal()}>
86+
Open the Modal
87+
</Button>
88+
</div>
89+
<Story
90+
args={{
91+
...args,
92+
ref,
93+
onClose,
94+
secondaryButtonProps: {
95+
...secondaryButtonProps,
96+
onClick: onClickSecondaryButton,
97+
},
98+
}}
99+
/>
100+
</>
101+
);
102+
},
103+
],
104+
args: { ...ModalContent.args, open: undefined },
105+
};
106+
107+
export const MobilePlayground: ModalStory = {
108+
...Playground,
109+
parameters: {
110+
viewport: { defaultViewport: "mobile1" },
111+
},
112+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.paragraph {
2+
margin: 0;
3+
}
4+
5+
.button-wrapper {
6+
padding: 1rem;
7+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import "./Modal.story.scss";
2+
3+
import {
4+
Button,
5+
ModalCoreBody,
6+
ModalCore as ModalCoreComponent,
7+
ModalCoreFooter,
8+
ModalCoreHeader,
9+
} from "@axa-fr/design-system-apollo-react";
10+
import bank from "@material-symbols/svg-700/rounded/account_balance.svg";
11+
import type { Meta, StoryObj } from "@storybook/react";
12+
import { fn } from "@storybook/test";
13+
import { useRef } from "react";
14+
15+
const meta: Meta<typeof ModalCoreComponent> = {
16+
title: "Components/Modal/ModalCore",
17+
component: ModalCoreComponent,
18+
parameters: {
19+
layout: "fullscreen",
20+
},
21+
args: {
22+
onSubmit: fn(),
23+
onCancel: fn(),
24+
onClose: fn(),
25+
},
26+
};
27+
export default meta;
28+
29+
type TModalCoreStory = StoryObj<typeof meta>;
30+
31+
export const ModalCore: TModalCoreStory = {
32+
decorators: [
33+
(Story, { args }) => {
34+
const ref = useRef<HTMLDialogElement>(null);
35+
const onClose = () => {
36+
ref.current?.close();
37+
args.onClose?.();
38+
};
39+
const children = (
40+
<>
41+
<ModalCoreHeader
42+
headingProps={{ children: args.title }}
43+
iconProps={{ src: bank }}
44+
onClose={onClose as VoidFunction}
45+
/>
46+
<ModalCoreBody>{args.children}</ModalCoreBody>
47+
<ModalCoreFooter
48+
primaryButtonProps={{ children: "Valider" }}
49+
secondaryButtonProps={{ children: "Annuler" }}
50+
/>
51+
</>
52+
);
53+
54+
return (
55+
<>
56+
<div style={{ padding: 8 }}>
57+
<Button onClick={() => ref.current?.showModal()}>
58+
Open the modal
59+
</Button>
60+
</div>
61+
<Story args={{ ...{ ...args, ref, onClose, children } }} />
62+
</>
63+
);
64+
},
65+
],
66+
args: {
67+
open: false,
68+
title: "Modal title",
69+
children: (
70+
<>
71+
<p className="paragraph">
72+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
73+
consectetur urna a tellus semper, id elementum ligula fermentum. In
74+
semper quis mi eu commodo. Vivamus in metus eros. Sed ut pellentesque
75+
purus. Maecenas congue ornare massa quis porttitor. Nullam ut diam
76+
dapibus, consequat libero eget, faucibus nibh. Etiam imperdiet metus
77+
at nulla fermentum semper. In ipsum urna, tempus vel lorem vel,
78+
venenatis malesuada dui. Cras massa ipsum, accumsan et scelerisque ut,
79+
vulputate at elit.
80+
</p>
81+
82+
<p className="paragraph">
83+
Donec non quam neque. Nullam fermentum erat in sem fermentum euismod.
84+
Phasellus sollicitudin condimentum diam ut euismod. Duis nec bibendum
85+
metus. Ut convallis tincidunt risus. Nam vel ultricies augue. Donec
86+
malesuada dolor et ligula egestas, sit amet ultrices libero bibendum.
87+
Phasellus varius pulvinar lectus, a ultrices risus tempus ut. Aliquam
88+
faucibus tortor lorem, et mattis dolor efficitur quis. Pellentesque
89+
ipsum nunc, finibus nec velit eget, sodales lobortis leo.
90+
</p>
91+
<p className="paragraph">
92+
Pellentesque venenatis est quis aliquam tristique. In tincidunt orci
93+
ac ipsum vulputate, quis mattis orci commodo. Pellentesque at
94+
hendrerit felis, pulvinar porttitor lorem. Sed vulputate quis diam sit
95+
amet ultricies. Cras non nisl pharetra, ornare lectus sed, fringilla
96+
turpis. Cras molestie velit in enim pretium, id vestibulum est luctus.
97+
Ut mattis consequat magna, ac scelerisque massa consequat in. Proin
98+
euismod pulvinar congue. Donec dapibus lorem tellus, dapibus dignissim
99+
elit condimentum non. Donec luctus nulla a turpis mattis, vehicula
100+
posuere quam convallis. Nullam gravida ante rutrum purus efficitur
101+
hendrerit. Aenean magna tortor, cursus at ligula vel, aliquet iaculis
102+
arcu. Praesent varius, purus eget interdum tempor, magna nisi pretium
103+
neque, pharetra viverra leo neque at est.
104+
</p>
105+
</>
106+
),
107+
},
108+
};

0 commit comments

Comments
 (0)