Skip to content

Commit d5c0f30

Browse files
committed
Call conceal after button callback
1 parent fbaaf14 commit d5c0f30

File tree

4 files changed

+115
-4
lines changed

4 files changed

+115
-4
lines changed

src/Modal/useIsModalOpen.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ export function useIsModalOpen(
2424
const observeDialogHtmlElement = (element: HTMLElement) => {
2525
const onConceal = () => {
2626
setIsModalOpen(false);
27-
getCurrentCallbacks()?.onConceal?.();
27+
setTimeout(() => {
28+
getCurrentCallbacks()?.onConceal?.();
29+
}, 0);
2830
};
2931
const onDisclose = () => {
3032
setIsModalOpen(true);

test/integration/cra/public/index.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
<meta charset="utf-8" />
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<meta name="description" content="Web site created using create-react-app" />
8-
<meta http-equiv="Content-Security-Policy"
9-
content="require-trusted-types-for 'script'; trusted-types react-dsfr react-dsfr-asap" />
108

119
<link rel="apple-touch-icon" href="%PUBLIC_URL%/dsfr/favicon/apple-touch-icon.png" />
1210
<link rel="icon" href="%PUBLIC_URL%/dsfr/favicon/favicon.svg" type="image/svg+xml" />

test/integration/cra/src/Home.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import { useState } from "react";
12
import { Alert } from "@codegouvfr/react-dsfr/Alert";
23
import { fr } from "@codegouvfr/react-dsfr";
34
import { useIsDark } from "@codegouvfr/react-dsfr/useIsDark";
45
import { SideMenu } from "@codegouvfr/react-dsfr/SideMenu";
56
import { Table } from "@codegouvfr/react-dsfr/Table";
67
import { routes } from "./router";
8+
import { Button } from "@codegouvfr/react-dsfr/Button";
9+
import { MyDialog, type DialogParams, type DialogResponse } from "./MyDialog";
710

811
const sideMenuItems = [
912
{
@@ -77,6 +80,10 @@ const sideMenuItems = [
7780
export function Home() {
7881
const { isDark, setIsDark } = useIsDark();
7982

83+
const [myDialogActions] = useState<{
84+
open?: (params: DialogParams) => Promise<DialogResponse>
85+
}>({});
86+
8087
return (
8188
<>
8289
<Alert
@@ -106,8 +113,23 @@ export function Home() {
106113
title="Titre de rubrique"
107114
burgerMenuButtonText="Dans cette rubrique"
108115
/>
109-
110116
<TableExample />
117+
<Button
118+
type="button"
119+
onClick={async () => {
120+
121+
const response = await myDialogActions.open!({
122+
title: "Ma question",
123+
body: "Voulez-vous continuer ?",
124+
});
125+
126+
alert(`Continuer: ${response.doProceed ? "oui" : "non"}`);
127+
128+
}}
129+
>
130+
Open Dialog
131+
</Button>
132+
<MyDialog actions={myDialogActions} />
111133
</>
112134
);
113135
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { createModal } from '@codegouvfr/react-dsfr/Modal'
2+
import { useIsModalOpen } from '@codegouvfr/react-dsfr/Modal/useIsModalOpen'
3+
import { useState, useEffect, useId } from 'react'
4+
5+
type Props = {
6+
actions: {
7+
open?: (params: DialogParams) => Promise<DialogResponse>
8+
}
9+
}
10+
11+
export type DialogParams = {
12+
title: string;
13+
body: string;
14+
};
15+
16+
export type DialogResponse = {
17+
doProceed: boolean;
18+
};
19+
20+
export function MyDialog(props: Props) {
21+
const { actions } = props
22+
23+
const id = useId()
24+
25+
const [modal] = useState(() =>
26+
createModal({
27+
id: `myDialog-${id}`,
28+
isOpenedByDefault: false,
29+
})
30+
);
31+
32+
const [openState, setOpenState] = useState<
33+
| {
34+
dialogParams: DialogParams;
35+
resolve: (params: DialogResponse) => void
36+
}
37+
| undefined
38+
>(undefined)
39+
40+
useEffect(() => {
41+
actions.open = dialogParams =>
42+
new Promise<DialogResponse>((resolve) => {
43+
setOpenState({
44+
dialogParams,
45+
resolve,
46+
})
47+
modal.open();
48+
})
49+
}, []);
50+
51+
useIsModalOpen(modal, {
52+
onConceal: async () => {
53+
54+
openState?.resolve({ doProceed: false });
55+
56+
setOpenState(undefined);
57+
}
58+
});
59+
60+
return (
61+
<modal.Component
62+
title={openState?.dialogParams.title}
63+
buttons={[
64+
{
65+
children: 'Annuler',
66+
onClick: () => {
67+
openState?.resolve({ doProceed: false })
68+
69+
setOpenState(undefined)
70+
},
71+
},
72+
{
73+
children: 'Ok',
74+
onClick: () => {
75+
76+
openState?.resolve({
77+
doProceed: true
78+
})
79+
80+
setOpenState(undefined)
81+
},
82+
},
83+
]}
84+
concealingBackdrop={true}
85+
>
86+
{openState?.dialogParams.body}
87+
</modal.Component>
88+
);
89+
}

0 commit comments

Comments
 (0)