import React, { FC, ReactNode, RefObject, useEffect, useRef, useState } from 'react' import ReactDOM from 'react-dom' import Button from '../button' import Modal from './modal' type LaunchModalProps = { blurId?: string, button?: boolean, children: ReactNode, launchText?: string, modalId: string, size?: string, title: string, variant?: string, [other:string]: unknown } const addARIAHidden = (elements: Element[], modalId: string): void => { for (let i: number = 0; i < elements.length; i++) { if (elements[i].id !== modalId) { elements[i].setAttribute('aria-hidden', 'true') } } } const removeARIAHidden = (elements: Element[]): void => { for (let i: number = 0; i < elements.length; i++) { elements[i].removeAttribute('aria-hidden') } } const getBodyNonScriptChildren = (): Element[] => { const bodyChildren: HTMLCollection = document.body.children let nonScriptChildren: Element[] = [] const excludeTags: string[] = ['SCRIPT', 'NOSCRIPT'] for (let i: number = 0; i < bodyChildren.length; i++) { if (!excludeTags.includes(bodyChildren[i].tagName)) { nonScriptChildren.push(bodyChildren[i]) } } return nonScriptChildren } const focusLaunchElement = (ref: RefObject | null): void => { if (!ref || !ref.current) { return } const button: HTMLButtonElement | null = ref.current.querySelector('button') if (button) { button.focus() } } const LaunchModal:FC = ({ blurId='', button, children, launchText, modalId, size='sm', title, variant='outline-indigo', ...other }: LaunchModalProps) => { const [showModal, setShowModal] = useState(false) const launchRef = useRef(null) useEffect(() => { if (showModal) { addARIAHidden(getBodyNonScriptChildren(), modalId) return } focusLaunchElement(launchRef) removeARIAHidden(getBodyNonScriptChildren()) }, [modalId, launchRef, showModal]) return (
{button ? : } {typeof(window) !== `undefined` && ReactDOM.createPortal( setShowModal(false)} setModalOpen={() => setShowModal(true)} title={title} > {children} , document.body ) }
) } export default LaunchModal