Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Search and Filter Sheet for React

A Filters button opens a right-side sheet with a search field, three category checkboxes, and an Apply Filters button.

The title is Search & Filter. A Search field comes first, then Categories with Category 1, Category 2, and Category 3. Apply Filters sits at the bottom.

Use it when filters should not push the results down the page. Keep one or two on the page as a Checkbox if people use them every time. In React, Base UI does not filter the list.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Sheet anatomy: content, close, title, description, footer

Usage

<Sheet>
  <SheetTrigger render={<Button variant="outline" />}>Filters</SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Search &amp; Filter</SheetTitle>
      <SheetDescription>
        Refine your search with filters below.
      </SheetDescription>
    </SheetHeader>
    <FieldGroup className="gap-4 p-4">
      <Field>
        <FieldLabel htmlFor="filter-search">Search</FieldLabel>
        <Input id="filter-search" placeholder="Search..." type="search" />
      </Field>
      <FieldSet className="gap-3">
        <FieldLegend variant="label">Categories</FieldLegend>
        <FieldGroup className="gap-3">
          {CATEGORIES.map((category) => (
            <Field key={category.id} orientation="horizontal">
              <Checkbox id={category.id} />
              <FieldLabel className="font-normal" htmlFor={category.id}>
                {category.label}
              </FieldLabel>
            </Field>
          ))}
        </FieldGroup>
      </FieldSet>
      <Button className="w-full">Apply Filters</Button>
    </FieldGroup>
  </SheetContent>
</Sheet>

FAQ

How are the categories grouped?

In a FieldSet whose FieldLegend reads Categories. Each category is a horizontal Field with the checkbox first and its label after, so clicking the label toggles the box.

Does Apply Filters filter anything?

Not yet: the checkboxes are uncontrolled and the button has no handler. Read the values when it's pressed, apply them to your list, and close the sheet.

How do I close the sheet after applying?

Control the open state and set it to false in the Apply handler: Pass open to Sheet; onOpenChange receives the next boolean.

How does Filters open the sheet?

The outline button labeled Filters is the trigger, and its text is the accessible name. The Button goes in the render prop of SheetTrigger, and the label stays its child.

What does the filter sheet announce?

SheetTitle names the dialog for assistive tech, so every sheet renders one; hide it with sr-only when the design has no visible heading. It reads Search & Filter, with Refine your search with filters below as the description.

API Reference

Sheet

No extra props in this demo. The rest is on the Sheet page.

Button

Sets variant="outline". The rest is on the Button page.

Field

Sets htmlFor="filter-search", variant="label", orientation="horizontal" and htmlFor={category.id}. The rest is on the Field page.

Input

Sets id="filter-search", placeholder="Search..." and type="search". The rest is on the Input page.

Checkbox

Sets id={category.id}. The rest is on the Checkbox page.