Skip to content

Commit e4039d3

Browse files
authored
Merge pull request #64 from internxt/feat/add-stop-propagation-modal
[PB-4903]: add stopMouseDownPropagation prop to Modal component
2 parents 38198e9 + c090fb1 commit e4039d3

4 files changed

Lines changed: 51 additions & 2 deletions

File tree

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.25",
3+
"version": "0.0.26",
44
"description": "Library of Internxt components",
55
"repository": {
66
"type": "git",

src/components/modal/Modal.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface ModalProps {
88
className?: string;
99
width?: string;
1010
preventClosing?: boolean;
11+
stopMouseDownPropagation?: boolean;
1112
}
1213

1314
/**
@@ -38,6 +39,9 @@ export interface ModalProps {
3839
* @property {boolean} [preventClosing=false]
3940
* - Optional flag to prevent the modal from closing when clicking outside or pressing the 'Escape' key.
4041
*
42+
* @property {boolean} [stopMouseDownPropagation=false]
43+
* - Optional flag to stop event propagation on mousedown events.
44+
*
4145
* @returns {JSX.Element | null}
4246
* - The rendered Modal component, or `null` if `isOpen` is `false`.
4347
*
@@ -59,6 +63,7 @@ const Modal = ({
5963
className,
6064
width,
6165
preventClosing = false,
66+
stopMouseDownPropagation = false,
6267
}: ModalProps): JSX.Element | null => {
6368
const modalRef = useRef<HTMLDivElement | null>(null);
6469
const [showContent, setShowContent] = useState(isOpen);
@@ -73,6 +78,12 @@ const Modal = ({
7378
}
7479
};
7580

81+
const handleMouseDown = (e: React.MouseEvent) => {
82+
if (stopMouseDownPropagation) {
83+
e.stopPropagation();
84+
}
85+
};
86+
7687
useEffect(() => {
7788
if (isOpen) {
7889
const timeout = setTimeout(() => {
@@ -128,7 +139,7 @@ const Modal = ({
128139
return (
129140
<>
130141
{showContent && (
131-
<div className="m-0">
142+
<div className="m-0" onMouseDown={handleMouseDown} role="dialog" aria-modal="true">
132143
<div
133144
className={`
134145
fixed

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,40 @@ describe('Modal Component', () => {
207207
expect(onClose1).not.toHaveBeenCalled();
208208
expect(onClose2).toHaveBeenCalled();
209209
});
210+
211+
it('should stop propagation when stopMouseDownPropagation is true', () => {
212+
const parentHandler = vi.fn();
213+
const { container } = render(
214+
<div onMouseDown={parentHandler}>
215+
<Modal isOpen={true} onClose={onCloseMock} stopMouseDownPropagation={true}>
216+
<div>Modal Content</div>
217+
</Modal>
218+
</div>,
219+
);
220+
221+
const modalWrapper = container.querySelector('[role="dialog"]');
222+
expect(modalWrapper).toBeInTheDocument();
223+
224+
fireEvent.mouseDown(modalWrapper!);
225+
226+
expect(parentHandler).not.toHaveBeenCalled();
227+
});
228+
229+
it('should not stop propagation when stopMouseDownPropagation is false', () => {
230+
const parentHandler = vi.fn();
231+
const { container } = render(
232+
<div onMouseDown={parentHandler}>
233+
<Modal isOpen={true} onClose={onCloseMock} stopMouseDownPropagation={false}>
234+
<div>Modal Content</div>
235+
</Modal>
236+
</div>,
237+
);
238+
239+
const modalWrapper = container.querySelector('[role="dialog"]');
240+
expect(modalWrapper).toBeInTheDocument();
241+
242+
fireEvent.mouseDown(modalWrapper!);
243+
244+
expect(parentHandler).toHaveBeenCalled();
245+
});
210246
});

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
exports[`Modal Component > should match snapshot when isOpen is true 1`] = `
44
<div>
55
<div
6+
aria-modal="true"
67
class="m-0"
8+
role="dialog"
79
>
810
<div
911
class="

0 commit comments

Comments
 (0)