mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 08:15:48 +00:00
WIP: Theme switcher
- Light/Dark Toggle works - Theme Preview works - TODO: Theme switching
This commit is contained in:
@@ -1,6 +1,16 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import {Provider as JotaiProvider} from "jotai"
|
||||||
import {ThemeProvider as NextThemesProvider} from "next-themes"
|
import {ThemeProvider as NextThemesProvider} from "next-themes"
|
||||||
import {type ThemeProviderProps} from "next-themes/dist/types"
|
import {ThemeProviderProps} from "next-themes/dist/types"
|
||||||
|
import {TooltipProvider} from "Frontend/@/components/ui/tooltip";
|
||||||
|
|
||||||
|
|
||||||
export function ThemeProvider({children, ...props}: ThemeProviderProps) {
|
export function ThemeProvider({children, ...props}: ThemeProviderProps) {
|
||||||
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
|
return (
|
||||||
|
<JotaiProvider>
|
||||||
|
<NextThemesProvider {...props}>
|
||||||
|
<TooltipProvider delayDuration={0}>{children}</TooltipProvider>
|
||||||
|
</NextThemesProvider>
|
||||||
|
</JotaiProvider>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as SwitchPrimitives from "@radix-ui/react-switch"
|
||||||
|
|
||||||
|
import {cn} from "Frontend/@/lib/utils"
|
||||||
|
|
||||||
|
const Switch = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SwitchPrimitives.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
|
||||||
|
>(({className, ...props}, ref) => (
|
||||||
|
<SwitchPrimitives.Root
|
||||||
|
className={cn(
|
||||||
|
"peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
>
|
||||||
|
<SwitchPrimitives.Thumb
|
||||||
|
className={cn(
|
||||||
|
"pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</SwitchPrimitives.Root>
|
||||||
|
))
|
||||||
|
Switch.displayName = SwitchPrimitives.Root.displayName
|
||||||
|
|
||||||
|
export {Switch}
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
import {useAtom} from "jotai"
|
import {useAtom} from "jotai"
|
||||||
import {atomWithStorage} from "jotai/utils"
|
import {atomWithStorage} from "jotai/utils"
|
||||||
|
|
||||||
import {Theme} from "Frontend/@/registry/themes"
|
import {Theme} from "@/registry/themes"
|
||||||
|
|
||||||
type Config = {
|
type Config = {
|
||||||
theme: Theme["name"]
|
theme: {
|
||||||
mode: "light" | "dark",
|
name: Theme["name"],
|
||||||
radius: number
|
mode: "light" | "dark" | "system"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const configAtom = atomWithStorage<Config>("config", {
|
const configAtom = atomWithStorage<Config>("config", {
|
||||||
theme: "zinc",
|
theme: {
|
||||||
mode: "light",
|
name: "zinc",
|
||||||
radius: 0.5,
|
mode: "system"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export function useConfig() {
|
export function useConfig() {
|
||||||
|
|||||||
+16
-2
@@ -1,6 +1,20 @@
|
|||||||
import { type ClassValue, clsx } from "clsx"
|
import {type ClassValue, clsx} from "clsx"
|
||||||
import { twMerge } from "tailwind-merge"
|
import {twMerge} from "tailwind-merge"
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs))
|
return twMerge(clsx(inputs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function cssVar(variable: string) {
|
||||||
|
return getComputedStyle(document.documentElement).getPropertyValue(`--${variable}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hsl(hsl: string) {
|
||||||
|
return `hsl(${hsl}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rand(min: number, max: number) {
|
||||||
|
const minCeiled = Math.ceil(min);
|
||||||
|
const maxFloored = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,164 +105,6 @@ export const themes = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "stone",
|
|
||||||
label: "Stone",
|
|
||||||
activeColor: {
|
|
||||||
light: "25 5.3% 44.7%",
|
|
||||||
dark: "33.3 5.5% 32.4%",
|
|
||||||
},
|
|
||||||
cssVars: {
|
|
||||||
light: {
|
|
||||||
background: "0 0% 100%",
|
|
||||||
foreground: "20 14.3% 4.1%",
|
|
||||||
card: "0 0% 100%",
|
|
||||||
"card-foreground": "20 14.3% 4.1%",
|
|
||||||
popover: "0 0% 100%",
|
|
||||||
"popover-foreground": "20 14.3% 4.1%",
|
|
||||||
primary: "24 9.8% 10%",
|
|
||||||
"primary-foreground": "60 9.1% 97.8%",
|
|
||||||
secondary: "60 4.8% 95.9%",
|
|
||||||
"secondary-foreground": "24 9.8% 10%",
|
|
||||||
muted: "60 4.8% 95.9%",
|
|
||||||
"muted-foreground": "25 5.3% 44.7%",
|
|
||||||
accent: "60 4.8% 95.9%",
|
|
||||||
"accent-foreground": "24 9.8% 10%",
|
|
||||||
destructive: "0 84.2% 60.2%",
|
|
||||||
"destructive-foreground": "60 9.1% 97.8%",
|
|
||||||
border: "20 5.9% 90%",
|
|
||||||
input: "20 5.9% 90%",
|
|
||||||
ring: "20 14.3% 4.1%",
|
|
||||||
radius: "0.95rem",
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
background: "20 14.3% 4.1%",
|
|
||||||
foreground: "60 9.1% 97.8%",
|
|
||||||
card: "20 14.3% 4.1%",
|
|
||||||
"card-foreground": "60 9.1% 97.8%",
|
|
||||||
popover: "20 14.3% 4.1%",
|
|
||||||
"popover-foreground": "60 9.1% 97.8%",
|
|
||||||
primary: "60 9.1% 97.8%",
|
|
||||||
"primary-foreground": "24 9.8% 10%",
|
|
||||||
secondary: "12 6.5% 15.1%",
|
|
||||||
"secondary-foreground": "60 9.1% 97.8%",
|
|
||||||
muted: "12 6.5% 15.1%",
|
|
||||||
"muted-foreground": "24 5.4% 63.9%",
|
|
||||||
accent: "12 6.5% 15.1%",
|
|
||||||
"accent-foreground": "60 9.1% 97.8%",
|
|
||||||
destructive: "0 62.8% 30.6%",
|
|
||||||
"destructive-foreground": "60 9.1% 97.8%",
|
|
||||||
border: "12 6.5% 15.1%",
|
|
||||||
input: "12 6.5% 15.1%",
|
|
||||||
ring: "24 5.7% 82.9%",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "gray",
|
|
||||||
label: "Gray",
|
|
||||||
activeColor: {
|
|
||||||
light: "220 8.9% 46.1%",
|
|
||||||
dark: "215 13.8% 34.1%",
|
|
||||||
},
|
|
||||||
cssVars: {
|
|
||||||
light: {
|
|
||||||
background: "0 0% 100%",
|
|
||||||
foreground: "224 71.4% 4.1%",
|
|
||||||
card: "0 0% 100%",
|
|
||||||
"card-foreground": "224 71.4% 4.1%",
|
|
||||||
popover: "0 0% 100%",
|
|
||||||
"popover-foreground": "224 71.4% 4.1%",
|
|
||||||
primary: "220.9 39.3% 11%",
|
|
||||||
"primary-foreground": "210 20% 98%",
|
|
||||||
secondary: "220 14.3% 95.9%",
|
|
||||||
"secondary-foreground": "220.9 39.3% 11%",
|
|
||||||
muted: "220 14.3% 95.9%",
|
|
||||||
"muted-foreground": "220 8.9% 46.1%",
|
|
||||||
accent: "220 14.3% 95.9%",
|
|
||||||
"accent-foreground": "220.9 39.3% 11%",
|
|
||||||
destructive: "0 84.2% 60.2%",
|
|
||||||
"destructive-foreground": "210 20% 98%",
|
|
||||||
border: "220 13% 91%",
|
|
||||||
input: "220 13% 91%",
|
|
||||||
ring: "224 71.4% 4.1%",
|
|
||||||
radius: "0.35rem",
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
background: "224 71.4% 4.1%",
|
|
||||||
foreground: "210 20% 98%",
|
|
||||||
card: "224 71.4% 4.1%",
|
|
||||||
"card-foreground": "210 20% 98%",
|
|
||||||
popover: "224 71.4% 4.1%",
|
|
||||||
"popover-foreground": "210 20% 98%",
|
|
||||||
primary: "210 20% 98%",
|
|
||||||
"primary-foreground": "220.9 39.3% 11%",
|
|
||||||
secondary: "215 27.9% 16.9%",
|
|
||||||
"secondary-foreground": "210 20% 98%",
|
|
||||||
muted: "215 27.9% 16.9%",
|
|
||||||
"muted-foreground": "217.9 10.6% 64.9%",
|
|
||||||
accent: "215 27.9% 16.9%",
|
|
||||||
"accent-foreground": "210 20% 98%",
|
|
||||||
destructive: "0 62.8% 30.6%",
|
|
||||||
"destructive-foreground": "210 20% 98%",
|
|
||||||
border: "215 27.9% 16.9%",
|
|
||||||
input: "215 27.9% 16.9%",
|
|
||||||
ring: "216 12.2% 83.9%",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "neutral",
|
|
||||||
label: "Neutral",
|
|
||||||
activeColor: {
|
|
||||||
light: "0 0% 45.1%",
|
|
||||||
dark: "0 0% 32.2%",
|
|
||||||
},
|
|
||||||
cssVars: {
|
|
||||||
light: {
|
|
||||||
background: "0 0% 100%",
|
|
||||||
foreground: "0 0% 3.9%",
|
|
||||||
card: "0 0% 100%",
|
|
||||||
"card-foreground": "0 0% 3.9%",
|
|
||||||
popover: "0 0% 100%",
|
|
||||||
"popover-foreground": "0 0% 3.9%",
|
|
||||||
primary: "0 0% 9%",
|
|
||||||
"primary-foreground": "0 0% 98%",
|
|
||||||
secondary: "0 0% 96.1%",
|
|
||||||
"secondary-foreground": "0 0% 9%",
|
|
||||||
muted: "0 0% 96.1%",
|
|
||||||
"muted-foreground": "0 0% 45.1%",
|
|
||||||
accent: "0 0% 96.1%",
|
|
||||||
"accent-foreground": "0 0% 9%",
|
|
||||||
destructive: "0 84.2% 60.2%",
|
|
||||||
"destructive-foreground": "0 0% 98%",
|
|
||||||
border: "0 0% 89.8%",
|
|
||||||
input: "0 0% 89.8%",
|
|
||||||
ring: "0 0% 3.9%",
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
background: "0 0% 3.9%",
|
|
||||||
foreground: "0 0% 98%",
|
|
||||||
card: "0 0% 3.9%",
|
|
||||||
"card-foreground": "0 0% 98%",
|
|
||||||
popover: "0 0% 3.9%",
|
|
||||||
"popover-foreground": "0 0% 98%",
|
|
||||||
primary: "0 0% 98%",
|
|
||||||
"primary-foreground": "0 0% 9%",
|
|
||||||
secondary: "0 0% 14.9%",
|
|
||||||
"secondary-foreground": "0 0% 98%",
|
|
||||||
muted: "0 0% 14.9%",
|
|
||||||
"muted-foreground": "0 0% 63.9%",
|
|
||||||
accent: "0 0% 14.9%",
|
|
||||||
"accent-foreground": "0 0% 98%",
|
|
||||||
destructive: "0 62.8% 30.6%",
|
|
||||||
"destructive-foreground": "0 0% 98%",
|
|
||||||
border: "0 0% 14.9%",
|
|
||||||
input: "0 0% 14.9%",
|
|
||||||
ring: "0 0% 83.1%",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "red",
|
name: "red",
|
||||||
label: "Red",
|
label: "Red",
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ export default function App() {
|
|||||||
attribute="class"
|
attribute="class"
|
||||||
defaultTheme="system"
|
defaultTheme="system"
|
||||||
enableSystem
|
enableSystem
|
||||||
disableTransitionOnChange
|
|
||||||
>
|
>
|
||||||
<IconContext.Provider value={{size: 20}}>
|
<IconContext.Provider value={{size: 20}}>
|
||||||
<RouterProvider router={router}/>
|
<RouterProvider router={router}/>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import {hsl} from "Frontend/@/lib/utils";
|
||||||
|
|
||||||
|
export default function GameyfinLogo({primary, secondary, className}: {
|
||||||
|
primary: string,
|
||||||
|
secondary: string,
|
||||||
|
className?: string
|
||||||
|
}) {
|
||||||
|
const primaryColor = hsl(primary)
|
||||||
|
const secondaryColor = (secondary === null || secondary === undefined) ? primaryColor : hsl(secondary);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 365.58 336.34" className={className}>
|
||||||
|
<polygon points="190.1 49.13 190.1 69.24 207.98 44.13 190.1 49.13" fill={secondaryColor}/>
|
||||||
|
<polygon points="365.58 0 263.22 28.66 205.64 95.97 365.58 51.18 365.58 0" fill={secondaryColor}/>
|
||||||
|
<polygon
|
||||||
|
points="190.1 283.11 248.6 266.73 248.6 149.74 365.58 116.99 365.58 73.12 190.1 122.25 190.1 283.11"
|
||||||
|
fill={secondaryColor}/>
|
||||||
|
<polygon
|
||||||
|
points="58.49 144.48 155.98 117.18 175.48 89.79 175.48 53.23 0 102.36 0 336.34 58.49 254.15 58.49 144.48"
|
||||||
|
fill={primaryColor}/>
|
||||||
|
<polygon
|
||||||
|
points="116.99 199.59 116.99 245.09 65.81 259.42 0 336.34 175.48 287.2 175.48 170.22 131.61 182.5 116.99 199.59"
|
||||||
|
fill={primaryColor}/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,46 +1,44 @@
|
|||||||
import {Theme} from "Frontend/@/registry/themes";
|
import {Theme} from "Frontend/@/registry/themes";
|
||||||
import {Card} from "Frontend/@/components/ui/card";
|
import {Card} from "Frontend/@/components/ui/card";
|
||||||
import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "Frontend/@/components/ui/tooltip";
|
import {Tooltip, TooltipContent, TooltipTrigger} from "Frontend/@/components/ui/tooltip";
|
||||||
import {useTheme} from "next-themes";
|
import {useTheme} from "next-themes";
|
||||||
|
import GameyfinLogo from "Frontend/components/theming/GameyfinLogo";
|
||||||
|
import {hsl} from "Frontend/@/lib/utils";
|
||||||
|
|
||||||
export default function ThemePreview({theme}: { theme: Theme }) {
|
export default function ThemePreview({theme}: { theme: Theme }) {
|
||||||
const {resolvedTheme} = useTheme();
|
//@ts-ignore
|
||||||
|
let resolvedTheme: "light" | "dark" = useTheme().resolvedTheme ?? "light";
|
||||||
|
const {setTheme} = useTheme();
|
||||||
|
|
||||||
|
function toggleMode() {
|
||||||
|
resolvedTheme = resolvedTheme === "light" ? "dark" : "light";
|
||||||
|
setTheme(resolvedTheme);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<Tooltip>
|
||||||
<Tooltip delayDuration={0}>
|
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Card className="overflow-hidden flex place-self-center">
|
<Card
|
||||||
<svg width="228" height="120" viewBox="0 0 228 120" fill="none"
|
className="overflow-hidden flex place-self-center justify-center p-6"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
style={{background: hsl(theme.cssVars[resolvedTheme].background)}}>
|
||||||
{/*@ts-ignore*/}
|
<GameyfinLogo primary={theme.cssVars[resolvedTheme].primary}
|
||||||
<path id="background" d="M0 0H228V120H0V0Z" fill={theme.cssVars[resolvedTheme].background}/>
|
secondary={theme.cssVars[resolvedTheme].secondary}
|
||||||
<rect id="background-secondary" x="29" y="54" width="144" height="53" rx="2"
|
className="w-1/2"
|
||||||
fill="#30363D"/>
|
/>
|
||||||
<rect x="184" y="54" width="32" height="36" rx="2" fill="#30363D"/>
|
|
||||||
<rect opacity="0.3" x="29" y="59" width="144" height="12" fill="#2EA043"/>
|
|
||||||
<path opacity="0.6" d="M0 0H228V23H0V0Z" fill="#484F58"/>
|
|
||||||
<rect x="13" y="9" width="32" height="6" rx="3" fill="#8B949E"/>
|
|
||||||
<rect x="29" y="36" width="48" height="6" rx="3" fill="#6E7681"/>
|
|
||||||
<rect x="34" y="62" width="64" height="6" rx="3" fill="#3FB950"/>
|
|
||||||
<rect x="210" y="36" width="6" height="6" rx="1" fill="#DA3633"/>
|
|
||||||
<rect x="202" y="36" width="6" height="6" rx="1" fill="#3FB950"/>
|
|
||||||
<rect x="53" y="9" width="32" height="6" rx="3" fill="#8B949E"/>
|
|
||||||
<rect x="93" y="9" width="32" height="6" rx="3" fill="#8B949E"/>
|
|
||||||
</svg>
|
|
||||||
</Card>
|
</Card>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="bottom">
|
<TooltipContent side="bottom">
|
||||||
<p className="capitalize">{theme.name}</p>
|
<p className="capitalize">{theme.name}</p>
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<svg width="228" height="120" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M0 0H228V120H0V0Z" fill="#161B22"/>
|
<svg width="228" height="120" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect x="29" y="54" width="144" height="53" rx="2" fill="#30363D"/>
|
<path id="background" d="M0 0H228V120H0V0Z" fill={theme.cssVars[resolvedTheme].background}/>
|
||||||
|
<rect id="background-secondary" x="29" y="54" width="144" height="53" rx="2" fill="#30363D"/>
|
||||||
<rect x="184" y="54" width="32" height="36" rx="2" fill="#30363D"/>
|
<rect x="184" y="54" width="32" height="36" rx="2" fill="#30363D"/>
|
||||||
<rect opacity="0.3" x="29" y="59" width="144" height="12" fill="#2EA043"/>
|
<rect opacity="0.3" x="29" y="59" width="144" height="12" fill="#2EA043"/>
|
||||||
<path opacity="0.6" d="M0 0H228V23H0V0Z" fill="#484F58"/>
|
<path opacity="0.6" d="M0 0H228V23H0V0Z" fill="#484F58"/>
|
||||||
@@ -51,5 +49,5 @@ export default function ThemePreview({theme}: { theme: Theme }) {
|
|||||||
<rect x="202" y="36" width="6" height="6" rx="1" fill="#3FB950"/>
|
<rect x="202" y="36" width="6" height="6" rx="1" fill="#3FB950"/>
|
||||||
<rect x="53" y="9" width="32" height="6" rx="3" fill="#8B949E"/>
|
<rect x="53" y="9" width="32" height="6" rx="3" fill="#8B949E"/>
|
||||||
<rect x="93" y="9" width="32" height="6" rx="3" fill="#8B949E"/>
|
<rect x="93" y="9" width="32" height="6" rx="3" fill="#8B949E"/>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -3,10 +3,12 @@ import * as Yup from 'yup';
|
|||||||
import Wizard from "Frontend/components/wizard/Wizard";
|
import Wizard from "Frontend/components/wizard/Wizard";
|
||||||
import WizardStep from "Frontend/components/wizard/WizardStep";
|
import WizardStep from "Frontend/components/wizard/WizardStep";
|
||||||
import Input from "Frontend/components/Input";
|
import Input from "Frontend/components/Input";
|
||||||
import {GearFine, HandWaving, Palette, User} from "@phosphor-icons/react";
|
import {GearFine, HandWaving, Moon, Palette, SunDim, User} from "@phosphor-icons/react";
|
||||||
import ThemePreview from "Frontend/components/theming/ThemePreview";
|
import ThemePreview from "Frontend/components/theming/ThemePreview";
|
||||||
import {Theme, themes} from "Frontend/@/registry/themes";
|
import {Theme, themes} from "Frontend/@/registry/themes";
|
||||||
import {Card} from "Frontend/@/components/ui/card";
|
import {Card} from "Frontend/@/components/ui/card";
|
||||||
|
import {Switch} from "Frontend/@/components/ui/switch";
|
||||||
|
import {useTheme} from "next-themes";
|
||||||
|
|
||||||
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
@@ -35,8 +37,19 @@ function WelcomeStep() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ThemeStep() {
|
function ThemeStep() {
|
||||||
|
const {setTheme, theme} = useTheme();
|
||||||
|
|
||||||
|
function toggleMode() {
|
||||||
|
setTheme(theme === "light" ? "dark" : "light");
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col size-full items-center">
|
<div className="flex flex-col size-full items-center">
|
||||||
|
<div className="w-full flex flex-row items-center justify-center gap-4 mb-16">
|
||||||
|
<SunDim size={32}/>
|
||||||
|
<Switch checked={theme === "dark"} onCheckedChange={() => toggleMode()}></Switch>
|
||||||
|
<Moon size={32}/>
|
||||||
|
</div>
|
||||||
<div className="grid grid-cols-3 w-1/2 min-w-[468px] gap-12">
|
<div className="grid grid-cols-3 w-1/2 min-w-[468px] gap-12">
|
||||||
{themes.map(((theme: Theme) => (
|
{themes.map(((theme: Theme) => (
|
||||||
<ThemePreview key={theme.name} theme={theme}/>
|
<ThemePreview key={theme.name} theme={theme}/>
|
||||||
|
|||||||
Generated
+47
@@ -30,6 +30,7 @@
|
|||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
"@radix-ui/react-switch": "^1.0.3",
|
||||||
"@radix-ui/react-tooltip": "^1.0.7",
|
"@radix-ui/react-tooltip": "^1.0.7",
|
||||||
"@vaadin/bundles": "24.3.0",
|
"@vaadin/bundles": "24.3.0",
|
||||||
"@vaadin/common-frontend": "0.0.19",
|
"@vaadin/common-frontend": "0.0.19",
|
||||||
@@ -3328,6 +3329,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-switch": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.13.10",
|
||||||
|
"@radix-ui/primitive": "1.0.1",
|
||||||
|
"@radix-ui/react-compose-refs": "1.0.1",
|
||||||
|
"@radix-ui/react-context": "1.0.1",
|
||||||
|
"@radix-ui/react-primitive": "1.0.3",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.0.1",
|
||||||
|
"@radix-ui/react-use-previous": "1.0.1",
|
||||||
|
"@radix-ui/react-use-size": "1.0.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-tooltip": {
|
"node_modules/@radix-ui/react-tooltip": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz",
|
||||||
@@ -3432,6 +3462,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-use-previous": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.13.10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-use-rect": {
|
"node_modules/@radix-ui/react-use-rect": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
"@radix-ui/react-switch": "^1.0.3",
|
||||||
"@radix-ui/react-tooltip": "^1.0.7",
|
"@radix-ui/react-tooltip": "^1.0.7",
|
||||||
"@vaadin/bundles": "24.3.0",
|
"@vaadin/bundles": "24.3.0",
|
||||||
"@vaadin/common-frontend": "0.0.19",
|
"@vaadin/common-frontend": "0.0.19",
|
||||||
|
|||||||
Reference in New Issue
Block a user