Skip to content

Commit 77143ab

Browse files
authored
feat(Switch): add 's' size option and loading state support (#2438)
1 parent 5ff5047 commit 77143ab

File tree

15 files changed

+132
-12
lines changed

15 files changed

+132
-12
lines changed

src/components/Checkbox/Checkbox.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import * as React from 'react';
44

55
import {useCheckbox} from '../../hooks/private';
66
import {ControlLabel} from '../ControlLabel';
7-
import type {ControlLabelSize} from '../ControlLabel';
87
import type {ControlProps, DOMProps, QAProps} from '../types';
98
import {block} from '../utils/cn';
109

@@ -13,7 +12,7 @@ import {CheckboxTickIcon} from './CheckboxTickIcon';
1312

1413
import './Checkbox.scss';
1514

16-
export type CheckboxSize = ControlLabelSize;
15+
export type CheckboxSize = 'm' | 'l' | 'xl';
1716

1817
export interface CheckboxProps extends ControlProps, DOMProps, QAProps {
1918
size?: CheckboxSize;

src/components/ControlLabel/ControlLabel.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ $block: '.#{variables.$ns}control-label';
1717
pointer-events: none;
1818
}
1919

20+
&_size_s,
2021
&_size_m {
2122
font-size: var(--g-text-body-1-font-size);
2223
line-height: 15px;

src/components/ControlLabel/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type {DOMProps, QAProps} from '../types';
22

3-
export type Size = 'm' | 'l' | 'xl';
3+
export type Size = 's' | 'm' | 'l' | 'xl';
44

55
export type Props = React.PropsWithChildren<{
66
labelClassName?: string;

src/components/Radio/Radio.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ import * as React from 'react';
44

55
import {useRadio} from '../../hooks/private';
66
import {ControlLabel} from '../ControlLabel';
7-
import type {ControlLabelSize} from '../ControlLabel';
87
import type {ControlProps, DOMProps, QAProps} from '../types';
98
import {block} from '../utils/cn';
109

1110
import './Radio.scss';
1211

1312
const b = block('radio');
1413

15-
export type RadioSize = ControlLabelSize;
14+
export type RadioSize = 'm' | 'l' | 'xl';
1615

1716
export interface RadioProps extends ControlProps, DOMProps, QAProps {
1817
value: string;

src/components/Switch/README-ru.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ LANDING_BLOCK-->
5151
5252
<ExampleBlock
5353
code={`
54+
<Switch size="s">S Size</Switch>
5455
<Switch size="m">M Size</Switch>
5556
<Switch size="l">L Size</Switch>
5657
`}
5758
>
59+
<UIKit.Switch size="s">S Size</UIKit.Switch>
5860
<UIKit.Switch size="m">M Size</UIKit.Switch>
5961
<UIKit.Switch size="l">L Size</UIKit.Switch>
6062
</ExampleBlock>
@@ -64,6 +66,7 @@ LANDING_BLOCK-->
6466
<!--GITHUB_BLOCK-->
6567

6668
```tsx
69+
<Switch size="s">S Size</Switch>
6770
<Switch size="m">M Size</Switch>
6871
<Switch size="l">L Size</Switch>
6972
```
@@ -134,13 +137,14 @@ LANDING_BLOCK-->
134137
| children | Содержимое переключателя (как правило, лейбл). | `ReactNode` | |
135138
| content | Содержимое переключателя (альтернатива `children`). | `ReactNode` | |
136139
| disabled | Включает или отключает состояние `disabled` у переключателя. | `boolean` | `false` |
140+
| loading | Включает или отключает состояние загрузки у переключателя. | `boolean` | `false` |
137141
| checked | Включает или отключает состояние `checked` у переключателя. | `boolean` | `false` |
138142
| defaultChecked | Задает начальное состояние `checked` при монтировании компонента. | `boolean` | `false` |
139143
| onUpdate | Срабатывает при изменении состояния переключателя пользователем и передает значение `checked` как аргумент обратного вызова. | `(checked: boolean) => void` | |
140144
| onChange | Срабатывает при изменении состояния переключателя пользователем и передает событие изменения как аргумент обратного вызова. | `Function` | |
141145
| onFocus | Обработчик события, вызываемый, когда элемент ввода переключателя получает фокус. | `Function` | |
142146
| onBlur | Обработчик события, вызываемый, когда элемент ввода переключателя теряет фокус. | `Function` | |
143-
| size | Определяет размер переключателя. | `m` `l` | `m` |
147+
| size | Определяет размер переключателя. | `s` `m` `l` | `m` |
144148
| id | HTML-атрибут `id`. | `string` | |
145149
| qa | HTML-атрибут `data-qa`, используется для тестирования. | `string` | |
146150
| style | HTML-атрибут `style`. | `React.CSSProperties` | |

src/components/Switch/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ Use the `size` property to manage the `Switch` size. The default size is `m`.
5151
5252
<ExampleBlock
5353
code={`
54+
<Switch size="s">S Size</Switch>
5455
<Switch size="m">M Size</Switch>
5556
<Switch size="l">L Size</Switch>
5657
`}
5758
>
59+
<UIKit.Switch size="s">S Size</UIKit.Switch>
5860
<UIKit.Switch size="m">M Size</UIKit.Switch>
5961
<UIKit.Switch size="l">L Size</UIKit.Switch>
6062
</ExampleBlock>
@@ -64,6 +66,7 @@ LANDING_BLOCK-->
6466
<!--GITHUB_BLOCK-->
6567

6668
```tsx
69+
<Switch size="s">S Size</Switch>
6770
<Switch size="m">M Size</Switch>
6871
<Switch size="l">L Size</Switch>
6972
```
@@ -134,13 +137,14 @@ LANDING_BLOCK-->
134137
| children | The content of the switch (usually, a label) | `ReactNode` | |
135138
| content | The content of the switch (alternative to children) | `ReactNode` | |
136139
| disabled | Toggles the `disabled` state of the switch | `boolean` | `false` |
140+
| loading | Toggles the `loading` state of the switch | `boolean` | `false` |
137141
| checked | Toggles the `checked` state of the switch | `boolean` | `false` |
138142
| defaultChecked | Sets the initial checked state when the component is mounted | `boolean` | `false` |
139143
| onUpdate | Fires when the switch state is changed by the user and provides the checked value as a callback argument | `(checked: boolean) => void` | |
140144
| onChange | Fires when the switch state is changed by the user and provides the change event as a callback argument | `Function` | |
141145
| onFocus | Event handler to use when the switch input element receives focus | `Function` | |
142146
| onBlur | Event handler to use when the switch input element loses focus | `Function` | |
143-
| size | Sets the size of the switch | `m` `l` | `m` |
147+
| size | Sets the size of the switch | `s` `m` `l` | `m` |
144148
| id | `id` HTML attribute | `string` | |
145149
| qa | `data-qa` HTML attribute, used for testing | `string` | |
146150
| style | `style` HTML attribute | `React.CSSProperties` | |

src/components/Switch/Switch.scss

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,53 @@ $block: '.#{variables.$ns}switch';
5151
outline: 2px solid var(--g-color-line-focus);
5252
}
5353

54+
&_loading {
55+
#{$block}__slider::after {
56+
content: '';
57+
position: absolute;
58+
box-sizing: border-box;
59+
60+
border-radius: 50%;
61+
62+
inset-inline-start: 2px;
63+
inset-block-start: 2px;
64+
65+
border-color: var(--g-color-base-generic-accent);
66+
border-style: solid;
67+
border-block-start-color: transparent;
68+
69+
animation: #{variables.$ns}spin 1s linear infinite;
70+
71+
@media (prefers-reduced-motion: reduce) {
72+
animation: none;
73+
}
74+
}
75+
}
76+
5477
&_size {
78+
&_s {
79+
#{$block}__indicator,
80+
#{$block}__indicator::before,
81+
#{$block}__outline {
82+
width: 28px;
83+
height: 16px;
84+
border-radius: 10px;
85+
}
86+
87+
#{$block}__slider {
88+
inset-block-start: 2px;
89+
inset-inline-start: 2px;
90+
width: 12px;
91+
height: 12px;
92+
93+
&::after {
94+
width: 8px;
95+
height: 8px;
96+
border-width: 2px;
97+
}
98+
}
99+
}
100+
55101
&_m {
56102
#{$block}__indicator,
57103
#{$block}__indicator::before,
@@ -66,6 +112,12 @@ $block: '.#{variables.$ns}switch';
66112
inset-inline-start: 2px;
67113
width: 16px;
68114
height: 16px;
115+
116+
&::after {
117+
width: 12px;
118+
height: 12px;
119+
border-width: 2px;
120+
}
69121
}
70122

71123
#{$block}__text {
@@ -87,6 +139,12 @@ $block: '.#{variables.$ns}switch';
87139
inset-inline-start: 3px;
88140
width: 18px;
89141
height: 18px;
142+
143+
&::after {
144+
width: 14px;
145+
height: 14px;
146+
border-width: 2px;
147+
}
90148
}
91149

92150
#{$block}__text {
@@ -106,6 +164,15 @@ $block: '.#{variables.$ns}switch';
106164
transform: translateX(var(--_--translate-x));
107165
}
108166

167+
&_checked {
168+
&#{$block}_loading {
169+
#{$block}__slider::after {
170+
border-color: var(--g-color-base-brand);
171+
border-block-start-color: transparent;
172+
}
173+
}
174+
}
175+
109176
&_checked,
110177
&_checked:hover {
111178
#{$block}__indicator::before {
@@ -124,5 +191,20 @@ $block: '.#{variables.$ns}switch';
124191
opacity: 0.5;
125192
}
126193
}
194+
195+
#{$block}__slider {
196+
&::after {
197+
opacity: 0.5;
198+
}
199+
}
200+
}
201+
}
202+
203+
@keyframes #{variables.$ns}spin {
204+
from {
205+
transform: rotate(0deg);
206+
}
207+
to {
208+
transform: rotate(360deg);
127209
}
128210
}

src/components/Switch/Switch.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,35 @@ import * as React from 'react';
44

55
import {useCheckbox} from '../../hooks/private';
66
import {ControlLabel} from '../ControlLabel';
7-
import type {ControlLabelSize} from '../ControlLabel';
87
import type {ControlProps, DOMProps, QAProps} from '../types';
98
import {block} from '../utils/cn';
109

1110
import './Switch.scss';
1211

1312
const b = block('switch');
1413

15-
export type SwitchSize = ControlLabelSize;
14+
export type SwitchSize = 's' | 'm' | 'l';
1615

1716
export interface SwitchProps extends ControlProps, DOMProps, QAProps {
1817
size?: SwitchSize;
18+
loading?: boolean;
1919
content?: React.ReactNode;
2020
children?: React.ReactNode;
2121
title?: string;
2222
}
2323

2424
export const Switch = React.forwardRef<HTMLLabelElement, SwitchProps>(function Switch(props, ref) {
25-
const {size = 'm', disabled = false, content, children, title, style, className, qa} = props;
25+
const {
26+
size = 'm',
27+
disabled = false,
28+
loading = false,
29+
content,
30+
children,
31+
title,
32+
style,
33+
className,
34+
qa,
35+
} = props;
2636
const {checked, inputProps} = useCheckbox({
2737
...props,
2838
controlProps: {...props.controlProps, role: 'switch'},
@@ -49,6 +59,7 @@ export const Switch = React.forwardRef<HTMLLabelElement, SwitchProps>(function S
4959
size,
5060
disabled,
5161
checked,
62+
loading,
5263
},
5364
className,
5465
)}
3.46 KB
Loading
3.26 KB
Loading

0 commit comments

Comments
 (0)