This commit is contained in:
nub31
2026-03-17 17:53:17 +01:00
parent ceb05f4a75
commit 73c1343b0d
10 changed files with 61 additions and 167 deletions

View File

@@ -10,12 +10,17 @@
import BusPage from "./pages/BusPage.svelte";
import ContactPage from "./pages/ContactPage.svelte";
import AccessibilityPage from "./pages/AccessibilityPage.svelte";
import { getTheme } from "./lib/theme.svelte";
route("/", HomePage);
route("/taxi", TaxiPage);
route("/bus", BusPage);
route("/contact", ContactPage);
route("/accessibility", AccessibilityPage);
$effect(() => {
document.body.dataset.theme = getTheme();
});
</script>
<div class="flex min-h-screen flex-col bg-primary-200 text-contrast-900">

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import Link from "./lib/components/link/Link.svelte";
import { Routes } from "./lib/global/routes";
import { Routes } from "./lib/routes";
</script>
<footer

View File

@@ -4,9 +4,9 @@
import moonIcon from "./assets/icons/moon.svg";
import { slide } from "svelte/transition";
import Toggle from "./lib/components/Toggle.svelte";
import { darkTheme } from "./lib/stores/theme";
import { Routes } from "./lib/global/routes";
import { Routes } from "./lib/routes";
import { isCurrentPath } from "./lib/components/Router.svelte";
import { getTheme, toggleTheme } from "./lib/theme.svelte";
let sidebarOpen = false;
@@ -63,15 +63,7 @@
{/each}
</ul>
<div class="flex w-fit flex-col items-center gap-3">
<Toggle
invertColor={true}
checked={$darkTheme}
leftIcon={sunIcon}
rightIcon={moonIcon}
on:change={() => {
$darkTheme = $darkTheme = !$darkTheme;
}}
/>
<Toggle invertColor={true} checked={getTheme() == "dark"} leftIcon={sunIcon} rightIcon={moonIcon} on:change={toggleTheme} />
</div>
</nav>
</aside>

View File

@@ -2,72 +2,36 @@
@custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *));
:root {
--mb-color-primary-100: rgb(250 250 250);
--mb-color-primary-200: rgb(240 240 240);
--mb-color-primary-300: rgb(230 230 230);
--mb-color-primary-400: rgb(220 220 220);
--mb-color-primary-500: rgb(210 210 210);
--mb-color-primary-600: rgb(200 200 200);
--mb-color-primary-700: rgb(190 190 190);
--mb-color-primary-800: rgb(180 180 180);
--mb-color-primary-900: rgb(170 170 170);
--mb-color-contrast-100: rgb(220 220 220);
--mb-color-contrast-200: rgb(200 200 200);
--mb-color-contrast-300: rgb(180 180 180);
--mb-color-contrast-400: rgb(160 160 160);
--mb-color-contrast-500: rgb(140 140 140);
--mb-color-contrast-600: rgb(110 110 110);
--mb-color-contrast-700: rgb(80 80 80);
--mb-color-contrast-800: rgb(60 60 60);
--mb-color-contrast-900: rgb(30 30 30);
body {
color-scheme: light;
}
[data-theme="dark"] {
--mb-color-primary-100: rgb(28 28 28);
--mb-color-primary-200: rgb(32 32 32);
--mb-color-primary-300: rgb(38 38 38);
--mb-color-primary-400: rgb(44 44 44);
--mb-color-primary-500: rgb(50 50 50);
--mb-color-primary-600: rgb(56 56 56);
--mb-color-primary-700: rgb(62 62 62);
--mb-color-primary-800: rgb(68 68 68);
--mb-color-primary-900: rgb(74 74 74);
--mb-color-contrast-100: rgb(25 25 25);
--mb-color-contrast-200: rgb(50 50 50);
--mb-color-contrast-300: rgb(80 80 80);
--mb-color-contrast-400: rgb(110 110 110);
--mb-color-contrast-500: rgb(140 140 140);
--mb-color-contrast-600: rgb(160 160 160);
--mb-color-contrast-700: rgb(180 180 180);
--mb-color-contrast-800: rgb(200 200 200);
--mb-color-contrast-900: rgb(220 220 220);
body[data-theme="dark"] {
color-scheme: dark;
}
@theme inline {
--color-accent: rgb(255 29 37);
--color-primary-100: var(--mb-color-primary-100);
--color-primary-200: var(--mb-color-primary-200);
--color-primary-300: var(--mb-color-primary-300);
--color-primary-400: var(--mb-color-primary-400);
--color-primary-500: var(--mb-color-primary-500);
--color-primary-600: var(--mb-color-primary-600);
--color-primary-700: var(--mb-color-primary-700);
--color-primary-800: var(--mb-color-primary-800);
--color-primary-900: var(--mb-color-primary-900);
--color-primary-100: light-dark(rgb(250 250 250), rgb(28 28 28));
--color-primary-200: light-dark(rgb(240 240 240), rgb(32 32 32));
--color-primary-300: light-dark(rgb(230 230 230), rgb(38 38 38));
--color-primary-400: light-dark(rgb(220 220 220), rgb(44 44 44));
--color-primary-500: light-dark(rgb(210 210 210), rgb(50 50 50));
--color-primary-600: light-dark(rgb(200 200 200), rgb(56 56 56));
--color-primary-700: light-dark(rgb(190 190 190), rgb(62 62 62));
--color-primary-800: light-dark(rgb(180 180 180), rgb(68 68 68));
--color-primary-900: light-dark(rgb(170 170 170), rgb(74 74 74));
--color-contrast-100: var(--mb-color-contrast-100);
--color-contrast-200: var(--mb-color-contrast-200);
--color-contrast-300: var(--mb-color-contrast-300);
--color-contrast-400: var(--mb-color-contrast-400);
--color-contrast-500: var(--mb-color-contrast-500);
--color-contrast-600: var(--mb-color-contrast-600);
--color-contrast-700: var(--mb-color-contrast-700);
--color-contrast-800: var(--mb-color-contrast-800);
--color-contrast-900: var(--mb-color-contrast-900);
--color-contrast-100: light-dark(rgb(220 220 220), rgb(25 25 25));
--color-contrast-200: light-dark(rgb(200 200 200), rgb(50 50 50));
--color-contrast-300: light-dark(rgb(180 180 180), rgb(80 80 80));
--color-contrast-400: light-dark(rgb(160 160 160), rgb(110 110 110));
--color-contrast-500: light-dark(rgb(140 140 140), rgb(140 140 140));
--color-contrast-600: light-dark(rgb(110 110 110), rgb(160 160 160));
--color-contrast-700: light-dark(rgb(80 80 80), rgb(180 180 180));
--color-contrast-800: light-dark(rgb(60 60 60), rgb(200 200 200));
--color-contrast-900: light-dark(rgb(30 30 30), rgb(220 220 220));
--shadow-t-lg: 0px -4px 6px -1px rgba(0, 0, 0, 0.1);
}

View File

@@ -5,7 +5,6 @@
export class RouteError extends Error {}
export class MissingRouteError extends RouteError {}
export class RouteFormatError extends RouteError {}
export class DuplicateRouteError extends RouteError {}
type RouteInfo = {
path: string;
@@ -67,7 +66,8 @@
*/
export function route(path: string, component: Component<{}>): void {
if (routes.has(path)) {
throw new DuplicateRouteError(`Route already registered for path: '${path}'.`);
console.warn(`Route already registered for path: '${path}'.`);
return;
}
const params = Array.from(path.matchAll(/\[([^\]]+)\]/g)).map((x) => x[1]);
@@ -179,53 +179,6 @@
// @ts-ignore
window.navigation.removeEventListener("navigate", handleNavigate);
};
} else {
function refresh() {
currentUrl = new URL(window.location.href);
}
function makeProxy(target: any) {
return new Proxy(target, {
apply: (target, thisArg, argArray) => {
const result = target.apply(thisArg, argArray);
refresh();
return result;
}
});
}
window.history.pushState = makeProxy(window.history.pushState);
window.history.replaceState = makeProxy(window.history.replaceState);
window.history.go = makeProxy(window.history.go);
window.history.forward = makeProxy(window.history.forward);
window.history.back = makeProxy(window.history.back);
function handleClick(e: MouseEvent) {
if (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) {
return;
}
const anchor = (e.target as Element)?.closest("a");
if (!(anchor instanceof HTMLAnchorElement)) return;
if (anchor.target === "_blank") return;
const targetUrl = new URL(anchor.href, document.baseURI);
const documentUrl = new URL(document.baseURI);
if (targetUrl.origin === documentUrl.origin) {
e.preventDefault();
history.pushState({}, "", targetUrl);
currentUrl = targetUrl;
}
}
window.addEventListener("popstate", refresh);
document.addEventListener("click", handleClick);
return () => {
window.removeEventListener("popstate", refresh);
document.removeEventListener("click", handleClick);
};
}
});
</script>

View File

@@ -1,6 +1,6 @@
import homeIcon from "../../assets/icons/home_icon.svg";
import contactIcon from "../../assets/icons/contact_icon.svg";
import busIcon from "../../assets/icons/bus_icon.svg";
import homeIcon from "../assets/icons/home_icon.svg";
import contactIcon from "../assets/icons/contact_icon.svg";
import busIcon from "../assets/icons/bus_icon.svg";
type Route = {
url: string;

View File

@@ -1,36 +0,0 @@
import { writable } from "svelte/store";
function createThemeToggler() {
let defaultValue = false;
let savedValue = localStorage.getItem("dark_theme");
if (savedValue) {
defaultValue = JSON.parse(savedValue);
} else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
defaultValue = true;
}
if (defaultValue) {
document.body.dataset.theme = "dark";
} else {
document.body.dataset.theme = "light";
}
const { subscribe, update } = writable(defaultValue);
return {
subscribe,
set: (value: boolean) => {
update(() => value);
if (value) {
document.body.dataset.theme = "dark";
} else {
document.body.dataset.theme = "light";
}
localStorage.setItem("dark_theme", JSON.stringify(value));
}
};
}
export const darkTheme = createThemeToggler();

24
src/lib/theme.svelte.ts Normal file
View File

@@ -0,0 +1,24 @@
function loadTheme() {
let theme = localStorage.getItem("theme");
if (!theme) {
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
theme = "dark";
} else {
theme = "light";
}
}
return theme;
}
let currentTheme = $state(loadTheme());
export function toggleTheme() {
const newTheme = currentTheme === "dark" ? "light" : "dark";
localStorage.setItem("theme", newTheme);
currentTheme = newTheme;
}
export function getTheme(): string {
return currentTheme;
}

View File

@@ -1,8 +0,0 @@
export function debounce<T extends Function>(cb: T, wait = 500) {
let h: any;
let callable = () => {
clearTimeout(h);
h = setTimeout(() => cb(), wait);
};
return callable;
}

View File

@@ -8,7 +8,7 @@
import twoTourBusses from "../assets/images/two_tour_busses.jpg";
import van from "../assets/images/van.webp";
import Link from "../lib/components/link/Link.svelte";
import { Routes } from "../lib/global/routes";
import { Routes } from "../lib/routes";
type CardCarouselItem = {
header: string;