PUI-42 feat(tree-index): dim rows outside the query's matching keys #115

Merged
pienter merged 3 commits from feature/PUI-42-dimming-search-and-filters-on-treeindex into main 2026-09-22 21:26:07 +00:00
Owner

Search and filters that dim rather than remove (ADR 0012, Goal Tree Index, milestone 31, page 45).

  • TreeIndex takes queryOptions (owning a loaderless useIndexQuery; load is now optional there) or a definition-owned state, provides it, and renders the search box, the filters slot and the active-filter chips. The chips row moves into an internal ActiveFilters component shared with Index; Index behaviour is unchanged.
  • It never reloads for a query: it emits query with the committed { search, filters } (TreeQuery) and takes matching, a set of row keys; undefined matches everything.
  • TreeTable takes matching and matchLabels, sets data-dimmed on rows outside the set, dims only the content cells with --opacity-disabled (the level, move and select cells stay usable) and appends a hidden "Does not match." to the row header. The count is announced as "n of m match." through the table's live region.
  • Playground: the Pages view owns a URL-synced loaderless query state, answers the query locally with listPageMatches, and puts the status filter in the page aside. Storybook: Layout/TreeIndex → Filters with a play.
  • AUDIT.md for tree-index and tree-table, CONVENTIONS.md, CMS_PLAYGROUND.md; ### Added under ## Unreleased in packages/ui/CHANGELOG.md.

Checks: typecheck, lint, format:check, bun test (165), build:vue, build:storybook. Browser: search and status filter dim with the tree shape kept, URL sync, match announcements and cue, a dimmed row moved by pointer and keyboard, clear restores every row; the Filters story play runs clean.

Stacked below: the PUI-43 pull request (Tree contract section and schema definitions) targets this branch.

Search and filters that dim rather than remove (ADR 0012, Goal Tree Index, milestone 31, page 45). - `TreeIndex` takes `queryOptions` (owning a loaderless `useIndexQuery`; `load` is now optional there) or a definition-owned `state`, provides it, and renders the search box, the `filters` slot and the active-filter chips. The chips row moves into an internal `ActiveFilters` component shared with `Index`; `Index` behaviour is unchanged. - It never reloads for a query: it emits `query` with the committed `{ search, filters }` (`TreeQuery`) and takes `matching`, a set of row keys; `undefined` matches everything. - `TreeTable` takes `matching` and `matchLabels`, sets `data-dimmed` on rows outside the set, dims only the content cells with `--opacity-disabled` (the level, move and select cells stay usable) and appends a hidden "Does not match." to the row header. The count is announced as "n of m match." through the table's live region. - Playground: the Pages view owns a URL-synced loaderless query state, answers the query locally with `listPageMatches`, and puts the status filter in the page aside. Storybook: `Layout/TreeIndex → Filters` with a play. - AUDIT.md for tree-index and tree-table, CONVENTIONS.md, CMS_PLAYGROUND.md; `### Added` under `## Unreleased` in `packages/ui/CHANGELOG.md`. Checks: typecheck, lint, format:check, bun test (165), build:vue, build:storybook. Browser: search and status filter dim with the tree shape kept, URL sync, match announcements and cue, a dimmed row moved by pointer and keyboard, clear restores every row; the Filters story play runs clean. Stacked below: the PUI-43 pull request (Tree contract section and schema definitions) targets this branch.
TreeIndex owns the same query state as Index (useIndexQuery without a
load, or a definition-owned state) and provides it, so the filter
controls, the filters slot and the active-filter chips work unchanged.
It never reloads for a query: it emits the committed search and filters
and takes matching, a set of row keys; the rest are dimmed, keep their
move button and stay offered as destinations. The count is announced and
a dimmed row carries a hidden cue (ADR 0012). The chips row moves into an
internal ActiveFilters component shared with Index.

Refs: PUI-42
The Pages view owns a loaderless useIndexQuery synced to the URL, answers
TreeIndex's query event with listPageMatches (the same search and status
rule as listPages) and passes the ids as matching; the status filter sits
in the page aside.

Refs: PUI-42
test(storybook): anchor the TreeIndex Filters play on the level cue
All checks were successful
ci / typecheck (pull_request) Successful in 47s
ci / format (pull_request) Successful in 58s
ci / release (pull_request) Has been skipped
ci / lint (pull_request) Successful in 51s
7cc2cfec4b
The level cue is part of every row header's accessible name and Team
offers two destinations, so the queries were ambiguous and the expected
announcement counted one child too few.

Refs: PUI-42
pienter deleted branch feature/PUI-42-dimming-search-and-filters-on-treeindex 2026-09-22 21:26:07 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
pienter/ui!115
No description provided.