Один hero-блок, три файла: проверяю установку UI через shadcn в отдельный проект

в 7:23, , рубрики: next.js, React, Registry, shadcn, Tailwind CSS, ui-компоненты

Красивое превью компонента ещё не доказывает, что он заработает за пределами каталога. Меня интересовала конкретная цепочка: получить инструкцию для ИИ, установить исходники в отдельный Next.js-проект и изменить содержание, сохранив устройство блока.

Я разрабатываю VibeUI, поэтому сразу обозначу заинтересованность. Это разбор одного собственного компонента, а не независимый рейтинг библиотек. Практическую установку, проверки и подготовку материалов 2 ноября 2026 года выполнял coding-агент. Ниже — фактический результат и границы проверки.

Что проверяем

Взяли hero-001: первый экран с заголовком, описанием, двумя ссылками и коротким списком преимуществ. Он состоит из трёх компонентов: самого hero, заголовка heading-001 и ссылки button-016.

У эксперимента четыре условия:

  • устанавливаем через работающий production-registry, без копирования файлов из репозитория;

  • проверяем результат в отдельном приложении со своими зависимостями;

  • содержание меняем через пропсы, установленные компоненты не редактируем;

  • проверяем узкие экраны, ссылки и отключение анимаций.

Сравнения с генерацией «по картинке» здесь нет: контрольный эксперимент с одинаковыми промптами не проводился.

Окружение и установка

Тестовое приложение: Next.js 16.4.2, React 19.2.8, TypeScript 5.9.3, Tailwind CSS 4.3.3. Среда — Windows и Chrome. Настроены App Router, alias @/* и components.json для shadcn.

Зависимости приложения установили отдельно. Это важно: время подготовки окружения нельзя выдавать за время установки блока или разработки сайта.

Из Copy for AI получили временную подписанную ссылку на registry JSON. В публичный текст её не переношу: срок действия ограничен, а сама ссылка предоставляет доступ к загрузке. Команда для воспроизведения выглядит так:

npx shadcn@4.22.1 add "<актуальная ссылка из Copy for AI>" --yes

В опыте запускался установленный CLI shadcn той же версии 4.22.1. Он завершился с кодом 0 за 5,11 секунды и создал:

components/vibeui/button-016.tsx
components/vibeui/heading-001.tsx
components/vibeui/hero-001.tsx

Это один замер, а не бенчмарк. Новых npm-пакетов при установке блока не потребовалось. При этом два внутренних registry-компонента всё равно являются зависимостями: «без дополнительных npm-зависимостей» не означает «один файл».

Содержимое полученных файлов сравнили с исходниками registry. После нормализации путей импортов все три совпали. Таким образом, в приложении оказалась именно распространяемая реализация.

Что пришлось поправить в тестовом окружении

Приложение лежало во вложенной папке основного репозитория. Turbopack первоначально определил корень родительского workspace и захватил настройки основного проекта. Для изоляции понадобилась настройка самого тестового приложения:

const nextConfig = {
  turbopack: { root: process.cwd() },
}
export default nextConfig

После этого dev-сервер запускался в нужном контексте. Это особенность размещения стенда, а не ошибка исходника hero. В отдельном репозитории такой же проблемы может не быть.

Сначала — исходный вид

До адаптации сравнили дефолтный блок в каталоге и в приложении при одинаковом CSS viewport 1280 × 720. У заголовка совпали семейство шрифта и ширина: примерно 768 CSS px. Разница координат и высоты была меньше 0,3 CSS px.

Это узкая проверка геометрии одного элемента. Она не доказывает попиксельное совпадение всего экрана: масштаб браузера, сглаживание и кадр анимации влияют на скриншоты.

Затем — вымышленная кофейня

Для адаптации использовали «Тихий двор». Это демонстрационный бизнес: настоящий адрес, график работы и цены не придумывали. Поменяли текст, подписи и назначения ссылок, список преимуществ и акцентный цвет.

Сокращённый пример вызова:

import { Hero001 } from "@/components/vibeui/hero-001"

export default function Page() {
  return (
    <main className="min-h-screen bg-[#111111] text-white">
      <Hero001
        badge="Кофейня · пример адаптации"
        title="Хорошее утро"
        titleAccent="начинается рядом"
        description="Кофе, свежая выпечка и столик у окна. Вымышленная кофейня «Тихий двор» — демонстрация замены контента готового блока."
        primaryAction={{ label: "Посмотреть меню", href: "#menu" }}
        secondaryAction={{ label: "Как нас найти", href: "#contacts" }}
        highlights={["Кофе с собой", "Выпечка каждый день", "Демо, не реальный бизнес"]}
        accent="#FF5900"
        tone="dark"
      />
      <section id="menu"><h2>Меню для примера</h2></section>
      <section id="contacts"><h2>Контакты для примера</h2></section>
    </main>
  )
}

В стенде секциям также задали отступы и добавили поясняющий текст. Три установленных файла остались без изменений. Поэтому проверка показывает границу между заменой данных страницы и изменением реализации компонента.

Первый экран вымышленной кофейни после замены пропсов

Первый экран вымышленной кофейни после замены пропсов

Первый экран тестового приложения. Три установленных компонента не редактировались.

Проверки после установки

CSS viewport

Горизонтальное переполнение

Контент за правой границей

1280 × 720

нет

нет

768 × 1024

нет

нет

400 × 860

нет

нет

320 × 760

нет

нет

Проверяли scrollWidth относительно clientWidth и границы видимых заголовков, абзацев и ссылок. В документе один h1 и два h2. Обе ссылки указывают на существующие секции. Реальный клик по первой изменил hash на #menu.

При эмуляции prefers-reduced-motion: reduce активных анимаций у потомков блока не обнаружено. Светлую тему отдельно проверили по вычисленному цвету заголовка и отсутствию горизонтального переполнения. TypeScript-проверка tsc --noEmit завершилась успешно.

Полную production-сборку в этом опыте не запускали. Также не проводили полноценный аудит доступности, тесты Safari и Firefox или измерения Core Web Vitals.

Что следует из этого опыта

Для одного проверенного блока цепочка сработала: production-registry отдал три связанных файла, CLI установил их в отдельное приложение, а предметную область удалось заменить через API компонента.

Но инструкция для ИИ сама по себе не является доказательством переносимости. Полезно отдельно проверять состав файлов, внутренние импорты и отсутствие обращений к инфраструктуре каталога. После установки нужны проверки уже в целевом окружении — прежде всего с настоящими текстами и на узких экранах.

Следующий полезный эксперимент — взять несколько блоков с разными зависимостями и повторить проверку в других приложениях. По одному hero нельзя сделать вывод о качестве всего registry или о превосходстве подхода над генерацией.

Описание формата registry и механизма установки: документация shadcn. Исходный блок для этого опыта — hero-001 из VibeUI.

Автор: Escape2002

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js