Skip to content

feat: add search filter to docs sidebar file tree#807

Open
rh-hemartin wants to merge 5 commits into
mainfrom
feat/794-docs-tree-search-filter
Open

feat: add search filter to docs sidebar file tree#807
rh-hemartin wants to merge 5 commits into
mainfrom
feat/794-docs-tree-search-filter

Conversation

@rh-hemartin
Copy link
Copy Markdown
Contributor

Summary

  • Adds a real-time text filter input to the docs sidebar, above the file tree (Add search bar to the files tree in the docs app #794)
  • Case-insensitive substring matching against document titles and directory names
  • Ancestor directories preserved for context; all directories auto-expand when filter is active
  • New filterTree utility with 6 unit tests

Test plan

  • vitest run — all 188 tests pass (including 6 new filterTree tests)
  • make lint — clean
  • Manual: filter input visible below "Outline" header, filters tree in real time
  • Manual: clearing input restores full tree, clicking filtered result navigates correctly

Closes #794

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown

fullsend review is working on this — view logs

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 11, 2026

Site preview

Preview: https://4535a35f-site.fullsend-ai.workers.dev

Commit: e9c673023dda841cb1f404902f34f4b55bca51c2

@fullsend-ai-review
Copy link
Copy Markdown

fullsend-ai-review Bot commented May 11, 2026

Review: #807

Head SHA: e9c6730
Timestamp: 2026-05-14T00:00:00Z
Outcome: approve

Summary

Clean, well-scoped feature addition that matches the linked issue's request. The filterTree utility correctly prunes non-matching branches while preserving ancestor context, and highlightSegments safely merges overlapping highlight ranges. The implementation avoids common pitfalls — no regex construction from user input, no innerHTML, and Svelte's auto-escaping prevents XSS through the filter input. Tests are comprehensive with 14 cases covering empty queries, case insensitivity, multi-word matching, ancestor preservation, pruning, and highlight merging. No security, injection, or correctness concerns.

Findings

Medium

  • [Correctness] web/docs/src/lib/filterTree.ts:27 / web/docs/src/lib/DocTreeNav.svelte — Files can match via routeKey (the search text is ${node.title} ${node.routeKey}), but highlightSegments in the template only highlights against node.title or node.name. A file matched purely by its path segment will appear in the filtered tree with no visual highlight, which may confuse users about why it matched.
    Remediation: Consider also running highlightSegments against node.routeKey and showing a secondary indicator, or matching only against node.title and node.name for consistency.

Low

  • [Correctness] web/docs/src/App.svelte:37 — No debounce on the reactive $derived(filterTree(manifest, filterQuery)). For the current docs tree size this is fine, but if the manifest grows large, filtering on every keystroke could cause input jank.
    Remediation: Not urgent — monitor if the tree grows significantly and add a debounce if needed.

Footer

Outcome: approve
This review applies to SHA e9c673023dda841cb1f404902f34f4b55bca51c2. Any push to the PR head clears this review and requires a new evaluation.

Previous run

Review: #807

Head SHA: 3cc73cd
Timestamp: 2026-05-14T00:00:00Z
Outcome: approve

Summary

This PR adds a real-time search filter to the docs sidebar file tree, closing #794. The implementation is clean and well-scoped: a new filterTree utility handles case-insensitive multi-word matching against document titles, route keys, and directory names, preserving ancestor directories for context. The highlightSegments utility marks matching substrings using <mark> elements via Svelte text interpolation (not {@html}), avoiding XSS. The code is covered by 6 unit tests spanning empty queries, case sensitivity, multi-word matching, ancestor preservation, branch pruning, and highlight merging. The change aligns precisely with the linked issue's scope — no unauthorized capability is introduced.

Findings

Critical

None.

High

None.

Medium

None.

Low

None.

Info

  • [style] DocTreeNav.svelte:105,137 — The inline {#each highlightSegments(...)} template expressions are dense single-line constructs. Consider extracting a HighlightedText snippet component if more highlight call sites are added in the future, to keep templates readable.

Footer

Outcome: approve
This review applies to SHA 3cc73cd35fb14a9f835d4635d92e6dce2a512911. Any push to the PR head clears this review and requires a new evaluation.

Previous run (2)

Review: #807

Head SHA: 48920ef
Timestamp: 2026-05-12T00:00:00Z
Outcome: approve

Summary

Clean, well-scoped feature addition that matches the linked issue (#794). The filterTree utility is correct, has good test coverage (12 tests across filtering and highlighting), and integrates cleanly with the existing Svelte 5 component architecture. No security, injection, or correctness concerns — text interpolation is auto-escaped by Svelte, the filter operates on the already-client-side manifest, and there are no new {@html} usages. Two minor style observations noted below.

Findings

Critical

None.

High

None.

Medium

None.

Low

  • [style] App.svelte (diff lines in filter-wrap block) — The <div class="docs-tree-filter-icon-wrapper"> is at the same indentation level as its parent <div class="docs-tree-filter-wrap">. Children should be indented one level deeper for consistency with the rest of the template.
    Remediation: Indent the icon-wrapper div and its contents by two additional spaces.

  • [style] DocTreeNav.svelte:105,137 — The {#each highlightSegments(...)} template blocks are dense single-line expressions (~160 chars). While functional, breaking them across multiple lines would improve readability, consistent with the multi-line template patterns used elsewhere in this file.
    Remediation: Optional — consider wrapping the each/if/mark blocks across lines.

Info

  • [correctness] filterTree.ts:31 — When a directory name matches all query words, the original node (with all children) is pushed directly. This means the subtree is shared by reference with the source manifest. This is safe because Svelte's $derived treats the result as read-only for rendering, and filterTree never mutates nodes. Just noting the design choice.

Footer

Outcome: approve
This review applies to SHA 48920efb75e9bc78d03345a3131ef6ecb6683a92. Any push to the PR head clears this review and requires a new evaluation.

Previous run (3)

Review: #807

Head SHA: c528637
Timestamp: 2026-05-12T00:00:00Z
Outcome: approve

Summary

Clean, well-scoped feature that adds a real-time search filter to the docs sidebar file tree, directly addressing #794. The filterTree utility correctly prunes non-matching branches while preserving ancestor directories, and highlightSegments handles overlapping match ranges properly. All user input flows through safe string operations (toLowerCase, includes) and Svelte template syntax — no XSS vectors. Tests are comprehensive with good coverage of edge cases (empty query, no matches, multi-word, case insensitivity, overlapping highlights). No blocking findings.

Findings

Info

  • [Correctness] web/docs/src/lib/filterTree.ts:27 / web/docs/src/lib/DocTreeNav.svelte:137 — File nodes are matched against the combined title + routeKey text, but highlightSegments in DocTreeNav only highlights within node.title. If a multi-word query matches one word solely in the routeKey (path), that word won't be visually highlighted in the tree. This is a minor visual inconsistency — the correct node still appears, it just won't show why it matched. Consider highlighting against the full search text or noting this as a known limitation.

Footer

Outcome: approve
This review applies to SHA c5286379b083d0e4673c8d5005765de11237a1be. Any push to the PR head clears this review and requires a new evaluation.

Previous run (4)

Review: #807

Head SHA: fd1a27c
Timestamp: 2026-05-11T00:00:00Z
Outcome: approve

Summary

Clean, well-scoped feature addition that directly addresses the linked issue (#794). The implementation adds a client-side text filter to the docs sidebar using a new filterTree utility that prunes the manifest tree by case-insensitive substring matching against document titles, route keys, and directory paths. The code follows existing Svelte 5 patterns, properly auto-escapes all user input (no {@html} for filter content), and includes thorough unit tests (6 for filterTree, 6 for highlightSegments). No security, correctness, or injection concerns identified.

Findings

Info

  • [style] DocTreeNav.svelte:105,137 — The inline {#each highlightSegments(...)} template expressions are dense single-line constructs. Consider extracting a {#snippet} for readability in future iterations, though this is not blocking.

  • [correctness] filterTree.ts:27 — File matching concatenates title and routeKey with a space separator (${node.title} ${node.routeKey}). A multi-word query like "guide guides" could match across the boundary (last word of title + first segment of routeKey). This is unlikely to cause user confusion in practice and arguably a feature, but worth noting.

Footer

Outcome: approve
This review applies to SHA fd1a27c6f8d547c39add7e95fa0a5dc72e161897. Any push to the PR head clears this review and requires a new evaluation.

Previous run (5)

Review: #807

Head SHA: 83c54e6
Timestamp: 2026-05-11T00:00:00Z
Outcome: approve

Summary

Clean, well-scoped feature addition that implements a real-time text filter for the docs sidebar file tree, directly matching the request in #794. The implementation is correct: filterTree performs case-insensitive substring matching against file titles and directory names, preserves ancestor directories for context, and keeps full subtrees when a directory name matches. The recursive forceExpandAll prop cleanly auto-expands all directories during active filtering without interfering with persisted expand/collapse state. Six unit tests cover the key scenarios. No security, injection, or style concerns.

Findings

Info

  • [Correctness] filterTree.ts — The filter matches files by title only, not by name or routeKey. This is a reasonable design choice for a user-facing filter (titles are what users see), but users searching by filename slug (e.g. "config" when the title is "Configuration") would need to know the exact title. The current test for "admin" shows directory-name matching works, which partially addresses this. No action required — just noting the design choice.

Footer

Outcome: approve
This review applies to SHA 83c54e61e1bbcd9730049ea3aa5fb446203d65d2. Any push to the PR head clears this review and requires a new evaluation.

@ifireball
Copy link
Copy Markdown
Contributor

Maybe its a matter of preference but I'd like the search to be fuzzier like fzf by:

  1. When typing multiple words in the search, look for them to appear separately in "file name". So that "Land Ana" would return "Landscape Analysis"
  2. Include the file "path" in the string we search into so that searching "ADR 7" will find it

Also some stylistic nitpicks:

  1. I'd really like to see it highlighting the matched sub-strings in the files and folder names
  2. Its useful to have a "clear filter" button
  3. It'd be nice to have a search icon somewhere to indicate its a search bar.

See for example what the search bar on the firefox history sidepane looks like:

image

@github-actions
Copy link
Copy Markdown

fullsend review is working on this — view logs

@rh-hemartin
Copy link
Copy Markdown
Contributor Author

@ifireball give it another review

@ifireball
Copy link
Copy Markdown
Contributor

@ifireball give it another review

Nice! I think you nailed it functionality-wise! Just a couple of nitpicks:

image

Both the search icon and the "clear" button seem misaligned, they probably should be vertically aligned to the text input. The "clear" icon could probably be bigger as well, it seems to be unnecessarily small.

@github-actions
Copy link
Copy Markdown

fullsend review is working on this — view logs

@rh-hemartin
Copy link
Copy Markdown
Contributor Author

The "clear" icon could probably be bigger as well, it seems to be unnecessarily small.

We are not using icons, we are using SVG directly so the size is not something i know how to change easily. I think it is fine as is.

@ifireball
Copy link
Copy Markdown
Contributor

The "clear" icon could probably be bigger as well, it seems to be unnecessarily small.

We are not using icons, we are using SVG directly so the size is not something i know how to change easily. I think it is fine as is.

WTYM you don't know? Can't your agent do it for you? Also its easy to change SVG size (SVG is basically a set of vector drawing instructions), you just change its positioning and it "stretches" itself...

@rh-hemartin rh-hemartin force-pushed the feat/794-docs-tree-search-filter branch from c528637 to 48920ef Compare May 12, 2026 12:05
@github-actions
Copy link
Copy Markdown

fullsend review is working on this — view logs

@rh-hemartin
Copy link
Copy Markdown
Contributor Author

I make it a bit bigger by changing the width and the height. I didn't want an agent to do this, as it was a very messy implementation, so I refactored to use flex and didn't want to touch it a lot after. However it went well:

image

But as you can see the bigger the search icon, the worse it looks.

@rh-hemartin
Copy link
Copy Markdown
Contributor Author

@ifireball take a look again please

@ifireball
Copy link
Copy Markdown
Contributor

@ifireball take a look again please

not sure why the search icon and the "clear" icon are outside the search bar area now, it seems conventional to include them inside it. (I know they are not really inside the text input tag, but CSS is typically used to make it appear as if they are)

@github-actions
Copy link
Copy Markdown

fullsend review is working on this — view logs

@rh-hemartin rh-hemartin force-pushed the feat/794-docs-tree-search-filter branch from 3cc73cd to d0b6252 Compare May 14, 2026 13:24
@github-actions
Copy link
Copy Markdown

fullsend review is working on this — view logs

@rh-hemartin
Copy link
Copy Markdown
Contributor Author

Ops, wrong force push

rh-hemartin and others added 5 commits May 14, 2026 15:27
Real-time text input in the sidebar filters the document tree by
title and directory name. Matching is case-insensitive substring;
ancestor directories are preserved for context. Filtered trees
auto-expand all directories so matches are immediately visible.

Closes #794

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address PR feedback: multi-word fuzzy search, path-inclusive
matching (routeKey for files, dir path for dirs), substring
highlighting via <mark> tags, search icon, and clear button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Hector Martinez <hemartin@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rh-hemartin rh-hemartin reopened this May 14, 2026
@github-actions
Copy link
Copy Markdown

fullsend review is working on this — view logs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add search bar to the files tree in the docs app

2 participants