Focus traps for dialog and dropdown

This commit is contained in:
Gregory Schier
2023-03-26 23:07:09 -07:00
parent b2dcc38982
commit 4f501abb72
11 changed files with 169 additions and 71 deletions

View File

@@ -1,13 +1,14 @@
import classnames from 'classnames';
import FocusTrap from 'focus-trap-react';
import type { ReactNode } from 'react';
import { motion } from 'framer-motion';
import { Portal } from './Portal';
interface Props {
children: ReactNode;
onClick?: () => void;
portalName: string;
open: boolean;
onClose?: () => void;
zIndex?: keyof typeof zIndexes;
}
@@ -19,22 +20,24 @@ const zIndexes: Record<number, string> = {
50: 'z-50',
};
export function Overlay({ zIndex = 30, open, children, onClick, portalName }: Props) {
export function Overlay({ zIndex = 30, open, onClose, portalName, children }: Props) {
return (
<Portal name={portalName}>
{open && (
<motion.div
className={classnames('fixed inset-0', zIndexes[zIndex])}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
>
<div
aria-hidden
onClick={onClick}
className="absolute inset-0 bg-gray-600/60 dark:bg-black/50"
/>
{children}
</motion.div>
<FocusTrap>
<motion.div
className={classnames('fixed inset-0', zIndexes[zIndex])}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
>
<div
aria-hidden
onClick={onClose}
className="absolute inset-0 bg-gray-600/60 dark:bg-black/50"
/>
{children}
</motion.div>
</FocusTrap>
)}
</Portal>
);