Database

Filter & Sort Menus

“Filter by…” and “Sort by…” property pickers, plus the editors behind the filter and sort rule pills.

Task
Due
Priority
Status
Team
Add advanced filter
Task
Due
Priority
Status
Team

Usage

  • Use FilterMenu and SortMenu as the first step of adding a filter or sort: pick a property, then open FilterEditor or SortEditor.
  • Order the properties the way people expect to scan them (title first, then frequently filtered ones).
  • Use PropertyPickerMenu directly for other “pick a property” flows (group by, calculations).
  • Don’t use these menus outside a database; use Menu or Combobox for general choices.

Installation

Install the package (React 19):

terminal
npm install @krackedui/motion

Import the styles once, in your app entry or root layout:

/src/main.tsx
import '@krackedui/motion/styles.css';

Use it anywhere inside your app's <Theme> (see Installation):

/src/FilterSortMenusExample.tsx
import { FilterMenu, SortMenu, createTasksSample } from '@krackedui/motion';

export function FilterSortMenusExample() {
  const { collection } = createTasksSample();
  const order = ['title', 'due', 'priority', 'status', 'team'];
  const properties = [...collection.properties].sort((a, b) => order.indexOf(a.id) - order.indexOf(b.id));

  return (
    <div className="flex flex-wrap items-start justify-center gap-6">
      <FilterMenu properties={properties} highlightFirst onSelect={(p) => console.log('Filter by', p.name)} />
      <SortMenu properties={properties} onSelect={(p) => console.log('Sort by', p.name)} />
    </div>
  );
}

Examples

Filter editor

Status
Not started
In progress
Done

Sort editor

Due
Add sort
Delete sort

Custom menu from the parts

Build other database pickers ("Group by…") from the same parts: DbMenuSearch on top, DbMenuItem rows in labelled groups, DbMenuRule between sections and useMenuKeys for ↑/↓ and Enter/Space.

Task
Status
Priority
Team
Due
No grouping

Composition

anatomy
<FilterMenu> / <SortMenu>         // = PropertyPickerMenu with a placeholder (+ footer for filter)
  DbMenuSearch "Filter by…" / "Sort by…"
  DbMenuItem × n → PropertyTypeIcon + name
  DbMenuRule · "Add advanced filter" (filter only)

<FilterEditor>   "Status  is ▾"  · value picker (options checklist / text / date) · delete
<SortEditor>     row per sort: property ▾ · direction ▾ · remove · "+ Add sort"

menu parts: DbMenuSearch, DbMenuRule, DbMenuItem, SubmenuRow, useMenuKeys()

API Reference

FilterMenu

PropertyPickerMenu with the "Filter by…" placeholder and the "Add advanced filter" footer. Based on <div> (except onSelect).

PropTypeDefault
properties
Property[]
onSelect
(property: Property) => void
onAdvanced
() => void
highlightFirst
boolean
false
autoFocus
boolean
false
width
number
290

SortMenu

PropertyPickerMenu with the "Sort by…" placeholder. Based on <div> (except onSelect).

PropTypeDefault
properties
Property[]
onSelect
(property: Property) => void
highlightFirst
boolean
false
autoFocus
boolean
false
width
number
290

PropertyPickerMenu

PropTypeDefault
properties
Property[]
placeholder
string
onSelect
(property: Property) => void
footer
{ label: string; onSelect?: () => void }
highlightFirst
boolean
false
autoFocus
boolean
false
width
number
290

FilterEditor

PropTypeDefault
property
Property
filter
Filter
onChange
(f: Filter) => void
onRemove
() => void

SortEditor

PropTypeDefault
properties
Property[]
sorts
Sort[]
onChange
(s: Sort[]) => void
onAdd
() => void

DbMenuSearch

The 28px search field at the top of database menus, placed 12px in. An <input type="search">: all input props pass through; its accessible name defaults to the placeholder (without "…").

PropTypeDefault
wrapperClassName
string

DbMenuItem

A MenuRow made focusable for useMenuKeys: a button (or a switch when toggle is set) with tabIndex={-1}; focus draws the highlighted look. Same props as MenuRow.

PropTypeDefault
children
ReactNode
icon
IconName | ReactNode
description
ReactNode
caption
ReactNode
shortcut
ReactNode
submenu
boolean
trailing
ReactNode
checked
boolean
toggle
boolean
onToggle
(next: boolean) => void
tone
'default' | 'danger' | 'accent' | 'muted'
'default'
highlighted
boolean

DbMenuRule

Inset hairline between database menu sections (12px from the edges).

PropTypeDefault
className
string

useMenuKeys

useMenuKeys(): (e: KeyboardEvent<HTMLElement>) => void. Attach to a menu surface's onKeyDown: ↑/↓ move focus across its DbMenuItems (wrapping), Enter/Space click the focused one.

PropTypeDefault

Menu row that opens a flyout to its right ("Layout Table ›"). Extends MenuRowProps (without submenu / content).

PropTypeDefault
content
ReactNode | ((close: () => void) => ReactNode)
value
ReactNode
width
number
240
children
ReactNode
icon
IconName | ReactNode
description
ReactNode
caption
ReactNode
shortcut
ReactNode
trailing
ReactNode
checked
boolean
toggle
boolean
onToggle
(next: boolean) => void
tone
'default' | 'danger' | 'accent' | 'muted'
'default'
highlighted
boolean

Accessibility

  • The search field takes focus with autoFocus; Enter picks the first match.
  • Rows are focusable DbMenuItems: ArrowUp/ArrowDown move, Enter/Space select (useMenuKeys).
  • Editors’ delete buttons are labelled "Delete filter" / "Remove sort".
© 2026 Motion. Internal documentation.