UNPKG

@nex-ui/react

Version:

🎉 A beautiful, modern, and reliable React component library.

72 lines (69 loc) • 2.11 kB
"use client"; import { jsx } from 'react/jsx-runtime'; import { useState, useEffect, useMemo } from 'react'; import { defineRecipe } from '@nex-ui/system'; import { useModal } from './ModalContext.mjs'; import { useModalManager } from './ModalManager.mjs'; import { useSlot } from '../utils/useSlot.mjs'; import { FocusTrap } from '../focusTrap/FocusTrap.mjs'; const recipe = defineRecipe({ base: { width: 'full', position: 'relative', display: 'flex', flexDirection: 'column', outline: 'none', bg: 'content' } }); const style = recipe(); const useAriaProps = (props)=>{ const { modalContentId, modalHeaderId, modalBodyId } = useModal(); const { tabIndex = -1, id = modalContentId, 'aria-labelledby': labelledBy = modalHeaderId, 'aria-describedby': describedBy = modalBodyId } = props; return useMemo(()=>{ return { tabIndex, id, 'aria-labelledby': labelledBy, 'aria-describedby': describedBy }; }, [ describedBy, id, labelledBy, tabIndex ]); }; const ModalContent = (inProps)=>{ const props = inProps; const ctx = useModal(); const [paused, setPaused] = useState(false); const modalManager = useModalManager(); const { isTopmostModal } = ctx; const ariaProps = useAriaProps(props); const [ModalContentRoot, getModalContentRootProps] = useSlot({ style, elementType: 'section', externalForwardedProps: props, a11y: ariaProps }); useEffect(()=>{ const unsubscribe = modalManager.subscribe(()=>{ setPaused(!isTopmostModal?.()); }); return unsubscribe; }, [ isTopmostModal, modalManager ]); return /*#__PURE__*/ jsx(FocusTrap, { active: ctx.open, restoreFocus: ctx.restoreFocus, paused: paused, children: /*#__PURE__*/ jsx(ModalContentRoot, { ...getModalContentRootProps() }) }); }; ModalContent.displayName = 'ModalContent'; export { ModalContent };