Sheet
The sheet slides a modal panel in from a screen edge. Use it for edit forms, filters, carts, and mobile navigation; for a centered window, reach for the dialog.
<button id="sheet-1-trigger" class="btn btn-outline">Open</button>
<dialog class="sheet" data-sp-toggle="#sheet-1-trigger">
<div class="sheet-panel">
<button
class="btn btn-ghost btn-xs btn-icon absolute top-3 right-3"
aria-label="Close"
data-sp-dismiss
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
</button>
<div class="sheet-header">
<h2 class="sheet-title">Edit profile</h2>
<p class="sheet-description">
Make changes to your profile here. Click save when you're done.
</p>
</div>
<div class="sheet-content">
<div class="field-group">
<div class="field">
<label class="label" for="sheet-profile-name">Name</label>
<input class="input" id="sheet-profile-name" value="Pedro Duarte" />
</div>
<div class="field">
<label class="label" for="sheet-profile-username">Username</label>
<input class="input" id="sheet-profile-username" value="@peduarte" />
</div>
</div>
</div>
<div class="sheet-footer">
<button class="btn">Save changes</button>
<button class="btn btn-outline" data-sp-dismiss>Close</button>
</div>
</div>
</dialog>Usage
Add the sheet class to a <dialog> element. Give your trigger an id, then point the sheet at it with data-sp-toggle. The trigger can be any element. Close the sheet with data-sp-dismiss on a button, a backdrop click, or the Escape key.
<!-- This is a button toggling the sheet -->
<button id="my-trigger" class="btn btn-outline">Open Sheet</button>
<!-- This is the sheet -->
<dialog class="sheet" data-sp-toggle="#my-trigger">
<div class="sheet-panel">
<div class="sheet-header">
<h2 class="sheet-title">Title</h2>
<p class="sheet-description">Description</p>
</div>
<div class="sheet-footer">
<button class="btn btn-outline" data-sp-dismiss>Close</button>
</div>
</div>
</dialog>Examples
Side
Pick the edge the sheet slides from with sheet-left, sheet-right, sheet-top, or sheet-bottom. Without one, it defaults to the right.
<!-- Left -->
<button id="side-left" class="btn btn-outline">Left</button>
<dialog class="sheet sheet-left" data-sp-toggle="#side-left">
<div class="sheet-panel">
<div class="sheet-header">
<h2 class="sheet-title">Left</h2>
<p class="sheet-description">Great for navigation menus.</p>
</div>
<div class="sheet-footer">
<button class="btn btn-outline" data-sp-dismiss>Close</button>
</div>
</div>
</dialog>
<!-- Right -->
<button id="side-right" class="btn btn-outline">Right</button>
<dialog class="sheet sheet-right" data-sp-toggle="#side-right">
<div class="sheet-panel">
<div class="sheet-header">
<h2 class="sheet-title">Right</h2>
<p class="sheet-description">Great for details and settings.</p>
</div>
<div class="sheet-footer">
<button class="btn btn-outline" data-sp-dismiss>Close</button>
</div>
</div>
</dialog>
<!-- Top -->
<button id="side-top" class="btn btn-outline">Top</button>
<dialog class="sheet sheet-top" data-sp-toggle="#side-top">
<div class="sheet-panel">
<div class="sheet-header">
<h2 class="sheet-title">Top</h2>
<p class="sheet-description">Great for notifications.</p>
</div>
<div class="sheet-footer">
<button class="btn btn-outline self-start" data-sp-dismiss>Close</button>
</div>
</div>
</dialog>
<!-- Bottom -->
<button id="side-bottom" class="btn btn-outline">Bottom</button>
<dialog class="sheet sheet-bottom" data-sp-toggle="#side-bottom">
<div class="sheet-panel">
<div class="sheet-header">
<h2 class="sheet-title">Bottom</h2>
<p class="sheet-description">Great for actions on mobile.</p>
</div>
<div class="sheet-footer">
<button class="btn btn-outline self-start" data-sp-dismiss>Close</button>
</div>
</div>
</dialog>Mobile navigation
Pair a left sheet with the sidebar menu classes for a simple mobile navigation drawer. For a full navigation layout with a desktop column, reach for the sidebar component instead.
<button id="sheet-nav-trigger" class="btn btn-ghost btn-icon" aria-label="Open menu">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12h16"/><path d="M4 18h16"/><path d="M4 6h16"/></svg>
</button>
<dialog class="sheet sheet-left" aria-label="Main menu" data-sp-toggle="#sheet-nav-trigger">
<div class="sheet-panel">
<button
class="btn btn-ghost btn-xs btn-icon absolute top-3 right-3"
aria-label="Close"
data-sp-dismiss
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
</button>
<div class="sheet-header">
<a href="#" class="flex h-10 min-w-0 items-center gap-2 text-foreground">
<span class="flex size-6 shrink-0 items-center justify-center overflow-hidden rounded-sm bg-primary text-base leading-none text-primary-foreground">
<i class="font-serif font-bold not-italic">A</i>
</span>
<span class="truncate text-sm font-medium">Acme Inc.</span>
</a>
</div>
<div class="sheet-content px-2">
<nav class="sidebar-menu">
<div class="sidebar-menu-item">
<a href="#" class="sidebar-menu-button active">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>
<span>Home</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="sidebar-menu-button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>
<span>Inbox</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="sidebar-menu-button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2v4"/><path d="M16 2v4"/><rect width="18" height="18" x="3" y="4" rx="2"/><path d="M3 10h18"/></svg>
<span>Calendar</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="sidebar-menu-button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>
<span>Settings</span>
</a>
</div>
</nav>
</div>
<div class="sheet-footer">
<button class="btn">Upgrade to Pro</button>
</div>
</div>
</dialog>Options
Sheet
Set each option with its own data-sp-* attribute on the sheet element.
<dialog class="sheet" data-sp-toggle="#my-trigger" data-sp-static>JavaScript
Events
Lifecycle events fire on the sheet element; before* events are cancelable.
el.addEventListener("sp-beforeshow", (e) => {
if (!ready) e.preventDefault(); // veto the open
});Methods
Get the instance with sp.sheet(el), then call its methods:
const sheet = sp.sheet(document.querySelector("#my-sheet"));
sheet.show();