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-systemIn 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
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | React.ReactNode | — |
...props | React.ComponentProps<'section'> | — |
| Data attribute | Values |
|---|---|
data-slot | horizontal-filters |
HorizontalFiltersControls
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | React.ReactNode | — |
...props | React.ComponentProps<'div'> | — |
| Data attribute | Values |
|---|---|
data-slot | horizontal-filters-controls |
HorizontalFiltersActions
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | React.ReactNode | — |
...props | React.ComponentProps<'div'> | — |
| Data attribute | Values |
|---|---|
data-slot | horizontal-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-overflowHorizontal 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-scrollLearn more about registry setup and authentication in Registry.