Skip to content

refactor(widgets): share one searchable list between the locale and timezone editors - #649

Merged
sirmalloc merged 4 commits into
sirmalloc:mainfrom
eric-engberg:refactor/locale-timezone-editor-duplication
Oct 6, 2026
Merged

sirmalloc merged 4 commits into
sirmalloc:mainfrom
eric-engberg:refactor/locale-timezone-editor-duplication

Conversation

@eric-engberg

Copy link
Copy Markdown
Contributor

#607 and #609 also touch these two editors (both move them behind a lazy loader); happy to rebase either way.

Demo

After the refactor: in the line editor, on a Block Reset Timer in timestamp mode, z opens the timezone list. Searching tokyo and picking Asia/Tokyo moves the preview's reset time to 17:30 GMT+9. l then opens the locale list, and picking ja-JP shows the zone as JST. Every case also renders byte-for-byte the same as before; see Testing.

Powerline

Picking a timezone and then a locale for the Block Reset Timer in Powerline mode

Plain

Picking a timezone and then a locale for the Block Reset Timer in plain mode

Summary

The Block Reset Timer and Weekly Reset Timer open a timezone editor with z and a locale editor with l in timestamp mode. The two editors were copies of one searchable list. They differed only in:

  • their options and how those are searched (the locale search also offers any valid locale you type);
  • which option is selected on open (a configured locale is matched in its canonical form);
  • the title, the default shown as Current (en-US, UTC) and the no-match message;
  • the setting the picked value is saved to.

SearchableOptionEditor (widgets/shared/searchable-option-editor.tsx) now holds the list: the header and search line, typing and Backspace, Up/Down that wraps and keeps the selection in a ten-row window, Enter to save and ESC to cancel. Each editor passes its options, search, starting value and labels, and saves the picked value to the widget.

3 source files, 221 lines added and 306 removed, plus a test file. No visual change; the editors also draw the same colors as before.

Testing

  • The existing editor tests cover searching, saving, the default clearing the setting, a typed custom locale and ESC. The first commit adds widgets/shared/__tests__/searchable-option-editor.test.tsx, which runs the list behavior on both editors:

    • the selection and Current label on open, with and without a configured value;
    • Up and Down wrapping at both ends, and the ten-row window scrolling with the selection;
    • typing and Backspace filtering the list and selecting the first match;
    • the no-match message, with Enter saving nothing;
    • another editor action showing only a notice.

    It passes at every commit under Bun and under Node, 15 or more runs in a row each. Breaking the wrap-around, the selection reset on Backspace, the window's centering or the canonical starting locale makes it fail.

  • bun run lint and bun test (2,370 pass).

  • Before/after render check: the Block Reset Timer and Weekly Reset Timer rendered on main and on this branch, in every state their own keys reach (42 and 80), raw and labeled, at all three color levels. All 854 preview cases are byte-identical, as are all 1,586 cases in each of two runs with live usage data (reset times in the past and in the future), and each state's editor label and keys. The timezone and locale themselves are only set through these editors, which the tests above cover.

  • Built dist/ and piped a status line with both timers in timestamp mode (one set to Europe/Paris and fr-FR), from a payload with rate limits, through it in plain and Powerline mode under Bun and Node 16, 18, 20, 22, 24 and 26: every runtime agrees, and the output matches main. The TUI opens and exits cleanly on each.

  • Under Node with Vitest, the full suite fails in the same 17 files as main (all from spying on Node built-ins), and the new tests pass.

eric-engberg and others added 4 commits October 4, 2026 16:12
… keys

Both reset timer date editors share the same list behavior: the current
value is selected on open, typing filters and selects the first match,
Up and Down wrap around and scroll a ten-row window, Backspace edits the
search, and Enter saves nothing when no option matches. Cover each of
these for both editors.
…imezone editors

The reset timers' locale and timezone editors were two copies of the
same searchable list: the search line, the Up/Down selection that wraps
and scrolls a ten-row window, Backspace, Enter to save and ESC to cancel.
They differed only in their options, how those are searched, the
selected value on open, and their labels.

SearchableOptionEditor (widgets/shared/searchable-option-editor.tsx) now
holds the list. Each editor passes its options, search, starting value
and labels, and saves the picked value to the widget. Behavior is
unchanged.
The selected row is all green and other rows highlight the letters that
match; a small helper says so more plainly than a nested conditional in
the JSX. Also mark the list's props read-only, since it never changes
them. Behavior is unchanged.
@sirmalloc
sirmalloc merged commit c17a906 into sirmalloc:main Oct 6, 2026
3 checks passed
@eric-engberg
eric-engberg deleted the refactor/locale-timezone-editor-duplication branch October 9, 2026 21:47
pcvelz added a commit to pcvelz/ccstatusline-usage that referenced this pull request Oct 11, 2026
Upstream: label prefixes editable with e (sirmalloc#601, sirmalloc#666), Session Cost Rate (sirmalloc#671) and Extra Usage Daily Budget (sirmalloc#672) widgets, own-lock-only usage lock clearing (sirmalloc#624), NO_PROXY and request deadlines, terminal control-sequence sanitizing, git hardening and linear-time parsing, shared searchable option editor (sirmalloc#649) and widget base classes (sirmalloc#646-sirmalloc#654), node: imports (sirmalloc#657), Number.* globals lint (sirmalloc#645), test waits on redraw instead of fixed delays (sirmalloc#652).

Hand edits outside conflicts:
- src/widgets/shared/searchable-option-editor.tsx: compat fix - ports the fork's ref-based input handling (Enter picks from what was just typed) into upstream's new shared editor
- src/utils/usage-fetch.ts: compat fix - fork's fetchFreshUsageData uses upstream's clearOwnUsageLock (sirmalloc#624) instead of the removed clearUsageLock
- src/widgets/ApiUsage.tsx, src/widgets/Battery.ts: compat fix - Number.isNaN/Number.parseInt for upstream's no-restricted-globals rule
- src/utils/__tests__/usage-prefetch.test.ts: compat fix - mock renamed to upstream's mockFetchUsage
- src/tui/components/__tests__/PowerlineSetup.test.ts, src/tui/components/__tests__/StatusLinePreview.test.ts, src/tui/components/__tests__/TerminalWidthMenu.test.ts: compat fix - drop the fork's flushInk import, unused after upstream's waitFor switch
- README.md: upstream notes linked docs/USAGE.md (deleted in the fork); inlined the proxy and workspace-trust text instead; upstream's own release-note entries not taken
- .fork-keep-deleted: src/widgets/FableWeeklyUsage.ts (upstream widget, unregistered in the fork, which ships WeeklyFableUsage.ts)
- src/widgets/WeeklyFableUsage.ts: compat fix - adopts upstream's shared getUsagePercentWidgetEditorDisplay, which carries the time-cursor modifier
- src/tui/__tests__/App.test.ts: fork deviation - one extra down-arrow for the fork's Off Hours main-menu row
- src/widgets/__tests__/CacheTimer.test.ts, src/widgets/CacheTimer.ts: compat fix - emoji toggle moved from e to o because upstream reserves e for edit-label
- src/widgets/AgentAddress.ts: split the session-title guard into its own if (same behaviour) so the .fork-invariants nameSource guard matches again
- docs/test-retirements.md: ledger for tests upstream renamed or replaced
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.

2 participants