21st

ReUI Filters

Component 2

About

ReUI Filters with the first 10 official ReUI examples, preserved from the MIT-licensed source registry.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds ReUI Filters to your project and fits it to your theme.

Code

How ReUI Filters is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import { ClockIcon, CircleAlertIcon, CircleCheckIcon, BanIcon, CircleIcon, StarIcon, TagIcon, MailIcon, GlobeIcon, ListFilterIcon } from "lucide-react"
"use client"

import { useCallback, useState } from "react"
import {
  createFilter,
  Filters,
  type Filter,
  type FilterFieldConfig,
} from "@/components/ui/reui-filters"

import { Button } from "@/components/ui/reui-filters-utils/button"

const StatusIcon = ({ status }: { status: string }) => {
  switch (status) {
    case "todo":
      return (
        <ClockIcon className="text-primary" />
      )
    case "in-progress":
      return (
        <CircleAlertIcon className="text-yellow-500" />
      )
    case "done":
      return (
        <CircleCheckIcon className="text-green-500" />
      )
    case "cancelled":
      return (
        <BanIcon className="text-destructive" />
      )
    default:
      return (
        <CircleIcon className="text-muted-foreground" />
      )
  }
}

// Priority icon component
const PriorityIcon = ({ priority }: { priority: string }) => {
  const colors = {
    low: "text-green-500",
    medium: "text-yellow-500",
    high: "text-orange-500",
    urgent: "text-red-500",
  }
  return (
    <StarIcon />
  )
}

export default function Pattern() {
  // Basic filter fields for size variant demo
  const fields: FilterFieldConfig[] = [
    {
      key: "text",
      label: "Text",
      icon: (
        <TagIcon className="size-3.5" />
      ),
      type: "text",
      className: "w-36",
      placeholder: "Search text...",
    },
    {
      key: "email",
      label: "Email",
      icon: (
        <MailIcon className="size-3.5" />
      ),
      type: "text",
      className: "w-48",
      placeholder: "user@example.com",
    },
    {
      key: "website",
      label: "Website",
      icon: (
        <GlobeIcon className="size-3.5" />
      ),
      type: "text",
      className: "w-40",
      placeholder: "https://example.com",
    },
    {
      key: "status",
      label: "Status",
      icon: (
        <ClockIcon className="size-3.5" />
      ),
      type: "select",
      searchable: false,
      className: "w-[200px]",
      options: [
        { value: "todo", label: "To Do", icon: <StatusIcon status="todo" /> },
        {
          value: "in-progress",
          label: "In Progress",
          icon: <StatusIcon status="in-progress" />,
        },
        { value: "done", label: "Done", icon: <StatusIcon status="done" /> },
        {
          value: "cancelled",
          label: "Cancelled",
          icon: <StatusIcon status="cancelled" />,
        },
      ],
    },
    {
      key: "priority",
      label: "Priority",
      icon: (
        <CircleAlertIcon className="size-3.5" />
      ),
      type: "multiselect",
      className: "w-[180px]",
      options: [
        { value: "low", label: "Low", icon: <PriorityIcon priority="low" /> },
        {
          value: "medium",
          label: "Medium",
          icon: <PriorityIcon priority="medium" />,
        },
        {
          value: "high",
          label: "High",
          icon: <PriorityIcon priority="high" />,
        },
        {
          value: "urgent",
          label: "Urgent",
          icon: <PriorityIcon priority="urgent" />,
        },
      ],
    },
  ]

  const [smallFilters, setSmallFilters] = useState<Filter[]>([
    createFilter("priority", "is_any_of", ["high", "urgent"]),
  ])

  const [mediumFilters, setMediumFilters] = useState<Filter[]>([
    createFilter("status", "is", ["todo"]),
  ])

  const [largeFilters, setLargeFilters] = useState<Filter[]>([
    createFilter("email", "contains", ["example@example.com"]),
  ])

  const handleSmallFiltersChange = useCallback((filters: Filter[]) => {
    setSmallFilters(filters)
  }, [])

  const handleMediumFiltersChange = useCallback((filters: Filter[]) => {
    setMediumFilters(filters)
  }, [])

  const handleLargeFiltersChange = useCallback((filters: Filter[]) => {
    setLargeFilters(filters)
  }, [])

  return (
    <div className="flex w-full max-w-[850px] flex-col items-start gap-2.5 space-y-6">
      <Filters
        size="sm"
        filters={smallFilters}
        fields={fields}
        onChange={handleSmallFiltersChange}
        trigger={
          <Button variant="outline" size="icon-sm">
            <ListFilterIcon />
          </Button>
        }
      />
    </div>
  )
}

Dependencies

More by 21st

View all
  • Futuristic Hero

    Futuristic Hero

    2.7K
  • Hero ASCII one

    Hero ASCII one

    1.4K
  • Hero ASCII

    Hero ASCII

    1.3K
  • Admit One Ticket

    Admit One Ticket

    961
  • Navigation Menu

    Navigation Menu

    916
  • Border Beam

    Border Beam

    890
  • Border Beam Search

    Border Beam Search

    545
  • Thinking Orbs

    Thinking Orbs

    438