feat: update dialog component to headlessui (#159)

This commit is contained in:
Razboy20
2024-03-13 23:09:43 -05:00
committed by GitHub
parent df7a7c65d6
commit 442be8cbee
8 changed files with 149 additions and 170 deletions

View File

@@ -0,0 +1,58 @@
import type { TransitionRootProps } from '@headlessui/react';
import { Dialog as HDialog, Transition } from '@headlessui/react';
import clsx from 'clsx';
import type { PropsWithChildren } from 'react';
import React, { Fragment } from 'react';
export interface _DialogProps {
className?: string;
title?: JSX.Element;
description?: JSX.Element;
}
export type DialogProps = _DialogProps & Omit<TransitionRootProps<typeof HDialog>, 'children'>;
/**
* A reusable popup component that can be used to display content on the page
*/
export default function Dialog(props: PropsWithChildren<DialogProps>): JSX.Element {
const { children, className, open, onTransitionEnd, ...rest } = props;
return (
<Transition show={open} as={HDialog} {...rest}>
<Transition.Child
as={Fragment}
enter='transition duration-300 ease-out'
enterFrom='opacity-0'
enterTo='opacity-100'
leave='transition duration-150 ease-in delay-25'
leaveFrom='opacity-100'
leaveTo='opacity-0'
>
<div className={clsx('fixed inset-0 z-50 bg-neutral-500/25')} />
</Transition.Child>
<Transition.Child
as={Fragment}
enter='transition duration-400 ease-[cubic-bezier(0.15,0.3,0.2,1)]'
enterFrom='transform scale-95 opacity-0'
enterTo='transform scale-100 opacity-100'
leave='transition duration-250 ease-[cubic-bezier(0.23,0.01,0.92,0.72)]'
leaveFrom='transform scale-100 opacity-100'
leaveTo='transform scale-95 opacity-0'
>
<div className='fixed inset-0 z-50 flex items-center justify-center'>
<HDialog.Panel
className={clsx(
'z-99 max-h-[80vh] flex flex-col overflow-y-scroll rounded bg-white shadow-xl',
className
)}
>
{props.title && <HDialog.Title>{props.title}</HDialog.Title>}
{props.description && <HDialog.Description>{props.description}</HDialog.Description>}
{children}
</HDialog.Panel>
</div>
</Transition.Child>
</Transition>
);
}

View File

@@ -1,24 +0,0 @@
@use 'src/views/styles/colors.module.scss';
.container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
&.overlay {
background-color: rgba(0, 0, 0, 0.5);
z-index: 2147483647;
}
}
.body {
overflow-y: auto;
z-index: 2147483647;
background-color: colors.$white;
box-shadow: 0px 12px 30px 0px #323e5f29;
transition: box-shadow 0.15s;
}

View File

@@ -1,65 +0,0 @@
import clsx from 'clsx';
import type { PropsWithChildren } from 'react';
import React, { useCallback } from 'react';
import styles from './Popup.module.scss';
interface Props {
testId?: string;
style?: React.CSSProperties;
className?: string;
/** Should it display a subtle dark overlay over the rest of the screen */
overlay?: boolean;
onClose?: () => void;
}
/**
* A reusable popup component that can be used to display content on the page
*/
export default function Popup({
onClose,
children,
className,
style,
testId,
overlay,
}: PropsWithChildren<Props>): JSX.Element {
const containerRef = React.useRef<HTMLDivElement>(null);
const bodyRef = React.useRef<HTMLDivElement>(null);
const handleClickOutside = useCallback(
(event: MouseEvent) => {
if (!bodyRef.current) return;
if (!bodyRef.current.contains(event.target as Node)) {
onClose?.();
}
},
[onClose, bodyRef]
);
React.useEffect(() => {
const shadowRoot = document.getElementById('ut-registration-plus-container')?.shadowRoot;
if (!shadowRoot) return;
shadowRoot.addEventListener('mousedown', handleClickOutside);
return () => {
shadowRoot.removeEventListener('mousedown', handleClickOutside);
};
}, [handleClickOutside]);
return (
<div
style={style}
ref={containerRef}
className={clsx(styles.container, {
[styles.overlay]: overlay,
})}
data-testid={testId}
>
<div ref={bodyRef} className={clsx(styles.body, className)}>
{children}
</div>
</div>
);
}