UNPKG

@lobehub/ui

Version:

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

1 lines 4.16 kB
{"version":3,"file":"useScrollOverflow.mjs","names":[],"sources":["../../src/ScrollShadow/useScrollOverflow.ts"],"sourcesContent":["import { type RefObject, useEffect, useRef, useState } from 'react';\n\ninterface ScrollState {\n bottom: boolean;\n left: boolean;\n right: boolean;\n top: boolean;\n}\n\nconst initialScrollState: ScrollState = {\n bottom: false,\n left: false,\n right: false,\n top: false,\n};\n\nconst isSameScrollState = (a: ScrollState, b: ScrollState) =>\n a.bottom === b.bottom && a.left === b.left && a.right === b.right && a.top === b.top;\n\ninterface UseScrollOverflowProps {\n domRef: RefObject<HTMLElement | null>;\n isEnabled?: boolean;\n offset?: number;\n onVisibilityChange?: (visibility: {\n bottom?: boolean;\n left?: boolean;\n right?: boolean;\n top?: boolean;\n }) => void;\n orientation?: 'vertical' | 'horizontal';\n updateDeps?: any[];\n}\n\nexport const useScrollOverflow = ({\n domRef,\n offset = 0,\n orientation = 'vertical',\n isEnabled = true,\n onVisibilityChange,\n updateDeps = [],\n}: UseScrollOverflowProps) => {\n const [scrollState, setScrollState] = useState(initialScrollState);\n const scrollStateRef = useRef(initialScrollState);\n\n useEffect(() => {\n const element = domRef.current;\n if (!element || !isEnabled) return;\n\n const checkScroll = () => {\n const newState = { ...initialScrollState };\n\n if (orientation === 'vertical') {\n const hasVerticalScroll = element.scrollHeight > element.clientHeight;\n\n if (hasVerticalScroll) {\n newState.top = element.scrollTop > offset;\n newState.bottom =\n element.scrollTop + element.clientHeight < element.scrollHeight - offset;\n } else {\n newState.top = false;\n newState.bottom = false;\n }\n } else {\n const hasHorizontalScroll = element.scrollWidth > element.clientWidth;\n\n if (hasHorizontalScroll) {\n newState.left = element.scrollLeft > offset;\n newState.right = element.scrollLeft + element.clientWidth < element.scrollWidth - offset;\n } else {\n newState.left = false;\n newState.right = false;\n }\n }\n\n if (isSameScrollState(scrollStateRef.current, newState)) return;\n\n scrollStateRef.current = newState;\n setScrollState(newState);\n onVisibilityChange?.(newState);\n };\n\n // 初始检查\n checkScroll();\n\n // 监听滚动事件\n element.addEventListener('scroll', checkScroll);\n window.addEventListener('resize', checkScroll);\n\n // 观察内容变化\n const resizeObserver = new ResizeObserver(checkScroll);\n resizeObserver.observe(element);\n\n return () => {\n element.removeEventListener('scroll', checkScroll);\n window.removeEventListener('resize', checkScroll);\n resizeObserver.disconnect();\n };\n }, [domRef, offset, orientation, isEnabled, ...updateDeps]);\n\n return scrollState;\n};\n"],"mappings":";;AASA,MAAM,qBAAkC;CACtC,QAAQ;CACR,MAAM;CACN,OAAO;CACP,KAAK;AACP;AAEA,MAAM,qBAAqB,GAAgB,MACzC,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE;AAgBnF,MAAa,qBAAqB,EAChC,QACA,SAAS,GACT,cAAc,YACd,YAAY,MACZ,oBACA,aAAa,CAAC,QACc;CAC5B,MAAM,CAAC,aAAa,kBAAkB,SAAS,kBAAkB;CACjE,MAAM,iBAAiB,OAAO,kBAAkB;CAEhD,gBAAgB;EACd,MAAM,UAAU,OAAO;EACvB,IAAI,CAAC,WAAW,CAAC,WAAW;EAE5B,MAAM,oBAAoB;GACxB,MAAM,WAAW,EAAE,GAAG,mBAAmB;GAEzC,IAAI,gBAAgB,YAGlB,IAF0B,QAAQ,eAAe,QAAQ,cAElC;IACrB,SAAS,MAAM,QAAQ,YAAY;IACnC,SAAS,SACP,QAAQ,YAAY,QAAQ,eAAe,QAAQ,eAAe;GACtE,OAAO;IACL,SAAS,MAAM;IACf,SAAS,SAAS;GACpB;QAIA,IAF4B,QAAQ,cAAc,QAAQ,aAEjC;IACvB,SAAS,OAAO,QAAQ,aAAa;IACrC,SAAS,QAAQ,QAAQ,aAAa,QAAQ,cAAc,QAAQ,cAAc;GACpF,OAAO;IACL,SAAS,OAAO;IAChB,SAAS,QAAQ;GACnB;GAGF,IAAI,kBAAkB,eAAe,SAAS,QAAQ,GAAG;GAEzD,eAAe,UAAU;GACzB,eAAe,QAAQ;GACvB,qBAAqB,QAAQ;EAC/B;EAGA,YAAY;EAGZ,QAAQ,iBAAiB,UAAU,WAAW;EAC9C,OAAO,iBAAiB,UAAU,WAAW;EAG7C,MAAM,iBAAiB,IAAI,eAAe,WAAW;EACrD,eAAe,QAAQ,OAAO;EAE9B,aAAa;GACX,QAAQ,oBAAoB,UAAU,WAAW;GACjD,OAAO,oBAAoB,UAAU,WAAW;GAChD,eAAe,WAAW;EAC5B;CACF,GAAG;EAAC;EAAQ;EAAQ;EAAa;EAAW,GAAG;CAAU,CAAC;CAE1D,OAAO;AACT"}