Skip to content

[CLOV-1600][BpkScrollableCalendar] Bump react-window to v2#4477

Closed
kerrie-wu wants to merge 4 commits into
mainfrom
kerriewu/clov-1600-react-window-v2
Closed

[CLOV-1600][BpkScrollableCalendar] Bump react-window to v2#4477
kerrie-wu wants to merge 4 commits into
mainfrom
kerriewu/clov-1600-react-window-v2

Conversation

@kerrie-wu

@kerrie-wu kerrie-wu commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

CLOV-1600. Migrates the only react-window consumer (BpkScrollableCalendarGridList) from v1 to v2.

v2 is an upstream rewrite, not a rename:

  • List replaces VariableSizeList; render-prop becomes rowComponent + rowProps
  • Auto-sizing is built-in — no more react-virtualized-auto-sizer
  • resetAfterIndex is gone — v2 auto-reacts to rowProps changes
  • initialScrollOffset is gone — replaced by imperative listRef.scrollToRow(...)
  • TypeScript types ship with the package — @types/react-window no longer needed

Changes

  • react-window ^1.8.7^2.0.0 (lockfile resolves to 2.2.7)
  • Removed react-virtualized-auto-sizer (only consumer was this file)
  • Removed @types/react-window (v2 has built-in types; upstream README explicitly drops it)
  • Rewrote BpkScrollableCalendarGridList.tsx:
    • List + useListRef + module-level Row component + rowHeight function
    • useEffect + listRef.current?.scrollToRow({ index, align: 'start', behavior: 'instant' }) replaces initialScrollOffset
    • Removed resetAfterIndex effect (v2 auto-detects rowProps changes)
    • Removed AutoSizer wrapper
    • Preserved sentinel <div> + ResizeObserver for browser font scaling — independent of react-window
    • Preserved RTL handling via dir-driven style={{ direction: 'rtl' }}

utils.ts (getMonthsArray, getMonthItemHeights) unchanged — outputs are still pixel heights consumed by the new rowHeight function.

Migration mapping

v1 v2
VariableSizeList List
itemCount rowCount
itemSize={fn} rowHeight={fn}
<List>{rowRenderer}</List> <List rowComponent={Row} rowProps={...} />
ref.current.resetAfterIndex(0) (removed — auto-detected)
initialScrollOffset listRef.current?.scrollToRow({ index, align, behavior })
<AutoSizer> wrapper (removed — built-in)

Test plan

  • npm run lint passes
  • npm run typecheck passes (verified locally — exit 0)
  • npm run jest packages/bpk-component-scrollable-calendar — snapshots regenerated via jest -u, diff reviewed (DOM structure differs because AutoSizer wrapper is removed and v2 emits different inner markup)
  • Storybook manual checks (per ticket validation notes):
    • Initial scroll position — opens scrolled to selected/focused month, not top
    • Variable row heights — months with 4 / 5 / 6 rendered week rows all measure correctly
    • Scrolling smoothness — overscanCount still in effect, no jank
    • RTL — <html dir="rtl"> renders right-to-left
    • Browser font scaling — sentinel + ResizeObserver still drive item heights under zoom and OS-level font-size changes
    • Resize — container resize updates width/height correctly without AutoSizer
    • Date selection — onDateClick, selectionConfiguration, focusedDate, aria-hidden propagation unchanged
    • SSR fallback — defaultHeight={estimatedMonthItemHeight} covers the initial render path

Notes

  • Initial scroll behaviour: v2 has no declarative initial offset. Using useEffect + imperative scrollToRow may produce a brief frame at the top before scrolling. To be confirmed visually in Storybook; if unacceptable, can defer mounting List until the sentinel ResizeObserver first fires.
  • Dependabot PR Bump @types/react-window from 1.8.8 to 2.0.0 #3997: kept open. This PR does not close it; will close once this lands.

🤖 Generated with Claude Code

react-window v2 is a major rewrite: List replaces VariableSizeList,
render-prop becomes rowComponent + rowProps, auto-sizing is built-in
(no more AutoSizer), resetAfterIndex is gone (rowProps changes are
auto-detected), initialScrollOffset is replaced by listRef.scrollToRow,
and TS types ship with the package.

- Bump react-window ^1.8.7 -> ^2.0.0
- Drop react-virtualized-auto-sizer (v2 has built-in sizing)
- Drop @types/react-window (v2 ships its own types)
- Rewrite BpkScrollableCalendarGridList for v2 API
- Preserve sentinelRef + ResizeObserver font-scaling logic

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kerrie-wu kerrie-wu added the major Breaking change label May 13, 2026
Skyscanner Artifactory's X-Ray policy returns 403 for react-window@2.2.7
(and its transitive color@5/color-convert@3/color-name@2/color-string@2
deps that we don't already cache). Local install resolved through
artifactory because of user-level npm config; the project .npmrc points
to the public registry.

Rewrite the resolved URLs in packages/package-lock.json from
artifactory.skyscannertools.net to registry.npmjs.org for these 5 deps.
Integrity hashes are unchanged (verified the public tarball produces
the same sha512), and @skyscanner/* scoped packages keep their
artifactory URLs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@skyscanner-backpack-bot

Copy link
Copy Markdown
Contributor

Visit https://backpack.github.io/storybook-prs/4477 to see this build running in a browser.

kerrie-wu and others added 2 commits May 13, 2026 14:31
react-window v2's List uses ResizeObserver internally for auto-sizing,
which jsdom does not provide. Three test files (BpkScrollableCalendar,
BpkScrollableCalendarGridList, accessibility) need the mock; reusing
the per-file pattern already used elsewhere in the repo
(bpk-component-chatbot-input, bpk-component-price-range, bpk-component-slider).

v2 also defaults the outer element to role="list", but our rows render
calendar grids (role="grid") and headings, not listitems — axe flagged
this as aria-required-children. Pass role="presentation" to opt out of
the implicit list semantics.

Snapshots still need regenerating (v2 emits different DOM); that is left
for the next jest -u pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
react-window v2 emits a different DOM tree than v1's AutoSizer + List
combination. In jsdom the new defaultHeight path also renders more
month rows than the v1 0x0 AutoSizer fallback did, so the snapshots
grow even though the rendered output is correct.

Verified manually:
- role="presentation" appears on the v2 List outer div (our override)
- rows are tagged with data-react-window-index
- bpk-scrollable-calendar-grid contents are unchanged

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@skyscanner-backpack-bot

Copy link
Copy Markdown
Contributor

Visit https://backpack.github.io/storybook-prs/4477 to see this build running in a browser.

@skyscanner-backpack-bot

Copy link
Copy Markdown
Contributor

Browser support

If this is a visual change, make sure you've tested it in multiple browsers.

Generated by 🚫 dangerJS against ffa36ca

@xiaogliu

Copy link
Copy Markdown
Contributor

Closing this older draft in favour of #4668, which reapplies the CLOV-1600 react-window v2 migration onto the current main repository structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

major Breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants