Filter

PreviousNext

A styled checkbox component for filtering content, with support for dropdown indicators, validation states, and error messages

'use client';

import { Filter } from '@/ui/forms/Filter';
import { Icon } from '@clubmed/trident-icons';

export function FilterDemo() {
  return (
    <Filter checked={false}>
      <div className="flex items-center gap-x-8">
        <Icon name="Filters" />
        Category Filter
      </div>
    </Filter>
  );
}

Installation

npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/filter.json

Usage

'use client';
 
import { useState } from 'react';
import { Filter } from '@/docs/lib/ui/forms/filter';
 
export function Component() {
  const [filters, setFilters] = useState<Record<string, boolean>>({
    category: false,
  });
 
  const handleFilterChange = (name: string, value: boolean | null) => {
    setFilters((prev) => ({ ...prev, [name]: value !== null }));
  };
 
  return (
    <Filter name="category" checked={filters.category} onChange={handleFilterChange}>
      Category Filter
    </Filter>
  );
}

API Reference

Filter

PropTypeDefaultDescription
childrenReactNodeundefinedThe label text or content to display inside the filter button
checkedbooleanfalseWhether the filter is currently selected/checked
hasDropdownbooleanundefinedWhen true, displays a dropdown arrow icon next to the check icon
onChange(name: string, value: Value | null) => voidundefinedCallback function triggered when the filter state changes. Receives the name and new value
valueValueundefinedThe value associated with this filter when checked. Defaults to the checked state if not provided
namestringidName attribute for the underlying checkbox input. Defaults to the id prop
idstringautoUnique identifier for the filter. Auto-generated using useId() if not provided
disabledbooleanfalseWhen true, prevents user interaction and applies disabled styling
tabIndexnumber0Controls the tab order for keyboard navigation
validationStatus"default" | "error" | "success""default"Visual state of the filter. Use "error" to display error messages
errorMessagestringundefinedError message to display when validationStatus is "error" and not disabled
dataTestIdstringundefinedCustom data-testid attribute for testing purposes
classNamestringundefinedAdditional CSS classes to apply to the outer container div
labelReactNodeundefinedOptional label element (from FormControlProps, though not commonly used for Filter)
descriptionstringundefinedOptional description text (from FormLabelProps)
requiredbooleanundefinedMarks the filter as required (from FormLabelProps)
hideRequiredStarbooleanundefinedHides the required star indicator (from FormLabelProps)
layout"horizontal" | "vertical" | "horizontal-${string}"undefinedLayout orientation for the label (from FormLabelProps)

The Filter component also supports all standard HTML input attributes via InputHTMLAttributes<HTMLInputElement>.

Notes

  • Checkbox-based: Filter is built on a native checkbox input, providing proper semantics and keyboard accessibility out of the box
  • Check icon: When checked, displays a check icon (CheckDefault) to indicate the selected state
  • Dropdown indicator: Set hasDropdown={true} to show an arrow icon, useful when the filter opens a dropdown menu
  • Validation states: Supports "default", "error", and "success" states. Error messages are automatically hidden when disabled
  • Error display: Error messages appear below the filter with an error icon and role="alert" for accessibility
  • Value handling: The onChange callback receives either the specified value (when checked) or null (when unchecked)
  • State management: Uses the internal useValue hook to manage checked state and coordinate with the onChange callback
  • Disabled state: When disabled, prevents clicks and hides error messages. Error state is automatically converted to disabled state internally
  • Data attributes: Includes data-name="Filter" for styling and data-testid for testing
  • Keyboard support: Fully keyboard accessible with configurable tabIndex
  • Client component: This is a client component that requires the "use client" directive due to state management and event handlers