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 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 14:22:50 -04:00
parent 6a8452d6c3
commit b035a88873
4 changed files with 24 additions and 9 deletions
+11 -4
View File
@@ -1,9 +1,9 @@
import { makeStyles, mergeClasses, tokens, shorthands } from '@fluentui/react-components'
import { makeStyles, mergeClasses, tokens, shorthands } from '@fluentui/react-components'
// A native <select> styled to match Fluent inputs. We use this instead of
// Fluent's <Dropdown> because Fluent's portal/popover menu is a composited
// overlay in the WebContents, and on this dev machine's GPU/driver that overlay
// paint blanks the whole window (same family as the documented flicker
// paint blanks the whole window (same family as the documented flicker --
// hardware acceleration is already disabled; see memory "aerofetch-gpu-flicker").
// The native <select> popup is drawn by the OS, so it can't trigger the blank.
// The popup's light/dark styling follows the `color-scheme` set on the app root
@@ -27,6 +27,11 @@ const useStyles = makeStyles({
outline: 'none',
...shorthands.borderColor(tokens.colorCompoundBrandStroke)
}
},
large: {
height: '40px',
padding: '0 12px',
fontSize: tokens.fontSizeBase400
}
})
@@ -41,6 +46,7 @@ interface SelectProps {
onChange: (value: string) => void
className?: string
'aria-label'?: string
size?: 'medium' | 'large'
}
export function Select({
@@ -48,12 +54,13 @@ export function Select({
options,
onChange,
className,
'aria-label': ariaLabel
'aria-label': ariaLabel,
size
}: SelectProps): React.JSX.Element {
const styles = useStyles()
return (
<select
className={mergeClasses(styles.select, className)}
className={mergeClasses(styles.select, size === 'large' && styles.large, className)}
value={value}
onChange={(e) => onChange(e.target.value)}
aria-label={ariaLabel}