Skip to content

Commit 9e9bf84

Browse files
dfreedmcopybara-github
authored andcommitted
fix(switch): update to latest animations, and implement sizing tokens
PiperOrigin-RevId: 503245453
1 parent c72e7fd commit 9e9bf84

File tree

4 files changed

+132
-124
lines changed

4 files changed

+132
-124
lines changed

switch/lib/_handle.scss

+56-9
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@
77
// Selector '.md3-*' should only be used in this project.
88

99
@use 'sass:map';
10-
10+
@use '../../tokens';
1111
@use '../../ripple/ripple';
1212

13+
$_md-sys-motion: tokens.md-sys-motion-values();
14+
$_easing-standard: map.get($_md-sys-motion, easing-standard);
15+
1316
@mixin styles() {
1417
.md3-switch__handle-container {
18+
position: relative;
19+
// this easing is custom to perform the "overshoot" animation
20+
transition: margin 300ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
1521
display: flex;
1622
$margin: calc(var(--_track-width) - var(--_track-height));
1723

@@ -22,6 +28,10 @@
2228
.md3-switch--unselected & {
2329
margin-inline-end: $margin;
2430
}
31+
32+
.md3-switch:disabled & {
33+
transition: none;
34+
}
2535
}
2636

2737
.md3-switch__handle {
@@ -30,21 +40,53 @@
3040
border-start-end-radius: var(--_handle-shape-start-end);
3141
border-end-end-radius: var(--_handle-shape-end-end);
3242
border-end-start-radius: var(--_handle-shape-end-start);
33-
height: 20px;
34-
width: 20px;
43+
height: var(--_unselected-handle-height);
44+
width: var(--_unselected-handle-width);
3545
background-color: var(--_selected-handle-color);
3646

37-
// TODO(b/230484095): Use token instead of hard coded values
47+
transform-origin: center;
48+
transition-property: height, width, background-color;
49+
transition-duration: 250ms, 250ms, 67ms;
50+
transition-timing-function: $_easing-standard, $_easing-standard, linear;
51+
z-index: 0;
52+
53+
&::before {
54+
content: '';
55+
display: flex;
56+
position: absolute;
57+
height: 100%;
58+
width: 100%;
59+
border-radius: inherit;
60+
box-sizing: border-box;
61+
62+
transition: opacity 67ms linear;
63+
64+
.md3-switch--selected & {
65+
// When selected, turn off ::before
66+
opacity: 0;
67+
}
68+
69+
.md3-switch:disabled & {
70+
transition: none;
71+
}
72+
}
73+
74+
.md3-switch:disabled & {
75+
transition: none;
76+
}
77+
3878
.md3-switch--selected &,
3979
.md3-switch--unselected &.md3-switch__handle--big {
40-
transform: scale(1.2);
41-
}
42-
.md3-switch--unselected & {
43-
transform: scale(0.8);
80+
height: var(--_selected-handle-height);
81+
width: var(--_selected-handle-width);
4482
}
83+
4584
.md3-switch--selected:enabled:active &,
4685
.md3-switch--unselected:enabled:active & {
47-
transform: scale(1.4);
86+
height: var(--_pressed-handle-height);
87+
width: var(--_pressed-handle-width);
88+
transition-timing-function: linear;
89+
transition-duration: 100ms;
4890
}
4991

5092
.md3-switch--selected:hover & {
@@ -85,6 +127,11 @@
85127
}
86128

87129
.md3-switch__ripple {
130+
position: absolute;
131+
display: inline-flex;
132+
top: 50%;
133+
left: 50%;
134+
transform: translate(-50%, -50%);
88135
height: var(--_state-layer-size);
89136
width: var(--_state-layer-size);
90137

switch/lib/_icon.scss

+36
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,44 @@
77
// Selector '.md3-*' should only be used in this project.
88

99
@use 'sass:map';
10+
@use '../../tokens';
11+
12+
$_md-sys-motion: tokens.md-sys-motion-values();
13+
$_easing-standard: map.get($_md-sys-motion, easing-standard);
1014

1115
@mixin styles() {
16+
.md3-switch__icons {
17+
position: relative;
18+
height: 100%;
19+
width: 100%;
20+
}
21+
22+
.md3-switch__icon {
23+
position: absolute;
24+
inset: 0;
25+
margin: auto;
26+
27+
transition: fill 67ms linear, opacity 33ms linear,
28+
transform 167ms $_easing-standard;
29+
opacity: 0;
30+
31+
.md3-switch:disabled & {
32+
transition: none;
33+
}
34+
}
35+
36+
.md3-switch--selected .md3-switch__icon--on,
37+
.md3-switch--unselected .md3-switch__icon--off {
38+
opacity: 1;
39+
}
40+
41+
// rotate selected icon into view when there is no unselected icon
42+
.md3-switch--unselected
43+
.md3-switch__handle:not(.md3-switch__handle--big)
44+
.md3-switch__icon--on {
45+
transform: rotate(-45deg);
46+
}
47+
1248
.md3-switch__icon {
1349
.md3-switch--selected & {
1450
width: var(--_selected-icon-size);

switch/lib/_switch.scss

+1-115
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
@use 'sass:map';
1212
@use '../../focus/focus-ring';
13-
@use '../../motion/animation';
1413
@use '../../sass/color';
1514
@use '../../sass/resolvers';
1615
@use '../../sass/shape';
@@ -23,13 +22,6 @@
2322
@use './handle';
2423
@use './icon';
2524

26-
// TODO(b/230768994): update animation timing
27-
$animation-duration: 75ms;
28-
$icon-exit-duration: 0.4 * $animation-duration;
29-
$icon-enter-duration: $animation-duration - $icon-exit-duration;
30-
31-
$_touch-target-size: 48px;
32-
3325
$_forced-colors-theme: (
3426
disabled-selected-icon-color: GrayText,
3527
disabled-selected-icon-opacity: 1,
@@ -52,7 +44,6 @@ $_forced-colors-theme: (
5244
);
5345

5446
@mixin theme($tokens) {
55-
$tokens: _warn-of-not-implemented($tokens);
5647
$tokens: theme.validate-theme(tokens.md-comp-switch-values(), $tokens);
5748
$tokens: _resolve-tokens($tokens);
5849
$tokens: theme.create-theme-vars($tokens, switch);
@@ -77,11 +68,11 @@ $_forced-colors-theme: (
7768

7869
display: inline-flex;
7970
outline: none;
71+
vertical-align: top;
8072
-webkit-tap-highlight-color: transparent;
8173
}
8274

8375
md-focus-ring {
84-
// TODO(b/231741594): use `track-shape` once this is not deleted.
8576
@include focus-ring.theme(
8677
(
8778
shape: (
@@ -115,96 +106,6 @@ $_forced-colors-theme: (
115106
border-end-start-radius: var(--_track-shape-end-start);
116107
}
117108

118-
// Track
119-
.md3-switch__handle,
120-
.md3-switch__track {
121-
&::before {
122-
content: '';
123-
display: flex;
124-
position: absolute;
125-
height: 100%;
126-
width: 100%;
127-
border-radius: inherit;
128-
box-sizing: border-box;
129-
130-
transition-property: opacity;
131-
transition-duration: #{$animation-duration};
132-
}
133-
}
134-
135-
.md3-switch__track {
136-
position: relative;
137-
width: 100%;
138-
height: 100%;
139-
box-sizing: border-box;
140-
141-
border-radius: inherit;
142-
143-
// Center content
144-
display: flex;
145-
justify-content: center;
146-
align-items: center;
147-
148-
&::before {
149-
border-style: solid;
150-
151-
.md3-switch--selected & {
152-
// When selected, turn off ::before
153-
opacity: 0;
154-
}
155-
}
156-
}
157-
158-
// Handle container
159-
.md3-switch__handle-container {
160-
position: relative;
161-
transition: animation.standard(margin, $animation-duration);
162-
}
163-
164-
// Handle
165-
.md3-switch__handle {
166-
transform-origin: center;
167-
transition: animation.standard(transform, $animation-duration);
168-
169-
&::before {
170-
.md3-switch--selected & {
171-
// When selected, turn off ::before
172-
opacity: 0;
173-
}
174-
}
175-
}
176-
177-
// Ripple
178-
.md3-switch__ripple {
179-
position: absolute;
180-
display: inline-flex;
181-
left: 50%;
182-
top: 50%;
183-
transform: translate(-50%, -50%);
184-
}
185-
186-
// Icons
187-
.md3-switch__icons {
188-
position: relative;
189-
height: 100%;
190-
width: 100%;
191-
}
192-
193-
.md3-switch__icon {
194-
position: absolute;
195-
inset: 0;
196-
margin: auto;
197-
198-
transition-property: fill;
199-
transition-duration: #{$animation-duration};
200-
opacity: 0;
201-
}
202-
203-
.md3-switch--selected .md3-switch__icon--on,
204-
.md3-switch--unselected .md3-switch__icon--off {
205-
opacity: 1;
206-
}
207-
208109
// Touch target
209110
.md3-switch__touch {
210111
@include touch-target.touch-target();
@@ -285,18 +186,3 @@ $_forced-colors-theme: (
285186
)
286187
);
287188
}
288-
289-
@function _warn-of-not-implemented($theme) {
290-
// TODO(b/230484095): remove this warning once these are implemented.
291-
@if (
292-
map.get($theme, selected-handle-height) or
293-
map.get($theme, selected-handle-width) or
294-
map.get($theme, unselected-handle-height) or
295-
map.get($theme, unselected-handle-width) or
296-
map.get($theme, pressed-handle-height) or
297-
map.get($theme, pressed-handle-width)
298-
) {
299-
@warn '`handle-height` and `handle-width` are not yet implemented. see b/230484095';
300-
}
301-
@return $theme;
302-
}

switch/lib/_track.scss

+39
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,25 @@
1010

1111
@mixin styles() {
1212
.md3-switch__track {
13+
position: absolute;
14+
width: 100%;
15+
height: 100%;
16+
box-sizing: border-box;
17+
18+
border-radius: inherit;
19+
20+
// Center content
21+
display: flex;
22+
justify-content: center;
23+
align-items: center;
24+
25+
transition: background-color 67ms linear;
1326
background-color: var(--_selected-track-color);
1427

28+
.md3-switch:disabled & {
29+
transition: none;
30+
}
31+
1532
.md3-switch--selected:hover & {
1633
background-color: var(--_selected-hover-track-color);
1734
}
@@ -29,10 +46,32 @@
2946
}
3047

3148
&::before {
49+
content: '';
50+
display: flex;
51+
position: absolute;
52+
height: 100%;
53+
width: 100%;
54+
border-radius: inherit;
55+
box-sizing: border-box;
56+
border-style: solid;
57+
58+
transition-property: opacity, background-color;
59+
transition-timing-function: linear;
60+
transition-duration: 67ms;
61+
3262
border-width: var(--_track-outline-width);
3363
background-color: var(--_unselected-track-color);
3464
border-color: var(--_unselected-track-outline-color);
3565

66+
.md3-switch:disabled & {
67+
transition: none;
68+
}
69+
70+
.md3-switch--selected & {
71+
// When selected, turn off ::before
72+
opacity: 0;
73+
}
74+
3675
.md3-switch--unselected:hover & {
3776
background-color: var(--_unselected-hover-track-color);
3877
border-color: var(--_unselected-hover-track-outline-color);

0 commit comments

Comments
 (0)