@donkit-ai/design-system 0.2.10 → 0.2.12

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 CHANGED
@@ -89,19 +89,30 @@ function MyComponent() {
89
89
 
90
90
  #### Размеры иконок
91
91
 
92
- **Важно:** Размеры иконок фиксированные (не адаптивные) и зависят от контекста использования:
92
+ Размеры иконок стандартизированы с помощью констант:
93
93
 
94
- - **20px** - компактные элементы
94
+ ```javascript
95
+ import { iconSizes } from '@donkit-ai/design-system';
96
+
97
+ // iconSizes = { xs: 16, s: 20, m: 24, l: 28 }
98
+ ```
99
+
100
+ **Соответствие размеров компонентам:**
101
+
102
+ - **16px (xs)** - очень мелкие элементы
103
+ - **20px (s)** - компактные элементы
95
104
  - Small кнопки (`size="small"`)
96
105
  - Tabs (вкладки)
97
106
  - Modal (иконка закрытия)
107
+ - Accordion, CodeAccordion
98
108
 
99
- - **24px** - стандартные элементы
109
+ - **24px (m)** - стандартные элементы
100
110
  - Medium кнопки (`size="medium"`, по умолчанию)
101
111
  - Input (иконки в полях ввода)
102
112
  - Alert (иконки статусов)
113
+ - Select (иконка выпадающего списка)
103
114
 
104
- - **28px** - крупные элементы
115
+ - **28px (l)** - крупные элементы
105
116
  - Large кнопки (`size="large"`)
106
117
 
107
118
  **Всегда используется `strokeWidth={1.5}`** для единообразия дизайна.
@@ -110,30 +121,31 @@ function MyComponent() {
110
121
 
111
122
  ```javascript
112
123
  import { Mail, Search, Eye, EyeOff, AlertCircle, Check, X } from 'lucide-react';
124
+ import { iconSizes } from '@donkit-ai/design-system';
113
125
 
114
126
  // Small button / Tabs / Modal
115
- <Button size="small" icon={<Mail size={20} strokeWidth={1.5} />}>
127
+ <Button size="small" icon={<Mail size={iconSizes.s} strokeWidth={1.5} />}>
116
128
  Send
117
129
  </Button>
118
- <Tab icon={<AlertCircle size={20} strokeWidth={1.5} />}>
130
+ <Tab icon={<AlertCircle size={iconSizes.s} strokeWidth={1.5} />}>
119
131
  Alerts
120
132
  </Tab>
121
133
 
122
134
  // Medium button / Input / Alert
123
- <Button size="medium" icon={<Search size={24} strokeWidth={1.5} />}>
135
+ <Button size="medium" icon={<Search size={iconSizes.m} strokeWidth={1.5} />}>
124
136
  Search
125
137
  </Button>
126
138
  <Input
127
- icon={<Search size={24} strokeWidth={1.5} />}
139
+ icon={<Search size={iconSizes.m} strokeWidth={1.5} />}
128
140
  placeholder="Search..."
129
141
  />
130
142
  <Alert
131
143
  type="success"
132
- icon={<Check size={24} strokeWidth={1.5} />}
144
+ icon={<Check size={iconSizes.m} strokeWidth={1.5} />}
133
145
  />
134
146
 
135
147
  // Large button
136
- <Button size="large" icon={<Mail size={28} strokeWidth={1.5} />}>
148
+ <Button size="large" icon={<Mail size={iconSizes.l} strokeWidth={1.5} />}>
137
149
  Send Email
138
150
  </Button>
139
151
  ```
@@ -154,9 +166,9 @@ document.documentElement.setAttribute('data-theme', 'light');
154
166
 
155
167
  #### Базовые примитивы
156
168
  - `--color-white`: #FFFAFA
157
- - `--color-white-65/50/40/20/15/13/06`: rgba с прозрачностью 65%, 50%, 40%, 20%, 15%, 13%, 6%
169
+ - `--color-white-95/92/65/50/40/20/15/13/06`: rgba с прозрачностью 95%, 92%, 65%, 50%, 40%, 20%, 15%, 13%, 6%
158
170
  - `--color-black`: #0E0F11
159
- - `--color-black-65/60/50/40/20/10/08/04`: rgba с прозрачностью 65%, 60%, 50%, 40%, 20%, 10%, 8%, 4%
171
+ - `--color-black-95/65/60/50/40/20/10/08/04`: rgba с прозрачностью 95%, 65%, 60%, 50%, 40%, 20%, 10%, 8%, 4%
160
172
  - `--color-red`: #EA6464
161
173
  - `--color-red-90`: rgba с прозрачностью 90%
162
174
 
@@ -170,7 +182,7 @@ document.documentElement.setAttribute('data-theme', 'light');
170
182
  - `--color-border` - границы
171
183
  - `--color-border-hover` - границы при hover (Dark: white-40, Light: black-40)
172
184
  - `--color-border-selected` - границы выбранного элемента (Dark: white-50, Light: black-50)
173
- - `--color-txt-icon-1` - основной текст/иконки (100%)
185
+ - `--color-txt-icon-1` - основной текст/иконки (Dark: white-92, Light: black-95)
174
186
  - `--color-txt-icon-2` - вторичный текст/иконки (65%)
175
187
  - `--color-accent` - акцентный цвет
176
188
  - `--color-accent-hover` - акцент при hover
@@ -203,7 +215,7 @@ document.documentElement.setAttribute('data-theme', 'light');
203
215
  - `--font-size-h1`: 32px → 40px → 40px
204
216
  - `--font-size-h2`: 28px → 36px → 36px
205
217
  - `--font-size-h3`: 24px → 28px → 28px
206
- - `--font-size-h4`: 18px20px20px
218
+ - `--font-size-h4`: 20px24px24px
207
219
  - `--font-size-p1`: 16px → 18px → 18px
208
220
  - `--font-size-p2`: 14px → 16px → 16px
209
221
  - `--font-size-p3`: 12px → 14px → 14px
@@ -214,7 +226,7 @@ document.documentElement.setAttribute('data-theme', 'light');
214
226
  - Меньше 14px → +6% (0.06em)
215
227
 
216
228
  Адаптивные значения трекинга:
217
- - `--letter-spacing-h4`: 0.02em → 0 → 0 (18px / 20px / 20px)
229
+ - `--letter-spacing-h4`: 0 → 0 → 0 (20px / 24px / 24px - без трекинга)
218
230
  - `--letter-spacing-p1`: 0.02em → 0.02em → 0.02em (16px / 18px / 18px)
219
231
  - `--letter-spacing-p2`: 0.04em → 0.02em → 0.02em (14px / 16px / 16px)
220
232
  - `--letter-spacing-p3`: 0.06em → 0.04em → 0.04em (12px / 14px / 14px)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donkit-ai/design-system",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Donkit Design System - minimal design tokens and React components",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -1,5 +1,6 @@
1
1
  import React, { useState } from 'react';
2
2
  import { ChevronDown } from 'lucide-react';
3
+ import { iconSizes } from '../styles/iconSizes';
3
4
  import './Accordion.css';
4
5
 
5
6
  export function Accordion({
@@ -20,7 +21,7 @@ export function Accordion({
20
21
  >
21
22
  <span className="ds-accordion__title">{title}</span>
22
23
  <ChevronDown
23
- size={20}
24
+ size={iconSizes.s}
24
25
  strokeWidth={1.5}
25
26
  className={`ds-accordion__icon ${isExpanded ? 'ds-accordion__icon--expanded' : ''}`}
26
27
  />
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Info, CheckCircle, AlertTriangle, XCircle, X } from 'lucide-react';
3
+ import { iconSizes } from '../styles/iconSizes';
3
4
  import './Alert.css';
4
5
 
5
6
  const ICON_MAP = {
@@ -24,7 +25,7 @@ export function Alert({
24
25
  <div className={`ds-alert ds-alert--${variant} ${!title ? 'ds-alert--no-title' : ''}`} role={alertRole} {...props}>
25
26
  {Icon && (
26
27
  <div className="ds-alert__icon">
27
- <Icon size={24} strokeWidth={1.5} />
28
+ <Icon size={iconSizes.m} strokeWidth={1.5} />
28
29
  </div>
29
30
  )}
30
31
  <div className="ds-alert__content">
@@ -38,7 +39,7 @@ export function Alert({
38
39
  onClick={onClose}
39
40
  aria-label="Close alert"
40
41
  >
41
- <X size={24} strokeWidth={1.5} />
42
+ <X size={iconSizes.m} strokeWidth={1.5} />
42
43
  </button>
43
44
  )}
44
45
  </div>
@@ -1,5 +1,6 @@
1
1
  import React, { useState } from 'react';
2
2
  import { ChevronDown } from 'lucide-react';
3
+ import { iconSizes } from '../styles/iconSizes';
3
4
  import './CodeAccordion.css';
4
5
 
5
6
  export function CodeAccordion({
@@ -20,7 +21,7 @@ export function CodeAccordion({
20
21
  >
21
22
  <span className="ds-code-accordion__title">{title}</span>
22
23
  <ChevronDown
23
- size={20}
24
+ size={iconSizes.s}
24
25
  strokeWidth={1.5}
25
26
  className={`ds-code-accordion__icon ${isExpanded ? 'ds-code-accordion__icon--expanded' : ''}`}
26
27
  />
@@ -1,5 +1,6 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
2
  import { X } from 'lucide-react';
3
+ import { iconSizes } from '../styles/iconSizes';
3
4
  import { Button } from './Button';
4
5
  import './Modal.css';
5
6
 
@@ -52,7 +53,7 @@ export function Modal({
52
53
  <Button
53
54
  variant="ghost"
54
55
  size="small"
55
- icon={<X size={20} strokeWidth={1.5} />}
56
+ icon={<X size={iconSizes.s} strokeWidth={1.5} />}
56
57
  onClick={onClose}
57
58
  aria-label="Close modal"
58
59
  />
@@ -1,5 +1,6 @@
1
1
  import React, { useState, useRef, useEffect } from 'react';
2
2
  import { ChevronDown } from 'lucide-react';
3
+ import { iconSizes } from '../styles/iconSizes';
3
4
  import './Select.css';
4
5
 
5
6
  export function Select({
@@ -52,7 +53,7 @@ export function Select({
52
53
  }, [isOpen]);
53
54
 
54
55
  const selectedOption = options.find(opt => opt.value === value);
55
- const iconSize = size === 'small' ? 20 : 24;
56
+ const iconSize = size === 'small' ? iconSizes.s : iconSizes.m;
56
57
 
57
58
  return (
58
59
  <div className={`ds-select-wrapper ${fullWidth ? 'ds-select-wrapper--full' : ''} ${disabled ? 'ds-select-wrapper--disabled' : ''}`}>
@@ -99,28 +99,32 @@
99
99
  /* Sizes */
100
100
 
101
101
  /* Small */
102
+ .ds-stepper--small {
103
+ height: var(--height-s);
104
+ }
105
+
102
106
  .ds-stepper--small .ds-stepper-button {
103
107
  width: var(--height-s);
104
- height: var(--height-s);
105
108
  padding: 0;
106
109
  }
107
110
 
108
111
  .ds-stepper--small .ds-stepper-input {
109
- height: var(--height-s);
110
112
  font-size: var(--font-size-p2);
111
113
  letter-spacing: var(--letter-spacing-p2);
112
114
  padding: 0 var(--space-xs);
113
115
  }
114
116
 
115
117
  /* Medium */
118
+ .ds-stepper--medium {
119
+ height: var(--height-m);
120
+ }
121
+
116
122
  .ds-stepper--medium .ds-stepper-button {
117
123
  width: var(--height-m);
118
- height: var(--height-m);
119
124
  padding: 0;
120
125
  }
121
126
 
122
127
  .ds-stepper--medium .ds-stepper-input {
123
- height: var(--height-m);
124
128
  font-size: var(--font-size-p1);
125
129
  letter-spacing: var(--letter-spacing-p1);
126
130
  padding: 0 var(--space-s);
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Minus, Plus } from 'lucide-react';
3
+ import { iconSizes } from '../styles/iconSizes';
3
4
  import './Stepper.css';
4
5
 
5
6
  export function Stepper({
@@ -56,7 +57,7 @@ export function Stepper({
56
57
  disabled && 'ds-stepper--disabled',
57
58
  ].filter(Boolean).join(' ');
58
59
 
59
- const iconSize = size === 'small' ? 20 : 24;
60
+ const iconSize = size === 'small' ? iconSizes.s : iconSizes.m;
60
61
 
61
62
  return (
62
63
  <div className={className}>
@@ -28,27 +28,31 @@
28
28
  transition: border-color var(--transition-normal);
29
29
  line-height: 1.5;
30
30
  resize: vertical;
31
- /* Кастомный resize handle */
31
+ /* Кастомный resize handle - 2 диагональные линии */
32
32
  background:
33
- linear-gradient(135deg, transparent 6px, var(--color-border) 6px, var(--color-border) 7px, transparent 7px),
34
- linear-gradient(135deg, transparent 10px, var(--color-border) 10px, var(--color-border) 11px, transparent 11px);
33
+ linear-gradient(315deg, transparent 5px, var(--color-border) 5px, var(--color-border) 6px, transparent 6px),
34
+ linear-gradient(315deg, transparent 10px, var(--color-border) 10px, var(--color-border) 11px, transparent 11px);
35
35
  background-repeat: no-repeat;
36
36
  background-position: bottom right;
37
- background-size: 12px 12px;
37
+ background-size: 16px 16px;
38
38
  }
39
39
 
40
40
  .ds-textarea::placeholder {
41
41
  color: var(--color-txt-icon-2);
42
42
  }
43
43
 
44
+ .ds-textarea::-webkit-resizer {
45
+ display: none;
46
+ }
47
+
44
48
  .ds-textarea:hover:not(:disabled) {
45
49
  border-color: var(--color-border-hover);
46
50
  background:
47
- linear-gradient(135deg, transparent 6px, var(--color-border-hover) 6px, var(--color-border-hover) 7px, transparent 7px),
48
- linear-gradient(135deg, transparent 10px, var(--color-border-hover) 10px, var(--color-border-hover) 11px, transparent 11px);
51
+ linear-gradient(315deg, transparent 5px, var(--color-border-hover) 5px, var(--color-border-hover) 6px, transparent 6px),
52
+ linear-gradient(315deg, transparent 10px, var(--color-border-hover) 10px, var(--color-border-hover) 11px, transparent 11px);
49
53
  background-repeat: no-repeat;
50
54
  background-position: bottom right;
51
- background-size: 12px 12px;
55
+ background-size: 16px 16px;
52
56
  }
53
57
 
54
58
  .ds-textarea:focus,
@@ -56,11 +60,11 @@
56
60
  outline: none;
57
61
  border-color: var(--color-border-hover);
58
62
  background:
59
- linear-gradient(135deg, transparent 6px, var(--color-border-hover) 6px, var(--color-border-hover) 7px, transparent 7px),
60
- linear-gradient(135deg, transparent 10px, var(--color-border-hover) 10px, var(--color-border-hover) 11px, transparent 11px);
63
+ linear-gradient(315deg, transparent 5px, var(--color-border-hover) 5px, var(--color-border-hover) 6px, transparent 6px),
64
+ linear-gradient(315deg, transparent 10px, var(--color-border-hover) 10px, var(--color-border-hover) 11px, transparent 11px);
61
65
  background-repeat: no-repeat;
62
66
  background-position: bottom right;
63
- background-size: 12px 12px;
67
+ background-size: 16px 16px;
64
68
  }
65
69
 
66
70
  .ds-textarea:disabled {
@@ -70,11 +74,11 @@
70
74
  .ds-textarea--error {
71
75
  border-color: var(--color-error);
72
76
  background:
73
- linear-gradient(135deg, transparent 6px, var(--color-error) 6px, var(--color-error) 7px, transparent 7px),
74
- linear-gradient(135deg, transparent 10px, var(--color-error) 10px, var(--color-error) 11px, transparent 11px);
77
+ linear-gradient(315deg, transparent 5px, var(--color-error) 5px, var(--color-error) 6px, transparent 6px),
78
+ linear-gradient(315deg, transparent 10px, var(--color-error) 10px, var(--color-error) 11px, transparent 11px);
75
79
  background-repeat: no-repeat;
76
80
  background-position: bottom right;
77
- background-size: 12px 12px;
81
+ background-size: 16px 16px;
78
82
  }
79
83
 
80
84
  .ds-textarea--no-resize {
package/src/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // Styles
2
2
  export * from './styles/tokens.css';
3
+ export { iconSizes } from './styles/iconSizes';
3
4
 
4
5
  // Components
5
6
  export { Button } from './components/Button';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Icon sizes matching CSS variables
3
+ * --icon-xs: 16px
4
+ * --icon-s: 20px
5
+ * --icon-m: 24px
6
+ * --icon-l: 28px
7
+ */
8
+ export const iconSizes = {
9
+ xs: 16,
10
+ s: 20,
11
+ m: 24,
12
+ l: 28,
13
+ };
@@ -11,6 +11,7 @@
11
11
  /* Color primitives - white */
12
12
  --color-white: #FFFAFA;
13
13
  --color-white-95: rgba(255, 250, 250, 0.95);
14
+ --color-white-92: rgba(255, 250, 250, 0.92);
14
15
  --color-white-65: rgba(255, 250, 250, 0.65);
15
16
  --color-white-50: rgba(255, 250, 250, 0.5);
16
17
  --color-white-40: rgba(255, 250, 250, 0.4);
@@ -67,7 +68,7 @@
67
68
  --color-border: var(--color-white-20);
68
69
  --color-border-hover: var(--color-white-40);
69
70
  --color-border-selected: var(--color-white-50);
70
- --color-txt-icon-1: var(--color-white-95);
71
+ --color-txt-icon-1: var(--color-white-92);
71
72
  --color-txt-icon-2: var(--color-white-65);
72
73
  --color-accent: var(--color-red);
73
74
  --color-accent-hover: var(--color-red-90);
@@ -173,6 +174,12 @@
173
174
  --height-s: 32px;
174
175
  --height-m: 44px;
175
176
  --height-l: 56px;
177
+
178
+ /* Icon sizes */
179
+ --icon-xs: 16px;
180
+ --icon-s: 20px;
181
+ --icon-m: 24px;
182
+ --icon-l: 28px;
176
183
  }
177
184
 
178
185
  :root {
@@ -188,7 +195,7 @@
188
195
  --font-size-h1: 32px;
189
196
  --font-size-h2: 28px;
190
197
  --font-size-h3: 24px;
191
- --font-size-h4: 18px;
198
+ --font-size-h4: 20px;
192
199
  --font-size-p1: 16px;
193
200
  --font-size-p2: 14px;
194
201
  --font-size-p3: 12px;
@@ -197,7 +204,7 @@
197
204
  --letter-spacing-h1: 0;
198
205
  --letter-spacing-h2: 0;
199
206
  --letter-spacing-h3: 0;
200
- --letter-spacing-h4: 0.02em; /* 18px+2% */
207
+ --letter-spacing-h4: 0; /* 20pxno tracking */
201
208
  --letter-spacing-p1: 0.02em; /* 16px → +2% */
202
209
  --letter-spacing-p2: 0.04em; /* 14px → +4% */
203
210
  --letter-spacing-p3: 0.06em; /* 12px → +6% */
@@ -209,12 +216,12 @@
209
216
  --font-size-h1: 40px;
210
217
  --font-size-h2: 36px;
211
218
  --font-size-h3: 28px;
212
- --font-size-h4: 20px;
219
+ --font-size-h4: 24px;
213
220
  --font-size-p1: 18px;
214
221
  --font-size-p2: 16px;
215
222
  --font-size-p3: 14px;
216
223
 
217
- --letter-spacing-h4: 0; /* 20px → no tracking */
224
+ --letter-spacing-h4: 0; /* 24px → no tracking */
218
225
  --letter-spacing-p1: 0.02em; /* 18px → +2% */
219
226
  --letter-spacing-p2: 0.02em; /* 16px → +2% */
220
227
  --letter-spacing-p3: 0.04em; /* 14px → +4% */
@@ -227,12 +234,12 @@
227
234
  --font-size-h1: 40px;
228
235
  --font-size-h2: 36px;
229
236
  --font-size-h3: 28px;
230
- --font-size-h4: 20px;
237
+ --font-size-h4: 24px;
231
238
  --font-size-p1: 18px;
232
239
  --font-size-p2: 16px;
233
240
  --font-size-p3: 14px;
234
241
 
235
- --letter-spacing-h4: 0; /* 20px → no tracking */
242
+ --letter-spacing-h4: 0; /* 24px → no tracking */
236
243
  --letter-spacing-p1: 0.02em; /* 18px → +2% */
237
244
  --letter-spacing-p2: 0.02em; /* 16px → +2% */
238
245
  --letter-spacing-p3: 0.04em; /* 14px → +4% */