Верстка сайту з використанням 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), базовий колір та алías для утиліт. Конфігурація зберігається в 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 з повним контролем над кодом компонентів.