kopia lustrzana https://github.com/shoelace-style/shoelace
docs changed theme toggle to theme selector (#1395)
rodzic
8e831aa3e7
commit
2914475821
|
@ -42,8 +42,8 @@
|
|||
<script>
|
||||
(() => {
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const theme = localStorage.getItem('theme');
|
||||
document.documentElement.classList.toggle('sl-theme-dark', theme === 'dark' || (!theme && prefersDark));
|
||||
const theme = localStorage.getItem('theme') || 'auto';
|
||||
document.documentElement.classList.toggle('sl-theme-dark', theme === 'dark' || (theme === 'auto' && prefersDark));
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
@ -80,16 +80,20 @@
|
|||
<sl-icon name="twitter"></sl-icon>
|
||||
</a>
|
||||
|
||||
{# Theme toggle #}
|
||||
<button
|
||||
id="theme-toggle"
|
||||
type="button"
|
||||
aria-label="Toggle light and dark theme"
|
||||
title="Toggle theme (press backslash)"
|
||||
>
|
||||
<sl-icon class="only-light" name="sun-fill"></sl-icon>
|
||||
<sl-icon class="only-dark" name="moon-fill"></sl-icon>
|
||||
</button>
|
||||
{# Theme selector #}
|
||||
<sl-dropdown id="theme-selector" placement="bottom-end">
|
||||
<sl-button size="small" variant="text" slot="trigger" caret>
|
||||
<sl-icon class="only-light" name="sun-fill"></sl-icon>
|
||||
<sl-icon class="only-dark" name="moon-fill"></sl-icon>
|
||||
</sl-button>
|
||||
<sl-menu>
|
||||
<sl-menu-label>Toggle <kbd>\</kbd></sl-menu-label>
|
||||
<sl-menu-item type="checkbox" value="light">Light</sl-menu-item>
|
||||
<sl-menu-item type="checkbox" value="dark">Dark</sl-menu-item>
|
||||
<sl-divider></sl-divider>
|
||||
<sl-menu-item type="checkbox" value="auto">Auto</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
</div>
|
||||
|
||||
<aside id="sidebar" data-preserve-scroll>
|
||||
|
|
|
@ -74,22 +74,56 @@
|
|||
})();
|
||||
|
||||
//
|
||||
// Theme switcher
|
||||
// Theme selector
|
||||
//
|
||||
(() => {
|
||||
function toggleTheme() {
|
||||
const isDark = !document.documentElement.classList.contains('sl-theme-dark');
|
||||
document.documentElement.classList.toggle('sl-theme-dark', isDark);
|
||||
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
||||
function getTheme() {
|
||||
return localStorage.getItem('theme') || 'auto';
|
||||
}
|
||||
|
||||
// Toggle the theme
|
||||
document.addEventListener('click', event => {
|
||||
const themeToggle = event.target.closest('#theme-toggle');
|
||||
if (!themeToggle) return;
|
||||
toggleTheme();
|
||||
function isDark() {
|
||||
if (theme === 'auto') {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
return theme === 'dark';
|
||||
}
|
||||
|
||||
function setTheme(newTheme) {
|
||||
theme = newTheme;
|
||||
localStorage.setItem('theme', theme);
|
||||
|
||||
// Update the UI
|
||||
updateSelection();
|
||||
|
||||
// Toggle the dark mode class
|
||||
document.documentElement.classList.toggle('sl-theme-dark', isDark());
|
||||
}
|
||||
|
||||
function updateSelection() {
|
||||
const menu = document.querySelector('#theme-selector sl-menu');
|
||||
if (!menu) return;
|
||||
[...menu.querySelectorAll('sl-menu-item')].map(item => (item.checked = item.getAttribute('value') === theme));
|
||||
}
|
||||
|
||||
let theme = getTheme();
|
||||
|
||||
// Selection is not preserved when changing page, so update when opening dropdown
|
||||
document.addEventListener('sl-show', event => {
|
||||
const themeSelector = event.target.closest('#theme-selector');
|
||||
if (!themeSelector) return;
|
||||
updateSelection();
|
||||
});
|
||||
|
||||
// Listen for selections
|
||||
document.addEventListener('sl-select', event => {
|
||||
const menu = event.target.closest('#theme-selector sl-menu');
|
||||
if (!menu) return;
|
||||
setTheme(event.detail.item.value);
|
||||
});
|
||||
|
||||
// Update the theme when the preference changes
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => setTheme(theme));
|
||||
|
||||
// Toggle with backslash
|
||||
document.addEventListener('keydown', event => {
|
||||
if (
|
||||
|
@ -97,9 +131,12 @@
|
|||
!event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase()))
|
||||
) {
|
||||
event.preventDefault();
|
||||
toggleTheme();
|
||||
setTheme(isDark() ? 'light' : 'dark');
|
||||
}
|
||||
});
|
||||
|
||||
// Set the initial theme and sync the UI
|
||||
setTheme(theme);
|
||||
})();
|
||||
|
||||
//
|
||||
|
|
|
@ -1054,6 +1054,31 @@ html.sidebar-open #menu-toggle {
|
|||
transition: 250ms scale ease;
|
||||
}
|
||||
|
||||
#theme-selector:not(:defined) {
|
||||
/* Hide when not defined to prevent extra wide icon toolbar while loading */
|
||||
display: none;
|
||||
}
|
||||
#theme-selector sl-menu {
|
||||
/* Set an initial size to prevent width being initally too small when first opening on small screen width */
|
||||
width: 140px;
|
||||
}
|
||||
#theme-selector sl-button {
|
||||
transition: 250ms scale ease;
|
||||
}
|
||||
#theme-selector sl-button::part(base) {
|
||||
color: var(--sl-color-neutral-0);
|
||||
}
|
||||
#theme-selector sl-button::part(label) {
|
||||
display: flex;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
#theme-selector sl-icon {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
.sl-theme-dark #theme-selector sl-button::part(base) {
|
||||
color: var(--sl-color-neutral-1000);
|
||||
}
|
||||
|
||||
.sl-theme-dark #icon-toolbar {
|
||||
background: var(--sl-color-neutral-200);
|
||||
}
|
||||
|
@ -1064,7 +1089,8 @@ html.sidebar-open #menu-toggle {
|
|||
}
|
||||
|
||||
#icon-toolbar button:hover,
|
||||
#icon-toolbar a:hover {
|
||||
#icon-toolbar a:hover,
|
||||
#theme-selector sl-button:hover {
|
||||
scale: 1.1;
|
||||
}
|
||||
|
||||
|
@ -1084,6 +1110,10 @@ html.sidebar-open #menu-toggle {
|
|||
font-size: 1rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
#theme-selector sl-icon {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar addons */
|
||||
|
|
Ładowanie…
Reference in New Issue