Skip to content

Commit 32ddeb2

Browse files
committed
Improve theme switcher accessibility, show check
This commit mirrors twbs/bootstrap#37780 with ~~a small fix~~ a fix from twbs/bootstrap#37836 and adds the missing checkmark icon to the theme dropdown.
1 parent eec703c commit 32ddeb2

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

static/css/style.css

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
fill: currentcolor;
77
}
88

9+
.checked-dropdown .active .bi {
10+
display: block !important;
11+
}
12+
913
.logout-btn {
1014
--bs-dropdown-link-color: var(--bs-danger-text);
1115
--bs-border-color: var(--bs-danger-border-subtle);

static/js/theme_toggle.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,27 @@
2727

2828
setTheme(getPreferredTheme());
2929

30-
const showActiveTheme = (theme) => {
30+
const showActiveTheme = (theme, focus = false) => {
31+
const themeSwitcher = document.querySelector("#theme-btn");
32+
const themeSwitcherText = document.querySelector("#theme-toggle-text");
3133
const activeThemeIcon = document.querySelector(".theme-icon-active use");
3234
const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`);
3335
const svgOfActiveBtn = btnToActive.querySelector("svg use").getAttribute("href");
3436

3537
document.querySelectorAll("[data-bs-theme-value]").forEach((element) => {
3638
element.classList.remove("active");
39+
element.setAttribute("aria-pressed", "false");
3740
});
3841

3942
btnToActive.classList.add("active");
43+
btnToActive.setAttribute("aria-pressed", "true");
4044
activeThemeIcon.setAttribute("href", svgOfActiveBtn);
45+
const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`;
46+
themeSwitcher.setAttribute("aria-label", themeSwitcherLabel);
47+
48+
if (focus) {
49+
themeSwitcher.focus();
50+
}
4151
};
4252

4353
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
@@ -55,7 +65,7 @@
5565
const theme = toggle.getAttribute("data-bs-theme-value");
5666
localStorage.setItem("theme", theme);
5767
setTheme(theme);
58-
showActiveTheme(theme);
68+
showActiveTheme(theme, true);
5969
});
6070
});
6171
});

views/header.ejs

+10-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
<symbol id="sun-fill" viewBox="0 0 16 16">
2929
<path
3030
d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
31+
</symbol>
32+
<symbol id="check2" viewBox="0 0 16 16">
33+
<path
34+
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" />
3135
</symbol><% if (flashedMessages.length) { %>
3236
<symbol id="check-circle-fill" viewBox="0 0 16 16">
3337
<path
@@ -79,17 +83,17 @@
7983
<li class="nav-item dropdown">
8084
<button class="btn btn-link nav-link py-2 px-0 px-sm-2 dropdown-toggle d-flex align-items-center"
8185
id="theme-btn" type="button" aria-expanded="false" data-bs-toggle="dropdown"
82-
data-bs-display="static">
86+
data-bs-display="static" aria-label="Toggle theme (auto)">
8387
<svg class="bi my-1 theme-icon-active">
8488
<use href="#circle-half"></use>
8589
</svg>
86-
<span class="d-sm-none ms-2">Toggle theme</span>
90+
<span class="d-sm-none ms-2" id="theme-toggle-text">Toggle theme</span>
8791
</button>
88-
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="theme-btn"
92+
<ul class="dropdown-menu dropdown-menu-end checked-dropdown" aria-labelledby="theme-toggle-text"
8993
style="--bs-dropdown-min-width: 8rem;">
9094
<li>
9195
<button type="button" class="dropdown-item d-flex align-items-center"
92-
data-bs-theme-value="light">
96+
data-bs-theme-value="light" aria-pressed="false">
9397
<svg class="bi me-2 opacity-50 theme-icon">
9498
<use href="#sun-fill"></use>
9599
</svg>
@@ -101,7 +105,7 @@
101105
</li>
102106
<li>
103107
<button type="button" class="dropdown-item d-flex align-items-center"
104-
data-bs-theme-value="dark">
108+
data-bs-theme-value="dark" aria-pressed="false">
105109
<svg class="bi me-2 opacity-50 theme-icon">
106110
<use href="#moon-stars-fill"></use>
107111
</svg>
@@ -113,7 +117,7 @@
113117
</li>
114118
<li>
115119
<button type="button" class="dropdown-item d-flex align-items-center active"
116-
data-bs-theme-value="auto">
120+
data-bs-theme-value="auto" aria-pressed="true">
117121
<svg class="bi me-2 opacity-50 theme-icon">
118122
<use href="#circle-half"></use>
119123
</svg>

0 commit comments

Comments
 (0)