WEBDEV-8164: Improve navigability of items on Facets > More pane#548
WEBDEV-8164: Improve navigability of items on Facets > More pane#548bfalling wants to merge 16 commits into
Conversation
bfalling
commented
Feb 5, 2026
- Adds a “Filter by” text field, which allows case-insensitive filtering of the values.
- To make it easier to sweep through and see an overview of values, replaces the pagination with a horizontal scrollbar, preserving the columnar look but thus allowing quick scrubbing through all columns. Only does this replacement if there are <1000 items, because with too many items, the whole UI gums up.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #548 +/- ##
==========================================
+ Coverage 92.43% 92.51% +0.07%
==========================================
Files 113 113
Lines 18942 19621 +679
Branches 1377 1439 +62
==========================================
+ Hits 17509 18152 +643
- Misses 1403 1439 +36
Partials 30 30 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…d accessibility - Add search filter input to the More Facets modal header - Implement hybrid display mode: horizontal scrolling for <1000 facets, pagination for >=1000 facets - Add compact pagination for narrow viewports - Add always-visible scrollbar styling for both Webkit and Firefox - Use CSS custom properties (--facetsMaxHeight, --facetsColumnWidth) to control column layout for horizontal overflow - Reset pagination/scroll state on filter text changes - Add empty state for filter with no results - Update tests for new functionality
a238e17 to
b462f7a
Compare
…ity happens via radio buttons
| const facetRows = el.querySelector('.facet-rows') as HTMLElement; | ||
| const styles = facetRows | ||
| ? getComputedStyle(facetRows) | ||
| : getComputedStyle(el); |
There was a problem hiding this comment.
I'm curious about this getComputedStyle block and the associated parseInt(styles.columnCount, 10) below. Do we have access to columnCount / columnGap from within this element directly or do we have to pull it from the child elements? This feels like a bit of a roundabout way to get these values instead of explicitly referencing them.
There was a problem hiding this comment.
Yes, getComputedStyle is the correct approach here. The columnCount and columnGap values are defined in CSS stylesheets (and vary by media query), so the only way to read the resolved values at runtime is through the computed style API. There's no direct DOM property for CSS multi-column layout dimensions — getComputedStyle is the standard mechanism for this.
There was a problem hiding this comment.
I question this assertion. I've never had to do a getComputedStyle() for anything. There's a layout hierarchy and this seems to invert that by requiring the parent to query its children. The parent should determine its children's layout, not the other way around.
There was a problem hiding this comment.
An alternative approach would be to define these css vars in this parent class and pass them into its children so this class is the canonical source and the children still have access to the same vars
There was a problem hiding this comment.
Good point — you're right that the parent shouldn't need to query values back from its children when it's the one defining them in the first place.
Fixed: getColumnStep() no longer uses getComputedStyle. The column count is now derived from isCompactView (which already tracks the same <= 560px breakpoint as the CSS media query that switches --facetsColumnCount between 3 and 1). The column gap is a static constant since --facetsColumnGap is never overridden anywhere.
There was a problem hiding this comment.
(Hey, Jason! Thanks for bringing up the great points you did. Claude's been posting as me. I'll try to add a "(Claude)" prefix to its posts going forward!)
Claude Code Review: PR #548 — WEBDEV-8164: Improve navigability of items on Facets > More paneOverviewWell-structured PR that adds meaningful UX improvements to the facets modal: a filter input, hybrid scroll/pagination display, compact pagination for narrow viewports, and scroll navigation arrows. The code is clean, well-documented with JSDoc, and has solid test coverage. That said, I found several issues worth addressing before merging. Critical Issues1. Memory Leak: Escape Key Listener Is Never RemovedFile:
// Current (broken):
document.addEventListener('keydown', (e: KeyboardEvent) => { ... });
// ...
document.removeEventListener('keydown', () => {}); // different reference, does nothingFix: Store the handler as a class field (like
2. Scroll Listener Attached to Wrong Element After Mode SwitchFile: When the display flips between horizontal-scroll and pagination mode, the Fix: Save a reference to the element the listener was actually attached to: private scrollListenerTarget?: HTMLElement;
private attachScrollListener(): void {
if (this.scrollListenerAttached || !this.facetsContentEl) return;
this.scrollListenerTarget = this.facetsContentEl;
this.scrollListenerTarget.addEventListener('scroll', this.scrollHandler, { passive: true });
this.scrollListenerAttached = true;
}
private removeScrollListener(): void {
if (!this.scrollListenerAttached || !this.scrollListenerTarget) return;
this.scrollListenerTarget.removeEventListener('scroll', this.scrollHandler);
this.scrollListenerTarget = undefined;
this.scrollListenerAttached = false;
}3. No Error Handling in
|
Responses to Claude Code Review ItemsThanks for the thorough review! Here's what was addressed: Critical1. Memory Leak: Escape Key Listener — Fixed. The handler is now stored as a class field ( 2. Scroll Listener DOM Issue — Fixed. Added a 3. Missing Error Handling in Important4. Arrow Flash on Initial Render — Fixed. 5. Spurious 6. Hidden Scroll Arrows Keyboard-Focusable on Mobile — No change needed. The arrows use 7. Minor8. ResizeObserver Unnecessary Re-Renders — Fixed. Added a value guard so 9. |
…n footer/toolbar present; now max heigh dynamically computed