mirror of
https://github.com/domfelipe/mika-agent-assist.git
synced 2026-08-07 09:36:43 +00:00
Changes
Co-authored-by: domfelipe <53182096+domfelipe@users.noreply.github.com>
This commit is contained in:
parent
6184835992
commit
b5254cf33d
7 changed files with 289 additions and 77 deletions
19
src/components/mika/Logo.tsx
Normal file
19
src/components/mika/Logo.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { Link } from "@tanstack/react-router";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function Logo({ className, size = "md" }: { className?: string; size?: "sm" | "md" | "lg" }) {
|
||||
const sizes = {
|
||||
sm: "text-xl",
|
||||
md: "text-2xl",
|
||||
lg: "text-3xl",
|
||||
};
|
||||
return (
|
||||
<Link
|
||||
to="/"
|
||||
aria-label="Mika — página inicial"
|
||||
className={cn("font-bold tracking-tight text-foreground", sizes[size], className)}
|
||||
>
|
||||
Mika<span className="text-accent">.</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
21
src/components/mika/ThemeToggle.tsx
Normal file
21
src/components/mika/ThemeToggle.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"use client";
|
||||
|
||||
import { Moon, Sun } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useTheme } from "@/components/theme-provider";
|
||||
|
||||
export function ThemeToggle() {
|
||||
const { theme, toggleTheme } = useTheme();
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
aria-label={theme === "dark" ? "Mudar para tema claro" : "Mudar para tema escuro"}
|
||||
onClick={toggleTheme}
|
||||
className="rounded-lg"
|
||||
>
|
||||
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
||||
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
65
src/components/theme-provider.tsx
Normal file
65
src/components/theme-provider.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
"use client";
|
||||
|
||||
import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
|
||||
|
||||
type Theme = "light" | "dark";
|
||||
type ThemeContextValue = {
|
||||
theme: Theme;
|
||||
setTheme: (t: Theme) => void;
|
||||
toggleTheme: () => void;
|
||||
};
|
||||
|
||||
const ThemeContext = createContext<ThemeContextValue | null>(null);
|
||||
const STORAGE_KEY = "mika-theme";
|
||||
|
||||
function applyTheme(theme: Theme) {
|
||||
if (typeof document === "undefined") return;
|
||||
const root = document.documentElement;
|
||||
if (theme === "dark") root.classList.add("dark");
|
||||
else root.classList.remove("dark");
|
||||
root.style.colorScheme = theme;
|
||||
}
|
||||
|
||||
function getInitialTheme(): Theme {
|
||||
if (typeof window === "undefined") return "light";
|
||||
try {
|
||||
const stored = window.localStorage.getItem(STORAGE_KEY);
|
||||
if (stored === "light" || stored === "dark") return stored;
|
||||
} catch {}
|
||||
if (window.matchMedia?.("(prefers-color-scheme: dark)").matches) return "dark";
|
||||
return "light";
|
||||
}
|
||||
|
||||
export function ThemeProvider({ children }: { children: ReactNode }) {
|
||||
const [theme, setThemeState] = useState<Theme>("light");
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const t = getInitialTheme();
|
||||
setThemeState(t);
|
||||
applyTheme(t);
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
const setTheme = (t: Theme) => {
|
||||
setThemeState(t);
|
||||
applyTheme(t);
|
||||
try {
|
||||
window.localStorage.setItem(STORAGE_KEY, t);
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const toggleTheme = () => setTheme(theme === "dark" ? "light" : "dark");
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, setTheme, toggleTheme }}>
|
||||
<div style={{ visibility: mounted ? "visible" : "visible" }}>{children}</div>
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useTheme() {
|
||||
const ctx = useContext(ThemeContext);
|
||||
if (!ctx) throw new Error("useTheme deve ser usado dentro de ThemeProvider");
|
||||
return ctx;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue