import classNames from 'classnames'; import { FocusTrap } from 'focus-trap-react'; import * as m from 'motion/react-m'; import type { ReactNode } from 'react'; import React, { useRef } from 'react'; import { Portal } from './Portal'; interface Props { children: ReactNode; portalName: string; open: boolean; onClose?: () => void; zIndex?: keyof typeof zIndexes; variant?: 'default' | 'transparent'; noBackdrop?: boolean; } const zIndexes: Record = { 10: 'z-10', 20: 'z-20', 30: 'z-30', 40: 'z-40', 50: 'z-50', }; export function Overlay({ variant = 'default', zIndex = 30, open, onClose, portalName, noBackdrop, children, }: Props) { const containerRef = useRef(null); if (noBackdrop) { return ( {open && ( {/* NOTE:
wrapper is required for some reason, or FocusTrap complains */}
{children}
)} ); } return ( {open && ( containerRef.current!, // always have a target initialFocus: () => // Doing this explicitly seems to work better than the default behavior for some reason containerRef.current?.querySelector( [ 'a[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', '[tabindex]:not([tabindex="-1"])', '[contenteditable]:not([contenteditable="false"])', ].join(', '), ) ?? undefined, }} >
{/* Show the draggable region at the top */} {/* TODO: Figure out tauri drag region and also make clickable still */} {variant === 'default' && (
)} {children} )} ); }