Components
Alert Dialog New · experimental
shadcn's AlertDialog with goo. It blooms like the Dialog, but lighter, because an alert is the serious one.
Customize
GoopAlertDialog wraps the same reka-ui AlertDialog primitive as shadcn-vue's AlertDialog, with the same API. It interrupts the user and waits for a response. Swap the imports and you're done.
Installation
Nuxt
pnpm add @goopui/nuxt
export default defineNuxtConfig({
modules: ['@goopui/nuxt'],
})
The module auto-imports every GoopAlertDialog* part, adds goop.css, and points Tailwind at the component classes. It needs Tailwind CSS v4 and the shadcn tokens.
Vue
pnpm add @goopui/vue
@import "tailwindcss";
@import "@goopui/vue/goop.css";
Usage
<script setup lang="ts">
// Nuxt auto-imports these. In plain Vue, import them:
import {
GoopAlertDialog,
GoopAlertDialogAction,
GoopAlertDialogCancel,
GoopAlertDialogContent,
GoopAlertDialogDescription,
GoopAlertDialogFooter,
GoopAlertDialogHeader,
GoopAlertDialogTitle,
GoopAlertDialogTrigger,
GoopButton,
} from '@goopui/vue'
</script>
<template>
<GoopAlertDialog>
<GoopAlertDialogTrigger as-child>
<GoopButton variant="outline">Delete account</GoopButton>
</GoopAlertDialogTrigger>
<GoopAlertDialogContent>
<GoopAlertDialogHeader>
<GoopAlertDialogTitle>Are you absolutely sure?</GoopAlertDialogTitle>
<GoopAlertDialogDescription>This action cannot be undone.</GoopAlertDialogDescription>
</GoopAlertDialogHeader>
<GoopAlertDialogFooter>
<GoopAlertDialogCancel>Cancel</GoopAlertDialogCancel>
<GoopAlertDialogAction>Continue</GoopAlertDialogAction>
</GoopAlertDialogFooter>
</GoopAlertDialogContent>
</GoopAlertDialog>
</template>
The parts are GoopAlertDialog, GoopAlertDialogTrigger, GoopAlertDialogContent, GoopAlertDialogOverlay, GoopAlertDialogHeader, GoopAlertDialogFooter, GoopAlertDialogTitle, GoopAlertDialogDescription, GoopAlertDialogAction, and GoopAlertDialogCancel. All the panel's goo lives on GoopAlertDialogContent.
GoopAlertDialogAction and GoopAlertDialogCancel render as a GoopButton (default and outline variants), so they drip too. variant, size, and goo pass through to the button.
Behavior
The panel blooms from its own center, exactly like the Dialog's, with every toggle and knob the Dialog has. Only the defaults differ:
- A lighter slosh.
openSloshis0.6andcloseSloshis0.7when you leave them alone (or passtrue). - A smaller splash. A few small drops, flung a short way:
openDripAmount0.35,openDripSize0.75,openDripFling0.6. - Content stays sharp. The goo is drawn on an
aria-hiddensurface behind your content.
Turn any of it up, or off:
<GoopAlertDialogContent>...</GoopAlertDialogContent> <!-- light defaults -->
<GoopAlertDialogContent
:open-slosh="1" :close-slosh="1"
:open-drip-amount="1" :open-drip-size="1" :open-drip-fling="1"
overlay
>
...
</GoopAlertDialogContent>
Goo overlay
Like the Dialog's, the goo overlay is opt-in: set overlay and the backdrop pours down over the page and drains off on close. overlayDrips shapes its leading edge. See Dialog: Goo overlay.
Plain shadcn
:goo="false" renders exactly shadcn's AlertDialogContent and overlay:
<GoopAlertDialogContent :goo="false">...</GoopAlertDialogContent>
GoopAlertDialogContent exposes its engine handle as handle (null before it mounts, or when goo is off).
Props
The root, trigger, header, footer, title, and description take shadcn-vue's props. GoopAlertDialogContent takes reka-ui's AlertDialogContent props, class, and these goo props. The defaults shown are the alert dialog's:
| Prop | Type | Default | Notes |
|---|---|---|---|
goo | boolean | true | Master switch. false renders a plain shadcn AlertDialogContent and overlay. |
bloomStart | 'single' | 'merge' | 'single' | How the bloom starts: one droplet swells, or a few drops fuse. |
wobble | boolean | true | The open overshoot past every side and its jelly settle. |
fade | boolean | true | The content fades in once the goo has mostly spread, and out first on close. |
openSlosh | boolean | number | 0.6 | On open, every edge bulges past rest, rebounds, and wobbles. A number from 0 to 2 sets the strength. |
openDrips | boolean | number | 1 (light knobs) | On open, the big all-around splash: globs, drops, and specks fling off every side, fall, and fade. A number from 0 to 2 sets the strength. |
openDripAmount | number | 0.35 | Splash drop count, 0 to 3. |
openDripSize | number | 0.75 | Splash drop size, 0.3 to 2.5. |
openDripFling | number | 0.6 | How far the drops are flung before they fall, 0 to 3. |
openDripVariety | number | 0.7 | Mix of big globs and specks, and how uneven the spray is, 0 to 1. 0 makes every drop alike. |
sloshVariety | number | 1 | How differently each side bulges on open and close (off-centre, one or two lumps, staggered), 0 to 1. 0 is an even, centred bulge. |
closeSlosh | boolean | number | 0.7 | On close, the panel pulls in and wobbles before it shrinks to the center. A number from 0 to 2 sets the strength. |
overlay | boolean | false | Opt-in goo overlay: the dimmed backdrop pours down over the page and drains off the bottom on close. false keeps shadcn's fading overlay. |
overlayDrips | boolean | number | true | The goo overlay's leading edge runs ahead in drips. false is a straight edge, a number from 0 to 2 sets the strength. Only with overlay. |
surface | 'popover' | 'trigger' | string | 'popover' | The panel's color. 'popover' is the content's own shadcn background. 'trigger' takes the trigger's background and text color. Any CSS color also works. |
speed | number | 1 | Animation speed multiplier, for the panel and the overlay. |
preset | 'subtle' | 'playful' | 'wild' | app config, then playful | The overall feel. |
renderer | 'svg' | 'canvas' | 'svg' | How the goo is drawn, for the panel and the overlay. |
Accessibility
Focus trapping (Cancel gets the initial focus), scroll locking, and the alertdialog role come from reka-ui. The goo surface is aria-hidden and can't be clicked, and your content is never filtered. Under reduced motion it opens and closes plainly: the panel keeps its goo shape and color, but the bloom, slosh, splash, and wobble are all turned off, and the goo overlay appears without pouring. See Accessibility & reduced motion.