fix(ui): suppress native focus outline on dialog, alert dialog and sheet panels

Radix focuses the content element (tabindex="-1") when a dialog opens, and the panel had no
outline suppression, so Chrome drew its default blue focus-visible ring around the whole panel.
Adds focus:outline-none to the dialog, alert dialog and sheet content base classes. Interactive
children keep their themed focus rings.
This commit is contained in:
ephraimduncan
2026-07-07 13:38:09 +00:00
parent 96539cda09
commit 8521e84bcd
3 changed files with 86 additions and 83 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ const AlertDialogContent = React.forwardRef<
<AlertDialogPrimitive.Content
ref={ref}
className={cn(
'fade-in-90 slide-in-from-bottom-10 sm:zoom-in-90 sm:slide-in-from-bottom-0 fixed z-50 grid w-full max-w-lg scale-100 animate-in gap-4 border bg-background p-6 opacity-100 shadow-lg sm:rounded-lg md:w-full',
'fade-in-90 slide-in-from-bottom-10 sm:zoom-in-90 sm:slide-in-from-bottom-0 fixed z-50 grid w-full max-w-lg scale-100 animate-in gap-4 border bg-background p-6 opacity-100 shadow-lg focus:outline-none sm:rounded-lg md:w-full',
className,
)}
{...props}
+1 -1
View File
@@ -61,7 +61,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
'data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0 fixed z-50 grid w-full animate-in gap-4 border bg-background p-6 shadow-lg sm:max-w-lg sm:rounded-lg',
'data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0 fixed z-50 grid w-full animate-in gap-4 border bg-background p-6 shadow-lg focus:outline-none sm:max-w-lg sm:rounded-lg',
{
'rounded-b-xl': position === 'start',
'rounded-t-xl': position === 'end',
+84 -81
View File
@@ -49,90 +49,93 @@ const SheetOverlay = React.forwardRef<
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva('fixed z-[61] scale-100 gap-4 bg-background p-6 opacity-100 shadow-lg border', {
variants: {
position: {
top: 'animate-in slide-in-from-top w-full duration-300',
bottom: 'animate-in slide-in-from-bottom w-full duration-300',
left: 'animate-in slide-in-from-left h-full duration-300',
right: 'animate-in slide-in-from-right h-full duration-300',
const sheetVariants = cva(
'fixed z-[61] scale-100 gap-4 border bg-background p-6 opacity-100 shadow-lg focus:outline-none',
{
variants: {
position: {
top: 'animate-in slide-in-from-top w-full duration-300',
bottom: 'animate-in slide-in-from-bottom w-full duration-300',
left: 'animate-in slide-in-from-left h-full duration-300',
right: 'animate-in slide-in-from-right h-full duration-300',
},
size: {
content: '',
default: '',
sm: '',
lg: '',
xl: '',
full: '',
},
},
size: {
content: '',
default: '',
sm: '',
lg: '',
xl: '',
full: '',
compoundVariants: [
{
position: ['top', 'bottom'],
size: 'content',
class: 'max-h-screen',
},
{
position: ['top', 'bottom'],
size: 'default',
class: 'h-1/3',
},
{
position: ['top', 'bottom'],
size: 'sm',
class: 'h-1/4',
},
{
position: ['top', 'bottom'],
size: 'lg',
class: 'h-1/2',
},
{
position: ['top', 'bottom'],
size: 'xl',
class: 'h-5/6',
},
{
position: ['top', 'bottom'],
size: 'full',
class: 'h-screen',
},
{
position: ['right', 'left'],
size: 'content',
class: 'max-w-screen',
},
{
position: ['right', 'left'],
size: 'default',
class: 'w-1/3',
},
{
position: ['right', 'left'],
size: 'sm',
class: 'w-1/4',
},
{
position: ['right', 'left'],
size: 'lg',
class: 'w-1/2',
},
{
position: ['right', 'left'],
size: 'xl',
class: 'w-5/6',
},
{
position: ['right', 'left'],
size: 'full',
class: 'w-screen',
},
],
defaultVariants: {
position: 'right',
size: 'default',
},
},
compoundVariants: [
{
position: ['top', 'bottom'],
size: 'content',
class: 'max-h-screen',
},
{
position: ['top', 'bottom'],
size: 'default',
class: 'h-1/3',
},
{
position: ['top', 'bottom'],
size: 'sm',
class: 'h-1/4',
},
{
position: ['top', 'bottom'],
size: 'lg',
class: 'h-1/2',
},
{
position: ['top', 'bottom'],
size: 'xl',
class: 'h-5/6',
},
{
position: ['top', 'bottom'],
size: 'full',
class: 'h-screen',
},
{
position: ['right', 'left'],
size: 'content',
class: 'max-w-screen',
},
{
position: ['right', 'left'],
size: 'default',
class: 'w-1/3',
},
{
position: ['right', 'left'],
size: 'sm',
class: 'w-1/4',
},
{
position: ['right', 'left'],
size: 'lg',
class: 'w-1/2',
},
{
position: ['right', 'left'],
size: 'xl',
class: 'w-5/6',
},
{
position: ['right', 'left'],
size: 'full',
class: 'w-screen',
},
],
defaultVariants: {
position: 'right',
size: 'default',
},
});
);
export interface DialogContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,