ComponentsOverlay
Fullscreen Overlay
A full-viewport overlay for expanding content to fill the screen. Built on Radix Dialog with keyboard dismiss, focus trap, and body scroll lock.
Basic Example
Fullbleed Mode
The fullbleed prop removes all inner padding, letting content fill the entire viewport edge-to-edge. Ideal for full-screen images, maps, or video players.
Controlled State
Use open and onOpenChange to control the overlay programmatically.
import { useState } from 'react';
import {
FullscreenOverlay,
FullscreenOverlayTrigger,
FullscreenOverlayContent,
} from '@/components/ui/fullscreen-overlay/fullscreen-overlay';
import { Button } from '@/components/ui/button/button';
export default function ControlledExample() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Open Overlay</Button>
<FullscreenOverlay open={open} onOpenChange={setOpen}>
<FullscreenOverlayContent>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
<Button onClick={() => setOpen(false)}>Close</Button>
</div>
</FullscreenOverlayContent>
</FullscreenOverlay>
</>
);
}Features
- Full viewport: Content fills the entire screen
- Keyboard dismiss: Escape key closes the overlay
- Focus trap: Built on Radix Dialog for automatic focus management
- Body scroll lock: Prevents background scrolling while open
- Fullbleed mode: Remove padding for edge-to-edge content
- Theme-agnostic: Uses CSS custom properties for all visual tokens
Installation
npx visor add fullscreen-overlayThis copies two files into your project:
components/ui/fullscreen-overlay/fullscreen-overlay.tsx— the componentcomponents/ui/fullscreen-overlay/fullscreen-overlay.module.css— the styles
Usage
import {
FullscreenOverlay,
FullscreenOverlayTrigger,
FullscreenOverlayContent,
} from '@/components/ui/fullscreen-overlay/fullscreen-overlay';
export default function Example() {
return (
<FullscreenOverlay>
<FullscreenOverlayTrigger asChild>
<Button>Expand</Button>
</FullscreenOverlayTrigger>
<FullscreenOverlayContent>
<p>Your content fills the full viewport here.</p>
</FullscreenOverlayContent>
</FullscreenOverlay>
);
}API Reference
FullscreenOverlayProps
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state of the overlay. |
onOpenChange | (open: boolean) => void | — | Callback when the open state changes. |
fullbleed | boolean | false | Removes all inner padding on FullscreenOverlayContent, allowing content to fill the entire viewport edge-to-edge. |
children | React.ReactNode | — | Content to render inside FullscreenOverlayContent. |
className | string | — | Additional CSS class names to merge onto FullscreenOverlayContent. |
asChild | boolean | false | On FullscreenOverlayTrigger — merges props onto the immediate child element instead of rendering a <button>. |
Sub-components
| Component | Element | Purpose |
|---|---|---|
FullscreenOverlay | Root | Context provider wrapping Radix Dialog.Root |
FullscreenOverlayTrigger | <button> | Opens the overlay; use asChild to wrap a custom trigger |
FullscreenOverlayContent | Dialog | Full-viewport container. Renders close button, title, and description automatically |
Accessibility
- Built on Radix UI Dialog —
role="dialog",aria-modal="true", and visually hidden title/description are provided automatically. - Focus is trapped inside the overlay when open and restored to the trigger element on close.
- Pressing
Escapecloses the overlay. - The close (×) button has a visually hidden "Close" label for screen readers.
- Use
aria-labelledbyoraria-describedbyonFullscreenOverlayContentif you render a visible heading inside.