UNPKG

@lobehub/ui

Version:

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

1 lines 5.87 kB
{"version":3,"file":"ParentSize.mjs","names":["defaultIgnoreDimensions: ParentSizeProps['ignoreDimensions']"],"sources":["../../../src/awesome/Spline/ParentSize.tsx"],"sourcesContent":["import { debounce } from 'es-toolkit/compat';\nimport {\n type CSSProperties,\n type ReactNode,\n type Ref,\n memo,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { mergeRefs } from 'react-merge-refs';\n\ninterface ResizeObserverCallback {\n (entries: ResizeObserverEntry[], observer: ResizeObserver): void;\n}\n\ninterface ResizeObserverPolyfill {\n new (callback: ResizeObserverCallback): ResizeObserver;\n}\n\n// @TODO remove when upgraded to TS 4 which has its own declaration\ninterface PrivateWindow {\n ResizeObserver: ResizeObserverPolyfill;\n}\n\nexport interface ParentSizeProps {\n /** Child render function `({ width, height, top, left, ref, resize }) => ReactNode`. */\n children: (\n args: {\n ref: HTMLDivElement | null;\n resize: (state: ParentSizeState) => void;\n } & ParentSizeState,\n ) => ReactNode;\n /** Optional `className` to add to the parent `div` wrapper used for size measurement. */\n className?: string;\n /** Child render updates upon resize are delayed until `debounceTime` milliseconds _after_ the last resize event is observed. */\n debounceTime?: number;\n /** Optional flag to toggle leading debounce calls. When set to true this will ensure that the component always renders immediately. (defaults to true) */\n enableDebounceLeadingCall?: boolean;\n /** Optional dimensions provided won't trigger a state change when changed. */\n ignoreDimensions?: keyof ParentSizeState | (keyof ParentSizeState)[];\n /** Optional `style` object to apply to the parent `div` wrapper used for size measurement. */\n parentSizeStyles?: CSSProperties;\n ref?: Ref<HTMLDivElement>;\n /** Optionally inject a ResizeObserver polyfill, else this *must* be globally available. */\n resizeObserverPolyfill?: ResizeObserverPolyfill;\n}\n\ntype ParentSizeState = {\n height: number;\n left: number;\n top: number;\n width: number;\n};\n\nexport type ParentSizeProvidedProps = ParentSizeState;\n\nconst defaultIgnoreDimensions: ParentSizeProps['ignoreDimensions'] = [];\nconst defaultParentSizeStyles = { height: '100%', width: '100%' };\n\nconst ParentSize = memo<ParentSizeProps>(\n ({\n ref,\n className,\n children,\n debounceTime = 300,\n ignoreDimensions = defaultIgnoreDimensions,\n parentSizeStyles,\n enableDebounceLeadingCall = true,\n resizeObserverPolyfill,\n ...restProps\n }) => {\n const target = useRef<HTMLDivElement | null>(null);\n const animationFrameID = useRef(0);\n\n const [state, setState] = useState<ParentSizeState>({\n height: 0,\n left: 0,\n top: 0,\n width: 0,\n });\n\n const resize = useMemo(() => {\n const normalized = Array.isArray(ignoreDimensions) ? ignoreDimensions : [ignoreDimensions];\n\n return debounce(\n (incoming: ParentSizeState) => {\n setState((existing) => {\n const stateKeys = Object.keys(existing) as (keyof ParentSizeState)[];\n const keysWithChanges = stateKeys.filter((key) => existing[key] !== incoming[key]);\n const shouldBail = keysWithChanges.every((key) => normalized.includes(key));\n\n return shouldBail ? existing : incoming;\n });\n },\n debounceTime,\n { leading: enableDebounceLeadingCall },\n );\n }, [debounceTime, enableDebounceLeadingCall, ignoreDimensions]);\n\n useEffect(() => {\n const LocalResizeObserver =\n resizeObserverPolyfill || (window as unknown as PrivateWindow).ResizeObserver;\n\n const observer = new LocalResizeObserver((entries) => {\n for (const entry of entries) {\n const { left, top, width, height } = entry?.contentRect ?? {};\n animationFrameID.current = window.requestAnimationFrame(() => {\n resize({ height, left, top, width });\n });\n }\n });\n if (target.current) observer.observe(target.current);\n\n return () => {\n window.cancelAnimationFrame(animationFrameID.current);\n observer.disconnect();\n resize.cancel();\n };\n }, [resize, resizeObserverPolyfill]);\n\n return (\n <div\n className={className}\n ref={mergeRefs<HTMLDivElement>([ref, target])}\n style={{ ...defaultParentSizeStyles, ...parentSizeStyles }}\n {...restProps}\n >\n {children({\n ...state,\n ref: target.current,\n resize,\n })}\n </div>\n );\n },\n);\n\nexport default ParentSize;\n"],"mappings":";;;;;;AA0DA,MAAMA,0BAA+D,EAAE;AACvE,MAAM,0BAA0B;CAAE,QAAQ;CAAQ,OAAO;CAAQ;AAEjE,MAAM,aAAa,MAChB,EACC,KACA,WACA,UACA,eAAe,KACf,mBAAmB,yBACnB,kBACA,4BAA4B,MAC5B,wBACA,GAAG,gBACC;CACJ,MAAM,SAAS,OAA8B,KAAK;CAClD,MAAM,mBAAmB,OAAO,EAAE;CAElC,MAAM,CAAC,OAAO,YAAY,SAA0B;EAClD,QAAQ;EACR,MAAM;EACN,KAAK;EACL,OAAO;EACR,CAAC;CAEF,MAAM,SAAS,cAAc;EAC3B,MAAM,aAAa,MAAM,QAAQ,iBAAiB,GAAG,mBAAmB,CAAC,iBAAiB;AAE1F,SAAO,UACJ,aAA8B;AAC7B,aAAU,aAAa;AAKrB,WAJkB,OAAO,KAAK,SAAS,CACL,QAAQ,QAAQ,SAAS,SAAS,SAAS,KAAK,CAC/C,OAAO,QAAQ,WAAW,SAAS,IAAI,CAAC,GAEvD,WAAW;KAC/B;KAEJ,cACA,EAAE,SAAS,2BAA2B,CACvC;IACA;EAAC;EAAc;EAA2B;EAAiB,CAAC;AAE/D,iBAAgB;EAId,MAAM,WAAW,KAFf,0BAA2B,OAAoC,iBAEvB,YAAY;AACpD,QAAK,MAAM,SAAS,SAAS;IAC3B,MAAM,EAAE,MAAM,KAAK,OAAO,WAAW,OAAO,eAAe,EAAE;AAC7D,qBAAiB,UAAU,OAAO,4BAA4B;AAC5D,YAAO;MAAE;MAAQ;MAAM;MAAK;MAAO,CAAC;MACpC;;IAEJ;AACF,MAAI,OAAO,QAAS,UAAS,QAAQ,OAAO,QAAQ;AAEpD,eAAa;AACX,UAAO,qBAAqB,iBAAiB,QAAQ;AACrD,YAAS,YAAY;AACrB,UAAO,QAAQ;;IAEhB,CAAC,QAAQ,uBAAuB,CAAC;AAEpC,QACE,oBAAC;EACY;EACX,KAAK,UAA0B,CAAC,KAAK,OAAO,CAAC;EAC7C,OAAO;GAAE,GAAG;GAAyB,GAAG;GAAkB;EAC1D,GAAI;YAEH,SAAS;GACR,GAAG;GACH,KAAK,OAAO;GACZ;GACD,CAAC;GACE;EAGX;AAED,yBAAe"}