diff --git a/BTCPayServer/Components/MainNav/Default.cshtml b/BTCPayServer/Components/MainNav/Default.cshtml index a741717a5..db1f1b9bf 100644 --- a/BTCPayServer/Components/MainNav/Default.cshtml +++ b/BTCPayServer/Components/MainNav/Default.cshtml @@ -249,7 +249,7 @@
  • - +
  • }
  • diff --git a/BTCPayServer/Components/ThemeSwitch/Default.cshtml b/BTCPayServer/Components/ThemeSwitch/Default.cshtml index 0a4d9c27b..fe34cd3dc 100644 --- a/BTCPayServer/Components/ThemeSwitch/Default.cshtml +++ b/BTCPayServer/Components/ThemeSwitch/Default.cshtml @@ -1,9 +1,10 @@ @model BTCPayServer.Components.ThemeSwitch.ThemeSwitchViewModel - +
    + Theme +
    + + + +
    +
    diff --git a/BTCPayServer/wwwroot/img/icon-sprite.svg b/BTCPayServer/wwwroot/img/icon-sprite.svg index d438dafec..d6f08d33e 100644 --- a/BTCPayServer/wwwroot/img/icon-sprite.svg +++ b/BTCPayServer/wwwroot/img/icon-sprite.svg @@ -77,8 +77,9 @@ - - + + + diff --git a/BTCPayServer/wwwroot/js/theme-switch.js b/BTCPayServer/wwwroot/js/theme-switch.js index ce7da5270..49847237a 100644 --- a/BTCPayServer/wwwroot/js/theme-switch.js +++ b/BTCPayServer/wwwroot/js/theme-switch.js @@ -1,16 +1,30 @@ -const COLOR_MODES = ["light", "dark"]; -const THEME_ATTR = "data-btcpay-theme"; -const STORE_ATTR = "btcpay-theme"; -const systemColorMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? COLOR_MODES[1] : COLOR_MODES[0]; -const userColorMode = window.localStorage.getItem(STORE_ATTR); -const initialColorMode = COLOR_MODES.includes(userColorMode) ? userColorMode : systemColorMode; +(function() { + const COLOR_MODES = ['light', 'dark']; + const THEME_ATTR = 'data-btcpay-theme'; + const STORE_ATTR = 'btcpay-theme'; + const mediaMatcher = window.matchMedia('(prefers-color-scheme: dark)'); -function setColorMode (mode) { - if (COLOR_MODES.includes(mode)) { - window.localStorage.setItem(STORE_ATTR, mode); - document.documentElement.setAttribute(THEME_ATTR, mode); - document.getElementById("DarkThemeLinkTag").setAttribute("rel", mode === "dark" ? "stylesheet" : null); + window.setColorMode = userMode => { + if (userMode === 'system') { + window.localStorage.removeItem(STORE_ATTR); + document.documentElement.removeAttribute(THEME_ATTR); + } else if (COLOR_MODES.includes(userMode)) { + window.localStorage.setItem(STORE_ATTR, userMode); + document.documentElement.setAttribute(THEME_ATTR, userMode); + } + const user = window.localStorage.getItem(STORE_ATTR); + const system = mediaMatcher.matches ? COLOR_MODES[1] : COLOR_MODES[0]; + const mode = user || system; + + document.getElementById('DarkThemeLinkTag').setAttribute('rel', mode === 'dark' ? 'stylesheet' : null); } -} -setColorMode(initialColorMode); + // set initial mode + setColorMode(window.localStorage.getItem(STORE_ATTR)); + + // listen for system mode changes + mediaMatcher.addEventListener('change', e => { + const userMode = window.localStorage.getItem(STORE_ATTR); + if (!userMode) setColorMode('system'); + }); +})(); diff --git a/BTCPayServer/wwwroot/main/layout.css b/BTCPayServer/wwwroot/main/layout.css index 06fd7f778..e465ced30 100644 --- a/BTCPayServer/wwwroot/main/layout.css +++ b/BTCPayServer/wwwroot/main/layout.css @@ -258,41 +258,37 @@ } /* Theme Switch */ -#mainNav .btcpay-theme-switch { - width: 100%; +.btcpay-theme-switch { + + display: inline-flex; + align-items: center; justify-content: space-between; } -#mainNav .btcpay-theme-switch svg { - order: 1; - margin: 0 !important; +.btcpay-theme-switch-label { + font-weight: var(--btcpay-font-weight-semibold); } -#mainNav .btcpay-theme-switch span { - order: 0; - margin: 0; -} - -.btcpay-theme-switch { +.btcpay-theme-switch-themes { display: inline-flex; + gap: var(--btcpay-space-m); align-items: center; +} + +.btcpay-theme-switch-themes button { + --icon-size: 1.25rem !important; background: none; - cursor: pointer; + padding: 0; border: 0; + color: var(--btcpay-body-text-muted); } -.btcpay-theme-switch svg { - height: 1rem; - width: 1rem; +.btcpay-theme-switch-themes button:hover { + color: var(--btcpay-body-link); } -.btcpay-theme-switch svg ~ span { - margin-left: var(--btcpay-space-xs); -} - -.btcpay-theme-switch path { - stroke-width: .5px; - fill: currentColor; +.btcpay-theme-switch-themes button svg { + margin: 0 !important; } .btcpay-theme-switch:hover .btcpay-theme-switch-light, @@ -300,32 +296,10 @@ fill: currentColor; } -.btcpay-theme-switch-dark { - stroke: currentColor; -} - -:root[data-btcpay-theme="dark"] .btcpay-theme-switch-dark { - display: none; -} - -@media (prefers-color-scheme: dark) { - :root:not([data-btcpay-theme="dark"]) .btcpay-theme-switch-dark { - display: inline-block; - } -} - -.btcpay-theme-switch-light { - display: none; -} - -:root[data-btcpay-theme="dark"] .btcpay-theme-switch-light { - display: inline-block; -} - -@media (prefers-color-scheme: dark) { - :root:not([data-btcpay-theme="light"]) .btcpay-theme-switch-light { - display: inline-block; - } +:root:not([data-btcpay-theme]) .btcpay-theme-switch [data-theme="system"], +:root[data-btcpay-theme="light"] .btcpay-theme-switch [data-theme="light"], +:root[data-btcpay-theme="dark"] .btcpay-theme-switch [data-theme="dark"] { + color: var(--btcpay-body-link); } /* Notifications */ diff --git a/BTCPayServer/wwwroot/main/site.js b/BTCPayServer/wwwroot/main/site.js index 949b44fc2..a344717c6 100644 --- a/BTCPayServer/wwwroot/main/site.js +++ b/BTCPayServer/wwwroot/main/site.js @@ -297,12 +297,11 @@ document.addEventListener("DOMContentLoaded", () => { delegate('click', '.switch-time-format', switchTimeFormat); // Theme Switch - delegate('click', '.btcpay-theme-switch', e => { + delegate('click', '.btcpay-theme-switch [data-theme]', e => { e.preventDefault() - const current = document.documentElement.getAttribute(THEME_ATTR) || COLOR_MODES[0] - const mode = current === COLOR_MODES[0] ? COLOR_MODES[1] : COLOR_MODES[0] - setColorMode(mode) - e.target.closest('.btcpay-theme-switch').blur() + const $btn = e.target.closest('.btcpay-theme-switch [data-theme]') + setColorMode($btn.dataset.theme) + $btn.blur() }) // Sensitive Info