All componentsform
Filter Bar
Status: OpenAssignee: MeLabel: bug
Installation
$ npx shadcn@latest add https://deepmoon.dev/r/filter-bar.jsonnpm dependencies: lucide-react
Props
FilterBarProps
| Prop | Type | Required |
|---|---|---|
| filters | FilterChip[] | Yes |
| onRemove | (id: string) => void | Yes |
| onClearAll | () => void | No |
Code
filter-bar.tsx
import * as React from "react";
import { X } from "lucide-react";
import { cn } from "@/lib/utils";
export interface FilterChip {
id: string;
label: string;
}
export interface FilterBarProps extends React.ComponentPropsWithoutRef<"div"> {
filters: FilterChip[];
onRemove: (id: string) => void;
onClearAll?: () => void;
}
export function FilterBar({ filters, onRemove, onClearAll, className, ...props }: FilterBarProps) {
if (filters.length === 0) return null;
return (
<div role="group" aria-label="Active filters" className={cn("flex flex-wrap items-center gap-2", className)} {...props}>
{filters.map((filter) => (
<span
key={filter.id}
className="flex items-center gap-1 rounded-full border border-border bg-secondary py-1 pl-3 pr-1.5 text-xs font-medium text-secondary-foreground"
>
{filter.label}
<button
type="button"
onClick={() => onRemove(filter.id)}
aria-label={`Remove ${filter.label} filter`}
className="rounded-full p-0.5 text-secondary-foreground/70 outline-none hover:bg-secondary-foreground/10 hover:text-secondary-foreground focus-visible:ring-1 focus-visible:ring-ring"
>
<X className="size-3" aria-hidden="true" />
</button>
</span>
))}
{onClearAll ? (
<button
type="button"
onClick={onClearAll}
className="text-xs font-medium text-muted-foreground outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring"
>
Clear all
</button>
) : null}
</div>
);
}