Acronis UIKit
Legacy (shadcn-uikit)Components

Filter

A control for narrowing down content by applying filter criteria.

Usage

import { Filter } from '@acronis-platform/shadcn-uikit';

Basic

A simple filter button.

View source
import { Filter } from '@acronis-platform/shadcn-uikit/react';

export function FilterBasic() {
  return (
    <div className="flex gap-4">
      <Filter />
      <Filter>Custom Label</Filter>
      <Filter>Apply Filters</Filter>
    </div>
  );
}

With counter

A filter showing the count of active criteria.

View source
import { Filter } from '@acronis-platform/shadcn-uikit/react';

export function FilterWithCounter() {
  return (
    <div className="flex gap-4 flex-wrap">
      <Filter count={0}>No Filters</Filter>
      <Filter count={1}>Filter</Filter>
      <Filter count={3}>Filter</Filter>
      <Filter count={5}>Filter</Filter>
      <Filter count={12}>Filter</Filter>
      <Filter count={99}>Filter</Filter>
    </div>
  );
}

Active state

A filter in its active/applied state.

View source
import { Filter } from '@acronis-platform/shadcn-uikit/react';

export function FilterActiveState() {
  return (
    <div className="flex gap-4">
      <Filter active={false}>Inactive</Filter>
      <Filter active={true} count={3}>
        Active
      </Filter>
    </div>
  );
}

Variants

Different visual variants of the filter component.

View source
import { Filter } from '@acronis-platform/shadcn-uikit/react';

export function FilterVariants() {
  return (
    <div className="flex gap-4 flex-wrap">
      <Filter variant="ghost" count={3}>
        Ghost
      </Filter>
      <Filter variant="outline" count={3}>
        Outline
      </Filter>
      <Filter variant="default" count={3}>
        Default
      </Filter>
    </div>
  );
}

Interactive

An interactive filter with toggle behavior.

Product List

Quick Filters

View source
import * as React from 'react';
import { Filter } from '@acronis-platform/shadcn-uikit/react';
import { Button } from '@acronis-platform/shadcn-uikit/react';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@acronis-platform/shadcn-uikit/react';

export function FilterInteractive() {
  const [activeFilters, setActiveFilters] = React.useState<string[]>([]);

  const toggleFilter = (filter: string) => {
    setActiveFilters((prev) =>
      prev.includes(filter)
        ? prev.filter((f) => f !== filter)
        : [...prev, filter]
    );
  };

  const clearAllFilters = () => {
    setActiveFilters([]);
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center justify-between">
          <span>Product List</span>
          <div className="flex gap-2">
            <Filter
              count={activeFilters.length}
              active={activeFilters.length > 0}
            >
              Filters
            </Filter>
            {activeFilters.length > 0 && (
              <Button variant="ghost" size="sm" onClick={clearAllFilters}>
                Clear All
              </Button>
            )}
          </div>
        </CardTitle>
      </CardHeader>
      <CardContent>
        <div className="space-y-4">
          <div>
            <h4 className="text-sm font-semibold mb-2">Quick Filters</h4>
            <div className="flex gap-2 flex-wrap">
              {['New', 'Popular', 'On Sale', 'In Stock', 'Featured'].map(
                (filter) => (
                  <Button
                    key={filter}
                    variant={
                      activeFilters.includes(filter) ? 'default' : 'outline'
                    }
                    size="sm"
                    onClick={() => toggleFilter(filter)}
                  >
                    {filter}
                  </Button>
                )
              )}
            </div>
          </div>
          {activeFilters.length > 0 && (
            <div className="p-4 bg-muted rounded-md">
              <p className="text-sm">
                <strong>Active Filters:</strong> {activeFilters.join(', ')}
              </p>
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  );
}

With dropdown

A filter that opens a dropdown for selecting criteria.

View source
import * as React from 'react';
import { Filter } from '@acronis-platform/shadcn-uikit/react';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
  DropdownMenuCheckboxItem,
} from '@acronis-platform/shadcn-uikit/react';

export function FilterWithDropdown() {
  const [statusFilters, setStatusFilters] = React.useState<string[]>([]);

  const toggleStatusFilter = (status: string) => {
    setStatusFilters((prev) =>
      prev.includes(status)
        ? prev.filter((s) => s !== status)
        : [...prev, status]
    );
  };

  return (
    <DropdownMenu>
      <DropdownMenuTrigger
        render={
          <Filter
            count={statusFilters.length}
            active={statusFilters.length > 0}
          />
        }
      >
        Status
      </DropdownMenuTrigger>
      <DropdownMenuContent className="w-56">
        <DropdownMenuLabel>Filter by Status</DropdownMenuLabel>
        <DropdownMenuSeparator />
        <DropdownMenuCheckboxItem
          checked={statusFilters.includes('active')}
          onCheckedChange={() => toggleStatusFilter('active')}
        >
          Active
        </DropdownMenuCheckboxItem>
        <DropdownMenuCheckboxItem
          checked={statusFilters.includes('pending')}
          onCheckedChange={() => toggleStatusFilter('pending')}
        >
          Pending
        </DropdownMenuCheckboxItem>
        <DropdownMenuCheckboxItem
          checked={statusFilters.includes('completed')}
          onCheckedChange={() => toggleStatusFilter('completed')}
        >
          Completed
        </DropdownMenuCheckboxItem>
        <DropdownMenuCheckboxItem
          checked={statusFilters.includes('cancelled')}
          onCheckedChange={() => toggleStatusFilter('cancelled')}
        >
          Cancelled
        </DropdownMenuCheckboxItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

Multiple groups

Multiple filter groups for complex filtering scenarios.

Advanced Filtering
View source
import * as React from 'react';
import { Filter } from '@acronis-platform/shadcn-uikit/react';
import { Button } from '@acronis-platform/shadcn-uikit/react';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@acronis-platform/shadcn-uikit/react';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
  DropdownMenuCheckboxItem,
} from '@acronis-platform/shadcn-uikit/react';

export function FilterMultipleGroups() {
  const [statusFilters, setStatusFilters] = React.useState<string[]>([]);
  const [categoryFilters, setCategoryFilters] = React.useState<string[]>([]);

  const toggleStatusFilter = (status: string) => {
    setStatusFilters((prev) =>
      prev.includes(status)
        ? prev.filter((s) => s !== status)
        : [...prev, status]
    );
  };

  const toggleCategoryFilter = (category: string) => {
    setCategoryFilters((prev) =>
      prev.includes(category)
        ? prev.filter((c) => c !== category)
        : [...prev, category]
    );
  };

  const clearAllFilters = () => {
    setStatusFilters([]);
    setCategoryFilters([]);
  };

  const totalFilters = statusFilters.length + categoryFilters.length;

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center justify-between">
          <span>Advanced Filtering</span>
          <div className="flex gap-2 items-center">
            <Filter count={totalFilters} active={totalFilters > 0}>
              All Filters
            </Filter>
            {totalFilters > 0 && (
              <Button variant="ghost" size="sm" onClick={clearAllFilters}>
                Clear All
              </Button>
            )}
          </div>
        </CardTitle>
      </CardHeader>
      <CardContent>
        <div className="space-y-6">
          <div className="flex gap-2 flex-wrap">
            <DropdownMenu>
              <DropdownMenuTrigger
                render={
                  <Filter
                    count={statusFilters.length}
                    active={statusFilters.length > 0}
                  />
                }
              >
                Status
              </DropdownMenuTrigger>
              <DropdownMenuContent className="w-56">
                <DropdownMenuLabel>Filter by Status</DropdownMenuLabel>
                <DropdownMenuSeparator />
                {['Active', 'Pending', 'Completed', 'Cancelled'].map(
                  (status) => (
                    <DropdownMenuCheckboxItem
                      key={status}
                      checked={statusFilters.includes(status.toLowerCase())}
                      onCheckedChange={() =>
                        toggleStatusFilter(status.toLowerCase())
                      }
                    >
                      {status}
                    </DropdownMenuCheckboxItem>
                  )
                )}
              </DropdownMenuContent>
            </DropdownMenu>

            <DropdownMenu>
              <DropdownMenuTrigger
                render={
                  <Filter
                    count={categoryFilters.length}
                    active={categoryFilters.length > 0}
                  />
                }
              >
                Category
              </DropdownMenuTrigger>
              <DropdownMenuContent className="w-56">
                <DropdownMenuLabel>Filter by Category</DropdownMenuLabel>
                <DropdownMenuSeparator />
                {[
                  'Electronics',
                  'Clothing',
                  'Books',
                  'Home & Garden',
                  'Sports',
                ].map((category) => (
                  <DropdownMenuCheckboxItem
                    key={category}
                    checked={categoryFilters.includes(category.toLowerCase())}
                    onCheckedChange={() =>
                      toggleCategoryFilter(category.toLowerCase())
                    }
                  >
                    {category}
                  </DropdownMenuCheckboxItem>
                ))}
              </DropdownMenuContent>
            </DropdownMenu>
          </div>

          {totalFilters > 0 && (
            <div className="p-4 bg-muted rounded-md space-y-2">
              {statusFilters.length > 0 && (
                <p className="text-sm">
                  <strong>Status:</strong> {statusFilters.join(', ')}
                </p>
              )}
              {categoryFilters.length > 0 && (
                <p className="text-sm">
                  <strong>Category:</strong> {categoryFilters.join(', ')}
                </p>
              )}
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  );
}

In toolbar

Filters integrated into a toolbar layout.

Showing 24 of 156 items
View source
import { Filter } from '@acronis-platform/shadcn-uikit/react';
import { Button } from '@acronis-platform/shadcn-uikit/react';

export function FilterInToolbar() {
  return (
    <div className="flex items-center justify-between p-4 border rounded-lg">
      <div className="flex gap-2">
        <Filter count={3}>Filters</Filter>
        <Button variant="outline" size="sm">
          Sort
        </Button>
        <Button variant="outline" size="sm">
          Export
        </Button>
      </div>
      <div className="text-sm text-muted-foreground">
        Showing 24 of 156 items
      </div>
    </div>
  );
}

Disabled state

Disabled filters that cannot be interacted with.

View source
import { Filter } from '@acronis-platform/shadcn-uikit/react';

export function FilterDisabled() {
  return (
    <div className="flex gap-4">
      <Filter disabled>Disabled</Filter>
      <Filter disabled count={3}>
        Disabled with Count
      </Filter>
    </div>
  );
}

API Reference

Filter

Prop

Type

Edit on GitHub

On this page