Describe the bug
The v4 component registry (apps/v4/registry/new-york-v4/ui/) has an incomplete migration from outline-none to outline-hidden.
In Tailwind CSS v4, outline-none and outline-hidden both produce outline-style: none in standard rendering. However, outline-hidden additionally preserves a visible outline in forced-colors mode (@media (forced-colors: active)) for accessibility. The Tailwind v4 upgrade tool explicitly maps outline-none to outline-hidden for this reason (see packages/@tailwindcss-upgrade/src/codemods/template/migrate-simple-legacy-classes.ts).
14 components in the v4 registry correctly use outline-hidden, but 19 still use outline-none. The inconsistency is most visible in menubar.tsx, where lines 59, 106, 124, and 149 correctly use outline-hidden but line 232 (SubTrigger) still uses outline-none with the identical pattern. Similarly, select.tsx uses outline-hidden on SelectItem but outline-none on the trigger.
Impact: Users relying on Windows High Contrast Mode / forced-colors mode will not see focus outlines on the affected components, while components that already use outline-hidden will show them correctly.
Components using outline-none (should be outline-hidden):
All follow the outline-none focus-visible:ring-* pattern where the intent is to suppress the browser default and show a custom focus ring:
accordion, button, checkbox, combobox (input), dialog (content panel), input, input-group, input-otp, item, menubar (SubTrigger only), native-select, navigation-menu, radio-group, scroll-area, select (trigger), switch, tabs (content), textarea, toggle
Components already correctly using outline-hidden:
chart, combobox (item), command, context-menu, dialog (close button), dropdown-menu, hover-card, menubar (Trigger, Item, CheckboxItem, RadioItem), popover, resizable, select (item), sheet, sidebar, slider
Affected component/components
Accordion, Button, Checkbox, Combobox, Dialog, Input, Input Group, Input OTP, Item, Menubar, Native Select, Navigation Menu, Radio Group, Scroll Area, Select, Switch, Tabs, Textarea, Toggle
How to reproduce
- Create a new project with Tailwind CSS v4
- Run
npx shadcn@latest add button switch menubar
- Inspect
menubar.tsx -- lines 59/106/124/149 use outline-hidden, line 232 uses outline-none
- Enable Windows High Contrast Mode (or use Chrome DevTools "Emulate CSS media feature forced-colors: active")
- Focus a MenubarTrigger (line 59,
outline-hidden) -- outline is visible
- Focus a MenubarSubTrigger (line 232,
outline-none) -- outline is not visible
Verification against the registry:
grep -c 'outline-none' apps/v4/registry/new-york-v4/ui/*.tsx
grep -c 'outline-hidden' apps/v4/registry/new-york-v4/ui/*.tsx
The Tailwind v4 upgrade codemod confirms outline-hidden is the intended replacement:
// From packages/@tailwindcss-upgrade/src/codemods/template/migrate-simple-legacy-classes.ts
if (version.isMajor(3)) {
LEGACY_CLASS_MAP['outline-none'] = 'outline-hidden'
}
Codesandbox/StackBlitz link
No response
Logs
No response
System Info
shadcn@3.5.0
tailwindcss@4.2.1
Before submitting
Describe the bug
The v4 component registry (
apps/v4/registry/new-york-v4/ui/) has an incomplete migration fromoutline-nonetooutline-hidden.In Tailwind CSS v4,
outline-noneandoutline-hiddenboth produceoutline-style: nonein standard rendering. However,outline-hiddenadditionally preserves a visible outline in forced-colors mode (@media (forced-colors: active)) for accessibility. The Tailwind v4 upgrade tool explicitly mapsoutline-nonetooutline-hiddenfor this reason (seepackages/@tailwindcss-upgrade/src/codemods/template/migrate-simple-legacy-classes.ts).14 components in the v4 registry correctly use
outline-hidden, but 19 still useoutline-none. The inconsistency is most visible inmenubar.tsx, where lines 59, 106, 124, and 149 correctly useoutline-hiddenbut line 232 (SubTrigger) still usesoutline-nonewith the identical pattern. Similarly,select.tsxusesoutline-hiddenon SelectItem butoutline-noneon the trigger.Impact: Users relying on Windows High Contrast Mode / forced-colors mode will not see focus outlines on the affected components, while components that already use
outline-hiddenwill show them correctly.Components using
outline-none(should beoutline-hidden):All follow the
outline-none focus-visible:ring-*pattern where the intent is to suppress the browser default and show a custom focus ring:accordion, button, checkbox, combobox (input), dialog (content panel), input, input-group, input-otp, item, menubar (SubTrigger only), native-select, navigation-menu, radio-group, scroll-area, select (trigger), switch, tabs (content), textarea, toggle
Components already correctly using
outline-hidden:chart, combobox (item), command, context-menu, dialog (close button), dropdown-menu, hover-card, menubar (Trigger, Item, CheckboxItem, RadioItem), popover, resizable, select (item), sheet, sidebar, slider
Affected component/components
Accordion, Button, Checkbox, Combobox, Dialog, Input, Input Group, Input OTP, Item, Menubar, Native Select, Navigation Menu, Radio Group, Scroll Area, Select, Switch, Tabs, Textarea, Toggle
How to reproduce
npx shadcn@latest add button switch menubarmenubar.tsx-- lines 59/106/124/149 useoutline-hidden, line 232 usesoutline-noneoutline-hidden) -- outline is visibleoutline-none) -- outline is not visibleVerification against the registry:
The Tailwind v4 upgrade codemod confirms
outline-hiddenis the intended replacement:Codesandbox/StackBlitz link
No response
Logs
No response
System Info
Before submitting