feat: Support sections in GridLayout#10340
Open
mehdibha wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes
Currently you have to choose between virtualization and sections in a grid:
GridLayouttreats every top level collection node as a fixed size cell, so section and header nodes are never walked and a sectionedGridList/ListBoxcannot be virtualized with<Virtualizer layout={GridLayout}>.ListLayoutsupports sections (headingSize/estimatedHeadingSize), but not grid arrangement.This gap shows up in any sectioned grid: emoji pickers (I hit this building one in dotUI — a
GridListwithlayout="grid", ~1,900GridListItems grouped intoGridListSections withGridListHeaders, filtered withAutocomplete), photo galleries grouped by album/date, dashboards grouped by category.This PR adds section support to
GridLayout:ListLayout: the layout produces a hierarchicalLayoutInfofor each section (parents before children, soCollectionBranchrendering andisPersistedKeyancestor checks work), sized to contain its rows.GridLayoutOptions:headingSizeandestimatedHeadingSize, mirroringListLayout's modern option names (no deprecated*Heightvariants). WithoutheadingSize, headers are measured, starting fromestimatedHeadingSize(default 48) likeListLayout.getVisibleLayoutInfos(matchingListLayout's behavior, e.g. for sticky positioning), and loaders inside sections are laid out as full width rows.getDropTargetFromPointignores section/header rows when searching for drop targets.ListKeyboardDelegategrid logic because columns stay x-aligned across sections (covered by tests).Backward compatibility: flat collections produce the same layout as before.
update()was restructured from a precomputed rows loop into a streaming walk, preserving the existing behaviors: loader nodes still consume a grid slot and the trailing loader sentinel is laid out at the end; skeleton nodes still repeat to fill the remainder of the row and then the viewport; empty collection andpreserveAspectRatio/measured-height semantics are unchanged. All existing GridLayout/GridList/ListBox tests pass unchanged, and the only public API change is the two new optional options.✅ Pull Request Checklist:
📝 Test Instructions:
yarn jest packages/react-stately/test/virtualizer/GridLayout.test.ts— new geometry tests for sections/headers (plus the existing drop target tests).yarn jest packages/react-aria-components/test/GridList.test.js— newvirtualized grid layout with sectionstests covering rendering/virtualization of offscreen sections and keyboard navigation across section boundaries (ArrowDown/Up keep the column across a section header, End reaches the last offscreen item).GridList → VirtualizedGridListGridSection— 10 sections × 25 items in a virtualized grid with headers. Scroll, click and arrow-key around; compare with the existingVirtualizedGridListGrid(flat) story for unchanged behavior.🧢 Your Project:
dotUI