# Sheet

> A modal panel that slides in from an edge of the viewport, for settings, filters, or any focused task that doesn't need a full page.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Overlays
- Tags: overlay, sheet, panel, modal, side panel, settings
- Docs: https://fancy-ui.rama.app/docs/components/sheet
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/sheet

## Import

```svelte
<script lang="ts">
  import { Sheet } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { Sheet } from 'fancy-ui-react';` (same prop names; `class` becomes `className`, snippets become `ReactNode`).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `open` | `boolean` | `false` | Whether the sheet is open. Bindable |
| `onOpenChange` | `(open: boolean) => void` | — | Called with the new value whenever the sheet opens or closes |
| `side` | `"left" \| "right" \| "top" \| "bottom"` | `"right"` | Edge of the viewport the panel slides in from |
| `title` | `string` | — | Heading rendered in the header and wired to aria-labelledby |
| `description` | `string` | — | Supporting text under the title, wired to aria-describedby |
| `dismissible` | `boolean` | `true` | Whether Escape, the scrim and the close button can close the sheet |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Panel width (left/right sides) or height (top/bottom sides) |
| `class` | `string` | — | Additional CSS classes merged onto the panel |
| `ref` | `HTMLDivElement \| null` | `null` | Bindable element reference to the panel |
| `sound` | `boolean` | `false` | Plays close when the sheet is dismissed, once the user has enabled sound |

## Snippets

| Snippet | Description |
| --- | --- |
| `children` | Panel body content |
| `footer` | Content pinned below the body, e.g. actions |

## Examples

### Basic Usage

```svelte
<script lang="ts">
	import { Sheet } from "fancy-ui-svelte";
	import { Button } from "fancy-ui-svelte";
	import { Switch } from "fancy-ui-svelte";

	let open = $state(false);
	let notifications = $state(true);
	let compactMode = $state(false);
</script>

<Button onclick={() => (open = true)}>Open settings</Button>

<Sheet sound bind:open title="Settings" description="Update your workspace preferences.">
	<div class="flex items-center justify-between">
		<span class="text-muted-foreground text-[13px]">Notifications</span>
		<Switch sound bind:checked={notifications} label="Notifications" />
	</div>
	<div class="flex items-center justify-between">
		<span class="text-muted-foreground text-[13px]">Compact mode</span>
		<Switch sound bind:checked={compactMode} label="Compact mode" />
	</div>
</Sheet>
```

### Sides

Slide in from any edge of the viewport.

```svelte
<script lang="ts">
	import { Sheet, type SheetSide } from "fancy-ui-svelte";
	import { Button } from "fancy-ui-svelte";

	let open = $state(false);
	let side = $state<SheetSide>("right");

	function openFrom(next: SheetSide) {
		side = next;
		open = true;
	}
</script>

<div class="flex flex-wrap gap-2">
	<Button variant="outline" onclick={() => openFrom("left")}>Left</Button>
	<Button variant="outline" onclick={() => openFrom("right")}>Right</Button>
	<Button variant="outline" onclick={() => openFrom("top")}>Top</Button>
	<Button variant="outline" onclick={() => openFrom("bottom")}>Bottom</Button>
</div>

<Sheet sound bind:open {side} title="Panel" description="Slides in from {side}.">
	<p class="text-muted-foreground text-[13px]">Body content goes here.</p>
</Sheet>
```

### With Footer

Pin actions below the body.

```svelte
<script lang="ts">
	import { Sheet } from "fancy-ui-svelte";
	import { Button } from "fancy-ui-svelte";
	import { Input } from "fancy-ui-svelte";

	let open = $state(false);
	let email = $state("");

	function send() {
		open = false;
	}
</script>

<Button onclick={() => (open = true)}>Invite a member</Button>

<Sheet
	sound
	bind:open
	title="Invite a member"
	description="Send an email invitation to join the workspace."
	{footer}
>
	<Input bind:value={email} type="email" placeholder="email@example.com" />
</Sheet>

{#snippet footer()}
	<Button variant="outline" onclick={() => (open = false)}>Cancel</Button>
	<Button onclick={send}>Invite</Button>
{/snippet}
```
