{"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,GAAG;AACpD,MAAM,gBAAgB;AACpB,OAAM;;AAGR,MAAM,oBAAoB,SAAsB;CAC9C,MAAM,WAAW,IAAI,IAAyB,CAAC,CAAC,MAAM,KAAK,MAAM,QAAQ,CAAC,CAAC;AAE3E,MAAK,MAAM,WAAW,KAAK,iBAA8B,IAAI,CAC3D,UAAS,IAAI,SAAS,QAAQ,MAAM,QAAQ;AAG9C,QAAO;;AAGT,MAAM,kCAAkC,SAAsB,oBAA4B;AACxF,KAAI,QAAQ,MAAM,YAAY,OAAQ;AACtC,KAAI,oBAAoB,OAAQ;AAEhC,SAAQ,MAAM,UAAU;;AAG1B,MAAM,gCAAgC,aAAuC;AAC3E,MAAK,MAAM,CAAC,SAAS,oBAAoB,SACvC,gCAA+B,SAAS,gBAAgB;;AAI5D,MAAM,UAAU,EAAE,QAAQ,eAA4B;CACpD,MAAM,aAAa,OAAuB,KAAK;CAC/C,MAAM,iBAAiB,OAAO,MAAM;CACpC,MAAM,qBAAqB,uBAAiC,IAAI,KAAK,CAAC;CAEtE,MAAM,gBAAgB,UAAU,eAAe;AAE/C,uBAAsB;EACpB,MAAM,UAAU,WAAW;AAC3B,MAAI,CAAC,QAAS;AAEd,MAAI,CAAC,QAAQ;AACX,sBAAmB,UAAU,iBAAiB,QAAQ;AACtD,kBAAe,UAAU;AACzB;;AAGF,MAAI,CAAC,eAAe,SAAS;AAC3B,sBAAmB,UAAU,iBAAiB,QAAQ;AACtD,kBAAe,UAAU;AACzB;;AAGF,+BAA6B,mBAAmB,QAAQ;GACxD;AAEF,uBAAsB;AACpB,MAAI,CAAC,cAAe;EAEpB,MAAM,WAAW,mBAAmB;EACpC,MAAM,WAAW,IAAI,kBAAkB,cAAc;AACnD,QAAK,MAAM,YAAY,WAAW;IAChC,MAAM,UAAU,SAAS;IACzB,MAAM,kBAAkB,SAAS,IAAI,QAAQ;AAC7C,QAAI,oBAAoB,KAAA,EAAW;AAEnC,mCAA+B,SAAS,gBAAgB;;IAE1D;AAEF,OAAK,MAAM,WAAW,SAAS,MAAM,CACnC,UAAS,QAAQ,SAAS;GAAE,iBAAiB,CAAC,QAAQ;GAAE,YAAY;GAAM,CAAC;AAG7E,+BAA6B,SAAS;AAEtC,eAAa,SAAS,YAAY;IACjC,CAAC,cAAc,CAAC;AAEnB,QACE,qBAAC,UAAD;EAAU,UAAU;YAApB,CACG,iBAAiB,oBAAC,SAAD,EAAW,CAAA,EAC7B,oBAAC,OAAD;GAAK,KAAK;GAAY,OAAO,EAAE,SAAS,YAAY;GACjD;GACG,CAAA,CACG;;;AAIf,OAAO,cAAc"}