A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
1<script lang="ts">
2 import Button from "@/components/ui/button/button.svelte"
3 import {
4 Dialog,
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/sveltenpm install @sprawlify/primitives @sprawlify/svelteyarn add @sprawlify/primitives @sprawlify/sveltebun add @sprawlify/primitives @sprawlify/svelte
Add the following files to your project:
1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import type { ComponentProps } from "svelte"
4
5 interface Props extends ComponentProps<typeof DialogPrimitive.CloseTrigger> {}
6
7 let { children, ...rest }: Props = $props()
8</script>
9
10<DialogPrimitive.CloseTrigger data-slot="dialog-close" {...rest}>
11 {@render children?.()}
12</DialogPrimitive.CloseTrigger>1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import { cn } from "@/lib/utils"
4 import DialogPortal from "./dialog-portal.svelte"
5 import DialogOverlay from "./dialog-overlay.svelte"
6 import Button from "../button/button.svelte"
7 import type { ComponentProps } from "svelte"
8 import { XIcon } from "lucide-svelte"
9
10 interface Props extends ComponentProps<typeof DialogPrimitive.Content> {
11 showCloseButton?: boolean
12 }
13
14 let { class: className, children, showCloseButton = true, ...rest }: Props = $props()
15</script>
16
17<DialogPortal>
18 <DialogOverlay />
19 <DialogPrimitive.Content
20 data-slot="dialog-content"
21 class={cn(
22 "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",
23 className
24 )}
25 {...rest}
26 >
27 {@render children?.()}
28 {#if showCloseButton}
29 <DialogPrimitive.CloseTrigger data-slot="dialog-close">
30 {#snippet asChild(props)}
31 <Button variant="ghost" class="absolute top-2 right-2" size="icon-sm" {...props()}>
32 <XIcon />
33 <span class="sr-only">Close</span>
34 </Button>
35 {/snippet}
36 </DialogPrimitive.CloseTrigger>
37 {/if}
38 </DialogPrimitive.Content>
39</DialogPortal>1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import { cn } from "@/lib/utils"
4 import type { ComponentProps } from "svelte"
5
6 interface Props extends ComponentProps<typeof DialogPrimitive.Description> {}
7
8 let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<DialogPrimitive.Description
12 data-slot="dialog-description"
13 class={cn(
14 "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
15 className
16 )}
17 {...rest}
18>
19 {@render children?.()}
20</DialogPrimitive.Description>1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import { cn } from "@/lib/utils"
4 import Button from "../button/button.svelte"
5 import type { HTMLAttributes } from "svelte/elements"
6 import { Sprawlify, type PolymorphicProps } from "@sprawlify/svelte";
7
8
9 interface Props extends HTMLAttributes<HTMLElement>, PolymorphicProps<"div"> {
10 showCloseButton?: boolean
11 }
12
13 let { class: className, children, showCloseButton = false, ...rest }: Props = $props()
14</script>
15
16<Sprawlify
17 as="div"
18 data-slot="dialog-footer"
19 class={cn(
20 "-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",
21 className
22 )}
23 {...rest}
24>
25 {@render children?.()}
26 {#if showCloseButton}
27 <DialogPrimitive.CloseTrigger>
28 {#snippet asChild(props)}
29 <Button variant="outline" {...props()}>Close</Button>
30 {/snippet}
31 </DialogPrimitive.CloseTrigger>
32 {/if}
33</Sprawlify>1<script lang="ts">
2 import { cn } from "@/lib/utils"
3 import { type HTMLAttributes } from "svelte/elements"
4 import { Sprawlify, type PolymorphicProps } from "@sprawlify/svelte"
5
6 interface Props extends HTMLAttributes<HTMLElement>, PolymorphicProps<"div"> {}
7
8 let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<Sprawlify as="div" data-slot="dialog-header" class={cn("flex flex-col gap-2", className)} {...rest}>
12 {@render children?.()}
13</Sprawlify>1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import { cn } from "@/lib/utils"
4 import type { ComponentProps } from "svelte"
5
6 interface Props extends ComponentProps<typeof DialogPrimitive.Backdrop> {}
7
8 let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<DialogPrimitive.Backdrop
12 data-slot="dialog-overlay"
13 class={cn(
14 "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",
15 className
16 )}
17 {...rest}
18>
19 {@render children?.()}
20</DialogPrimitive.Backdrop>1<script lang="ts">
2 import { Portal } from "@sprawlify/svelte/portal"
3 import type { ComponentProps } from "svelte"
4
5 interface Props extends ComponentProps<typeof Portal> {
6 "data-slot"?: string
7 }
8
9 let { children, ...rest }: Props = $props()
10</script>
11
12<Portal data-slot="dialog-portal" {...rest}>
13 {@render children?.()}
14</Portal>1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import { cn } from "@/lib/utils"
4 import type { ComponentProps } from "svelte"
5
6 interface Props extends ComponentProps<typeof DialogPrimitive.Title> {}
7
8 let { class: className, children, ...rest }: Props = $props()
9</script>
10
11<DialogPrimitive.Title
12 data-slot="dialog-title"
13 class={cn("cn-font-heading text-base leading-none font-medium", className)}
14 {...rest}
15>
16 {@render children?.()}
17</DialogPrimitive.Title>1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import type { ComponentProps } from "svelte"
4
5 interface Props extends ComponentProps<typeof DialogPrimitive.Trigger> {}
6
7 let { children, ...rest }: Props = $props()
8</script>
9
10<DialogPrimitive.Trigger data-slot="dialog-trigger" {...rest}>
11 {@render children?.()}
12</DialogPrimitive.Trigger>1<script lang="ts">
2 import { Dialog as DialogPrimitive } from "@sprawlify/svelte/dialog"
3 import type { ComponentProps } from "svelte"
4
5 interface Props extends ComponentProps<typeof DialogPrimitive.Root> {
6 "data-slot"?: string
7 }
8
9 let { children, ...rest }: Props = $props()
10</script>
11
12<DialogPrimitive.Root data-slot="dialog" {...rest}>
13 {@render children?.()}
14</DialogPrimitive.Root>1export { default as Dialog } from "./dialog.svelte";2export { default as DialogTrigger } from "./dialog-trigger.svelte";3export { default as DialogPortal } from "./dialog-portal.svelte";4export { default as DialogOverlay } from "./dialog-overlay.svelte";5export { default as DialogContent } from "./dialog-content.svelte";6export { default as DialogHeader } from "./dialog-header.svelte";7export { default as DialogFooter } from "./dialog-footer.svelte";8export { default as DialogTitle } from "./dialog-title.svelte";9export { default as DialogDescription } from "./dialog-description.svelte";10export { default as DialogClose } from "./dialog-close.svelte";11Update 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.
1<script lang="ts">
2 import Button from "@/components/ui/button/button.svelte"
3 import {
4 Dialog,
No Close Button
Use showCloseButton={false} to hide the close button.
1<script lang="ts">
2 import Button from "@/components/ui/button/button.svelte"
3 import {
4 Dialog,
Scrollable Content
Long content can scroll while the header stays in view.
1<script lang="ts">
2 import Button from "@/components/ui/button/button.svelte"
3 import {
4 Dialog,
Sticky Footer
Keep actions visible while the content scrolls.
1<script lang="ts">
2 import Button from "@/components/ui/button/button.svelte"
3 import {
4 Dialog,
On This Page
InstallationUsageExamplesCustom Close ButtonNo Close ButtonScrollable ContentSticky FooterGet PRO
Need premium blocks and templates? Upgrade to PRO and get access.