Skip to content

Add VirtualList + supporting flex/focus/resize infrastructure#103

Merged
WillsonHaw merged 10 commits intomainfrom
virtuallist
May 4, 2026
Merged

Add VirtualList + supporting flex/focus/resize infrastructure#103
WillsonHaw merged 10 commits intomainfrom
virtuallist

Conversation

@WillsonHaw
Copy link
Copy Markdown
Contributor

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 from LayoutManager) and measured (flex ancestor → cells wrap in FlexRoot, report main-axis size to LayoutManager, report cross-axis to a monotonic maxContentCross viewport-fallback). Authoritative spec lives in VirtualList.md next to the source.

Supporting infrastructure

  • @plextv/react-lightningNodeResizeObserver (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), new resized element event, and CanvasProps type export.
  • @plextv/react-native-lightningNativeCanvas export for embedding a Lightning canvas inside a React Native Lightning tree.
  • @plextv/react-lightning-plugin-flexbox — performance refactor of YogaManager, LightningManager, and the main-thread/worker pipeline. Adds a fast-path scan in transformProps so non-flex elements skip the split-and-allocate path entirely.

Tooling

  • Migrated from Biome to oxc (oxlint + oxfmt).
  • Adopted pnpm catalogs for cross-package version pinning.
  • Updated dependencies across the workspace.

Examples / Storybook

  • New apps/react-lightning-example page: NestedListPage (vertical VL of horizontal VLs with variable row heights, demonstrates focus restoration across recycle).
  • Added VirtualList.stories.tsx covering vertical/horizontal/grid/header-footer-separator/empty/padding/snap-alignment/override-layout/infinite-scroll/item-types/initial-scroll/imperative/draw-distance variants.
  • Removed the old FlashList.stories.tsx and react-native-lightning-components/CellContainer + FlashList (superseded by the new VL).

Breaking Changes

  1. FlashList and CellContainer removed from @plextv/react-native-lightning-components
- import { FlashList, CellContainer } from '@plextv/react-native-lightning-components';
+ import VirtualList from '@plextv/react-lightning-components/lists/VirtualList';

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, initialScrollIndex are 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.h set viewport explicitly. contentContainerStyle carries RN-style padding + backgroundColor.
  • See VirtualList.md next to the source for the authoritative model.
  1. @lightningjs/renderer left beta (3.0.0-beta20 → 3.0.1)

  2. @plextv/react-lightning-plugin-flexbox now exports FlexRoot, 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 a FlexRoot component. The exported NativeCanvas component in @plextv/react-native-lightning automatically wraps the application with a FlexRoot.

@WillsonHaw WillsonHaw self-assigned this May 4, 2026
@WillsonHaw WillsonHaw merged commit 38f1b60 into main May 4, 2026
1 check passed
@WillsonHaw WillsonHaw deleted the virtuallist branch May 4, 2026 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant