Sort Menu
The one-key sort — the fields, then the two directions worded by field type, with Reset while the order is not the page's default.
- Status
- Since
0.25.100- Accessibility pattern
- two labelled radio groups; arrow keys move
Last updated
Install
Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Sort Menu before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify sort-menuInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/sort-menuRun the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.
The same command installs the registry items it composes: @vegastack/button.
Usage
import { SortMenu, sortSummary } from "@/components/ui/sort-menu";
<ListToolbar
sort={{
content: (
<SortMenu
fields={[
{ key: "due", label: "Due date", type: "date" },
{ key: "title", label: "Title" },
]}
value={sort}
defaultValue={{ key: "due", direction: "asc" }}
onValueChange={setSort}
/>
),
isDefault: sort.key === "due" && sort.direction === "asc",
summary: sortSummary(fields, sort),
}}
/>;A list that sorts by one key shows exactly that: which field, then which direction, each a group of
options with a check on the chosen one. There are no drag handles, selects or "Add sort" — an
affordance a one-key list can never use is not shown. The directions read in the field's own words:
dates "Oldest first / Newest first", text "A → Z / Z → A", numbers "Low → high / High → low", a
fixed order (priority, status) "First to last / Last to first". "Reset" sits in the header while the
order differs from defaultValue. A column header click writes the same value.
A field the list can sort only one way sets fixedDirection: its direction shows in muted words
beside its name ("Last updated Newest first"), picking it sets that direction, and the direction
group hides while it is chosen, so the menu never offers an order the server cannot give.
fixedDirection: "none" is a manual order ("Custom order"): no direction words at all.
sortSummary(fields, value) returns one line ("Due date, oldest first") for the Sort row Display
shows once the toolbar has folded Sort into it.
For several keys at once (a table), use SortBuilder from
filter-bar-managed.
Examples
Fields of every type
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
fields* | readonly SortMenuField[] | — | The fields, in the order offered. |
onValueChange* | (value: SortMenuValue) => void | — | Called with the next order. |
value* | SortMenuValue | — | The current order. |
className | string | — | Extra classes for the root. |
defaultValue | SortMenuValue | — | The page's default order. While value differs from it, "Reset" shows. |
labels | (Partial<Omit<SortMenuLabels, "directions">> & { directions?: Partial<SortMenuLabels["directions"]>; }) | English | The component's words. |
Data attributes and CSS variables on SortMenu
| Attribute | Values |
|---|---|
data-default | "" |
data-slot | "sort-menu" | "sort-menu-direction" | "sort-menu-fields" | "sort-menu-header" | "sort-menu-reset" |
Field
| Prop | Type | Default | Description |
|---|---|---|---|
key* | string | — | Stable key. |
label* | string | — | The field's name ("Due date"). |
fixedDirection | "asc" | "desc" | "none" | undefined (both ways) | The one way this field sorts, when the list cannot sort it both ways: its direction shows
beside the name and the direction group hides while it is chosen. "none" is a manual order
(no direction to show at all). |
type | "date" | "enum" | "number" | "text" | "text" | What the field holds — it words the directions. |
Accessibility
- The fields are a
radiogrouplabelled by its "Sort by" heading; the directions are a secondradiogroupnamed "Direction". The chosen option isaria-checked. - Each option is 32px tall from the surface's 8px inset.
| Key | Action |
|---|---|
| ↑ ↓ | Move within a group and pick |
| Tab | Move between Reset and groups |
| Contract | States tested |
|---|---|
| Behaviour | default, changed |
| Accessibility | labeled, browser-accessibility-test |
| Visual | default, hover |
Do / Don't
Add Filter Menu
+ Filter — one input that narrows the fields or sends a plain-language request to the page's AI filter; fields open their pickers in place.
Display Menu
The toolbar's Display tool — layout and sort once folded in, row height, group by, columns, the Show switches and Reset, on one surface.