small-design-system
v1.1.5
Published
Small React design system with TypeScript and Tailwind CSS
Maintainers
Readme
Краткое описание проекта
Small Design System — это современная React библиотека компонентов, созданная для обеспечения консистентного пользовательского опыта во всех продуктах компании.
Основная цель
Создание единой экосистемы UI компонентов, которая ускоряет разработку и обеспечивает высокие стандарты доступности и качества.
Назначение дизайн-системы
Основные задачи
| Задача | Решение | Результат | | ------------------------ | ---------------------------------- | -------------------------------- | | Единообразие UI | Стандартизированные компоненты | Консистентный опыт пользователей | | Ускорение разработки | Готовые к использованию компоненты | Сокращение времени на 60% | | Масштабируемость | Модульная архитектура | Легкое расширение системы | | Типобезопасность | TypeScript first подход | Меньше багов в продакшене |
Ключевые преимущества
- 🎨 Современный дизайн - Минималистичные, чистые компоненты
- 🔧 TypeScript First - Полная типизация всех компонентов
- 🚀 Performance - Оптимизированные компоненты
- 📱 Responsive - Адаптивность на всех устройствах
- 🌙 Dark Mode - Встроенная поддержка тем
Локальное развертывание проекта
Системные требования
Минимальные требования:Минимальные требования:
- Node.js 18.0.0+Node.js 18.0.0+
- npm 8.0.0+npm 8.0.0+
- Git 2.20.0+Git 2.20.0+
Быстрый старт
# 1. Клонирование
git clone https://gitlab16.skiftrade.kz/platform/small-design-system.git
cd small-design-system
# 2. Установка зависимостей
npm i
# 3. Запуск development сервера
npm run dev
Основные команды
Разработка
npm run dev- Development сервер (порт 5173)npm run start- Документация компонентов (порт 6006)
Тестирование
npm run test- Запуск всех тестовnpm run test --watch- Watch режимnpm run test --coverage- Покрытие кода
Качество кода
npm run lint- ESLint проверкаnpm run lint:fix- Автоисправлениеnpm run format- Prettier форматирование
Сборка
npm run build:lib- Сборка библиотекиnpm run build:types- Генерация типов
Архитектура проекта
src/
├── components/ # UI компоненты
│ ├── button/
│ │ ├── button.tsx # Основной компонент
│ │ ├── button.variants.ts # Стили и варианты
│ │ ├── button.stories.tsx # Storybook
│ │ ├── button.test.tsx # Тесты
│ │ └── index.ts # Экспорты
├── core/ # Ядро системы
├── hooks/ # React хуки
├── styles/ # Глобальные стили
├── types/ # TypeScript типы
└── utils/ # Утилиты
Правила разработки компонентов
Структура нового компонента
src/components/my-component/
├── index.ts # Экспорты
├── my-component.tsx # Основной компонент
├── my-component.variants.ts # Стили
├── my-component.stories.tsx # Storybook
├── my-component.test.tsx # Тесты
├── types.ts # TypeScript типы
└── sub-component/ # Подкомпонент
Соглашения по именованию
Файлы и папки
- Папки:
kebab-case(dropdown-menu, icon-button) - Компоненты:
PascalCaseв коде,kebab-caseв файлах - Типы:
PascalCase+ суффикс (ButtonProps, SelectVariants)
Props и переменные
- Props:
camelCase(isDisabled, showIcon, onValueChange) - Variants:
kebab-caseстроки ('primary', 'ghost', 'destructive') - Boolean props:
is*,has*,should*(isLoading, hasError) - Callbacks:
on*(onClick, onSubmit, onValueChange)
Пример создания компонента
// my-component.tsx
import React from "react";
import { createPolymorphicComponent } from "@/core/factory";
import { myComponentVariants } from "./my-component.variants";
const _MyComponent = React.forwardRef<HTMLElement, MyComponentProps>(
({ className, variant = "default", size = "md", ...props }, ref) => {
return (
<div
ref={ref}
className={cn(myComponentVariants({ variant, size }), className)}
{...props}
/>
);
}
);
export const MyComponent = createPolymorphicComponent<"div", MyComponentProps>(
_MyComponent
);Рекомендации по стилям
Технологический стек
- Tailwind CSS v4 - Основной CSS фреймворк
- Tailwind Variants - Создание вариантов компонентов
- CSS Custom Properties - Токены дизайна
- Inter Font - Variable font для типографики
Принципы стилизации
✅ Правильно
- Использовать Tailwind утилиты для 95% стилизации
- Создавать варианты через
tailwind-variants - Группировать классы логически
- Использовать семантические токены
❌ Избегать
- Inline стили (
styleатрибут) - Кастомный CSS вместо Tailwind
- Магические числа
- Дублирование стилей
Пример вариантов
export const buttonVariants = tv({
base: [
"inline-flex items-center justify-center",
"rounded-md font-medium transition-colors",
"focus-visible:outline-none focus-visible:ring-2",
"disabled:pointer-events-none disabled:opacity-50",
],
variants: {
variant: {
primary: "bg-blue-600 text-white hover:bg-blue-700",
secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200",
ghost: "text-gray-600 hover:bg-gray-100",
},
size: {
sm: "h-8 px-3 text-sm",
md: "h-10 px-4",
lg: "h-12 px-6 text-lg",
},
},
defaultVariants: {
variant: "primary",
size: "md",
},
});Тестирование компонентов
Стек технологий
- Vitest - Test runner
- React Testing Library - Тестирование компонентов
- @testing-library/jest-dom - Дополнительные матчеры
- @testing-library/user-event - Симуляция пользователя
- jsdom - Browser-like окружение
Что тестировать
| Категория | Примеры | Приоритет | | ------------------ | ---------------------- | ------------- | | Рендеринг | Компонент отображается | 🔴 Критично | | Props | Все props работают | 🔴 Критично | | Взаимодействия | Клики, фокус, ввод | 🟡 Важно | | Accessibility | ARIA, навигация | 🟡 Важно | | Варианты | Стилевые варианты | 🟢 Желательно |
Принципы тестирования
- Описательные имена тестов
- Тестировать поведение, не implementation details
- Accessibility first - всегда проверять ARIA
- Один тест = один сценарий
- AAA pattern: Arrange, Act, Assert
Пример теста
describe("Button Component", () => {
it("should render with correct text and role", () => {
render(<Button>Click me</Button>);
const button = screen.getByRole("button", { name: "Click me" });
expect(button).toBeInTheDocument();
});
it("should call onClick when clicked", async () => {
const user = userEvent.setup();
const handleClick = vi.fn();
render(<Button onClick={handleClick}>Click me</Button>);
await user.click(screen.getByRole("button"));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});Процесс Pull Requests
Pre-commit чеклист
Перед созданием PR проверьте:
- [ ]
npm run lint- проходит без ошибок - [ ]
npm run test- все тесты зеленые - [ ]
npm run build:lib- сборка успешная - [ ] Storybook stories обновлены (для новых компонентов)
- [ ] Документация обновлена (при необходимости)
Конвенции именования PR
Формат: [type]: краткое описание
| Тип | Пример |
| ---------- | -------------------------------------- |
| feat | feat: add Alert component |
| fix | fix: resolve focus issue in Modal |
| refactor | refactor: optimize Input performance |
Шаблон описания PR
## 🎯 Что изменено
- Краткое описание изменений
## 🤔 Зачем
- Причина изменений
- Ссылка на issue: Closes #123
## 🧪 Как тестировать
1. Клонируйте ветку
2. Запустите `npm run storybook`
3. Проверьте компонент
4. Запустите тесты
## ✅ Checklist
- [ ] Линтинг проходит
- [ ] Тесты проходят
- [ ] Сборка работает
- [ ] Тесты добавлены/обновлены
- [ ] Storybook обновлен
- [ ] Accessibility проверенаCode Review Guidelines
Для автора
- ✅ Self-review перед созданием PR
- 💬 Быстро отвечать на комментарии
- 🔄 Вносить изменения согласно фидбеку
Для reviewer
- 🎯 Проверить функциональность
- 🎨 Соответствие дизайн-системе
- ♿ Accessibility compliance
- 📚 Качество документации
- 🧪 Покрытие тестами
- 📱 Responsive поведение
Быстрые ссылки
- 📚 Storybook: https://storybook.small.kz/
- 📚 Storybook(Stage): https://storybook-test.small.kz/
- 🎨 Дизайн Figma: https://www.figma.com/
- 📦 NPM: small-design-system
