Skip to content

Commit eadc3d3

Browse files
Merge pull request #1086 from Yayo-Arellano/feature/ep-5383
feat: Add support for loading state on switch component #1085
2 parents 64156ce + cd5fcbb commit eadc3d3

55 files changed

Lines changed: 190 additions & 2 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/@next/Switch/Switch.stories.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default {
1717
const DefaultTemplate: Story = args => {
1818
const [checked, setChecked] = useState(args.checked);
1919
const [isDisabled, setIsDisabled] = useState(args.disabled);
20+
const [loading, setLoading] = useState(args.loading);
2021

2122
return (
2223
<>
@@ -25,10 +26,16 @@ const DefaultTemplate: Story = args => {
2526
label="Set disable"
2627
onChange={() => setIsDisabled(!isDisabled)}
2728
/>
29+
<Checkbox
30+
checked={loading}
31+
label="Set loading"
32+
onChange={() => setLoading(!loading)}
33+
/>
2834
<div>
2935
<Switch
3036
{...args}
3137
disabled={isDisabled}
38+
loading={loading}
3239
value={'switch'}
3340
onChange={() => setChecked(!checked)}
3441
/>
@@ -44,16 +51,24 @@ Default.args = {};
4451
const SwitchWithIconTemplate: Story = args => {
4552
const [checked, setChecked] = useState(args.checked);
4653
const [isDisabled, setIsDisabled] = useState(args.disabled);
54+
const [loading, setLoading] = useState(args.loading);
55+
4756
return (
4857
<>
4958
<div>The checkbox checked is {checked ? 'true' : 'false'}</div>
5059
<Checkbox
5160
label="Set disable"
5261
onChange={() => setIsDisabled(!isDisabled)}
5362
/>
63+
<Checkbox
64+
checked={loading}
65+
label="Set loading"
66+
onChange={() => setLoading(!loading)}
67+
/>
5468
<div>
5569
<Switch
5670
{...args}
71+
loading={loading}
5772
disabled={isDisabled}
5873
value={'switch'}
5974
onChange={() => setChecked(!checked)}
@@ -71,18 +86,26 @@ WithIcon.args = {};
7186
const SwitchWithTextTemplate: Story = args => {
7287
const [checked, setChecked] = useState(args.checked);
7388
const [isDisabled, setIsDisabled] = useState(args.disabled);
89+
const [loading, setLoading] = useState(args.loading);
90+
7491
return (
7592
<>
7693
<div>The checkbox checked is {checked ? 'true' : 'false'}</div>
7794
<Checkbox
7895
label="Set disable"
7996
onChange={() => setIsDisabled(!isDisabled)}
8097
/>
98+
<Checkbox
99+
checked={loading}
100+
label="Set loading"
101+
onChange={() => setLoading(!loading)}
102+
/>
81103
<div>
82104
<Switch
83105
{...args}
84106
disabled={isDisabled}
85107
value={'switch'}
108+
loading={loading}
86109
onChange={() => setChecked(!checked)}
87110
checkedText="Active"
88111
uncheckedText="Inactive"
@@ -99,19 +122,26 @@ WithText.args = {};
99122
const SwitchWithTextAndCustomBackgroundColorTemplate: Story = args => {
100123
const [checked, setChecked] = useState(args.checked);
101124
const [isDisabled, setIsDisabled] = useState(args.disabled);
125+
const [loading, setLoading] = useState(args.loading);
102126
return (
103127
<>
104128
<div>The checkbox checked is {checked ? 'true' : 'false'}</div>
105129
<Checkbox
106130
label="Set disable"
107131
onChange={() => setIsDisabled(!isDisabled)}
108132
/>
133+
<Checkbox
134+
checked={loading}
135+
label="Set loading"
136+
onChange={() => setLoading(!loading)}
137+
/>
109138
<div>
110139
<Switch
111140
{...args}
112141
disabled={isDisabled}
113142
value={'switch'}
114143
onChange={() => setChecked(!checked)}
144+
loading={loading}
115145
checkedText="Active"
116146
uncheckedText="Inactive"
117147
checkedBackgroundColor={Green.B61}

src/@next/Switch/Switch.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface SwitchProps
1212
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
1313
checked?: boolean;
1414
disabled?: boolean;
15+
loading?: boolean;
1516
onChange: () => void;
1617
value: string;
1718
withIcon?: boolean;
@@ -27,6 +28,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
2728
disabled,
2829
onChange,
2930
value,
31+
loading,
3032
withIcon,
3133
checkedText,
3234
uncheckedText,
@@ -74,7 +76,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
7476
<InputStyle
7577
value={value}
7678
{...otherProps}
77-
disabled={disabled}
79+
disabled={disabled || loading}
7880
checked={checked}
7981
type="checkbox"
8082
onChange={onChange}
@@ -85,6 +87,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
8587
/>
8688
<SwitchStyle
8789
data-disabled={disabled}
90+
data-loading={loading}
8891
data-with-icon={!withText && withIcon}
8992
data-with-text={withText}
9093
>

src/@next/Switch/SwitchStyle.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import styled from 'styled-components';
22
import { Breakpoints, Spacing, Typography } from '..';
33

44
import { Blue, Neutral } from '../utilities/colors';
5+
import { keyframes } from 'styled-components';
6+
7+
const spin = keyframes`
8+
to {
9+
transform: rotate(360deg);
10+
}
11+
`;
512

613
export const SwitchTextStyle = styled(Typography)``;
714

@@ -67,13 +74,25 @@ export const SwitchStyle = styled.div`
6774
right: 0;
6875
border-radius: 16px;
6976
background: ${Neutral.B100};
70-
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
77+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
7178
transform: scale(1);
7279
@media (max-width: ${Breakpoints.large}) {
7380
width: 14px;
7481
height: 14px;
7582
}
7683
}
84+
85+
&[data-loading='true']::before {
86+
border: 2px solid ${Neutral.B100};
87+
border-top-color: transparent;
88+
background: transparent;
89+
animation: ${spin} 0.6s linear infinite;
90+
transform: rotate(0deg);
91+
}
92+
93+
&[data-loading='true'] {
94+
pointer-events: none;
95+
}
7796
`;
7897

7998
export const InputStyle = styled.input<{

test/e2e/switch/switch-with-icon.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ test('disabled and checked', async ({ page }) => {
3232
);
3333
});
3434

35+
test('loading and unchecked', async ({ page }) => {
36+
const switchPage = getPage(page);
37+
await switchPage.goto('args=loading:true;checked:false');
38+
await expect(switchPage.container).toHaveScreenshot(
39+
'switch-loading-unchecked.png'
40+
);
41+
});
42+
43+
test('loading and checked', async ({ page }) => {
44+
const switchPage = getPage(page);
45+
await switchPage.goto('args=loading:true;checked:true');
46+
await expect(switchPage.container).toHaveScreenshot(
47+
'switch-loading-checked.png'
48+
);
49+
});
50+
3551
test('mobile - default', async ({ page }) => {
3652
page.setViewportSize({ width: 768, height: 600 });
3753
const switchPage = getPage(page);
@@ -65,3 +81,21 @@ test('mobile - disabled and checked', async ({ page }) => {
6581
'switch-mobile-disabled-checked.png'
6682
);
6783
});
84+
85+
test('mobile - loading and unchecked', async ({ page }) => {
86+
page.setViewportSize({ width: 768, height: 600 });
87+
const switchPage = getPage(page);
88+
await switchPage.goto('args=loading:true;checked:false');
89+
await expect(switchPage.container).toHaveScreenshot(
90+
'switch-mobile-loading-unchecked.png'
91+
);
92+
});
93+
94+
test('mobile - loading and checked', async ({ page }) => {
95+
page.setViewportSize({ width: 768, height: 600 });
96+
const switchPage = getPage(page);
97+
await switchPage.goto('args=loading:true;checked:true');
98+
await expect(switchPage.container).toHaveScreenshot(
99+
'switch-mobile-loading-checked.png'
100+
);
101+
});
2.29 KB
2.29 KB
2.49 KB
2.47 KB
9.47 KB
9.73 KB

0 commit comments

Comments
 (0)