From 4a8961d58a3f66699d4c9a7e7142f6c9dfccf1db Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 2 Jun 2026 17:54:41 +0000 Subject: [PATCH] fix(gui): keep tool-page Help button on one line at narrow widths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the viewport shrunk, the help popover button in the title row was wrapping its label vertically — ``[icon]`` over ``Help`` — because the button was set to use_container_width=True and the column it sat in collapsed below the button's natural width. Two-pronged fix: - Set use_container_width=False on the popover so the button sizes to content (icon + label) instead of stretching to the column. - Widen the column ratio from [10, 1] to [8, 2] so there's room for the button without forcing the title text to truncate. - Add CSS pinning ``white-space: nowrap`` on every popover button (and its inner div / p) as defense-in-depth — even if the button does get squeezed, the label can't wrap. ``min-width: max-content`` keeps the button from compressing below its content. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/gui/components/_legacy.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/gui/components/_legacy.py b/src/gui/components/_legacy.py index 78ef4a7..47a0125 100644 --- a/src/gui/components/_legacy.py +++ b/src/gui/components/_legacy.py @@ -369,6 +369,25 @@ body, .stApp { color: var(--ink) !important; } +/* ---------- Popover button — never wrap the label ---------- + Tagged ``dt-help-popover`` in code comments so the render-time + docstring can point editors here. Streamlit's popover trigger is + a normal button; on the tool-page header it sits in a narrow + column right of the title, and a small viewport was squeezing + the column enough to wrap ``Help`` onto two lines under the icon. + ``white-space: nowrap`` keeps the icon + label on one line; the + companion ``min-width: max-content`` keeps the BUTTON itself from + shrinking below its content, so it overflows the column cleanly + instead of compressing into a vertical pile. */ +[data-testid="stPopover"] button { + white-space: nowrap !important; + min-width: max-content !important; +} +[data-testid="stPopover"] button > div, +[data-testid="stPopover"] button > div > p { + white-space: nowrap !important; +} + /* Inline + block code → mono with subtle accent chip. theme.py owns the family + size; this layer adds the warm-fill background. */ [data-testid="stMarkdownContainer"] code { @@ -2131,8 +2150,16 @@ def render_tool_header(tool_id: str) -> None: column is narrow; the title gets the rest. Vertical alignment is left to Streamlit's column default (top) — works on 1.35+ without the ``vertical_alignment`` kwarg that landed later. + + The popover button uses ``use_container_width=False`` so it sizes + to its content (icon + ``Help`` label). With ``True`` the button + stretches to fill the narrow column, and when the viewport shrinks + the label was wrapping vertically. The companion CSS rule (search + ``dt-help-popover``) pins ``white-space: nowrap`` on every popover + button as a defense-in-depth so the label can never wrap, no + matter how the column ends up sized. """ - col_title, col_help = st.columns([10, 1]) + col_title, col_help = st.columns([8, 2]) with col_title: st.title(_t(f"tools.{tool_id}.page_title")) with col_help: @@ -2146,7 +2173,7 @@ def render_tool_header(tool_id: str) -> None: with st.popover( _t("help.button_label"), icon=":material/help_outline:", - use_container_width=True, + use_container_width=False, ): st.markdown(body) st.caption(_t(f"tools.{tool_id}.page_caption"))