Skip to content

Commit f10c765

Browse files
🪟 🎨 Aligns Switch design according to the latest Figma updates (#20629)
* Aligns Switch design according to the latest Figma updates * Updates snapshots tests, after adding aria-checked property for switch input; Adds mixed UI state for Switch component
1 parent 3631418 commit f10c765

File tree

13 files changed

+142
-62
lines changed

13 files changed

+142
-62
lines changed

airbyte-webapp/src/components/CreateConnection/__snapshots__/CreateConnectionForm.test.tsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ exports[`CreateConnectionForm should render 1`] = `
676676
class="<removed-for-snapshot-test>"
677677
>
678678
<input
679+
aria-checked="true"
679680
checked=""
680681
class="<removed-for-snapshot-test>"
681682
data-testid="pokemon-stream-sync-switch"

airbyte-webapp/src/components/LabeledSwitch/LabeledSwitch.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Switch } from "components/ui/Switch";
66

77
import styles from "./LabeledSwitch.module.scss";
88

9-
interface LabeledSwitchProps extends React.InputHTMLAttributes<HTMLInputElement> {
9+
interface LabeledSwitchProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
1010
message?: React.ReactNode;
1111
label?: React.ReactNode;
1212
checkbox?: boolean;

airbyte-webapp/src/components/connection/CatalogTree/BulkHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const BulkHeader: React.FC = () => {
8282
<CheckboxCell />
8383
<ArrowCell />
8484
<HeaderCell flex={0.4}>
85-
<Switch small checked={options.selected} onChange={() => onChangeOption({ selected: !options.selected })} />
85+
<Switch size="sm" checked={options.selected} onChange={() => onChangeOption({ selected: !options.selected })} />
8686
</HeaderCell>
8787
<HeaderCell />
8888
<HeaderCell />

airbyte-webapp/src/components/connection/CatalogTree/FieldRow.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ const FieldRowInner: React.FC<FieldRowProps> = ({
6161
<Cell flex={0}>
6262
<SyncCheckboxContainer>
6363
{!isNestedField && (
64-
<Switch small checked={isSelected} onChange={() => onToggleFieldSelected(field.path, !isSelected)} />
64+
<Switch size="sm" checked={isSelected} onChange={() => onToggleFieldSelected(field.path, !isSelected)} />
6565
)}
6666
{isNestedField && (
67-
<Tooltip control={<Switch small disabled checked={isSelected} />}>
67+
<Tooltip control={<Switch size="sm" disabled checked={isSelected} />}>
6868
<FormattedMessage id="form.field.sync.nestedFieldTooltip" values={{ fieldName: field.path[0] }} />
6969
</Tooltip>
7070
)}

airbyte-webapp/src/components/connection/CatalogTree/StreamHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export const StreamHeader: React.FC<StreamHeaderProps> = ({
118118
<div className={streamHeaderContentStyle}>
119119
<HeaderCell flex={0.4}>
120120
<Switch
121-
small
121+
size="sm"
122122
checked={stream.config?.selected}
123123
onChange={onSelectStream}
124124
disabled={disabled}

airbyte-webapp/src/components/connection/CatalogTree/next/BulkEditPanel.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,12 @@ export const BulkEditPanel: React.FC = () => {
112112
<FormattedMessage id="sources.sync" />
113113
</p>
114114
<div className={styles.syncCellContent}>
115-
<Switch small checked={options.selected} onChange={() => onChangeOption({ selected: !options.selected })} />
115+
<Switch
116+
variant="strong-blue"
117+
size="sm"
118+
checked={options.selected}
119+
onChange={() => onChangeOption({ selected: !options.selected })}
120+
/>
116121
</div>
117122
</HeaderCell>
118123
<HeaderCell flex={1} className={styles.headerCell}>

airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const CatalogTreeTableRow: React.FC<StreamHeaderProps> = ({
6565
</div>
6666
)}
6767
<Cell flex={0.5} flush>
68-
<Switch small checked={stream.config?.selected} onChange={onSelectStream} disabled={disabled} />
68+
<Switch size="sm" checked={stream.config?.selected} onChange={onSelectStream} disabled={disabled} />
6969
</Cell>
7070
{/* <Cell>{fieldCount}</Cell> */}
7171
<Cell flex={1} title={stream.stream?.namespace || ""}>

airbyte-webapp/src/components/connection/CatalogTree/next/StreamDetailsPanel/StreamPanelHeader/StreamPanelHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const StreamPanelHeader: React.FC<StreamPanelHeaderProps> = ({
5151
return (
5252
<div className={styles.container}>
5353
<div>
54-
<Switch small checked={config?.selected} onChange={onSelectedChange} disabled={disabled} />
54+
<Switch size="sm" checked={config?.selected} onChange={onSelectedChange} disabled={disabled} />
5555
</div>
5656
<div className={styles.properties}>
5757
<StreamProperty

airbyte-webapp/src/components/connection/CatalogTree/next/__snapshots__/BulkEditPanel.test.tsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ exports[`<BulkEditPanel /> should render 1`] = `
3535
class="<removed-for-snapshot-test>"
3636
>
3737
<input
38+
aria-checked="false"
3839
class="<removed-for-snapshot-test>"
3940
type="checkbox"
4041
value=""

airbyte-webapp/src/components/ui/Switch/Switch.module.scss

Lines changed: 96 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,63 @@
22
@use "scss/variables";
33
@use "scss/z-indices";
44

5-
@mixin knob-transform($position, $small: false) {
5+
@mixin knob-transform($position, $size) {
66
@if $position == left {
77
transform: translateX(0);
8-
} @else if $small {
9-
transform: translateX(10px);
8+
} @else if $position == middle {
9+
@if $size == lg {
10+
transform: translateX(8px);
11+
}
12+
@if $size == sm {
13+
transform: translateX(4.5px);
14+
}
15+
@if $size == xs {
16+
transform: translateX(3.5px);
17+
}
1018
} @else {
11-
transform: translateX(18px);
19+
@if $size == lg {
20+
transform: translateX(16px);
21+
}
22+
@if $size == sm {
23+
transform: translateX(9px);
24+
}
25+
@if $size == xs {
26+
transform: translateX(7px);
27+
}
28+
}
29+
}
30+
31+
@mixin all-sizes-knob-transform($position) {
32+
&.sizeLg::before {
33+
@include knob-transform($position, lg);
34+
}
35+
36+
&.sizeSm::before {
37+
@include knob-transform($position, sm);
38+
}
39+
40+
&.sizeXs::before {
41+
@include knob-transform($position, xs);
1242
}
1343
}
1444

1545
.switch {
1646
position: relative;
1747
display: inline-block;
18-
width: 42px;
19-
height: 26px;
2048

21-
&.small {
22-
width: 28px;
23-
height: 18px;
49+
&.sizeLg {
50+
width: 42px;
51+
height: 26px;
52+
}
53+
54+
&.sizeSm {
55+
width: 25px;
56+
height: 16px;
57+
}
58+
59+
&.sizeXs {
60+
width: 17px;
61+
height: 10px;
2462
}
2563

2664
.slider {
@@ -33,25 +71,39 @@
3371
background: colors.$grey-100;
3472
transition: variables.$transition;
3573
border-radius: variables.$border-radius-pill;
36-
border: 1px solid colors.$grey-200;
3774

38-
&.small::before {
39-
height: 16px;
40-
width: 16px;
75+
&.sizeLg {
76+
border: 1px solid colors.$grey-200;
77+
}
78+
79+
&.sizeLg::before {
80+
width: 24px;
81+
height: 24px;
82+
left: 0;
83+
top: 0;
84+
}
85+
86+
&.sizeSm::before {
87+
height: 14px;
88+
width: 14px;
89+
top: 1px;
90+
left: 1px;
91+
}
92+
93+
&.sizeXs::before {
94+
width: 8px;
95+
height: 8px;
96+
top: 1px;
97+
left: 1px;
4198
}
4299

43100
&::before {
44101
position: absolute;
45102
z-index: z-indices.$switchSliderBefore;
46103
content: "";
47-
height: 24px;
48-
width: 24px;
49-
left: -1px;
50-
top: -1px;
51104
background: colors.$white;
52105
transition: variables.$transition;
53106
border-radius: 50%;
54-
border: 1px solid colors.$grey-200;
55107
}
56108
}
57109

@@ -60,55 +112,52 @@
60112
width: 0;
61113
height: 0;
62114

63-
&:checked + .slider {
64-
background-color: colors.$blue;
65-
66-
&::before {
67-
@include knob-transform(right, false);
115+
&[aria-checked="true"] + .slider {
116+
&.variantDefault {
117+
background-color: colors.$blue;
68118
}
69119

70-
&.small::before {
71-
@include knob-transform(right, true);
120+
&.variantStrongBlue {
121+
background-color: colors.$blue-700;
72122
}
73123

124+
@include all-sizes-knob-transform(right);
125+
74126
&.loading {
75127
background-image: url("./ProgressReverse.svg");
76-
77-
&::before {
78-
@include knob-transform(left, false);
79-
}
80-
81-
&.small::before {
82-
@include knob-transform(left, true);
83-
}
128+
@include all-sizes-knob-transform(left);
84129
}
85130
}
86131

87-
&:not(:checked) + .slider {
88-
&::before {
89-
@include knob-transform(left, false);
90-
}
91-
92-
&.small::before {
93-
@include knob-transform(left, true);
94-
}
132+
&[aria-checked="false"] + .slider {
133+
@include all-sizes-knob-transform(left);
95134

96135
&.loading {
97136
background-image: url("./Progress.svg");
137+
@include all-sizes-knob-transform(right);
138+
}
139+
}
98140

99-
&::before {
100-
@include knob-transform(right, false);
101-
}
141+
&[aria-checked="mixed"] + .slider {
142+
&.variantDefault {
143+
background-color: colors.$blue-200;
144+
}
102145

103-
&.small::before {
104-
@include knob-transform(right, true);
105-
}
146+
&.loading {
147+
background-color: colors.$blue-100;
148+
background-image: url("./ProgressReverse.svg");
106149
}
150+
151+
@include all-sizes-knob-transform(middle);
107152
}
108153

109154
&:disabled + .slider {
110155
opacity: 0.5;
111156
cursor: auto;
157+
158+
&.loading {
159+
opacity: 1;
160+
}
112161
}
113162
}
114163
}

airbyte-webapp/src/components/ui/Switch/Switch.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ const Template: ComponentStory<typeof Switch> = (args) => <Switch {...args} />;
1313
export const SwitchControl = Template.bind({});
1414
SwitchControl.args = {
1515
checked: false,
16-
small: false,
16+
size: "sm",
1717
loading: false,
1818
};

airbyte-webapp/src/components/ui/Switch/Switch.tsx

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,52 @@ import React from "react";
33

44
import styles from "./Switch.module.scss";
55

6-
interface SwitchProps extends React.InputHTMLAttributes<HTMLInputElement> {
7-
small?: boolean;
6+
type SwitchSize = "lg" | "sm" | "xs";
7+
8+
type SwitchVariant = "default" | "strong-blue";
9+
10+
interface SwitchProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
11+
indeterminate?: boolean;
812
loading?: boolean;
13+
size?: SwitchSize;
14+
variant?: SwitchVariant;
915
}
1016

11-
export const Switch: React.FC<SwitchProps> = ({ loading, small, checked, value, ...props }) => {
17+
export const Switch: React.FC<SwitchProps> = ({
18+
checked,
19+
disabled,
20+
indeterminate,
21+
loading,
22+
size = "lg",
23+
value,
24+
variant = "default",
25+
...props
26+
}) => {
1227
const labelStyle = classnames(styles.switch, {
13-
[styles.small]: small,
28+
[styles.sizeLg]: size === "lg",
29+
[styles.sizeSm]: size === "sm",
30+
[styles.sizeXs]: size === "xs",
1431
[styles.loading]: loading,
1532
});
1633
const spanStyle = classnames(styles.slider, {
17-
[styles.small]: small,
34+
[styles.sizeLg]: size === "lg",
35+
[styles.sizeSm]: size === "sm",
36+
[styles.sizeXs]: size === "xs",
37+
[styles.variantDefault]: variant === "default",
38+
[styles.variantStrongBlue]: variant === "strong-blue",
39+
[styles.indeterminate]: indeterminate,
1840
[styles.loading]: loading,
1941
});
2042

2143
return (
2244
<label className={labelStyle}>
2345
<input
2446
{...props}
47+
aria-checked={indeterminate ? "mixed" : checked}
2548
className={styles.switchInput}
2649
type="checkbox"
2750
value={value}
28-
disabled={loading || props.disabled}
51+
disabled={loading || disabled}
2952
checked={checked || !!value}
3053
/>
3154
<span className={spanStyle} />

airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/__snapshots__/ConnectionReplicationTab.test.tsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ exports[`ConnectionReplicationTab should render 1`] = `
623623
class="<removed-for-snapshot-test>"
624624
>
625625
<input
626+
aria-checked="true"
626627
checked=""
627628
class="<removed-for-snapshot-test>"
628629
data-testid="pokemon-stream-sync-switch"

0 commit comments

Comments
 (0)