From 42883e8d777cf279f81c0af346529d153f935f8c Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Wed, 5 Jul 2023 10:40:55 -0700 Subject: [PATCH 1/6] Fix up horizontal list start margin --- .../useVirtualizerStyles.styles.ts | 4 +- .../SnapToAlignment.stories.tsx | 60 +++++++++++++++++++ .../VirtualizerScrollView/index.stories.ts | 1 + 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx diff --git a/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizerStyles.styles.ts b/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizerStyles.styles.ts index 0f11ce8778d7b..b3fcfd4b20f3f 100644 --- a/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizerStyles.styles.ts +++ b/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizerStyles.styles.ts @@ -76,9 +76,9 @@ export const useVirtualizerStyles_unstable = (state: VirtualizerState): Virtuali // Column-Reverse ...(reversed && !horizontal && { marginTop: `-${bufferPx}` }), // Row - ...(!reversed && horizontal && { marginLeft: `-${bufferPx}` }), + ...(!reversed && horizontal && { marginRight: `-${bufferPx}` }), // Row-Reverse - ...(reversed && horizontal && { marginRight: `-${bufferPx}` }), + ...(reversed && horizontal && { marginLeft: `-${bufferPx}` }), }; const afterBuffer = { diff --git a/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx new file mode 100644 index 0000000000000..292a1abb94884 --- /dev/null +++ b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx @@ -0,0 +1,60 @@ +import { Button, makeStyles, shorthands, useArrowNavigationGroup } from '@fluentui/react-components'; +import * as React from 'react'; +import { VirtualizerScrollView } from '@fluentui/react-components/unstable'; + +const useStyles = makeStyles({ + container: { + maxHeight: '300px', + width: '100%', + maxWidth: '100%', + scrollSnapType: 'x mandatory', + scrollBehavior: 'auto', + overflowAnchor: 'none', + ...shorthands.padding('10px', '2px'), + ...shorthands.gap('10px'), + }, + child: { + // comment out `scrollSnapAlign` for keyboard + // and scrolling to work + scrollSnapAlign: 'start', + height: '100px', + width: '100px', + midWidth: '100px', + }, + button: { + width: '100%', + height: '100%', + }, +}); + +export const SnapToAlignment = () => { + const styles = useStyles(); + const childLength = 1000; + const attributes = useArrowNavigationGroup({ + axis: 'horizontal', + memorizeCurrent: true, + }); + + return ( + + {(index: number) => { + return ( +
+ +
+ ); + }} +
+ ); +}; diff --git a/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/index.stories.ts b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/index.stories.ts index 456f3e7ae733f..82d353041b649 100644 --- a/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/index.stories.ts +++ b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/index.stories.ts @@ -3,6 +3,7 @@ import descriptionMd from './VirtualizerScrollViewDescription.md'; export { Default } from './Default.stories'; export { ScrollTo } from './ScrollTo.stories'; +export { SnapToAlignment } from './SnapToAlignment.stories'; export default { title: 'Preview Components/VirtualizerScrollView', From 6839fadbc9158b281e90b87625de5038cc34b8e3 Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Wed, 5 Jul 2023 10:47:11 -0700 Subject: [PATCH 2/6] Add change log --- ...t-virtualizer-eeedf712-20cc-43fd-afc3-c4bc3ce8f9d7.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-virtualizer-eeedf712-20cc-43fd-afc3-c4bc3ce8f9d7.json diff --git a/change/@fluentui-react-virtualizer-eeedf712-20cc-43fd-afc3-c4bc3ce8f9d7.json b/change/@fluentui-react-virtualizer-eeedf712-20cc-43fd-afc3-c4bc3ce8f9d7.json new file mode 100644 index 0000000000000..eb7a69c4e2818 --- /dev/null +++ b/change/@fluentui-react-virtualizer-eeedf712-20cc-43fd-afc3-c4bc3ce8f9d7.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Fix: Ensure 'start buffer' is margin padded into the non-virtualized space on horizontal layouts", + "packageName": "@fluentui/react-virtualizer", + "email": "mifraser@microsoft.com", + "dependentChangeType": "patch" +} From 037a386d52c861c9a0ea95b8717b98f8193bcea7 Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Thu, 6 Jul 2023 11:03:59 -0700 Subject: [PATCH 3/6] Remove unneeded commment --- .../stories/VirtualizerScrollView/SnapToAlignment.stories.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx index 292a1abb94884..a60d40385e3bb 100644 --- a/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx @@ -14,8 +14,6 @@ const useStyles = makeStyles({ ...shorthands.gap('10px'), }, child: { - // comment out `scrollSnapAlign` for keyboard - // and scrolling to work scrollSnapAlign: 'start', height: '100px', width: '100px', From f04a2356b2dd35fc634818748555ab027a8eb6f2 Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Thu, 6 Jul 2023 12:38:40 -0700 Subject: [PATCH 4/6] Fix up sizing arrays and more eloquent measure --- .../src/components/Virtualizer/useVirtualizer.ts | 11 +++++------ .../src/hooks/useDynamicVirtualizerMeasure.ts | 6 +++--- .../VirtualizerScrollViewDynamic/Default.stories.tsx | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizer.ts b/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizer.ts index 9f6c4d24b0743..c624eca75bd47 100644 --- a/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizer.ts +++ b/packages/react-components/react-virtualizer/src/components/Virtualizer/useVirtualizer.ts @@ -113,7 +113,6 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta // Local updates updateChildRows(index); updateCurrentItemSizes(index); - // State setters setActualIndex(index); }; @@ -277,7 +276,7 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta }, [getItemSize, itemSize, numItems]); const calculateBefore = useCallback(() => { - const currentIndex = Math.min(actualIndex, numItems); + const currentIndex = Math.min(actualIndex, numItems - 1); if (!getItemSize) { // The missing items from before virtualization starts height @@ -293,19 +292,19 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta }, [actualIndex, getItemSize, itemSize, numItems]); const calculateAfter = useCallback(() => { - if (numItems === 0) { + if (numItems === 0 || actualIndex + virtualizerLength >= numItems) { return 0; } - const lastItemIndex = Math.min(actualIndex + virtualizerLength, numItems - 1); + const lastItemIndex = Math.min(actualIndex + virtualizerLength, numItems); if (!getItemSize) { // The missing items from after virtualization ends height - const remainingItems = numItems - lastItemIndex - 1; + const remainingItems = numItems - lastItemIndex; return remainingItems * itemSize; } // Time for custom size calcs - return childProgressiveSizes.current[numItems - 1] - childProgressiveSizes.current[lastItemIndex]; + return childProgressiveSizes.current[numItems - 1] - childProgressiveSizes.current[lastItemIndex - 1]; }, [actualIndex, getItemSize, itemSize, numItems, virtualizerLength]); const updateChildRows = useCallback( diff --git a/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts b/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts index e026991d5801c..dc832a406465c 100644 --- a/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts +++ b/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts @@ -58,14 +58,14 @@ export const useDynamicVirtualizerMeasure = ( /* * Number of items to append at each end, i.e. 'preload' each side before entering view. */ - const bufferItems = Math.max(Math.floor(length / 4), 2); + const bufferItems = Math.max(Math.floor(length / 4), 4); /* * This is how far we deviate into the bufferItems to detect a redraw. */ - const bufferSize = Math.max(Math.floor((length / 8) * defaultItemSize), 1); + const bufferSize = Math.max(Math.floor((length / 8) * defaultItemSize), 25); - const totalLength = length + bufferItems * 2 + 3; + const totalLength = length + bufferItems * 2 + 1; setState({ virtualizerLength: totalLength, virtualizerBufferSize: bufferSize, diff --git a/packages/react-components/react-virtualizer/stories/VirtualizerScrollViewDynamic/Default.stories.tsx b/packages/react-components/react-virtualizer/stories/VirtualizerScrollViewDynamic/Default.stories.tsx index 6c804c6c2cef6..63fff1f9724f8 100644 --- a/packages/react-components/react-virtualizer/stories/VirtualizerScrollViewDynamic/Default.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/VirtualizerScrollViewDynamic/Default.stories.tsx @@ -23,7 +23,7 @@ export const Default = () => { useEffect(() => { let _totalSize = 0; for (let i = 0; i < childLength; i++) { - arraySize.current[i] = Math.random() * 150 + minHeight; + arraySize.current[i] = Math.floor(Math.random() * 150 + minHeight); _totalSize += arraySize.current[i]; } setTotalSize(_totalSize); From ca36daa8e73ea7780b9600e382f32e42b9738bba Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Thu, 6 Jul 2023 12:52:05 -0700 Subject: [PATCH 5/6] Use 1px overflow min on dynamic (cant assume sizing) --- .../react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts b/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts index dc832a406465c..91302fe36d734 100644 --- a/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts +++ b/packages/react-components/react-virtualizer/src/hooks/useDynamicVirtualizerMeasure.ts @@ -63,7 +63,7 @@ export const useDynamicVirtualizerMeasure = ( /* * This is how far we deviate into the bufferItems to detect a redraw. */ - const bufferSize = Math.max(Math.floor((length / 8) * defaultItemSize), 25); + const bufferSize = Math.max(Math.floor((length / 8) * defaultItemSize), 1); const totalLength = length + bufferItems * 2 + 1; setState({ From ee2ce1910fe4cd7e39e7ce7efad0dd8fd86316e6 Mon Sep 17 00:00:00 2001 From: Mitch-At-Work Date: Thu, 6 Jul 2023 12:59:13 -0700 Subject: [PATCH 6/6] Remove dependency on anchor overflow none --- .../useVirtualizerScrollViewStyles.styles.ts | 2 -- .../useVirtualizerScrollViewDynamicStyles.styles.ts | 1 - .../react-virtualizer/stories/Virtualizer/Default.stories.tsx | 1 - .../stories/Virtualizer/DefaultUnbounded.stories.tsx | 1 - .../react-virtualizer/stories/Virtualizer/Dynamic.stories.tsx | 1 - .../stories/Virtualizer/Horizontal.stories.tsx | 1 - .../stories/Virtualizer/MultiUnbounded.stories.tsx | 1 - .../react-virtualizer/stories/Virtualizer/RTL.stories.tsx | 1 - .../react-virtualizer/stories/Virtualizer/Reversed.stories.tsx | 1 - .../stories/Virtualizer/ReversedHorizontal.stories.tsx | 1 - .../stories/VirtualizerScrollView/SnapToAlignment.stories.tsx | 1 - 11 files changed, 12 deletions(-) diff --git a/packages/react-components/react-virtualizer/src/components/VirtualizerScrollView/useVirtualizerScrollViewStyles.styles.ts b/packages/react-components/react-virtualizer/src/components/VirtualizerScrollView/useVirtualizerScrollViewStyles.styles.ts index cd0221a8cff35..15e818c0f0cb5 100644 --- a/packages/react-components/react-virtualizer/src/components/VirtualizerScrollView/useVirtualizerScrollViewStyles.styles.ts +++ b/packages/react-components/react-virtualizer/src/components/VirtualizerScrollView/useVirtualizerScrollViewStyles.styles.ts @@ -16,11 +16,9 @@ const useStyles = makeStyles({ display: 'flex', width: '100%', height: '100%', - overflowAnchor: 'none', }, vertical: { flexDirection: 'column', - overflowAnchor: 'none', overflowY: 'auto', }, horizontal: { diff --git a/packages/react-components/react-virtualizer/src/components/VirtualizerScrollViewDynamic/useVirtualizerScrollViewDynamicStyles.styles.ts b/packages/react-components/react-virtualizer/src/components/VirtualizerScrollViewDynamic/useVirtualizerScrollViewDynamicStyles.styles.ts index 40c3c2a9b18de..a1a58fb7e6994 100644 --- a/packages/react-components/react-virtualizer/src/components/VirtualizerScrollViewDynamic/useVirtualizerScrollViewDynamicStyles.styles.ts +++ b/packages/react-components/react-virtualizer/src/components/VirtualizerScrollViewDynamic/useVirtualizerScrollViewDynamicStyles.styles.ts @@ -18,7 +18,6 @@ const useStyles = makeStyles({ display: 'flex', width: '100%', height: '100%', - overflowAnchor: 'none', }, vertical: { flexDirection: 'column', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/Default.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/Default.stories.tsx index 28b75b3f13a2f..a1e8b98ff9145 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/Default.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/Default.stories.tsx @@ -6,7 +6,6 @@ const useStyles = makeStyles({ container: { display: 'flex', flexDirection: 'column', - overflowAnchor: 'none', overflowY: 'auto', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/DefaultUnbounded.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/DefaultUnbounded.stories.tsx index 799190d010d26..a22d4758951ae 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/DefaultUnbounded.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/DefaultUnbounded.stories.tsx @@ -14,7 +14,6 @@ const useStyles = makeStyles({ */ display: 'flex', flexDirection: 'column', - overflowAnchor: 'none', maxHeight: '300VH', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/Dynamic.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/Dynamic.stories.tsx index f89975410c0e7..6705c92cf2a9b 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/Dynamic.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/Dynamic.stories.tsx @@ -13,7 +13,6 @@ const useStyles = makeStyles({ container: { display: 'flex', flexDirection: 'column', - overflowAnchor: 'none', overflowY: 'auto', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/Horizontal.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/Horizontal.stories.tsx index 9b0539346f338..16edbe43f39f4 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/Horizontal.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/Horizontal.stories.tsx @@ -6,7 +6,6 @@ const useStyles = makeStyles({ container: { display: 'flex', flexDirection: 'row', - overflowAnchor: 'none', overflowY: 'auto', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/MultiUnbounded.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/MultiUnbounded.stories.tsx index 53bab4dffe408..e6bf79745fd88 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/MultiUnbounded.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/MultiUnbounded.stories.tsx @@ -12,7 +12,6 @@ const useStyles = makeStyles({ */ display: 'flex', flexDirection: 'column', - overflowAnchor: 'none', maxHeight: '300VH', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/RTL.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/RTL.stories.tsx index 9f6d296753b31..dcb16f951cb12 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/RTL.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/RTL.stories.tsx @@ -6,7 +6,6 @@ const useStyles = makeStyles({ container: { display: 'flex', flexDirection: 'row', - overflowAnchor: 'none', overflowY: 'auto', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/Reversed.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/Reversed.stories.tsx index a774d23f4321c..109f2da1f82c9 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/Reversed.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/Reversed.stories.tsx @@ -6,7 +6,6 @@ const useStyles = makeStyles({ container: { display: 'flex', flexDirection: 'column-reverse', - overflowAnchor: 'none', overflowY: 'auto', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/Virtualizer/ReversedHorizontal.stories.tsx b/packages/react-components/react-virtualizer/stories/Virtualizer/ReversedHorizontal.stories.tsx index 8d0ca6180070d..bdb10df418cf6 100644 --- a/packages/react-components/react-virtualizer/stories/Virtualizer/ReversedHorizontal.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/Virtualizer/ReversedHorizontal.stories.tsx @@ -6,7 +6,6 @@ const useStyles = makeStyles({ container: { display: 'flex', flexDirection: 'row-reverse', - overflowAnchor: 'none', overflowY: 'auto', width: '100%', height: '100%', diff --git a/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx index a60d40385e3bb..3c28373410a70 100644 --- a/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/VirtualizerScrollView/SnapToAlignment.stories.tsx @@ -9,7 +9,6 @@ const useStyles = makeStyles({ maxWidth: '100%', scrollSnapType: 'x mandatory', scrollBehavior: 'auto', - overflowAnchor: 'none', ...shorthands.padding('10px', '2px'), ...shorthands.gap('10px'), },