Fullscreen Takeover Modal
A free fullscreen modal overlay built on the native dialog element, with a clip-path takeover reveal and staged content entrance.
- Automated axe check
- Reduced-motion tested
- SSR build verified
- Motion
- 2 runtime packages
Fullscreen Takeover Modal is a free fullscreen modal for React and Next.js, built with Motion and Tailwind on top of the native dialog element. Clicking the trigger button opens the dialog with showModal, so the browser owns the focus trap, top layer rendering and Escape handling, and the panel takes over the whole viewport with a clip-path inset reveal that grows from a small centred rectangle to full screen. Once the expand settles, the heading and body fade and rise into place with a short stagger.
The component renders its own trigger and manages its open state internally, locks background scroll while open, and stages its close so the animation is never cut short: Escape, the close button and a native close all play the reverse clip-path collapse first, and only when that finishes does the dialog close and focus return to the trigger. The dialog is made inert the instant it starts collapsing, so the exit animation never traps focus. The visible title labels the dialog for screen readers through aria-labelledby, the close button is a real button with an accessible name, and with prefers-reduced-motion enabled the clip-path and stagger are dropped for a plain opacity fade of 150 milliseconds or less with the layout final immediately.
Give the moment the whole screen
Some steps deserve more than a card in the corner. Open the takeover to see the clip-path reveal and the staged content entrance.
Install
Add the @te registry to your components.json once:
{
"registries": {
"@te": "https://templateempire.io/r/{name}.json"
}
}Then install the component:
npx shadcn@latest add @te/modal-fullscreen-takeoverUsage
"use client";
import { ModalFullscreenTakeover } from "@/components/modal-fullscreen-takeover";
export default function Page() {
return (
<ModalFullscreenTakeover
trigger={{ label: "Start the tour" }}
title="A workspace built for focus"
>
<p>Everything your team ships lives in one place.</p>
</ModalFullscreenTakeover>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| trigger | { label: string } | required | Renders a real button that opens the takeover. |
| title | string | required | Visible h2 heading that names the dialog via aria-labelledby. |
| children | ReactNode | required | Fullscreen content; heading and body rise in after the expand. |
| className | string | undefined | Additional classes merged onto the dialog. |
Customisation
Fullscreen Takeover Modal declares no tokens of its own; the panel consumes the global semantic tokens through Tailwind utilities, and the takeover uses the shared springSoft preset from lib/motion.ts, so retuning that preset retunes every soft-spring component together. The className prop is merged onto the dialog, which is the usual place to change its surface or add padding:
:root {
--border: oklch(from var(--color-neutral-50) l c h / 0.16);
}
<ModalFullscreenTakeover
trigger={{ label: "Start the tour" }}
title="A workspace built for focus"
className="text-foreground"
>
...
</ModalFullscreenTakeover>Frequently asked questions
- Is Fullscreen Takeover Modal free for commercial use?
- Yes. Fullscreen Takeover Modal is MIT licensed, so you can use it in personal and commercial projects without attribution.
- Is Fullscreen Takeover Modal accessible for keyboard and screen reader users?
- Yes. It renders a native dialog element opened with showModal, so the browser provides the focus trap, top layer rendering and Escape handling, and the page behind it becomes inert. The visible title labels the dialog through aria-labelledby, the trigger and close button are real buttons with accessible names, background scroll is locked while the takeover is open, and closing returns focus to the trigger that opened it. The dialog is made inert while it collapses, so the exit animation never traps focus.
- How does the takeover animation work, and what happens with reduced motion?
- Motion animates only clip-path and opacity: the panel expands from a small centred inset to full screen on the shared springSoft preset while it fades in, and once that settles the heading and body rise 8 pixels into place with a short stagger. Closing plays the same clip-path collapse in reverse over 0.35 seconds before the dialog closes. With prefers-reduced-motion enabled the clip-path and stagger are dropped entirely and both directions become plain opacity fades of 150 milliseconds or less with the layout final immediately.