Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4189380
Squish dynamic changes for rebase
Mitch-At-Work Mar 21, 2023
ab58ef0
Update size function to use callback and be updateable if changed
Mitch-At-Work Mar 23, 2023
c6b3afb
Removed unneeded style
Mitch-At-Work Mar 23, 2023
96c6f06
Change files
Mitch-At-Work Mar 23, 2023
8cc6259
Dont export context itself
Mitch-At-Work Mar 23, 2023
5edf804
Update api
Mitch-At-Work Mar 23, 2023
27a7f30
Merge branch 'master' into user/mifraser/dynamic-virtualizer-hooks
Mitch-At-Work Mar 23, 2023
0265b0a
Merge branch 'master' into user/mifraser/dynamic-virtualizer-hooks
Mitch-At-Work Mar 24, 2023
5aaa60e
Merge branch 'master' into user/mifraser/dynamic-virtualizer-hooks
Mitch-At-Work Mar 28, 2023
39d20de
Remove Theme Provider and ensure all demos have a max height set
Mitch-At-Work Mar 28, 2023
3555dd8
Enable virtualizer render in dynamic scroll view
Mitch-At-Work Mar 28, 2023
9645956
Fix comment
Mitch-At-Work Mar 28, 2023
4a72600
Merge branch 'master' into user/mifraser/dynamic-virtualizer-hooks
Mitch-At-Work Mar 28, 2023
bde3877
Fix up storybook use effect import
Mitch-At-Work Mar 28, 2023
42b2c28
Merge branch 'user/mifraser/dynamic-virtualizer-hooks' of https://git…
Mitch-At-Work Mar 28, 2023
fb7811a
Tidy up ref and fix numItems link
Mitch-At-Work Apr 3, 2023
d4700aa
Update dynamic sizing algo to ensure optimization prior to render (dy…
Mitch-At-Work Apr 3, 2023
5f7be10
Remove smaller check (for now)
Mitch-At-Work Apr 3, 2023
765cf33
Fix up smaller/larger dynamic size virtualizer length detection
Mitch-At-Work Apr 3, 2023
dff5d76
Update demo to return randomization
Mitch-At-Work Apr 3, 2023
a157094
Dynamic function requires an additional item for buffer for safer mea…
Mitch-At-Work Apr 3, 2023
5ba9d33
Initial callback framework
Mitch-At-Work Mar 31, 2023
f714bda
Completed PoC for static
Mitch-At-Work Apr 3, 2023
99820ce
Stash dynamic changes
Mitch-At-Work Apr 3, 2023
42344ca
Ensure dynamic can track most up to date internal sizing
Mitch-At-Work Apr 3, 2023
92c4acf
Remove content index (for now)
Mitch-At-Work Apr 3, 2023
c67a009
remove comment
Mitch-At-Work Apr 3, 2023
b34623c
We are gonna have to rely on our pre-calcs via context to be fully ac…
Mitch-At-Work Apr 3, 2023
2804630
unneeded dep
Mitch-At-Work Apr 4, 2023
b25bcae
Add optional 'isScrolling' flag in case users want to render placehol…
Mitch-At-Work Apr 4, 2023
1038aa3
Lets expose progressive sizes also so that users can inject any async…
Mitch-At-Work Apr 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "feature: Add dynamically sized virtualizer scroll view",
"packageName": "@fluentui/react-components",
"email": "mifraser@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "feature: Add dynamically sized virtualizer scroll view",
"packageName": "@fluentui/react-virtualizer",
"email": "mifraser@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { CheckboxFieldProps_unstable as CheckboxFieldProps } from '@fluentui/rea
import { ComboboxField_unstable as ComboboxField } from '@fluentui/react-combobox';
import { comboboxFieldClassNames } from '@fluentui/react-combobox';
import { ComboboxFieldProps_unstable as ComboboxFieldProps } from '@fluentui/react-combobox';
import { ContextlessVirtualizerScrollViewDynamic } from '@fluentui/react-virtualizer';
import { Field } from '@fluentui/react-field';
import { fieldClassNames } from '@fluentui/react-field';
import { FieldProps } from '@fluentui/react-field';
Expand Down Expand Up @@ -46,6 +47,7 @@ import { RadioGroupField_unstable as RadioGroupField } from '@fluentui/react-rad
import { radioGroupFieldClassNames } from '@fluentui/react-radio';
import { RadioGroupFieldProps_unstable as RadioGroupFieldProps } from '@fluentui/react-radio';
import { renderAlert_unstable } from '@fluentui/react-alert';
import { renderContextlessVirtualizerScrollViewDynamic_unstable } from '@fluentui/react-virtualizer';
import { renderField_unstable } from '@fluentui/react-field';
import { renderInfoButton_unstable } from '@fluentui/react-infobutton';
import { renderInfoLabel_unstable } from '@fluentui/react-infobutton';
Expand All @@ -57,6 +59,7 @@ import { renderTreeItemLayout_unstable } from '@fluentui/react-tree';
import { renderTreeItemPersonaLayout_unstable } from '@fluentui/react-tree';
import { renderVirtualizer_unstable } from '@fluentui/react-virtualizer';
import { renderVirtualizerScrollView_unstable } from '@fluentui/react-virtualizer';
import { renderVirtualizerScrollViewDynamic_unstable } from '@fluentui/react-virtualizer';
import { SelectField_unstable as SelectField } from '@fluentui/react-select';
import { selectFieldClassNames } from '@fluentui/react-select';
import { SelectFieldProps_unstable as SelectFieldProps } from '@fluentui/react-select';
Expand Down Expand Up @@ -115,6 +118,7 @@ import { TreeSlots } from '@fluentui/react-tree';
import { TreeState } from '@fluentui/react-tree';
import { useAlert_unstable } from '@fluentui/react-alert';
import { useAlertStyles_unstable } from '@fluentui/react-alert';
import { useDynamicVirtualizerMeasure } from '@fluentui/react-virtualizer';
import { useField_unstable } from '@fluentui/react-field';
import { useFieldStyles_unstable } from '@fluentui/react-field';
import { useFlatTree_unstable } from '@fluentui/react-tree';
Expand All @@ -140,15 +144,25 @@ import { useTreeItemPersonaLayoutStyles_unstable } from '@fluentui/react-tree';
import { useTreeItemStyles_unstable } from '@fluentui/react-tree';
import { useTreeStyles_unstable } from '@fluentui/react-tree';
import { useVirtualizer_unstable } from '@fluentui/react-virtualizer';
import { useVirtualizerContext } from '@fluentui/react-virtualizer';
import { useVirtualizerScrollView_unstable } from '@fluentui/react-virtualizer';
import { useVirtualizerScrollViewDynamic_unstable } from '@fluentui/react-virtualizer';
import { useVirtualizerScrollViewDynamicStyles_unstable } from '@fluentui/react-virtualizer';
import { useVirtualizerScrollViewStyles_unstable } from '@fluentui/react-virtualizer';
import { useVirtualizerStyles_unstable } from '@fluentui/react-virtualizer';
import { Virtualizer } from '@fluentui/react-virtualizer';
import { VirtualizerChildRenderFunction } from '@fluentui/react-virtualizer';
import { virtualizerClassNames } from '@fluentui/react-virtualizer';
import { VirtualizerContextProps } from '@fluentui/react-virtualizer';
import { VirtualizerContextProvider } from '@fluentui/react-virtualizer';
import { VirtualizerProps } from '@fluentui/react-virtualizer';
import { VirtualizerScrollView } from '@fluentui/react-virtualizer';
import { virtualizerScrollViewClassNames } from '@fluentui/react-virtualizer';
import { VirtualizerScrollViewDynamic } from '@fluentui/react-virtualizer';
import { virtualizerScrollViewDynamicClassNames } from '@fluentui/react-virtualizer';
import { VirtualizerScrollViewDynamicProps } from '@fluentui/react-virtualizer';
import { VirtualizerScrollViewDynamicSlots } from '@fluentui/react-virtualizer';
import { VirtualizerScrollViewDynamicState } from '@fluentui/react-virtualizer';
import { VirtualizerScrollViewProps } from '@fluentui/react-virtualizer';
import { VirtualizerScrollViewSlots } from '@fluentui/react-virtualizer';
import { VirtualizerScrollViewState } from '@fluentui/react-virtualizer';
Expand Down Expand Up @@ -177,6 +191,8 @@ export { comboboxFieldClassNames }

export { ComboboxFieldProps }

export { ContextlessVirtualizerScrollViewDynamic }

export { Field }

export { fieldClassNames }
Expand Down Expand Up @@ -239,6 +255,8 @@ export { RadioGroupFieldProps }

export { renderAlert_unstable }

export { renderContextlessVirtualizerScrollViewDynamic_unstable }

export { renderField_unstable }

export { renderInfoButton_unstable }
Expand All @@ -261,6 +279,8 @@ export { renderVirtualizer_unstable }

export { renderVirtualizerScrollView_unstable }

export { renderVirtualizerScrollViewDynamic_unstable }

export { SelectField }

export { selectFieldClassNames }
Expand Down Expand Up @@ -377,6 +397,8 @@ export { useAlert_unstable }

export { useAlertStyles_unstable }

export { useDynamicVirtualizerMeasure }

export { useField_unstable }

export { useFieldStyles_unstable }
Expand Down Expand Up @@ -427,8 +449,14 @@ export { useTreeStyles_unstable }

export { useVirtualizer_unstable }

export { useVirtualizerContext }

export { useVirtualizerScrollView_unstable }

export { useVirtualizerScrollViewDynamic_unstable }

export { useVirtualizerScrollViewDynamicStyles_unstable }

export { useVirtualizerScrollViewStyles_unstable }

export { useVirtualizerStyles_unstable }
Expand All @@ -439,12 +467,26 @@ export { VirtualizerChildRenderFunction }

export { virtualizerClassNames }

export { VirtualizerContextProps }

export { VirtualizerContextProvider }

export { VirtualizerProps }

export { VirtualizerScrollView }

export { virtualizerScrollViewClassNames }

export { VirtualizerScrollViewDynamic }

export { virtualizerScrollViewDynamicClassNames }

export { VirtualizerScrollViewDynamicProps }

export { VirtualizerScrollViewDynamicSlots }

export { VirtualizerScrollViewDynamicState }

export { VirtualizerScrollViewProps }

export { VirtualizerScrollViewSlots }
Expand Down
14 changes: 14 additions & 0 deletions packages/react-components/react-components/src/unstable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,21 @@ export {
useVirtualizerStyles_unstable,
useIntersectionObserver,
useStaticVirtualizerMeasure,
useDynamicVirtualizerMeasure,
VirtualizerContextProvider,
useVirtualizerContext,
VirtualizerScrollView,
virtualizerScrollViewClassNames,
useVirtualizerScrollView_unstable,
renderVirtualizerScrollView_unstable,
useVirtualizerScrollViewStyles_unstable,
VirtualizerScrollViewDynamic,
ContextlessVirtualizerScrollViewDynamic,
virtualizerScrollViewDynamicClassNames,
useVirtualizerScrollViewDynamic_unstable,
renderVirtualizerScrollViewDynamic_unstable,
renderContextlessVirtualizerScrollViewDynamic_unstable,
useVirtualizerScrollViewDynamicStyles_unstable,
} from '@fluentui/react-virtualizer';
export type {
VirtualizerProps,
Expand All @@ -135,6 +145,10 @@ export type {
VirtualizerScrollViewProps,
VirtualizerScrollViewState,
VirtualizerScrollViewSlots,
VirtualizerContextProps,
VirtualizerScrollViewDynamicProps,
VirtualizerScrollViewDynamicState,
VirtualizerScrollViewDynamicSlots,
} from '@fluentui/react-virtualizer';

export {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,29 @@ import type { SetStateAction } from 'react';
import { Slot } from '@fluentui/react-utilities';
import type { SlotClassNames } from '@fluentui/react-utilities';

// @public
export const ContextlessVirtualizerScrollViewDynamic: React_2.FC<VirtualizerScrollViewDynamicProps>;

// @public (undocumented)
export const renderContextlessVirtualizerScrollViewDynamic_unstable: (state: VirtualizerScrollViewDynamicState) => JSX.Element;

// @public (undocumented)
export const renderVirtualizer_unstable: (state: VirtualizerState) => JSX.Element;

// @public (undocumented)
export const renderVirtualizerScrollView_unstable: (state: VirtualizerScrollViewState) => JSX.Element;

// @public (undocumented)
export const renderVirtualizerScrollViewDynamic_unstable: (props: VirtualizerScrollViewDynamicProps, context: VirtualizerContextProps) => JSX.Element;

// @public
export const useDynamicVirtualizerMeasure: (virtualizerProps: VirtualizerMeasureDynamicProps) => {
virtualizerLength: number;
bufferItems: number;
bufferSize: number;
scrollRef: (instance: HTMLElement | HTMLDivElement | null) => void;
};

// @public
export const useIntersectionObserver: (callback: IntersectionObserverCallback, options?: IntersectionObserverInit | undefined) => {
setObserverList: Dispatch<SetStateAction<Element[] | undefined>>;
Expand All @@ -38,9 +55,18 @@ export const useStaticVirtualizerMeasure: (virtualizerProps: VirtualizerMeasureP
// @public (undocumented)
export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerState;

// @public (undocumented)
export const useVirtualizerContext: () => VirtualizerContextProps;

// @public (undocumented)
export function useVirtualizerScrollView_unstable(props: VirtualizerScrollViewProps): VirtualizerScrollViewState;

// @public (undocumented)
export function useVirtualizerScrollViewDynamic_unstable(props: VirtualizerScrollViewDynamicProps): VirtualizerScrollViewDynamicState;

// @public
export const useVirtualizerScrollViewDynamicStyles_unstable: (state: VirtualizerScrollViewDynamicState) => VirtualizerScrollViewDynamicState;

// @public
export const useVirtualizerScrollViewStyles_unstable: (state: VirtualizerScrollViewState) => VirtualizerScrollViewState;

Expand All @@ -56,6 +82,15 @@ export type VirtualizerChildRenderFunction = (index: number) => React_2.ReactNod
// @public (undocumented)
export const virtualizerClassNames: SlotClassNames<VirtualizerSlots>;

// @public (undocumented)
export type VirtualizerContextProps = {
contextIndex: number;
setContextIndex: (index: number) => void;
};

// @public (undocumented)
export const VirtualizerContextProvider: React_2.Provider<VirtualizerContextProps>;

// @public (undocumented)
export type VirtualizerProps = ComponentProps<Partial<VirtualizerSlots>> & VirtualizerConfigProps;

Expand All @@ -65,6 +100,26 @@ export const VirtualizerScrollView: React_2.FC<VirtualizerScrollViewProps>;
// @public (undocumented)
export const virtualizerScrollViewClassNames: SlotClassNames<VirtualizerScrollViewSlots>;

// @public (undocumented)
export const VirtualizerScrollViewDynamic: React_2.FC<VirtualizerScrollViewDynamicProps>;

// @public (undocumented)
export const virtualizerScrollViewDynamicClassNames: SlotClassNames<VirtualizerScrollViewDynamicSlots>;

// @public (undocumented)
export type VirtualizerScrollViewDynamicProps = ComponentProps<Partial<VirtualizerScrollViewDynamicSlots>> & Partial<Omit<VirtualizerConfigProps, 'itemSize' | 'numItems' | 'getItemSize' | 'children'>> & {
itemSize: number;
getItemSize: (index: number) => number;
numItems: number;
children: VirtualizerChildRenderFunction;
};

// @public (undocumented)
export type VirtualizerScrollViewDynamicSlots = VirtualizerScrollViewSlots;

// @public (undocumented)
export type VirtualizerScrollViewDynamicState = ComponentState<VirtualizerScrollViewDynamicSlots> & VirtualizerConfigState;

// @public (undocumented)
export type VirtualizerScrollViewProps = ComponentProps<Partial<VirtualizerScrollViewSlots>> & Partial<Omit<VirtualizerConfigProps, 'itemSize' | 'numItems' | 'getItemSize' | 'children'>> & {
itemSize: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './utilities/index';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/VirtualizerScrollViewDynamic/index';
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export type VirtualizerState = ComponentState<VirtualizerSlots> & VirtualizerCon

// Virtualizer render function to procedurally generate children elements as rows or columns via index.
// Q: Use generic typing and passing through object data or a simple index system?
export type VirtualizerChildRenderFunction = (index: number) => React.ReactNode;
export type VirtualizerChildRenderFunction = (index: number, isScrolling?: boolean) => React.ReactNode;

export type VirtualizerConfigProps = {
/**
Expand Down Expand Up @@ -135,14 +135,26 @@ export type VirtualizerConfigProps = {
getItemSize?: (index: number) => number;

/**
* Notify users of index changes
* Callback for notifying when a flagged index has been rendered
*/
onUpdateIndex?: (index: number, prevIndex: number) => void;
onRenderedFlaggedIndex?: (index: number) => number;

/*
* Callback object to notify when a flagged index has been rendered
*/
flagIndex?: FlaggedIndexCallback;
};

export type FlaggedIndexCallback = {
/**
* Allow users to intervene in index calculation changes
* Callback for notifying when a flagged index has been rendered
*/
onRenderedFlaggedIndex: (index: number) => number;

/*
* Callback for notifying when a flagged index has been rendered
*/
onCalculateIndex?: (newIndex: number) => number;
flaggedIndex: React.MutableRefObject<number | null>;
};

export type VirtualizerProps = ComponentProps<Partial<VirtualizerSlots>> & VirtualizerConfigProps;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { getSlots } from '@fluentui/react-utilities';
import { VirtualizerSlots, VirtualizerState } from './Virtualizer.types';
import { ReactNode } from 'react';

export const renderVirtualizer_unstable = (state: VirtualizerState) => {
const { slots, slotProps } = getSlots<VirtualizerSlots>(state);
Expand All @@ -20,3 +21,11 @@ export const renderVirtualizer_unstable = (state: VirtualizerState) => {
</React.Fragment>
);
};

export const renderVirtualizerChildPlaceholder = (child: ReactNode, index: number, isScrolling?: boolean) => {
return (
<React.Suspense key={`fui-virtualizer-placeholder-${index}`} fallback={null}>
{child}
</React.Suspense>
);
};
Loading