From 5934de06037203b01dc7dd532abe2ee89fec109a Mon Sep 17 00:00:00 2001 From: Elizabeth Mitchell Date: Wed, 26 Apr 2023 11:12:25 -0700 Subject: [PATCH] fix(focus): update focus-ring tokens PiperOrigin-RevId: 527319619 --- button/lib/_shared.scss | 6 +- chips/lib/_shared.scss | 6 +- fab/lib/_fab.scss | 6 +- fab/lib/_shared.scss | 11 +++- focus/lib/_focus-ring.scss | 68 ++++++++++++++--------- iconbutton/lib/_shared.scss | 5 +- iconbutton/lib/_standard-icon-button.scss | 5 +- list/lib/listitem/_list-item.scss | 4 +- navigationtab/lib/_navigation-tab.scss | 4 +- radio/lib/_radio.scss | 2 +- slider/lib/_slider.scss | 3 +- switch/lib/_switch.scss | 10 ++-- tokens/_md-comp-focus-ring.scss | 47 ++++++++-------- 13 files changed, 103 insertions(+), 74 deletions(-) diff --git a/button/lib/_shared.scss b/button/lib/_shared.scss index 254bbf2ae0..84d3987053 100644 --- a/button/lib/_shared.scss +++ b/button/lib/_shared.scss @@ -13,7 +13,6 @@ @use '../../focus/focus-ring'; @use '../../ripple/ripple'; @use '../../sass/dom'; -@use '../../sass/shape'; // go/keep-sorted end @mixin styles() { @@ -41,7 +40,10 @@ @include focus-ring.theme( ( - shape: shape.corners-to-shape-token('--_container-shape'), + 'shape-start-start': var(--_container-shape-start-start), + 'shape-start-end': var(--_container-shape-start-end), + 'shape-end-end': var(--_container-shape-end-end), + 'shape-end-start': var(--_container-shape-end-start), ) ); } diff --git a/chips/lib/_shared.scss b/chips/lib/_shared.scss index 05e17c093b..a6857559e1 100644 --- a/chips/lib/_shared.scss +++ b/chips/lib/_shared.scss @@ -10,7 +10,6 @@ @use '../../elevation/elevation'; @use '../../focus/focus-ring'; @use '../../ripple/ripple'; -@use '../../sass/shape'; // go/keep-sorted end @mixin styles() { @@ -139,7 +138,10 @@ md-focus-ring { @include focus-ring.theme( ( - 'shape': shape.corners-to-shape-token('--_container-shape'), + 'shape-start-start': var(--_container-shape-start-start), + 'shape-start-end': var(--_container-shape-start-end), + 'shape-end-end': var(--_container-shape-end-end), + 'shape-end-start': var(--_container-shape-end-start), ) ); } diff --git a/fab/lib/_fab.scss b/fab/lib/_fab.scss index 323cf4e73a..079e26a5cb 100644 --- a/fab/lib/_fab.scss +++ b/fab/lib/_fab.scss @@ -9,7 +9,6 @@ // go/keep-sorted start @use '../../focus/focus-ring'; @use '../../ripple/ripple'; -@use '../../sass/shape'; @use '../../sass/theme'; @use '../../tokens'; // go/keep-sorted end @@ -119,7 +118,10 @@ border-end-end-radius: var(--_small-container-shape-end-end); @include focus-ring.theme( ( - 'shape': shape.corners-to-shape-token('--_small-container-shape'), + 'shape-start-start': var(--_small-container-shape-start-start), + 'shape-start-end': var(--_small-container-shape-start-end), + 'shape-end-end': var(--_small-container-shape-end-end), + 'shape-end-start': var(--_small-container-shape-end-start), ) ); } diff --git a/fab/lib/_shared.scss b/fab/lib/_shared.scss index 247ecdb521..a5cbb5a8f4 100644 --- a/fab/lib/_shared.scss +++ b/fab/lib/_shared.scss @@ -10,7 +10,6 @@ @use '../../elevation/elevation'; @use '../../focus/focus-ring'; @use '../../ripple/ripple'; -@use '../../sass/shape'; @use '../../tokens'; @use './fab'; // go/keep-sorted end @@ -79,7 +78,10 @@ $_md-sys-motion: tokens.md-sys-motion-values(); @include focus-ring.theme( ( - 'shape': shape.corners-to-shape-token('--_large-container-shape'), + 'shape-start-start': var(--_large-container-shape-start-start), + 'shape-start-end': var(--_large-container-shape-start-end), + 'shape-end-end': var(--_large-container-shape-end-end), + 'shape-end-start': var(--_large-container-shape-end-start), ) ); } @@ -164,7 +166,10 @@ $_md-sys-motion: tokens.md-sys-motion-values(); border-end-end-radius: var(--_container-shape-end-end); @include focus-ring.theme( ( - 'shape': shape.corners-to-shape-token('--_container-shape'), + 'shape-start-start': var(--_container-shape-start-start), + 'shape-start-end': var(--_container-shape-start-end), + 'shape-end-end': var(--_container-shape-end-end), + 'shape-end-start': var(--_container-shape-end-start), ) ); } diff --git a/focus/lib/_focus-ring.scss b/focus/lib/_focus-ring.scss index 94686b3899..cad51d8086 100644 --- a/focus/lib/_focus-ring.scss +++ b/focus/lib/_focus-ring.scss @@ -4,47 +4,63 @@ // // go/keep-sorted start +@use 'sass:list'; @use 'sass:map'; // go/keep-sorted end // go/keep-sorted start -@use '../../sass/shape'; -@use '../../sass/theme'; @use '../../tokens'; // go/keep-sorted end -$_custom-property-prefix: 'focus-ring'; +$_md-sys-motion: tokens.md-sys-motion-values(); @mixin theme($tokens) { - $tokens: theme.validate-theme(tokens.md-comp-focus-ring-values(), $tokens); - $tokens: theme.create-theme-vars($tokens, $_custom-property-prefix); - $tokens: shape.resolve-tokens($tokens, 'shape'); + $supported-tokens: list.join( + tokens.$md-comp-focus-ring-supported-tokens, + ('shape-start-start', 'shape-start-end', 'shape-end-end', 'shape-end-start') + ); - @include theme.emit-theme-vars($tokens); + @each $token, $value in $tokens { + @if list.index($supported-tokens, $token) == null { + @error 'Token `#{$token}` is not a supported token.'; + } + + @if $value { + --md-focus-ring-#{$token}: #{$value}; + } + } } @mixin styles() { $tokens: tokens.md-comp-focus-ring-values(); - $tokens: theme.create-theme-vars($tokens, $_custom-property-prefix); - $tokens: shape.resolve-tokens($tokens, 'shape'); :host { @each $token, $value in $tokens { - --_#{$token}: #{$value}; + --_#{$token}: var(--md-focus-ring-#{$token}, #{$value}); } - display: none; - position: absolute; - box-sizing: border-box; - pointer-events: none; - border-start-start-radius: calc(var(--_offset) + var(--_shape-start-start)); - border-start-end-radius: calc(var(--_offset) + var(--_shape-start-end)); - border-end-start-radius: calc(var(--_offset) + var(--_shape-end-start)); + // Support logical shape properties + --_shape-start-start: var(--md-focus-ring-shape-start-start, var(--_shape)); + --_shape-start-end: var(--md-focus-ring-shape-start-end, var(--_shape)); + --_shape-end-end: var(--md-focus-ring-shape-end-end, var(--_shape)); + --_shape-end-start: var(--md-focus-ring-shape-end-start, var(--_shape)); + + animation-duration: var(--_duration); + animation-timing-function: map.get($_md-sys-motion, 'easing-emphasized'); border-end-end-radius: calc(var(--_offset) + var(--_shape-end-end)); - box-shadow: inset 0 0 0 0 var(--_color); - outline: var(--_width) solid var(--_color); - // NOTE: this 1px offset hides a transparent ring between the outline and offset when border-radius is large - outline-offset: -1px; + border-end-start-radius: calc(var(--_offset) + var(--_shape-end-start)); + border-start-end-radius: calc(var(--_offset) + var(--_shape-start-end)); + border-start-start-radius: calc(var(--_offset) + var(--_shape-start-start)); + box-shadow: inset 0 0 0 0 currentColor; + box-sizing: border-box; + color: var(--_color); + display: none; inset: calc(-1 * (var(--_offset) + 1px)); + // NOTE: this 1px offset hides a transparent ring between the outline and + // offset when border-radius is large + outline-offset: -1px; + outline: var(--_width) solid currentColor; + pointer-events: none; + position: absolute; } :host([visible]) { @@ -55,16 +71,16 @@ $_custom-property-prefix: 'focus-ring'; outline-width: 0px; } 25% { - box-shadow: inset 0 0 0 calc(var(--_animation-width) / 2) var(--_color); - outline-width: calc(var(--_animation-width) / 2); + box-shadow: inset 0 0 0 calc(var(--_active-width) / 2) currentColor; + outline-width: calc(var(--_active-width) / 2); } } animation-name: focus-ring; - animation-duration: var(--_animation-duration); - animation-timing-function: var(--_easing); + } - @media (prefers-reduced-motion) { + @media (prefers-reduced-motion) { + :host { animation: none; } } diff --git a/iconbutton/lib/_shared.scss b/iconbutton/lib/_shared.scss index 594c556ae0..e44ee203b1 100644 --- a/iconbutton/lib/_shared.scss +++ b/iconbutton/lib/_shared.scss @@ -32,7 +32,10 @@ @include focus-ring.theme( ( - shape: shape.corners-to-shape-token('--_container-shape'), + 'shape-start-start': var(--_container-shape-start-start), + 'shape-start-end': var(--_container-shape-start-end), + 'shape-end-end': var(--_container-shape-end-end), + 'shape-end-start': var(--_container-shape-end-start), ) ); } diff --git a/iconbutton/lib/_standard-icon-button.scss b/iconbutton/lib/_standard-icon-button.scss index bd86b66c0d..69ace4c01a 100644 --- a/iconbutton/lib/_standard-icon-button.scss +++ b/iconbutton/lib/_standard-icon-button.scss @@ -46,7 +46,10 @@ $_shape-property: 'state-layer-shape'; @include focus-ring.theme( ( - shape: shape.corners-to-shape-token('--_state-layer-shape'), + 'shape-start-start': var(--_state-layer-shape-start-start), + 'shape-start-end': var(--_state-layer-shape-start-end), + 'shape-end-end': var(--_state-layer-shape-end-end), + 'shape-end-start': var(--_state-layer-shape-end-start), ) ); } diff --git a/list/lib/listitem/_list-item.scss b/list/lib/listitem/_list-item.scss index 9f01af4aa7..fa36dc75e2 100644 --- a/list/lib/listitem/_list-item.scss +++ b/list/lib/listitem/_list-item.scss @@ -46,8 +46,8 @@ @include focus-ring.theme( ( - offset: -3px, - shape: map.get(tokens.md-sys-shape-values(), corner-extra-small), + 'offset': -3px, + 'shape': map.get(tokens.md-sys-shape-values(), 'corner-extra-small'), ) ); @include ripple.theme( diff --git a/navigationtab/lib/_navigation-tab.scss b/navigationtab/lib/_navigation-tab.scss index e1471a458a..481926633d 100644 --- a/navigationtab/lib/_navigation-tab.scss +++ b/navigationtab/lib/_navigation-tab.scss @@ -43,8 +43,8 @@ $_custom-property-prefix: 'navigation-bar'; @include focus-ring.theme( ( - offset: -2px, - shape: map.get(tokens.md-sys-shape-values(), corner-small), + 'offset': -2px, + 'shape': map.get(tokens.md-sys-shape-values(), 'corner-small'), ) ); diff --git a/radio/lib/_radio.scss b/radio/lib/_radio.scss index 4aec8a3386..c3ea569d05 100644 --- a/radio/lib/_radio.scss +++ b/radio/lib/_radio.scss @@ -45,7 +45,7 @@ $_md-sys-motion: tokens.md-sys-motion-values(); @include focus-ring.theme( ( - offset: -2px, + 'offset': -2px, ) ); diff --git a/slider/lib/_slider.scss b/slider/lib/_slider.scss index 23431a9abf..cf9cab1845 100644 --- a/slider/lib/_slider.scss +++ b/slider/lib/_slider.scss @@ -451,8 +451,7 @@ $_md-sys-shape: tokens.md-sys-shape-values(); md-focus-ring { @include focus-ring.theme( ( - offset: -2px, - shape: map.get($_md-sys-shape, 'corner-full'), + 'offset': -2px, ) ); } diff --git a/switch/lib/_switch.scss b/switch/lib/_switch.scss index 5bd3eab0b9..a3bc9c313d 100644 --- a/switch/lib/_switch.scss +++ b/switch/lib/_switch.scss @@ -79,12 +79,10 @@ $_forced-colors-theme: ( md-focus-ring { @include focus-ring.theme( ( - shape: ( - var(--_track-shape-start-start), - var(--_track-shape-start-end), - var(--_track-shape-end-start), - var(--_track-shape-end-end), - ), + 'shape-start-start': var(--_track-shape-start-start), + 'shape-start-end': var(--_track-shape-start-end), + 'shape-end-end': var(--_track-shape-end-end), + 'shape-end-start': var(--_track-shape-end-start), ) ); } diff --git a/tokens/_md-comp-focus-ring.scss b/tokens/_md-comp-focus-ring.scss index 417bcad59c..91dc5a04bd 100644 --- a/tokens/_md-comp-focus-ring.scss +++ b/tokens/_md-comp-focus-ring.scss @@ -5,42 +5,41 @@ // go/keep-sorted start @use 'sass:map'; +@use 'sass:string'; // go/keep-sorted end // go/keep-sorted start @use './md-sys-color'; @use './md-sys-motion'; @use './md-sys-shape'; +@use './values'; // go/keep-sorted end +$supported-tokens: ( + // go/keep-sorted start + 'active-width', + 'color', + 'duration', + 'offset', + 'shape', + 'width', + // go/keep-sorted end +); + $_default: ( 'md-sys-color': md-sys-color.values-light(), - 'md-sys-shape': md-sys-shape.values(), 'md-sys-motion': md-sys-motion.values(), + 'md-sys-shape': md-sys-shape.values(), ); @function values($deps: $_default, $exclude-hardcoded-values: false) { - @return ( - shape: - if( - $exclude-hardcoded-values, - null, - map.get($deps, 'md-sys-shape', 'corner-full') - ), - offset: if($exclude-hardcoded-values, null, 2px), - width: if($exclude-hardcoded-values, null, 3px), - animation-width: if($exclude-hardcoded-values, null, 8px), - animation-duration: - if( - $exclude-hardcoded-values, - null, - map.get($deps, 'md-sys-motion', 'duration-long4') - ), - easing: - if( - $exclude-hardcoded-values, - null, - map.get($deps, 'md-sys-motion', 'easing-emphasized') - ), - color: map.get($deps, 'md-sys-color', 'secondary') + $tokens: ( + 'active-width': if($exclude-hardcoded-values, null, 8px), + 'color': map.get($deps, 'md-sys-color', 'secondary'), + 'duration': map.get($deps, 'md-sys-motion', 'duration-long4'), + 'offset': if($exclude-hardcoded-values, null, 2px), + 'shape': map.get($deps, 'md-sys-shape', 'corner-full'), + 'width': if($exclude-hardcoded-values, null, 3px), ); + + @return values.validate($tokens, $supported-tokens: $supported-tokens); }