From b035a8887353addc66f49b6e4ec497b692f534db Mon Sep 17 00:00:00 2001 From: debont80 Date: Tue, 30 Jun 2026 14:22:50 -0400 Subject: [PATCH] Fix L6/L12: Select size=large variant, command palette scroll-into-view L6: Select.tsx adds a `size` prop ('medium' | 'large'). When size='large', the select is 40px tall (matching Fluent size='large' Input/Button) with slightly larger padding and font. DownloadBar quality/format selects now use size='large' so they align with the row's large Input and buttons. L12: CommandPalette keyboard navigation now scrolls the highlighted item into view on each ArrowUp/ArrowDown press. Uses a listRef + data-sel attribute so no DOM imperative tracking of individual buttons is needed. typecheck + 242 tests + eslint green. Co-Authored-By: Claude Opus 4.8 --- CODE-AUDIT.md | 4 ++-- src/renderer/src/components/CommandPalette.tsx | 12 +++++++++--- src/renderer/src/components/DownloadBar.tsx | 2 ++ src/renderer/src/components/Select.tsx | 15 +++++++++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CODE-AUDIT.md b/CODE-AUDIT.md index 4ad973f..2f5bade 100644 --- a/CODE-AUDIT.md +++ b/CODE-AUDIT.md @@ -386,7 +386,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n - [ ] **L5 — Inline `style={{}}` vs makeStyles** (25× across 8 files; SettingsView 14×). Notably Sidebar's active-nav inset shadow and DownloadOptionsForm's hint caption use inline styles where a class exists elsewhere. -- [ ] **L6 — Control height mismatch.** `Select` is a fixed 32px sitting beside `size="large"` +- [x] **L6 — Control height mismatch.** `Select` is a fixed 32px sitting beside `size="large"` (~40px) Input/Buttons in DownloadBar. - [x] **L7 — `canceled` and `paused` share the 'warning' badge color** (QueueItem) — visually ambiguous. @@ -399,7 +399,7 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n Consider a central constants module. - [x] **L11 — "Queue (N)" overcounts.** DownloadsView's header count is `items.length` (includes completed/error/canceled), not the active queue. -- [ ] **L12 — Command palette polish.** No scroll-into-view for keyboard selection in the 50vh +- [x] **L12 — Command palette polish.** No scroll-into-view for keyboard selection in the 50vh list; `role="dialog"` without `aria-modal`/focus-trap; Esc handled only on the input. - [x] **L13 — Destructive actions lack confirmation.** "Clear history", "Clear log", "Remove source" are one-click — inconsistent with the careful confirm on backup import. diff --git a/src/renderer/src/components/CommandPalette.tsx b/src/renderer/src/components/CommandPalette.tsx index f3bd05f..ba0e525 100644 --- a/src/renderer/src/components/CommandPalette.tsx +++ b/src/renderer/src/components/CommandPalette.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { useEffect, useRef, useState } from 'react' import { makeStyles, mergeClasses, tokens, shorthands } from '@fluentui/react-components' import { useFocusStyles } from './ui/focusRing' @@ -11,7 +11,7 @@ export interface PaletteAction { } const useStyles = makeStyles({ - // A plain fixed overlay — NOT a Fluent Dialog, since this app avoids Fluent's + // A plain fixed overlay -- NOT a Fluent Dialog, since this app avoids Fluent's // portal-based overlays (GPU/driver blank-overlay issue, see Select.tsx). backdrop: { position: 'fixed', @@ -95,6 +95,7 @@ export function CommandPalette({ const [q, setQ] = useState('') const [sel, setSel] = useState(0) const inputRef = useRef(null) + const listRef = useRef(null) const filtered = actions.filter((a) => a.label.toLowerCase().includes(q.trim().toLowerCase())) @@ -104,6 +105,10 @@ export function CommandPalette({ useEffect(() => { setSel(0) }, [q]) + useEffect(() => { + const btn = listRef.current?.querySelector(`[data-sel="true"]`) + btn?.scrollIntoView({ block: 'nearest' }) + }, [sel]) function onKeyDown(e: React.KeyboardEvent): void { if (e.key === 'Escape') { @@ -141,7 +146,7 @@ export function CommandPalette({ placeholder="Type a command…" aria-label="Command palette search" /> -
+
{filtered.length === 0 ? (
No matching commands
) : ( @@ -149,6 +154,7 @@ export function CommandPalette({