Repository navigation
Conversation
Promotes the `demo/filter-rail` prototype into packages/core as a public component. It writes the same CollectionControl a DataTable reads, so there is no second filter engine. - Config sections (checkbox, radio, boolean, text, numberRange, date, dateRange, custom) + optional compound parts: Root, Header, ClearAll, Settings, SavedViews, Sections, Trigger, Sheet. - Hooks: useFilterRailCounts, useFilterRailLayout, useSavedViews, useFilterRailCompact. - Showcase page /showcase/filter-rail with three variants, docs outline, decision record and changeset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ponent-da0c71 # Conflicts: # docs-manifest.json
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A new public component,
FilterRail: an always-visible faceted filter rail that sits beside aDataTable, in its ownLayout.Column. Every filterable axis is visible, with optional counts per option, instead of being hidden behind the "Add filter" panel.It writes the same
CollectionControlthe table reads, so there's no second filter engine. A checkbox section is theinoperator, a radio iseq, a range isbetween.This promotes the prototype from the
demo/filter-railbranch (examples-only, never meant to merge) intopackages/core.Demo:
/showcase/filter-railin the vite example has three variants:lg.Root+Sectionsand nothing else.API: config sections + optional parts
This follows the DataTable model:
sectionsworks likecolumns. Each section ischeckbox,radio,boolean,text,numberRange,date,dateRangeorcustom.Parts:
Root,HeaderandSections: the rail itself.ClearAll: clears only the rail's own fields.Settings: show/hide, reorder and sort sections.SavedViews: filters plus sort, page size and column layout.Trigger+Sheet: the narrow-screen layout.Hooks:
useFilterRailCounts: in-memory faceting.useFilterRailLayout: the user's section layout, persisted.useSavedViews(table, { storageKey, storage? }): saved views, with a pluggable store.useFilterRailCompact: true belowlg.The rail stays backend-agnostic. It never sees rows: counts are a prop, with a backend returning the same shape from an aggregation query. Layout and saved views are bindings that default to localStorage and can be backed by a server store.
The reasoning is in
decisions/filter-rail.md. Highlights:DataTable.FilterRail: the rail lives outsideDataTable.Root.Relation to
DataTable.FiltersThe two complement each other. Use the rail for the 4–6 everyday fields and
DataTable.Filtersfor the long tail. A field should belong to one surface, not both.Changed vs the demo
gte/lte. The demo filled the empty end from the section bounds, which made the boxes impossible to clear one at a time.setFiltercalls in one handler now both stick.@base-ui/react/popover, the same as DataTable column settings, instead of a hand-rolled portal.Open questions for review
useFilterRailCompactpublic, or leave breakpoint detection to apps?span role="button"with a lint exception. The alternative is a separate delete action.FilterRail.fromColumns(columns, ids)helper derive sections fromcolumn.filter, so a field isn't configured twice?Checks
The following all pass locally after merging
main:type-check,lint,fmt:check,test(2,145 core tests, 122 of them for FilterRail).docs:syncanddocs:check.Notes:
🤖 Generated with Claude Code