diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Add a light and dark theme toggle
The button is emitted hidden and only revealed by the script, so a browser without JavaScript never shows a control that cannot work and the page keeps tracking the system theme.
Diffstat (limited to 'assets/cgit.js')
-rw-r--r--assets/cgit.js56
1 file changed, 56 insertions, 0 deletions
diff --git a/assets/cgit.js b/assets/cgit.js
index df3ad4e..85826b4 100644
--- a/assets/cgit.js
+++ b/assets/cgit.js
@@ -66,3 +66,59 @@ document.addEventListener("DOMContentLoaded", function() {
}, false);
})();
+
+/* Colour theme toggle: cycles auto -> light -> dark and remembers the
+ * choice. "auto" leaves the page following the system preference via CSS. */
+
+(function () {
+
+var KEY = "cgit-theme";
+var ORDER = [ "auto", "light", "dark" ];
+var ICONS = {
+ auto: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 3a9 9 0 0 0 0 18z" fill="currentColor" stroke="none"/></svg>',
+ light: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="5"/><path d="M12 1v3M12 20v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M1 12h3M20 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"/></svg>',
+ dark: '<svg viewBox="0 0 24 24"><path d="M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8z"/></svg>'
+};
+
+function saved() {
+ try { return localStorage.getItem(KEY); } catch (e) { return null; }
+}
+
+function persist(value) {
+ try { localStorage.setItem(KEY, value); } catch (e) { }
+}
+
+function apply(theme, root, btn) {
+ if (theme === "auto")
+ root.removeAttribute("data-theme");
+ else
+ root.setAttribute("data-theme", theme);
+ /* Keep the standalone page background in sync with the choice. */
+ document.documentElement.style.colorScheme = (theme === "auto") ? "" : theme;
+ if (btn) {
+ btn.innerHTML = ICONS[theme];
+ btn.title = "Colour theme: " + theme;
+ }
+}
+
+document.addEventListener("DOMContentLoaded", function () {
+ var root = document.getElementById("cgit");
+ if (!root)
+ return;
+ var btn = root.querySelector(".theme-toggle");
+ var theme = saved();
+ if (ORDER.indexOf(theme) < 0)
+ theme = "auto";
+
+ apply(theme, root, btn);
+ if (!btn)
+ return;
+ btn.hidden = false;
+ btn.addEventListener("click", function () {
+ theme = ORDER[(ORDER.indexOf(theme) + 1) % ORDER.length];
+ persist(theme);
+ apply(theme, root, btn);
+ });
+}, false);
+
+})();