{"version":3,"file":"usePortal.cjs","sources":["../../src/hooks/usePortal.tsx"],"sourcesContent":["import {\n  type FC,\n  type ReactNode,\n  createContext,\n  useCallback,\n  useContext,\n  useMemo,\n  useState,\n} from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useEnhancedEffect } from './useEnhancedEffect'\n\ntype ParentContextValue = {\n  seqs: number[]\n}\n\nconst ParentContext = createContext<ParentContextValue>({\n  seqs: [],\n})\n\nlet portalSeq = 0\n\nexport function usePortal() {\n  const [portalRoot, setPortalRoot] = useState<HTMLDivElement | null>(null)\n  const currentSeq = useMemo(() => ++portalSeq, [])\n  const parent = useContext(ParentContext)\n\n  const calculatedSeqs = useMemo(() => {\n    const parentSeqs = parent.seqs.concat(currentSeq)\n\n    return {\n      parentSeqs,\n      portalChildOf: parentSeqs.join(','),\n    }\n  }, [currentSeq, parent.seqs])\n\n  useEnhancedEffect(() => {\n    // Next.jsのhydration error回避のため、初回レンダリング時にdivを作成する\n    setPortalRoot(document.createElement('div'))\n  }, [])\n\n  useEnhancedEffect(() => {\n    if (!portalRoot) {\n      return\n    }\n\n    portalRoot.dataset.portalChildOf = calculatedSeqs.portalChildOf\n    document.body.appendChild(portalRoot)\n\n    return () => {\n      document.body.removeChild(portalRoot)\n    }\n  }, [portalRoot, calculatedSeqs.portalChildOf])\n\n  const isChildPortal = useCallback(\n    (element: HTMLElement | null) => _isChildPortal(element, new RegExp(`(^|,)${currentSeq}(,|$)`)),\n    [currentSeq],\n  )\n\n  const PortalParentProvider: FC<{ children: ReactNode }> = useCallback(\n    ({ children }) => {\n      const value: ParentContextValue = {\n        seqs: calculatedSeqs.parentSeqs,\n      }\n\n      return <ParentContext.Provider value={value}>{children}</ParentContext.Provider>\n    },\n    [calculatedSeqs.parentSeqs],\n  )\n\n  const wrappedCreatePortal = useCallback(\n    (children: ReactNode) => {\n      if (portalRoot === null) {\n        return null\n      }\n\n      return createPortal(children, portalRoot)\n    },\n    [portalRoot],\n  )\n\n  const isPortalRootMounted = useCallback(() => portalRoot !== null, [portalRoot])\n\n  return {\n    portalRoot,\n    isPortalRootMounted,\n    isChildPortal,\n    PortalParentProvider,\n    createPortal: wrappedCreatePortal,\n  }\n}\n\nfunction _isChildPortal(element: HTMLElement | SVGElement | null, seqRegex: RegExp): boolean {\n  if (!element) return false\n\n  let includesSeq = false\n  const childOf = element.dataset?.portalChildOf\n\n  if (childOf) {\n    includesSeq = seqRegex.test(childOf)\n  }\n\n  return includesSeq || _isChildPortal(element.parentElement, seqRegex)\n}\n"],"names":["createContext","useState","useMemo","useContext","useEnhancedEffect","useCallback","_jsx","createPortal"],"mappings":"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"}