UNPKG

@lobehub/ui

Version:

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

1 lines • 5.88 kB
{"version":3,"file":"ToastDodge.mjs","names":[],"sources":["../../../src/base-ui/FloatingPanel/ToastDodge.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\nimport {\n PANEL_ALIGN_INLINE_VAR,\n PANEL_RESERVE_VAR,\n resolveToastDodge,\n TOAST_SHIFT_X_VAR,\n TOAST_SHIFT_Y_VAR,\n TOAST_WIDTH,\n TOAST_WIDTH_VAR,\n} from '../Toast/dodge';\n\nconst TOAST_VARS = [TOAST_SHIFT_X_VAR, TOAST_SHIFT_Y_VAR, TOAST_WIDTH_VAR];\n\n// A closing panel unmounts after its exit animation, so it can outlive the\n// panel that replaced it. Only the panel that wrote the vars may clear them.\nlet owner: object | undefined;\n\n// Mounted inside the panel so it lives exactly as long as the panel does, and\n// reads its own parentElement to measure it.\nexport const ToastDodge = () => {\n const probeRef = useRef<HTMLSpanElement>(null);\n const reserveRef = useRef(0);\n const tokenRef = useRef({});\n const insetRef = useRef<{ x: number; y: number }>(undefined);\n\n useEffect(() => {\n const root = document.documentElement;\n const panel = probeRef.current?.parentElement;\n\n const token = tokenRef.current;\n const wrapper = panel?.parentElement;\n const clear = () => {\n reserveRef.current = 0;\n // The reserve lives on this panel's own wrapper, so it is always ours to\n // drop; the toast vars are global and only the last writer may clear them.\n if (wrapper instanceof HTMLElement) {\n wrapper.style.removeProperty(PANEL_RESERVE_VAR);\n wrapper.style.removeProperty(PANEL_ALIGN_INLINE_VAR);\n }\n if (owner !== token) return;\n owner = undefined;\n for (const name of TOAST_VARS) root.style.removeProperty(name);\n };\n\n if (!panel) return;\n\n const apply = () => {\n if (!(panel instanceof HTMLElement) || !(wrapper instanceof HTMLElement)) return;\n // Read the resting insets once, before anything is reserved: the wrapper\n // padding animates, so sampling it later feeds the transition's midpoint\n // back into the verdict and the reserve ratchets upward every frame.\n if (!insetRef.current) {\n const padding = getComputedStyle(wrapper);\n insetRef.current = {\n x: Number.parseFloat(padding.paddingInlineEnd) || 0,\n y: Number.parseFloat(padding.paddingBlockEnd) || 0,\n };\n }\n // Layout size, never getBoundingClientRect: the rect carries the entrance\n // animation's transform, so measuring mid-flight reports a scaled-down\n // panel and the toast lands short of the gutter.\n const inset = insetRef.current;\n // Measure the panel as if it were not already yielding, otherwise the\n // reserve it applies shrinks the panel and flips the next verdict.\n // Only add the reserve back when max-height is what is holding the panel\n // down; a panel shorter than its cap was never shrunk by it.\n const maxHeight = Number.parseFloat(getComputedStyle(panel).maxHeight);\n const reserved = reserveRef.current;\n const clamped = panel.offsetHeight >= maxHeight - 0.5 ? reserved : 0;\n const dodge = resolveToastDodge({\n panelHeight: panel.offsetHeight + clamped,\n panelOffsetX: inset.x,\n panelOffsetY: inset.y,\n panelWidth: panel.offsetWidth,\n viewportHeight: wrapper.clientHeight,\n viewportWidth: wrapper.clientWidth,\n });\n\n owner = token;\n reserveRef.current = dodge.reserve;\n root.style.setProperty(TOAST_SHIFT_X_VAR, `${dodge.shiftX}px`);\n root.style.setProperty(TOAST_SHIFT_Y_VAR, `${dodge.shiftY}px`);\n wrapper.style.setProperty(PANEL_RESERVE_VAR, `${dodge.reserve}px`);\n wrapper.style.setProperty(PANEL_ALIGN_INLINE_VAR, `${dodge.alignInline}px`);\n if (dodge.width === TOAST_WIDTH) root.style.removeProperty(TOAST_WIDTH_VAR);\n else root.style.setProperty(TOAST_WIDTH_VAR, `${dodge.width}px`);\n };\n\n const observer = new ResizeObserver(apply);\n observer.observe(panel);\n window.addEventListener('resize', apply);\n apply();\n\n return () => {\n observer.disconnect();\n window.removeEventListener('resize', apply);\n clear();\n };\n }, []);\n\n return <span aria-hidden hidden ref={probeRef} />;\n};\n"],"mappings":";;;;AAYA,MAAM,aAAa;CAAC;CAAmB;CAAmB;AAAe;AAIzE,IAAI;AAIJ,MAAa,mBAAmB;CAC9B,MAAM,WAAW,OAAwB,IAAI;CAC7C,MAAM,aAAa,OAAO,CAAC;CAC3B,MAAM,WAAW,OAAO,CAAC,CAAC;CAC1B,MAAM,WAAW,OAAiC,KAAA,CAAS;CAE3D,gBAAgB;EACd,MAAM,OAAO,SAAS;EACtB,MAAM,QAAQ,SAAS,SAAS;EAEhC,MAAM,QAAQ,SAAS;EACvB,MAAM,UAAU,OAAO;EACvB,MAAM,cAAc;GAClB,WAAW,UAAU;GAGrB,IAAI,mBAAmB,aAAa;IAClC,QAAQ,MAAM,eAAe,iBAAiB;IAC9C,QAAQ,MAAM,eAAe,sBAAsB;GACrD;GACA,IAAI,UAAU,OAAO;GACrB,QAAQ,KAAA;GACR,KAAK,MAAM,QAAQ,YAAY,KAAK,MAAM,eAAe,IAAI;EAC/D;EAEA,IAAI,CAAC,OAAO;EAEZ,MAAM,cAAc;GAClB,IAAI,EAAE,iBAAiB,gBAAgB,EAAE,mBAAmB,cAAc;GAI1E,IAAI,CAAC,SAAS,SAAS;IACrB,MAAM,UAAU,iBAAiB,OAAO;IACxC,SAAS,UAAU;KACjB,GAAG,OAAO,WAAW,QAAQ,gBAAgB,KAAK;KAClD,GAAG,OAAO,WAAW,QAAQ,eAAe,KAAK;IACnD;GACF;GAIA,MAAM,QAAQ,SAAS;GAKvB,MAAM,YAAY,OAAO,WAAW,iBAAiB,KAAK,CAAC,CAAC,SAAS;GACrE,MAAM,WAAW,WAAW;GAC5B,MAAM,UAAU,MAAM,gBAAgB,YAAY,KAAM,WAAW;GACnE,MAAM,QAAQ,kBAAkB;IAC9B,aAAa,MAAM,eAAe;IAClC,cAAc,MAAM;IACpB,cAAc,MAAM;IACpB,YAAY,MAAM;IAClB,gBAAgB,QAAQ;IACxB,eAAe,QAAQ;GACzB,CAAC;GAED,QAAQ;GACR,WAAW,UAAU,MAAM;GAC3B,KAAK,MAAM,YAAY,mBAAmB,GAAG,MAAM,OAAO,GAAG;GAC7D,KAAK,MAAM,YAAY,mBAAmB,GAAG,MAAM,OAAO,GAAG;GAC7D,QAAQ,MAAM,YAAY,mBAAmB,GAAG,MAAM,QAAQ,GAAG;GACjE,QAAQ,MAAM,YAAY,wBAAwB,GAAG,MAAM,YAAY,GAAG;GAC1E,IAAI,MAAM,UAAA,KAAuB,KAAK,MAAM,eAAe,eAAe;QACrE,KAAK,MAAM,YAAY,iBAAiB,GAAG,MAAM,MAAM,GAAG;EACjE;EAEA,MAAM,WAAW,IAAI,eAAe,KAAK;EACzC,SAAS,QAAQ,KAAK;EACtB,OAAO,iBAAiB,UAAU,KAAK;EACvC,MAAM;EAEN,aAAa;GACX,SAAS,WAAW;GACpB,OAAO,oBAAoB,UAAU,KAAK;GAC1C,MAAM;EACR;CACF,GAAG,CAAC,CAAC;CAEL,OAAO,oBAAC,QAAD;EAAM,eAAA;EAAY,QAAA;EAAO,KAAK;CAAW,CAAA;AAClD"}