Summit
ComponentsOverlays

Sheet

A Sheet shows users a panel that slides over the page from one side of the screen.

When to Use

  • to edit a record while the page that it belongs to stays in view, such as “Edit client”
  • for a form with more fields than fit in a Dialog, as a side Sheet is as tall as the screen
  • for navigation on a narrow screen, as the Sidebar does below 768px

When Not to Use

  • for a short form in the center of the screen (use a Dialog)
  • for a panel that users swipe away, or one that rests at set heights (use a Drawer)
  • to confirm an action that can’t be undone (use an Alert Dialog)

See Dialog for a comparison of the Dialog, the Alert Dialog, the Sheet, and the Drawer.

Anatomy

ElementUsage
OverlayRequired
Close buttonShown by default
PopupRequired
Title*Required
DescriptionOptional
FooterOptional

* The title is the Sheet’s accessible name. If the design shows no title, visually hide it and keep it in the markup.

SheetContent renders the portal, the overlay, and the close button, so you don’t need to add them. SheetHeader and SheetFooter have 16px of padding and the popup has none, so add your own padding to the content between them.

The footer is positioned at the bottom edge, and its Buttons are stacked in the order in which they are written. Write the main action first.

DoWrite the main action first so that it is at the top of the footer.
Don’tWhen “Cancel” is written first, as it is in a Dialog, it is displayed above “Save”, so users find the main action at the bottom of a Sheet and at the top of a Dialog below 640px.

Behavior

A Sheet is Base UI’s Dialog fixed to one side of the screen. It is modal, and it opens, closes, and moves focus as a Dialog does.

Position and Size

To choose the edge, set side on SheetContent.

SidePositionSize
right, leftThat edge, from the top to the bottom384px wide from 640px, and 75% of the screen below 640px
top, bottomThat edge, across the screenAs tall as its content

If floating is set on SheetContent, the Sheet is inset from the edges of the screen. See Layout for the widths of the other overlays.

side is physical: right is the right edge in both directions. If you want the Sheet at the end edge of a right-to-left layout, pass side="left". See Right-to-Left for how to read the direction.

Overflow

If the content is taller than the Sheet, the Sheet scrolls. To keep the footer in view, see Scroll Long Content.

Safe Areas

When a Sheet touches the top or the bottom of the screen, it adds the safe-area inset of a phone to its padding. The insets apply only if the page sets viewport-fit=cover.

Content

For the title, the description, and the actions of a Sheet, follow the rules for a Dialog.

The label of the close button is labels.sheet.close, which is “Close” by default. To translate it, use the Summit Provider.

Accessibility

A Sheet has the role, the keys, and the focus handling of a Dialog. The close button is last in the popup’s markup, so users reach it with Tab after the footer.

A Sheet needs a SheetTitle so that screen readers can announce what it is for, as WCAG 2.2 SC 4.1.2 Name, Role, Value requires. If the design shows no title, add sr-only to its SheetHeader to visually hide it, as the Sidebar does.

If showCloseButton is false, keep a SheetClose in the popup. See Dialog for the reason.

Installation

npx shadcn@latest add @summit/sheet

The CLI also adds @summit/button and @summit/summit-provider.

Usage

import { Button } from '@/components/ui/button';
import {
    Sheet,
    SheetClose,
    SheetContent,
    SheetDescription,
    SheetFooter,
    SheetHeader,
    SheetTitle,
    SheetTrigger,
} from '@/components/ui/sheet';

<Sheet>
    <SheetTrigger render={<Button variant="outline" />}>Edit client</SheetTrigger>
    <SheetContent>
        <SheetHeader>
            <SheetTitle>Edit client</SheetTitle>
            <SheetDescription>Changes apply to new invoices only.</SheetDescription>
        </SheetHeader>
        <SheetFooter>
            <SheetClose render={<Button />}>Save</SheetClose>
            <SheetClose render={<Button variant="outline" />}>Cancel</SheetClose>
        </SheetFooter>
    </SheetContent>
</Sheet>;

Choose the Side

To choose the edge, set side to right, left, top, or bottom. To inset the Sheet from the edges of the screen, set floating.

Choose the Side
<SheetContent side="left" floating>
    <SheetTitle>Filters</SheetTitle>
</SheetContent>

Scroll Long Content

To scroll long content, add flex-1 and overflow-y-auto to the content between the header and the footer. The footer then stays at the bottom of the Sheet.

Scroll Long Content
<SheetContent>
    <SheetHeader>
        <SheetTitle>Edit client</SheetTitle>
    </SheetHeader>
    <div className="flex-1 overflow-y-auto px-4">{fields}</div>
    <SheetFooter>
        <SheetClose render={<Button />}>Save</SheetClose>
    </SheetFooter>
</SheetContent>

Hide the Close Button

To remove the close button in the corner, set showCloseButton={false} on SheetContent.

Hide the Close Button
<SheetContent showCloseButton={false}>
    <SheetTitle>Edit client</SheetTitle>
    <SheetFooter>
        <SheetClose render={<Button variant="outline" />}>Close</SheetClose>
    </SheetFooter>
</SheetContent>

API Reference

The parts accept the props of their matching parts in Base UI’s Dialog, where SheetContent is Dialog.Popup. SheetHeader and SheetFooter accept the props of a div. See the Base UI Dialog documentation for open, onOpenChange, modal, initialFocus, and finalFocus.

SheetContent

PropTypeDefaultDescription
side'top' | 'right' | 'bottom' | 'left''right'The edge the Sheet is fixed to
floatingbooleanfalseInsets the Sheet from the edges of the screen and rounds it
showCloseButtonbooleantrueShows the close button in the top corner

On this page