Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Add Virtualizer docs #7700

Merged
merged 16 commits into from
Feb 20, 2025
Merged

docs: Add Virtualizer docs #7700

merged 16 commits into from
Feb 20, 2025

Conversation

devongovett
Copy link
Member

@devongovett devongovett commented Feb 1, 2025

Closes #7361, closes #6751, closes #5707, closes #6981

Adds docs for Virtualizer with examples of list, grid, and table layouts, along with basic docs for custom collection renderers. Decided to only put these docs on a standalone Virtualizer page and not add examples to each individual component for now to keep the size of component pages down. We'll see how well people fined it.

Added padding and gap options to ListLayout while I was at it since I needed it for the examples.

Also removes UNSTABLE prefix from virtualizer exports. Did not yet remove it from collection renderer and collection builder stuff. Are we ready to do that? We will need to update the hook docs to use new collections at some point as well.

@rspbot
Copy link

rspbot commented Feb 1, 2025

@rspbot
Copy link

rspbot commented Feb 1, 2025

Copy link
Member

@reidbarber reidbarber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look great!

@rspbot
Copy link

rspbot commented Feb 4, 2025

…er-docs

# Conflicts:
#	packages/@react-spectrum/s2/src/TreeView.tsx
#	packages/react-aria-components/stories/Autocomplete.stories.tsx
@rspbot
Copy link

rspbot commented Feb 14, 2025

reidbarber
reidbarber previously approved these changes Feb 14, 2025

return (
<Virtualizer layout={layout}>
<ListBox aria-label="Favorite animal" items={items} style={{height: 'fit-content'}}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to add "orientation="horizontal" to the listbox. just feels weird having to use the up and down arrow keys to navigate through it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great catch!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

turns out I had to handle persisted keys in the layout as well. I'd like to move this logic into Virtualizer itself so every layout doesn't have to handle it but will do that separately.

@rspbot
Copy link

rspbot commented Feb 15, 2025

@rspbot
Copy link

rspbot commented Feb 19, 2025

@rspbot
Copy link

rspbot commented Feb 19, 2025

## API Changes

react-aria-components

/react-aria-components:UNSTABLE_CollectionRendererContext

-UNSTABLE_CollectionRendererContext {
-  UNTYPED
-}

/react-aria-components:UNSTABLE_DefaultCollectionRenderer

-UNSTABLE_DefaultCollectionRenderer {
-  CollectionBranch: (any) => void
-  CollectionRoot: (any) => void
-}

/react-aria-components:UNSTABLE_TableLayout

-UNSTABLE_TableLayout <T> {
-  constructor: (ListLayoutOptions) => void
-  getContentSize: () => void
-  getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget | null
-  getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
-  getItemRect: (Key) => Rect | null
-  getLayoutInfo: (Key) => void
-  getVisibleLayoutInfos: (Rect) => void
-  getVisibleRect: () => Rect
-  shouldInvalidate: (Rect, Rect) => boolean
-  update: (InvalidationContext<TableLayoutProps>) => void
-  updateItemSize: (Key, Size) => void
-  useLayoutOptions: () => void
-  virtualizer: Virtualizer<{}, any> | null
-}

/react-aria-components:UNSTABLE_Virtualizer

-UNSTABLE_Virtualizer <O> {
-  children: ReactNode
-  layout: ILayout<O>
-  layoutOptions?: O
-}

/react-aria-components:UNSTABLE_ListLayout

-UNSTABLE_ListLayout <O = any, T> {
-  constructor: (ListLayoutOptions) => void
-  getContentSize: () => void
-  getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget | null
-  getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
-  getItemRect: (Key) => Rect | null
-  getLayoutInfo: (Key) => void
-  getVisibleLayoutInfos: (Rect) => void
-  getVisibleRect: () => Rect
-  shouldInvalidate: (Rect, Rect) => boolean
-  update: (InvalidationContext<O>) => void
-  updateItemSize: (Key, Size) => void
-  virtualizer: Virtualizer<{}, any> | null
-}

/react-aria-components:UNSTABLE_GridLayout

-UNSTABLE_GridLayout <O = any, T> {
-  constructor: (GridLayoutOptions) => void
-  getContentSize: () => Size
-  getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget
-  getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
-  getItemRect: (Key) => Rect | null
-  getLayoutInfo: (Key) => LayoutInfo | null
-  getVisibleLayoutInfos: (Rect) => Array<LayoutInfo>
-  getVisibleRect: () => Rect
-  shouldInvalidate: (Rect, Rect) => boolean
-  update: () => void
-  updateItemSize: (Key, Size) => boolean
-  virtualizer: Virtualizer<{}, any> | null
-}

/react-aria-components:ListLayoutOptions

 ListLayoutOptions {
-  dropIndicatorThickness?: number
+  dropIndicatorThickness?: number = 2
   estimatedHeadingHeight?: number
   estimatedRowHeight?: number
-  headingHeight?: number
-  loaderHeight?: number
-  rowHeight?: number
+  gap?: number = 0
+  headingHeight?: number = 48
+  loaderHeight?: number = 48
+  padding?: number = 0
+  rowHeight?: number = 48
 }

/react-aria-components:CollectionRendererContext

+CollectionRendererContext {
+  UNTYPED
+}

/react-aria-components:DefaultCollectionRenderer

+DefaultCollectionRenderer {
+  CollectionBranch: (any) => void
+  CollectionRoot: (any) => void
+}

/react-aria-components:TableLayout

+TableLayout <T> {
+  constructor: (ListLayoutOptions) => void
+  getContentSize: () => void
+  getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget | null
+  getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
+  getLayoutInfo: (Key) => void
+  getVisibleLayoutInfos: (Rect) => void
+  shouldInvalidate: (Rect, Rect) => boolean
+  update: (InvalidationContext<TableLayoutProps>) => void
+  updateItemSize: (Key, Size) => void
+  useLayoutOptions: () => void
+  virtualizer: Virtualizer<{}, any> | null
+}

/react-aria-components:Virtualizer

+Virtualizer <O> {
+  children: ReactNode
+  layout: ILayout<O>
+  layoutOptions?: O
+}

/react-aria-components:ListLayout

+ListLayout <O = any, T> {
+  constructor: (ListLayoutOptions) => void
+  getContentSize: () => void
+  getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget | null
+  getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
+  getLayoutInfo: (Key) => void
+  getVisibleLayoutInfos: (Rect) => void
+  shouldInvalidate: (Rect, Rect) => boolean
+  update: (InvalidationContext<O>) => void
+  updateItemSize: (Key, Size) => void
+  virtualizer: Virtualizer<{}, any> | null
+}

/react-aria-components:GridLayout

+GridLayout <O = any, T> {
+  constructor: (GridLayoutOptions) => void
+  getContentSize: () => Size
+  getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget
+  getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
+  getLayoutInfo: (Key) => LayoutInfo | null
+  getVisibleLayoutInfos: (Rect) => Array<LayoutInfo>
+  shouldInvalidate: (Rect, Rect) => boolean
+  update: () => void
+  updateItemSize: (Key, Size) => boolean
+  virtualizer: Virtualizer<{}, any> | null
+}

/react-aria-components:Layout

+Layout <O = any, T extends {} = Node<any>> {
+  getContentSize: () => Size
+  getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
+  getLayoutInfo: (Key) => LayoutInfo | null
+  getVisibleLayoutInfos: (Rect) => Array<LayoutInfo>
+  shouldInvalidate: (Rect, Rect) => boolean
+  update: (InvalidationContext<O>) => void
+  updateItemSize: (Key, Size) => boolean
+  virtualizer: Virtualizer<{}, any> | null
+}

/react-aria-components:LayoutInfo

+LayoutInfo {
+  allowOverflow: boolean = false
+  constructor: (string, Key, Rect) => void
+  content: any | null
+  copy: () => LayoutInfo
+  estimatedSize: boolean = false
+  isSticky: boolean = false
+  key: Key
+  opacity: number = 1
+  parentKey: Key | null
+  rect: Rect
+  transform: string | null
+  type: string
+  zIndex: number
+}

/react-aria-components:Size

+Size {
+  area: any
+  constructor: (any, any) => void
+  copy: () => Size
+  equals: (Size) => boolean
+  height: number
+  width: number
+}

/react-aria-components:Rect

+Rect {
+  area: number
+  bottomLeft: Point
+  bottomRight: Point
+  constructor: (any, any, any, any) => void
+  containsPoint: (Point) => boolean
+  containsRect: (Rect) => boolean
+  copy: () => Rect
+  equals: (Rect) => void
+  getCornerInRect: (Rect) => RectCorner | null
+  height: number
+  intersection: (Rect) => Rect
+  intersects: (Rect) => boolean
+  maxX: number
+  maxY: number
+  pointEquals: (Point | Rect) => void
+  sizeEquals: (Size | Rect) => void
+  topLeft: Point
+  topRight: Point
+  union: (Rect) => void
+  width: number
+  x: number
+  y: number
+}

/react-aria-components:Point

+Point {
+  constructor: (any, any) => void
+  copy: () => Point
+  equals: (Point) => boolean
+  isOrigin: () => boolean
+  x: number
+  y: number
+}

@react-spectrum/card

/@react-spectrum/card:GalleryLayout

 GalleryLayout <T> {
   _distributeWidths: (any) => void
   _findClosest: (Rect, Rect) => void
   _findClosestLayoutInfo: (Rect, Rect) => void
   buildCollection: () => void
   collection: GridCollection<T>
   constructor: (GalleryLayoutOptions) => void
   direction: Direction
   disabledKeys: Set<Key>
   getContentSize: () => void
   getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
   getFirstKey: () => void
-  getItemRect: (Key) => Rect | null
   getKeyAbove: (Key) => void
   getKeyBelow: (Key) => void
   getKeyForSearch: (string, Key) => void
   getKeyLeftOf: (Key) => void
   getKeyPageAbove: (Key) => void
   getKeyPageBelow: (Key) => void
   getKeyRightOf: (Key) => void
   getLastKey: () => void
   getLayoutInfo: (Key) => void
   getVisibleLayoutInfos: (Rect, any) => void
-  getVisibleRect: () => Rect
   isLoading: boolean
   isVisible: (LayoutInfo, Rect, boolean) => void
   itemPadding: number
   layoutType: any
   scale: Scale
   shouldInvalidate: (Rect, Rect) => boolean
   update: (InvalidationContext<CardViewLayoutOptions>) => void
   updateItemSize: (Key, Size) => boolean
   virtualizer: Virtualizer<{}, any> | null
 }

/@react-spectrum/card:GridLayout

 GridLayout <T> {
   _findClosest: (Rect, Rect) => void
   _findClosestLayoutInfo: (Rect, Rect) => void
   buildChild: (Node<T>, number, number) => LayoutInfo
   buildCollection: () => void
   cardOrientation: Orientation
   collection: GridCollection<T>
   constructor: (GridLayoutOptions) => void
   direction: Direction
   disabledKeys: Set<Key>
   getContentSize: () => void
   getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
   getFirstKey: () => void
   getIndexAtPoint: (any, any, any) => void
-  getItemRect: (Key) => Rect | null
   getKeyAbove: (Key) => void
   getKeyBelow: (Key) => void
   getKeyForSearch: (string, Key) => void
   getKeyLeftOf: (Key) => void
   getKeyPageAbove: (Key) => void
   getKeyPageBelow: (Key) => void
   getKeyRightOf: (Key) => void
   getLastKey: () => void
   getLayoutInfo: (Key) => void
   getVisibleLayoutInfos: (Rect, any) => void
-  getVisibleRect: () => Rect
   isLoading: boolean
   isVisible: (LayoutInfo, Rect, boolean) => void
   itemPadding: number
   layoutType: any
   scale: Scale
   shouldInvalidate: (Rect, Rect) => boolean
   update: (InvalidationContext<CardViewLayoutOptions>) => void
   updateItemSize: (Key, Size) => boolean
   virtualizer: Virtualizer<{}, any> | null
 }

/@react-spectrum/card:WaterfallLayout

 WaterfallLayout <T> {
   _findClosest: (Rect, Rect) => void
   _findClosestLayoutInfo: (Rect, Rect) => void
   buildCollection: (InvalidationContext) => void
   collection: GridCollection<T>
   constructor: (WaterfallLayoutOptions) => void
   direction: Direction
   disabledKeys: Set<Key>
   getClosestLeft: (Key) => void
   getClosestRight: (Key) => void
   getContentSize: () => void
   getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
   getFirstKey: () => void
-  getItemRect: (Key) => Rect | null
   getKeyAbove: (Key) => void
   getKeyBelow: (Key) => void
   getKeyForSearch: (string, Key) => void
   getKeyLeftOf: (Key) => void
   getKeyPageAbove: (Key) => void
   getKeyPageBelow: (Key) => void
   getKeyRightOf: (Key) => void
   getLastKey: () => void
   getLayoutInfo: (Key) => void
   getNextColumnIndex: (any) => void
   getVisibleLayoutInfos: (Rect, any) => void
-  getVisibleRect: () => Rect
   isLoading: boolean
   isVisible: (LayoutInfo, Rect, boolean) => void
   layoutType: any
   margin: number
   shouldInvalidate: (Rect, Rect) => boolean
   update: (InvalidationContext<CardViewLayoutOptions>) => void
   updateItemSize: (Key, Size) => void
   virtualizer: Virtualizer<{}, any> | null
 }

@react-stately/layout

/@react-stately/layout:ListLayoutOptions

 ListLayoutOptions {
-  dropIndicatorThickness?: number
+  dropIndicatorThickness?: number = 2
   estimatedHeadingHeight?: number
   estimatedRowHeight?: number
-  headingHeight?: number
-  loaderHeight?: number
-  rowHeight?: number
+  gap?: number = 0
+  headingHeight?: number = 48
+  loaderHeight?: number = 48
+  padding?: number = 0
+  rowHeight?: number = 48
 }

/@react-stately/layout:GridLayout

 GridLayout <O = any, T> {
   constructor: (GridLayoutOptions) => void
   getContentSize: () => Size
   getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget
   getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
-  getItemRect: (Key) => Rect | null
   getLayoutInfo: (Key) => LayoutInfo | null
   getVisibleLayoutInfos: (Rect) => Array<LayoutInfo>
-  getVisibleRect: () => Rect
   shouldInvalidate: (Rect, Rect) => boolean
   update: () => void
   updateItemSize: (Key, Size) => boolean
   virtualizer: Virtualizer<{}, any> | null

/@react-stately/layout:ListLayout

 ListLayout <O = any, T> {
   constructor: (ListLayoutOptions) => void
   getContentSize: () => void
   getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget | null
   getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
-  getItemRect: (Key) => Rect | null
   getLayoutInfo: (Key) => void
   getVisibleLayoutInfos: (Rect) => void
-  getVisibleRect: () => Rect
   shouldInvalidate: (Rect, Rect) => boolean
   update: (InvalidationContext<O>) => void
   updateItemSize: (Key, Size) => void
   virtualizer: Virtualizer<{}, any> | null

/@react-stately/layout:TableLayout

 TableLayout <O extends TableLayoutProps = TableLayoutProps, T> {
   constructor: (ListLayoutOptions) => void
   getContentSize: () => void
   getDropTargetFromPoint: (number, number, (DropTarget) => boolean) => DropTarget | null
   getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
-  getItemRect: (Key) => Rect | null
   getLayoutInfo: (Key) => void
   getVisibleLayoutInfos: (Rect) => void
-  getVisibleRect: () => Rect
   shouldInvalidate: (Rect, Rect) => boolean
   update: (InvalidationContext<TableLayoutProps>) => void
   updateItemSize: (Key, Size) => void
   virtualizer: Virtualizer<{}, any> | null

@react-stately/virtualizer

/@react-stately/virtualizer:Layout

-Layout <O = any, T extends {}> {
+Layout <O = any, T extends {} = Node<any>> {
   getContentSize: () => Size
   getDropTargetLayoutInfo: (ItemDropTarget) => LayoutInfo
-  getItemRect: (Key) => Rect | null
   getLayoutInfo: (Key) => LayoutInfo | null
   getVisibleLayoutInfos: (Rect) => Array<LayoutInfo>
-  getVisibleRect: () => Rect
   shouldInvalidate: (Rect, Rect) => boolean
   update: (InvalidationContext<O>) => void
   updateItemSize: (Key, Size) => boolean
   virtualizer: Virtualizer<{}, any> | null

/@react-stately/virtualizer:LayoutInfo

 LayoutInfo {
   allowOverflow: boolean = false
   constructor: (string, Key, Rect) => void
   content: any | null
   copy: () => LayoutInfo
-  estimatedSize: boolean
-  isSticky: boolean
+  estimatedSize: boolean = false
+  isSticky: boolean = false
   key: Key
-  opacity: number
+  opacity: number = 1
   parentKey: Key | null
   rect: Rect
   transform: string | null
   type: string
 }

@devongovett devongovett added this pull request to the merge queue Feb 20, 2025
Merged via the queue into main with commit ec9ae73 Feb 20, 2025
30 checks passed
@devongovett devongovett deleted the virtualizer-docs branch February 20, 2025 01:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants