Урок 19. Решения
⚡ Кратко
Готовая фирменная тема, своя пара токенов и страница-образец.
Решение задания 1
📄 src/index.css
/* src/index.css */
:root {
--primary: oklch(0.55 0.21 264);
--primary-foreground: oklch(0.985 0 0);
}
.dark {
--primary: oklch(0.62 0.19 264);
--primary-foreground: oklch(0.145 0 0);
}
Почему в тёмной теме foreground тёмный: сам primary стал светлее (чтобы выделяться на тёмном фоне), значит, текст на нём должен быть тёмным. Пара всегда переворачивается вместе.
Переключите тему — пара перевернётся
<div class="flex flex-wrap items-center gap-3">
<button class="inline-flex h-8 items-center justify-center rounded-lg bg-brand px-3 text-sm font-medium text-brand-foreground">Фирменная кнопка</button>
<span class="text-sm text-muted-foreground">Переключите тему — пара перевернётся</span>
</div>
Решение задания 2
📄 src/index.css
@theme inline {
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
}
:root {
--success: oklch(0.62 0.15 160);
--success-foreground: oklch(0.985 0 0);
}
.dark {
--success: oklch(0.72 0.14 160);
--success-foreground: oklch(0.145 0 0);
}
<Badge className="bg-success text-success-foreground">Оплачено</Badge>
<Button className="bg-success text-success-foreground hover:opacity-90">Подтвердить</Button>
Если роль используется часто, не ограничивайтесь
className — заведите вариант в компоненте:
success: "bg-success text-success-foreground". Тогда
применение будет единообразным по всему проекту.Решение задания 3
📄 src/routes/theme.tsx
// src/routes/theme.tsx — страница-образец
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
const TOKENS = [
["bg-background text-foreground", "background"],
["bg-card text-card-foreground", "card"],
["bg-primary text-primary-foreground", "primary"],
["bg-secondary text-secondary-foreground", "secondary"],
["bg-muted text-muted-foreground", "muted"],
["bg-accent text-accent-foreground", "accent"],
]
export function ThemePage() {
return (
<div className="space-y-6 p-6">
<div className="grid gap-2 sm:grid-cols-3">
{TOKENS.map(([classes, name]) => (
<div key={name} className={`rounded-lg p-3 text-sm ring-1 ring-border ${classes}`}>{name}</div>
))}
</div>
<div className="flex flex-wrap gap-2">
<Button>Default</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Destructive</Button>
</div>
<div className="flex flex-wrap gap-2">
<Badge>Badge</Badge>
<Badge variant="outline">Outline</Badge>
</div>
<Input placeholder="Поле ввода" />
<Card><CardHeader><CardTitle>Карточка</CardTitle></CardHeader><CardContent>Содержимое</CardContent></Card>
</div>
)
}
Зачем это нужно: любая правка темы проверяется за десять секунд на одном экране, а не хождением по всему приложению. Это дешёвая страховка от «поправил кнопку — сломал меню».