@cloud-ru/ds-toggles 1.0.0

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 (106) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +201 -0
  3. package/README.md +492 -0
  4. package/dist/cjs/components/Checkbox/Checkbox.d.ts +8 -0
  5. package/dist/cjs/components/Checkbox/Checkbox.js +61 -0
  6. package/dist/cjs/components/Checkbox/index.d.ts +1 -0
  7. package/dist/cjs/components/Checkbox/index.js +17 -0
  8. package/dist/cjs/components/Checkbox/styles.module.css +223 -0
  9. package/dist/cjs/components/Favourite/Favourite.d.ts +9 -0
  10. package/dist/cjs/components/Favourite/Favourite.js +42 -0
  11. package/dist/cjs/components/Favourite/index.d.ts +1 -0
  12. package/dist/cjs/components/Favourite/index.js +17 -0
  13. package/dist/cjs/components/Favourite/styles.module.css +138 -0
  14. package/dist/cjs/components/Radio/Radio.d.ts +3 -0
  15. package/dist/cjs/components/Radio/Radio.js +34 -0
  16. package/dist/cjs/components/Radio/index.d.ts +1 -0
  17. package/dist/cjs/components/Radio/index.js +17 -0
  18. package/dist/cjs/components/Radio/styles.module.css +219 -0
  19. package/dist/cjs/components/Switch/Switch.d.ts +3 -0
  20. package/dist/cjs/components/Switch/Switch.js +42 -0
  21. package/dist/cjs/components/Switch/index.d.ts +1 -0
  22. package/dist/cjs/components/Switch/index.js +17 -0
  23. package/dist/cjs/components/Switch/styles.module.css +269 -0
  24. package/dist/cjs/components/ToggleGroup/ToggleGroup.d.ts +22 -0
  25. package/dist/cjs/components/ToggleGroup/ToggleGroup.js +33 -0
  26. package/dist/cjs/components/ToggleGroup/hooks.d.ts +9 -0
  27. package/dist/cjs/components/ToggleGroup/hooks.js +26 -0
  28. package/dist/cjs/components/ToggleGroup/index.d.ts +2 -0
  29. package/dist/cjs/components/ToggleGroup/index.js +18 -0
  30. package/dist/cjs/components/index.d.ts +5 -0
  31. package/dist/cjs/components/index.js +21 -0
  32. package/dist/cjs/constants.d.ts +23 -0
  33. package/dist/cjs/constants.js +26 -0
  34. package/dist/cjs/context.d.ts +9 -0
  35. package/dist/cjs/context.js +12 -0
  36. package/dist/cjs/index.d.ts +4 -0
  37. package/dist/cjs/index.js +20 -0
  38. package/dist/cjs/package.json +3 -0
  39. package/dist/cjs/style.css +849 -0
  40. package/dist/cjs/types.d.ts +57 -0
  41. package/dist/cjs/types.js +2 -0
  42. package/dist/cjs/utils.d.ts +3 -0
  43. package/dist/cjs/utils.js +22 -0
  44. package/dist/esm/components/Checkbox/Checkbox.d.ts +8 -0
  45. package/dist/esm/components/Checkbox/Checkbox.js +55 -0
  46. package/dist/esm/components/Checkbox/index.d.ts +1 -0
  47. package/dist/esm/components/Checkbox/index.js +1 -0
  48. package/dist/esm/components/Checkbox/styles.module.css +223 -0
  49. package/dist/esm/components/Favourite/Favourite.d.ts +9 -0
  50. package/dist/esm/components/Favourite/Favourite.js +36 -0
  51. package/dist/esm/components/Favourite/index.d.ts +1 -0
  52. package/dist/esm/components/Favourite/index.js +1 -0
  53. package/dist/esm/components/Favourite/styles.module.css +138 -0
  54. package/dist/esm/components/Radio/Radio.d.ts +3 -0
  55. package/dist/esm/components/Radio/Radio.js +28 -0
  56. package/dist/esm/components/Radio/index.d.ts +1 -0
  57. package/dist/esm/components/Radio/index.js +1 -0
  58. package/dist/esm/components/Radio/styles.module.css +219 -0
  59. package/dist/esm/components/Switch/Switch.d.ts +3 -0
  60. package/dist/esm/components/Switch/Switch.js +36 -0
  61. package/dist/esm/components/Switch/index.d.ts +1 -0
  62. package/dist/esm/components/Switch/index.js +1 -0
  63. package/dist/esm/components/Switch/styles.module.css +269 -0
  64. package/dist/esm/components/ToggleGroup/ToggleGroup.d.ts +22 -0
  65. package/dist/esm/components/ToggleGroup/ToggleGroup.js +30 -0
  66. package/dist/esm/components/ToggleGroup/hooks.d.ts +9 -0
  67. package/dist/esm/components/ToggleGroup/hooks.js +23 -0
  68. package/dist/esm/components/ToggleGroup/index.d.ts +2 -0
  69. package/dist/esm/components/ToggleGroup/index.js +2 -0
  70. package/dist/esm/components/index.d.ts +5 -0
  71. package/dist/esm/components/index.js +5 -0
  72. package/dist/esm/constants.d.ts +23 -0
  73. package/dist/esm/constants.js +23 -0
  74. package/dist/esm/context.d.ts +9 -0
  75. package/dist/esm/context.js +8 -0
  76. package/dist/esm/index.d.ts +4 -0
  77. package/dist/esm/index.js +4 -0
  78. package/dist/esm/style.css +849 -0
  79. package/dist/esm/types.d.ts +57 -0
  80. package/dist/esm/types.js +1 -0
  81. package/dist/esm/utils.d.ts +3 -0
  82. package/dist/esm/utils.js +18 -0
  83. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  84. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  85. package/package.json +46 -0
  86. package/src/components/Checkbox/Checkbox.tsx +140 -0
  87. package/src/components/Checkbox/index.ts +1 -0
  88. package/src/components/Checkbox/styles.module.scss +162 -0
  89. package/src/components/Favourite/Favourite.tsx +116 -0
  90. package/src/components/Favourite/index.ts +1 -0
  91. package/src/components/Favourite/styles.module.scss +138 -0
  92. package/src/components/Radio/Radio.tsx +84 -0
  93. package/src/components/Radio/index.ts +1 -0
  94. package/src/components/Radio/styles.module.scss +159 -0
  95. package/src/components/Switch/Switch.tsx +94 -0
  96. package/src/components/Switch/index.ts +1 -0
  97. package/src/components/Switch/styles.module.scss +250 -0
  98. package/src/components/ToggleGroup/ToggleGroup.tsx +71 -0
  99. package/src/components/ToggleGroup/hooks.ts +34 -0
  100. package/src/components/ToggleGroup/index.ts +2 -0
  101. package/src/components/index.ts +5 -0
  102. package/src/constants.ts +27 -0
  103. package/src/context.ts +18 -0
  104. package/src/index.ts +4 -0
  105. package/src/types.ts +80 -0
  106. package/src/utils.ts +21 -0
@@ -0,0 +1,250 @@
1
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
2
+ @use '@cloud-ru/ds-figma-variables/build/scss/components/toggles.module' as toggles;
3
+ @use '@cloud-ru/ds-materials' as m;
4
+
5
+ $sizes: 'xs', 's';
6
+ $switchAnimationDuration: 0.1s;
7
+ $iconRevealEasing: cubic-bezier(0.33, 1, 0.68, 1);
8
+
9
+ .spinner {
10
+ // По макету спиннер шире ползунка (24 на surface 16) и выходит за его границы,
11
+ // поэтому flex-контейнер не должен его ужимать.
12
+ flex-shrink: 0;
13
+ }
14
+
15
+ .icon {
16
+ pointer-events: none;
17
+
18
+ position: absolute;
19
+ transform: scale(0.72);
20
+
21
+ opacity: 0;
22
+
23
+ transition:
24
+ opacity $switchAnimationDuration $iconRevealEasing,
25
+ transform $switchAnimationDuration $iconRevealEasing,
26
+ color $switchAnimationDuration linear;
27
+ }
28
+
29
+ .surface[data-checked="true"]:not([data-loading="true"]) .icon {
30
+ transform: scale(1);
31
+ opacity: 1;
32
+ }
33
+
34
+ .inputPrivate {
35
+ cursor: pointer;
36
+
37
+ position: absolute;
38
+ inset: 0;
39
+
40
+ width: 100%;
41
+ height: 100%;
42
+ margin: 0;
43
+ padding: 0;
44
+
45
+ opacity: 0;
46
+
47
+ &:disabled {
48
+ cursor: not-allowed;
49
+ }
50
+ }
51
+
52
+ .backgroundStateLayer {
53
+ visibility: initial;
54
+ }
55
+
56
+ .flag {
57
+ position: absolute;
58
+ top: 50%;
59
+ left: 0;
60
+ transform: translateY(-50%);
61
+
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+
66
+ transition: left $switchAnimationDuration linear;
67
+ }
68
+
69
+ .framing {
70
+ position: relative;
71
+
72
+ display: flex;
73
+ align-items: center;
74
+
75
+ box-sizing: border-box;
76
+
77
+ outline-style: solid;
78
+
79
+ transition:
80
+ background-color $switchAnimationDuration linear,
81
+ outline-color $switchAnimationDuration linear;
82
+
83
+ &[data-checked="false"] {
84
+ background-color: base.$sn-theme-color-neutral-accent;
85
+ outline-color: base.$sn-theme-color-neutral-accent;
86
+ }
87
+
88
+ &[data-checked="true"] {
89
+ &[data-disabled="false"] {
90
+ background-color: base.$sn-theme-color-primary-accent;
91
+ outline-color: base.$sn-theme-color-primary-accent;
92
+ }
93
+
94
+ &[data-disabled="true"] {
95
+ background-color: base.$sn-theme-color-neutral-accent;
96
+ outline-color: base.$sn-theme-color-neutral-accent;
97
+ }
98
+ }
99
+
100
+ &[data-disabled="true"] {
101
+ opacity: base.$sn-theme-effect-opacity-disabled;
102
+ }
103
+ }
104
+
105
+ .container {
106
+ position: relative;
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ }
111
+
112
+ .surface {
113
+ position: relative;
114
+
115
+ display: flex;
116
+ align-items: center;
117
+ justify-content: center;
118
+
119
+ box-sizing: border-box;
120
+
121
+ transition:
122
+ width $switchAnimationDuration linear,
123
+ height $switchAnimationDuration linear,
124
+ background-color $switchAnimationDuration linear,
125
+ color $switchAnimationDuration linear;
126
+
127
+ &[data-checked="false"] {
128
+ &[data-loading="false"] {
129
+ // Ползунок лежит на дорожке `neutral/accent`, поэтому берёт парный `neutral/onAccent`.
130
+ background-color: base.$sn-theme-color-neutral-onAccent;
131
+ }
132
+
133
+ &[data-disabled="false"][data-loading="true"] {
134
+ // Спиннер лежит прямо на дорожке `neutral/accent` — берёт парный `neutral/onAccent`.
135
+ color: base.$sn-theme-color-neutral-onAccent;
136
+ }
137
+ }
138
+
139
+ &[data-checked="true"] {
140
+ &[data-loading="false"] {
141
+ // Кружок лежит на дорожке `primary/accent`, поэтому и цвет берётся из той же
142
+ // пары — `primary/onAccent` (#fbfffc), а не нейтральный белый.
143
+ background-color: base.$sn-theme-color-primary-onAccent;
144
+
145
+ &[data-disabled="false"] {
146
+ color: base.$sn-theme-color-primary-accent;
147
+ }
148
+
149
+ &[data-disabled="true"] {
150
+ color: base.$sn-theme-color-neutral-accent;
151
+ }
152
+ }
153
+
154
+ &[data-loading="true"] {
155
+ color: base.$sn-theme-color-primary-onAccent;
156
+ }
157
+ }
158
+ }
159
+
160
+ .root {
161
+ position: relative;
162
+
163
+ display: inline-flex;
164
+ flex-direction: row;
165
+ flex-grow: 0;
166
+ flex-shrink: 0;
167
+ align-items: center;
168
+
169
+ vertical-align: middle;
170
+
171
+ // Sizes
172
+ @each $size in $sizes {
173
+ &[data-size='#{$size}'] {
174
+ .container {
175
+ @include base.composite-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'container');
176
+ }
177
+
178
+ .framing {
179
+ // Pseudo-border
180
+ $offsetWidth: base.simple-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'border-width');
181
+
182
+ width: base.simple-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'min-width');
183
+ height: base.simple-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'min-height');
184
+ border-radius: base.simple-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'border-radius');
185
+
186
+ outline-width: $offsetWidth;
187
+ outline-offset: calc(0px - $offsetWidth);
188
+ }
189
+
190
+ .flag {
191
+ @include base.composite-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'flag');
192
+ }
193
+
194
+ .framing[data-checked="true"] .flag {
195
+ $flagTrackWidth: base.simple-var(
196
+ toggles.$toggles,
197
+ 'anatomy',
198
+ 'size',
199
+ $size,
200
+ 'switch',
201
+ 'framing',
202
+ 'flag',
203
+ 'min-width'
204
+ );
205
+
206
+ left: calc(100% - #{$flagTrackWidth});
207
+ }
208
+
209
+ &[data-focusvisible="true"] {
210
+ .container {
211
+ // Real offset
212
+ $offsetWidth: base.$sn-primitive-strokeWeight-strokeSemiBold;
213
+
214
+ @if ($size == 'xs') {
215
+ outline-offset: $offsetWidth;
216
+ }
217
+
218
+ border-radius: base.simple-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'border-radius');
219
+ outline: $offsetWidth solid base.$sn-theme-color-available-complementary;
220
+ }
221
+ }
222
+
223
+ &[data-checked="false"] {
224
+ .surface {
225
+ @include base.composite-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'flag', 'surface', 'checkedFalse');
226
+ }
227
+ }
228
+
229
+ &[data-checked="true"] {
230
+ .surface {
231
+ @include base.composite-var(toggles.$toggles, 'anatomy', 'size', $size, 'switch', 'framing', 'flag', 'surface', 'checkedTrue');
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ // States management
238
+ &[data-loading="false"][data-disabled="false"] {
239
+ .container {
240
+ @include m.has-state-layer-as-child(#{backgroundStateLayer});
241
+ }
242
+ }
243
+
244
+ &[data-loading="true"],
245
+ &[data-disabled="true"] {
246
+ .backgroundStateLayer {
247
+ visibility: hidden;
248
+ }
249
+ }
250
+ }
@@ -0,0 +1,71 @@
1
+ import { useUncontrolledProp } from '@cloud-ru/ds-utils';
2
+ import { PropsWithChildren, useCallback } from 'react';
3
+
4
+ import { SELECTION_MODE } from '../../constants';
5
+ import { ToggleGroupContext } from '../../context';
6
+
7
+ export type ToggleGroupProps = PropsWithChildren<
8
+ | {
9
+ /** Начальное состояние */
10
+ defaultValue?: string;
11
+ /** Controlled состояние */
12
+ value?: string;
13
+ /** Controlled обработчик измения состояния */
14
+ onChange?(value: (string | undefined) | string): void;
15
+ /** Режим выбора */
16
+ selectionMode?: typeof SELECTION_MODE.Single;
17
+ }
18
+ | {
19
+ /** Начальное состояние */
20
+ defaultValue?: string[];
21
+ /** Controlled состояние */
22
+ value?: string[];
23
+ /** Controlled обработчик измения состояния */
24
+ onChange?(value: (string[] | undefined) | string[]): void;
25
+ /** Режим выбора */
26
+ selectionMode?: typeof SELECTION_MODE.Multiple;
27
+ }
28
+ >;
29
+
30
+ export function ToggleGroup({
31
+ children,
32
+ value: valueProp,
33
+ onChange: onChangeProp,
34
+ selectionMode = SELECTION_MODE.Single,
35
+ defaultValue,
36
+ }: ToggleGroupProps) {
37
+ const [value, setValue] = useUncontrolledProp<string | string[] | undefined>(valueProp, defaultValue, cb => {
38
+ onChangeProp?.(cb(value));
39
+ });
40
+
41
+ const onChange = useCallback(
42
+ (newValue: string) => {
43
+ if (selectionMode === SELECTION_MODE.Single) {
44
+ return setValue((oldValue: string | undefined) => {
45
+ if (newValue !== oldValue) {
46
+ return newValue;
47
+ }
48
+
49
+ return undefined;
50
+ });
51
+ }
52
+
53
+ return setValue((oldValues: string[] | undefined = []) => {
54
+ if (Array.isArray(oldValues)) {
55
+ if (oldValues.includes(newValue)) {
56
+ return oldValues.filter(oldValue => oldValue !== newValue);
57
+ }
58
+
59
+ return oldValues.concat(newValue);
60
+ }
61
+
62
+ return undefined;
63
+ });
64
+ },
65
+ [selectionMode, setValue],
66
+ );
67
+
68
+ return (
69
+ <ToggleGroupContext.Provider value={{ value, onChange, selectionMode }}>{children}</ToggleGroupContext.Provider>
70
+ );
71
+ }
@@ -0,0 +1,34 @@
1
+ import { useCallback, useMemo } from 'react';
2
+
3
+ import { SELECTION_MODE } from '../../constants';
4
+ import { useToggleGroupContext } from '../../context';
5
+
6
+ type UseToggleGroupProps = {
7
+ value: string;
8
+ };
9
+
10
+ export function useToggleGroup({ value: itemValue }: UseToggleGroupProps) {
11
+ const { value, onChange, selectionMode } = useToggleGroupContext();
12
+
13
+ const isChecked = useMemo(() => {
14
+ if (typeof value === 'string') {
15
+ return value === itemValue;
16
+ }
17
+
18
+ if (Array.isArray(value)) {
19
+ return value.includes(itemValue);
20
+ }
21
+
22
+ return false;
23
+ }, [value, itemValue]);
24
+
25
+ const handleClick = useCallback(() => {
26
+ onChange?.(itemValue);
27
+ }, [itemValue, onChange]);
28
+
29
+ return {
30
+ isChecked,
31
+ handleClick,
32
+ multipleSelection: selectionMode === SELECTION_MODE.Multiple,
33
+ };
34
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ToggleGroup';
2
+ export * from './hooks';
@@ -0,0 +1,5 @@
1
+ export * from './Radio';
2
+ export * from './Checkbox';
3
+ export * from './Switch';
4
+ export * from './Favourite';
5
+ export * from './ToggleGroup';
@@ -0,0 +1,27 @@
1
+ export const MODE = {
2
+ Checkbox: 'checkbox',
3
+ Radio: 'radio',
4
+ } as const;
5
+
6
+ export const SIZE = {
7
+ XS: 'xs',
8
+ S: 's',
9
+ } as const;
10
+
11
+ export const FAVOURITE_ICON = {
12
+ Star: 'star',
13
+ Heart: 'heart',
14
+ } as const;
15
+
16
+ export const SELECTION_MODE = {
17
+ Single: 'single',
18
+ Multiple: 'multiple',
19
+ } as const;
20
+
21
+ /**
22
+ * Суффикс `data-test-id` нативного `<input>` внутри Checkbox/Radio/Switch/Favourite.
23
+ * Если потребитель передаёт `data-test-id='foo'` на корень, нативный input получает
24
+ * `data-test-id='foo-native-input'`. Константа публичная — потребитель и e2e helpers
25
+ * берут один и тот же суффикс из API пакета.
26
+ */
27
+ export const NATIVE_INPUT_SUFFIX = '-native-input';
package/src/context.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ import { SELECTION_MODE } from './constants';
4
+ import { SelectionMode } from './types';
5
+
6
+ type ToggleGroupContextType = {
7
+ value: string | undefined | string[];
8
+ onChange: ((id: string) => void) | undefined;
9
+ selectionMode: SelectionMode;
10
+ };
11
+
12
+ export const ToggleGroupContext = createContext<ToggleGroupContextType>({
13
+ value: undefined,
14
+ onChange: undefined,
15
+ selectionMode: SELECTION_MODE.Single,
16
+ });
17
+
18
+ export const useToggleGroupContext = () => useContext(ToggleGroupContext);
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './components';
2
+ export * from './constants';
3
+ export * from './types';
4
+ export * from './context';
package/src/types.ts ADDED
@@ -0,0 +1,80 @@
1
+ import { ValueOf, WithSupportProps } from '@cloud-ru/ds-utils';
2
+ import { FocusEventHandler, KeyboardEventHandler, MouseEventHandler, ReactNode, RefObject } from 'react';
3
+
4
+ import { FAVOURITE_ICON, MODE, SELECTION_MODE, SIZE } from './constants';
5
+
6
+ export type DataAttributes = Record<`data-${string}`, string | boolean>;
7
+
8
+ export type Size = ValueOf<typeof SIZE>;
9
+ export type Mode = ValueOf<typeof MODE>;
10
+ export type SelectionMode = ValueOf<typeof SELECTION_MODE>;
11
+ export type FavouriteIcon = ValueOf<typeof FAVOURITE_ICON>;
12
+
13
+ export type InputVisualState = {
14
+ focusVisible: boolean;
15
+ disabled: boolean;
16
+ checked: boolean;
17
+ hover: boolean;
18
+ size: Size;
19
+ };
20
+
21
+ type TogglePropsBase = WithSupportProps<{
22
+ /** Размер */
23
+ size?: Size;
24
+ /** Колбек рендера компонента */
25
+ render: (visualState: InputVisualState) => ReactNode;
26
+ /** HTML-аттрибут id */
27
+ id?: string;
28
+ /** Режим работы */
29
+ mode?: Mode;
30
+ /** HTML-аттрибут value */
31
+ value?: string;
32
+ /** HTML-аттрибут name */
33
+ name?: string;
34
+ /** HTML-аттрибут tab-index */
35
+ tabIndex?: number;
36
+ /** HTML-аттрибут autofocus */
37
+ autofocus?: boolean;
38
+ /** HTML-аттрибут checked */
39
+ checked?: boolean;
40
+ /** HTML-аттрибут checked по-умолчанию */
41
+ defaultChecked?: boolean;
42
+ /** HTML-аттрибут disabled */
43
+ disabled?: boolean;
44
+ /** Колбек смены значения */
45
+ onChange?: (checked: boolean) => void;
46
+ /** Колбек клика */
47
+ onClick?: MouseEventHandler<HTMLInputElement>;
48
+ /** Колбек потери фокуса */
49
+ onBlur?: FocusEventHandler<HTMLInputElement>;
50
+ /** Колбек приобретения фокуса */
51
+ onFocus?: FocusEventHandler<HTMLInputElement>;
52
+ /** Колбек нажатия клавиши клавиатуры */
53
+ onKeyUp?: KeyboardEventHandler<HTMLDivElement>;
54
+ /** CSS-класс */
55
+ className?: string;
56
+ }>;
57
+
58
+ export type ToggleProps = WithSupportProps<
59
+ Pick<
60
+ TogglePropsBase,
61
+ | 'id'
62
+ | 'name'
63
+ | 'value'
64
+ | 'tabIndex'
65
+ | 'autofocus'
66
+ | 'checked'
67
+ | 'defaultChecked'
68
+ | 'disabled'
69
+ | 'onChange'
70
+ | 'onClick'
71
+ | 'onBlur'
72
+ | 'onFocus'
73
+ | 'className'
74
+ | 'size'
75
+ > & {
76
+ inputRef?: RefObject<HTMLInputElement>;
77
+ /** Состояние загрузки */
78
+ loading?: boolean;
79
+ }
80
+ >;
package/src/utils.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { SIZE } from './constants';
2
+ import { DataAttributes, Size } from './types';
3
+
4
+ export function getVisualStateAttributes(state: Record<string, string | boolean>) {
5
+ return Object.entries(state).reduce<DataAttributes>(function (result, [name, value]) {
6
+ result[`data-${name.toLowerCase()}`] = value;
7
+ return result;
8
+ }, {});
9
+ }
10
+
11
+ export function getIconSize(size?: Size) {
12
+ switch (size) {
13
+ case SIZE.XS: {
14
+ return 16;
15
+ }
16
+ case SIZE.S:
17
+ default: {
18
+ return 24;
19
+ }
20
+ }
21
+ }