Fix CustomSelect panel to left-align by default, right-align only when it would overflow the viewport

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Fraxle
2026-05-26 17:09:17 +01:00
co-authored by Claude Sonnet 4.6
parent 90789b5f47
commit d2952cddd2
2 changed files with 21 additions and 4 deletions
+13 -2
View File
@@ -41,7 +41,9 @@ const html = htm.bind(h);
// -------------------------------------------------------------------
export function CustomSelect({ value, options, onChange, hideLabel, hidingLabel, buttonLabel, isOn, noHide, groupedLeft, isLastChild, grpClass }) {
const [open, setOpen] = useState(false);
const wrapRef = useRef(null);
const [flipRight, setFlipRight] = useState(false);
const wrapRef = useRef(null);
const panelRef = useRef(null);
// Close on outside click or Escape
useEffect(() => {
@@ -60,6 +62,15 @@ export function CustomSelect({ value, options, onChange, hideLabel, hidingLabel,
};
}, [open]);
// After the panel renders, check if it overflows the right viewport edge.
// If so, flip it to right-align; otherwise keep it left-aligned.
useEffect(() => {
if (!open) { setFlipRight(false); return; }
if (!panelRef.current) return;
const rect = panelRef.current.getBoundingClientRect();
setFlipRight(rect.right > window.innerWidth - 8);
}, [open]);
// Build the label shown on the button
const activeOpt = options.find(o => o.value === value);
const btnLabel = buttonLabel || (isOn
@@ -85,7 +96,7 @@ export function CustomSelect({ value, options, onChange, hideLabel, hidingLabel,
<span class="cs-arrow"></span>
</button>
${open && html`
<div class="cs-panel" role="listbox">
<div class=${`cs-panel${flipRight ? ' cs-panel--right' : ''}`} ref=${panelRef} role="listbox">
${isOn && !noHide && html`
<span
class="cs-option"