Filter

A faceted filter component for selecting and displaying multiple filter options.

Anatomy

<FilterFaceted.Root>
  <FilterFaceted.Trigger />
  <FilterFaceted.Content>
    <FilterFaceted.Input />
    <FilterFaceted.Empty />
    <FilterFaceted.List>
      <FilterFaceted.Option />
    </FilterFaceted.List>
    <FilterFaceted.Separator />
    <FilterFaceted.Footer />
  </FilterFaceted.Content>
</FilterFaceted.Root>
<DataFilters.Root>
  <DataFilters.Items>
    <DataFilters.Item />
  </DataFilters.Items>
  <DataFilters.Separator />
  <DataFilters.Clear />
</DataFilters.Root>

Usage

import { Filter } from '@ivaldi/ui'
const options = [
  { value: 'pending', label: 'Pending', count: 12 },
  { value: 'processing', label: 'Processing', count: 3 },
  { value: 'completed', label: 'Completed', count: 8 }
]

return (
  <FilterFaceted.Root>
    <FilterFaceted.Trigger asChild>
      <Button variant="outline">Status</Button>
    </FilterFaceted.Trigger>
    <FilterFaceted.Content>
      <FilterFaceted.Input placeholder="Search status..." />
      <FilterFaceted.List>
        {options.map((option) => (
          <FilterFaceted.Option 
            key={option.value}
            value={option.value}
            count={option.count}
          >
            {option.label}
          </FilterFaceted.Option>
        ))}
      </FilterFaceted.List>
    </FilterFaceted.Content>
  </FilterFaceted.Root>
)

With Data Filters

const [filters, setFilters] = useState<string[]>([])

return (
  <DataFilters.Root value={filters} onValueChange={setFilters}>
    <DataFilters.Items>
      {filters.map((filter) => (
        <DataFilters.Item key={filter} value={filter}>
          {filter}
        </DataFilters.Item>
      ))}
    </DataFilters.Items>
    {filters.length > 0 && (
      <>
        <DataFilters.Separator />
        <DataFilters.Clear>Reset filters</DataFilters.Clear>
      </>
    )}
  </DataFilters.Root>
)

With Color Indicators

const options = [
  { value: 'low', label: 'Low Priority', count: 12, color: 'success' },
  { value: 'medium', label: 'Medium Priority', count: 3, color: 'warning' },
  { value: 'high', label: 'High Priority', count: 8, color: 'danger' }
]

return (
  <FilterFaceted.Root>
    <FilterFaceted.Trigger asChild>
      <Button variant="outline">Priority</Button>
    </FilterFaceted.Trigger>
    <FilterFaceted.Content>
      <FilterFaceted.List>
        {options.map((option) => (
          <FilterFaceted.Option 
            key={option.value}
            value={option.value}
            count={option.count}
            color={option.color}
          >
            <div className="flex items-center gap-2">
              <div className={cn(
                'size-2 rounded-full',
                option.color === 'success' && 'bg-success-solid',
                option.color === 'warning' && 'bg-warning-solid',
                option.color === 'danger' && 'bg-danger-solid'
              )} />
              {option.label}
            </div>
          </FilterFaceted.Option>
        ))}
      </FilterFaceted.List>
    </FilterFaceted.Content>
  </FilterFaceted.Root>
)

With Custom Icons

const options = [
  { value: 'inbox', label: 'Inbox', icon: InboxIcon, count: 12 },
  { value: 'sent', label: 'Sent', icon: SendIcon, count: 3 },
  { value: 'draft', label: 'Draft', icon: FileIcon, count: 8 }
]

return (
  <FilterFaceted.Root>
    <FilterFaceted.Trigger asChild>
      <Button variant="outline">Mail</Button>
    </FilterFaceted.Trigger>
    <FilterFaceted.Content>
      <FilterFaceted.List>
        {options.map((option) => (
          <FilterFaceted.Option 
            key={option.value}
            value={option.value}
            count={option.count}
          >
            <div className="flex items-center gap-2">
              <option.icon className="size-4" />
              {option.label}
            </div>
          </FilterFaceted.Option>
        ))}
      </FilterFaceted.List>
    </FilterFaceted.Content>
  </FilterFaceted.Root>
)

FilterData.sComposed Props

PropTypeDefault
filtersDataFilter<Datum>[]—
tableTable<Datum>—
compressedboolean—
filterState*FilterState—
setFilterState*Dispatch<FilterAction>—

Filter.FacetedComposed Props

PropTypeDefault
labelstring—
icontrue | LucideIcon—
value*string[]—
onValueChangefunction—
options*T[]—
buttonPropsany"{}"
asBadgeboolean—

Filter.FacetedRoot Props

PropTypeDefault
childrenReactNode—
openboolean—
defaultOpenboolean—
onOpenChangefunction—
modalboolean—

FilterData. Props

PropTypeDefault
filter*DataFilter<Datum>—
compressedboolean—
index*number—
statestring | boolean | string[]—
setState*function—
setFilterState*Dispatch<FilterAction>—
tableTable<Datum>—

Filter Props

PropTypeDefault
filter*DataFilter<Datum>—
compressedboolean—
index*number—
statestring | boolean | string[]—
setState*function—
setFilterState*Dispatch<FilterAction>—
tableTable<Datum>—

Filter.FacetedButton Props

PropTypeDefault

Filter.FacetedOption Props

PropTypeDefault
childrenReactNode—
classNamestring—
asChildboolean—
disabledboolean—
onSelectfunction—
valuestring—
keywordsstring[]—
forceMountboolean—
countnumber—
checkedboolean—

Filter.FacetedOptions Props

PropTypeDefault
panelPropsany—
arrowboolean—
forceMounttrue—
classNamestring—
childrenReactNode—
asChildboolean—
sideenum—
sideOffsetnumber"4"
alignenum—
alignOffsetnumber—
arrowPaddingnumber—
avoidCollisionsboolean—
collisionBoundaryElement | Element[]—
collisionPaddingsee more—
stickyenum—
hideWhenDetachedboolean—
updatePositionStrategyenum—
onEscapeKeyDownfunction—
onPointerDownOutsidefunction—
onFocusOutsidefunction—
onInteractOutsidefunction—
onOpenAutoFocusfunction—
onCloseAutoFocusfunction—
placeholderstring—
onValueChangefunction—
valuestring[]—

Filter.FacetedTrigger Props

PropTypeDefault
typeenum—
classNamestring—
childrenReactNode—
asChildboolean—

Filter.FacetedVirtualized Props

PropTypeDefault
classNamestring—
labelstring—
icontrue | LucideIcon—
value*string[]—
onValueChangefunction—
itemSearchTermfunction"(item) => item.value"
estimateSizefunction"() => 32"
options*T[]—
buttonPropsany"{}"
asBadgeboolean—

Filter.s Props

PropTypeDefault
filtersDataFilter<Datum>[]—
tableTable<Datum>—
compressedboolean—
filterState*FilterState—
setFilterState*Dispatch<FilterAction>—