Conversation
The left/right handlers stepped from the `range` captured in the input handler's closure. Ink re-registers `useInput` handlers in a passive effect that runs after the frame is painted, so a press arriving in that window was dispatched with the previous render's value, recomputed the tab it had already moved to, and React bailed out - leaving the tabs stuck until another key broke the tie. Both directions now step from the value React holds, which also collapses the two near-identical branches into one. The spec pressed once per tick and polled the frame in between, which is exactly the window that hides this, so it only failed when the passive effect lost the race - intermittently on CI, consistently on Windows. It now sends two presses in one tick to pin the bug deterministically, and adds a left-arrow press so the shared step is covered in both directions.
nc-review: comments — 1 nit@addyCooks — a few things worth a look, none blocking. The fix replaces the ⚪ nit · The inline comment says the second rapid press 'lands on 3m again', but with two stale-closure presses from 🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with |
Description
Pressing
←/→quickly on/statscould silently drop a press and freeze the range tabs on one value until another key broke the tie.The left/right handlers stepped from the
rangecaptured in the input handler's closure. Ink re-registersuseInputhandlers in a passive effect that runs after the frame is painted, so a press arriving in that window was dispatched with the previous render's value, recomputed the tab it had already moved to, and React bailed out — leaving the tabs stuck. Both directions now step from the value React holds, which also collapses the two near-identical branches into one.Instrumented trace on the unfixed code:
This is also why
Unit Tests & Coverage Analysishas been failing on unrelated PRs (e.g. #1374): the spec pressed once per tick and polled the frame in between, which is exactly the window that hides the bug, so it only failed when the passive effect lost the race. It reproduces onmain, so it can wedge on any branch.Type of Change
Changeset
pnpm changeset) describing this change for the changelogTesting
Automated Tests
.spec.ts/tsxfiles — regression test, verified failing before the fix and passing afterpnpm test:allcompletes successfully) — with the caveat belowManual Testing
Checklist