shadcn Studio: компоненты React и генератор тем — примеры
Практическое руководство по shadcn Studio: установка компонентов, настройка темы для Tailwind CSS 4 и шесть примеров CSS/TSX. Бесплатная мастерская оформления без регистрации с предпросмотром и экспортом CSS/JSON.

У хорошего интерфейса кнопки, поля, карточки и вкладки выглядят как части одного продукта. Когда каждый элемент оформляется отдельно, даже небольшая страница быстро обрастает разными цветами и отступами. shadcn Studio помогает начать с готовых вариантов компонентов для React, а затем подобрать общую тему и изменить код под свою задачу.
Ниже — бесплатная интерактивная мастерская без регистрации: выберите палитру, настройте цвета и скругления, сравните светлый и темный режимы на нескольких элементах интерфейса. После демонстрации разберем установку, CSS-переменные и собственные примеры TSX, которые можно использовать в своем проекте.
Мастерская темы для вашего интерфейса
Настройте цвета и скругления. Посмотрите оформление на кнопках, форме и карточках, затем скачайте CSS для своего проекта.
Загрузка мастерской…
Учебная мастерская — ae-nekrasov.ru. Материал посвящён shadcn Studio. Настройки обрабатываются в браузере.
Мастерская на этой странице создана нами для изучения темизации. Предпросмотр использует HTML и собственные стили с совместимыми именами токенов; это не официальный редактор Studio и не приложение на shadcn/ui. CSS переносит настройки оформления, JSON сохраняет проект мастерской. React-примеры ниже показывают, как применять тот же принцип в настоящем React-проекте.
Что такое shadcn Studio
В официальном репозитории shadcn Studio представлены варианты компонентов, блоки и инструменты оформления. Подход основан на добавлении исходного кода в проект: после установки можно менять разметку, классы и поведение. Обновления не заменяют внесенные вами изменения автоматически, поэтому перед повторным добавлением компонента полезно сравнить файлы.
В каталоге есть бесплатные и платные ресурсы. Для знакомства достаточно бесплатных компонентов и ручной настройки темы. PRO открывает дополнительные возможности и материалы; условия конкретного ресурса проверяйте на официальной странице. По вводной документации, Studio развивается отдельно от shadcn/ui и предлагает варианты поверх его экосистемы.
У бесплатной части лицензия MIT с дополнительными условиями Commons Clause. Условия ограничивают распространение неизмененных компонентов и создание конкурирующих продуктов. Поэтому наш материал объясняет подключение, а примеры ниже — собственные композиции из обычных shadcn/ui-элементов. Смотрите лицензию репозитория и раздел лицензирования Studio.
Установка: сначала проект, затем выбранные элементы
Понадобится React-проект со сборкой TypeScript/TSX, Tailwind CSS и настроенным shadcn/ui. Для нового проекта на Vite официальный CLI предлагает интерактивную подготовку. Выберите подходящие стиль и основу компонентов; в примерах ниже используются обычные API Button, Card, Input, Label, Badge и Tabs:
npx shadcn@latest init -t vite
npx shadcn@latest add button card input label badge tabs
Для существующего проекта не нужно создавать новый: настройте Tailwind, пути импорта @/ и файл components.json по инструкции shadcn/ui для Vite. Путь к глобальному CSS зависит от проекта: например, src/index.css в Vite или app/globals.css в Next.js. Компоненты должны читать этот файл через вашу сборку. Примеры рассчитаны на Vite; в Next.js файлы с состоянием и обработчиками событий должны быть клиентскими компонентами с директивой "use client" в начале.
Для бесплатных вариантов самого Studio зарегистрируйте его пространство имен, затем добавьте конкретный вариант. button-01 приведен в официальной инструкции как бесплатный:
npx shadcn@latest registry add "@shadcn-studio=https://shadcnstudio.com/r/{style}/{name}.json"
npx shadcn@latest add @shadcn-studio/button-01
Первая команда настраивает реестр, вторая устанавливает вариант; она не является установкой всех возможностей Studio. Перед подтверждением посмотрите, какие файлы и зависимости добавляются. Не включайте перезапись измененных файлов без сравнения. Актуальные команды и различия бесплатных и PRO-реестров описаны в документации Studio CLI.
Пример 1. Цвета как роли, а не разрозненные значения
Токен описывает роль цвета. --background отвечает за поверхность страницы, --foreground — за текст, --primary и --primary-foreground — за главное действие и надпись на нем. Если поменять эту пару, все элементы, использующие ее, получают единый вид. Темному режиму нужны собственные значения: простое затемнение страницы часто делает текст менее читаемым.
:root {
--background: #f7f8fa;
--foreground: #18212b;
--card: #ffffff;
--card-foreground: #18212b;
--primary: #155e63;
--primary-foreground: #ffffff;
--muted: #eaf0f1;
--muted-foreground: #52616b;
--border: #cad7da;
--input: #cad7da;
--ring: #155e63;
--radius: 0.75rem;
}
.dark {
--background: #101c22;
--foreground: #edf6f7;
--card: #182a32;
--card-foreground: #edf6f7;
--primary: #8fd8d2;
--primary-foreground: #102a2c;
--muted: #233942;
--muted-foreground: #b1c7ce;
--border: #38535e;
--input: #38535e;
--ring: #8fd8d2;
}
Это сокращенный фрагмент нашей палитры: другие токены существующей темы сохраняйте. Не заменяйте им весь глобальный файл. Имена и пары цветов соответствуют правилам темизации shadcn/ui. В современных темах используются полноценные значения цветов, включая HEX или OKLCH; старые инструкции с hsl(var(--primary)) нельзя смешивать с такими значениями без адаптации.
Пример 2. Связь переменных с Tailwind CSS 4
Объявить переменную недостаточно, чтобы появился класс Tailwind. В настроенном shadcn-проекте связь обычно уже создана CLI. При ручной настройке проверьте блок @theme inline. Он позволяет применять семантические классы: bg-primary, text-primary-foreground и border-border, вместо повторения конкретного цвета в каждом элементе.
/* Фрагмент существующего CSS после подключения Tailwind 4. */
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--radius-lg: var(--radius);
}
Сохраните остальные сопоставления и шкалу радиусов своего проекта. Директива обрабатывается сборкой Tailwind, а обычный браузер не превращает ее в CSS-классы. Подробнее — в официальном руководстве Tailwind по переменным темы. Переключение светлой и темной схемы подключается отдельно; для Vite есть пример ThemeProvider, который управляет классом .dark.
Пример 3. Кнопки с понятной иерархией
Одно действие выделяем цветом, дополнительное оставляем контурным. Состояние результата показываем текстом: посетитель должен понять, произошло ли действие. Здесь кнопка лишь демонстрирует локальный выбор — серверного сохранения нет. Такой небольшой пример полезен для проверки палитры, фокуса и длинной подписи.
import { useState } from "react";
import { Button } from "@/components/ui/button";
export function ThemeActions() {
const [message, setMessage] = useState("");
return (
<div className="space-y-3">
<div className="flex flex-wrap gap-3">
<Button onClick={() => setMessage("Оформление выбрано")}>
Использовать оформление
</Button>
<Button variant="outline" onClick={() => setMessage("")}>
Сбросить выбор
</Button>
</div>
<p role="status" className="text-sm text-muted-foreground">
{message}
</p>
</div>
);
}
Для состояния загрузки блокируйте повторное нажатие и объясняйте его надписью. Для перехода на другую страницу используйте ссылку с соответствующим оформлением. Свойства variant и способы применения приведены в документации Button; варианты Studio можно искать в его каталоге кнопок.
Пример 4. Карточка проекта
Карточка группирует название, статус и краткое пояснение. Отдельные поверхности помогают проверить тему на реальном содержимом. Не делайте всю карточку неочевидной кликабельной областью, если внутри есть несколько действий: отдельная кнопка или ссылка понятнее. Здесь карточка остается обычным информационным блоком.
import { Badge } from "@/components/ui/badge";
import {
Card, CardContent, CardDescription, CardHeader, CardTitle
} from "@/components/ui/card";
export function ProjectCard() {
return (
<Card className="w-full max-w-md">
<CardHeader className="space-y-3">
<Badge variant="secondary">В работе</Badge>
<CardTitle>Личный кабинет клиента</CardTitle>
<CardDescription>
Документы, этапы проекта и понятная обратная связь.
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-sm">Следующий этап: согласование макета.</p>
</CardContent>
</Card>
);
}
max-w-md ограничивает ширину, а w-full позволяет карточке занять доступное место на телефоне. Не назначайте фиксированную высоту ради выравнивания: длинное описание должно помещаться. Больше вариантов есть в официальном каталоге Card.
Пример 5. Форма с подписью и обратной связью
Красивого поля недостаточно: нужны подпись, понятное действие и результат. Используем встроенную проверку обязательного email браузером. Отправка ниже учебная: данные не уходят на сервер. В рабочем продукте подключите обработчик и проверку на сервере, сохранив сообщения об ошибках рядом с полями.
import { useId, useState, type FormEvent } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
export function ContactPreview() {
const emailId = useId();
const [message, setMessage] = useState("");
function submit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
setMessage("Форма прошла проверку. Это учебный пример без отправки.");
}
return (
<form onSubmit={submit} className="max-w-md space-y-4">
<div className="space-y-2">
<Label htmlFor={emailId}>Электронная почта</Label>
<Input id={emailId} name="email" type="email"
autoComplete="email" placeholder="name@example.com" required />
</div>
<Button type="submit">Проверить форму</Button>
<p role="status" className="text-sm text-muted-foreground">
{message}
</p>
</form>
);
}
useId() связывает подпись с конкретным полем даже при нескольких формах на странице. Placeholder дает пример, но не заменяет Label. Проверяйте активное поле и ошибку в обеих схемах. Свойства поля описаны в документации Input.
Пример 6. Вкладки для связанной информации
Вкладки полезны, когда несколько разделов относятся к одному объекту: описание, состав, параметры. Они сокращают видимую длину блока, но скрывают часть информации. Критичные условия заказа лучше показывать сразу. Короткие названия удобнее на узком экране и не требуют горизонтального прокручивания.
import {
Tabs, TabsContent, TabsList, TabsTrigger
} from "@/components/ui/tabs";
export function ProjectTabs() {
return (
<Tabs defaultValue="overview" className="w-full max-w-lg">
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="overview">Описание</TabsTrigger>
<TabsTrigger value="details">Состав</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="p-4">
Единая тема для кабинета клиента и страницы проекта.
</TabsContent>
<TabsContent value="details" className="p-4">
Кнопки, карточки, поля формы и понятные статусы.
</TabsContent>
</Tabs>
);
}
Значения value связывают переключатели с содержимым, а defaultValue определяет начальный раздел. Используйте компонент вкладок, чтобы не собирать управление фокусом вручную. Поведение и варианты приведены в документации Tabs.
Как перенести результат в свой проект
Начните с готовой палитры, затем настройте основной цвет, текст и фон. Проверьте кнопку, карточку и форму; после этого переключите тему и повторите проверку. В мастерской скачайте CSS для оформления и JSON для возврата к настройкам. CSS не добавляет поведение React-компонентов, а JSON не является реестром Studio.
В рабочем shadcn-проекте обновите значения в существующих блоках :root и .dark, сохранив подключение Tailwind и дополнительные токены. В официальном генераторе Studio также предусмотрен ручной перенос CSS-переменных; установка сохраненной пользовательской темы одной командой отмечена как PRO. Для больших проектов полезно рассмотреть его расширенные настройки.
Перед публикацией пройдите страницу клавиатурой, проверьте видимый фокус, контраст, перенос длинных названий и форму на телефоне. Готовая библиотека помогает начать, но удобство итоговой страницы зависит от выбранной композиции и содержания. Для следующего шага посмотрите примеры анимации React Bits, генерацию PDF в React или конструктор страницы на Bootstrap 5.


