Add VirtualList + supporting flex/focus/resize infrastructure#103
Merged
WillsonHaw merged 10 commits intomainfrom May 4, 2026
Merged
Add VirtualList + supporting flex/focus/resize infrastructure#103WillsonHaw merged 10 commits intomainfrom
WillsonHaw merged 10 commits intomainfrom
Conversation
Also ran oxc lint/fmt and react-compiler and fixed reported issues
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.
Summary
Adds a FlashList v1-style virtualized list component (
@plextv/react-lightning-components/lists/VirtualList) and the supporting primitives needed to make it work cleanly inside the existing renderer/plugin stack.Headline
VirtualList— viewport derivation, scroll/focus state, recycler-pool-backed cell reuse, viewability tracking. Two layout modes decided at runtime: pinned (no flex ancestor → single source of truth fromLayoutManager) and measured (flex ancestor → cells wrap inFlexRoot, report main-axis size toLayoutManager, report cross-axis to a monotonicmaxContentCrossviewport-fallback). Authoritative spec lives inVirtualList.mdnext to the source.Supporting infrastructure
@plextv/react-lightning—NodeResizeObserver(lazy, frameTick-driven element-size watcher),FocusManager.setFocusedChild(mark a parent's preferred focus target without yanking the active focus path — load-bearing for VL recycle-restore), newresizedelement event, andCanvasPropstype export.@plextv/react-native-lightning—NativeCanvasexport for embedding a Lightning canvas inside a React Native Lightning tree.@plextv/react-lightning-plugin-flexbox— performance refactor ofYogaManager,LightningManager, and the main-thread/worker pipeline. Adds a fast-path scan intransformPropsso non-flex elements skip the split-and-allocate path entirely.Tooling
oxlint+oxfmt).Examples / Storybook
apps/react-lightning-examplepage:NestedListPage(vertical VL of horizontal VLs with variable row heights, demonstrates focus restoration across recycle).VirtualList.stories.tsxcovering vertical/horizontal/grid/header-footer-separator/empty/padding/snap-alignment/override-layout/infinite-scroll/item-types/initial-scroll/imperative/draw-distance variants.FlashList.stories.tsxandreact-native-lightning-components/CellContainer+FlashList(superseded by the new VL).Breaking Changes
The old FlashList wrapper and its CellContainer were deleted entirely. Replace usages with the new VirtualList. Public API differences worth knowing:
data,renderItem,keyExtractor,numColumns,horizontal,estimatedItemSize,ListHeaderComponent/ListFooterComponent/ListEmptyComponent/ItemSeparatorComponent,onScroll,onEndReached,onViewableItemsChanged,onLoad/onLayout,initialScrollIndexare equivalent.overrideItemLayout(layout, item, index, numColumns, extraData)— set layout.size (main-axis) and optional layout.span (multi-column). Replaces FlashList's getItemType-only hook.getItemType(item, index, extraData)— same role.style.w/style.hset viewport explicitly. contentContainerStyle carries RN-style padding + backgroundColor.@lightningjs/rendererleft beta (3.0.0-beta20 → 3.0.1)@plextv/react-lightning-plugin-flexboxnow exportsFlexRoot,FlexBoundary,useIsInFlex(and their prop types). Flexbox is now opt-in. Just including the plugin no longer enables flexbox, you need to wrap flex boundaries with aFlexRootcomponent. The exportedNativeCanvascomponent in@plextv/react-native-lightningautomatically wraps the application with a FlexRoot.