Skip to content
This repository was archived by the owner on Dec 28, 2023. It is now read-only.

Commit a780b52

Browse files
authored
Hubert / Migrate dialog component to typescript (#272)
1 parent 2cada38 commit a780b52

File tree

6 files changed

+78
-71
lines changed

6 files changed

+78
-71
lines changed

src/components/app-registration/AppRegistration/AppRegistrationForm/RegisterAppDialogError/RegisterAppDialogError.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import DelayedFallback from '../../../../global/DelayedFallback/DelayedFallback'
77
const Modal = lazy(() => import('../../../../global/Modal/Modal'));
88

99
export default function RegisterAppDialogError({ error }) {
10-
const isModalOpen = useSelector(stateService, isRegisterErrorSelector);
10+
const isModalOpen: boolean = useSelector(stateService, isRegisterErrorSelector);
1111
if (!isModalOpen) {
1212
return null;
1313
}

src/components/app-registration/AppRegistration/RegisterAppDialogSuccess/RegisterAppDialogSuccess.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { stateService } from '../../../../state/stateSignal';
66
const Modal = lazy(() => import('../../../global/Modal/Modal'));
77

88
export default function RegisterAppDialogSuccess() {
9-
const isModalOpen = useSelector(stateService, isRegisterSuccessSelector);
9+
const isModalOpen: boolean = useSelector(stateService, isRegisterSuccessSelector);
1010
const isUpdateMode = useSelector(stateService, isUpdateModeSelector);
1111
const description = isUpdateMode
1212
? 'Your app has been updated successfully.'

src/components/global/Dialog/Dialog.jsx

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React from 'react';
2+
import styles from './Dialog.module.scss';
3+
4+
type TDialog = {
5+
closeOnOutsideClick: boolean;
6+
onRequestClose: () => void;
7+
open: boolean;
8+
children: React.ReactNode[] | HTMLElement[];
9+
};
10+
11+
type TDialogRef = React.RefObject<HTMLDialogElement>;
12+
13+
export const Dialog = ({ closeOnOutsideClick, onRequestClose, open, ...children }: TDialog) => {
14+
const dialog_ref = React.useRef<HTMLDialogElement>(null);
15+
16+
useDialogOpening(dialog_ref, open);
17+
useDialogClosing(dialog_ref, onRequestClose);
18+
19+
const handleOutsideClick = (event: React.MouseEvent<HTMLDialogElement>) => {
20+
const dialog_node = dialog_ref?.current;
21+
if (closeOnOutsideClick && event?.target === dialog_node) {
22+
onRequestClose();
23+
}
24+
};
25+
26+
return (
27+
<dialog ref={dialog_ref} className={styles.dialogWrapper} onClick={handleOutsideClick}>
28+
<div className={styles.dialogContent} {...children} />
29+
</dialog>
30+
);
31+
};
32+
33+
const useDialogOpening = (dialog_ref: TDialogRef, open: boolean) => {
34+
const lastActiveElement = React.useRef<HTMLDialogElement>(null);
35+
React.useEffect(() => {
36+
const dialog_node = dialog_ref?.current;
37+
if (open) {
38+
dialog_node?.showModal();
39+
} else {
40+
dialog_node?.close();
41+
lastActiveElement?.current?.focus();
42+
}
43+
}, [open]);
44+
};
45+
46+
const useDialogClosing = (dialog_ref: TDialogRef, onRequestClose: () => void) => {
47+
React.useEffect(() => {
48+
const dialog_node = dialog_ref?.current;
49+
const handleCancel: EventListener = event => {
50+
event.preventDefault();
51+
onRequestClose();
52+
};
53+
dialog_node?.addEventListener('cancel', handleCancel);
54+
return () => {
55+
dialog_node?.removeEventListener('cancel', handleCancel);
56+
};
57+
}, [onRequestClose]);
58+
};

src/components/global/Modal/Modal.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
import Button from '../Button/Button';
2-
import Dialog from '../Dialog/Dialog';
2+
import { Dialog } from '../Dialog/Dialog';
33
import styles from './Modal.module.scss';
44

5+
type TModal = {
6+
onRequestClose: () => void;
7+
open: boolean;
8+
type: 'success' | 'warning';
9+
title: string;
10+
description: string;
11+
primaryButtonText?: string | null;
12+
secondaryButtonText: string;
13+
onPrimaryButtonClick?: () => void;
14+
onSecondaryButtonClick: () => void;
15+
};
16+
517
export default function Modal({
618
onRequestClose,
719
open,
@@ -12,17 +24,7 @@ export default function Modal({
1224
secondaryButtonText,
1325
onPrimaryButtonClick,
1426
onSecondaryButtonClick,
15-
}: {
16-
onRequestClose: () => void;
17-
open: any;
18-
type: 'success' | 'warning';
19-
title: string;
20-
description: string;
21-
primaryButtonText?: any;
22-
secondaryButtonText: string;
23-
onPrimaryButtonClick?: () => void;
24-
onSecondaryButtonClick: () => void;
25-
}) {
27+
}: TModal) {
2628
return (
2729
<Dialog onRequestClose={onRequestClose} open={open} closeOnOutsideClick>
2830
<div className={styles.modalHeader}>
@@ -32,9 +34,7 @@ export default function Modal({
3234
{type === 'success' && <div className={styles.modalImageSuccess} />}
3335
{type === 'warning' && <div className={styles.modalImageWarning} />}
3436
<div className={styles.modalTitle}>{title}</div>
35-
<div className={styles.modalDescription}>
36-
<span>{description}</span>
37-
</div>
37+
<div className={styles.modalDescription}>{description}</div>
3838
</div>
3939
<div className={styles.modalFooter}>
4040
<Button type='secondary' onClick={onSecondaryButtonClick}>

src/index.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
declare module '*.png';
1+
declare module '*.png';
2+
declare module '*.css';
3+
declare module '*.scss';

0 commit comments

Comments
 (0)