From 3c6ea681e7a8003cffef7565abf5241b3dd44035 Mon Sep 17 00:00:00 2001 From: coy Date: Wed, 27 May 2026 11:03:50 -0400 Subject: [PATCH] dynamically follow system theme when `respect-user-color-scheme: true` --- .../formats/html/templates/quarto-html-before-body.ejs | 9 +++++---- .../tests/html-dark-mode-defaultdark.spec.ts | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/resources/formats/html/templates/quarto-html-before-body.ejs b/src/resources/formats/html/templates/quarto-html-before-body.ejs index a81090e2bfa..931ff8f1db5 100644 --- a/src/resources/formats/html/templates/quarto-html-before-body.ejs +++ b/src/resources/formats/html/templates/quarto-html-before-body.ejs @@ -191,11 +191,12 @@ <% if (respectUserColorScheme) { %> queryPrefersDark.addEventListener("change", e => { - if(window.localStorage.getItem("quarto-color-scheme") !== null) - return; - const alternate = e.matches + const alternate = e.matches; + if (window.localStorage.getItem("quarto-color-scheme") !== null) { + window.localStorage.removeItem("quarto-color-scheme"); + } toggleColorMode(alternate); - localAlternateSentinel = e.matches ? 'alternate' : 'default'; // this is used alongside local storage! + localAlternateSentinel = alternate ? 'alternate' : 'default'; toggleGiscusIfUsed(alternate, darkModeDefault); }); <% } %> diff --git a/tests/integration/playwright/tests/html-dark-mode-defaultdark.spec.ts b/tests/integration/playwright/tests/html-dark-mode-defaultdark.spec.ts index a21c808674f..6796b42a2f9 100644 --- a/tests/integration/playwright/tests/html-dark-mode-defaultdark.spec.ts +++ b/tests/integration/playwright/tests/html-dark-mode-defaultdark.spec.ts @@ -89,7 +89,7 @@ test('Project specifies dark and light brands, dynamic respect-user-color-scheme }); -test('Project specifies dark and light brands, do not respect-user-color-scheme after toggling', async ({ page }) => { +test('Project specifies dark and light brands, manual override expires on system theme change', async ({ page }) => { await page.goto('./html/dark-brand/project-dark/simple-respect-color-scheme.html'); const locatr = await page.locator('body').first(); await expect(locatr).toHaveClass(`fullcontent quarto-dark`); @@ -100,8 +100,10 @@ test('Project specifies dark and light brands, do not respect-user-color-scheme await check_backgrounds(page, 'quarto-light', blue, red); await check_toggle(page, true); + // After the system theme changes, the manual override expires + // and the page follows the system again await page.emulateMedia({ colorScheme: 'light' }); - await expect(locatr).toHaveClass(`fullcontent quarto-dark`); - await expect(locatr).toHaveCSS('background-color', red); - await check_toggle(page, true); + await expect(locatr).toHaveClass(`fullcontent quarto-light`); + await expect(locatr).toHaveCSS('background-color', blue); + await check_toggle(page, false); });