@donkit-ai/design-system 0.3.5 → 0.4.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.
Files changed (45) hide show
  1. package/dist/index.cjs.js +22 -0
  2. package/dist/index.es.js +1105 -0
  3. package/dist/tokens.css +1 -0
  4. package/package.json +15 -9
  5. package/src/components/Accordion.css +0 -70
  6. package/src/components/Accordion.jsx +0 -42
  7. package/src/components/Alert.css +0 -93
  8. package/src/components/Alert.jsx +0 -47
  9. package/src/components/Badge.css +0 -52
  10. package/src/components/Badge.jsx +0 -25
  11. package/src/components/Button.css +0 -103
  12. package/src/components/Button.jsx +0 -80
  13. package/src/components/Card.css +0 -46
  14. package/src/components/Card.jsx +0 -70
  15. package/src/components/Checkbox.css +0 -88
  16. package/src/components/Checkbox.jsx +0 -47
  17. package/src/components/Code.css +0 -30
  18. package/src/components/Code.jsx +0 -27
  19. package/src/components/CodeAccordion.css +0 -80
  20. package/src/components/CodeAccordion.jsx +0 -42
  21. package/src/components/Input.css +0 -163
  22. package/src/components/Input.jsx +0 -55
  23. package/src/components/Link.css +0 -18
  24. package/src/components/Link.jsx +0 -21
  25. package/src/components/Modal.css +0 -70
  26. package/src/components/Modal.jsx +0 -72
  27. package/src/components/Radio.css +0 -115
  28. package/src/components/Radio.jsx +0 -42
  29. package/src/components/Select.css +0 -167
  30. package/src/components/Select.jsx +0 -118
  31. package/src/components/Stepper.css +0 -183
  32. package/src/components/Stepper.jsx +0 -104
  33. package/src/components/Tabs.css +0 -87
  34. package/src/components/Tabs.jsx +0 -81
  35. package/src/components/Textarea.css +0 -116
  36. package/src/components/Textarea.jsx +0 -41
  37. package/src/components/Toggle.css +0 -133
  38. package/src/components/Toggle.jsx +0 -38
  39. package/src/components/Tooltip.css +0 -134
  40. package/src/components/Tooltip.jsx +0 -158
  41. package/src/components/Typography.css +0 -74
  42. package/src/components/Typography.jsx +0 -42
  43. package/src/index.js +0 -24
  44. package/src/styles/iconSizes.js +0 -15
  45. package/src/styles/tokens.css +0 -298
@@ -1,183 +0,0 @@
1
- /* Stepper Component */
2
-
3
- .ds-stepper-wrapper {
4
- display: flex;
5
- flex-direction: column;
6
- gap: var(--space-xs);
7
- }
8
-
9
- .ds-stepper-label {
10
- font-size: var(--font-size-p2);
11
- letter-spacing: var(--letter-spacing-p2);
12
- color: var(--color-txt-icon-1);
13
- }
14
-
15
- .ds-stepper {
16
- display: flex;
17
- align-items: stretch;
18
- width: fit-content;
19
- border: 1px solid var(--color-border);
20
- border-radius: var(--radius-xs);
21
- transition: border-color var(--transition-normal);
22
- }
23
-
24
- .ds-stepper:hover:not(.ds-stepper--disabled) {
25
- border-color: var(--color-border-hover);
26
- }
27
-
28
- .ds-stepper:focus-within {
29
- border-color: var(--color-border-hover);
30
- }
31
-
32
- .ds-stepper--disabled {
33
- cursor: not-allowed;
34
- }
35
-
36
- .ds-stepper-button {
37
- display: flex;
38
- align-items: center;
39
- justify-content: center;
40
- background-color: transparent;
41
- border: none;
42
- color: var(--color-txt-icon-2);
43
- cursor: pointer;
44
- transition: background-color var(--transition-fast), color var(--transition-fast);
45
- flex-shrink: 0;
46
- }
47
-
48
- .ds-stepper-button:hover:not(:disabled) {
49
- background-color: var(--color-item-bg-hover);
50
- color: var(--color-txt-icon-1);
51
- }
52
-
53
- .ds-stepper-button:active:not(:disabled) {
54
- background-color: var(--color-item-bg-selected);
55
- }
56
-
57
- .ds-stepper-button:disabled {
58
- opacity: 0.5;
59
- cursor: not-allowed;
60
- }
61
-
62
- .ds-stepper-button--minus {
63
- border-radius: var(--radius-xs) 0 0 var(--radius-xs);
64
- border-right: 1px solid var(--color-border);
65
- }
66
-
67
- .ds-stepper-button--plus {
68
- border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
69
- border-left: 1px solid var(--color-border);
70
- }
71
-
72
- .ds-stepper-input {
73
- width: 80px;
74
- text-align: center;
75
- border: none;
76
- background-color: transparent;
77
- color: var(--color-txt-icon-1);
78
- font-size: var(--font-size-p1);
79
- letter-spacing: var(--letter-spacing-p1);
80
- outline: none;
81
- cursor: text;
82
- }
83
-
84
- .ds-stepper-input:disabled {
85
- cursor: not-allowed;
86
- }
87
-
88
- /* Remove spinner arrows */
89
- .ds-stepper-input::-webkit-inner-spin-button,
90
- .ds-stepper-input::-webkit-outer-spin-button {
91
- -webkit-appearance: none;
92
- margin: 0;
93
- }
94
-
95
- .ds-stepper-input[type=number] {
96
- -moz-appearance: textfield;
97
- }
98
-
99
- /* Sizes */
100
-
101
- /* Extra Small */
102
- .ds-stepper--xs {
103
- height: var(--height-xs);
104
- }
105
-
106
- .ds-stepper--xs .ds-stepper-button {
107
- width: var(--height-xs);
108
- padding: 0;
109
- }
110
-
111
- .ds-stepper--xs .ds-stepper-input {
112
- font-size: var(--font-size-p3);
113
- letter-spacing: var(--letter-spacing-p3);
114
- padding: 0 var(--space-xs);
115
- }
116
-
117
- /* Small */
118
- .ds-stepper--s {
119
- height: var(--height-s);
120
- }
121
-
122
- .ds-stepper--s .ds-stepper-button {
123
- width: var(--height-s);
124
- padding: 0;
125
- }
126
-
127
- .ds-stepper--s .ds-stepper-input {
128
- font-size: var(--font-size-p2);
129
- letter-spacing: var(--letter-spacing-p2);
130
- padding: 0 var(--space-xs);
131
- }
132
-
133
- /* Medium */
134
- .ds-stepper--m {
135
- height: var(--height-m);
136
- }
137
-
138
- .ds-stepper--m .ds-stepper-button {
139
- width: var(--height-m);
140
- padding: 0;
141
- }
142
-
143
- .ds-stepper--m .ds-stepper-input {
144
- font-size: var(--font-size-p1);
145
- letter-spacing: var(--letter-spacing-p1);
146
- padding: 0 var(--space-s);
147
- }
148
-
149
- /* Hint & Error */
150
- .ds-stepper-hint {
151
- font-size: var(--font-size-p2);
152
- letter-spacing: var(--letter-spacing-p2);
153
- color: var(--color-txt-icon-2);
154
- }
155
-
156
- .ds-stepper-error {
157
- font-size: var(--font-size-p2);
158
- letter-spacing: var(--letter-spacing-p2);
159
- color: var(--color-status-error);
160
- }
161
-
162
- /* Error state */
163
- .ds-stepper-wrapper--error .ds-stepper {
164
- border-color: var(--color-status-error);
165
- }
166
-
167
- .ds-stepper-wrapper--error .ds-stepper:hover:not(.ds-stepper--disabled) {
168
- border-color: var(--color-status-error);
169
- }
170
-
171
- .ds-stepper-wrapper--error .ds-stepper:focus-within {
172
- border-color: var(--color-status-error);
173
- }
174
-
175
- /* Disabled state */
176
- .ds-stepper-wrapper--disabled {
177
- opacity: 0.5;
178
- cursor: not-allowed;
179
- }
180
-
181
- .ds-stepper-wrapper--disabled * {
182
- cursor: not-allowed;
183
- }
@@ -1,104 +0,0 @@
1
- import React from 'react';
2
- import { Minus, Plus } from 'lucide-react';
3
- import { iconSizes } from '../styles/iconSizes';
4
- import './Stepper.css';
5
-
6
- export function Stepper({
7
- label,
8
- value = 0,
9
- onChange,
10
- min = 0,
11
- max = 100,
12
- step = 1,
13
- size = 'm',
14
- disabled = false,
15
- hint,
16
- error,
17
- ...props
18
- }) {
19
- const handleIncrement = () => {
20
- if (disabled) return;
21
- const newValue = Math.min(Number(value) + step, max);
22
- onChange?.(newValue);
23
- };
24
-
25
- const handleDecrement = () => {
26
- if (disabled) return;
27
- const newValue = Math.max(Number(value) - step, min);
28
- onChange?.(newValue);
29
- };
30
-
31
- const handleInputChange = (e) => {
32
- if (disabled) return;
33
- const newValue = e.target.value;
34
-
35
- // Allow empty string for user to clear and type
36
- if (newValue === '') {
37
- onChange?.(min);
38
- return;
39
- }
40
-
41
- const numValue = Number(newValue);
42
- if (!isNaN(numValue)) {
43
- const clampedValue = Math.min(Math.max(numValue, min), max);
44
- onChange?.(clampedValue);
45
- }
46
- };
47
-
48
- const className = [
49
- 'ds-stepper-wrapper',
50
- disabled && 'ds-stepper-wrapper--disabled',
51
- error && 'ds-stepper-wrapper--error',
52
- ].filter(Boolean).join(' ');
53
-
54
- const stepperClassName = [
55
- 'ds-stepper',
56
- `ds-stepper--${size}`,
57
- disabled && 'ds-stepper--disabled',
58
- ].filter(Boolean).join(' ');
59
-
60
- const iconSize = size === 'xs' ? iconSizes.xs : size === 'small' ? iconSizes.s : iconSizes.m;
61
-
62
- return (
63
- <div className={className}>
64
- {label && <label className="ds-stepper-label">{label}</label>}
65
-
66
- <div className={stepperClassName}>
67
- <button
68
- type="button"
69
- className="ds-stepper-button ds-stepper-button--minus"
70
- onClick={handleDecrement}
71
- disabled={disabled || value <= min}
72
- aria-label="Decrease"
73
- >
74
- <Minus size={iconSize} strokeWidth={1.5} />
75
- </button>
76
-
77
- <input
78
- type="number"
79
- className="ds-stepper-input"
80
- value={value}
81
- onChange={handleInputChange}
82
- min={min}
83
- max={max}
84
- step={step}
85
- disabled={disabled}
86
- {...props}
87
- />
88
-
89
- <button
90
- type="button"
91
- className="ds-stepper-button ds-stepper-button--plus"
92
- onClick={handleIncrement}
93
- disabled={disabled || value >= max}
94
- aria-label="Increase"
95
- >
96
- <Plus size={iconSize} strokeWidth={1.5} />
97
- </button>
98
- </div>
99
-
100
- {hint && !error && <div className="ds-stepper-hint">{hint}</div>}
101
- {error && <div className="ds-stepper-error">{error}</div>}
102
- </div>
103
- );
104
- }
@@ -1,87 +0,0 @@
1
- .ds-tabs {
2
- display: flex;
3
- gap: var(--space-xs);
4
- flex-wrap: wrap;
5
- }
6
-
7
- .ds-tab {
8
- display: inline-flex;
9
- align-items: center;
10
- justify-content: center;
11
- gap: var(--space-xs);
12
- font-family: inherit;
13
- font-weight: 400;
14
- line-height: 1;
15
- cursor: pointer;
16
- background-color: transparent;
17
- color: var(--color-txt-icon-1);
18
- transition: border-color var(--transition-normal), background-color var(--transition-normal);
19
- white-space: nowrap;
20
- text-decoration: none;
21
- }
22
-
23
- /* Variants */
24
- .ds-tab--ghost {
25
- border: none;
26
- color: var(--color-txt-icon-2);
27
- }
28
-
29
- .ds-tab--ghost:hover:not(.ds-tab--selected):not(:disabled):not([aria-disabled="true"]) {
30
- background-color: var(--color-item-bg-hover);
31
- color: var(--color-txt-icon-1);
32
- }
33
-
34
- .ds-tab--ghost.ds-tab--selected {
35
- background-color: var(--color-item-bg-selected);
36
- color: var(--color-txt-icon-1);
37
- }
38
-
39
- /* Sizes */
40
- .ds-tab--xs {
41
- height: var(--height-xs);
42
- padding: 0 calc(var(--height-xs) / 2);
43
- font-size: var(--font-size-p3);
44
- border-radius: var(--radius-xs);
45
- }
46
-
47
- .ds-tab--s {
48
- height: var(--height-s);
49
- padding: 0 calc(var(--height-s) / 2);
50
- font-size: var(--font-size-p2);
51
- border-radius: var(--radius-xs);
52
- }
53
-
54
- .ds-tab--m {
55
- height: var(--height-m);
56
- padding: 0 calc(var(--height-m) / 2);
57
- font-size: var(--font-size-p1);
58
- border-radius: var(--radius-s);
59
- }
60
-
61
- .ds-tab--l {
62
- height: var(--height-l);
63
- padding: 0 calc(var(--height-l) / 2);
64
- font-size: var(--font-size-p1);
65
- border-radius: var(--radius-s);
66
- gap: var(--space-s);
67
- }
68
-
69
- .ds-tab:disabled,
70
- .ds-tab[aria-disabled="true"] {
71
- opacity: 0.5;
72
- cursor: not-allowed;
73
- pointer-events: none;
74
- }
75
-
76
- .ds-tab-icon {
77
- display: flex;
78
- align-items: center;
79
- justify-content: center;
80
- flex-shrink: 0;
81
- }
82
-
83
- .ds-tab--icon-only {
84
- aspect-ratio: 1;
85
- padding-left: 0;
86
- padding-right: 0;
87
- }
@@ -1,81 +0,0 @@
1
- import React from 'react';
2
- import './Tabs.css';
3
-
4
- export function Tabs({ children, size = 'm', variant = 'ghost', ...props }) {
5
- return (
6
- <div className="ds-tabs" role="tablist" {...props}>
7
- {React.Children.map(children, (child) => {
8
- if (React.isValidElement(child)) {
9
- return React.cloneElement(child, { size, variant });
10
- }
11
- return child;
12
- })}
13
- </div>
14
- );
15
- }
16
-
17
- export function Tab({ children, selected = false, onClick, size = 'm', variant = 'ghost', disabled = false, icon, href, ...props }) {
18
- const isIconOnly = icon && !children;
19
-
20
- const className = [
21
- 'ds-tab',
22
- `ds-tab--${size}`,
23
- `ds-tab--${variant}`,
24
- selected && 'ds-tab--selected',
25
- isIconOnly && 'ds-tab--icon-only',
26
- ].filter(Boolean).join(' ');
27
-
28
- const content = (
29
- <>
30
- {icon && <span className="ds-tab-icon">{icon}</span>}
31
- {children}
32
- </>
33
- );
34
-
35
- // Render as link if href is provided
36
- if (href) {
37
- const handleClick = (e) => {
38
- if (disabled) {
39
- e.preventDefault();
40
- return;
41
- }
42
-
43
- // При Cmd/Ctrl+Click или Middle Click — пусть браузер откроет новую вкладку
44
- if (e.metaKey || e.ctrlKey || e.button === 1) {
45
- return;
46
- }
47
-
48
- // Обычный клик — preventDefault и вызов onClick
49
- e.preventDefault();
50
- onClick?.(e);
51
- };
52
-
53
- return (
54
- <a
55
- role="tab"
56
- aria-current={selected ? 'page' : undefined}
57
- aria-disabled={disabled ? 'true' : undefined}
58
- className={className}
59
- href={disabled ? undefined : href}
60
- onClick={handleClick}
61
- {...props}
62
- >
63
- {content}
64
- </a>
65
- );
66
- }
67
-
68
- // Render as button (default)
69
- return (
70
- <button
71
- role="tab"
72
- aria-selected={selected}
73
- className={className}
74
- onClick={onClick}
75
- disabled={disabled}
76
- {...props}
77
- >
78
- {content}
79
- </button>
80
- );
81
- }
@@ -1,116 +0,0 @@
1
- .ds-textarea-wrapper {
2
- display: flex;
3
- flex-direction: column;
4
- gap: var(--space-xs);
5
- }
6
-
7
- .ds-textarea-wrapper--full {
8
- width: 100%;
9
- }
10
-
11
- .ds-textarea-wrapper--disabled {
12
- opacity: 0.5;
13
- cursor: not-allowed;
14
- }
15
-
16
- .ds-textarea-label {
17
- font-size: var(--font-size-p2);
18
- font-weight: 400;
19
- color: var(--color-txt-icon-1);
20
- }
21
-
22
- .ds-textarea {
23
- width: 100%;
24
- font-family: inherit;
25
- color: var(--color-txt-icon-1);
26
- background-color: transparent;
27
- border: 1px solid var(--color-border);
28
- transition: border-color var(--transition-normal);
29
- line-height: 1.5;
30
- resize: vertical;
31
- /* Кастомный resize handle - 2 диагональные линии */
32
- background:
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
- background-repeat: no-repeat;
36
- background-position: bottom right;
37
- background-size: 16px 16px;
38
- }
39
-
40
- .ds-textarea::placeholder {
41
- color: var(--color-txt-icon-2);
42
- }
43
-
44
- .ds-textarea::-webkit-resizer {
45
- display: none;
46
- }
47
-
48
- .ds-textarea:hover:not(:disabled) {
49
- border-color: var(--color-border-hover);
50
- background:
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);
53
- background-repeat: no-repeat;
54
- background-position: bottom right;
55
- background-size: 16px 16px;
56
- }
57
-
58
- .ds-textarea:focus,
59
- .ds-textarea:active {
60
- outline: none;
61
- border-color: var(--color-border-hover);
62
- background:
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);
65
- background-repeat: no-repeat;
66
- background-position: bottom right;
67
- background-size: 16px 16px;
68
- }
69
-
70
- .ds-textarea:disabled {
71
- cursor: not-allowed;
72
- }
73
-
74
- .ds-textarea--error {
75
- border-color: var(--color-error);
76
- background:
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);
79
- background-repeat: no-repeat;
80
- background-position: bottom right;
81
- background-size: 16px 16px;
82
- }
83
-
84
- .ds-textarea--no-resize {
85
- resize: none;
86
- background: none;
87
- }
88
-
89
- /* Sizes */
90
- .ds-textarea--xs {
91
- padding: var(--space-xs);
92
- font-size: var(--font-size-p3);
93
- border-radius: var(--radius-xs);
94
- }
95
-
96
- .ds-textarea--s {
97
- padding: var(--space-xs) var(--space-s);
98
- font-size: var(--font-size-p2);
99
- border-radius: var(--radius-xs);
100
- }
101
-
102
- .ds-textarea--m {
103
- padding: var(--space-s);
104
- font-size: var(--font-size-p1);
105
- border-radius: var(--radius-s);
106
- }
107
-
108
- .ds-textarea-hint {
109
- font-size: var(--font-size-p2);
110
- color: var(--color-txt-icon-2);
111
- }
112
-
113
- .ds-textarea-error {
114
- font-size: var(--font-size-p2);
115
- color: var(--color-error);
116
- }
@@ -1,41 +0,0 @@
1
- import React from 'react';
2
- import './Textarea.css';
3
-
4
- export function Textarea({
5
- label,
6
- error,
7
- hint,
8
- fullWidth = true,
9
- size = 'm',
10
- disabled,
11
- id,
12
- resize = true,
13
- rows = 3,
14
- ...props
15
- }) {
16
- const textareaId = id || `textarea-${React.useId()}`;
17
- const hintId = hint ? `${textareaId}-hint` : undefined;
18
- const errorId = error ? `${textareaId}-error` : undefined;
19
- const describedBy = errorId || hintId;
20
-
21
- return (
22
- <div className={`ds-textarea-wrapper ${fullWidth ? 'ds-textarea-wrapper--full' : ''} ${disabled ? 'ds-textarea-wrapper--disabled' : ''}`}>
23
- {label && (
24
- <label className="ds-textarea-label" htmlFor={textareaId}>
25
- {label}
26
- </label>
27
- )}
28
- <textarea
29
- id={textareaId}
30
- className={`ds-textarea ds-textarea--${size} ${error ? 'ds-textarea--error' : ''} ${!resize ? 'ds-textarea--no-resize' : ''}`}
31
- disabled={disabled}
32
- aria-invalid={error ? 'true' : 'false'}
33
- aria-describedby={describedBy}
34
- rows={rows}
35
- {...props}
36
- />
37
- {hint && !error && <span id={hintId} className="ds-textarea-hint">{hint}</span>}
38
- {error && <span id={errorId} className="ds-textarea-error" role="alert">{error}</span>}
39
- </div>
40
- );
41
- }