Skip to content
Mendy UI

Filters

Filter behavior and defaults

What a new project gets from Filters, and what its definitions need to supply.

On this page

Start with defineFilters, a state hook, and <FilterBar filters={filters} />. You do not need a provider or custom CSS to get the standard interactions. The demos use these defaults.

Included behavior

InteractionDefaultOverride
Desktop menuList matches the search width; each editor sits beside its row at its own height, moving upward when neededMendyUIProvider menuLayout="connected" for a full-height attached editor
Phone menuOne panel, with Back from the editor to the listAutomatic below 640px
Opening the menuShows the list without opening the first filterHover previews; click, Enter, Space, or the entry arrow enters an editor
Hover and focusPreview leaves input focus alone; an active input is protected from incidental hoverCustom editors receive autoFocus
Applying in the menuApplies immediately and keeps the menu opencloseMenuOnApply on the bar or a field
Single choiceSelecting the current value again clears it; no synthetic "Any" optionclearValue and removable: false
Option searchIntegrated search row, enabled by defaultsearchable: false for short lists
Text and tokensEnter saves; closing discards unapplied textCustom editor or low-level commitMode="apply"
DatesOne click applies a day; the next extends a rangeCustom calendar or editor
SuggestionsFirst click applies the preset; second click edits it; other suggestions remainsuggestions="when-empty" or "never"
Selected labelsSkeleton while unresolved; known labels survive refetches; settled missing values fall back to IDsSupply query loading state and selected records
Choice chip labelsSelected option labels only; field name remains in accessible labelschipLabel: true or a shorter string
Text, token, date, and range chip labelsField name followed by the valuechipLabel: false or a shorter string
Long selectionsThree values, then "and N more"Global or per-field summary
ClearingEach chip has a remove button; Clear all follows active removable filters and clears filters plus search. Search-only bars use the input clear controlremovable: false, showClear={false}, or a separately placed FilterClear
MotionChip entrance stagger; instant menus and editor popupseditorAnimation opts chip popups into animation; reduced motion disables chip movement
DismissalOutside click closes and reaches the underlying page; Escape restores trigger focusCustom composition can supply focus callbacks
Large listsMeasured virtualization above 100 rows; Find a filter above 20 categoriesPaginate remote data to limit downloads
AppearanceCompact desktop rows, larger touch targets, shadcn colors, application font and radiusTheme tokens, named classes, component replacements

Editing an applied chip is a separate flow: single choice and Enter-saved text close on completion; multi-select, dates, and number ranges stay open. Clearing a chip closes its editor and moves focus to the filter trigger. Switching directly to another chip opens that chip without an intervening dismissal.

Configure once for your data

The package supplies the interaction. A definition tells it what a value means:

  • Data sources. Supply an array, externalOptions for your existing query hooks, or remoteOptions for package-managed requests. Provide loading state and a way to resolve selected IDs outside the current page.
  • Recognized input. Add recognize to fields such as issue IDs or email addresses. Use menu: false when recognition makes a menu entry unnecessary. Parsing, merging, validation, ambiguity handling, and chip editing are shared.
  • Groups. List related field IDs in groups; use separatorBefore to separate categories. menuLayout: "inline" places an editor beside its label inside a group; single-choice fields use compact toggle buttons.
  • Relationships. Derive source parameters from current values. Use a binding's update callback to clear dependent values or enforce mutual exclusion in one patch. Selections are retained unless your rule explicitly clears them.
  • Custom content. renderOption adds tag colors or avatars while the package keeps selection and keyboard handling. renderSummary can describe a whole team when all members are selected. renderEditor supports a hierarchy or another application-specific interaction.
  • Persistence. Choose useUrlFilters for a new URL-backed view. Its scope separates users or organizations. remember: "session" restores saved filters; oversized URLs fall back to session storage. Existing query-state hooks can use useControlledFilters.

Dynamic data and existing-state examples show these together. The system reference documents their typed contracts.

Theme compatibility

Square filter corners are an application preference, not a requirement. Set --radius: 0px on the filter theme to get them; otherwise the component follows your theme. Tailwind 3 projects use the compatibility stylesheet and may need to convert HSL channel tokens to complete colors. See installation and customization.

The package does not choose API authorization, matching logic, timezone boundaries, or team/member relationships. Those remain in the app. A custom editor owns its internal hierarchy and keyboard interaction; the library still supplies its placement, lifecycle, value updates, and chip.