Experience System

Horizontal Filters

Composable horizontal filter layout primitives for page-level filtering, with dedicated slots for filter controls and actions.

Not applied yet

Installation

The component is exported from @by/experience-system. Add the package with your package manager:

pnpm add @by/experience-system

In this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.

Composition

Use the following composition to build a horizontal filter bar:

HorizontalFilters
├── HorizontalFiltersControls
│   └── Filter controls (Select, Input, Combobox, etc.)
└── HorizontalFiltersActions (optional)
    └── Action controls (Reset, Apply, custom actions)

HorizontalFiltersControls is the primary slot for filter fields. HorizontalFiltersActions is optional and aligns action controls to the end of the row. Compose with other Experience System form and action primitives such as Select, Input, and Button.

Usage

import {
  Button,
  HorizontalFilters,
  HorizontalFiltersActions,
  HorizontalFiltersControls,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@by/experience-system';

HorizontalFilters and its slot components are client components ('use client' in the package). Use them inside a Client Component or a dynamic import when using the Next.js App Router.

<HorizontalFilters>
  <HorizontalFiltersControls>
    <Select defaultValue="USA">
      <SelectTrigger className="w-scaled-40" aria-label="Country">
        <SelectValue placeholder="Select country" />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="USA">USA</SelectItem>
        <SelectItem value="Canada">Canada</SelectItem>
      </SelectContent>
    </Select>
  </HorizontalFiltersControls>

  <HorizontalFiltersActions>
    <Button variant="ghost" size="sm">Reset</Button>
    <Button variant="fill" size="sm">Apply</Button>
  </HorizontalFiltersActions>
</HorizontalFilters>

When to use

  • Dense page-level filters where users need to combine multiple criteria quickly.
  • Compositions that should keep filter inputs and actions visually grouped.
  • Layouts that need full control over action behavior (your own Reset/Apply handlers).

When not to use

  • Long, multi-step forms where vertical form structure is clearer.
  • Advanced query builders with nested rules and logical operators.
  • Cases where a single filter control is enough and wrapper layout is unnecessary.

Examples

Overview

A baseline horizontal filter composition with three selects and Reset/Apply actions.

Not applied yet

API Reference

These primitives are layout wrappers around semantic HTML elements. All standard DOM props are forwarded to the rendered element for each export.

HorizontalFilters

PropTypeDefault
classNamestring
childrenReact.ReactNode
...propsReact.ComponentProps<'section'>
Data attributeValues
data-slothorizontal-filters

HorizontalFiltersControls

PropTypeDefault
classNamestring
childrenReact.ReactNode
...propsReact.ComponentProps<'div'>
Data attributeValues
data-slothorizontal-filters-controls

HorizontalFiltersActions

PropTypeDefault
classNamestring
childrenReact.ReactNode
...propsReact.ComponentProps<'div'>
Data attributeValues
data-slothorizontal-filters-actions

Accessibility

Horizontal Filters is a layout primitive and does not apply field semantics on its own. Ensure each control inside HorizontalFiltersControls has an accessible name (for example through Label, aria-label, or aria-labelledby), and ensure action buttons in HorizontalFiltersActions use descriptive text or aria-label values.

Source in the repo: packages/experience-system/src/components/HorizontalFilters/HorizontalFilters.tsx. Agent-oriented contracts: packages/experience-system/src/components/HorizontalFilters/HorizontalFilters.instructions.md.

Registry examples

These @by-es items are registry-only composites built on top of HorizontalFilters. Live previews below show the recipe behavior, and View code shows the full registry recipe implementation. See Registry for components.json setup and REGISTRY_TOKEN.

Horizontal Filter With Overflow

Horizontal filter bar with three visible filters, a 3-dot overflow trigger, and three additional filters presented in a dialog. Built with HorizontalFilters, Select, Dialog, and Button from @by/experience-system.

Not applied yet

After shadcn add, import HorizontalFilterWithOverflow from your generated registry path (for example @/components/ui/horizontal-filter-with-overflow).

npx shadcn@latest add @by-es/horizontal-filter-with-overflow

Horizontal Filter With Overflow Scroll

Horizontal filter bar that keeps all filters in one row and reveals overflow through left/right chevron scroll controls. Built with HorizontalFilters, Select, and Button from @by/experience-system.

Not applied yet

After shadcn add, import HorizontalFilterWithOverflowScroll from your generated registry path (for example @/components/ui/horizontal-filter-with-overflow-scroll).

npx shadcn@latest add @by-es/horizontal-filter-with-overflow-scroll

Learn more about registry setup and authentication in Registry.