You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ka...@apache.org on 2026/04/16 00:17:48 UTC
(airflow-site) 01/01: Replace theme dropdown with sun/moon pill toggle, fix navbar alignment
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch improve-theme-toggle
in repository https://gitbox.apache.org/repos/asf/airflow-site.git
commit d7728244e445c39c026fd1b5a52cb263f98cf5f9
Author: Kaxil Naik <ka...@gmail.com>
AuthorDate: Thu Apr 16 01:17:34 2026 +0100
Replace theme dropdown with sun/moon pill toggle, fix navbar alignment
- Replace the 3-option dropdown (Light/Dark/Auto) with a compact sun/moon
pill toggle — single click instead of two, shows both states at a glance
- Auto (system preference) is the implicit default on first visit; once
the user clicks sun or moon, their choice is stored in localStorage
- Remove redundant theme toggle from inside navbar links container
- Fix navbar link vertical alignment: remove padding-top:16px on
menu-content that was sized for the old 30px navbar padding
- Add flex-wrap:nowrap to navbar to prevent pill from wrapping to next line
- Clean up unused SVG symbols (check2, circle-half) and dropdown JS logic
- Apply same changes to both Hugo (theme-toggler.html, dark-mode.js)
and Sphinx theme (header.html, layout.html)
---
.github/pr-assets/after-dark.png | Bin 0 -> 9934 bytes
.github/pr-assets/after-light.png | Bin 0 -> 9474 bytes
.github/pr-assets/before-dark.png | Bin 0 -> 9934 bytes
.github/pr-assets/before-light.png | Bin 0 -> 9474 bytes
landing-pages/site/assets/js/dark-mode.js | 94 +++++---------------
landing-pages/site/assets/scss/_navbar.scss | 96 ++------------------
landing-pages/site/assets/scss/main-custom.scss | 62 +++++++++++++
landing-pages/site/layouts/partials/navbar.html | 5 --
.../site/layouts/partials/theme-toggler.html | 56 ++----------
sphinx_airflow_theme/.theme_files_hash | 2 +-
sphinx_airflow_theme/LATEST_VERSION.txt | 2 +-
.../sphinx_airflow_theme/__init__.py | 2 +-
.../sphinx_airflow_theme/header.html | 40 ++-------
.../sphinx_airflow_theme/layout.html | 98 ++++++---------------
14 files changed, 137 insertions(+), 320 deletions(-)
diff --git a/.github/pr-assets/after-dark.png b/.github/pr-assets/after-dark.png
new file mode 100644
index 0000000000..a956997ffb
Binary files /dev/null and b/.github/pr-assets/after-dark.png differ
diff --git a/.github/pr-assets/after-light.png b/.github/pr-assets/after-light.png
new file mode 100644
index 0000000000..1118d9417f
Binary files /dev/null and b/.github/pr-assets/after-light.png differ
diff --git a/.github/pr-assets/before-dark.png b/.github/pr-assets/before-dark.png
new file mode 100644
index 0000000000..a956997ffb
Binary files /dev/null and b/.github/pr-assets/before-dark.png differ
diff --git a/.github/pr-assets/before-light.png b/.github/pr-assets/before-light.png
new file mode 100644
index 0000000000..1118d9417f
Binary files /dev/null and b/.github/pr-assets/before-light.png differ
diff --git a/landing-pages/site/assets/js/dark-mode.js b/landing-pages/site/assets/js/dark-mode.js
index 5d1b5aea26..55cbbf65db 100644
--- a/landing-pages/site/assets/js/dark-mode.js
+++ b/landing-pages/site/assets/js/dark-mode.js
@@ -17,16 +17,6 @@
* under the License.
*/
-/*!
- * This is a Docsy-adapted version of https://github.com/twbs/examples/blob/main/color-modes/js/color-modes.js.
- *
- * Original header:
- *
- * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
- * Copyright 2011-2024 The Bootstrap Authors
- * Licensed under the Creative Commons Attribution 3.0 Unported License.
- */
-
(() => {
'use strict'
@@ -39,82 +29,44 @@
if (storedTheme) {
return storedTheme
}
-
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
const setTheme = theme => {
- if (theme === 'auto') {
- document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'))
- } else {
- document.documentElement.setAttribute('data-bs-theme', theme)
- }
+ document.documentElement.setAttribute('data-bs-theme', theme)
}
- setTheme(getPreferredTheme())
-
- const showActiveTheme = (theme, focus = false) => {
- const themeSwitchers = document.querySelectorAll('#bd-theme')
-
- if (!themeSwitchers.length) {
- return
- }
-
- themeSwitchers.forEach(themeSwitcher => {
- const themeSwitcherText = document.querySelector('#bd-theme-text')
- const activeThemeIcon = themeSwitcher.querySelector('.theme-icon-active use')
- const dropdownMenu = themeSwitcher.nextElementSibling
-
- if (!dropdownMenu) return
-
- const btnToActive = dropdownMenu.querySelector(`[data-bs-theme-value="${theme}"]`)
-
- if (!btnToActive) return
-
- const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href')
-
- dropdownMenu.querySelectorAll('[data-bs-theme-value]').forEach(element => {
- element.classList.remove('active')
- element.setAttribute('aria-pressed', 'false')
- })
-
- btnToActive.classList.add('active')
- btnToActive.setAttribute('aria-pressed', 'true')
-
- if (activeThemeIcon) {
- activeThemeIcon.setAttribute('href', svgOfActiveBtn)
- }
-
- if (themeSwitcherText) {
- const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`
- themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)
- }
-
- if (focus) {
- themeSwitcher.focus()
- }
+ const updateToggle = (theme) => {
+ document.querySelectorAll('.theme-toggle-pill__btn').forEach(btn => {
+ const isActive = btn.getAttribute('data-theme-value') === theme
+ btn.classList.toggle('active', isActive)
+ btn.setAttribute('aria-pressed', isActive)
})
}
+ // Apply theme immediately (before DOM ready) to prevent flash
+ setTheme(getPreferredTheme())
+
+ // Follow system preference changes when no explicit choice stored
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
- const storedTheme = getStoredTheme()
- if (storedTheme !== 'light' && storedTheme !== 'dark') {
- setTheme(getPreferredTheme())
+ if (!getStoredTheme()) {
+ const theme = getPreferredTheme()
+ setTheme(theme)
+ updateToggle(theme)
}
})
const init = () => {
- showActiveTheme(getPreferredTheme())
-
- document.querySelectorAll('[data-bs-theme-value]')
- .forEach(toggle => {
- toggle.addEventListener('click', () => {
- const theme = toggle.getAttribute('data-bs-theme-value')
- setStoredTheme(theme)
- setTheme(theme)
- showActiveTheme(theme, true)
- })
+ updateToggle(getPreferredTheme())
+
+ document.querySelectorAll('.theme-toggle-pill__btn').forEach(btn => {
+ btn.addEventListener('click', () => {
+ const theme = btn.getAttribute('data-theme-value')
+ setStoredTheme(theme)
+ setTheme(theme)
+ updateToggle(theme)
})
+ })
}
if (document.readyState === 'loading') {
diff --git a/landing-pages/site/assets/scss/_navbar.scss b/landing-pages/site/assets/scss/_navbar.scss
index ca669e3c87..6ab2d041cd 100644
--- a/landing-pages/site/assets/scss/_navbar.scss
+++ b/landing-pages/site/assets/scss/_navbar.scss
@@ -27,6 +27,8 @@
border-bottom: solid 1px map-get($colors, very-light-pink);
z-index: 32;
padding: 14px 60px;
+ flex-wrap: nowrap;
+ align-items: center;
transition: background-color 0.3s ease, border-color 0.3s ease;
&__menu-container {
@@ -37,7 +39,7 @@
display: flex;
justify-content: space-between;
align-items: center;
- padding-top: 16px;
+ padding-top: 0;
padding-left: 88px;
}
@@ -76,58 +78,14 @@
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .12);
}
- // Theme toggle styling
+ // Theme toggle styling — pill toggle (sun/moon)
&__theme-toggle {
- display: inline-flex;
+ display: flex;
align-items: center;
- position: relative;
- margin-top: 0;
- transform: translateY(-2px);
+ order: 10; // push to far right in the navbar flex layout
@media (max-width: $tablet) {
- transform: none;
- margin-right: 20px;
- margin-left: auto;
- }
-
- .btn {
- padding: 0.25rem 0.5rem;
- font-size: 0.875rem;
- border: none;
- background: none;
-
- svg {
- width: 1rem;
- height: 1rem;
- }
- }
-
- .dropdown-menu {
- font-size: 0.8125rem;
- min-width: 7rem;
- padding: 0.25rem 0;
- left: auto !important;
- right: 0 !important;
-
- .dropdown-item {
- padding: 0.375rem 0.75rem;
- font-size: 0.8125rem;
- justify-content: center;
-
- &:not(.active):hover, &:not(.active):focus {
- background-color: map-get($colors, very-light-pink);
- }
-
- svg {
- width: 0.875rem;
- height: 0.875rem;
- fill: currentColor;
- }
-
- .ms-auto {
- margin-left: 0.5rem !important;
- }
- }
+ margin-right: 12px;
}
}
}
@@ -233,45 +191,5 @@
background-color: var(--bs-body-bg);
}
- // Theme toggle button visibility in dark mode
- &__theme-toggle {
- .btn,
- .btn-link,
- .nav-link {
- color: var(--bs-body-color) !important;
-
- &:hover, &:focus {
- color: var(--bs-emphasis-color) !important;
- }
-
- svg {
- fill: currentColor !important;
- color: currentColor !important;
-
- use {
- fill: currentColor !important;
- }
- }
- }
-
- .dropdown-menu {
- background-color: var(--bs-secondary-bg);
- border-color: var(--bs-border-color);
-
- .dropdown-item:not(.active) {
- color: var(--bs-body-color);
-
- &:hover, &:focus {
- background-color: var(--bs-tertiary-bg);
- color: var(--bs-emphasis-color);
- }
- }
-
- .dropdown-item.active {
- background-color: var(--bs-link-color);
- color: #fff;
- }
- }
- }
}
}
diff --git a/landing-pages/site/assets/scss/main-custom.scss b/landing-pages/site/assets/scss/main-custom.scss
index defe50572b..ad0d949ef6 100644
--- a/landing-pages/site/assets/scss/main-custom.scss
+++ b/landing-pages/site/assets/scss/main-custom.scss
@@ -60,6 +60,68 @@
@import "testimonial";
@import "suggest-change";
+/* Theme toggle pill (sun/moon) */
+.theme-toggle-pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 2px;
+ padding: 3px;
+ border-radius: 999px;
+ background-color: #e9ecef;
+ border: 1px solid #dee2e6;
+ transition: background-color 0.2s ease, border-color 0.2s ease;
+
+ &__btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 30px;
+ height: 30px;
+ padding: 0;
+ border: none;
+ border-radius: 50%;
+ background: transparent;
+ color: #636365;
+ cursor: pointer;
+ transition: background-color 0.2s ease, color 0.2s ease;
+
+ &:hover {
+ color: #333;
+ }
+
+ &.active {
+ background-color: #fff;
+ color: #333;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
+ }
+
+ svg {
+ width: 16px;
+ height: 16px;
+ fill: currentColor;
+ }
+ }
+}
+
+[data-bs-theme="dark"] .theme-toggle-pill {
+ background-color: rgba(255, 255, 255, 0.08);
+ border-color: rgba(255, 255, 255, 0.1);
+
+ .theme-toggle-pill__btn {
+ color: rgba(255, 255, 255, 0.5);
+
+ &:hover {
+ color: rgba(255, 255, 255, 0.8);
+ }
+
+ &.active {
+ background-color: rgba(255, 255, 255, 0.15);
+ color: rgba(255, 255, 255, 0.95);
+ box-shadow: none;
+ }
+ }
+}
+
/* Blog Snippet Section */
.blog-snippet-list {
display: grid;
diff --git a/landing-pages/site/layouts/partials/navbar.html b/landing-pages/site/layouts/partials/navbar.html
index 3043c67bb9..ca5ad81a57 100644
--- a/landing-pages/site/layouts/partials/navbar.html
+++ b/landing-pages/site/layouts/partials/navbar.html
@@ -74,11 +74,6 @@
{{ $el.Name }}
</a>
{{ end }}
- {{ if .Site.Params.ui.showLightDarkModeMenu -}}
- <div class="navbar__theme-toggle">
- {{ partial "theme-toggler" . }}
- </div>
- {{ end -}}
</div>
</div>
{{ end }}
diff --git a/landing-pages/site/layouts/partials/theme-toggler.html b/landing-pages/site/layouts/partials/theme-toggler.html
index dd5ed9a55e..469cd91bc3 100644
--- a/landing-pages/site/layouts/partials/theme-toggler.html
+++ b/landing-pages/site/layouts/partials/theme-toggler.html
@@ -17,15 +17,7 @@
under the License.
*/}}
-{{/* Adapted from: https://github.com/twbs/bootstrap/blob/main/site/layouts/partials/icons.html */ -}}
-
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
- <symbol id="check2" viewBox="0 0 16 16">
- <path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/>
- </symbol>
- <symbol id="circle-half" viewBox="0 0 16 16">
- <path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z"/>
- </symbol>
<symbol id="moon-stars-fill" viewBox="0 0 16 16">
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/>
<path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l- [...]
@@ -35,43 +27,11 @@
</symbol>
</svg>
-{{/* Adapted from: https://github.com/twbs/bootstrap/blob/main/site/layouts/partials/theme-toggler.html */ -}}
-
-{{ $isExamples := eq .Layout "examples" -}}
-<button class="btn
- {{- if $isExamples }} btn-bd-primary
- {{- else }} btn-link nav-link
- {{- end }} dropdown-toggle d-flex align-items-center theme-switcher" id="bd-theme"
- type="button"
- aria-expanded="false"
- data-bs-toggle="dropdown"
- {{ if not $isExamples }}data-bs-display="static"{{ end }}
- aria-label="Toggle theme (auto)">
- <svg class="bi my-1 theme-icon-active"><use href="#circle-half"></use></svg>
- {{- /* Disable menu name for Docsy:
- <span class="{{ if $isExamples }}visually-hidden{{ else }}d-lg-none ms-2{{ end }}" id="bd-theme-text">Toggle theme</span>
- */}}
-</button>
-<ul class="dropdown-menu dropdown-menu-end{{ if $isExamples }} shadow{{ end }}" aria-labelledby="bd-theme">
- <li>
- <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
- <svg class="bi me-2 opacity-50"><use href="#sun-fill"></use></svg>
- Light
- <svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
- </button>
- </li>
- <li>
- <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
- <svg class="bi me-2 opacity-50"><use href="#moon-stars-fill"></use></svg>
- Dark
- <svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
- </button>
- </li>
- <li>
- <button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto" aria-pressed="true">
- <svg class="bi me-2 opacity-50"><use href="#circle-half"></use></svg>
- Auto
- <svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
- </button>
- </li>
-</ul>
+<div class="theme-toggle-pill" role="radiogroup" aria-label="Toggle color theme">
+ <button type="button" class="theme-toggle-pill__btn" data-theme-value="light" aria-label="Light theme">
+ <svg class="bi"><use href="#sun-fill"></use></svg>
+ </button>
+ <button type="button" class="theme-toggle-pill__btn" data-theme-value="dark" aria-label="Dark theme">
+ <svg class="bi"><use href="#moon-stars-fill"></use></svg>
+ </button>
+</div>
diff --git a/sphinx_airflow_theme/.theme_files_hash b/sphinx_airflow_theme/.theme_files_hash
index 8859b075f9..769bd07882 100644
--- a/sphinx_airflow_theme/.theme_files_hash
+++ b/sphinx_airflow_theme/.theme_files_hash
@@ -1 +1 @@
-1086787f171cfa7569806c9dc130755931e0c52f16e036253ec4ac1deedace38
+f46dbcb27d4a704f9be5ce49eec3ec283353e17a0f233b0e4f5945a012b0b38f
diff --git a/sphinx_airflow_theme/LATEST_VERSION.txt b/sphinx_airflow_theme/LATEST_VERSION.txt
index 449d7e73a9..0f82685331 100644
--- a/sphinx_airflow_theme/LATEST_VERSION.txt
+++ b/sphinx_airflow_theme/LATEST_VERSION.txt
@@ -1 +1 @@
-0.3.6
+0.3.7
diff --git a/sphinx_airflow_theme/sphinx_airflow_theme/__init__.py b/sphinx_airflow_theme/sphinx_airflow_theme/__init__.py
index d8f848df74..5b4336f16f 100644
--- a/sphinx_airflow_theme/sphinx_airflow_theme/__init__.py
+++ b/sphinx_airflow_theme/sphinx_airflow_theme/__init__.py
@@ -18,7 +18,7 @@
from os import path
from sphinx.application import Sphinx
-__version__ = '0.3.6'
+__version__ = '0.3.7'
__version_full__ = __version__
diff --git a/sphinx_airflow_theme/sphinx_airflow_theme/header.html b/sphinx_airflow_theme/sphinx_airflow_theme/header.html
index 67f6828012..e3dedcda13 100644
--- a/sphinx_airflow_theme/sphinx_airflow_theme/header.html
+++ b/sphinx_airflow_theme/sphinx_airflow_theme/header.html
@@ -71,38 +71,14 @@
</div>
<div class="navbar__theme-toggle">
- <button class="btn btn-link nav-link dropdown-toggle d-flex align-items-center"
- id="bd-theme"
- type="button"
- aria-expanded="false"
- data-bs-toggle="dropdown"
- data-bs-display="static"
- aria-label="Toggle theme (auto)">
- <svg class="bi my-1 theme-icon-active"><use href="#circle-half"></use></svg>
- </button>
- <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme-text">
- <li>
- <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
- <svg class="bi me-2 theme-icon-active"><use href="#sun-fill"></use></svg>
- Light
- <svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
- </button>
- </li>
- <li>
- <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
- <svg class="bi me-2 theme-icon-active"><use href="#moon-stars-fill"></use></svg>
- Dark
- <svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
- </button>
- </li>
- <li>
- <button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto" aria-pressed="true">
- <svg class="bi me-2 theme-icon-active"><use href="#circle-half"></use></svg>
- Auto
- <svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
- </button>
- </li>
- </ul>
+ <div class="theme-toggle-pill" role="radiogroup" aria-label="Toggle color theme">
+ <button type="button" class="theme-toggle-pill__btn" data-theme-value="light" aria-label="Light theme">
+ <svg class="bi"><use href="#sun-fill"></use></svg>
+ </button>
+ <button type="button" class="theme-toggle-pill__btn" data-theme-value="dark" aria-label="Dark theme">
+ <svg class="bi"><use href="#moon-stars-fill"></use></svg>
+ </button>
+ </div>
</div>
<div class="mobile-only navbar__drawer-container">
<button class="navbar__toggle-button" id="navbar-toggle-button">
diff --git a/sphinx_airflow_theme/sphinx_airflow_theme/layout.html b/sphinx_airflow_theme/sphinx_airflow_theme/layout.html
index 1f6f30e5ff..b9b2e1b788 100644
--- a/sphinx_airflow_theme/sphinx_airflow_theme/layout.html
+++ b/sphinx_airflow_theme/sphinx_airflow_theme/layout.html
@@ -325,12 +325,6 @@
{%- block body_tag %}<body class="td-section">{% endblock %}
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
- <symbol id="check2" viewBox="0 0 16 16">
- <path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/>
- </symbol>
- <symbol id="circle-half" viewBox="0 0 16 16">
- <path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z"/>
- </symbol>
<symbol id="moon-stars-fill" viewBox="0 0 16 16">
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/>
<path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l- [...]
@@ -341,92 +335,52 @@
</svg>
<script>
- /*!
- * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
- * Copyright 2011-2024 The Bootstrap Authors
- * Licensed under Creative Commons Attribution 3.0 Unported License.
- */
-
(() => {
'use strict'
- const getStoredTheme = () => localStorage.getItem('theme')
- const setStoredTheme = theme => localStorage.setItem('theme', theme)
+ const themeKey = 'theme'
+ const getStoredTheme = () => localStorage.getItem(themeKey)
+ const setStoredTheme = theme => localStorage.setItem(themeKey, theme)
const getPreferredTheme = () => {
const storedTheme = getStoredTheme()
- if (storedTheme) {
- return storedTheme
- }
-
- return 'auto'
+ if (storedTheme) return storedTheme
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
const setTheme = theme => {
- if (theme === 'auto') {
- document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'))
- } else {
- document.documentElement.setAttribute('data-bs-theme', theme)
- }
+ document.documentElement.setAttribute('data-bs-theme', theme)
}
- setTheme(getPreferredTheme())
-
- const showActiveTheme = (theme, focus = false) => {
- const themeSwitcher = document.querySelector('#bd-theme')
-
- if (!themeSwitcher) {
- return
- }
-
- const themeSwitcherText = document.querySelector('#bd-theme-text')
- const activeThemeIcon = document.querySelector('.theme-icon-active use')
- const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
- const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href')
-
- document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
- element.classList.remove('active')
- element.setAttribute('aria-pressed', 'false')
- const checkIcon = element.querySelector('.bi.ms-auto')
- if (checkIcon) {
- checkIcon.classList.add('d-none')
- }
+ const updateToggle = (theme) => {
+ document.querySelectorAll('.theme-toggle-pill__btn').forEach(btn => {
+ const isActive = btn.getAttribute('data-theme-value') === theme
+ btn.classList.toggle('active', isActive)
+ btn.setAttribute('aria-pressed', isActive)
})
-
- btnToActive.classList.add('active')
- btnToActive.setAttribute('aria-pressed', 'true')
- const activeCheckIcon = btnToActive.querySelector('.bi.ms-auto')
- if (activeCheckIcon) {
- activeCheckIcon.classList.remove('d-none')
- }
- activeThemeIcon.setAttribute('href', svgOfActiveBtn)
- const themeSwitcherLabel = `${themeSwitcherText ? themeSwitcherText.textContent : ''} (${btnToActive.dataset.bsThemeValue})`
- themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)
-
- if (focus) {
- themeSwitcher.focus()
- }
}
+ setTheme(getPreferredTheme())
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
- const storedTheme = getStoredTheme()
- if (storedTheme !== 'light' && storedTheme !== 'dark') {
- setTheme(getPreferredTheme())
+ if (!getStoredTheme()) {
+ const theme = getPreferredTheme()
+ setTheme(theme)
+ updateToggle(theme)
}
})
window.addEventListener('DOMContentLoaded', () => {
- showActiveTheme(getPreferredTheme())
-
- document.querySelectorAll('[data-bs-theme-value]')
- .forEach(toggle => {
- toggle.addEventListener('click', () => {
- const theme = toggle.getAttribute('data-bs-theme-value')
- setStoredTheme(theme)
- setTheme(theme)
- showActiveTheme(theme, true)
- })
+ updateToggle(getPreferredTheme())
+
+ document.querySelectorAll('.theme-toggle-pill__btn').forEach(btn => {
+ btn.addEventListener('click', () => {
+ const theme = btn.getAttribute('data-theme-value')
+ setStoredTheme(theme)
+ setTheme(theme)
+ updateToggle(theme)
})
+ })
})
})()
</script>