@donkit-ai/design-system 0.2.15 → 0.2.17

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
@@ -41,6 +41,7 @@ npm install @donkit-ai/design-system@latest
41
41
  - **Tabs** - вкладки с состоянием selected в трех размерах (small, medium, large). Поддерживает `href` для рендера как ссылка
42
42
  - **Input** - текстовые поля с поддержкой иконок, ошибок и подсказок (small, medium)
43
43
  - **Stepper** - числовое поле с кнопками +/- для изменения значения (small, medium)
44
+ - **Toggle** - переключатель для включения/выключения опций (small, medium)
44
45
  - **Card** - карточки двух типов: info (информационная, прозрачный фон) и interactive (интерактивная с hover эффектом)
45
46
  - **Typography** - H1-H4, P1-P3 компоненты
46
47
  - **Code** - inline и block код с monospace шрифтом
@@ -547,6 +548,70 @@ import { AlertCircle } from 'lucide-react';
547
548
  - Small: 16px (Minus, Plus)
548
549
  - Medium: 20px (Minus, Plus)
549
550
 
551
+ ### Toggle
552
+
553
+ Переключатель для включения/выключения опций. Высота совпадает с другими элементами интерфейса.
554
+
555
+ ```jsx
556
+ // Basic toggle
557
+ <Toggle
558
+ checked={isEnabled}
559
+ onChange={setIsEnabled}
560
+ label="Enable notifications"
561
+ />
562
+
563
+ // Small size
564
+ <Toggle
565
+ size="small"
566
+ checked={isEnabled}
567
+ onChange={setIsEnabled}
568
+ label="Auto-save"
569
+ />
570
+
571
+ // Medium size (default)
572
+ <Toggle
573
+ size="medium"
574
+ checked={darkMode}
575
+ onChange={setDarkMode}
576
+ label="Dark mode"
577
+ />
578
+
579
+ // Without label (for tables/cards where context is clear)
580
+ <Toggle
581
+ checked={isEnabled}
582
+ onChange={setIsEnabled}
583
+ />
584
+
585
+ // Disabled states
586
+ <Toggle
587
+ checked={false}
588
+ onChange={() => {}}
589
+ label="Disabled unchecked"
590
+ disabled
591
+ />
592
+
593
+ <Toggle
594
+ checked={true}
595
+ onChange={() => {}}
596
+ label="Disabled checked"
597
+ disabled
598
+ />
599
+ ```
600
+
601
+ **Параметры:**
602
+ - `checked` - состояние переключателя (true/false)
603
+ - `onChange` - функция обработки изменения состояния, получает новое значение (boolean)
604
+ - `size` - размер: "small" или "medium" (default: "medium")
605
+ - `label` - текст подписи (опционально)
606
+ - `disabled` - отключить переключатель
607
+ - `id` - пользовательский ID (по умолчанию генерируется автоматически)
608
+
609
+ **Стиль:**
610
+ - Высота совпадает с Input, Select, Stepper (`--height-s` / `--height-m`)
611
+ - Ширина трека: 1.75x от высоты
612
+ - Включенное состояние: фон `--color-status-success`, border `--color-status-success` (зеленый)
613
+ - Выключенное состояние: фон `--color-item-bg`, border `--color-border`, hover `--color-border-hover`
614
+
550
615
  ### Card
551
616
 
552
617
  Карточки бывают двух типов:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donkit-ai/design-system",
3
- "version": "0.2.15",
3
+ "version": "0.2.17",
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,4 @@
1
1
  .ds-accordion {
2
- border: 1px solid var(--color-border);
3
2
  border-radius: var(--radius-s);
4
3
  overflow: hidden;
5
4
  }
@@ -39,5 +38,5 @@
39
38
 
40
39
  .ds-accordion__content {
41
40
  padding: var(--space-m);
42
- border-top: 1px solid var(--color-border);
41
+ background-color: var(--color-item-bg);
43
42
  }
@@ -1,5 +1,4 @@
1
1
  .ds-code-accordion {
2
- border: 1px solid var(--color-border);
3
2
  border-radius: var(--radius-s);
4
3
  overflow: hidden;
5
4
  }
@@ -43,7 +42,6 @@
43
42
  background-color: var(--color-code-bg);
44
43
  color: var(--color-txt-icon-1);
45
44
  padding: var(--space-xs);
46
- border-top: 1px solid var(--color-border);
47
45
  overflow-x: auto;
48
46
  line-height: 1.6;
49
47
  margin: 0;
@@ -65,4 +65,6 @@
65
65
  background-color: var(--color-bg);
66
66
  position: relative;
67
67
  z-index: 10;
68
+ border-bottom-left-radius: var(--space-s);
69
+ border-bottom-right-radius: var(--space-s);
68
70
  }
@@ -0,0 +1,91 @@
1
+ .ds-toggle {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: var(--space-s);
5
+ cursor: pointer;
6
+ }
7
+
8
+ .ds-toggle--disabled {
9
+ opacity: 0.5;
10
+ cursor: not-allowed;
11
+ }
12
+
13
+ .ds-toggle__input {
14
+ position: absolute;
15
+ opacity: 0;
16
+ pointer-events: none;
17
+ }
18
+
19
+ .ds-toggle__track {
20
+ position: relative;
21
+ display: flex;
22
+ align-items: center;
23
+ background-color: var(--color-item-bg);
24
+ border: 1px solid var(--color-border);
25
+ transition: background-color var(--transition-normal), border-color var(--transition-normal);
26
+ flex-shrink: 0;
27
+ }
28
+
29
+ .ds-toggle__input:checked + .ds-toggle__track {
30
+ background-color: var(--color-status-success);
31
+ border-color: var(--color-status-success);
32
+ }
33
+
34
+ .ds-toggle__input:not(:checked) + .ds-toggle__track:hover {
35
+ border-color: var(--color-border-hover);
36
+ }
37
+
38
+ .ds-toggle__thumb {
39
+ background-color: var(--color-white);
40
+ border-radius: 50%;
41
+ transition: transform var(--transition-normal);
42
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
43
+ }
44
+
45
+ .ds-toggle__label {
46
+ font-size: var(--font-size-p1);
47
+ color: var(--color-txt-icon-1);
48
+ user-select: none;
49
+ }
50
+
51
+ /* Small */
52
+ .ds-toggle--small .ds-toggle__track {
53
+ width: calc(var(--height-s) * 1.75);
54
+ height: var(--height-s);
55
+ border-radius: calc(var(--height-s) / 2);
56
+ padding: 3px;
57
+ }
58
+
59
+ .ds-toggle--small .ds-toggle__thumb {
60
+ width: calc(var(--height-s) - 8px);
61
+ height: calc(var(--height-s) - 8px);
62
+ }
63
+
64
+ .ds-toggle--small .ds-toggle__input:checked + .ds-toggle__track .ds-toggle__thumb {
65
+ transform: translateX(calc(var(--height-s) * 0.75));
66
+ }
67
+
68
+ .ds-toggle--small .ds-toggle__label {
69
+ font-size: var(--font-size-p2);
70
+ }
71
+
72
+ /* Medium */
73
+ .ds-toggle--medium .ds-toggle__track {
74
+ width: calc(var(--height-m) * 1.75);
75
+ height: var(--height-m);
76
+ border-radius: calc(var(--height-m) / 2);
77
+ padding: 4px;
78
+ }
79
+
80
+ .ds-toggle--medium .ds-toggle__thumb {
81
+ width: calc(var(--height-m) - 10px);
82
+ height: calc(var(--height-m) - 10px);
83
+ }
84
+
85
+ .ds-toggle--medium .ds-toggle__input:checked + .ds-toggle__track .ds-toggle__thumb {
86
+ transform: translateX(calc(var(--height-m) * 0.75));
87
+ }
88
+
89
+ .ds-toggle--medium .ds-toggle__label {
90
+ font-size: var(--font-size-p1);
91
+ }
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import './Toggle.css';
3
+
4
+ export function Toggle({
5
+ checked = false,
6
+ onChange,
7
+ size = 'medium',
8
+ disabled = false,
9
+ label,
10
+ id,
11
+ ...props
12
+ }) {
13
+ const toggleId = id || `toggle-${React.useId()}`;
14
+
15
+ const className = [
16
+ 'ds-toggle',
17
+ `ds-toggle--${size}`,
18
+ disabled && 'ds-toggle--disabled',
19
+ ].filter(Boolean).join(' ');
20
+
21
+ return (
22
+ <label className={className} htmlFor={toggleId}>
23
+ <input
24
+ type="checkbox"
25
+ id={toggleId}
26
+ className="ds-toggle__input"
27
+ checked={checked}
28
+ onChange={(e) => onChange?.(e.target.checked)}
29
+ disabled={disabled}
30
+ {...props}
31
+ />
32
+ <span className="ds-toggle__track">
33
+ <span className="ds-toggle__thumb" />
34
+ </span>
35
+ {label && <span className="ds-toggle__label">{label}</span>}
36
+ </label>
37
+ );
38
+ }
package/src/index.js CHANGED
@@ -19,3 +19,4 @@ export { Tabs, Tab } from './components/Tabs';
19
19
  export { Accordion } from './components/Accordion';
20
20
  export { CodeAccordion } from './components/CodeAccordion';
21
21
  export { Tooltip } from './components/Tooltip';
22
+ export { Toggle } from './components/Toggle';