6037a9e1db
Root cause (confirmed via Chrome DevTools on the live app): the reading-position
restore jittered on reload — it landed at the saved spot, jumped to the top, then
back. The jump was NOT a height collapse: the title editor auto-focuses ~300ms
after mount, and TipTap's focus scrolls the focused node into view. Since the
title sits at the top of the page, that yanked window scroll to the top, between
two restore passes.
- title-editor: focus with { scrollIntoView: false }, and skip the title
auto-focus entirely when a saved reading position will be restored (else the
caret lands in the off-screen title). hasSavedReadingPosition() is the single
source of truth for "a position will be restored".
- use-scroll-position: restore once the document height has been STABLE for
HEIGHT_STABLE_MS and the target is reachable, else clamp only at the timeout —
so the saved offset lands on the same content instead of drifting via
scroll-anchoring while images/embeds still stream in. Replaces the reachable-
or-timeout poll (removed restoreStartRef).
- useScrollRestoreOnSwap keeps both triggers: an early on-mount one (covers the
offline / collab-never-syncs path — the static cache stays shown) plus a
post-swap re-assert for the final live layout; restore is idempotent so the two
never double-scroll.
- Abort restore on genuine scroll intent (wheel/touch/scroll-keys); #hash wins.
- Tests updated for the stable-height logic, hasSavedReadingPosition, and the
two-trigger wiring (incl. the offline path).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Babel for Fast Refresh
- @vitejs/plugin-react-swc uses SWC for Fast Refresh
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
- Configure the top-level
parserOptionsproperty like this:
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
- Replace
plugin:@typescript-eslint/recommendedtoplugin:@typescript-eslint/recommended-type-checkedorplugin:@typescript-eslint/strict-type-checked - Optionally add
plugin:@typescript-eslint/stylistic-type-checked - Install eslint-plugin-react and add
plugin:react/recommended&plugin:react/jsx-runtimeto theextendslist