fix(buttons,footer): unify disabled state + restyle Help/Close as nav links

(3) Disabled primary buttons no longer read as a "whited-out" dark
slab. Streamlit's primary-button selector
``button[data-testid="stBaseButton-primary"]`` has the same
specificity as our previous ``button:disabled`` selector, so the
primary background + cream text kept winning the cascade tie-break.
The disabled rule's selector list now explicitly matches both the
``kind="primary"``/``kind="secondary"`` shapes AND the
``stBaseButton-primary``/``-secondary`` testids, so disabled
buttons collapse to ``surface-hover`` background, ``ink-tertiary``
label, soft border — same look regardless of starting kind. A
follow-up rule re-asserts ``color: var(--ink-tertiary)`` on every
descendant of the disabled primary so the inner
``stMarkdownContainer > p`` doesn't keep the cream label from the
"all descendants get --bg" primary rule.

(4) The sticky-footer Help + Close buttons now match the sidebar
nav-item look. Old outlined-pill chrome is gone:
``.datatools-footer-btn`` is now display:inline-flex with a
Material-Symbols ligature icon + label, borderless, ``ink-secondary``
text on a transparent surface, ``rgba(0,0,0,0.04)`` hover background.
The Close button keeps a danger tint via ``.close`` so it still reads
as the shut-down action, with a soft ``--danger-fill`` hover. Help
uses the ``help_outline`` icon, Close uses ``power_settings_new``.
Built via a small ``makeFooterBtn`` helper in the iframe JS that
appends the icon span + label text node to the button — keeps the
existing soft-nav click handlers intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 01:12:03 +00:00
parent 784695e3a7
commit 06f1ea6cf7

View File

@@ -311,13 +311,30 @@ body, .stApp {
color: inherit !important;
}
/* Disabled state — same low-contrast for both kinds. */
[data-testid="stButton"] button:disabled {
/* Disabled state — same low-contrast look for primary and secondary
kinds. Selector list explicitly includes
``button[data-testid="stBaseButton-primary"]:disabled`` so this rule
beats the primary-button block's identically-shaped selector on
specificity tie-breaks — without that, the primary's dark-ink
background stays and the disabled state reads as a black button
with greyed-out text. */
[data-testid="stButton"] button:disabled,
[data-testid="stButton"] button[kind="primary"]:disabled,
[data-testid="stButton"] button[kind="secondary"]:disabled,
[data-testid="stButton"] button[data-testid="stBaseButton-primary"]:disabled,
[data-testid="stButton"] button[data-testid="stBaseButton-secondary"]:disabled {
background: var(--surface-hover) !important;
color: var(--ink-tertiary) !important;
border-color: var(--border) !important;
border: 1px solid var(--border) !important;
cursor: not-allowed !important;
}
/* Override the "every descendant gets ``--bg``" rule the primary
block declares so the label inside a disabled primary button
inherits the tertiary ink color too, not the cream ``--bg``. */
[data-testid="stButton"] button[kind="primary"]:disabled *,
[data-testid="stButton"] button[data-testid="stBaseButton-primary"]:disabled * {
color: var(--ink-tertiary) !important;
}
/* ---------- File uploader — soft cream dropzone ---------- */
[data-testid="stFileUploader"] section,
@@ -1339,30 +1356,49 @@ def render_sticky_footer() -> None:
box-sizing: border-box !important;
min-height: 32px !important;
}
/* Footer buttons match the sidebar nav-item style: borderless,
icon + label, ink-secondary text, soft hover. Close keeps a danger
tint via the ``.close`` modifier so it still reads as the
shut-down action without the outlined-pill chrome it used to wear. */
#datatools-sticky-footer .datatools-footer-btn {
display: inline-block !important;
color: rgb(38, 39, 48) !important;
background: rgb(240, 242, 246) !important;
display: inline-flex !important;
align-items: center !important;
gap: 8px !important;
color: var(--ink-secondary) !important;
background: transparent !important;
text-decoration: none !important;
padding: 0.2rem 0.6rem !important;
border-radius: 0.35rem !important;
border: 1px solid rgba(49, 51, 63, 0.22) !important;
font-size: 12px !important;
padding: 5px 10px !important;
border-radius: var(--r-sm) !important;
border: none !important;
font-family: var(--font-sans) !important;
font-size: 13px !important;
font-weight: 500 !important;
line-height: 1.3 !important;
cursor: pointer !important;
transition: background 0.12s ease, border-color 0.12s ease;
transition: background 0.12s ease, color 0.12s ease;
}
#datatools-sticky-footer .datatools-footer-btn:hover {
background: rgb(225, 228, 235) !important;
border-color: rgba(49, 51, 63, 0.35) !important;
background: rgba(0, 0, 0, 0.04) !important;
color: var(--ink) !important;
}
/* The icon ligature span inside each button — Material Symbols, 16px,
inherits the surrounding ink color so hover-tint propagates. */
#datatools-sticky-footer .datatools-footer-btn .dt-mui {
font-family: "Material Symbols Outlined" !important;
font-size: 16px !important;
font-weight: 400 !important;
font-feature-settings: normal !important;
letter-spacing: 0 !important;
line-height: 1 !important;
}
/* Close — danger tint stays as a hint but the chrome is otherwise
identical to Help. */
#datatools-sticky-footer .datatools-footer-btn.close {
color: rgb(176, 0, 32) !important;
border-color: rgba(176, 0, 32, 0.35) !important;
color: var(--danger) !important;
}
#datatools-sticky-footer .datatools-footer-btn.close:hover {
background: rgba(176, 0, 32, 0.08) !important;
background: var(--danger-fill) !important;
color: var(--danger) !important;
}
#datatools-help-popover {
position: fixed !important;
@@ -1494,15 +1530,21 @@ a[data-testid="stPageLink-NavLink"][href*="close"] {
var div = doc.createElement('div');
div.id = 'datatools-sticky-footer';
var helpBtn = doc.createElement('button');
helpBtn.type = 'button';
helpBtn.className = 'datatools-footer-btn help';
helpBtn.textContent = labels.help;
var closeBtn = doc.createElement('button');
closeBtn.type = 'button';
closeBtn.className = 'datatools-footer-btn close';
closeBtn.textContent = labels.close;
// Build a button with a Material-Symbols ligature icon + label,
// matching the sidebar nav-link layout.
function makeFooterBtn(cls, iconName, label) {{
var btn = doc.createElement('button');
btn.type = 'button';
btn.className = 'datatools-footer-btn ' + cls;
var icon = doc.createElement('span');
icon.className = 'dt-mui';
icon.textContent = iconName;
btn.appendChild(icon);
btn.appendChild(doc.createTextNode(label));
return btn;
}}
var helpBtn = makeFooterBtn('help', 'help_outline', labels.help);
var closeBtn = makeFooterBtn('close', 'power_settings_new', labels.close);
// Soft-nav via the hidden ``st.page_link`` that
// ``render_sticky_footer`` injects. Streamlit owns its click
// handler and will route through ``st.switch_page`` (same