UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

1 lines 4.24 kB
{"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,OAAW;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;EAAS,UAAU;aACjB,iBAAiB,oBAAC,YAAU,EAC7B,oBAAC;GAAI,KAAK;GAAY,OAAO,EAAE,SAAS,YAAY;GACjD;IACG;GACG;;AAIf,OAAO,cAAc;AAErB,qBAAe"}