@fluentui/react-virtualizer 9.0.0-alpha.95 → 9.0.0-alpha.97

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,32 @@
1
1
  # Change Log - @fluentui/react-virtualizer
2
2
 
3
- This log was last generated on Thu, 27 Mar 2025 21:08:38 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 06 Jun 2025 13:10:55 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.0.0-alpha.97](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.97)
8
+
9
+ Fri, 06 Jun 2025 13:10:55 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-virtualizer_v9.0.0-alpha.96..@fluentui/react-virtualizer_v9.0.0-alpha.97)
11
+
12
+ ### Changes
13
+
14
+ - Bump @fluentui/react-jsx-runtime to v9.0.55 ([PR #34572](https://github.com/microsoft/fluentui/pull/34572) by beachball)
15
+ - Bump @fluentui/react-utilities to v9.20.0 ([PR #34572](https://github.com/microsoft/fluentui/pull/34572) by beachball)
16
+
17
+ ## [9.0.0-alpha.96](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.96)
18
+
19
+ Wed, 16 Apr 2025 19:42:06 GMT
20
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-virtualizer_v9.0.0-alpha.95..@fluentui/react-virtualizer_v9.0.0-alpha.96)
21
+
22
+ ### Changes
23
+
24
+ - Bump @fluentui/react-jsx-runtime to v9.0.54 ([PR #34166](https://github.com/microsoft/fluentui/pull/34166) by beachball)
25
+ - Bump @fluentui/react-utilities to v9.19.0 ([PR #34166](https://github.com/microsoft/fluentui/pull/34166) by beachball)
26
+
7
27
  ## [9.0.0-alpha.95](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.95)
8
28
 
9
- Thu, 27 Mar 2025 21:08:38 GMT
29
+ Thu, 27 Mar 2025 21:12:51 GMT
10
30
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-virtualizer_v9.0.0-alpha.94..@fluentui/react-virtualizer_v9.0.0-alpha.95)
11
31
 
12
32
  ### Changes
@@ -92,7 +92,7 @@ import { useTimeout } from '@fluentui/react-utilities';
92
92
  ]);
93
93
  /**
94
94
  * On scroll timer that will continuously delay callback until scrolling stops
95
- */ const onScroll = React.useCallback((event)=>{
95
+ */ const onScroll = React.useCallback(()=>{
96
96
  clearScrollTimer();
97
97
  setScrollTimer(onScrollEnd, 100);
98
98
  }, [
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useDynamicPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerDynamicPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are dynamic so we require a progressive sizing array (passed in from Dynamic virtualizer hooks)\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerDynamicPaginationProps can be grabbed from dynamic Virtualizer hooks externally and passed in\n */\nexport const useDynamicVirtualizerPagination = (\n virtualizerProps: VirtualizerDynamicPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { axis = 'vertical', currentIndex, progressiveItemSizes, virtualizerLength } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(-1);\n const lastIndexScrolled = React.useRef<number>(-1);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n *\n * Users/Virtualizer-Hooks must pass in a cumulative array of sizes\n * This prevents the need to recalculate and ensures size arrays are synced externally\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled || !progressiveItemSizes?.current) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n let closestItemPos = 0;\n let closestItem = 0;\n const endItem = Math.min(currentIndex + virtualizerLength, progressiveItemSizes.current.length);\n\n for (let i = currentIndex; i < endItem - 1; i++) {\n if (\n currentScrollPos <= progressiveItemSizes.current[i + 1] &&\n currentScrollPos >= progressiveItemSizes.current[i]\n ) {\n // Found our in between position\n const distanceToPrev = Math.abs(currentScrollPos - progressiveItemSizes.current[i]);\n const distanceToNext = Math.abs(progressiveItemSizes.current[i + 1] - currentScrollPos);\n if (distanceToPrev < distanceToNext) {\n closestItem = i;\n } else {\n closestItem = i + 1;\n }\n break;\n }\n }\n\n let nextItem;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n // This will also handle a case where we scrolled to the exact correct position (noop)\n const isSecondaryScroll = Math.round(lastScrollPos.current - currentScrollPos) === 0;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n // Safeguard nextItem\n nextItem = Math.min(Math.max(0, nextItem), progressiveItemSizes.current.length);\n closestItemPos = progressiveItemSizes.current[nextItem];\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: closestItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: closestItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = progressiveItemSizes.current[nextItem];\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, currentIndex, scrollContainer, virtualizerLength, axis, progressiveItemSizes]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(\n event => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n },\n [onScrollEnd, clearScrollTimer, setScrollTimer],\n );\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["React","useTimeout","useDynamicVirtualizerPagination","virtualizerProps","paginationEnabled","axis","currentIndex","progressiveItemSizes","virtualizerLength","setScrollTimer","clearScrollTimer","lastScrollPos","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItemPos","closestItem","endItem","min","length","i","distanceToPrev","abs","distanceToNext","nextItem","nextTarget","isSecondaryScroll","posMod","max","scrollTo","top","behavior","left","event","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../src/hooks/useDynamicPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerDynamicPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are dynamic so we require a progressive sizing array (passed in from Dynamic virtualizer hooks)\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerDynamicPaginationProps can be grabbed from dynamic Virtualizer hooks externally and passed in\n */\nexport const useDynamicVirtualizerPagination = (\n virtualizerProps: VirtualizerDynamicPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { axis = 'vertical', currentIndex, progressiveItemSizes, virtualizerLength } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(-1);\n const lastIndexScrolled = React.useRef<number>(-1);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n *\n * Users/Virtualizer-Hooks must pass in a cumulative array of sizes\n * This prevents the need to recalculate and ensures size arrays are synced externally\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled || !progressiveItemSizes?.current) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n let closestItemPos = 0;\n let closestItem = 0;\n const endItem = Math.min(currentIndex + virtualizerLength, progressiveItemSizes.current.length);\n\n for (let i = currentIndex; i < endItem - 1; i++) {\n if (\n currentScrollPos <= progressiveItemSizes.current[i + 1] &&\n currentScrollPos >= progressiveItemSizes.current[i]\n ) {\n // Found our in between position\n const distanceToPrev = Math.abs(currentScrollPos - progressiveItemSizes.current[i]);\n const distanceToNext = Math.abs(progressiveItemSizes.current[i + 1] - currentScrollPos);\n if (distanceToPrev < distanceToNext) {\n closestItem = i;\n } else {\n closestItem = i + 1;\n }\n break;\n }\n }\n\n let nextItem;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n // This will also handle a case where we scrolled to the exact correct position (noop)\n const isSecondaryScroll = Math.round(lastScrollPos.current - currentScrollPos) === 0;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n // Safeguard nextItem\n nextItem = Math.min(Math.max(0, nextItem), progressiveItemSizes.current.length);\n closestItemPos = progressiveItemSizes.current[nextItem];\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: closestItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: closestItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = progressiveItemSizes.current[nextItem];\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, currentIndex, scrollContainer, virtualizerLength, axis, progressiveItemSizes]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(() => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n }, [onScrollEnd, clearScrollTimer, setScrollTimer]);\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["React","useTimeout","useDynamicVirtualizerPagination","virtualizerProps","paginationEnabled","axis","currentIndex","progressiveItemSizes","virtualizerLength","setScrollTimer","clearScrollTimer","lastScrollPos","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItemPos","closestItem","endItem","min","length","i","distanceToPrev","abs","distanceToNext","nextItem","nextTarget","isSecondaryScroll","posMod","max","scrollTo","top","behavior","left","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -68,7 +68,7 @@ import { useTimeout } from '@fluentui/react-utilities';
68
68
  ]);
69
69
  /**
70
70
  * On scroll timer that will continuously delay callback until scrolling stops
71
- */ const onScroll = React.useCallback((event)=>{
71
+ */ const onScroll = React.useCallback(()=>{
72
72
  clearScrollTimer();
73
73
  setScrollTimer(onScrollEnd, 100);
74
74
  }, [
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useStaticPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerStaticPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are uniform/static, we round to the nearest item on long scrolls\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerStaticPaginationProps can be grabbed from Virtualizer hooks externally and passed in\n */\nexport const useStaticVirtualizerPagination = (\n virtualizerProps: VirtualizerStaticPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { itemSize, axis = 'vertical' } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(0);\n const lastIndexScrolled = React.useRef<number>(0);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n const closestItem = Math.round(currentScrollPos / itemSize);\n\n let nextItem = 0;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n const isSecondaryScroll = lastScrollPos.current === currentScrollPos;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n const nextItemPos = nextItem * itemSize;\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: nextItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: nextItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = nextItemPos;\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, axis, itemSize]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(\n event => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n },\n [onScrollEnd, clearScrollTimer, setScrollTimer],\n );\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["React","useTimeout","useStaticVirtualizerPagination","virtualizerProps","paginationEnabled","itemSize","axis","setScrollTimer","clearScrollTimer","lastScrollPos","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItem","nextItem","nextTarget","isSecondaryScroll","posMod","nextItemPos","scrollTo","top","behavior","left","event","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,UAAU,QAAQ,4BAA4B;AAEvD;;;;;CAKC,GACD,OAAO,MAAMC,iCAAiC,CAC5CC,kBACAC,oBAA6B,IAAI;IAEjC;IAEA,MAAM,EAAEC,QAAQ,EAAEC,OAAO,UAAU,EAAE,GAAGH;IAExC,MAAM,CAACI,gBAAgBC,iBAAiB,GAAGP;IAC3C,MAAMQ,gBAAgBT,MAAMU,MAAM,CAAS;IAC3C,MAAMC,oBAAoBX,MAAMU,MAAM,CAAS;IAE/C,MAAME,kBAAkBZ,MAAMU,MAAM,CAAqB;IAEzD,MAAMG,iBAAiB;QACrB,IAAID,gBAAgBE,OAAO,EAAE;YAC3BF,gBAAgBE,OAAO,CAACC,mBAAmB,CAAC,UAAUC;YAEtDJ,gBAAgBE,OAAO,GAAG;YAC1BN;QACF;IACF;IAEAR,MAAMiB,SAAS,CAAC;QACd,OAAO;YACLJ;QACF;IACA,uDAAuD;IACzD,GAAG,EAAE;IAEL;;;;GAIC,GACD,MAAMK,cAAclB,MAAMmB,WAAW,CAAC;QACpC,IAAI,CAACP,gBAAgBE,OAAO,IAAI,CAACV,mBAAmB;YAClD,qBAAqB;YACrB;QACF;QAEA,MAAMgB,mBAAmBC,KAAKC,KAAK,CACjChB,SAAS,aAAaM,gBAAgBE,OAAO,CAACS,SAAS,GAAGX,gBAAgBE,OAAO,CAACU,UAAU;QAE9F,MAAMC,cAAcJ,KAAKC,KAAK,CAACF,mBAAmBf;QAElD,IAAIqB,WAAW;QACf,IAAIL,KAAKC,KAAK,CAACG,cAAcd,kBAAkBG,OAAO,MAAM,GAAG;YAC7D,4EAA4E;YAC5E,MAAMa,aAAalB,cAAcK,OAAO,GAAGM,mBAAmB,IAAI,CAAC;YACnE,MAAMQ,oBAAoBnB,cAAcK,OAAO,KAAKM;YACpD,MAAMS,SAASD,oBAAoB,IAAID;YAEvCD,WAAWD,cAAcI;QAC3B,OAAO;YACL,6DAA6D;YAC7DH,WAAWD;QACb;QAEA,MAAMK,cAAcJ,WAAWrB;QAE/B,IAAIC,SAAS,YAAY;YACvBM,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEC,KAAKF;gBAAaG,UAAU;YAAS;QAC1E,OAAO;YACLrB,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEG,MAAMJ;gBAAaG,UAAU;YAAS;QAC3E;QACAxB,cAAcK,OAAO,GAAGgB;QACxBnB,kBAAkBG,OAAO,GAAGY;IAC9B,GAAG;QAACtB;QAAmBE;QAAMD;KAAS;IAEtC;;GAEC,GACD,MAAMW,WAAWhB,MAAMmB,WAAW,CAChCgB,CAAAA;QACE3B;QACAD,eAAeW,aAAa;IAC9B,GACA;QAACA;QAAaV;QAAkBD;KAAe;IAGjD;;;GAGC,GACD,MAAM6B,gBAAgBpC,MAAMmB,WAAW,CACrC,CAACkB;QACC,IAAI,CAACjC,mBAAmB;YACtBS;YACAD,gBAAgBE,OAAO,GAAG;YAC1B;QACF;QACA,IAAIF,gBAAgBE,OAAO,KAAKuB,UAAU;YACxCxB;YAEAD,gBAAgBE,OAAO,GAAGuB;YAC1B,IAAIzB,gBAAgBE,OAAO,EAAE;gBAC3BF,gBAAgBE,OAAO,CAACwB,gBAAgB,CAAC,UAAUtB;YACrD;QACF;IACF,GACA,uDAAuD;IACvD;QAACA;QAAUE;QAAad;KAAkB;IAG5C,OAAOgC;AACT,EAAE"}
1
+ {"version":3,"sources":["../src/hooks/useStaticPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerStaticPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are uniform/static, we round to the nearest item on long scrolls\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerStaticPaginationProps can be grabbed from Virtualizer hooks externally and passed in\n */\nexport const useStaticVirtualizerPagination = (\n virtualizerProps: VirtualizerStaticPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { itemSize, axis = 'vertical' } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(0);\n const lastIndexScrolled = React.useRef<number>(0);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n const closestItem = Math.round(currentScrollPos / itemSize);\n\n let nextItem = 0;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n const isSecondaryScroll = lastScrollPos.current === currentScrollPos;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n const nextItemPos = nextItem * itemSize;\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: nextItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: nextItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = nextItemPos;\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, axis, itemSize]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(() => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n }, [onScrollEnd, clearScrollTimer, setScrollTimer]);\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["React","useTimeout","useStaticVirtualizerPagination","virtualizerProps","paginationEnabled","itemSize","axis","setScrollTimer","clearScrollTimer","lastScrollPos","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItem","nextItem","nextTarget","isSecondaryScroll","posMod","nextItemPos","scrollTo","top","behavior","left","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,UAAU,QAAQ,4BAA4B;AAEvD;;;;;CAKC,GACD,OAAO,MAAMC,iCAAiC,CAC5CC,kBACAC,oBAA6B,IAAI;IAEjC;IAEA,MAAM,EAAEC,QAAQ,EAAEC,OAAO,UAAU,EAAE,GAAGH;IAExC,MAAM,CAACI,gBAAgBC,iBAAiB,GAAGP;IAC3C,MAAMQ,gBAAgBT,MAAMU,MAAM,CAAS;IAC3C,MAAMC,oBAAoBX,MAAMU,MAAM,CAAS;IAE/C,MAAME,kBAAkBZ,MAAMU,MAAM,CAAqB;IAEzD,MAAMG,iBAAiB;QACrB,IAAID,gBAAgBE,OAAO,EAAE;YAC3BF,gBAAgBE,OAAO,CAACC,mBAAmB,CAAC,UAAUC;YAEtDJ,gBAAgBE,OAAO,GAAG;YAC1BN;QACF;IACF;IAEAR,MAAMiB,SAAS,CAAC;QACd,OAAO;YACLJ;QACF;IACA,uDAAuD;IACzD,GAAG,EAAE;IAEL;;;;GAIC,GACD,MAAMK,cAAclB,MAAMmB,WAAW,CAAC;QACpC,IAAI,CAACP,gBAAgBE,OAAO,IAAI,CAACV,mBAAmB;YAClD,qBAAqB;YACrB;QACF;QAEA,MAAMgB,mBAAmBC,KAAKC,KAAK,CACjChB,SAAS,aAAaM,gBAAgBE,OAAO,CAACS,SAAS,GAAGX,gBAAgBE,OAAO,CAACU,UAAU;QAE9F,MAAMC,cAAcJ,KAAKC,KAAK,CAACF,mBAAmBf;QAElD,IAAIqB,WAAW;QACf,IAAIL,KAAKC,KAAK,CAACG,cAAcd,kBAAkBG,OAAO,MAAM,GAAG;YAC7D,4EAA4E;YAC5E,MAAMa,aAAalB,cAAcK,OAAO,GAAGM,mBAAmB,IAAI,CAAC;YACnE,MAAMQ,oBAAoBnB,cAAcK,OAAO,KAAKM;YACpD,MAAMS,SAASD,oBAAoB,IAAID;YAEvCD,WAAWD,cAAcI;QAC3B,OAAO;YACL,6DAA6D;YAC7DH,WAAWD;QACb;QAEA,MAAMK,cAAcJ,WAAWrB;QAE/B,IAAIC,SAAS,YAAY;YACvBM,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEC,KAAKF;gBAAaG,UAAU;YAAS;QAC1E,OAAO;YACLrB,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEG,MAAMJ;gBAAaG,UAAU;YAAS;QAC3E;QACAxB,cAAcK,OAAO,GAAGgB;QACxBnB,kBAAkBG,OAAO,GAAGY;IAC9B,GAAG;QAACtB;QAAmBE;QAAMD;KAAS;IAEtC;;GAEC,GACD,MAAMW,WAAWhB,MAAMmB,WAAW,CAAC;QACjCX;QACAD,eAAeW,aAAa;IAC9B,GAAG;QAACA;QAAaV;QAAkBD;KAAe;IAElD;;;GAGC,GACD,MAAM4B,gBAAgBnC,MAAMmB,WAAW,CACrC,CAACiB;QACC,IAAI,CAAChC,mBAAmB;YACtBS;YACAD,gBAAgBE,OAAO,GAAG;YAC1B;QACF;QACA,IAAIF,gBAAgBE,OAAO,KAAKsB,UAAU;YACxCvB;YAEAD,gBAAgBE,OAAO,GAAGsB;YAC1B,IAAIxB,gBAAgBE,OAAO,EAAE;gBAC3BF,gBAAgBE,OAAO,CAACuB,gBAAgB,CAAC,UAAUrB;YACrD;QACF;IACF,GACA,uDAAuD;IACvD;QAACA;QAAUE;QAAad;KAAkB;IAG5C,OAAO+B;AACT,EAAE"}
@@ -98,7 +98,7 @@ const useDynamicVirtualizerPagination = (virtualizerProps, paginationEnabled = t
98
98
  ]);
99
99
  /**
100
100
  * On scroll timer that will continuously delay callback until scrolling stops
101
- */ const onScroll = _react.useCallback((event)=>{
101
+ */ const onScroll = _react.useCallback(()=>{
102
102
  clearScrollTimer();
103
103
  setScrollTimer(onScrollEnd, 100);
104
104
  }, [
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useDynamicPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerDynamicPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are dynamic so we require a progressive sizing array (passed in from Dynamic virtualizer hooks)\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerDynamicPaginationProps can be grabbed from dynamic Virtualizer hooks externally and passed in\n */\nexport const useDynamicVirtualizerPagination = (\n virtualizerProps: VirtualizerDynamicPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { axis = 'vertical', currentIndex, progressiveItemSizes, virtualizerLength } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(-1);\n const lastIndexScrolled = React.useRef<number>(-1);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n *\n * Users/Virtualizer-Hooks must pass in a cumulative array of sizes\n * This prevents the need to recalculate and ensures size arrays are synced externally\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled || !progressiveItemSizes?.current) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n let closestItemPos = 0;\n let closestItem = 0;\n const endItem = Math.min(currentIndex + virtualizerLength, progressiveItemSizes.current.length);\n\n for (let i = currentIndex; i < endItem - 1; i++) {\n if (\n currentScrollPos <= progressiveItemSizes.current[i + 1] &&\n currentScrollPos >= progressiveItemSizes.current[i]\n ) {\n // Found our in between position\n const distanceToPrev = Math.abs(currentScrollPos - progressiveItemSizes.current[i]);\n const distanceToNext = Math.abs(progressiveItemSizes.current[i + 1] - currentScrollPos);\n if (distanceToPrev < distanceToNext) {\n closestItem = i;\n } else {\n closestItem = i + 1;\n }\n break;\n }\n }\n\n let nextItem;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n // This will also handle a case where we scrolled to the exact correct position (noop)\n const isSecondaryScroll = Math.round(lastScrollPos.current - currentScrollPos) === 0;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n // Safeguard nextItem\n nextItem = Math.min(Math.max(0, nextItem), progressiveItemSizes.current.length);\n closestItemPos = progressiveItemSizes.current[nextItem];\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: closestItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: closestItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = progressiveItemSizes.current[nextItem];\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, currentIndex, scrollContainer, virtualizerLength, axis, progressiveItemSizes]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(\n event => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n },\n [onScrollEnd, clearScrollTimer, setScrollTimer],\n );\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["useDynamicVirtualizerPagination","virtualizerProps","paginationEnabled","axis","currentIndex","progressiveItemSizes","virtualizerLength","setScrollTimer","clearScrollTimer","useTimeout","lastScrollPos","React","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItemPos","closestItem","endItem","min","length","i","distanceToPrev","abs","distanceToNext","nextItem","nextTarget","isSecondaryScroll","posMod","max","scrollTo","top","behavior","left","event","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../src/hooks/useDynamicPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerDynamicPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are dynamic so we require a progressive sizing array (passed in from Dynamic virtualizer hooks)\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerDynamicPaginationProps can be grabbed from dynamic Virtualizer hooks externally and passed in\n */\nexport const useDynamicVirtualizerPagination = (\n virtualizerProps: VirtualizerDynamicPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { axis = 'vertical', currentIndex, progressiveItemSizes, virtualizerLength } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(-1);\n const lastIndexScrolled = React.useRef<number>(-1);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n *\n * Users/Virtualizer-Hooks must pass in a cumulative array of sizes\n * This prevents the need to recalculate and ensures size arrays are synced externally\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled || !progressiveItemSizes?.current) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n let closestItemPos = 0;\n let closestItem = 0;\n const endItem = Math.min(currentIndex + virtualizerLength, progressiveItemSizes.current.length);\n\n for (let i = currentIndex; i < endItem - 1; i++) {\n if (\n currentScrollPos <= progressiveItemSizes.current[i + 1] &&\n currentScrollPos >= progressiveItemSizes.current[i]\n ) {\n // Found our in between position\n const distanceToPrev = Math.abs(currentScrollPos - progressiveItemSizes.current[i]);\n const distanceToNext = Math.abs(progressiveItemSizes.current[i + 1] - currentScrollPos);\n if (distanceToPrev < distanceToNext) {\n closestItem = i;\n } else {\n closestItem = i + 1;\n }\n break;\n }\n }\n\n let nextItem;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n // This will also handle a case where we scrolled to the exact correct position (noop)\n const isSecondaryScroll = Math.round(lastScrollPos.current - currentScrollPos) === 0;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n // Safeguard nextItem\n nextItem = Math.min(Math.max(0, nextItem), progressiveItemSizes.current.length);\n closestItemPos = progressiveItemSizes.current[nextItem];\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: closestItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: closestItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = progressiveItemSizes.current[nextItem];\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, currentIndex, scrollContainer, virtualizerLength, axis, progressiveItemSizes]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(() => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n }, [onScrollEnd, clearScrollTimer, setScrollTimer]);\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["useDynamicVirtualizerPagination","virtualizerProps","paginationEnabled","axis","currentIndex","progressiveItemSizes","virtualizerLength","setScrollTimer","clearScrollTimer","useTimeout","lastScrollPos","React","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItemPos","closestItem","endItem","min","length","i","distanceToPrev","abs","distanceToNext","nextItem","nextTarget","isSecondaryScroll","posMod","max","scrollTo","top","behavior","left","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -74,7 +74,7 @@ const useStaticVirtualizerPagination = (virtualizerProps, paginationEnabled = tr
74
74
  ]);
75
75
  /**
76
76
  * On scroll timer that will continuously delay callback until scrolling stops
77
- */ const onScroll = _react.useCallback((event)=>{
77
+ */ const onScroll = _react.useCallback(()=>{
78
78
  clearScrollTimer();
79
79
  setScrollTimer(onScrollEnd, 100);
80
80
  }, [
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useStaticPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerStaticPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are uniform/static, we round to the nearest item on long scrolls\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerStaticPaginationProps can be grabbed from Virtualizer hooks externally and passed in\n */\nexport const useStaticVirtualizerPagination = (\n virtualizerProps: VirtualizerStaticPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { itemSize, axis = 'vertical' } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(0);\n const lastIndexScrolled = React.useRef<number>(0);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n const closestItem = Math.round(currentScrollPos / itemSize);\n\n let nextItem = 0;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n const isSecondaryScroll = lastScrollPos.current === currentScrollPos;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n const nextItemPos = nextItem * itemSize;\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: nextItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: nextItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = nextItemPos;\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, axis, itemSize]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(\n event => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n },\n [onScrollEnd, clearScrollTimer, setScrollTimer],\n );\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["useStaticVirtualizerPagination","virtualizerProps","paginationEnabled","itemSize","axis","setScrollTimer","clearScrollTimer","useTimeout","lastScrollPos","React","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItem","nextItem","nextTarget","isSecondaryScroll","posMod","nextItemPos","scrollTo","top","behavior","left","event","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAUaA;;;eAAAA;;;;iEAVU;gCAEI;AAQpB,MAAMA,iCAAiC,CAC5CC,kBACAC,oBAA6B,IAAI;IAEjC;IAEA,MAAM,EAAEC,QAAQ,EAAEC,OAAO,UAAU,EAAE,GAAGH;IAExC,MAAM,CAACI,gBAAgBC,iBAAiB,GAAGC,IAAAA,0BAAAA;IAC3C,MAAMC,gBAAgBC,OAAMC,MAAM,CAAS;IAC3C,MAAMC,oBAAoBF,OAAMC,MAAM,CAAS;IAE/C,MAAME,kBAAkBH,OAAMC,MAAM,CAAqB;IAEzD,MAAMG,iBAAiB;QACrB,IAAID,gBAAgBE,OAAO,EAAE;YAC3BF,gBAAgBE,OAAO,CAACC,mBAAmB,CAAC,UAAUC;YAEtDJ,gBAAgBE,OAAO,GAAG;YAC1BR;QACF;IACF;IAEAG,OAAMQ,SAAS,CAAC;QACd,OAAO;YACLJ;QACF;IACA,uDAAuD;IACzD,GAAG,EAAE;IAEL;;;;GAIC,GACD,MAAMK,cAAcT,OAAMU,WAAW,CAAC;QACpC,IAAI,CAACP,gBAAgBE,OAAO,IAAI,CAACZ,mBAAmB;YAClD,qBAAqB;YACrB;QACF;QAEA,MAAMkB,mBAAmBC,KAAKC,KAAK,CACjClB,SAAS,aAAaQ,gBAAgBE,OAAO,CAACS,SAAS,GAAGX,gBAAgBE,OAAO,CAACU,UAAU;QAE9F,MAAMC,cAAcJ,KAAKC,KAAK,CAACF,mBAAmBjB;QAElD,IAAIuB,WAAW;QACf,IAAIL,KAAKC,KAAK,CAACG,cAAcd,kBAAkBG,OAAO,MAAM,GAAG;YAC7D,4EAA4E;YAC5E,MAAMa,aAAanB,cAAcM,OAAO,GAAGM,mBAAmB,IAAI,CAAC;YACnE,MAAMQ,oBAAoBpB,cAAcM,OAAO,KAAKM;YACpD,MAAMS,SAASD,oBAAoB,IAAID;YAEvCD,WAAWD,cAAcI;QAC3B,OAAO;YACL,6DAA6D;YAC7DH,WAAWD;QACb;QAEA,MAAMK,cAAcJ,WAAWvB;QAE/B,IAAIC,SAAS,YAAY;YACvBQ,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEC,KAAKF;gBAAaG,UAAU;YAAS;QAC1E,OAAO;YACLrB,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEG,MAAMJ;gBAAaG,UAAU;YAAS;QAC3E;QACAzB,cAAcM,OAAO,GAAGgB;QACxBnB,kBAAkBG,OAAO,GAAGY;IAC9B,GAAG;QAACxB;QAAmBE;QAAMD;KAAS;IAEtC;;GAEC,GACD,MAAMa,WAAWP,OAAMU,WAAW,CAChCgB,CAAAA;QACE7B;QACAD,eAAea,aAAa;IAC9B,GACA;QAACA;QAAaZ;QAAkBD;KAAe;IAGjD;;;GAGC,GACD,MAAM+B,gBAAgB3B,OAAMU,WAAW,CACrC,CAACkB;QACC,IAAI,CAACnC,mBAAmB;YACtBW;YACAD,gBAAgBE,OAAO,GAAG;YAC1B;QACF;QACA,IAAIF,gBAAgBE,OAAO,KAAKuB,UAAU;YACxCxB;YAEAD,gBAAgBE,OAAO,GAAGuB;YAC1B,IAAIzB,gBAAgBE,OAAO,EAAE;gBAC3BF,gBAAgBE,OAAO,CAACwB,gBAAgB,CAAC,UAAUtB;YACrD;QACF;IACF,GAEA;QAACA;QAAUE;QAAahB;KAAkB;IAG5C,OAAOkC;AACT"}
1
+ {"version":3,"sources":["../src/hooks/useStaticPagination.ts"],"sourcesContent":["import * as React from 'react';\nimport { VirtualizerStaticPaginationProps } from './hooks.types';\nimport { useTimeout } from '@fluentui/react-utilities';\n\n/**\n * Optional hook that will enable pagination on the virtualizer so that it 'autoscrolls' to an items exact position\n * Sizes are uniform/static, we round to the nearest item on long scrolls\n * On short scrolls, we will go at minimum to the next/previous item so that arrow pagination works\n * All VirtualizerStaticPaginationProps can be grabbed from Virtualizer hooks externally and passed in\n */\nexport const useStaticVirtualizerPagination = (\n virtualizerProps: VirtualizerStaticPaginationProps,\n paginationEnabled: Boolean = true,\n) => {\n 'use no memo';\n\n const { itemSize, axis = 'vertical' } = virtualizerProps;\n\n const [setScrollTimer, clearScrollTimer] = useTimeout();\n const lastScrollPos = React.useRef<number>(0);\n const lastIndexScrolled = React.useRef<number>(0);\n\n const scrollContainer = React.useRef<HTMLElement | null>(null);\n\n const clearListeners = () => {\n if (scrollContainer.current) {\n scrollContainer.current.removeEventListener('scroll', onScroll);\n\n scrollContainer.current = null;\n clearScrollTimer();\n }\n };\n\n React.useEffect(() => {\n return () => {\n clearListeners();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Handle scroll stop event and paginate to the closest item\n * If the closest item is the same as the previous scroll end\n * we paginate to the next/previous one based on direction\n */\n const onScrollEnd = React.useCallback(() => {\n if (!scrollContainer.current || !paginationEnabled) {\n // No container found\n return;\n }\n\n const currentScrollPos = Math.round(\n axis === 'vertical' ? scrollContainer.current.scrollTop : scrollContainer.current.scrollLeft,\n );\n const closestItem = Math.round(currentScrollPos / itemSize);\n\n let nextItem = 0;\n if (Math.round(closestItem - lastIndexScrolled.current) === 0) {\n // Special case for go to next/previous with minimum amount of scroll needed\n const nextTarget = lastScrollPos.current < currentScrollPos ? 1 : -1;\n const isSecondaryScroll = lastScrollPos.current === currentScrollPos;\n const posMod = isSecondaryScroll ? 0 : nextTarget;\n\n nextItem = closestItem + posMod;\n } else {\n // Pagination for anything else can just jump to the closest!\n nextItem = closestItem;\n }\n\n const nextItemPos = nextItem * itemSize;\n\n if (axis === 'vertical') {\n scrollContainer.current.scrollTo({ top: nextItemPos, behavior: 'smooth' });\n } else {\n scrollContainer.current.scrollTo({ left: nextItemPos, behavior: 'smooth' });\n }\n lastScrollPos.current = nextItemPos;\n lastIndexScrolled.current = nextItem;\n }, [paginationEnabled, axis, itemSize]);\n\n /**\n * On scroll timer that will continuously delay callback until scrolling stops\n */\n const onScroll = React.useCallback(() => {\n clearScrollTimer();\n setScrollTimer(onScrollEnd, 100);\n }, [onScrollEnd, clearScrollTimer, setScrollTimer]);\n\n /**\n * Pagination ref will ensure we attach listeners to containers on change\n * It is returned from hook and merged into the scroll container externally\n */\n const paginationRef = React.useCallback(\n (instance: HTMLElement | HTMLDivElement | null) => {\n if (!paginationEnabled) {\n clearListeners();\n scrollContainer.current = null;\n return;\n }\n if (scrollContainer.current !== instance) {\n clearListeners();\n\n scrollContainer.current = instance;\n if (scrollContainer.current) {\n scrollContainer.current.addEventListener('scroll', onScroll);\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onScroll, onScrollEnd, paginationEnabled],\n );\n\n return paginationRef;\n};\n"],"names":["useStaticVirtualizerPagination","virtualizerProps","paginationEnabled","itemSize","axis","setScrollTimer","clearScrollTimer","useTimeout","lastScrollPos","React","useRef","lastIndexScrolled","scrollContainer","clearListeners","current","removeEventListener","onScroll","useEffect","onScrollEnd","useCallback","currentScrollPos","Math","round","scrollTop","scrollLeft","closestItem","nextItem","nextTarget","isSecondaryScroll","posMod","nextItemPos","scrollTo","top","behavior","left","paginationRef","instance","addEventListener"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAUaA;;;eAAAA;;;;iEAVU;gCAEI;AAQpB,MAAMA,iCAAiC,CAC5CC,kBACAC,oBAA6B,IAAI;IAEjC;IAEA,MAAM,EAAEC,QAAQ,EAAEC,OAAO,UAAU,EAAE,GAAGH;IAExC,MAAM,CAACI,gBAAgBC,iBAAiB,GAAGC,IAAAA,0BAAAA;IAC3C,MAAMC,gBAAgBC,OAAMC,MAAM,CAAS;IAC3C,MAAMC,oBAAoBF,OAAMC,MAAM,CAAS;IAE/C,MAAME,kBAAkBH,OAAMC,MAAM,CAAqB;IAEzD,MAAMG,iBAAiB;QACrB,IAAID,gBAAgBE,OAAO,EAAE;YAC3BF,gBAAgBE,OAAO,CAACC,mBAAmB,CAAC,UAAUC;YAEtDJ,gBAAgBE,OAAO,GAAG;YAC1BR;QACF;IACF;IAEAG,OAAMQ,SAAS,CAAC;QACd,OAAO;YACLJ;QACF;IACA,uDAAuD;IACzD,GAAG,EAAE;IAEL;;;;GAIC,GACD,MAAMK,cAAcT,OAAMU,WAAW,CAAC;QACpC,IAAI,CAACP,gBAAgBE,OAAO,IAAI,CAACZ,mBAAmB;YAClD,qBAAqB;YACrB;QACF;QAEA,MAAMkB,mBAAmBC,KAAKC,KAAK,CACjClB,SAAS,aAAaQ,gBAAgBE,OAAO,CAACS,SAAS,GAAGX,gBAAgBE,OAAO,CAACU,UAAU;QAE9F,MAAMC,cAAcJ,KAAKC,KAAK,CAACF,mBAAmBjB;QAElD,IAAIuB,WAAW;QACf,IAAIL,KAAKC,KAAK,CAACG,cAAcd,kBAAkBG,OAAO,MAAM,GAAG;YAC7D,4EAA4E;YAC5E,MAAMa,aAAanB,cAAcM,OAAO,GAAGM,mBAAmB,IAAI,CAAC;YACnE,MAAMQ,oBAAoBpB,cAAcM,OAAO,KAAKM;YACpD,MAAMS,SAASD,oBAAoB,IAAID;YAEvCD,WAAWD,cAAcI;QAC3B,OAAO;YACL,6DAA6D;YAC7DH,WAAWD;QACb;QAEA,MAAMK,cAAcJ,WAAWvB;QAE/B,IAAIC,SAAS,YAAY;YACvBQ,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEC,KAAKF;gBAAaG,UAAU;YAAS;QAC1E,OAAO;YACLrB,gBAAgBE,OAAO,CAACiB,QAAQ,CAAC;gBAAEG,MAAMJ;gBAAaG,UAAU;YAAS;QAC3E;QACAzB,cAAcM,OAAO,GAAGgB;QACxBnB,kBAAkBG,OAAO,GAAGY;IAC9B,GAAG;QAACxB;QAAmBE;QAAMD;KAAS;IAEtC;;GAEC,GACD,MAAMa,WAAWP,OAAMU,WAAW,CAAC;QACjCb;QACAD,eAAea,aAAa;IAC9B,GAAG;QAACA;QAAaZ;QAAkBD;KAAe;IAElD;;;GAGC,GACD,MAAM8B,gBAAgB1B,OAAMU,WAAW,CACrC,CAACiB;QACC,IAAI,CAAClC,mBAAmB;YACtBW;YACAD,gBAAgBE,OAAO,GAAG;YAC1B;QACF;QACA,IAAIF,gBAAgBE,OAAO,KAAKsB,UAAU;YACxCvB;YAEAD,gBAAgBE,OAAO,GAAGsB;YAC1B,IAAIxB,gBAAgBE,OAAO,EAAE;gBAC3BF,gBAAgBE,OAAO,CAACuB,gBAAgB,CAAC,UAAUrB;YACrD;QACF;IACF,GAEA;QAACA;QAAUE;QAAahB;KAAkB;IAG5C,OAAOiC;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-virtualizer",
3
- "version": "9.0.0-alpha.95",
3
+ "version": "9.0.0-alpha.97",
4
4
  "description": "Generic and composable virtualizer framework built on browser intersection observer",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -18,8 +18,8 @@
18
18
  "@fluentui/scripts-api-extractor": "*"
19
19
  },
20
20
  "dependencies": {
21
- "@fluentui/react-jsx-runtime": "^9.0.53",
22
- "@fluentui/react-utilities": "^9.18.23",
21
+ "@fluentui/react-jsx-runtime": "^9.0.55",
22
+ "@fluentui/react-utilities": "^9.20.0",
23
23
  "@fluentui/react-shared-contexts": "^9.23.1",
24
24
  "@griffel/react": "^1.5.22",
25
25
  "@swc/helpers": "^0.5.1"