Skip to content

Filter Panel

Card of grouped chips that folds away behind a round button on narrow screens.

From the Findit template — see it in context

Explore : Queens

Pick a type, a category and an area — each filter is a page of its own.

Type

Category

Location

Installation

$ npx shadcn@latest add https://framebrick.co/r/filter-panel.json

Usage

import { FilterPanel } from "@/components/ui/filter-panel";

<FilterPanel
  title="Explore : Queens"
  description="Pick a type, a category and an area."
  groups={[
    { label: "Type", items: [{ label: "House", href: "/houses", active: true }, { label: "Studio", href: "/studios" }] },
    { label: "Category", items: [{ label: "For sale", href: "/for-sale" }] },
  ]}
/>

Props

PropTypeDefaultDescription
groups{ label, items: { label, href?, onClick?, active? }[] }[]—The groups of chips. A chip with `href` is a link (its own page), otherwise a button.
titleReactNode—Heading at the top of the card.
descriptionReactNode—One line under the heading.
openFrom768 | 1024 | 12801024Width from which the panel is always open.
stickybooleantrueStick to the top while the list beside it scrolls, where the panel is always open.
stickyTopnumber120Distance from the top while stuck, in px.
showLabel / hideLabelstring—Accessible names of the round button.
  • The chips are rendered once: the same panel folds, instead of a second copy for narrow screens, so filter links are not in the page twice.
  • The server renders it open, so the chips are in the HTML for search engines; a closed panel is inert, so keyboards and screen readers skip it.
  • Chip colours ease over 0.4 s, as in Framer.

AI prompt

Paste into v0, Lovable, Bolt or Claude to rebuild this component in your own project.

Create a React + Tailwind CSS + Motion (motion/react) component called FilterPanel.
- A card (rounded-lg, 1px border, bg-card, p-5) holding an optional title and description, then groups of chips.
- Each group: a small uppercase muted heading (role group + aria-labelledby) and pill chips, text-sm font-medium,
  px-4 py-1.5: active bg-primary text-primary-foreground, otherwise bg-secondary with a hover that fills them,
  colours transitioning over 400ms ease-out. A chip with href is a Next.js Link with aria-current, otherwise a button
  with aria-pressed.
- From `openFrom` (default 1024px) up the panel is always open and may stick to the top of the window.
  Below that, the groups collapse behind a round primary button holding a caret, centred between two hairlines;
  the caret rotates 180° when open.
- The panel animates height 0 → auto with a spring (bounce 0, 0.4s) and fades its content in 0.25s after a 0.1s delay.
- Render the chips once and fold that same panel; decide "wide" with useSyncExternalStore over
  matchMedia(min-width) whose server snapshot is true, so the server renders it open and a closed panel is inert.
- Accessibility: aria-expanded and aria-controls on the button, an aria-label that says show or hide.

Be the first to know

Get new templates and components first

One short email when we release a template or a free component. No spam — unsubscribe anytime.

We use your email only for Framebrick updates. Privacy policy