feat(shared): ThemeToggle + Logo + design system rules (Sprint 0.5 étape 8)

This commit is contained in:
Hermann_Kitio 2026-04-18 01:33:24 +03:00
parent 7dfd0df6b3
commit ee6d679950
4 changed files with 120 additions and 18 deletions

View file

@ -0,0 +1,46 @@
import { cn } from '@/shared/lib/utils'
type LogoSize = 'sm' | 'md'
type LogoVariant = 'icon' | 'full'
interface LogoProps {
size?: LogoSize
variant?: LogoVariant
className?: string
}
const markStyles: Record<LogoSize, string> = {
sm: 'size-6 text-[11px]',
md: 'size-8 text-[13px]',
}
const wordmarkStyles: Record<LogoSize, string> = {
sm: 'text-sm',
md: 'text-base',
}
export function Logo({ size = 'md', variant = 'full', className }: LogoProps) {
return (
<div
className={cn(
'inline-flex items-center gap-2.5 font-bold tracking-tight text-ink-1',
className
)}
role={variant === 'icon' ? 'img' : undefined}
aria-label={variant === 'icon' ? 'Expria' : undefined}
>
<span
className={cn(
'flex shrink-0 items-center justify-center rounded-sm bg-expria font-bold tracking-tight text-white',
markStyles[size]
)}
aria-hidden="true"
>
EX
</span>
{variant === 'full' && (
<span className={cn('leading-none', wordmarkStyles[size])}>Expria</span>
)}
</div>
)
}

View file

@ -0,0 +1,24 @@
import { Moon, Sun } from 'lucide-react'
import { useTheme } from '@/shared/hooks/useTheme'
import { Button } from '@/shared/components/ui/button'
interface ThemeToggleProps {
className?: string
}
export function ThemeToggle({ className }: ThemeToggleProps) {
const { theme, setTheme } = useTheme()
const isDark = theme === 'dark'
return (
<Button
variant="ghost"
size="icon"
className={className}
aria-label={isDark ? 'Passer en mode clair' : 'Passer en mode sombre'}
onClick={() => setTheme(isDark ? 'light' : 'dark')}
>
{isDark ? <Sun className="size-4" /> : <Moon className="size-4" />}
</Button>
)
}