{"version":3,"file":"Freeze.mjs","names":[],"sources":["../../src/Freeze/Freeze.tsx"],"sourcesContent":["// @see https://barvian.me/react-exit-animations\n\n'use client';\n\nimport { Suspense, useLayoutEffect, useRef } from 'react';\n\nimport type { FreezeProps } from './type';\n\nconst infinitePromise = new Promise<never>(() => {});\nconst Suspend = () => {\n  throw infinitePromise;\n};\n\nconst snapshotDisplays = (root: HTMLElement) => {\n  const snapshot = new Map<HTMLElement, string>([[root, root.style.display]]);\n\n  for (const element of root.querySelectorAll<HTMLElement>('*')) {\n    snapshot.set(element, element.style.display);\n  }\n\n  return snapshot;\n};\n\nconst restoreDisplayIfSuspenseHidden = (element: HTMLElement, originalDisplay: string) => {\n  if (element.style.display !== 'none') return;\n  if (originalDisplay === 'none') return;\n\n  element.style.display = originalDisplay;\n};\n\nconst restoreSuspenseHiddenDisplay = (snapshot: Map<HTMLElement, string>) => {\n  for (const [element, originalDisplay] of snapshot) {\n    restoreDisplayIfSuspenseHidden(element, originalDisplay);\n  }\n};\n\nconst Freeze = ({ frozen, children }: FreezeProps) => {\n  const contentRef = useRef<HTMLDivElement>(null);\n  const hasSnapshotRef = useRef(false);\n  const displaySnapshotRef = useRef<Map<HTMLElement, string>>(new Map());\n\n  const shouldSuspend = frozen && hasSnapshotRef.current;\n\n  useLayoutEffect(() => {\n    const content = contentRef.current;\n    if (!content) return;\n\n    if (!frozen) {\n      displaySnapshotRef.current = snapshotDisplays(content);\n      hasSnapshotRef.current = true;\n      return;\n    }\n\n    if (!hasSnapshotRef.current) {\n      displaySnapshotRef.current = snapshotDisplays(content);\n      hasSnapshotRef.current = true;\n      return;\n    }\n\n    restoreSuspenseHiddenDisplay(displaySnapshotRef.current);\n  });\n\n  useLayoutEffect(() => {\n    if (!shouldSuspend) return;\n\n    const snapshot = displaySnapshotRef.current;\n    const observer = new MutationObserver((mutations) => {\n      for (const mutation of mutations) {\n        const element = mutation.target as HTMLElement;\n        const originalDisplay = snapshot.get(element);\n        if (originalDisplay === undefined) continue;\n\n        restoreDisplayIfSuspenseHidden(element, originalDisplay);\n      }\n    });\n\n    for (const element of snapshot.keys()) {\n      observer.observe(element, { attributeFilter: ['style'], attributes: true });\n    }\n\n    restoreSuspenseHiddenDisplay(snapshot);\n\n    return () => observer.disconnect();\n  }, [shouldSuspend]);\n\n  return (\n    <Suspense fallback={null}>\n      {shouldSuspend && <Suspend />}\n      <div ref={contentRef} style={{ display: 'contents' }}>\n        {children}\n      </div>\n    </Suspense>\n  );\n};\n\nFreeze.displayName = 'Freeze';\n\nexport default Freeze;\n"],"mappings":";;;;AAQA,MAAM,kBAAkB,IAAI,cAAqB,CAAC,CAAC;AACnD,MAAM,gBAAgB;CACpB,MAAM;AACR;AAEA,MAAM,oBAAoB,SAAsB;CAC9C,MAAM,2BAAW,IAAI,IAAyB,CAAC,CAAC,MAAM,KAAK,MAAM,OAAO,CAAC,CAAC;CAE1E,KAAK,MAAM,WAAW,KAAK,iBAA8B,GAAG,GAC1D,SAAS,IAAI,SAAS,QAAQ,MAAM,OAAO;CAG7C,OAAO;AACT;AAEA,MAAM,kCAAkC,SAAsB,oBAA4B;CACxF,IAAI,QAAQ,MAAM,YAAY,QAAQ;CACtC,IAAI,oBAAoB,QAAQ;CAEhC,QAAQ,MAAM,UAAU;AAC1B;AAEA,MAAM,gCAAgC,aAAuC;CAC3E,KAAK,MAAM,CAAC,SAAS,oBAAoB,UACvC,+BAA+B,SAAS,eAAe;AAE3D;AAEA,MAAM,UAAU,EAAE,QAAQ,eAA4B;CACpD,MAAM,aAAa,OAAuB,IAAI;CAC9C,MAAM,iBAAiB,OAAO,KAAK;CACnC,MAAM,qBAAqB,uBAAiC,IAAI,IAAI,CAAC;CAErE,MAAM,gBAAgB,UAAU,eAAe;CAE/C,sBAAsB;EACpB,MAAM,UAAU,WAAW;EAC3B,IAAI,CAAC,SAAS;EAEd,IAAI,CAAC,QAAQ;GACX,mBAAmB,UAAU,iBAAiB,OAAO;GACrD,eAAe,UAAU;GACzB;EACF;EAEA,IAAI,CAAC,eAAe,SAAS;GAC3B,mBAAmB,UAAU,iBAAiB,OAAO;GACrD,eAAe,UAAU;GACzB;EACF;EAEA,6BAA6B,mBAAmB,OAAO;CACzD,CAAC;CAED,sBAAsB;EACpB,IAAI,CAAC,eAAe;EAEpB,MAAM,WAAW,mBAAmB;EACpC,MAAM,WAAW,IAAI,kBAAkB,cAAc;GACnD,KAAK,MAAM,YAAY,WAAW;IAChC,MAAM,UAAU,SAAS;IACzB,MAAM,kBAAkB,SAAS,IAAI,OAAO;IAC5C,IAAI,oBAAoB,KAAA,GAAW;IAEnC,+BAA+B,SAAS,eAAe;GACzD;EACF,CAAC;EAED,KAAK,MAAM,WAAW,SAAS,KAAK,GAClC,SAAS,QAAQ,SAAS;GAAE,iBAAiB,CAAC,OAAO;GAAG,YAAY;EAAK,CAAC;EAG5E,6BAA6B,QAAQ;EAErC,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,aAAa,CAAC;CAElB,OACE,qBAAC,UAAD;EAAU,UAAU;YAApB,CACG,iBAAiB,oBAAC,SAAD,CAAU,CAAA,GAC5B,oBAAC,OAAD;GAAK,KAAK;GAAY,OAAO,EAAE,SAAS,WAAW;GAChD;EACE,CAAA,CACG;;AAEd;AAEA,OAAO,cAAc"}