Presets

Blocks

Get PRO

Need premium blocks and templates? Upgrade to PRO and get access.

Upgrade
JoinLogin
Presets
Monochrome
Overview
  • Introduction
  • Components
  • Installation
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • CalendarNEW
  • Card
  • CarouselNEW
  • Checkbox
  • Collapsible
  • Dialog
  • Dropdown Menu
  • Empty
  • Field
  • Input
  • Input Group
  • Item
  • Kbd
  • Label
  • Native Select
  • Scroll Area
  • SelectNEW
  • Separator
  • SwitchNEW
  • Table
  • Tabs
  • Textarea
  • TooltipNEW

Dialog

PreviousNext

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 dialog
npx sprawlify@latest add dialog
yarn sprawlify@latest add dialog
bunx --bun sprawlify@latest add dialog

Install the following dependencies:

pnpm add @sprawlify/primitives @sprawlify/solid
npm install @sprawlify/primitives @sprawlify/solid
yarn add @sprawlify/primitives @sprawlify/solid
bun add @sprawlify/primitives @sprawlify/solid

Add the following files to your project:

dialog.tsx
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};153

Update 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 Footer

Get PRO

Need premium blocks and templates? Upgrade to PRO and get access.