@scrolia/react
Version:
A headless scrollbar component
1 lines • 7.36 kB
Source Map (JSON)
{"version":3,"file":"scroll.mjs","names":["scrollbarOffsetNext: number","result: OnScrollResult | undefined","offset: number"],"sources":["../../src/hooks/scroll.ts"],"sourcesContent":["import type { Axis, OnScrollResult, Plugin } from \"#/@types/options\";\n\nimport * as React from \"react\";\n\nimport { useScrollCore } from \"#/contexts/scrollcore\";\nimport { tryPlugin } from \"#/functions/plugin\";\n\ntype HandleScrollOptions = {\n axis: Axis;\n disabled: boolean;\n page: boolean;\n plugins: Plugin[];\n contentRef: React.RefObject<HTMLElement | null>;\n hvTrack: boolean;\n hvThumb: boolean;\n total: React.RefObject<number>;\n view: React.RefObject<number>;\n viewOffset: React.RefObject<number>;\n scrollbarOffset: number;\n setScrollbarOffset: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst handleScrollFn = ({\n axis,\n disabled,\n page,\n plugins,\n contentRef,\n hvTrack,\n hvThumb,\n total,\n view,\n viewOffset,\n scrollbarOffset,\n setScrollbarOffset,\n}: HandleScrollOptions): void => {\n if (page) {\n if (axis === \"x\") {\n viewOffset.current = window.scrollX;\n } else {\n viewOffset.current = window.scrollY;\n }\n } else if (contentRef.current) {\n if (axis === \"x\") {\n viewOffset.current = contentRef.current.scrollLeft;\n } else {\n viewOffset.current = contentRef.current.scrollTop;\n }\n }\n\n const scrollbarOffsetNext: number =\n (viewOffset.current / total.current) * view.current;\n\n let result: OnScrollResult | undefined;\n\n for (const plugin of plugins) {\n if (!plugin.onScroll) continue;\n\n result =\n tryPlugin(plugin, plugin.onScroll, {\n axis,\n isDisabled: disabled,\n isPage: page,\n isDefined: hvTrack && hvThumb,\n total: total.current,\n view: view.current,\n viewOffset: viewOffset.current,\n scrollbarOffsetPrev: scrollbarOffset,\n scrollbarOffsetNext:\n result?.scrollbarOffset ?? scrollbarOffsetNext,\n }) ?? result;\n }\n\n let offset: number;\n\n if (result?.scrollbarOffset) {\n offset = result.scrollbarOffset;\n } else {\n offset = scrollbarOffsetNext;\n }\n\n setScrollbarOffset(offset);\n};\n\n/** Hook for handling scroll events. */\nconst useScrollHandler = (): void => {\n const {\n options: { disabled, page, plugins },\n contentRef,\n x,\n y,\n } = useScrollCore();\n\n React.useEffect((): (() => void) => {\n const handleScroll = (): void => {\n x.hvTrack &&\n x.hvThumb &&\n handleScrollFn({\n axis: \"x\",\n disabled,\n page,\n plugins,\n contentRef,\n hvTrack: x.hvTrack,\n hvThumb: x.hvThumb,\n total: x.total,\n view: x.view,\n viewOffset: x.viewOffset,\n scrollbarOffset: x.scrollbarOffset,\n setScrollbarOffset: x.setScrollbarOffset,\n });\n };\n\n if (page) {\n window.addEventListener(\"scroll\", handleScroll);\n } else if (contentRef.current) {\n contentRef.current.addEventListener(\"scroll\", handleScroll);\n }\n\n return (): void => {\n if (page) {\n window.removeEventListener(\"scroll\", handleScroll);\n } else if (contentRef.current) {\n contentRef.current.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, [\n disabled,\n page,\n plugins,\n contentRef,\n\n x.hvTrack,\n x.hvThumb,\n x.total,\n x.view,\n x.viewOffset,\n x.scrollbarOffset,\n x.setScrollbarOffset,\n ]);\n\n React.useEffect((): (() => void) => {\n const handleScroll = (): void => {\n y.hvTrack &&\n y.hvThumb &&\n handleScrollFn({\n axis: \"y\",\n disabled,\n page,\n plugins,\n contentRef,\n hvTrack: y.hvTrack,\n hvThumb: y.hvThumb,\n total: y.total,\n view: y.view,\n viewOffset: y.viewOffset,\n scrollbarOffset: y.scrollbarOffset,\n setScrollbarOffset: y.setScrollbarOffset,\n });\n };\n\n if (page) {\n window.addEventListener(\"scroll\", handleScroll);\n } else if (contentRef.current) {\n contentRef.current.addEventListener(\"scroll\", handleScroll);\n }\n\n return (): void => {\n if (page) {\n window.removeEventListener(\"scroll\", handleScroll);\n } else if (contentRef.current) {\n contentRef.current.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, [\n disabled,\n page,\n plugins,\n contentRef,\n\n y.hvTrack,\n y.hvThumb,\n y.total,\n y.view,\n y.viewOffset,\n y.scrollbarOffset,\n y.setScrollbarOffset,\n ]);\n};\n\nexport { useScrollHandler };\n"],"mappings":";;;;AAsBA,MAAM,iBAAiB,CAAC,EACpB,MACA,UACA,MACA,SACA,YACA,SACA,SACA,OACA,MACA,YACA,iBACA,oBACkB,KAAW;AAC7B,KAAI,KACA,KAAI,SAAS,IACT,YAAW,UAAU,OAAO;KAE5B,YAAW,UAAU,OAAO;UAEzB,WAAW,QAClB,KAAI,SAAS,IACT,YAAW,UAAU,WAAW,QAAQ;KAExC,YAAW,UAAU,WAAW,QAAQ;CAIhD,MAAMA,sBACD,WAAW,UAAU,MAAM,UAAW,KAAK;CAEhD,IAAIC;AAEJ,MAAK,MAAM,UAAU,SAAS;AAC1B,OAAK,OAAO,SAAU;AAEtB,WACI,UAAU,QAAQ,OAAO,UAAU;GAC/B;GACA,YAAY;GACZ,QAAQ;GACR,WAAW,WAAW;GACtB,OAAO,MAAM;GACb,MAAM,KAAK;GACX,YAAY,WAAW;GACvB,qBAAqB;GACrB,qBACI,QAAQ,mBAAmB;EAClC,EAAC,IAAI;CACb;CAED,IAAIC;AAEJ,KAAI,QAAQ,gBACR,UAAS,OAAO;KAEhB,UAAS;AAGb,oBAAmB,OAAO;AAC7B;;AAGD,MAAM,mBAAmB,MAAY;CACjC,MAAM,EACF,SAAS,EAAE,UAAU,MAAM,SAAS,EACpC,YACA,GACA,GACH,GAAG,eAAe;AAEnB,OAAM,UAAU,MAAoB;EAChC,MAAM,eAAe,MAAY;AAC7B,KAAE,WACE,EAAE,WACF,eAAe;IACX,MAAM;IACN;IACA;IACA;IACA;IACA,SAAS,EAAE;IACX,SAAS,EAAE;IACX,OAAO,EAAE;IACT,MAAM,EAAE;IACR,YAAY,EAAE;IACd,iBAAiB,EAAE;IACnB,oBAAoB,EAAE;GACzB,EAAC;EACT;AAED,MAAI,KACA,QAAO,iBAAiB,UAAU,aAAa;WACxC,WAAW,QAClB,YAAW,QAAQ,iBAAiB,UAAU,aAAa;AAG/D,SAAO,MAAY;AACf,OAAI,KACA,QAAO,oBAAoB,UAAU,aAAa;YAC3C,WAAW,QAClB,YAAW,QAAQ,oBAAoB,UAAU,aAAa;EAErE;CACJ,GAAE;EACC;EACA;EACA;EACA;EAEA,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;CACL,EAAC;AAEF,OAAM,UAAU,MAAoB;EAChC,MAAM,eAAe,MAAY;AAC7B,KAAE,WACE,EAAE,WACF,eAAe;IACX,MAAM;IACN;IACA;IACA;IACA;IACA,SAAS,EAAE;IACX,SAAS,EAAE;IACX,OAAO,EAAE;IACT,MAAM,EAAE;IACR,YAAY,EAAE;IACd,iBAAiB,EAAE;IACnB,oBAAoB,EAAE;GACzB,EAAC;EACT;AAED,MAAI,KACA,QAAO,iBAAiB,UAAU,aAAa;WACxC,WAAW,QAClB,YAAW,QAAQ,iBAAiB,UAAU,aAAa;AAG/D,SAAO,MAAY;AACf,OAAI,KACA,QAAO,oBAAoB,UAAU,aAAa;YAC3C,WAAW,QAClB,YAAW,QAAQ,oBAAoB,UAAU,aAAa;EAErE;CACJ,GAAE;EACC;EACA;EACA;EACA;EAEA,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;EACF,EAAE;CACL,EAAC;AACL"}