TGViewer
alexgriss.tech alexgriss.tech @alexgriss · 1.14K subscribers
Post #122 810
Как построить свою UI-библиотеку на базе Vanilla Extract

В прошлом посте я рассказывал про Vanilla Extract (VE) и его возможности. В частности, упоминал такие инструменты для построения дизайн-систем, как sprinkles и recipes.

Сегодня расскажу о том, как построить на основе Vanilla Extract свою дизайн-систему на примере моей библиотеки компонентов Vanilla Sugar для React.

Дисклеймер: этот пост скорее демонстрация возможностей Vanilla Extract и описание основных концепций, которые лежат в основе библиотеки компонентов, чем описание готового продукта. Пост будет интересен тем, кто ищет новые подходы в разработке UI.

Ссылка на библиотеку: https://github.com/alexgriss/vanilla-sugar.

➖➖➖

Основные концепции библиотеки

• Дизайн-токены как основа •

Библиотека построена на основе централизованной системы токенов. В src/tokens.ts определены все дизайн-константы: цвета, брейкпоинты, отступы, размеры и т.д. Дизайн-токены — это фундамент типобезопасности всей дизайн-системы.

const colors = {
primary: "#78B64C",
secondary: "#3C3C3C",
tertiary: "#EDEDED",
// ...
} as const;

const fontWeights = {
normal: "400",
medium: "500",
bold: "700",
} as const;

// ...


• Темы •

Чтобы дизайн-токены начали работать с VE, нужно создать тему. Это позволит автоматически сгенерировать глобальные CSS-переменные для всех токенов. Тем может быть сколько угодно, у меня пока одна:

import { createGlobalTheme } from "@vanilla-extract/css";

import { tokens } from "./tokens";

export const vars = createGlobalTheme(":root", tokens);


В результате VE создаст CSS-переменные вроде --colors-primary__1q5vhka6: #78B64C;, которые можно будет использовать в любом месте.

• Атомы •

Для создания атомарных стилей используется пакет @vanilla-extract/sprinkles. С его помощью можно сгенерировать собственную систему утилитарных классов (как в Tailwind), но сразу с привязкой к токенам темы.

В src/props.ts я описываю конфиги для генерации наборов классов: для цветов, типографики, размеров и отступов, а также для часто используемых свойств разметки блоков. Дополнительно можно генерировать классы для media/feature/container‑запросов или для разных селекторов состояний.

Самое приятное — это возможность задать короткие алиасы для свойств, которые потом можно передавать прямо в пропсы компонентов, как в Chakra UI. Настройку sprinkles можно посмотреть в файле src/sprinkles.css.ts.

• Полиморфный компонент Box •

Все React-компоненты библиотеки строятся на базе полиморфного компонента Box (аналогичный компонент есть, например, в Chakra UI). Это фундамент дизайн-системы: по умолчанию он рендерит <div />, но поддерживает свойство as для изменения тега в конечном элементе. Разбор реализации такого компонента можно найти в этом исчерпывающем гайде.

Примеры использования Box:

<Box as="button" type="submit">Кнопка</Box>

<Box as="ul">
<Box as="li">Item</Box>
<Box as="li">Item</Box>
</Box>


А благодаря sprinkles стили можно задавать пропсами (с поддержкой адаптивности):

<Box
as="button"
type="submit"
bg="primary"
color="secondary"
py={16}
px={[8, 16, 32]}
w={{ mobile: 96, tablet: 192, desktop: 256 }}
>
Кнопка
</Box>


• Рецепты •

Ещё одна киллер-фича VE — это @vanilla-extract/recipes. Рецепты позволяют описывать предустановленные варианты стилей для одного компонента и переключать их простыми пропсами.

В моей UI-библиотеке с помощью рецептов полностью реализован компонент Button:

<Button variant="primary" size="small">
Кнопка
</Button>

<Button variant="outline" size="large">
Кнопка
</Button>


Все эти концепции вместе позволяют построить type-safe UI-библиотеку любой сложности. Самое трудное — реализовать базовые блоки, а дальше любые компоненты будут строиться как конструктор из настроек дизайн-системы.

В библиотеке уже есть базовый набор «кристаллов» (я назвал так UI-блоки, продолжая кондитерскую тему VE ♥️) с демкой в Storybook. Потестировать библиотеку можно, просто склонировав её к себе в проект.

➖➖➖

Напишите в комментах, стали бы использовать подобную библиотеку в своём проекте?
  • 🔥 12
  • 👍 5
  • 🤔 4
  • ❤ 2
  • 🤪 1
More from @alexgriss
  1. Sep 29, 2026У нас есть свой Web Audio API дома. Купил себе Behringer Proton — полумодульный аналоговый…
  2. Sep 7, 2026video post
  3. Sep 2, 2026Мне потребовалось два месяца, чтобы сменить привязанный к Telegram российский номер на кип…
  4. Jul 6, 2026Короче, похоже не зря запрещали Claude Fable, мир больше не будет прежним, предел AGI прой…
  5. Jul 5, 2026За последние две недели в моей жизни поменялось очень многое, и пока до спокойной размерен…
  6. Jul 4, 2026После переезда на Кипр и решения основных бытовых задач появилось немного творческой энерг…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →