docs: Add dark mode (#17940)

Closes https://github.com/zed-industries/zed/issues/17911

This PR enables dark mode on the documentation. This is done without any
special plugins, just pure JavaScript and CSS variables. I may open
fast-follow PRs to fine-tune design and code details that haven't been
super polished yet. For example, when switching to dark mode, the
`class` attribute on the `html` tag would change immediately, whereas
other attributes such as `data-theme` and `data-color-scheme` would
require a full refresh. This seems to be resolved, but not 100%
confident yet.

---

Release Notes:

- Enabled dark mode on the documentation
This commit is contained in:
Danilo Leal 2024-09-17 17:39:06 +02:00 committed by GitHub
parent 10cfaecffa
commit 7c54965b11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 224 additions and 46 deletions

62
docs/theme/plugins.js vendored
View file

@ -48,3 +48,65 @@ console.log("Operating System:", os);
// Start the process from the body
walkDOM(document.body);
})();
function darkModeToggle() {
var html = document.documentElement;
var themeToggleButton = document.getElementById("theme-toggle");
var themePopup = document.getElementById("theme-list");
var themePopupButtons = themePopup.querySelectorAll("button");
function setTheme(theme) {
html.setAttribute("data-theme", theme);
html.setAttribute("data-color-scheme", theme);
html.className = theme;
localStorage.setItem("mdbook-theme", theme);
// Force a repaint to ensure the changes take effect in the client immediately
document.body.style.display = "none";
document.body.offsetHeight;
document.body.style.display = "";
}
themeToggleButton.addEventListener("click", function (event) {
event.preventDefault();
themePopup.style.display =
themePopup.style.display === "block" ? "none" : "block";
});
themePopupButtons.forEach(function (button) {
button.addEventListener("click", function () {
setTheme(this.id);
themePopup.style.display = "none";
});
});
document.addEventListener("click", function (event) {
if (
!themePopup.contains(event.target) &&
!themeToggleButton.contains(event.target)
) {
themePopup.style.display = "none";
}
});
// Set initial theme
var currentTheme = localStorage.getItem("mdbook-theme");
if (currentTheme) {
setTheme(currentTheme);
} else {
// If no theme is set, use the system's preference
var systemPreference = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
setTheme(systemPreference);
}
// Listen for system's preference changes
const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
darkModeMediaQuery.addEventListener("change", function (e) {
if (!localStorage.getItem("mdbook-theme")) {
setTheme(e.matches ? "dark" : "light");
}
});
}