Anatomy of the GodUI Alert Dialog
Why an alert dialog moves exactly like a dialog, and how its buttons inherit the press without a line of extra code.
↓Scroll to step through it
Same motion, on purpose
An alert dialog is a dialog that refuses to be dismissed by accident: no outside click, and focus starts on Cancel. Its motion shouldn't say anything different, so it uses the same two keyframes as Dialog.
Both components read their curves from godui-motion. Tune
--godui-duration-base or --godui-enter-scale once and every overlay
changes together.
Buttons that press
AlertDialogAction and AlertDialogCancel render Button asChild around the
Radix primitive. asChild merges Button's classes onto the primitive, so the
action gets the spring press (active:scale-[0.97] on ease-spring-bouncy)
and keeps its own data-slot.
When you install the alert dialog, its registry entry depends on
@godui/button, so the GodUI button comes along.
The result
Open the dialog and try clicking the overlay: nothing happens. Cancel or Continue closes it with the 150ms exit.
- opacity
- 0 → 1
- scale
- 0.96 → 1
<AlertDialogPrimitive.Contentdata-slot="alert-dialog-content"data-size={size}className={cn( "group/alert-dialog-content fixed top-[50%] left-[50%] … shadow-lg data-[size=sm]:max-w-xs data-[state=open]:animate-godui-fade-scale-in data-[state=closed]:animate-godui-fade-scale-out …", className,)}/>Anatomy of the GodUI Alert Dialog
Why an alert dialog moves exactly like a dialog, and how its buttons inherit the press without a line of extra code.
- opacity
- 0 → 1
- scale
- 0.96 → 1
<AlertDialogPrimitive.Contentdata-slot="alert-dialog-content"data-size={size}className={cn( "group/alert-dialog-content fixed top-[50%] left-[50%] … shadow-lg data-[size=sm]:max-w-xs data-[state=open]:animate-godui-fade-scale-in data-[state=closed]:animate-godui-fade-scale-out …", className,)}/>Same motion, on purpose
An alert dialog is a dialog that refuses to be dismissed by accident: no outside click, and focus starts on Cancel. Its motion shouldn't say anything different, so it uses the same two keyframes as Dialog.
Both components read their curves from godui-motion. Tune
--godui-duration-base or --godui-enter-scale once and every overlay
changes together.
function AlertDialogAction({ className, variant = "default", size = "default", ...props }) {return ( <Button variant={variant} size={size} asChild> <AlertDialogPrimitive.Action data-slot="alert-dialog-action" className={cn(className)} {...props} /> </Button>);}Buttons that press
AlertDialogAction and AlertDialogCancel render Button asChild around the
Radix primitive. asChild merges Button's classes onto the primitive, so the
action gets the spring press (active:scale-[0.97] on ease-spring-bouncy)
and keeps its own data-slot.
When you install the alert dialog, its registry entry depends on
@godui/button, so the GodUI button comes along.
The result
Open the dialog and try clicking the overlay: nothing happens. Cancel or Continue closes it with the 150ms exit.
What's animated
| Interaction | Keyframe / mechanism | Properties | Easing | Duration |
|---|---|---|---|---|
| Open | godui-fade-scale-in | opacity, scale 0.96 → 1 | ease-spring-snappy | 260ms |
| Close | godui-fade-scale-out | opacity, scale 1 → 0.96 | ease-out-expo | 150ms |
| Overlay | godui-fade-in / godui-fade-out | opacity | snappy / expo | 260 / 150ms |
| Action, Cancel press | transition on active:scale-[0.97] | scale | ease-spring-bouncy | 260ms |
Why GPU-only
Content and overlay animate scale and opacity; the buttons animate
scale. shadcn's buttons inside the dialog use transition-all, which also
animates background and ring paint. GodUI's don't.
Reduced motion
--godui-motion: 0 removes the scale from the keyframes, so the dialog only
fades, and the buttons' motion-reduce:transition-none makes the press
instant.
Replacing shadcn
npx shadcn add @godui/alert-dialog overwrites components/ui/alert-dialog.tsx.
Exports, props and data-slot attributes match shadcn/ui new-york-v4, so
existing imports keep working. It also installs godui-motion (easings,
keyframes, the FLIP hook) and the GodUI button its actions render.