Вёрстка сайта с использованием Shadcn/UI

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Вёрстка сайта с использованием Shadcn/UI
Простая
~2-3 рабочих дня
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Вёрстка сайта с использованием Shadcn/UI

Shadcn/UI — это не npm-пакет, а коллекция копируемых компонентов на основе Radix UI Primitives и Tailwind CSS. Компоненты добавляются в проект через CLI — исходный код оказывается прямо в репозитории и может быть изменён без форков. Это принципиально отличает Shadcn/UI от традиционных библиотек.

Инициализация

npx shadcn@latest init

CLI спрашивает о стиле (default/new-york), base color, alias для утилит. Конфигурация записывается в components.json:

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": false,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "src/styles/globals.css",
    "baseColor": "slate",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  }
}

Добавление компонентов:

npx shadcn@latest add button card dialog form input select table tabs

Каждая команда создаёт файл в src/components/ui/.

Цветовая система через CSS-переменные

/* src/styles/globals.css */
@import "tailwindcss";

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222 47% 11%;
    --card: 0 0% 100%;
    --card-foreground: 222 47% 11%;
    --popover: 0 0% 100%;
    --popover-foreground: 222 47% 11%;
    --primary: 221 83% 53%;       /* #2563eb */
    --primary-foreground: 0 0% 100%;
    --secondary: 210 40% 96%;
    --secondary-foreground: 222 47% 11%;
    --muted: 210 40% 96%;
    --muted-foreground: 215 16% 47%;
    --accent: 210 40% 96%;
    --accent-foreground: 222 47% 11%;
    --destructive: 0 84% 60%;
    --destructive-foreground: 0 0% 100%;
    --border: 214 32% 91%;
    --input: 214 32% 91%;
    --ring: 221 83% 53%;
    --radius: 0.5rem;
  }

  .dark {
    --background: 222 47% 7%;
    --foreground: 210 40% 98%;
    --card: 222 47% 11%;
    --card-foreground: 210 40% 98%;
    --popover: 222 47% 11%;
    --popover-foreground: 210 40% 98%;
    --primary: 217 91% 60%;
    --primary-foreground: 0 0% 100%;
    --secondary: 217 33% 17%;
    --secondary-foreground: 210 40% 98%;
    --muted: 217 33% 17%;
    --muted-foreground: 215 20% 65%;
    --accent: 217 33% 17%;
    --accent-foreground: 210 40% 98%;
    --destructive: 0 63% 31%;
    --destructive-foreground: 210 40% 98%;
    --border: 217 33% 17%;
    --input: 217 33% 17%;
    --ring: 217 91% 60%;
  }
}

Компоненты из коробки: примеры использования

Диалог с формой

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

const ContactDialog = () => (
  <Dialog>
    <DialogTrigger asChild>
      <Button>Связаться</Button>
    </DialogTrigger>
    <DialogContent className="sm:max-w-md">
      <DialogHeader>
        <DialogTitle>Свяжитесь с нами</DialogTitle>
        <DialogDescription>
          Заполните форму и мы ответим в течение 24 часов.
        </DialogDescription>
      </DialogHeader>
      <div className="flex flex-col gap-4 py-4">
        <div className="flex flex-col gap-2">
          <Label htmlFor="name">Имя</Label>
          <Input id="name" placeholder="Иван Иванов" />
        </div>
        <div className="flex flex-col gap-2">
          <Label htmlFor="email">Email</Label>
          <Input id="email" type="email" placeholder="[email protected]" />
        </div>
      </div>
      <DialogFooter>
        <Button type="submit" className="w-full">Отправить</Button>
      </DialogFooter>
    </DialogContent>
  </Dialog>
);

Форма с React Hook Form + Zod

import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';

const formSchema = z.object({
  email: z.string().email('Некорректный email'),
  name: z.string().min(2, 'Минимум 2 символа'),
  subject: z.string().min(5, 'Минимум 5 символов'),
});

type FormValues = z.infer<typeof formSchema>;

const LeadForm = () => {
  const form = useForm<FormValues>({ resolver: zodResolver(formSchema) });

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-5">
        <FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Имя</FormLabel>
              <FormControl>
                <Input placeholder="Иван Иванов" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input type="email" placeholder="[email protected]" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit" className="w-full">
          Отправить заявку
        </Button>
      </form>
    </Form>
  );
};

Карточки с Tabs

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';

const PricingTabs = () => (
  <Tabs defaultValue="monthly" className="mx-auto max-w-2xl">
    <TabsList className="grid w-full grid-cols-2">
      <TabsTrigger value="monthly">Ежемесячно</TabsTrigger>
      <TabsTrigger value="annual">Ежегодно</TabsTrigger>
    </TabsList>
    <TabsContent value="monthly">
      <Card>
        <CardHeader>
          <CardTitle>Ежемесячная подписка</CardTitle>
          <CardDescription>Оплата каждый месяц, отмена в любое время.</CardDescription>
        </CardHeader>
        <CardContent>
          {/* Контент тарифов */}
        </CardContent>
      </Card>
    </TabsContent>
    <TabsContent value="annual">
      <Card>
        <CardHeader>
          <CardTitle>Годовая подписка</CardTitle>
          <CardDescription>Экономия 20% по сравнению с месячным тарифом.</CardDescription>
        </CardHeader>
        <CardContent>
          {/* Контент тарифов */}
        </CardContent>
      </Card>
    </TabsContent>
  </Tabs>
);

Кастомизация компонентов

Поскольку код компонента в проекте, его можно модифицировать напрямую:

// src/components/ui/button.tsx — добавить вариант
const buttonVariants = cva(
  'inline-flex items-center justify-center ...',
  {
    variants: {
      variant: {
        default: '...',
        // Добавить новый вариант
        gradient: 'bg-gradient-to-r from-brand-500 to-violet-600 text-white hover:opacity-90',
      },
    },
  }
);

Обновление компонентов

# Проверить обновления
npx shadcn@latest diff

# Обновить конкретный компонент
npx shadcn@latest add button --overwrite

Сроки

Инициализация Shadcn/UI и базовая настройка темы: 1–2 часа. Добавление и кастомизация нужных компонентов: 2–4 часа. Посадочная страница на Shadcn/UI + Tailwind + React: 1–2 дня. Shadcn/UI хорошо подходит для SaaS-продуктов, admin-панелей и любых проектов, где нужен профессиональный UI с полным контролем над кодом компонентов.