agent-ecosystem/landing/plugins/vuetify.ts

70 lines
1.8 KiB
TypeScript

import "vuetify/styles";
import { createVuetify } from "vuetify";
import { aliases, mdi } from "vuetify/iconsets/mdi-svg";
type ThemeName = "light" | "dark";
const brand = {
cyan: "#00f0ff",
magenta: "#ff00ff",
lightBackground: "#f0f2f5",
lightSurface: "#ffffff",
darkBackground: "#0a0a0f",
darkSurface: "#12121a"
};
function isThemeName(value: string | null | undefined): value is ThemeName {
return value === "dark" || value === "light";
}
function resolveInitialTheme(cookieTheme: ThemeName | null): ThemeName {
if (import.meta.client) {
const saved = localStorage.getItem("theme");
if (isThemeName(saved)) return saved;
if (cookieTheme) return cookieTheme;
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
return cookieTheme ?? "light";
}
export default defineNuxtPlugin({
name: "vuetify",
setup(nuxtApp) {
const themeCookie = useCookie<ThemeName | null>("theme");
const cookieTheme = isThemeName(themeCookie.value) ? themeCookie.value : null;
const defaultTheme = resolveInitialTheme(cookieTheme);
const vuetify = createVuetify({
icons: {
defaultSet: "mdi",
aliases,
sets: { mdi }
},
theme: {
defaultTheme,
themes: {
light: {
colors: {
primary: brand.cyan,
secondary: brand.magenta,
background: brand.lightBackground,
surface: brand.lightSurface
}
},
dark: {
colors: {
primary: brand.cyan,
secondary: brand.magenta,
background: brand.darkBackground,
surface: brand.darkSurface
}
}
}
}
});
nuxtApp.vueApp.use(vuetify);
nuxtApp.provide("vuetifyTheme", vuetify.theme);
}
});