ux: add public theme selector

This commit is contained in:
Marco Allegretti 2026-02-05 12:35:58 +01:00
parent 8ce353262b
commit b604d99960

View file

@ -103,6 +103,11 @@ const defaultTheme = DEFAULT_THEME;
<a href="/docs">Documentation</a>
</div>
<div class="nav-actions">
<select id="theme-select" class="theme-select" aria-label="Theme">
{Object.values(themeRegistry).map((t) => (
<option value={t.id}>{t.name}</option>
))}
</select>
<a href="/demo" class="ui-btn ui-btn-primary">Explore Demo</a>
{!publicDemoSite ? <a href="/login" class="ui-btn ui-btn-secondary">Sign In</a> : null}
</div>
@ -149,9 +154,10 @@ const defaultTheme = DEFAULT_THEME;
</div>
</footer>
</div>
<script>
<script is:inline define:vars={{ themes, defaultTheme }}>
const nav = document.getElementById('public-nav');
const toggle = document.getElementById('public-nav-toggle');
const themeSelect = document.getElementById('theme-select');
function openNav() {
if (!nav || !toggle) return;
@ -226,6 +232,58 @@ const defaultTheme = DEFAULT_THEME;
}
});
}
function applySelectedTheme() {
if (!(themeSelect instanceof HTMLSelectElement)) return;
const selected = themeSelect.value || defaultTheme;
const theme = themes[selected] || themes[defaultTheme];
const root = document.documentElement;
const c = theme.colors;
root.style.setProperty('--color-bg', c.bg);
root.style.setProperty('--color-bg-alt', c.bgAlt);
root.style.setProperty('--color-surface', c.surface);
root.style.setProperty('--color-surface-hover', c.surfaceHover);
root.style.setProperty('--color-border', c.border);
root.style.setProperty('--color-border-hover', c.borderHover);
root.style.setProperty('--color-text', c.text);
root.style.setProperty('--color-text-muted', c.textMuted);
root.style.setProperty('--color-text-inverse', c.textInverse);
root.style.setProperty('--color-primary', c.primary);
root.style.setProperty('--color-primary-hover', c.primaryHover);
root.style.setProperty('--color-primary-muted', c.primaryMuted);
root.style.setProperty('--color-secondary', c.secondary);
root.style.setProperty('--color-secondary-hover', c.secondaryHover);
root.style.setProperty('--color-info', c.info);
root.style.setProperty('--color-info-hover', c.infoHover);
root.style.setProperty('--color-info-muted', c.infoMuted);
root.style.setProperty('--color-neutral', c.neutral);
root.style.setProperty('--color-neutral-hover', c.neutralHover);
root.style.setProperty('--color-neutral-muted', c.neutralMuted);
root.style.setProperty('--color-success', c.success);
root.style.setProperty('--color-success-muted', c.successMuted);
root.style.setProperty('--color-success-hover', c.successHover);
root.style.setProperty('--color-warning', c.warning);
root.style.setProperty('--color-warning-muted', c.warningMuted);
root.style.setProperty('--color-error', c.error);
root.style.setProperty('--color-error-muted', c.errorMuted);
root.style.setProperty('--color-error-hover', c.errorHover);
root.style.setProperty('--color-link', c.link);
root.style.setProperty('--color-link-visited', c.linkVisited);
root.style.setProperty('--color-overlay', c.overlay);
root.style.setProperty('--color-field-bg', c.fieldBg);
root.style.setProperty('--color-on-primary', c.onPrimary);
root.setAttribute('data-theme', selected);
root.setAttribute('data-theme-mode', theme.isDark ? 'dark' : 'light');
}
if (themeSelect instanceof HTMLSelectElement) {
const saved = localStorage.getItem('likwid-theme') || defaultTheme;
themeSelect.value = themes[saved] ? saved : defaultTheme;
themeSelect.addEventListener('change', () => {
localStorage.setItem('likwid-theme', themeSelect.value);
applySelectedTheme();
});
}
</script>
</body>
</html>
@ -384,6 +442,20 @@ const defaultTheme = DEFAULT_THEME;
align-items: center;
}
.theme-select {
width: auto;
padding: 0.5rem 0.75rem;
font-size: 0.875rem;
background: rgba(255, 255, 255, 0.06);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
color: var(--color-text);
}
.theme-select:hover {
border-color: var(--color-border-hover);
}
.public-main {
flex: 1;
}
@ -464,7 +536,8 @@ const defaultTheme = DEFAULT_THEME;
@media (max-width: 768px) {
.public-nav {
flex-wrap: wrap;
padding: 1rem;
gap: 1rem;
padding: 0.875rem 1rem;
}
.nav-toggle {