Skip to content

Commit d260200

Browse files
committed
Make the modal work again
1 parent ebe5887 commit d260200

File tree

2 files changed

+50
-33
lines changed

2 files changed

+50
-33
lines changed
Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import React, { useEffect, useMemo, useState } from 'react';
22
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
33
import { faTimes } from '@fortawesome/free-solid-svg-icons/faTimes';
4-
import { CSSTransition } from 'react-transition-group';
54
import Spinner from '@/components/elements/Spinner';
6-
import classNames from 'classnames';
5+
import tw from 'twin.macro';
6+
import styled from 'styled-components/macro';
7+
import Fade from '@/components/elements/Fade';
78

89
export interface RequiredModalProps {
910
visible: boolean;
@@ -12,73 +13,86 @@ export interface RequiredModalProps {
1213
top?: boolean;
1314
}
1415

15-
type Props = RequiredModalProps & {
16+
interface Props extends RequiredModalProps {
1617
dismissable?: boolean;
1718
closeOnEscape?: boolean;
1819
closeOnBackground?: boolean;
1920
showSpinnerOverlay?: boolean;
20-
children: React.ReactNode;
2121
}
2222

23-
export default ({ visible, appear, dismissable, showSpinnerOverlay, top = true, closeOnBackground = true, closeOnEscape = true, onDismissed, children }: Props) => {
24-
const [render, setRender] = useState(visible);
23+
const ModalMask = styled.div`
24+
${tw`fixed z-50 overflow-auto flex w-full inset-0`};
25+
background: rgba(0, 0, 0, 0.70);
26+
`;
27+
28+
const ModalContainer = styled.div<{ alignTop?: boolean }>`
29+
${tw`relative flex flex-col w-full m-auto`};
30+
max-width: 50%;
31+
// @todo max-w-screen-lg perhaps?
32+
${props => props.alignTop && 'margin-top: 10%'};
33+
34+
& > .close-icon {
35+
${tw`absolute right-0 p-2 text-white cursor-pointer opacity-50 transition-all duration-150 ease-linear hover:opacity-100`};
36+
top: -2rem;
37+
38+
&:hover {${tw`transform rotate-90`}}
39+
}
40+
`;
41+
42+
const Modal: React.FC<Props> = ({ visible, appear, dismissable, showSpinnerOverlay, top = true, closeOnBackground = true, closeOnEscape = true, onDismissed, children }) => {
43+
const [ render, setRender ] = useState(visible);
2544

2645
const isDismissable = useMemo(() => {
2746
return (dismissable || true) && !(showSpinnerOverlay || false);
28-
}, [dismissable, showSpinnerOverlay]);
47+
}, [ dismissable, showSpinnerOverlay ]);
2948

3049
const handleEscapeEvent = (e: KeyboardEvent) => {
3150
if (isDismissable && closeOnEscape && e.key === 'Escape') {
3251
setRender(false);
3352
}
3453
};
3554

36-
useEffect(() => {
37-
setRender(visible);
38-
}, [visible]);
55+
useEffect(() => setRender(visible), [ visible ]);
3956

4057
useEffect(() => {
4158
window.addEventListener('keydown', handleEscapeEvent);
4259

4360
return () => window.removeEventListener('keydown', handleEscapeEvent);
44-
}, [render]);
61+
}, [ render ]);
4562

4663
return (
47-
<CSSTransition
48-
timeout={250}
49-
classNames={'fade'}
50-
appear={appear}
51-
in={render}
52-
unmountOnExit={true}
53-
onExited={() => onDismissed()}
54-
>
55-
<div className={'modal-mask'} onClick={e => {
56-
if (isDismissable && closeOnBackground) {
57-
e.stopPropagation();
58-
if (e.target === e.currentTarget) {
59-
setRender(false);
64+
<Fade timeout={250} appear={appear} in={render} unmountOnExit onExited={onDismissed}>
65+
<ModalMask
66+
onClick={e => {
67+
if (isDismissable && closeOnBackground) {
68+
e.stopPropagation();
69+
if (e.target === e.currentTarget) {
70+
setRender(false);
71+
}
6072
}
61-
}
62-
}}>
63-
<div className={classNames('modal-container', { top })}>
73+
}}
74+
>
75+
<ModalContainer alignTop={top}>
6476
{isDismissable &&
65-
<div className={'modal-close-icon'} onClick={() => setRender(false)}>
77+
<div className={'close-icon'} onClick={() => setRender(false)}>
6678
<FontAwesomeIcon icon={faTimes}/>
6779
</div>
6880
}
6981
{showSpinnerOverlay &&
7082
<div
71-
className={'absolute w-full h-full rounded flex items-center justify-center'}
83+
css={tw`absolute w-full h-full rounded flex items-center justify-center`}
7284
style={{ background: 'hsla(211, 10%, 53%, 0.25)' }}
7385
>
7486
<Spinner/>
7587
</div>
7688
}
77-
<div className={'modal-content p-6'}>
89+
<div css={tw`bg-neutral-800 p-6 rounded shadow-md overflow-y-scroll transition-all duration-250`}>
7890
{children}
7991
</div>
80-
</div>
81-
</div>
82-
</CSSTransition>
92+
</ModalContainer>
93+
</ModalMask>
94+
</Fade>
8395
);
8496
};
97+
98+
export default Modal;

tailwind.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ module.exports = {
116116
fontSize: {
117117
'2xs': '0.625rem',
118118
},
119+
transitionDuration: {
120+
250: '250ms',
121+
},
119122
borderColor: theme => ({
120123
default: theme('colors.neutral.400', 'cuurrentColor'),
121124
}),

0 commit comments

Comments
 (0)