Add client-side blog theme switcher (dropdown, localStorage, default Tokyo Night)

This commit is contained in:
trilium-share-gruvbox
2026-09-07 22:08:53 +02:00
parent 6edd75bbad
commit 1211046eb5
2 changed files with 87 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
<style>
.blog-theme-picker-wrap { display: inline-flex; align-items: center; gap: 6px; margin-right: 10px; flex-shrink: 0; }
.blog-theme-picker-label { font-size: 0.78em; color: var(--text-menu); }
.blog-theme-picker {
font-size: 0.8em;
color: var(--text-heading);
background: var(--background-secondary);
border: 1px solid var(--background-highlight);
border-radius: 6px;
padding: 3px 8px;
max-width: 130px;
cursor: pointer;
}
</style>
<script>
(function () {
// Replace the __THEME_*_ID__ placeholders with the note IDs of your theme notes
// (code notes, mime text/css, living under the .blog system note).
var THEMES = [
{ id: "tokyonight", name: "Tokyo Night", url: "api/notes/__THEME_TOKYO_ID__/download" },
{ id: "solarized", name: "Solarized", url: "api/notes/__THEME_SOLARIZED_ID__/download" },
{ id: "coffee", name: "Coffee", url: "api/notes/__THEME_COFFEE_ID__/download" },
{ id: "harbor", name: "Harbor", url: "api/notes/__THEME_HARBOR_ID__/download" },
{ id: "gruvbox", name: "Gruvbox", url: "api/notes/__THEME_GRUVBOX_ID__/download" }
];
var KEY = "blogTheme";
var DEFAULT = "tokyonight";
var currentLink = null;
function chosen() {
var v = null;
try { v = localStorage.getItem(KEY); } catch (e) {}
for (var i = 0; i < THEMES.length; i++) if (THEMES[i].id === v) return v;
return DEFAULT;
}
function applyTheme(id) {
var t = null;
for (var i = 0; i < THEMES.length; i++) if (THEMES[i].id === id) t = THEMES[i];
if (!t) return;
if (currentLink) {
try { currentLink.parentNode && currentLink.parentNode.removeChild(currentLink); } catch (e) {}
currentLink = null;
}
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = t.url;
document.head.appendChild(link);
currentLink = link;
}
function build() {
var host = document.querySelector("#site-header");
if (!host) return;
var wrap = document.createElement("div");
wrap.className = "blog-theme-picker-wrap";
var label = document.createElement("span");
label.className = "blog-theme-picker-label";
label.textContent = "Theme";
var select = document.createElement("select");
select.className = "blog-theme-picker";
select.setAttribute("aria-label", "Theme");
THEMES.forEach(function (t) {
var opt = document.createElement("option");
opt.value = t.id;
opt.textContent = t.name;
select.appendChild(opt);
});
select.value = chosen();
select.addEventListener("change", function () {
try { localStorage.setItem(KEY, select.value); } catch (e) {}
applyTheme(select.value);
});
wrap.appendChild(label);
wrap.appendChild(select);
host.appendChild(wrap);
}
applyTheme(chosen());
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", build);
} else {
build();
}
})();
</script>