Skip to content

chore(deps): react 19, react-window 2, globals 17 - #78

Merged
alex-clickhouse merged 1 commit into
mainfrom
chore/deps-react19-react-window2
Aug 28, 2026
Merged

alex-clickhouse merged 1 commit into
mainfrom
chore/deps-react19-react-window2

Conversation

@alex-clickhouse

Copy link
Copy Markdown
Collaborator

Combines four dependabot bumps into one PR, because three of them cannot pass CI on their own. Replaces #64, #62, #61 and #59.

Package From To
react, @types/react 18 19
react-dom, @types/react-dom 18 19
react-window 1.8 2.3
globals 15 17
@types/react-window 1.8 removed

Why they had to be combined

#64 and #62 (React 19) each failed at npm ci with ERESOLVE. Dependabot split the upgrade in two, but @types/react and @types/react-dom peer-require the same major version, so bumping one half leaves the other unsatisfiable. Neither PR was fixable alone.

#61 (react-window 2) got past install and failed the build. Version 2 is a rewrite that removed FixedSizeList, so a version bump alone cannot work.

Required code changes

react-window 2 API migration in src/components/HexViewer/HexViewer.tsx, the only place the library is used:

v1 v2
FixedSizeList List
children={HexRow} rowComponent={HexRow}
itemCount / itemSize rowCount / rowHeight
itemData rowProps (spread onto the row)
height / width removed, the list sizes to its container
ref: FixedSizeList listRef via useListRef
scrollToItem(i, 'center') scrollToRow({ index: i, align: 'center' })

HexRow now takes RowComponentProps<HexRowData> and reads bytes/highlightMap/onByteClick as direct props instead of a data object.

Because v2 sizes itself to its parent, .hex-viewer becomes a flex column that owns the height and no longer scrolls itself. This drops the height={window.innerHeight - 150} approximation, so the hex view now tracks panel resizes exactly.

@types/react-window@2 is a deprecated stub, so the devDependency is dropped instead of bumped.

React 19 types no longer accept a zero-argument useRef<T>(). saveTimerRef in src/components/QueryInput.tsx passes an explicit undefined.

Verification

All green locally:

  • npm run build (eslint + tsc + vite): clean, no warnings
  • ELECTRON=true npx vite build: passes
  • npm test: 1040 tests in 10 files pass
  • npx playwright test: 3 Electron e2e tests pass

The e2e suite does not load data into the hex viewer, so the migration was checked with a throwaway Playwright spec that uploads fixtures/protocol/06-logs.chproto into the Electron app:

  • 32 hex rows render
  • the list fills its panel exactly (621.8px of 621.8px) with a single scroll container, confirming the flex change
  • double-clicking a deep AST node scrolls the hex view (scrollTop 0 to 6022), confirming scrollToRow
  • byte highlighting still lines up: the highlighted 05 at 0x12D2 matches the selected packet_type: 5 (EndOfStream) node at [4819:4820]

react-resizable-panels and zustand already declared react ^19 in their peer ranges, so nothing else needed changing.

🤖 Generated with Claude Code

Combines four dependabot bumps that cannot land separately:

- react + @types/react 18 -> 19
- react-dom + @types/react-dom 18 -> 19
- react-window 1 -> 2
- globals 15 -> 17

The two React bumps fail `npm ci` in isolation because @types/react
and @types/react-dom peer-require matching major versions.

react-window 2 replaces FixedSizeList with List. HexViewer moves to
the new props (rowComponent, rowCount, rowHeight, rowProps, listRef)
and scrollToRow. List sizes itself to its container, so .hex-viewer
becomes a flex column and the window.innerHeight estimate is gone.
@types/react-window is dropped because react-window 2 ships types.

React 19 types require an argument to useRef.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@alex-clickhouse
alex-clickhouse merged commit fc78e1b into main Aug 28, 2026
1 check passed
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