@donkit-ai/design-system 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +795 -0
- package/package.json +40 -0
- package/src/components/Accordion.css +43 -0
- package/src/components/Accordion.jsx +35 -0
- package/src/components/Alert.css +98 -0
- package/src/components/Alert.jsx +46 -0
- package/src/components/Badge.css +57 -0
- package/src/components/Badge.jsx +25 -0
- package/src/components/Button.css +94 -0
- package/src/components/Button.jsx +40 -0
- package/src/components/Card.css +32 -0
- package/src/components/Card.jsx +37 -0
- package/src/components/Code.css +30 -0
- package/src/components/Code.jsx +27 -0
- package/src/components/CodeAccordion.css +59 -0
- package/src/components/CodeAccordion.jsx +35 -0
- package/src/components/Input.css +140 -0
- package/src/components/Input.jsx +55 -0
- package/src/components/Link.css +18 -0
- package/src/components/Link.jsx +21 -0
- package/src/components/Modal.css +66 -0
- package/src/components/Modal.jsx +71 -0
- package/src/components/Select.css +150 -0
- package/src/components/Select.jsx +117 -0
- package/src/components/Stepper.css +163 -0
- package/src/components/Stepper.jsx +103 -0
- package/src/components/Tabs.css +92 -0
- package/src/components/Tabs.jsx +41 -0
- package/src/components/Textarea.css +80 -0
- package/src/components/Textarea.jsx +41 -0
- package/src/components/Typography.css +74 -0
- package/src/components/Typography.jsx +42 -0
- package/src/index.js +19 -0
- package/src/styles/tokens.css +278 -0
package/README.md
ADDED
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
# Donkit Design System
|
|
2
|
+
|
|
3
|
+
Минимальная дизайн система на основе дизайн токенов с поддержкой светлой и темной темы.
|
|
4
|
+
|
|
5
|
+
## 🚀 Быстрый старт для команды
|
|
6
|
+
|
|
7
|
+
### Вариант 1: Через GitLab Package Registry (БЫСТРО ⚡)
|
|
8
|
+
|
|
9
|
+
**Рекомендуется** - в 10 раз быстрее чем через Git!
|
|
10
|
+
|
|
11
|
+
1. **Настройте доступ к GitLab Package Registry (один раз):**
|
|
12
|
+
|
|
13
|
+
Создайте файл `.npmrc` в корне вашего проекта:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
@donkit-ai:registry=https://gitlab.com/api/v4/packages/npm/
|
|
17
|
+
//gitlab.com/api/v4/packages/npm/:_authToken=${CI_JOB_TOKEN}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Или используйте свой Personal Access Token вместо `${CI_JOB_TOKEN}`:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
@donkit-ai:registry=https://gitlab.com/api/v4/packages/npm/
|
|
24
|
+
//gitlab.com/api/v4/packages/npm/:_authToken=YOUR_GITLAB_TOKEN
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> **Создать токен:**
|
|
28
|
+
> 1. GitLab → Settings → Access Tokens
|
|
29
|
+
> 2. Name: `npm-packages` (любое имя)
|
|
30
|
+
> 3. **Scope:** `api` или `read_api` (для чтения пакетов)
|
|
31
|
+
> 4. **Role:** `Developer` (минимум для доступа к Package Registry)
|
|
32
|
+
> 5. Create token → скопируйте токен в `.npmrc`
|
|
33
|
+
|
|
34
|
+
2. **Добавьте пакет в `package.json`:**
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@donkit-ai/design-system": "^0.1.2"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
3. **Установите:**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Установка займет **5-10 секунд** вместо 1-2 минут! 🚀
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### Вариант 2: Через Git (МЕДЛЕННО 🐢)
|
|
55
|
+
|
|
56
|
+
1. **Добавьте пакет через Git в `package.json`:**
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@donkit-ai/design-system": "git+https://gitlab.com/donkit-ai/platform/design/design-system.git#main"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Для приватных репозиториев используйте SSH:
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@donkit-ai/design-system": "git+ssh://[email protected]:donkit-ai/platform/design/design-system.git#main"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. **Установите зависимости:**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm install
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Готово!** Дизайн-система установлена и готова к использованию.
|
|
82
|
+
|
|
83
|
+
> 💡 **Совет:** Для ускорения установки используйте флаг `--prefer-offline`:
|
|
84
|
+
> ```bash
|
|
85
|
+
> npm install --prefer-offline
|
|
86
|
+
> ```
|
|
87
|
+
> Это использует локальный кэш npm и ускоряет повторные установки.
|
|
88
|
+
|
|
89
|
+
### Обновление до последней версии
|
|
90
|
+
|
|
91
|
+
Когда дизайн-система обновляется, выполните:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npm update @donkit-ai/design-system
|
|
95
|
+
# или
|
|
96
|
+
npm install @donkit-ai/design-system@latest
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Использование конкретной версии
|
|
100
|
+
|
|
101
|
+
Можно зафиксировать конкретную версию через Git теги:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"dependencies": {
|
|
106
|
+
"@donkit-ai/design-system": "git+...#v0.1.2"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Особенности
|
|
112
|
+
|
|
113
|
+
- 🎨 **Дизайн токены** - семантические CSS переменные для цветов, отступов, типографики
|
|
114
|
+
- 🌓 **Две темы** - автоматическое переключение между светлой и темной темой
|
|
115
|
+
- 📱 **Адаптивность** - responsive spacing и typography для mobile/tablet/desktop
|
|
116
|
+
- ⚛️ **React компоненты** - готовые к использованию компоненты
|
|
117
|
+
- 🎯 **Lucide Icons** - фиксированные размеры иконок (20/24/28px, stroke 1.5)
|
|
118
|
+
- 📖 **Интерактивная документация** - страница с примерами всех компонентов
|
|
119
|
+
|
|
120
|
+
## Компоненты
|
|
121
|
+
|
|
122
|
+
- **Button** - кнопки с вариантами (primary, secondary, ghost) и размерами (small, medium, large)
|
|
123
|
+
- **Tabs** - вкладки с вариантами secondary (с border) и ghost (без border), состоянием selected (small, medium, large)
|
|
124
|
+
- **Input** - текстовые поля с поддержкой иконок, ошибок и подсказок (small, medium)
|
|
125
|
+
- **Stepper** - числовое поле с кнопками +/- для изменения значения (small, medium)
|
|
126
|
+
- **Card** - карточки двух типов: info (информационная, прозрачный фон) и interactive (интерактивная с hover эффектом)
|
|
127
|
+
- **Typography** - H1-H4, P1-P3 компоненты
|
|
128
|
+
- **Code** - inline и block код с monospace шрифтом
|
|
129
|
+
- **Link** - ссылки акцентным цветом, при hover цвет меняется и появляется подчеркивание
|
|
130
|
+
- **Badge** - бейджи для статусов (success, error, warning, accent) в двух размерах (small, medium)
|
|
131
|
+
- **Modal** - модальные окна с header и footer
|
|
132
|
+
- **Select** - выпадающий список с кастомным дизайном (small, medium)
|
|
133
|
+
|
|
134
|
+
## Использование в проекте
|
|
135
|
+
|
|
136
|
+
### 1. Импорт токенов (обязательно в корне приложения)
|
|
137
|
+
|
|
138
|
+
В главном файле вашего приложения (например, `main.tsx` или `App.tsx`):
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
// Подключите CSS токены ОДИН РАЗ в корне приложения
|
|
142
|
+
import '@donkit-ai/design-system/tokens.css';
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 2. Использование компонентов
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
import { Button, Tabs, Tab, Input, Card, H1, P1, P3, Badge, Code, Link } from '@donkit-ai/design-system';
|
|
149
|
+
import { Mail } from 'lucide-react';
|
|
150
|
+
|
|
151
|
+
function MyComponent() {
|
|
152
|
+
return (
|
|
153
|
+
<Card padding="medium">
|
|
154
|
+
<H1>Welcome</H1>
|
|
155
|
+
<P1 secondary>This is a demo</P1>
|
|
156
|
+
<Button
|
|
157
|
+
variant="primary"
|
|
158
|
+
size="medium"
|
|
159
|
+
icon={<Mail size={24} strokeWidth={1.5} />}
|
|
160
|
+
>
|
|
161
|
+
Send Email
|
|
162
|
+
</Button>
|
|
163
|
+
</Card>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 3. Иконки
|
|
169
|
+
|
|
170
|
+
Все иконки используются из библиотеки `lucide-react` (уже включена в зависимости).
|
|
171
|
+
|
|
172
|
+
#### Размеры иконок
|
|
173
|
+
|
|
174
|
+
**Важно:** Размеры иконок фиксированные (не адаптивные) и зависят от контекста использования:
|
|
175
|
+
|
|
176
|
+
- **20px** - компактные элементы
|
|
177
|
+
- Small кнопки (`size="small"`)
|
|
178
|
+
- Tabs (вкладки)
|
|
179
|
+
- Modal (иконка закрытия)
|
|
180
|
+
|
|
181
|
+
- **24px** - стандартные элементы
|
|
182
|
+
- Medium кнопки (`size="medium"`, по умолчанию)
|
|
183
|
+
- Input (иконки в полях ввода)
|
|
184
|
+
- Alert (иконки статусов)
|
|
185
|
+
|
|
186
|
+
- **28px** - крупные элементы
|
|
187
|
+
- Large кнопки (`size="large"`)
|
|
188
|
+
|
|
189
|
+
**Всегда используется `strokeWidth={1.5}`** для единообразия дизайна.
|
|
190
|
+
|
|
191
|
+
#### Примеры использования
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
import { Mail, Search, Eye, EyeOff, AlertCircle, Check, X } from 'lucide-react';
|
|
195
|
+
|
|
196
|
+
// Small button / Tabs / Modal
|
|
197
|
+
<Button size="small" icon={<Mail size={20} strokeWidth={1.5} />}>
|
|
198
|
+
Send
|
|
199
|
+
</Button>
|
|
200
|
+
<Tab icon={<AlertCircle size={20} strokeWidth={1.5} />}>
|
|
201
|
+
Alerts
|
|
202
|
+
</Tab>
|
|
203
|
+
|
|
204
|
+
// Medium button / Input / Alert
|
|
205
|
+
<Button size="medium" icon={<Search size={24} strokeWidth={1.5} />}>
|
|
206
|
+
Search
|
|
207
|
+
</Button>
|
|
208
|
+
<Input
|
|
209
|
+
icon={<Search size={24} strokeWidth={1.5} />}
|
|
210
|
+
placeholder="Search..."
|
|
211
|
+
/>
|
|
212
|
+
<Alert
|
|
213
|
+
type="success"
|
|
214
|
+
icon={<Check size={24} strokeWidth={1.5} />}
|
|
215
|
+
/>
|
|
216
|
+
|
|
217
|
+
// Large button
|
|
218
|
+
<Button size="large" icon={<Mail size={28} strokeWidth={1.5} />}>
|
|
219
|
+
Send Email
|
|
220
|
+
</Button>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### 3. Переключение темы
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
// Темная тема (по умолчанию)
|
|
227
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
228
|
+
|
|
229
|
+
// Светлая тема
|
|
230
|
+
document.documentElement.setAttribute('data-theme', 'light');
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Дизайн токены
|
|
234
|
+
|
|
235
|
+
### Цвета
|
|
236
|
+
|
|
237
|
+
#### Базовые примитивы
|
|
238
|
+
- `--color-white`: #FFFAFA
|
|
239
|
+
- `--color-white-65/50/40/20/15/13/06`: rgba с прозрачностью 65%, 50%, 40%, 20%, 15%, 13%, 6%
|
|
240
|
+
- `--color-black`: #0E0F11
|
|
241
|
+
- `--color-black-65/60/50/40/20/10/08/04`: rgba с прозрачностью 65%, 60%, 50%, 40%, 20%, 10%, 8%, 4%
|
|
242
|
+
- `--color-red`: #EA6464
|
|
243
|
+
- `--color-red-90`: rgba с прозрачностью 90%
|
|
244
|
+
|
|
245
|
+
#### Status/Alert Colors
|
|
246
|
+
- `--color-error`: #FF1200 - Error/destructive actions
|
|
247
|
+
- `--color-neutral`: #FFBB00 - Warning/neutral states
|
|
248
|
+
- `--color-success`: #00C86E - Success/positive states
|
|
249
|
+
|
|
250
|
+
#### Семантические (меняются в зависимости от темы)
|
|
251
|
+
- `--color-bg` - фон
|
|
252
|
+
- `--color-border` - границы
|
|
253
|
+
- `--color-border-hover` - границы при hover (Dark: white-40, Light: black-40)
|
|
254
|
+
- `--color-border-selected` - границы выбранного элемента (Dark: white-50, Light: black-50)
|
|
255
|
+
- `--color-txt-icon-1` - основной текст/иконки (100%)
|
|
256
|
+
- `--color-txt-icon-2` - вторичный текст/иконки (65%)
|
|
257
|
+
- `--color-accent` - акцентный цвет
|
|
258
|
+
- `--color-accent-hover` - акцент при hover
|
|
259
|
+
- `--color-item-bg` - фон элементов (subtle) (Dark: white-06, Light: black-04)
|
|
260
|
+
- `--color-item-bg-selected` - выделенный элемент (Dark: white-06, Light: black-04)
|
|
261
|
+
- `--color-item-bg-hover` - hover состояние (Dark: white-13, Light: black-08)
|
|
262
|
+
- `--color-code-bg` - фон элементов кода (Dark: white-15, Light: black-10)
|
|
263
|
+
|
|
264
|
+
### Отступы (adaptive)
|
|
265
|
+
|
|
266
|
+
Используются для padding, margin, gap, а также для border-radius скругления углов.
|
|
267
|
+
|
|
268
|
+
- `--space-xs`: 8px
|
|
269
|
+
- `--space-s`: 12px → 16px → 16px (mobile → tablet → desktop)
|
|
270
|
+
- `--space-m`: 16px → 20px → 24px
|
|
271
|
+
- `--space-l`: 24px → 28px → 32px
|
|
272
|
+
- `--space-xl`: 32px → 40px → 48px
|
|
273
|
+
|
|
274
|
+
### Типографика (adaptive)
|
|
275
|
+
|
|
276
|
+
**Основной шрифт:**
|
|
277
|
+
- Font Family: **Inter** (fallback: system-ui, Avenir, Helvetica, Arial, sans-serif)
|
|
278
|
+
- Font Weight: **300** (Light) - для всех заголовков и текста
|
|
279
|
+
- Line Height: 1.2-1.3 (заголовки), 1.5 (текст)
|
|
280
|
+
|
|
281
|
+
**Monospace шрифт (для Code):**
|
|
282
|
+
- Font Family: **Fira Mono** (fallback: SF Mono, Monaco, Cascadia Code, Roboto Mono, monospace)
|
|
283
|
+
|
|
284
|
+
**Размеры шрифтов (mobile → tablet → desktop):**
|
|
285
|
+
- `--font-size-h1`: 36px → 40px → 48px
|
|
286
|
+
- `--font-size-h2`: 28px → 32px → 36px
|
|
287
|
+
- `--font-size-h3`: 24px → 28px → 32px
|
|
288
|
+
- `--font-size-h4`: 16px → 20px → 24px
|
|
289
|
+
- `--font-size-p1`: 16px → 16px → 20px
|
|
290
|
+
- `--font-size-p2`: 12px → 16px → 16px
|
|
291
|
+
- `--font-size-p3`: 12px → 12px → 14px
|
|
292
|
+
|
|
293
|
+
**Letter Spacing (трекинг для мелких кеглей):**
|
|
294
|
+
- Меньше 20px → +2% (0.02em)
|
|
295
|
+
- Меньше 16px → +4% (0.04em)
|
|
296
|
+
- Меньше 14px → +6% (0.06em)
|
|
297
|
+
|
|
298
|
+
Адаптивные значения трекинга:
|
|
299
|
+
- `--letter-spacing-h4`: 0.02em → 0 → 0 (16px / 20px / 24px)
|
|
300
|
+
- `--letter-spacing-p1`: 0.02em → 0.02em → 0 (16px / 16px / 20px)
|
|
301
|
+
- `--letter-spacing-p2`: 0.06em → 0.02em → 0.02em (12px / 16px / 16px)
|
|
302
|
+
- `--letter-spacing-p3`: 0.06em → 0.06em → 0.04em (12px / 12px / 14px)
|
|
303
|
+
|
|
304
|
+
### Переходы
|
|
305
|
+
|
|
306
|
+
- `--transition-fast`: 0.15s ease
|
|
307
|
+
- `--transition-normal`: 0.2s ease
|
|
308
|
+
- `--transition-slow`: 0.3s ease
|
|
309
|
+
|
|
310
|
+
## Disabled States (состояния недоступности)
|
|
311
|
+
|
|
312
|
+
Базовые правила для disabled состояний интерактивных компонентов:
|
|
313
|
+
|
|
314
|
+
### Стили
|
|
315
|
+
|
|
316
|
+
```css
|
|
317
|
+
/* Для кнопок */
|
|
318
|
+
.button:disabled {
|
|
319
|
+
opacity: 0.5;
|
|
320
|
+
cursor: not-allowed;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* Для полей ввода - применяется ко всему wrapper */
|
|
324
|
+
.input-wrapper--disabled,
|
|
325
|
+
.select-wrapper--disabled {
|
|
326
|
+
opacity: 0.5;
|
|
327
|
+
cursor: not-allowed;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* Отключение hover эффектов */
|
|
331
|
+
.component:hover:not(:disabled) {
|
|
332
|
+
/* hover стили */
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Правила
|
|
337
|
+
|
|
338
|
+
- **Прозрачность**: `opacity: 0.5` (50%) - единственный визуальный эффект для всех disabled элементов
|
|
339
|
+
- **Курсор**: `cursor: not-allowed` - указывает на недоступность
|
|
340
|
+
- **Область применения**:
|
|
341
|
+
- Для **Button** - применяется к самой кнопке
|
|
342
|
+
- Для **Input/Select** - применяется ко всему полю целиком (wrapper), включая label, input/select, hint/error
|
|
343
|
+
- **Hover эффекты**: отключаются через `:hover:not(:disabled)`
|
|
344
|
+
- **Цвет текста**: не меняется (сохраняет семантический цвет в зависимости от состояния поля)
|
|
345
|
+
- **Применимо к**: Button, Input, Select и другие интерактивные компоненты
|
|
346
|
+
|
|
347
|
+
### Примеры
|
|
348
|
+
|
|
349
|
+
```jsx
|
|
350
|
+
<Button variant="primary" disabled>Disabled Button</Button>
|
|
351
|
+
<Input label="Name" value="Cannot edit" disabled />
|
|
352
|
+
<Select label="Choose" options={[...]} disabled />
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## Структура проекта
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
/src
|
|
359
|
+
/styles
|
|
360
|
+
tokens.css # Дизайн токены
|
|
361
|
+
/components
|
|
362
|
+
Button.jsx/.css # Компонент кнопки
|
|
363
|
+
Tabs.jsx/.css # Компонент вкладок
|
|
364
|
+
Input.jsx/.css # Компонент input
|
|
365
|
+
Card.jsx/.css # Компонент карточки
|
|
366
|
+
Typography.jsx/.css # Типографика
|
|
367
|
+
Code.jsx/.css # Inline и block код
|
|
368
|
+
Link.jsx/.css # Ссылки
|
|
369
|
+
Badge.jsx/.css # Бейджи
|
|
370
|
+
Modal.jsx/.css # Модальное окно
|
|
371
|
+
Select.jsx/.css # Выпадающий список
|
|
372
|
+
/docs
|
|
373
|
+
App.jsx # Страница документации
|
|
374
|
+
main.jsx # Точка входа
|
|
375
|
+
docs.css # Стили документации
|
|
376
|
+
index.js # Экспорт всех компонентов
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Примеры использования
|
|
380
|
+
|
|
381
|
+
### Кнопки
|
|
382
|
+
|
|
383
|
+
```jsx
|
|
384
|
+
<Button variant="primary">Primary</Button>
|
|
385
|
+
<Button variant="secondary">Secondary</Button>
|
|
386
|
+
<Button variant="ghost">Ghost</Button>
|
|
387
|
+
|
|
388
|
+
// Размеры с соответствующими иконками
|
|
389
|
+
<Button size="small" icon={<Mail size={20} strokeWidth={1.5} />}>
|
|
390
|
+
Small
|
|
391
|
+
</Button>
|
|
392
|
+
<Button size="medium" icon={<Mail size={24} strokeWidth={1.5} />}>
|
|
393
|
+
Medium
|
|
394
|
+
</Button>
|
|
395
|
+
<Button size="large" icon={<Mail size={28} strokeWidth={1.5} />}>
|
|
396
|
+
Large
|
|
397
|
+
</Button>
|
|
398
|
+
|
|
399
|
+
// С fullWidth
|
|
400
|
+
<Button
|
|
401
|
+
variant="primary"
|
|
402
|
+
size="medium"
|
|
403
|
+
icon={<Mail size={24} strokeWidth={1.5} />}
|
|
404
|
+
fullWidth
|
|
405
|
+
>
|
|
406
|
+
Send Email
|
|
407
|
+
</Button>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Tabs
|
|
411
|
+
|
|
412
|
+
Вкладки с двумя вариантами оформления: secondary (с border) и ghost (без border).
|
|
413
|
+
|
|
414
|
+
```jsx
|
|
415
|
+
import { Tabs, Tab } from '@donkit-ai/design-system';
|
|
416
|
+
import { AlertCircle } from 'lucide-react';
|
|
417
|
+
|
|
418
|
+
// Secondary tabs (default) - с border
|
|
419
|
+
<Tabs size="medium" variant="secondary">
|
|
420
|
+
<Tab selected={selectedTab === 'tab1'} onClick={() => setSelectedTab('tab1')}>
|
|
421
|
+
Overview
|
|
422
|
+
</Tab>
|
|
423
|
+
<Tab selected={selectedTab === 'tab2'} onClick={() => setSelectedTab('tab2')}>
|
|
424
|
+
Details
|
|
425
|
+
</Tab>
|
|
426
|
+
<Tab selected={selectedTab === 'tab3'} onClick={() => setSelectedTab('tab3')}>
|
|
427
|
+
Settings
|
|
428
|
+
</Tab>
|
|
429
|
+
</Tabs>
|
|
430
|
+
|
|
431
|
+
// Ghost tabs - без border, минималистичный стиль
|
|
432
|
+
<Tabs size="medium" variant="ghost">
|
|
433
|
+
<Tab selected={selectedTab === 'tab1'} onClick={() => setSelectedTab('tab1')}>
|
|
434
|
+
Overview
|
|
435
|
+
</Tab>
|
|
436
|
+
<Tab selected={selectedTab === 'tab2'} onClick={() => setSelectedTab('tab2')}>
|
|
437
|
+
Details
|
|
438
|
+
</Tab>
|
|
439
|
+
<Tab selected={selectedTab === 'tab3'} onClick={() => setSelectedTab('tab3')}>
|
|
440
|
+
Settings
|
|
441
|
+
</Tab>
|
|
442
|
+
</Tabs>
|
|
443
|
+
|
|
444
|
+
// With icons (всегда 20px для Tabs)
|
|
445
|
+
<Tabs size="small" variant="secondary">
|
|
446
|
+
<Tab
|
|
447
|
+
selected={selectedTab === 'alerts'}
|
|
448
|
+
onClick={() => setSelectedTab('alerts')}
|
|
449
|
+
icon={<AlertCircle size={20} strokeWidth={1.5} />}
|
|
450
|
+
>
|
|
451
|
+
Alerts
|
|
452
|
+
</Tab>
|
|
453
|
+
<Tab selected={selectedTab === 'other'} onClick={() => setSelectedTab('other')}>
|
|
454
|
+
Other
|
|
455
|
+
</Tab>
|
|
456
|
+
</Tabs>
|
|
457
|
+
|
|
458
|
+
// Disabled tab
|
|
459
|
+
<Tabs size="medium" variant="secondary">
|
|
460
|
+
<Tab selected>Active</Tab>
|
|
461
|
+
<Tab disabled>Disabled</Tab>
|
|
462
|
+
</Tabs>
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Варианты:**
|
|
466
|
+
- **secondary** (default) - с border, как вторичные кнопки
|
|
467
|
+
- Selected: фон `--color-item-bg-selected`, border `--color-border-selected`
|
|
468
|
+
- Hover: фон `--color-item-bg-hover`, border `--color-border-hover`
|
|
469
|
+
- **ghost** - без border, минималистичный
|
|
470
|
+
- Selected: фон `--color-item-bg-selected`
|
|
471
|
+
- Hover: фон `--color-item-bg-hover`
|
|
472
|
+
|
|
473
|
+
**Размеры:** small, medium, large
|
|
474
|
+
|
|
475
|
+
**Дополнительно:** поддержка иконок и disabled состояния
|
|
476
|
+
|
|
477
|
+
### Input
|
|
478
|
+
|
|
479
|
+
```jsx
|
|
480
|
+
// Basic input
|
|
481
|
+
<Input
|
|
482
|
+
label="Email"
|
|
483
|
+
size="medium"
|
|
484
|
+
type="email"
|
|
485
|
+
placeholder="email@example.com"
|
|
486
|
+
hint="We'll never share your email"
|
|
487
|
+
/>
|
|
488
|
+
|
|
489
|
+
// Left icon (informational) - size small
|
|
490
|
+
<Input
|
|
491
|
+
label="Search"
|
|
492
|
+
size="small"
|
|
493
|
+
icon={<Search size={20} strokeWidth={1.5} />}
|
|
494
|
+
placeholder="Search..."
|
|
495
|
+
/>
|
|
496
|
+
|
|
497
|
+
// Left icon - size medium
|
|
498
|
+
<Input
|
|
499
|
+
label="Search"
|
|
500
|
+
size="medium"
|
|
501
|
+
icon={<Search size={24} strokeWidth={1.5} />}
|
|
502
|
+
placeholder="Search..."
|
|
503
|
+
/>
|
|
504
|
+
|
|
505
|
+
// Right icon (action with hover) - size medium
|
|
506
|
+
<Input
|
|
507
|
+
label="Password"
|
|
508
|
+
size="medium"
|
|
509
|
+
type={showPassword ? 'text' : 'password'}
|
|
510
|
+
iconRight={showPassword ? <EyeOff size={24} strokeWidth={1.5} /> : <Eye size={24} strokeWidth={1.5} />}
|
|
511
|
+
onIconRightClick={() => setShowPassword(!showPassword)}
|
|
512
|
+
/>
|
|
513
|
+
|
|
514
|
+
// Error state
|
|
515
|
+
<Input
|
|
516
|
+
label="Name"
|
|
517
|
+
error="This field is required"
|
|
518
|
+
/>
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**Работа с иконками:**
|
|
522
|
+
- **Иконки слева** (`icon`) - информационные, не интерактивные (email, phone, user, search)
|
|
523
|
+
- **Иконки справа** (`iconRight`) - действия с hover (показать/скрыть пароль, копировать)
|
|
524
|
+
- **Цвет**: по умолчанию `--color-txt-icon-2`, при hover `--color-txt-icon-1`
|
|
525
|
+
- **Обработчик**: используйте `onIconRightClick` для действий правой иконки
|
|
526
|
+
|
|
527
|
+
### Select
|
|
528
|
+
|
|
529
|
+
```jsx
|
|
530
|
+
<Select
|
|
531
|
+
label="Choose option"
|
|
532
|
+
size="medium"
|
|
533
|
+
value={value}
|
|
534
|
+
onChange={setValue}
|
|
535
|
+
options={[
|
|
536
|
+
{ value: 'opt1', label: 'Option 1' },
|
|
537
|
+
{ value: 'opt2', label: 'Option 2' },
|
|
538
|
+
]}
|
|
539
|
+
placeholder="Select..."
|
|
540
|
+
/>
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### Stepper
|
|
544
|
+
|
|
545
|
+
Числовое поле с кнопками увеличения и уменьшения значения.
|
|
546
|
+
|
|
547
|
+
```jsx
|
|
548
|
+
// Basic stepper
|
|
549
|
+
<Stepper
|
|
550
|
+
label="Quantity"
|
|
551
|
+
size="medium"
|
|
552
|
+
value={quantity}
|
|
553
|
+
onChange={setQuantity}
|
|
554
|
+
min={1}
|
|
555
|
+
max={10}
|
|
556
|
+
step={1}
|
|
557
|
+
/>
|
|
558
|
+
|
|
559
|
+
// Small size
|
|
560
|
+
<Stepper
|
|
561
|
+
label="Price"
|
|
562
|
+
size="small"
|
|
563
|
+
value={price}
|
|
564
|
+
onChange={setPrice}
|
|
565
|
+
min={0}
|
|
566
|
+
max={1000}
|
|
567
|
+
step={10}
|
|
568
|
+
hint="In increments of 10"
|
|
569
|
+
/>
|
|
570
|
+
|
|
571
|
+
// With error
|
|
572
|
+
<Stepper
|
|
573
|
+
label="Age"
|
|
574
|
+
value={age}
|
|
575
|
+
onChange={setAge}
|
|
576
|
+
min={0}
|
|
577
|
+
max={120}
|
|
578
|
+
error="Age is required"
|
|
579
|
+
/>
|
|
580
|
+
|
|
581
|
+
// Disabled
|
|
582
|
+
<Stepper
|
|
583
|
+
label="Fixed value"
|
|
584
|
+
value={50}
|
|
585
|
+
disabled
|
|
586
|
+
/>
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
**Параметры:**
|
|
590
|
+
- `value` - текущее значение (число)
|
|
591
|
+
- `onChange` - функция обработки изменения значения
|
|
592
|
+
- `min` - минимальное значение (default: 0)
|
|
593
|
+
- `max` - максимальное значение (default: 100)
|
|
594
|
+
- `step` - шаг изменения (default: 1)
|
|
595
|
+
- `size` - размер: "small" или "medium" (default: "medium")
|
|
596
|
+
- `label` - подпись поля
|
|
597
|
+
- `hint` - подсказка под полем
|
|
598
|
+
- `error` - текст ошибки (показывается вместо hint)
|
|
599
|
+
- `disabled` - отключить поле
|
|
600
|
+
|
|
601
|
+
**Иконки в кнопках:**
|
|
602
|
+
- Small: 16px (Minus, Plus)
|
|
603
|
+
- Medium: 20px (Minus, Plus)
|
|
604
|
+
|
|
605
|
+
### Card
|
|
606
|
+
|
|
607
|
+
Карточки бывают двух типов:
|
|
608
|
+
|
|
609
|
+
```jsx
|
|
610
|
+
// Card Info (по умолчанию)
|
|
611
|
+
// Информационная карточка без интерактивности
|
|
612
|
+
// Прозрачный фон, только border
|
|
613
|
+
<Card padding="medium" variant="info">
|
|
614
|
+
<H4>Card Title</H4>
|
|
615
|
+
<P1>Information content</P1>
|
|
616
|
+
</Card>
|
|
617
|
+
|
|
618
|
+
// Card Interactive
|
|
619
|
+
// Интерактивная карточка с hover эффектом
|
|
620
|
+
// При hover меняется фон и border
|
|
621
|
+
<Card padding="large" variant="interactive" onClick={handleClick}>
|
|
622
|
+
<H4>Clickable Card</H4>
|
|
623
|
+
<P1>Interactive content</P1>
|
|
624
|
+
</Card>
|
|
625
|
+
|
|
626
|
+
// Размеры padding
|
|
627
|
+
<Card padding="small">Small padding</Card>
|
|
628
|
+
<Card padding="medium">Medium padding</Card>
|
|
629
|
+
<Card padding="large">Large padding</Card>
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
**Стиль:**
|
|
633
|
+
- **variant="info"** (по умолчанию): прозрачный фон, border `--color-border`
|
|
634
|
+
- **variant="interactive"**: фон `--color-item-bg`, при hover фон `--color-item-bg-hover` и border `--color-border-hover`, курсор pointer
|
|
635
|
+
|
|
636
|
+
### Code
|
|
637
|
+
|
|
638
|
+
```jsx
|
|
639
|
+
// Inline code
|
|
640
|
+
<p>Use <Code>--color-accent</Code> variable</p>
|
|
641
|
+
|
|
642
|
+
// Code block
|
|
643
|
+
<Code block>{`function example() {
|
|
644
|
+
return "Hello World";
|
|
645
|
+
}`}</Code>
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### Link
|
|
649
|
+
|
|
650
|
+
Ссылки акцентным цветом, подчеркивание появляется при hover.
|
|
651
|
+
|
|
652
|
+
**Стиль:**
|
|
653
|
+
- Цвет: `--color-accent`
|
|
654
|
+
- Без подчеркивания по умолчанию
|
|
655
|
+
- При hover: цвет меняется на `--color-accent-hover` + появляется подчеркивание
|
|
656
|
+
- При active: цвет `--color-accent-hover`
|
|
657
|
+
|
|
658
|
+
### Badge
|
|
659
|
+
|
|
660
|
+
Бейджи для отображения статусов и категорий в двух размерах.
|
|
661
|
+
|
|
662
|
+
```jsx
|
|
663
|
+
// Medium size (default)
|
|
664
|
+
<Badge variant="success" size="medium">Success</Badge>
|
|
665
|
+
<Badge variant="error" size="medium">Error</Badge>
|
|
666
|
+
<Badge variant="warning" size="medium">Warning</Badge>
|
|
667
|
+
<Badge variant="info" size="medium">Info</Badge>
|
|
668
|
+
|
|
669
|
+
// Small size
|
|
670
|
+
<Badge variant="success" size="small">Success</Badge>
|
|
671
|
+
<Badge variant="error" size="small">Error</Badge>
|
|
672
|
+
<Badge variant="warning" size="small">Warning</Badge>
|
|
673
|
+
|
|
674
|
+
// Variants
|
|
675
|
+
<Badge variant="default">Default</Badge>
|
|
676
|
+
<Badge variant="accent">Accent</Badge>
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
**Размеры:**
|
|
680
|
+
- `small` - компактный размер (font-size: p3, padding: 0 4px, radius: xs)
|
|
681
|
+
- `medium` - стандартный размер (font-size: p2, padding: 2px 8px, radius: s)
|
|
682
|
+
|
|
683
|
+
**Варианты:**
|
|
684
|
+
- `default` - серый с border
|
|
685
|
+
- `info` - синий (информация)
|
|
686
|
+
- `success` - зелёный (успех)
|
|
687
|
+
- `warning` - жёлтый (предупреждение)
|
|
688
|
+
- `error` - красный (ошибка)
|
|
689
|
+
- `accent` - красный акцентный
|
|
690
|
+
|
|
691
|
+
Цвета адаптируются для светлой и тёмной темы для обеспечения контраста минимум 4.5:1.
|
|
692
|
+
|
|
693
|
+
### Modal
|
|
694
|
+
|
|
695
|
+
```jsx
|
|
696
|
+
<Modal
|
|
697
|
+
title="Modal Title"
|
|
698
|
+
onClose={handleClose}
|
|
699
|
+
size="medium"
|
|
700
|
+
>
|
|
701
|
+
<P1>Modal content here...</P1>
|
|
702
|
+
<Input label="Name" placeholder="Enter name" />
|
|
703
|
+
|
|
704
|
+
<ModalFooter>
|
|
705
|
+
<Button variant="secondary" size="medium" onClick={handleClose}>
|
|
706
|
+
Cancel
|
|
707
|
+
</Button>
|
|
708
|
+
<Button variant="primary" size="medium">
|
|
709
|
+
Submit
|
|
710
|
+
</Button>
|
|
711
|
+
</ModalFooter>
|
|
712
|
+
</Modal>
|
|
713
|
+
|
|
714
|
+
{/* Modal использует иконку закрытия 20px (автоматически) */}
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
## 🛠 Для мейнтейнеров дизайн-системы
|
|
720
|
+
|
|
721
|
+
### Публикация в GitLab Package Registry (рекомендуется)
|
|
722
|
+
|
|
723
|
+
1. **Внесите изменения** в компоненты или токены
|
|
724
|
+
|
|
725
|
+
2. **Обновите версию** в `package.json`:
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
npm version patch # 0.1.0 → 0.1.2 (багфиксы)
|
|
729
|
+
npm version minor # 0.1.0 → 0.2.0 (новые фичи)
|
|
730
|
+
npm version major # 0.1.0 → 1.0.0 (breaking changes)
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
3. **Создайте тег и запушьте:**
|
|
734
|
+
|
|
735
|
+
```bash
|
|
736
|
+
git push --follow-tags
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
**Готово!** GitLab CI автоматически опубликует новую версию в Package Registry.
|
|
740
|
+
|
|
741
|
+
### Команда получит обновления
|
|
742
|
+
|
|
743
|
+
```bash
|
|
744
|
+
npm update @donkit-ai/design-system
|
|
745
|
+
# или
|
|
746
|
+
npm install @donkit-ai/design-system@latest
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
### Публикация через Git (альтернатива)
|
|
752
|
+
|
|
753
|
+
Если не используете Package Registry:
|
|
754
|
+
|
|
755
|
+
```bash
|
|
756
|
+
git add .
|
|
757
|
+
git commit -m "Update button styles"
|
|
758
|
+
git push origin main
|
|
759
|
+
|
|
760
|
+
# Опционально: создать тег
|
|
761
|
+
git tag v0.1.2
|
|
762
|
+
git push --tags
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
Команда обновляет:
|
|
766
|
+
|
|
767
|
+
```bash
|
|
768
|
+
npm update @donkit-ai/design-system
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Локальная разработка
|
|
772
|
+
|
|
773
|
+
Для тестирования изменений локально используйте `npm link`:
|
|
774
|
+
|
|
775
|
+
```bash
|
|
776
|
+
# В папке Donkit-desing-tokens
|
|
777
|
+
npm link
|
|
778
|
+
|
|
779
|
+
# В папке вашего проекта (agent-platform/frontend)
|
|
780
|
+
npm link @donkit-ai/design-system
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
Теперь изменения в дизайн-системе сразу видны в вашем проекте без переустановки.
|
|
784
|
+
|
|
785
|
+
### Структура версионирования
|
|
786
|
+
|
|
787
|
+
- **Главная ветка:** `main` - стабильная версия
|
|
788
|
+
- **Теги:** `v0.1.0`, `v0.1.2` - релизные версии
|
|
789
|
+
- **Фичи:** создавайте ветки для больших изменений, мерджите в `main` после ревью
|
|
790
|
+
|
|
791
|
+
---
|
|
792
|
+
|
|
793
|
+
## Лицензия
|
|
794
|
+
|
|
795
|
+
MIT
|