feat(settings): results-only search, keyboard nav, flash animation, Ctrl+F (#264)

Follow-up on #263. Refines the cross-tab search into a proper
command-palette-ish flow and polishes the UX around it.

Results-only mode:
- When a query is active, the tab content is hidden entirely; the
  results list is the only thing shown. Unified list (was: in-place
  current-tab filter + "In other tabs" panel underneath), sorted with
  current-tab matches first and then by score.
- Removed the DOM-based hide/show logic and its CSS helper class, the
  dead searchOtherTabs i18n key, and the searchHits/otherTabHits state.

Keyboard navigation inside the search field:
- ↓/↑ moves selection through the result list (clamped, no wrap).
- Enter activates the selected item (same flow as a click — clears
  query, switches tab, scrolls + opens + flashes the target).
- Mouse hover syncs with the keyboard selection so the two input modes
  don't fight each other.
- Selected item gets accent-border + tinted background; scrollIntoView
  with block:'nearest' keeps it visible when the list is long.

Ctrl/Cmd+F (Settings page only):
- Window keydown listener registered on mount, removed on unmount →
  the shortcut is live only while Settings is rendered.
- Opens the search input, focuses + selects it even if already open.
- preventDefault blocks the native WebKit find bar.
- Placeholder now hints at the shortcut: "… (Ctrl+F)" / "… (⌘F)" on
  macOS, no new i18n keys needed.

Target flash animation:
- After navigating from a result, the target SettingsSubSection gets a
  1.4s accent-colored border + glow pulse so the user immediately sees
  which entry the result pointed at. Reflow trick lets it retrigger
  when clicking the same result twice.

Misc:
- "Next Track Buffering" → "Buffering" in all 8 locales + the section
  comment in Settings.tsx. The SETTINGS_INDEX keeps "next track" as a
  keyword so old search habits still find it.

Co-authored-by: Psychotoxical <dev@psysonic.app>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Frank Stellmacher
2026-04-22 15:12:48 +02:00
committed by GitHub
parent ae7b94f190
commit f0e5b2542b
10 changed files with 139 additions and 105 deletions
+21 -24
View File
@@ -2460,6 +2460,15 @@
overflow: hidden;
}
@keyframes settings-sub-section-flash {
0% { border-color: var(--border-subtle); box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); }
20% { border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 35%, transparent); }
100% { border-color: var(--border-subtle); box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); }
}
.settings-sub-section--flash {
animation: settings-sub-section-flash 1.4s ease-out;
}
.settings-sub-section-summary {
display: flex;
align-items: center;
@@ -2591,10 +2600,6 @@
color: var(--text-primary);
}
.settings-sub-section--hidden {
display: none;
}
.settings-search-empty {
padding: var(--space-3) var(--space-4);
font-size: 13px;
@@ -2605,31 +2610,18 @@
text-align: center;
}
.settings-search-other-tabs {
margin-top: var(--space-4);
margin-bottom: var(--space-6);
.settings-search-results {
list-style: none;
margin: var(--space-4) 0 var(--space-6);
padding: var(--space-3);
border-radius: var(--radius-md);
background: var(--bg-card);
border: 1px solid var(--border-subtle);
}
.settings-search-other-tabs-title {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--text-muted);
margin-bottom: var(--space-2);
}
.settings-search-other-tabs-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.settings-search-other-tab-item {
.settings-search-result-item {
width: 100%;
display: flex;
align-items: center;
@@ -2644,11 +2636,16 @@
font-size: 13px;
transition: background 0.12s, border-color 0.12s;
}
.settings-search-other-tab-item:hover {
.settings-search-result-item:hover,
.settings-search-result-item[data-selected="true"] {
background: var(--bg-hover);
border-color: var(--border);
}
.settings-search-other-tab-badge {
.settings-search-result-item[data-selected="true"] {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 8%, var(--bg-hover));
}
.settings-search-result-badge {
flex-shrink: 0;
font-size: 11px;
font-weight: 500;
@@ -2657,7 +2654,7 @@
background: color-mix(in srgb, var(--accent) 15%, transparent);
color: var(--accent);
}
.settings-search-other-tab-title {
.settings-search-result-title {
flex: 1;
min-width: 0;
overflow: hidden;