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>
|
Questions: The FilterSettings: Reordering/hiding the fields / updating sort. If the user changes this, then saves a filter, do these save as well? I wasn't clear on if it was the settings as well as the selected values Something feels a bit odd with the FilterSettings bit. I think my clearest thought is the sorting: This might be unnecessary to allow the user to update. It could just be in the code, where at code-level you specify for each field that can be filtered it's sort order. I suspect it will be pretty fixed. (If we decide we want to allow sorting, maybe it would be better in each section to have an option. Along the same lines I'm not sure the user needs to be able to re-order the sections. I could be convinced that they do. We would see something like this on an AirTable type app, but AirTable is a generic builder, whereas we provide bespoke screens. It would be great for the user to be able to search for a value. This UX seems to preference a list of options; so for a long list, they would have to scroll unless they can use a text-search to quickly front-end filter down to matching values, then they can select which values they want to include in their filter search And I'm wondering how in-depth this POC is, is it more of a mock-up, or is it working? I am wondering what the best way is to get all the values for something like color, where we want to show all the options available. For a dataset with a lot of rows, we may need to check if there's a way to select all distinct values (like you would with a traditional sql db), or if this won't work in TailorDB and to support this we'd need some CDC events to keep some cache tables Likewise, I'd be keen to discuss if it is possible to show the numbers. As you select items, e.g. black, all the other numbers would need to change right? Because now there are fewer matching 'Accessories', 'Tops' that are black. Probably do-able since queries can return totals, but this would be a lot of queries to fire off to get these numbers |
…veView) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ects - Narrow screens follow the Sidebar pattern: below lg the rail turns itself into a left sheet behind a "Filters" button. New FilterRail.Provider lets FilterRail.Trigger sit anywhere (e.g. a table toolbar); with no Trigger, Root renders a fallback button. Removes FilterRail.Sheet and the public useFilterRailCompact hook (breakpoint check is internal, like useIsMobile). - Move saved views out to a follow-up (branch feat/filter-rail-saved-views). - Fix CodeQL prototype pollution: null-prototype count maps, and countOf() reads only own keys so an option value like "constructor" counts as 0. - Replace useEffect prop mirroring in the text and number-range controls with render-time reconciliation; debounce text in the change handler, keeping keys typed after the input's own commit. - Number range ignores invalid input and swaps ends typed the wrong way round. - Value search appears whenever a checkbox list is long enough to truncate. - Layout hook re-hydrates on key change during render, not in an effect. - Add type tests for field typing and Root/Provider config. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`<Layout fill>` bounded its rows at every width, so below the breakpoint where columns stack (lg for two, xl for three) every column but the last got zero height and the next column painted over it. The fill docs already say a stacked layout scrolls as usual; this makes the code match. The fill bound now applies only from the breakpoint where columns sit side by side, and `data-layout-fill` carries that breakpoint (always | lg | xl) so the AppShell content area clips only while the page is actually bounded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ponent-da0c71 # Conflicts: # docs-manifest.json # examples/vite-app/src/App.tsx
…earch
Agreed with the team (2026-10-13):
- Remove per-option result counts. There is no proven way yet to get
distinct values and grouped counts cheaply from TailorDB, so `counts`,
`zeroBehavior`, `useFilterRailCounts`, the empty-result hint and the
count-based option sorts ("By count" in Settings) go. The prototype is kept
on feat/filter-rail-counts for a spike; counts can return as an additive,
optional prop.
- Leave the filters as they are otherwise.
- Checkbox and radio sections are for small, fixed sets. Docs gain a
"Choosing a control" table steering fields whose values keep growing
(names, customers, suppliers) to a search, and in development the rail
warns when a listed section has more than 50 options.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ponent-da0c71 # Conflicts: # docs-manifest.json
What
A new public component,
FilterRail. It's an always-visible filter rail that sits beside aDataTablein its ownLayout.Column. Every filterable axis is visible up front, 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, and a range isbetween,gteorlte.Demo:
/showcase/filter-railin the vite example has three variants:Team decisions (2026-10-13)
API: config sections + optional parts
This follows the DataTable model:
sectionsworks likecolumns. Each section ischeckbox,radio,boolean,text,numberRange,date,dateRangeorcustom.Public surface:
FilterRailwith the partsProvider,Root,Header,ClearAll,Settings,SectionsandTrigger.FilterRailRootPropsandFilterRailSection.useFilterRailLayout, the user's section layout, persisted.Narrow screens follow the Sidebar pattern
Below
lg, the rail turns itself into a left sheet behind a Filters (n) button, where n is the number of applied filters. Apps write no breakpoint code, and the check stays internal, likeuseIsMobile.FilterRail.Providerand place<FilterRail.Trigger />there.Rootrenders a fallback button in its own spot, so the filters are never unreachable.The reasoning is in
decisions/filter-rail.md.Also in this PR: a
Layoutfix (separate commit)fix(layout): don't squash stacked columns in fill modeis a pre-existing bug that this PR surfaced.The bug: below the breakpoint where columns stack,
<Layout fill>still bounded its rows. Every column except the last got 0px of height, and the next column painted over it. Thefilldocs already say a stacked layout "scrolls as usual", so the code didn't match its own docs.The fix:
lgfor two,xlfor three.data-layout-fillcarries that breakpoint, so the AppShell content area clips only while the page is actually bounded.Changes since the draft
feat/filter-rail-saved-viewsbranch.FilterRail.Sheetand the publicuseFilterRailCompactare removed.useEffectprop mirroring:gteorlte.fieldfails against a typed control, and that Root's config rules are enforced.Checks
Run locally after merging the latest
main:type-check,lint,fmt:checkandtestall pass (2,229 core tests).docs:syncanddocs:checkpass.Layout fillpage.Commits are unsigned (local GPG prompt issue) and will be re-signed.
🤖 Generated with Claude Code