From a7a1b05817e768574c0cafd2659f19f179fccf2d Mon Sep 17 00:00:00 2001 From: Kawa Date: Wed, 5 Aug 2026 17:18:58 +0200 Subject: [PATCH] fix: theme toggle now properly handles auto mode Remove data-theme attribute when mode="auto" instead of setting it to "auto". Pico's OS-dark selector is :root:not([data-theme]), so any value (even "auto") prevents dark-mode Pico styles. Add Pico form element background vars and color-scheme: light to match active theme. Co-Authored-By: Claude Haiku 4.5 --- imptune/static/app.css | 16 +++++++++++++++- imptune/templates/base.html | 19 ++++++++++++++++--- .../partials/printer_edit_modal.html | 2 +- imptune/templates/partials/printer_list.html | 5 +++-- imptune/templates/printers_new.html | 2 +- tests/e2e/test_theme_toggle.py | 13 +++++++++++-- 6 files changed, 47 insertions(+), 10 deletions(-) diff --git a/imptune/static/app.css b/imptune/static/app.css index e997d0a..3a78c65 100644 --- a/imptune/static/app.css +++ b/imptune/static/app.css @@ -8,7 +8,9 @@ Theme selectors mirror Pico's own so equal specificity + later source order wins: light = :root:not([data-theme=dark]) ; dark = the two dark selectors. - `data-theme="auto"` is not `light`, so it follows the OS preference. + The "system" state renders with **no** data-theme attribute (base.html + removes it) — Pico's OS-dark block is `:root:not([data-theme])`, so a literal + data-theme="auto" would keep Pico light while this file went dark. ========================================================================== */ /* --- Tokens: light (paper) ----------------------------------------------- */ @@ -73,9 +75,15 @@ --pico-form-element-placeholder-color: var(--im-text-faint); --pico-form-element-active-border-color: var(--im-accent); --pico-form-element-focus-color: var(--im-accent); + /* Pico swaps the *background* on :focus/:active. Remap it too, or a focused + field falls back to Pico's own palette instead of ours. */ + --pico-form-element-active-background-color: var(--im-surface); + --pico-form-element-selected-background-color: var(--im-surface-3); --pico-code-background-color: var(--im-surface-3); --pico-code-color: var(--im-text); --pico-modal-overlay-background-color: rgba(24, 30, 36, .42); + /* Native widgets: diff --git a/imptune/templates/partials/printer_list.html b/imptune/templates/partials/printer_list.html index be6583a..b9392cd 100644 --- a/imptune/templates/partials/printer_list.html +++ b/imptune/templates/partials/printer_list.html @@ -18,6 +18,7 @@ ~ (printers | map(attribute='ip_address') | join(' ')) ~ ' ' ~ (printers | map(attribute='port_name') | join(' ')) ~ ' ' ~ (printers | selectattr('driver_id') | map(attribute='driver.original_filename') | join(' ')) ~ ' ' + ~ (printers | selectattr('driver_id') | map(attribute='driver.label') | join(' ')) ~ ' ' ~ client_name %}
{% for p in printers %} - @@ -54,7 +55,7 @@ {% if p.driver_id %} {{ ico.i('check', 12) }}Ready - {{ p.driver.original_filename }} + {{ p.driver.label }} {% else %} {{ ico.i('alert', 12) }}Driver needed {% endif %} diff --git a/imptune/templates/printers_new.html b/imptune/templates/printers_new.html index 0b8156d..3b5572a 100644 --- a/imptune/templates/printers_new.html +++ b/imptune/templates/printers_new.html @@ -65,7 +65,7 @@ {% for item in driver_data %} {% endfor %} diff --git a/tests/e2e/test_theme_toggle.py b/tests/e2e/test_theme_toggle.py index b47f73a..4e2a07f 100644 --- a/tests/e2e/test_theme_toggle.py +++ b/tests/e2e/test_theme_toggle.py @@ -7,9 +7,11 @@ def test_theme_cycles_on_click(page, live_server: str) -> None: """Clicking theme button cycles data-theme attribute: auto -> light -> dark -> auto.""" page.goto(f"{live_server}/", wait_until="domcontentloaded") - # Initial state: auto (default from base.html) + # Initial state: auto — the attribute must be ABSENT, not "auto". Pico's + # OS-dark block is keyed on `:root:not([data-theme])`, so any value pins + # Pico to its light theme while app.css follows the OS into dark. initial_theme = page.evaluate("document.documentElement.getAttribute('data-theme')") - assert initial_theme == "auto" + assert initial_theme is None # Click once -> light page.click("button[aria-label='auto']") @@ -27,6 +29,13 @@ def test_theme_cycles_on_click(page, live_server: str) -> None: ) assert page.evaluate("document.documentElement.getAttribute('data-theme')") == "dark" + # Click again -> auto, which removes the attribute again + page.click("button[aria-label='dark']") + page.wait_for_function( + "!document.documentElement.hasAttribute('data-theme')", + timeout=2000, + ) + def test_theme_persists_across_reload(page, live_server: str) -> None: """After clicking theme toggle, the chosen theme is restored on reload."""