What happened
FilterPanel positions itself with position: fixed, computing left/top purely from the trigger's getBoundingClientRect():
useEffect(() => {
if (isOpen && anchorRef.current) {
const rect = anchorRef.current.getBoundingClientRect();
setPosition({ top: rect.bottom + 8, left: rect.left });
}
}, [isOpen]);
(Source/JavaScript/Filter/FilterPanel.tsx, compiled output at dist/esm/Filter/FilterPanel.js.)
The panel then renders at that left and extends rightward by its own intrinsic width, with no check against window.innerWidth and no fallback to open leftward (right-aligned) when there isn't enough room. If the trigger sits close to the right edge of the viewport - a completely ordinary layout, e.g. a filter button placed at the end of a full-width toolbar row (search box flex: 1 + trailing filter button) - most of the panel renders past the edge of the viewport and is unreachable/unreadable.
Repro
- Put a
FilterPanel trigger button as the last item in a full-width flex row (so its right edge is near the browser window's right edge) - a very common toolbar pattern.
- Give it 2+ facets with several options each (panel's natural width ends up ~260-320px).
- Open the panel.
Expected: the panel repositions (e.g. right-aligns to the trigger, or clamps left so left + panelWidth <= window.innerWidth) so it stays fully visible.
Observed: the panel opens at left: <trigger's left edge> regardless of remaining viewport width, so most of its content (facet labels, checkboxes, the label search box) renders off-screen to the right - functionally unusable without manually resizing the window or scrolling in a way the page doesn't support.
Impact
Every consumer whose natural UI placement for a filter trigger is "at the end of a toolbar" (arguably the most common placement for this kind of control - see e.g. GitHub's own "Filters"-style buttons, which right-align their dropdowns for exactly this reason) hits this. The only workaround today is avoiding that placement altogether (e.g. moving the trigger to the start of the row instead), which isn't always the right layout for the surrounding UI.
Suggested direction
On open, after the panel has its natural size, check whether rect.left + panelWidth would exceed window.innerWidth (and similarly for vertical overflow against window.innerHeight) and flip to right-aligning against the trigger's right edge (and/or clamp) in that case - the same kind of collision detection most portal-based dropdown/popover libraries do. Leaving the exact approach to whoever owns the component.
What happened
FilterPanelpositions itself withposition: fixed, computingleft/toppurely from the trigger'sgetBoundingClientRect():(
Source/JavaScript/Filter/FilterPanel.tsx, compiled output atdist/esm/Filter/FilterPanel.js.)The panel then renders at that
leftand extends rightward by its own intrinsic width, with no check againstwindow.innerWidthand no fallback to open leftward (right-aligned) when there isn't enough room. If the trigger sits close to the right edge of the viewport - a completely ordinary layout, e.g. a filter button placed at the end of a full-width toolbar row (search boxflex: 1+ trailing filter button) - most of the panel renders past the edge of the viewport and is unreachable/unreadable.Repro
FilterPaneltrigger button as the last item in a full-width flex row (so its right edge is near the browser window's right edge) - a very common toolbar pattern.Expected: the panel repositions (e.g. right-aligns to the trigger, or clamps
leftsoleft + panelWidth <= window.innerWidth) so it stays fully visible.Observed: the panel opens at
left: <trigger's left edge>regardless of remaining viewport width, so most of its content (facet labels, checkboxes, the label search box) renders off-screen to the right - functionally unusable without manually resizing the window or scrolling in a way the page doesn't support.Impact
Every consumer whose natural UI placement for a filter trigger is "at the end of a toolbar" (arguably the most common placement for this kind of control - see e.g. GitHub's own "Filters"-style buttons, which right-align their dropdowns for exactly this reason) hits this. The only workaround today is avoiding that placement altogether (e.g. moving the trigger to the start of the row instead), which isn't always the right layout for the surrounding UI.
Suggested direction
On open, after the panel has its natural size, check whether
rect.left + panelWidthwould exceedwindow.innerWidth(and similarly for vertical overflow againstwindow.innerHeight) and flip to right-aligning against the trigger's right edge (and/or clamp) in that case - the same kind of collision detection most portal-based dropdown/popover libraries do. Leaving the exact approach to whoever owns the component.