Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Popover examples · Standard

Filter Popover for React

A Filter button that opens a popover of status checkboxes and an Apply Filters button.

Framework
UI library

A Filter button that opens three status checkboxes, Active, Pending and Archived, with an Apply Filters button under them. Keep the filters next to the list they narrow instead of in a sidebar. In React, Base UI handles opening, dismissing and focus.

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.

FAQ

How are the status checkboxes built?

statuses lists Active, Pending and Archived. Each row is a Field with orientation="horizontal", a Checkbox named status with the status as its value, and a FieldLabel. The checkbox id is filter- plus the value, and the label's htmlFor matches it.

Which filter starts checked?

Active, whose entry has checked: true. Pending and Archived start unchecked. The checkboxes take it as their starting value only, so they stay uncontrolled. The prop is defaultChecked on Checkbox.

How do I close this panel from code?

Apply Filters closes the panel. Here the panel is controlled: open and onOpenChange on Popover, and the button's handler sets the state to false. The callback gets the next open state first.

How does the Filter button become the trigger?

The trigger is a Button with variant="outline". FilterIcon has aria-hidden="true" and data-icon="inline-start", and the label is Filter. PopoverContent is w-80 max-w-full, and PopoverTitle reads Filter Options. Pass the button to render on PopoverTrigger, and use PopoverContent as the panel.

What does Apply Filters change on the page?

Nothing yet: it closes the panel, and nothing reads the checkboxes. Read their values, or control them, to filter your data. The button is size="sm" and w-full.

How does this panel dismiss?

Escape closes the panel and returns focus to the trigger. A click outside closes it too. The panel sits beside the button, and the rest of the page stays usable.