mirror of
https://github.com/Lissy93/awesome-privacy.git
synced 2026-03-11 08:55:33 +00:00
Adds theme switcher
This commit is contained in:
parent
b7c93b1005
commit
37a3b6f879
3 changed files with 138 additions and 1 deletions
|
|
@ -1,7 +1,12 @@
|
|||
---
|
||||
import FontAwesome from "@components/form/FontAwesome.svelte"
|
||||
import ThemeSwitcher from "@components/form/ThemeSwitcher.svelte"
|
||||
---
|
||||
|
||||
<div class="theme-switcher">
|
||||
<ThemeSwitcher client:load />
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<h1>Awesome Privacy</h1>
|
||||
<p class="intro">
|
||||
|
|
@ -119,6 +124,12 @@ import FontAwesome from "@components/form/FontAwesome.svelte"
|
|||
}
|
||||
}
|
||||
|
||||
.theme-switcher {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
top: 1rem;
|
||||
}
|
||||
|
||||
.top-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
|
|||
100
web/src/components/form/ThemeSwitcher.svelte
Normal file
100
web/src/components/form/ThemeSwitcher.svelte
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
// Define a store for the theme which reacts to changes
|
||||
let theme = writable('dark');
|
||||
|
||||
// On component mount, check local storage for a theme setting
|
||||
onMount(() => {
|
||||
const storedTheme = localStorage.getItem('theme');
|
||||
theme.set(storedTheme || 'dark');
|
||||
applyTheme(storedTheme || 'dark');
|
||||
});
|
||||
|
||||
// Function to toggle theme between light and dark
|
||||
function toggleTheme(): void {
|
||||
theme.update((currentTheme) => {
|
||||
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||
localStorage.setItem('theme', newTheme);
|
||||
applyTheme(newTheme);
|
||||
return newTheme;
|
||||
});
|
||||
}
|
||||
|
||||
// Function to apply the theme by setting the attribute on the <html> element
|
||||
function applyTheme(selectedTheme: string): void {
|
||||
document.documentElement.setAttribute('data-theme', selectedTheme);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div class="theme-switcher" on:click={toggleTheme}>
|
||||
<div class={`toggle ${$theme}`}>
|
||||
<span class="theme-icon">🌘</span>
|
||||
<span class="theme-icon">☀️</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.theme-switcher {
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2px solid transparent;
|
||||
border-radius: var(--curve-lg);
|
||||
padding: 0.25rem;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
transition: background-color 0.3s ease;
|
||||
border: 2px solid var(--box-outline);
|
||||
box-shadow: 3px 3px 0 var(--box-outline);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 4rem;
|
||||
height: 2rem;
|
||||
background: var(--accent-fg);
|
||||
border-radius: var(--curve-lg);
|
||||
padding: 0.25rem;
|
||||
position: relative;
|
||||
transition: background 0.3s ease;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0.25rem;
|
||||
left: 0.25rem;
|
||||
width: 1.6rem;
|
||||
height: 1.6rem;
|
||||
border-radius: 50%;
|
||||
background: var(--background);
|
||||
opacity: 0.6;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
&.dark::before {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
&:not(.dark)::before {
|
||||
transform: translateX(2.2rem);
|
||||
}
|
||||
}
|
||||
|
||||
.theme-icon {
|
||||
display: flex;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
|
||||
html {
|
||||
--accent: #f45397;
|
||||
--accent-fg: #1e1f21;
|
||||
|
||||
|
|
@ -23,4 +24,29 @@
|
|||
--background-form: #19191c;
|
||||
|
||||
--box-outline: #000;
|
||||
|
||||
&[data-theme='light'] {
|
||||
--accent: #f45397;
|
||||
--accent-fg: #fff;
|
||||
|
||||
--accent-2: #ffdf60;
|
||||
--accent-3: #5f53f4;
|
||||
--accent-4: #28dffd;
|
||||
|
||||
--foreground: #13151a;
|
||||
|
||||
--curve-sm: 4px;
|
||||
--curve-md: 6px;
|
||||
--curve-lg: 12px;
|
||||
|
||||
--danger: #ff0048;
|
||||
--success: #00ff64;
|
||||
|
||||
--transparent-accent: #5f53f482;
|
||||
|
||||
--background: #feecff;
|
||||
--bg-gradient-comp-1: #feecff;
|
||||
--bg-gradient-comp-2: #e1e4fb;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue