A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
1import { Button } from "@/components/ui/button";2import {3 Dialog,4 DialogClose,Installation
pnpm dlx sprawlify@latest add dialognpx sprawlify@latest add dialogyarn sprawlify@latest add dialogbunx --bun sprawlify@latest add dialog
Install the following dependencies:
pnpm add @sprawlify/primitives @sprawlify/solidnpm install @sprawlify/primitives @sprawlify/solidyarn add @sprawlify/primitives @sprawlify/solidbun add @sprawlify/primitives @sprawlify/solid
Add the following files to your project:
1import { XIcon } from "lucide-solid";2import { cn } from "@/lib/utils";3import { Button } from "@/components/ui/button";4import { Dialog as DialogPrimitive } from "@sprawlify/solid/dialog";5import type { ComponentProps } from "solid-js";6import { Show, splitProps } from "solid-js";7import { Portal } from "solid-js/web";8import { sprawlify } from "@sprawlify/solid";910function Dialog(props: ComponentProps<typeof DialogPrimitive.Root>) {11 return <DialogPrimitive.Root data-slot="dialog" {...props} />;12}1314function DialogTrigger(props: ComponentProps<typeof DialogPrimitive.Trigger>) {15 return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;16}1718function DialogPortal(props: ComponentProps<typeof Portal>) {19 return <Portal data-slot="dialog-portal" {...props} />;20}2122function DialogClose(props: ComponentProps<typeof DialogPrimitive.CloseTrigger>) {23 return <DialogPrimitive.CloseTrigger data-slot="dialog-close" {...props} />;24}2526function DialogOverlay(props: ComponentProps<typeof DialogPrimitive.Backdrop>) {27 const [local, others] = splitProps(props, ["class"]);2829 return (30 <DialogPrimitive.Backdrop31 data-slot="dialog-overlay"32 class={cn(33 "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0",34 local.class,35 )}36 {...others}37 />38 );39}4041function DialogContent(42 props: ComponentProps<typeof DialogPrimitive.Content> & { showCloseButton?: boolean },43) {44 const [local, others] = splitProps(props, ["class", "children", "showCloseButton"]);45 const showCloseButton = () => local.showCloseButton ?? true;4647 return (48 <DialogPortal>49 <DialogOverlay />50 <DialogPrimitive.Content51 data-slot="dialog-content"52 class={cn(53 "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",54 local.class,55 )}56 {...others}57 >58 {local.children}59 <Show when={showCloseButton()}>60 <DialogPrimitive.CloseTrigger61 data-slot="dialog-close"62 asChild={(props) => (63 <Button variant="ghost" class="absolute top-2 right-2" size="icon-sm" {...props()}>64 <XIcon />65 <span class="sr-only">Close</span>66 </Button>67 )}68 />69 </Show>70 </DialogPrimitive.Content>71 </DialogPortal>72 );73}7475function DialogHeader(props: ComponentProps<"div">) {76 const [local, others] = splitProps(props, ["class"]);7778 return (79 <sprawlify.div80 data-slot="dialog-header"81 class={cn("flex flex-col gap-2", local.class)}82 {...others}83 />84 );85}8687function DialogFooter(props: ComponentProps<typeof sprawlify.div> & { showCloseButton?: boolean }) {88 const [local, others] = splitProps(props, ["class", "showCloseButton", "children"]);89 const showCloseButton = () => local.showCloseButton ?? false;9091 return (92 <sprawlify.div93 data-slot="dialog-footer"94 class={cn(95 "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",96 local.class,97 )}98 {...others}99 >100 {local.children}101 {showCloseButton() && (102 <DialogPrimitive.CloseTrigger103 asChild={(props) => (104 <Button variant="outline" {...props()}>105 Close106 </Button>107 )}108 />109 )}110 </sprawlify.div>111 );112}113114function DialogTitle(props: ComponentProps<typeof DialogPrimitive.Title>) {115 const [local, others] = splitProps(props, ["class"]);116117 return (118 <DialogPrimitive.Title119 data-slot="dialog-title"120 class={cn("cn-font-heading text-base leading-none font-medium", local.class)}121 {...others}122 />123 );124}125126function DialogDescription(props: ComponentProps<typeof DialogPrimitive.Description>) {127 const [local, others] = splitProps(props, ["class"]);128129 return (130 <DialogPrimitive.Description131 data-slot="dialog-description"132 class={cn(133 "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",134 local.class,135 )}136 {...others}137 />138 );139}140141export {142 Dialog,143 DialogClose,144 DialogContent,145 DialogDescription,146 DialogFooter,147 DialogHeader,148 DialogOverlay,149 DialogPortal,150 DialogTitle,151 DialogTrigger,152};153Update the import paths to match your project setup.
Usage
1import {
2 Dialog,
3 DialogContent,
4 DialogDescription,
5 DialogHeader,
6 DialogTitle,
7 DialogTrigger,
8} from "@/components/ui/dialog"1<Dialog>
2 <DialogTrigger>Open</DialogTrigger>
3 <DialogContent>
4 <DialogHeader>
5 <DialogTitle>Are you absolutely sure?</DialogTitle>
6 <DialogDescription>
7 This action cannot be undone. This will permanently delete your account
8 and remove your data from our servers.
9 </DialogDescription>
10 </DialogHeader>
11 </DialogContent>
12</Dialog>Examples
Custom Close Button
Replace the default close control with your own button.
1import { Button } from "@/components/ui/button";2import {3 Dialog,4 DialogClose,No Close Button
Use showCloseButton={false} to hide the close button.
1import { Button } from "@/components/ui/button";2import {3 Dialog,4 DialogContent,Scrollable Content
Long content can scroll while the header stays in view.
1import { Button } from "@/components/ui/button";2import {3 Dialog,4 DialogContent,Sticky Footer
Keep actions visible while the content scrolls.
1import { Button } from "@/components/ui/button";2import {3 Dialog,4 DialogClose,On This Page
InstallationUsageExamplesCustom Close ButtonNo Close ButtonScrollable ContentSticky FooterGet PRO
Need premium blocks and templates? Upgrade to PRO and get access.