Add color picker for new Bootstrap 5.3 color themes feature

This commit is contained in:
Adam Goldsmith 2023-09-11 11:55:32 -04:00
parent 2dfa0db316
commit 33024d7d62
5 changed files with 138 additions and 6 deletions

95
static/bootstrap-color-toggle.js vendored Normal file
View File

@ -0,0 +1,95 @@
/*!
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Modified by Adam Goldsmith
* Licensed under the Creative Commons Attribution 3.0 Unported License.
*/
(() => {
"use strict";
const getStoredTheme = () => localStorage.getItem("theme");
const setStoredTheme = (theme) => localStorage.setItem("theme", theme);
const getPreferredTheme = () => {
const storedTheme = getStoredTheme();
if (storedTheme) {
return storedTheme;
}
return window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
};
const setTheme = (theme) => {
if (
theme === "auto" &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
document.documentElement.setAttribute("data-bs-theme", "dark");
} else {
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");
const btnToActive = document.querySelector(
`[data-bs-theme-value="${theme}"]`,
);
const activeIcon = [
...btnToActive.querySelector(".theme-icon").classList,
].find((c) => c.startsWith("bi-"));
document.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");
[...activeThemeIcon.classList]
.filter((c) => c.startsWith("bi-"))
.forEach((icon) => activeThemeIcon.classList.remove(icon));
activeThemeIcon.classList.add(activeIcon);
const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`;
themeSwitcher.setAttribute("aria-label", themeSwitcherLabel);
if (focus) {
themeSwitcher.focus();
}
};
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", () => {
const storedTheme = getStoredTheme();
if (storedTheme !== "light" && storedTheme !== "dark") {
setTheme(getPreferredTheme());
}
});
window.addEventListener("DOMContentLoaded", () => {
console.log(getPreferredTheme());
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);
});
});
});
})();

5
static/bootstrap-icons.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,8 @@
content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link href="{% static 'bootstrap.min.css' %}" rel="stylesheet">
<!-- Bootstrap Icons CSS -->
<link href="{% static 'bootstrap-icons.min.css' %}" rel="stylesheet">
<!-- Tabulator CSS -->
<link href="{% static 'tabulator_bootstrap5.min.css' %}" rel="stylesheet">
<title>
@ -15,7 +17,8 @@
</title>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-light bg-light">
<script src="{% static 'bootstrap-color-toggle.js' %}"></script>
<nav class="navbar navbar-expand-sm bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="{% url 'dashboard:dashboard' %}">Claremont MakerSpace</a>
<button class="navbar-toggler"
@ -30,6 +33,35 @@
<div id="user-nav" class="collapse navbar-collapse justify-content-end">
<div class="navbar-nav">
{% block nav_extra %}{% endblock %}
<div class="nav-item dropdown">
<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)">
<i class="bi theme-icon-active bi-circle-half"></i>
<span class="d-none ms-2" id="bd-theme-text">Toggle theme</span>
</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">
<i class="bi me-2 opacity-50 theme-icon bi-sun-fill"></i>
Light
<i class="bi ms-auto d-none bi-check2"></i>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
<i class="bi me-2 opacity-50 theme-icon bi-moon-stars-fill"></i>
Dark
<i class="bi ms-auto d-none bi-check2"></i>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto" aria-pressed="true">
<i class="bi me-2 opacity-50 theme-icon bi-circle-half"></i>
Auto
<i class="bi ms-auto d-none bi-check2"></i>
</button>
</li>
</ul>
</div>
{% if user.is_staff %}
<a class="nav-item nav-link"
href="{% block admin_link %}{% url 'admin:index' %}{% endblock %}">Admin</a>
@ -66,10 +98,10 @@
{% block content %}{% endblock %}
</div>
{% block footer %}{% endblock %}
<!-- Bootstrap JS -->
<script src="{% static 'bootstrap.bundle.min.js' %}"></script>
<!-- Tabulator JS -->
<script src="{% static 'tabulator.min.js' %}"></script>
{% block script %}{% endblock %}
</body>
<!-- Bootstrap JS -->
<script src="{% static 'bootstrap.bundle.min.js' %}"></script>
<!-- Tabulator JS -->
<script src="{% static 'tabulator.min.js' %}"></script>
{% block script %}{% endblock %}
</html>