feat(shared): ThemeToggle + Logo + design system rules (Sprint 0.5 étape 8)
This commit is contained in:
parent
7dfd0df6b3
commit
ee6d679950
4 changed files with 120 additions and 18 deletions
46
src/shared/components/Logo.tsx
Normal file
46
src/shared/components/Logo.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
24
src/shared/components/ThemeToggle.tsx
Normal file
24
src/shared/components/ThemeToggle.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue