fix(switch): update to latest animations, and implement sizing tokens

PiperOrigin-RevId: 503245453
This commit is contained in:
Daniel Freedman 2023-01-19 13:09:16 -08:00 committed by Copybara-Service
parent c72e7fd6f7
commit 9e9bf845be
4 changed files with 132 additions and 124 deletions

View File

@ -7,11 +7,17 @@
// Selector '.md3-*' should only be used in this project.
@use 'sass:map';
@use '../../tokens';
@use '../../ripple/ripple';
$_md-sys-motion: tokens.md-sys-motion-values();
$_easing-standard: map.get($_md-sys-motion, easing-standard);
@mixin styles() {
.md3-switch__handle-container {
position: relative;
// this easing is custom to perform the "overshoot" animation
transition: margin 300ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
display: flex;
$margin: calc(var(--_track-width) - var(--_track-height));
@ -22,6 +28,10 @@
.md3-switch--unselected & {
margin-inline-end: $margin;
}
.md3-switch:disabled & {
transition: none;
}
}
.md3-switch__handle {
@ -30,21 +40,53 @@
border-start-end-radius: var(--_handle-shape-start-end);
border-end-end-radius: var(--_handle-shape-end-end);
border-end-start-radius: var(--_handle-shape-end-start);
height: 20px;
width: 20px;
height: var(--_unselected-handle-height);
width: var(--_unselected-handle-width);
background-color: var(--_selected-handle-color);
// TODO(b/230484095): Use token instead of hard coded values
transform-origin: center;
transition-property: height, width, background-color;
transition-duration: 250ms, 250ms, 67ms;
transition-timing-function: $_easing-standard, $_easing-standard, linear;
z-index: 0;
&::before {
content: '';
display: flex;
position: absolute;
height: 100%;
width: 100%;
border-radius: inherit;
box-sizing: border-box;
transition: opacity 67ms linear;
.md3-switch--selected & {
// When selected, turn off ::before
opacity: 0;
}
.md3-switch:disabled & {
transition: none;
}
}
.md3-switch:disabled & {
transition: none;
}
.md3-switch--selected &,
.md3-switch--unselected &.md3-switch__handle--big {
transform: scale(1.2);
}
.md3-switch--unselected & {
transform: scale(0.8);
height: var(--_selected-handle-height);
width: var(--_selected-handle-width);
}
.md3-switch--selected:enabled:active &,
.md3-switch--unselected:enabled:active & {
transform: scale(1.4);
height: var(--_pressed-handle-height);
width: var(--_pressed-handle-width);
transition-timing-function: linear;
transition-duration: 100ms;
}
.md3-switch--selected:hover & {
@ -85,6 +127,11 @@
}
.md3-switch__ripple {
position: absolute;
display: inline-flex;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: var(--_state-layer-size);
width: var(--_state-layer-size);

View File

@ -7,8 +7,44 @@
// Selector '.md3-*' should only be used in this project.
@use 'sass:map';
@use '../../tokens';
$_md-sys-motion: tokens.md-sys-motion-values();
$_easing-standard: map.get($_md-sys-motion, easing-standard);
@mixin styles() {
.md3-switch__icons {
position: relative;
height: 100%;
width: 100%;
}
.md3-switch__icon {
position: absolute;
inset: 0;
margin: auto;
transition: fill 67ms linear, opacity 33ms linear,
transform 167ms $_easing-standard;
opacity: 0;
.md3-switch:disabled & {
transition: none;
}
}
.md3-switch--selected .md3-switch__icon--on,
.md3-switch--unselected .md3-switch__icon--off {
opacity: 1;
}
// rotate selected icon into view when there is no unselected icon
.md3-switch--unselected
.md3-switch__handle:not(.md3-switch__handle--big)
.md3-switch__icon--on {
transform: rotate(-45deg);
}
.md3-switch__icon {
.md3-switch--selected & {
width: var(--_selected-icon-size);

View File

@ -10,7 +10,6 @@
@use 'sass:map';
@use '../../focus/focus-ring';
@use '../../motion/animation';
@use '../../sass/color';
@use '../../sass/resolvers';
@use '../../sass/shape';
@ -23,13 +22,6 @@
@use './handle';
@use './icon';
// TODO(b/230768994): update animation timing
$animation-duration: 75ms;
$icon-exit-duration: 0.4 * $animation-duration;
$icon-enter-duration: $animation-duration - $icon-exit-duration;
$_touch-target-size: 48px;
$_forced-colors-theme: (
disabled-selected-icon-color: GrayText,
disabled-selected-icon-opacity: 1,
@ -52,7 +44,6 @@ $_forced-colors-theme: (
);
@mixin theme($tokens) {
$tokens: _warn-of-not-implemented($tokens);
$tokens: theme.validate-theme(tokens.md-comp-switch-values(), $tokens);
$tokens: _resolve-tokens($tokens);
$tokens: theme.create-theme-vars($tokens, switch);
@ -77,11 +68,11 @@ $_forced-colors-theme: (
display: inline-flex;
outline: none;
vertical-align: top;
-webkit-tap-highlight-color: transparent;
}
md-focus-ring {
// TODO(b/231741594): use `track-shape` once this is not deleted.
@include focus-ring.theme(
(
shape: (
@ -115,96 +106,6 @@ $_forced-colors-theme: (
border-end-start-radius: var(--_track-shape-end-start);
}
// Track
.md3-switch__handle,
.md3-switch__track {
&::before {
content: '';
display: flex;
position: absolute;
height: 100%;
width: 100%;
border-radius: inherit;
box-sizing: border-box;
transition-property: opacity;
transition-duration: #{$animation-duration};
}
}
.md3-switch__track {
position: relative;
width: 100%;
height: 100%;
box-sizing: border-box;
border-radius: inherit;
// Center content
display: flex;
justify-content: center;
align-items: center;
&::before {
border-style: solid;
.md3-switch--selected & {
// When selected, turn off ::before
opacity: 0;
}
}
}
// Handle container
.md3-switch__handle-container {
position: relative;
transition: animation.standard(margin, $animation-duration);
}
// Handle
.md3-switch__handle {
transform-origin: center;
transition: animation.standard(transform, $animation-duration);
&::before {
.md3-switch--selected & {
// When selected, turn off ::before
opacity: 0;
}
}
}
// Ripple
.md3-switch__ripple {
position: absolute;
display: inline-flex;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
// Icons
.md3-switch__icons {
position: relative;
height: 100%;
width: 100%;
}
.md3-switch__icon {
position: absolute;
inset: 0;
margin: auto;
transition-property: fill;
transition-duration: #{$animation-duration};
opacity: 0;
}
.md3-switch--selected .md3-switch__icon--on,
.md3-switch--unselected .md3-switch__icon--off {
opacity: 1;
}
// Touch target
.md3-switch__touch {
@include touch-target.touch-target();
@ -285,18 +186,3 @@ $_forced-colors-theme: (
)
);
}
@function _warn-of-not-implemented($theme) {
// TODO(b/230484095): remove this warning once these are implemented.
@if (
map.get($theme, selected-handle-height) or
map.get($theme, selected-handle-width) or
map.get($theme, unselected-handle-height) or
map.get($theme, unselected-handle-width) or
map.get($theme, pressed-handle-height) or
map.get($theme, pressed-handle-width)
) {
@warn '`handle-height` and `handle-width` are not yet implemented. see b/230484095';
}
@return $theme;
}

View File

@ -10,8 +10,25 @@
@mixin styles() {
.md3-switch__track {
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
border-radius: inherit;
// Center content
display: flex;
justify-content: center;
align-items: center;
transition: background-color 67ms linear;
background-color: var(--_selected-track-color);
.md3-switch:disabled & {
transition: none;
}
.md3-switch--selected:hover & {
background-color: var(--_selected-hover-track-color);
}
@ -29,10 +46,32 @@
}
&::before {
content: '';
display: flex;
position: absolute;
height: 100%;
width: 100%;
border-radius: inherit;
box-sizing: border-box;
border-style: solid;
transition-property: opacity, background-color;
transition-timing-function: linear;
transition-duration: 67ms;
border-width: var(--_track-outline-width);
background-color: var(--_unselected-track-color);
border-color: var(--_unselected-track-outline-color);
.md3-switch:disabled & {
transition: none;
}
.md3-switch--selected & {
// When selected, turn off ::before
opacity: 0;
}
.md3-switch--unselected:hover & {
background-color: var(--_unselected-hover-track-color);
border-color: var(--_unselected-hover-track-outline-color);