V-/Srcv0.1.0beta
// dialog
A modal glass pane over a dimmed page.
npx shadcn add @vsrc/dialogOnly the vsrc surface is documented here. Everything else passes through to Radix Dialog.
// DialogContent
| prop | type | default | notes |
|---|---|---|---|
| glass | "subtle" | "regular" | "heavy" | LiquidGlassOptions | false | — | Optics override for the modal pane. A preset name replaces the tuned values, an object merges over them, `false` disables refraction entirely. |
| showCloseButton | boolean | true | Hide the corner close affordance when the footer carries the only valid exits. |
Forwards `glass` to GlassSurface — engine defaults. The pane animates in once (animate-glass-in) and then holds still; the map is generated after mount, so the entrance never smears.
The exact file the CLI copies into your project — you own it after install.
"use client";
import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import type { GlassPreset, LiquidGlassOptions } from "vsrc/react";
import { GlassSurface } from "@/registry/vsrc/ui/glass-surface";
import { cn } from "@/lib/utils";
const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogClose = DialogPrimitive.Close;
function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
return (
<DialogPrimitive.Overlay
data-slot="dialog-overlay"
className={cn("animate-glass-in fixed inset-0 z-50 bg-background/70", className)}
{...props}
/>
);
}
function DialogContent({
className,
children,
glass,
showCloseButton = true,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
glass?: LiquidGlassOptions | GlassPreset | false;
/** The corner ✕. Off for surfaces that own their own chrome (e.g. the command palette). */
showCloseButton?: boolean;
}) {
return (
<DialogPrimitive.Portal>
<DialogOverlay />
<GlassSurface asChild glass={glass}>
<DialogPrimitive.Content
data-slot="dialog-content"
className={cn(
"animate-glass-in fixed top-1/2 left-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2",
"flex flex-col gap-4 p-8 text-foreground outline-none",
className,
)}
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close
aria-label="Close"
className={cn(
"absolute top-4 right-4 rounded-full p-1.5 text-muted-foreground transition-colors",
"outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring",
)}
>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" className="size-4">
<path d="M4 4l8 8M12 4l-8 8" />
</svg>
</DialogPrimitive.Close>
)}
</DialogPrimitive.Content>
</GlassSurface>
</DialogPrimitive.Portal>
);
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return <div data-slot="dialog-header" className={cn("flex flex-col gap-1.5", className)} {...props} />;
}
function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("font-display text-2xl leading-tight", className)}
{...props}
/>
);
}
function DialogDescription({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
return (
<DialogPrimitive.Description
data-slot="dialog-description"
className={cn("text-sm leading-relaxed text-muted-foreground", className)}
{...props}
/>
);
}
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div data-slot="dialog-footer" className={cn("flex justify-end gap-3 pt-2", className)} {...props} />
);
}
export {
Dialog,
DialogTrigger,
DialogClose,
DialogOverlay,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
};