shadcn-remix
GitHub

Sheet

Extends the Dialog component to display content that complements the main content of the screen.

import { css } from 'remix/component'

import { Button, buttonVariants } from '#app/ui/button.tsx'
import { Input } from '#app/ui/input.tsx'
import { Label } from '#app/ui/label.tsx'
import {
import { css } from 'remix/component'

import { Button, buttonVariants } from '#app/ui/button.tsx'
import { Input } from '#app/ui/input.tsx'
import { Label } from '#app/ui/label.tsx'
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '#app/ui/sheet.tsx'

const field = css({ display: 'grid', gap: '0.75rem' })

export function SheetDemo() {
  return () => (
    <Sheet>
      <SheetTrigger mix={buttonVariants({ variant: 'outline' })}>Open</SheetTrigger>
      <SheetContent>
        <SheetHeader>
          <SheetTitle>Edit profile</SheetTitle>
          <SheetDescription>
            Make changes to your profile here. Click save when you&apos;re done.
          </SheetDescription>
        </SheetHeader>
        <div
          mix={css({
            display: 'grid',
            flex: '1 1 0%',
            gridAutoRows: 'min-content',
            gap: '1.5rem',
            paddingInline: '1rem',
          })}
        >
          <div mix={field}>
            <Label htmlFor="sheet-demo-name">Name</Label>
            <Input id="sheet-demo-name" defaultValue="Pedro Duarte" />
          </div>
          <div mix={field}>
            <Label htmlFor="sheet-demo-username">Username</Label>
            <Input id="sheet-demo-username" defaultValue="@peduarte" />
          </div>
        </div>
        <SheetFooter>
          <Button type="submit">Save changes</Button>
          <SheetClose mix={buttonVariants({ variant: 'outline' })}>Close</SheetClose>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  )
}

Installation

$ pnpm dlx shadcn@latest add https://www.shadcn-remix.com/r/sheet.json

Usage

import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '#app/ui/sheet.tsx'
<Sheet>
  <SheetTrigger>Open</SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Are you absolutely sure?</SheetTitle>
      <SheetDescription>This action cannot be undone.</SheetDescription>
    </SheetHeader>
  </SheetContent>
</Sheet>

Examples

Side

Use the side prop on SheetContent to set the edge of the screen where the sheet appears. Values are top, right, bottom, or left.

import { css } from 'remix/component'

import { buttonVariants } from '#app/ui/button.tsx'
import { Input } from '#app/ui/input.tsx'
import { Label } from '#app/ui/label.tsx'
import {
import { css } from 'remix/component'

import { buttonVariants } from '#app/ui/button.tsx'
import { Input } from '#app/ui/input.tsx'
import { Label } from '#app/ui/label.tsx'
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '#app/ui/sheet.tsx'

const SHEET_SIDES = ['top', 'right', 'bottom', 'left'] as const

const row = css({
  display: 'grid',
  gridTemplateColumns: 'repeat(4, minmax(0, 1fr))',
  alignItems: 'center',
  gap: '1rem',
})
const labelRight = css({ textAlign: 'right' })
const span3 = css({ gridColumn: 'span 3 / span 3' })

export function SheetSide() {
  return () => (
    <div mix={css({ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: '0.5rem' })}>
      {SHEET_SIDES.map((side) => (
        <Sheet key={side}>
          <SheetTrigger mix={buttonVariants({ variant: 'outline' })}>{side}</SheetTrigger>
          <SheetContent side={side}>
            <SheetHeader>
              <SheetTitle>Edit profile</SheetTitle>
              <SheetDescription>
                Make changes to your profile here. Click save when you&apos;re done.
              </SheetDescription>
            </SheetHeader>
            <div mix={css({ display: 'grid', gap: '1rem', paddingBlock: '1rem' })}>
              <div mix={row}>
                <Label htmlFor="name" mix={labelRight}>
                  Name
                </Label>
                <Input id="name" value="Pedro Duarte" mix={span3} />
              </div>
              <div mix={row}>
                <Label htmlFor="username" mix={labelRight}>
                  Username
                </Label>
                <Input id="username" value="@peduarte" mix={span3} />
              </div>
            </div>
            <SheetFooter>
              <SheetClose type="submit" mix={buttonVariants()}>
                Save changes
              </SheetClose>
            </SheetFooter>
          </SheetContent>
        </Sheet>
      ))}
    </div>
  )
}

API Reference

Sheet

PropTypeDefault
openboolean-
defaultOpenboolean-
onOpenChange((open: boolean) => void)-

SheetTrigger

PropTypeDefault
mixMixValue-

SheetClose

PropTypeDefault
mixMixValue-

SheetContent

PropTypeDefault
sideSheetSide"right"
showCloseButtonbooleantrue
mixMixValue-

SheetHeader

PropTypeDefault
mixMixValue-

SheetFooter

PropTypeDefault
mixMixValue-

SheetTitle

PropTypeDefault
mixMixValue-

SheetDescription

PropTypeDefault
mixMixValue-