Add color mode switcher
This commit is contained in:
parent
de99a221d6
commit
51cce2ee9f
3 changed files with 56 additions and 1 deletions
53
src/components/ColorSchemeSwitcher.svelte
Normal file
53
src/components/ColorSchemeSwitcher.svelte
Normal file
|
@ -0,0 +1,53 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from '@sveltestrap/sveltestrap';
|
||||
|
||||
type Theme = 'light' | 'dark' | 'auto';
|
||||
|
||||
let theme: Theme = 'auto';
|
||||
|
||||
// Set the theme based on user selection and store it in localStorage
|
||||
function setTheme(newTheme: Theme) {
|
||||
theme = newTheme;
|
||||
localStorage.setItem('theme', newTheme);
|
||||
applyTheme(newTheme);
|
||||
}
|
||||
|
||||
// Apply the selected theme to the document
|
||||
function applyTheme(selectedTheme: Theme) {
|
||||
if (selectedTheme === 'auto') {
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
document.documentElement.setAttribute('data-bs-theme', prefersDark ? 'dark' : 'light');
|
||||
} else {
|
||||
document.documentElement.setAttribute('data-bs-theme', selectedTheme);
|
||||
}
|
||||
}
|
||||
|
||||
// On component mount, check localStorage and apply the saved theme
|
||||
onMount(() => {
|
||||
const savedTheme = (localStorage.getItem('theme') as Theme) || 'auto';
|
||||
applyTheme(savedTheme);
|
||||
theme = savedTheme;
|
||||
|
||||
// Listen for changes in the system color scheme preference
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
mediaQuery.addEventListener('change', () => {
|
||||
if (theme === 'auto') {
|
||||
applyTheme('auto');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<Dropdown inNavbar class="ms-3">
|
||||
<DropdownToggle nav caret>
|
||||
{theme === 'auto' ? '🌗' : theme === 'dark' ? '🌙' : '☀️'}
|
||||
</DropdownToggle>
|
||||
<DropdownMenu end>
|
||||
<DropdownItem active={theme === 'light'} on:click={() => setTheme('light')}
|
||||
>☀️ Light</DropdownItem
|
||||
>
|
||||
<DropdownItem active={theme === 'dark'} on:click={() => setTheme('dark')}>🌙 Dark</DropdownItem>
|
||||
<DropdownItem active={theme === 'auto'} on:click={() => setTheme('auto')}>🌗 Auto</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
@import './satsymbol';
|
||||
|
||||
$color-mode-type: media-query;
|
||||
$color-mode-type: data;
|
||||
$font-family-base: 'Ubuntu';
|
||||
$font-size-base: 0.9rem;
|
||||
$input-font-size-sm: $font-size-base * 0.875;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
import { page } from '$app/stores';
|
||||
import { locale, locales, isLoading } from 'svelte-i18n';
|
||||
import ColorSchemeSwitcher from '../components/ColorSchemeSwitcher.svelte';
|
||||
|
||||
export const setLocale = (lang: string) => () => {
|
||||
locale.set(lang);
|
||||
|
@ -88,6 +89,7 @@
|
|||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
{/if}
|
||||
<ColorSchemeSwitcher></ColorSchemeSwitcher>
|
||||
</Collapse>
|
||||
</Navbar>
|
||||
|
||||
|
|
Loading…
Reference in a new issue