From 77707a3cbe8ead2cae445e6a51ad2439863e0d89 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Wed, 1 Jul 2026 00:01:26 +0200 Subject: [PATCH] fix(channels): flip the row tag picker upward when it would clip below The per-row tag '+' menu always opened downward (top-full) and clipped against the scroll container for rows near the viewport bottom. Measure the button on open and flip it upward (bottom-full) when there isn't room below but there is above; cap its height with an internal scroll so a long tag list can't overflow either way. --- frontend/src/components/Channels.tsx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/Channels.tsx b/frontend/src/components/Channels.tsx index 32b3a36..a110d7b 100644 --- a/frontend/src/components/Channels.tsx +++ b/frontend/src/components/Channels.tsx @@ -664,8 +664,20 @@ function TagsCell({ }) { const { t } = useTranslation(); const [open, setOpen] = useState(false); + // Open the picker upward when there isn't room below (rows near the viewport bottom would + // otherwise clip it against the scroll container), as long as there's room above. + const [openUp, setOpenUp] = useState(false); const ref = useRef(null); + const btnRef = useRef(null); useDismiss(open, () => setOpen(false), ref); + const toggle = () => { + if (!open) { + const r = btnRef.current?.getBoundingClientRect(); + const est = Math.min(userTags.length * 30 + 12, 264); // matches the max-height cap below + setOpenUp(!!r && r.bottom + est > window.innerHeight - 8 && r.top - est > 8); + } + setOpen((o) => !o); + }; if (userTags.length === 0) return null; // Show only the tags actually attached to this channel; the “+” opens a per-channel // picker to attach/detach (kept the convenient "kirakás" without listing every tag @@ -684,7 +696,8 @@ function TagsCell({ ))} {open && ( -
+
{userTags.map((tg) => { const on = c.tag_ids.includes(tg.id); return (