a11y: Select disabled (UI31), native colorScheme (UI32), touch targets (W16), High Contrast (W18)
UI31 — the native <Select> wrapper now takes a `disabled` prop that passes to the <select> and applies disabled foreground/background/stroke tokens + not-allowed cursor, so it can show a disabled state like Fluent controls. UI32 — dropped the datetime-local's explicit colorScheme:'light dark' so it inherits the resolved in-app scheme from the app root; the native calendar popup now follows the app's Light/Dark theme, consistent with the native <Select>, instead of tracking the OS preference. W16 — the icon-only row-action clusters (QueueItem + HistoryView) enforce a >=40x40px hit target via a `& button` min-size rule (glyph unchanged, subtle button just gains padding). Labels were already non-hover-only: the shared Hint shows on :focus-within and every action has an aria-label. LibraryView item rows have no icon-only actions, so nothing there needed changing. W18 — defended the two color-meaning surfaces against forced-colors: accent swatches set forced-color-adjust:none (they're color previews; otherwise all flatten to one system color), and the SegmentedControl active segment paints with system Highlight/HighlightText under @media (forced-colors: active) so the checked state stays visible. Status chips (Fluent Badge) and thumbnail tints correctly let the system palette win. typecheck + 253 tests + eslint + prettier + production build all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,15 @@ const useStyles = makeStyles({
|
||||
height: '40px',
|
||||
padding: '0 12px',
|
||||
fontSize: tokens.fontSizeBase400
|
||||
},
|
||||
disabled: {
|
||||
cursor: 'not-allowed',
|
||||
color: tokens.colorNeutralForegroundDisabled,
|
||||
backgroundColor: tokens.colorNeutralBackgroundDisabled,
|
||||
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled),
|
||||
':hover': {
|
||||
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -47,6 +56,7 @@ interface SelectProps {
|
||||
className?: string
|
||||
'aria-label'?: string
|
||||
size?: 'medium' | 'large'
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export function Select({
|
||||
@@ -55,15 +65,22 @@ export function Select({
|
||||
onChange,
|
||||
className,
|
||||
'aria-label': ariaLabel,
|
||||
size
|
||||
size,
|
||||
disabled
|
||||
}: SelectProps): React.JSX.Element {
|
||||
const styles = useStyles()
|
||||
return (
|
||||
<select
|
||||
className={mergeClasses(styles.select, size === 'large' && styles.large, className)}
|
||||
className={mergeClasses(
|
||||
styles.select,
|
||||
size === 'large' && styles.large,
|
||||
disabled && styles.disabled,
|
||||
className
|
||||
)}
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
aria-label={ariaLabel}
|
||||
disabled={disabled}
|
||||
>
|
||||
{options.map((o) => (
|
||||
<option key={o.value} value={o.value}>
|
||||
|
||||
Reference in New Issue
Block a user