@alfalab/core-components-switch 6.0.3 → 6.1.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.
- package/Component.d.ts +10 -0
- package/Component.js +15 -5
- package/Component.js.map +1 -1
- package/cssm/Component.d.ts +10 -0
- package/cssm/Component.js +17 -7
- package/cssm/Component.js.map +1 -1
- package/cssm/index.module.css +23 -3
- package/default.css +11 -11
- package/default.module.css.js +1 -1
- package/esm/Component.d.ts +10 -0
- package/esm/Component.js +15 -5
- package/esm/Component.js.map +1 -1
- package/esm/default.css +11 -11
- package/esm/default.module.css.js +1 -1
- package/esm/index.css +41 -21
- package/esm/index.module.css.js +1 -1
- package/esm/index.module.css.js.map +1 -1
- package/esm/inverted.css +11 -11
- package/esm/inverted.module.css.js +1 -1
- package/index.css +41 -21
- package/index.module.css.js +1 -1
- package/index.module.css.js.map +1 -1
- package/inverted.css +11 -11
- package/inverted.module.css.js +1 -1
- package/modern/Component.d.ts +10 -0
- package/modern/Component.js +14 -4
- package/modern/Component.js.map +1 -1
- package/modern/default.css +11 -11
- package/modern/default.module.css.js +1 -1
- package/modern/index.css +41 -21
- package/modern/index.module.css.js +1 -1
- package/modern/index.module.css.js.map +1 -1
- package/modern/inverted.css +11 -11
- package/modern/inverted.module.css.js +1 -1
- package/moderncssm/Component.d.ts +10 -0
- package/moderncssm/Component.js +14 -4
- package/moderncssm/Component.js.map +1 -1
- package/moderncssm/index.module.css +24 -3
- package/package.json +2 -1
- package/src/Component.tsx +43 -7
- package/src/index.module.css +27 -2
package/modern/index.css
CHANGED
|
@@ -12,10 +12,13 @@
|
|
|
12
12
|
--gap-3xs: 2px;
|
|
13
13
|
--gap-2xs: 4px;
|
|
14
14
|
--gap-s: 12px;
|
|
15
|
+
--gap-2s: 14px;
|
|
15
16
|
--gap-m: 16px;
|
|
16
17
|
--gap-0: 0px;
|
|
17
18
|
--gap-2: var(--gap-3xs);
|
|
18
19
|
--gap-4: var(--gap-2xs);
|
|
20
|
+
--gap-6: 6px;
|
|
21
|
+
--gap-10: 10px;
|
|
19
22
|
--gap-12: var(--gap-s);
|
|
20
23
|
--gap-16: var(--gap-m);
|
|
21
24
|
}
|
|
@@ -32,7 +35,7 @@
|
|
|
32
35
|
--switch-error-color: var(--color-light-text-negative);
|
|
33
36
|
--switch-icon-color: var(--color-static-neutral-0);
|
|
34
37
|
}
|
|
35
|
-
.
|
|
38
|
+
.switch__component_afshm {
|
|
36
39
|
display: inline-flex;
|
|
37
40
|
align-items: flex-start;
|
|
38
41
|
margin: var(--gap-0);
|
|
@@ -41,26 +44,27 @@
|
|
|
41
44
|
cursor: pointer;
|
|
42
45
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
43
46
|
}
|
|
44
|
-
.
|
|
47
|
+
.switch__component_afshm input {
|
|
45
48
|
opacity: 0;
|
|
46
49
|
position: absolute;
|
|
47
50
|
}
|
|
48
|
-
.
|
|
51
|
+
.switch__start_afshm {
|
|
49
52
|
align-items: flex-start;
|
|
50
53
|
}
|
|
51
|
-
.
|
|
54
|
+
.switch__center_afshm {
|
|
52
55
|
align-items: center;
|
|
53
56
|
}
|
|
54
|
-
.
|
|
57
|
+
.switch__addons_afshm {
|
|
55
58
|
margin-left: auto;
|
|
56
59
|
padding-left: var(--gap-16);
|
|
57
60
|
line-height: 24px;
|
|
58
61
|
}
|
|
59
|
-
.
|
|
62
|
+
.switch__block_afshm {
|
|
60
63
|
width: 100%;
|
|
61
64
|
}
|
|
62
|
-
.
|
|
65
|
+
.switch__switch_afshm {
|
|
63
66
|
position: relative;
|
|
67
|
+
display: block;
|
|
64
68
|
border-radius: var(--border-radius-16);
|
|
65
69
|
width: 36px;
|
|
66
70
|
height: 20px;
|
|
@@ -72,7 +76,12 @@
|
|
|
72
76
|
border-color 0.2s ease;
|
|
73
77
|
box-sizing: border-box;
|
|
74
78
|
}
|
|
75
|
-
.
|
|
79
|
+
.switch__switchSkeleton_afshm {
|
|
80
|
+
width: 36px;
|
|
81
|
+
height: 20px;
|
|
82
|
+
margin: var(--gap-2);
|
|
83
|
+
}
|
|
84
|
+
.switch__switch_afshm:before {
|
|
76
85
|
content: '';
|
|
77
86
|
position: absolute;
|
|
78
87
|
top: var(--gap-0);
|
|
@@ -85,54 +94,65 @@
|
|
|
85
94
|
box-sizing: border-box;
|
|
86
95
|
transition: transform 0.2s ease;
|
|
87
96
|
}
|
|
88
|
-
.
|
|
97
|
+
.switch__content_afshm {
|
|
89
98
|
margin-left: var(--gap-12);
|
|
90
99
|
flex-grow: 1;
|
|
91
100
|
}
|
|
92
|
-
.
|
|
101
|
+
.switch__label_afshm {
|
|
93
102
|
font-size: 16px;
|
|
94
103
|
line-height: 24px;
|
|
95
104
|
font-weight: 400;
|
|
96
105
|
font-family: var(--font-family-system);
|
|
97
106
|
display: block;
|
|
98
107
|
}
|
|
99
|
-
.
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
.
|
|
108
|
+
.switch__labelWrap_afshm:not(:only-child) {
|
|
109
|
+
margin-bottom: var(--gap-4);
|
|
110
|
+
}
|
|
111
|
+
.switch__labelWrap_afshm.switch__loading_afshm {
|
|
112
|
+
height: var(--gap-12);
|
|
113
|
+
margin: var(--gap-6) 0;
|
|
114
|
+
}
|
|
115
|
+
.switch__labelWrap_afshm.switch__loading_afshm:not(:only-child) {
|
|
116
|
+
margin-bottom: var(--gap-2s);
|
|
117
|
+
}
|
|
118
|
+
.switch__errorMessage_afshm {
|
|
103
119
|
font-size: 14px;
|
|
104
120
|
line-height: 18px;
|
|
105
121
|
font-weight: 400;
|
|
106
122
|
font-family: var(--font-family-system);
|
|
107
123
|
color: var(--switch-error-color);
|
|
108
124
|
}
|
|
109
|
-
.
|
|
125
|
+
.switch__hint_afshm {
|
|
110
126
|
font-size: 14px;
|
|
111
127
|
line-height: 18px;
|
|
112
128
|
font-weight: 400;
|
|
113
129
|
font-family: var(--font-family-system);
|
|
114
130
|
display: block;
|
|
115
131
|
}
|
|
116
|
-
.
|
|
132
|
+
.switch__hintWrap_afshm.switch__loading_afshm {
|
|
133
|
+
height: var(--gap-10);
|
|
134
|
+
margin-bottom: var(--gap-4);
|
|
135
|
+
}
|
|
136
|
+
.switch__component_afshm.switch__reversed_afshm {
|
|
117
137
|
flex-direction: row-reverse;
|
|
118
138
|
}
|
|
119
|
-
.
|
|
139
|
+
.switch__reversed_afshm .switch__content_afshm {
|
|
120
140
|
margin-right: var(--gap-16);
|
|
121
141
|
margin-left: var(--gap-0);
|
|
122
142
|
}
|
|
123
|
-
.
|
|
143
|
+
.switch__reversed_afshm .switch__addons_afshm {
|
|
124
144
|
margin-left: var(--gap-0);
|
|
125
145
|
padding-left: var(--gap-0);
|
|
126
146
|
margin-right: auto;
|
|
127
147
|
padding-right: var(--gap-16);
|
|
128
148
|
}
|
|
129
|
-
.
|
|
149
|
+
.switch__checked_afshm .switch__switch_afshm:before {
|
|
130
150
|
transform: translateX(16px);
|
|
131
151
|
}
|
|
132
|
-
.
|
|
152
|
+
.switch__disabled_afshm {
|
|
133
153
|
cursor: var(--disabled-cursor);
|
|
134
154
|
}
|
|
135
|
-
.
|
|
155
|
+
.switch__focused_afshm .switch__switch_afshm {
|
|
136
156
|
outline: 2px solid var(--focus-color);
|
|
137
157
|
outline-offset: 2px;
|
|
138
158
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './index.css';
|
|
2
2
|
|
|
3
|
-
const styles = {"component":"
|
|
3
|
+
const styles = {"component":"switch__component_afshm","start":"switch__start_afshm","center":"switch__center_afshm","addons":"switch__addons_afshm","block":"switch__block_afshm","switch":"switch__switch_afshm","switchSkeleton":"switch__switchSkeleton_afshm","content":"switch__content_afshm","label":"switch__label_afshm","labelWrap":"switch__labelWrap_afshm","loading":"switch__loading_afshm","errorMessage":"switch__errorMessage_afshm","hint":"switch__hint_afshm","hintWrap":"switch__hintWrap_afshm","reversed":"switch__reversed_afshm","checked":"switch__checked_afshm","disabled":"switch__disabled_afshm","focused":"switch__focused_afshm"};
|
|
4
4
|
|
|
5
5
|
export { styles as default };
|
|
6
6
|
//# sourceMappingURL=index.module.css.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n@import './vars.css';\n\n.component {\n display: inline-flex;\n align-items: flex-start;\n margin: var(--gap-0);\n padding: var(--gap-0);\n border: 0;\n cursor: pointer;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n.component input {\n opacity: 0;\n position: absolute;\n}\n\n.start {\n align-items: flex-start;\n}\n\n.center {\n align-items: center;\n}\n\n.addons {\n margin-left: auto;\n padding-left: var(--gap-16);\n line-height: 24px;\n}\n\n.block {\n width: 100%;\n}\n\n.switch {\n position: relative;\n border-radius: var(--border-radius-16);\n width: 36px;\n height: 20px;\n margin: var(--gap-2);\n flex-shrink: 0;\n border: 2px solid var(--switch-border-color);\n transition:\n background-color 0.2s ease,\n border-color 0.2s ease;\n box-sizing: border-box;\n}\n\n.switch:before {\n content: '';\n position: absolute;\n top: var(--gap-0);\n left: var(--gap-0);\n bottom: var(--gap-0);\n right: var(--gap-16);\n display: block;\n border-radius: var(--border-radius-circle);\n background-color: var(--switch-icon-color);\n box-sizing: border-box;\n transition: transform 0.2s ease;\n}\n\n.content {\n margin-left: var(--gap-12);\n flex-grow: 1;\n}\n\n.label {\n @mixin paragraph_primary_medium;\n display: block;\n}\n\n.
|
|
1
|
+
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n@import './vars.css';\n\n.component {\n display: inline-flex;\n align-items: flex-start;\n margin: var(--gap-0);\n padding: var(--gap-0);\n border: 0;\n cursor: pointer;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n.component input {\n opacity: 0;\n position: absolute;\n}\n\n.start {\n align-items: flex-start;\n}\n\n.center {\n align-items: center;\n}\n\n.addons {\n margin-left: auto;\n padding-left: var(--gap-16);\n line-height: 24px;\n}\n\n.block {\n width: 100%;\n}\n\n.switch {\n position: relative;\n display: block;\n border-radius: var(--border-radius-16);\n width: 36px;\n height: 20px;\n margin: var(--gap-2);\n flex-shrink: 0;\n border: 2px solid var(--switch-border-color);\n transition:\n background-color 0.2s ease,\n border-color 0.2s ease;\n box-sizing: border-box;\n}\n\n.switchSkeleton {\n width: 36px;\n height: 20px;\n margin: var(--gap-2);\n}\n\n.switch:before {\n content: '';\n position: absolute;\n top: var(--gap-0);\n left: var(--gap-0);\n bottom: var(--gap-0);\n right: var(--gap-16);\n display: block;\n border-radius: var(--border-radius-circle);\n background-color: var(--switch-icon-color);\n box-sizing: border-box;\n transition: transform 0.2s ease;\n}\n\n.content {\n margin-left: var(--gap-12);\n flex-grow: 1;\n}\n\n.label {\n @mixin paragraph_primary_medium;\n display: block;\n}\n\n.labelWrap {\n &:not(:only-child) {\n margin-bottom: var(--gap-4);\n }\n\n &.loading {\n height: var(--gap-12);\n margin: var(--gap-6) 0;\n\n &:not(:only-child) {\n margin-bottom: var(--gap-2s);\n }\n }\n}\n\n.errorMessage {\n @mixin paragraph_component_secondary;\n color: var(--switch-error-color);\n}\n\n.hint {\n @mixin paragraph_component_secondary;\n display: block;\n}\n\n.hintWrap {\n &.loading {\n height: var(--gap-10);\n margin-bottom: var(--gap-4);\n }\n}\n\n/* Reversed state */\n\n.component.reversed {\n flex-direction: row-reverse;\n}\n\n.reversed .content {\n margin-right: var(--gap-16);\n margin-left: var(--gap-0);\n}\n\n.reversed .addons {\n margin-left: var(--gap-0);\n padding-left: var(--gap-0);\n margin-right: auto;\n padding-right: var(--gap-16);\n}\n\n/* Checked state */\n\n.checked .switch:before {\n /* ширина компонента(36px + 2*2px) - отступы(2 * 2px) - размер кружка(20px) */\n transform: translateX(16px);\n}\n\n/* Disabled state */\n\n.disabled {\n cursor: var(--disabled-cursor);\n}\n\n/* Focused state */\n\n.focused .switch {\n @mixin focus-outline;\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,WAAW,CAAC,yBAAyB,CAAC,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,8BAA8B,CAAC,SAAS,CAAC,uBAAuB,CAAC,OAAO,CAAC,qBAAqB,CAAC,WAAW,CAAC,yBAAyB,CAAC,SAAS,CAAC,uBAAuB,CAAC,cAAc,CAAC,4BAA4B,CAAC,MAAM,CAAC,oBAAoB,CAAC,UAAU,CAAC,wBAAwB,CAAC,UAAU,CAAC,wBAAwB,CAAC,SAAS,CAAC,uBAAuB,CAAC,UAAU,CAAC,wBAAwB,CAAC,SAAS,CAAC,uBAAuB,CAAC;;;;"}
|
package/modern/inverted.css
CHANGED
|
@@ -20,36 +20,36 @@
|
|
|
20
20
|
--switch-disabled-checked-bg-inverted-color: var(--switch-disabled-bg-inverted-color);
|
|
21
21
|
--switch-icon-disabled-inverted-color: var(--color-light-neutral-translucent-500-inverted);
|
|
22
22
|
}
|
|
23
|
-
.
|
|
23
|
+
.switch__switch_11ccj {
|
|
24
24
|
background-color: var(--switch-bg-inverted-color);
|
|
25
25
|
}
|
|
26
|
-
.
|
|
26
|
+
.switch__switch_11ccj:hover {
|
|
27
27
|
background-color: var(--switch-hover-bg-inverted-color);
|
|
28
28
|
}
|
|
29
|
-
.
|
|
29
|
+
.switch__label_11ccj {
|
|
30
30
|
color: var(--switch-label-inverted-color);
|
|
31
31
|
}
|
|
32
|
-
.
|
|
32
|
+
.switch__hint_11ccj {
|
|
33
33
|
color: var(--switch-hint-inverted-color);
|
|
34
34
|
}
|
|
35
|
-
.
|
|
35
|
+
.switch__checked_11ccj .switch__switch_11ccj {
|
|
36
36
|
background-color: var(--switch-checked-bg-inverted-color);
|
|
37
37
|
}
|
|
38
|
-
.
|
|
38
|
+
.switch__checked_11ccj .switch__switch_11ccj:hover {
|
|
39
39
|
background-color: var(--switch-checked-hover-bg-inverted-color);
|
|
40
40
|
}
|
|
41
|
-
.
|
|
41
|
+
.switch__disabled_11ccj .switch__label_11ccj {
|
|
42
42
|
color: var(--switch-disabled-inverted-color);
|
|
43
43
|
}
|
|
44
|
-
.
|
|
44
|
+
.switch__disabled_11ccj .switch__hint_11ccj {
|
|
45
45
|
color: var(--switch-disabled-inverted-color);
|
|
46
46
|
}
|
|
47
|
-
.
|
|
47
|
+
.switch__disabled_11ccj .switch__switch_11ccj {
|
|
48
48
|
background-color: var(--switch-disabled-bg-inverted-color);
|
|
49
49
|
}
|
|
50
|
-
.
|
|
50
|
+
.switch__disabled_11ccj .switch__switch_11ccj:before {
|
|
51
51
|
background-color: var(--switch-icon-disabled-inverted-color);
|
|
52
52
|
}
|
|
53
|
-
.
|
|
53
|
+
.switch__disabled_11ccj.switch__checked_11ccj .switch__switch_11ccj {
|
|
54
54
|
background-color: var(--switch-disabled-checked-bg-inverted-color);
|
|
55
55
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './inverted.css';
|
|
2
2
|
|
|
3
|
-
const invertedStyles = {"switch":"
|
|
3
|
+
const invertedStyles = {"switch":"switch__switch_11ccj","label":"switch__label_11ccj","hint":"switch__hint_11ccj","checked":"switch__checked_11ccj","disabled":"switch__disabled_11ccj"};
|
|
4
4
|
|
|
5
5
|
export { invertedStyles as default };
|
|
6
6
|
//# sourceMappingURL=inverted.module.css.js.map
|
|
@@ -54,6 +54,11 @@ export type SwitchProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | '
|
|
|
54
54
|
* @default default
|
|
55
55
|
*/
|
|
56
56
|
colors?: Colors;
|
|
57
|
+
/**
|
|
58
|
+
* Показать скелетон
|
|
59
|
+
* @default false
|
|
60
|
+
*/
|
|
61
|
+
showSkeleton?: boolean;
|
|
57
62
|
};
|
|
58
63
|
export declare const Switch: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "hint" | "onChange" | "disabled" | "enterKeyHint"> & {
|
|
59
64
|
/**
|
|
@@ -108,5 +113,10 @@ export declare const Switch: React.ForwardRefExoticComponent<Omit<React.InputHTM
|
|
|
108
113
|
* @default default
|
|
109
114
|
*/
|
|
110
115
|
colors?: Colors;
|
|
116
|
+
/**
|
|
117
|
+
* Показать скелетон
|
|
118
|
+
* @default false
|
|
119
|
+
*/
|
|
120
|
+
showSkeleton?: boolean;
|
|
111
121
|
} & React.RefAttributes<HTMLLabelElement>>;
|
|
112
122
|
export {};
|
package/moderncssm/Component.js
CHANGED
|
@@ -2,6 +2,7 @@ import React, { forwardRef, useRef } from 'react';
|
|
|
2
2
|
import mergeRefs from 'react-merge-refs';
|
|
3
3
|
import cn from 'classnames';
|
|
4
4
|
import { dom } from '@alfalab/core-components-shared/moderncssm';
|
|
5
|
+
import { Skeleton } from '@alfalab/core-components-skeleton/moderncssm';
|
|
5
6
|
import { useFocus } from '@alfalab/hooks';
|
|
6
7
|
import defaultStyles from './default.module.css';
|
|
7
8
|
import styles from './index.module.css';
|
|
@@ -11,7 +12,7 @@ const colorStyles = {
|
|
|
11
12
|
default: defaultStyles,
|
|
12
13
|
inverted: invertedStyles,
|
|
13
14
|
};
|
|
14
|
-
const Switch = forwardRef(({ reversed = false, checked = false, align = 'start', addons, block, disabled, error, label, hint, name, value, className, onChange, dataTestId, colors = 'default', ...restProps }, ref) => {
|
|
15
|
+
const Switch = forwardRef(({ reversed = false, checked = false, align = 'start', addons, block, disabled, error, label, hint, name, value, className, onChange, dataTestId, colors = 'default', showSkeleton = false, ...restProps }, ref) => {
|
|
15
16
|
const labelRef = useRef(null);
|
|
16
17
|
const [focused] = useFocus(labelRef, 'keyboard');
|
|
17
18
|
const handleChange = (e) => {
|
|
@@ -30,10 +31,19 @@ const Switch = forwardRef(({ reversed = false, checked = false, align = 'start',
|
|
|
30
31
|
[styles.block]: block,
|
|
31
32
|
}), ref: mergeRefs([labelRef, ref]) },
|
|
32
33
|
React.createElement("input", { type: 'checkbox', onChange: handleChange, disabled: disabled, checked: checked, name: name, value: value, "data-test-id": dataTestId, ...restProps }),
|
|
33
|
-
React.createElement(
|
|
34
|
+
React.createElement(Skeleton, { visible: showSkeleton, borderRadius: 'pill', colors: colors, className: cn({
|
|
35
|
+
[styles.switchSkeleton]: showSkeleton,
|
|
36
|
+
}) },
|
|
37
|
+
React.createElement("span", { className: cn(styles.switch, colorStyles[colors].switch) })),
|
|
34
38
|
(label || hint || errorMessage) && (React.createElement("span", { className: styles.content },
|
|
35
|
-
label && (React.createElement(
|
|
36
|
-
|
|
39
|
+
label && (React.createElement(Skeleton, { visible: showSkeleton, borderRadius: 'pill', colors: colors, className: cn(styles.labelWrap, {
|
|
40
|
+
[styles.loading]: showSkeleton,
|
|
41
|
+
}) },
|
|
42
|
+
React.createElement("span", { className: cn(styles.label, colorStyles[colors].label) }, label))),
|
|
43
|
+
hint && !errorMessage && (React.createElement(Skeleton, { visible: showSkeleton, borderRadius: 'pill', colors: colors, className: cn(styles.hintWrap, {
|
|
44
|
+
[styles.loading]: showSkeleton,
|
|
45
|
+
}) },
|
|
46
|
+
React.createElement("span", { className: cn(styles.hint, colorStyles[colors].hint) }, hint))),
|
|
37
47
|
errorMessage && (React.createElement("span", { className: styles.errorMessage, role: 'alert' }, errorMessage)))),
|
|
38
48
|
addons && (
|
|
39
49
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n forwardRef,\n type InputHTMLAttributes,\n type ReactNode,\n useRef,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport cn from 'classnames';\n\nimport { dom } from '@alfalab/core-components-shared';\nimport { useFocus } from '@alfalab/hooks';\n\nimport { type Colors } from './types/colors';\n\nimport defaultStyles from './default.module.css';\nimport styles from './index.module.css';\nimport invertedStyles from './inverted.module.css';\n\nconst colorStyles = {\n default: defaultStyles,\n inverted: invertedStyles,\n};\n\ntype Align = 'start' | 'center';\n\nexport type SwitchProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'hint' | 'onChange' | 'disabled' | 'enterKeyHint'\n> & {\n /**\n * Управление состоянием вкл/выкл компонента\n */\n checked?: boolean;\n\n /**\n * Текст подписи к переключателю\n */\n label?: ReactNode;\n\n /**\n * Текст подсказки снизу\n */\n hint?: ReactNode;\n\n /**\n * Переключатель будет отрисован справа от контента\n */\n reversed?: boolean;\n\n /**\n * Выравнивание\n */\n align?: Align;\n\n /**\n * Дополнительный слот\n */\n addons?: React.ReactNode;\n\n /**\n * Растягивать ли компонент на всю ширину\n */\n block?: boolean;\n\n /**\n * Управление состоянием включен / выключен\n */\n disabled?: boolean;\n\n /**\n * Отображение ошибки\n */\n error?: ReactNode | boolean;\n\n /**\n * Обработчик переключения компонента\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: {\n checked: boolean;\n name: InputHTMLAttributes<HTMLInputElement>['name'];\n },\n ) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Набор цветов для компонента\n * @default default\n */\n colors?: Colors;\n};\n\nexport const Switch = forwardRef<HTMLLabelElement, SwitchProps>(\n (\n {\n reversed = false,\n checked = false,\n align = 'start',\n addons,\n block,\n disabled,\n error,\n label,\n hint,\n name,\n value,\n className,\n onChange,\n dataTestId,\n colors = 'default',\n ...restProps\n },\n ref,\n ) => {\n const labelRef = useRef<HTMLLabelElement>(null);\n\n const [focused] = useFocus(labelRef, 'keyboard');\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (onChange) {\n onChange(e, { checked: e.target.checked, name });\n }\n };\n\n const errorMessage = typeof error === 'boolean' ? '' : error;\n\n return (\n <label\n className={cn(styles.component, styles[align], className, {\n [styles.disabled]: disabled,\n [colorStyles[colors].disabled]: disabled,\n\n [styles.checked]: checked,\n [colorStyles[colors].checked]: checked,\n\n [styles.reversed]: reversed,\n [styles.focused]: focused,\n [styles.block]: block,\n })}\n ref={mergeRefs([labelRef, ref])}\n >\n <input\n type='checkbox'\n onChange={handleChange}\n disabled={disabled}\n checked={checked}\n name={name}\n value={value}\n data-test-id={dataTestId}\n {...restProps}\n />\n\n <span className={cn(styles.switch, colorStyles[colors].switch)} />\n\n {(label || hint || errorMessage) && (\n <span className={styles.content}>\n {label && (\n <span className={cn(styles.label, colorStyles[colors].label)}>\n
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n forwardRef,\n type InputHTMLAttributes,\n type ReactNode,\n useRef,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport cn from 'classnames';\n\nimport { dom } from '@alfalab/core-components-shared';\nimport { Skeleton } from '@alfalab/core-components-skeleton';\nimport { useFocus } from '@alfalab/hooks';\n\nimport { type Colors } from './types/colors';\n\nimport defaultStyles from './default.module.css';\nimport styles from './index.module.css';\nimport invertedStyles from './inverted.module.css';\n\nconst colorStyles = {\n default: defaultStyles,\n inverted: invertedStyles,\n};\n\ntype Align = 'start' | 'center';\n\nexport type SwitchProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'hint' | 'onChange' | 'disabled' | 'enterKeyHint'\n> & {\n /**\n * Управление состоянием вкл/выкл компонента\n */\n checked?: boolean;\n\n /**\n * Текст подписи к переключателю\n */\n label?: ReactNode;\n\n /**\n * Текст подсказки снизу\n */\n hint?: ReactNode;\n\n /**\n * Переключатель будет отрисован справа от контента\n */\n reversed?: boolean;\n\n /**\n * Выравнивание\n */\n align?: Align;\n\n /**\n * Дополнительный слот\n */\n addons?: React.ReactNode;\n\n /**\n * Растягивать ли компонент на всю ширину\n */\n block?: boolean;\n\n /**\n * Управление состоянием включен / выключен\n */\n disabled?: boolean;\n\n /**\n * Отображение ошибки\n */\n error?: ReactNode | boolean;\n\n /**\n * Обработчик переключения компонента\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: {\n checked: boolean;\n name: InputHTMLAttributes<HTMLInputElement>['name'];\n },\n ) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Набор цветов для компонента\n * @default default\n */\n colors?: Colors;\n\n /**\n * Показать скелетон\n * @default false\n */\n showSkeleton?: boolean;\n};\n\nexport const Switch = forwardRef<HTMLLabelElement, SwitchProps>(\n (\n {\n reversed = false,\n checked = false,\n align = 'start',\n addons,\n block,\n disabled,\n error,\n label,\n hint,\n name,\n value,\n className,\n onChange,\n dataTestId,\n colors = 'default',\n showSkeleton = false,\n ...restProps\n },\n ref,\n ) => {\n const labelRef = useRef<HTMLLabelElement>(null);\n\n const [focused] = useFocus(labelRef, 'keyboard');\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (onChange) {\n onChange(e, { checked: e.target.checked, name });\n }\n };\n\n const errorMessage = typeof error === 'boolean' ? '' : error;\n\n return (\n <label\n className={cn(styles.component, styles[align], className, {\n [styles.disabled]: disabled,\n [colorStyles[colors].disabled]: disabled,\n\n [styles.checked]: checked,\n [colorStyles[colors].checked]: checked,\n\n [styles.reversed]: reversed,\n [styles.focused]: focused,\n [styles.block]: block,\n })}\n ref={mergeRefs([labelRef, ref])}\n >\n <input\n type='checkbox'\n onChange={handleChange}\n disabled={disabled}\n checked={checked}\n name={name}\n value={value}\n data-test-id={dataTestId}\n {...restProps}\n />\n\n <Skeleton\n visible={showSkeleton}\n borderRadius='pill'\n colors={colors}\n className={cn({\n [styles.switchSkeleton]: showSkeleton,\n })}\n >\n <span className={cn(styles.switch, colorStyles[colors].switch)} />\n </Skeleton>\n\n {(label || hint || errorMessage) && (\n <span className={styles.content}>\n {label && (\n <Skeleton\n visible={showSkeleton}\n borderRadius='pill'\n colors={colors}\n className={cn(styles.labelWrap, {\n [styles.loading]: showSkeleton,\n })}\n >\n <span className={cn(styles.label, colorStyles[colors].label)}>\n {label}\n </span>\n </Skeleton>\n )}\n\n {hint && !errorMessage && (\n <Skeleton\n visible={showSkeleton}\n borderRadius='pill'\n colors={colors}\n className={cn(styles.hintWrap, {\n [styles.loading]: showSkeleton,\n })}\n >\n <span className={cn(styles.hint, colorStyles[colors].hint)}>\n {hint}\n </span>\n </Skeleton>\n )}\n\n {errorMessage && (\n <span className={styles.errorMessage} role='alert'>\n {errorMessage}\n </span>\n )}\n </span>\n )}\n\n {addons && (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions\n <span className={styles.addons} onClick={dom.preventDefault}>\n {addons}\n </span>\n )}\n </label>\n );\n },\n);\n\nSwitch.displayName = 'Switch';\n"],"names":[],"mappings":"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"}
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
.switch {
|
|
41
41
|
position: relative;
|
|
42
|
+
display: block;
|
|
42
43
|
border-radius: var(--border-radius-16);
|
|
43
44
|
width: 36px;
|
|
44
45
|
height: 20px;
|
|
@@ -51,6 +52,12 @@
|
|
|
51
52
|
box-sizing: border-box;
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
.switchSkeleton {
|
|
56
|
+
width: 36px;
|
|
57
|
+
height: 20px;
|
|
58
|
+
margin: var(--gap-2);
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
.switch:before {
|
|
55
62
|
content: '';
|
|
56
63
|
position: absolute;
|
|
@@ -78,9 +85,18 @@
|
|
|
78
85
|
display: block;
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
.
|
|
82
|
-
|
|
83
|
-
}
|
|
88
|
+
.labelWrap:not(:only-child) {
|
|
89
|
+
margin-bottom: var(--gap-4);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.labelWrap.loading {
|
|
93
|
+
height: var(--gap-12);
|
|
94
|
+
margin: var(--gap-6) 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.labelWrap.loading:not(:only-child) {
|
|
98
|
+
margin-bottom: var(--gap-2s);
|
|
99
|
+
}
|
|
84
100
|
|
|
85
101
|
.errorMessage {
|
|
86
102
|
font-size: 14px;
|
|
@@ -98,6 +114,11 @@
|
|
|
98
114
|
display: block;
|
|
99
115
|
}
|
|
100
116
|
|
|
117
|
+
.hintWrap.loading {
|
|
118
|
+
height: var(--gap-10);
|
|
119
|
+
margin-bottom: var(--gap-4);
|
|
120
|
+
}
|
|
121
|
+
|
|
101
122
|
.component.reversed {
|
|
102
123
|
flex-direction: row-reverse;
|
|
103
124
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfalab/core-components-switch",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"module": "./esm/index.js",
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@alfalab/core-components-shared": "^2.1.1",
|
|
14
|
+
"@alfalab/core-components-skeleton": "^7.0.2",
|
|
14
15
|
"@alfalab/hooks": "^1.13.1",
|
|
15
16
|
"classnames": "^2.5.1",
|
|
16
17
|
"react-merge-refs": "^1.1.0",
|
package/src/Component.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import mergeRefs from 'react-merge-refs';
|
|
|
9
9
|
import cn from 'classnames';
|
|
10
10
|
|
|
11
11
|
import { dom } from '@alfalab/core-components-shared';
|
|
12
|
+
import { Skeleton } from '@alfalab/core-components-skeleton';
|
|
12
13
|
import { useFocus } from '@alfalab/hooks';
|
|
13
14
|
|
|
14
15
|
import { type Colors } from './types/colors';
|
|
@@ -94,6 +95,12 @@ export type SwitchProps = Omit<
|
|
|
94
95
|
* @default default
|
|
95
96
|
*/
|
|
96
97
|
colors?: Colors;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Показать скелетон
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
showSkeleton?: boolean;
|
|
97
104
|
};
|
|
98
105
|
|
|
99
106
|
export const Switch = forwardRef<HTMLLabelElement, SwitchProps>(
|
|
@@ -114,6 +121,7 @@ export const Switch = forwardRef<HTMLLabelElement, SwitchProps>(
|
|
|
114
121
|
onChange,
|
|
115
122
|
dataTestId,
|
|
116
123
|
colors = 'default',
|
|
124
|
+
showSkeleton = false,
|
|
117
125
|
...restProps
|
|
118
126
|
},
|
|
119
127
|
ref,
|
|
@@ -156,19 +164,47 @@ export const Switch = forwardRef<HTMLLabelElement, SwitchProps>(
|
|
|
156
164
|
{...restProps}
|
|
157
165
|
/>
|
|
158
166
|
|
|
159
|
-
<
|
|
167
|
+
<Skeleton
|
|
168
|
+
visible={showSkeleton}
|
|
169
|
+
borderRadius='pill'
|
|
170
|
+
colors={colors}
|
|
171
|
+
className={cn({
|
|
172
|
+
[styles.switchSkeleton]: showSkeleton,
|
|
173
|
+
})}
|
|
174
|
+
>
|
|
175
|
+
<span className={cn(styles.switch, colorStyles[colors].switch)} />
|
|
176
|
+
</Skeleton>
|
|
160
177
|
|
|
161
178
|
{(label || hint || errorMessage) && (
|
|
162
179
|
<span className={styles.content}>
|
|
163
180
|
{label && (
|
|
164
|
-
<
|
|
165
|
-
{
|
|
166
|
-
|
|
181
|
+
<Skeleton
|
|
182
|
+
visible={showSkeleton}
|
|
183
|
+
borderRadius='pill'
|
|
184
|
+
colors={colors}
|
|
185
|
+
className={cn(styles.labelWrap, {
|
|
186
|
+
[styles.loading]: showSkeleton,
|
|
187
|
+
})}
|
|
188
|
+
>
|
|
189
|
+
<span className={cn(styles.label, colorStyles[colors].label)}>
|
|
190
|
+
{label}
|
|
191
|
+
</span>
|
|
192
|
+
</Skeleton>
|
|
167
193
|
)}
|
|
194
|
+
|
|
168
195
|
{hint && !errorMessage && (
|
|
169
|
-
<
|
|
170
|
-
{
|
|
171
|
-
|
|
196
|
+
<Skeleton
|
|
197
|
+
visible={showSkeleton}
|
|
198
|
+
borderRadius='pill'
|
|
199
|
+
colors={colors}
|
|
200
|
+
className={cn(styles.hintWrap, {
|
|
201
|
+
[styles.loading]: showSkeleton,
|
|
202
|
+
})}
|
|
203
|
+
>
|
|
204
|
+
<span className={cn(styles.hint, colorStyles[colors].hint)}>
|
|
205
|
+
{hint}
|
|
206
|
+
</span>
|
|
207
|
+
</Skeleton>
|
|
172
208
|
)}
|
|
173
209
|
|
|
174
210
|
{errorMessage && (
|
package/src/index.module.css
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
.switch {
|
|
38
38
|
position: relative;
|
|
39
|
+
display: block;
|
|
39
40
|
border-radius: var(--border-radius-16);
|
|
40
41
|
width: 36px;
|
|
41
42
|
height: 20px;
|
|
@@ -48,6 +49,12 @@
|
|
|
48
49
|
box-sizing: border-box;
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
.switchSkeleton {
|
|
53
|
+
width: 36px;
|
|
54
|
+
height: 20px;
|
|
55
|
+
margin: var(--gap-2);
|
|
56
|
+
}
|
|
57
|
+
|
|
51
58
|
.switch:before {
|
|
52
59
|
content: '';
|
|
53
60
|
position: absolute;
|
|
@@ -72,8 +79,19 @@
|
|
|
72
79
|
display: block;
|
|
73
80
|
}
|
|
74
81
|
|
|
75
|
-
.
|
|
76
|
-
|
|
82
|
+
.labelWrap {
|
|
83
|
+
&:not(:only-child) {
|
|
84
|
+
margin-bottom: var(--gap-4);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&.loading {
|
|
88
|
+
height: var(--gap-12);
|
|
89
|
+
margin: var(--gap-6) 0;
|
|
90
|
+
|
|
91
|
+
&:not(:only-child) {
|
|
92
|
+
margin-bottom: var(--gap-2s);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
77
95
|
}
|
|
78
96
|
|
|
79
97
|
.errorMessage {
|
|
@@ -86,6 +104,13 @@
|
|
|
86
104
|
display: block;
|
|
87
105
|
}
|
|
88
106
|
|
|
107
|
+
.hintWrap {
|
|
108
|
+
&.loading {
|
|
109
|
+
height: var(--gap-10);
|
|
110
|
+
margin-bottom: var(--gap-4);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
89
114
|
/* Reversed state */
|
|
90
115
|
|
|
91
116
|
.component.reversed {
|