Skip to content

Commit 93150f8

Browse files
Merge pull request #49 from internxt/fix/PB-3511-close-modals
[PB-3511]:Fix/close multiple modals
2 parents b3e6ca5 + 015b2ca commit 93150f8

File tree

4 files changed

+75
-36
lines changed

4 files changed

+75
-36
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@internxt/ui",
3-
"version": "0.0.19",
3+
"version": "0.0.20",
44
"description": "Library of Internxt components",
55
"repository": {
66
"type": "git",

src/components/modal/Modal.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ const Modal = ({
6565
const [transitionOpacity, setTransitionOpacity] = useState<string>('opacity-0');
6666
const [transitionScale, setTransitionScale] = useState<string>('scale-95');
6767

68+
const closeLastOpenModal = () => {
69+
const openModals = document.querySelectorAll('[data-modal]');
70+
const lastModal = openModals[openModals.length - 1];
71+
if (modalRef.current === lastModal) {
72+
onClose();
73+
}
74+
};
75+
6876
useEffect(() => {
6977
if (isOpen) {
7078
const timeout = setTimeout(() => {
@@ -86,7 +94,8 @@ const Modal = ({
8694
useEffect(() => {
8795
const handleClickOutside = (event: MouseEvent) => {
8896
if (modalRef.current && !modalRef.current.contains(event.target as Node) && !preventClosing) {
89-
onClose();
97+
event.preventDefault();
98+
closeLastOpenModal();
9099
}
91100
};
92101

@@ -102,7 +111,8 @@ const Modal = ({
102111
useEffect(() => {
103112
const handleKeyDown = (event: KeyboardEvent) => {
104113
if (event.key === 'Escape' && !preventClosing) {
105-
onClose();
114+
event.preventDefault();
115+
closeLastOpenModal();
106116
}
107117
};
108118

@@ -116,14 +126,15 @@ const Modal = ({
116126
}, [isOpen, onClose, preventClosing]);
117127

118128
return (
119-
<>
129+
<div className="m-0">
120130
{showContent && (
121131
<>
122132
<div
123133
className={`
124134
fixed
135+
min-h-full
125136
inset-0
126-
z-50
137+
z-[9999]
127138
bg-highlight/40
128139
transition-opacity
129140
duration-150
@@ -136,7 +147,7 @@ const Modal = ({
136147
className={`
137148
fixed
138149
inset-0
139-
z-50
150+
z-[9999]
140151
flex
141152
min-h-full
142153
items-center
@@ -152,6 +163,7 @@ const Modal = ({
152163
<section
153164
data-testid={'ModalContent'}
154165
ref={modalRef}
166+
data-modal
155167
className={`
156168
${width ?? 'w-full'}
157169
${maxWidth ?? 'max-w-lg'}
@@ -173,7 +185,7 @@ const Modal = ({
173185
</div>
174186
</>
175187
)}
176-
</>
188+
</div>
177189
);
178190
};
179191

src/components/modal/__test__/Modal.test.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,25 @@ describe('Modal Component', () => {
186186
expect(screen.queryByText('Modal Content')).not.toBeInTheDocument();
187187
});
188188
});
189+
190+
it('closeLastOpenModal should close only the last opened modal', () => {
191+
const onClose1 = vi.fn();
192+
const onClose2 = vi.fn();
193+
194+
render(
195+
<>
196+
<Modal isOpen={true} onClose={onClose1}>
197+
<div data-testid="modal-1">Modal 1</div>
198+
</Modal>
199+
<Modal isOpen={true} onClose={onClose2}>
200+
<div data-testid="modal-2">Modal 2</div>
201+
</Modal>
202+
</>,
203+
);
204+
205+
fireEvent.mouseDown(document.body);
206+
207+
expect(onClose1).not.toHaveBeenCalled();
208+
expect(onClose2).toHaveBeenCalled();
209+
});
189210
});

src/components/modal/__test__/__snapshots__/Modal.test.tsx.snap

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,27 @@
33
exports[`Modal Component > should match snapshot when isOpen is true 1`] = `
44
<div>
55
<div
6-
class="
6+
class="m-0"
7+
>
8+
<div
9+
class="
710
fixed
11+
min-h-full
812
inset-0
9-
z-50
13+
z-[9999]
1014
bg-highlight/40
1115
transition-opacity
1216
duration-150
1317
ease-out
1418
opacity-0
1519
pointer-events-none
1620
"
17-
/>
18-
<div
19-
class="
21+
/>
22+
<div
23+
class="
2024
fixed
2125
inset-0
22-
z-50
26+
z-[9999]
2327
flex
2428
min-h-full
2529
items-center
@@ -31,9 +35,9 @@ exports[`Modal Component > should match snapshot when isOpen is true 1`] = `
3135
opacity-0
3236
scale-95
3337
"
34-
>
35-
<section
36-
class="
38+
>
39+
<section
40+
class="
3741
w-full
3842
max-w-lg
3943
p-5
@@ -48,28 +52,30 @@ exports[`Modal Component > should match snapshot when isOpen is true 1`] = `
4852
opacity-0
4953
scale-95
5054
"
51-
data-testid="ModalContent"
52-
>
53-
<div
54-
class="text-center"
55+
data-modal="true"
56+
data-testid="ModalContent"
5557
>
56-
<h2
57-
class="text-lg font-semibold"
58-
>
59-
Title
60-
</h2>
61-
<p
62-
class="mt-2"
63-
>
64-
Modal Content
65-
</p>
66-
<button
67-
class="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
58+
<div
59+
class="text-center"
6860
>
69-
Close
70-
</button>
71-
</div>
72-
</section>
61+
<h2
62+
class="text-lg font-semibold"
63+
>
64+
Title
65+
</h2>
66+
<p
67+
class="mt-2"
68+
>
69+
Modal Content
70+
</p>
71+
<button
72+
class="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
73+
>
74+
Close
75+
</button>
76+
</div>
77+
</section>
78+
</div>
7379
</div>
7480
</div>
7581
`;

0 commit comments

Comments
 (0)