From 205b20b361f4747faf6c7b85e1ab3d2b76834595 Mon Sep 17 00:00:00 2001 From: Material Web Team Date: Wed, 13 Sep 2023 10:07:26 -0700 Subject: [PATCH] chore: refactor button focus ring PiperOrigin-RevId: 565084645 --- packages/mdc-button/_button-filled-theme.scss | 2 + .../mdc-button/_button-outlined-theme.scss | 2 + .../mdc-button/_button-protected-theme.scss | 2 + packages/mdc-button/_button-shared-theme.scss | 70 ++++++++++++---- packages/mdc-button/_button-text-theme.scss | 2 + packages/mdc-focus-ring/_focus-ring.scss | 79 ++++++++++++++----- 6 files changed, 122 insertions(+), 35 deletions(-) diff --git a/packages/mdc-button/_button-filled-theme.scss b/packages/mdc-button/_button-filled-theme.scss index ae844b2a450..5ccddb3cd7f 100644 --- a/packages/mdc-button/_button-filled-theme.scss +++ b/packages/mdc-button/_button-filled-theme.scss @@ -68,6 +68,8 @@ $light-theme: ( with-icon-icon-color: null, with-icon-icon-size: 18px, with-icon-pressed-icon-color: null, + focus-ring-color: null, + focus-ring-offset: 0, ); /// Sets theme based on provided theme configuration. diff --git a/packages/mdc-button/_button-outlined-theme.scss b/packages/mdc-button/_button-outlined-theme.scss index 292a905e4c9..c7f7c15bb2b 100644 --- a/packages/mdc-button/_button-outlined-theme.scss +++ b/packages/mdc-button/_button-outlined-theme.scss @@ -76,6 +76,8 @@ $light-theme: ( with-icon-focus-icon-color: null, with-icon-pressed-icon-color: null, with-icon-disabled-icon-color: null, + focus-ring-color: null, + focus-ring-offset: 0, ); /// Sets theme based on provided theme configuration. diff --git a/packages/mdc-button/_button-protected-theme.scss b/packages/mdc-button/_button-protected-theme.scss index 7253f722ee2..99d58422303 100644 --- a/packages/mdc-button/_button-protected-theme.scss +++ b/packages/mdc-button/_button-protected-theme.scss @@ -64,6 +64,8 @@ $light-theme: ( with-icon-icon-color: null, with-icon-icon-size: 18px, with-icon-pressed-icon-color: null, + focus-ring-color: null, + focus-ring-offset: 0, ); /// Sets theme based on provided theme configuration. diff --git a/packages/mdc-button/_button-shared-theme.scss b/packages/mdc-button/_button-shared-theme.scss index 342f429e4bb..f1b1b020fe5 100644 --- a/packages/mdc-button/_button-shared-theme.scss +++ b/packages/mdc-button/_button-shared-theme.scss @@ -180,6 +180,9 @@ $disabled-container-color: rgba( $shadow-color: map.get($theme, container-shadow-color), $query: $query ); + + @include _focus-ring-color(map.get($theme, focus-ring-color), $query); + @include _focus-ring-offset(map.get($theme, focus-ring-offset), $query); } @function resolve-theme-elevation-keys($theme, $resolver) { @@ -496,20 +499,6 @@ $disabled-container-color: rgba( $query: $query ); - $radius-value: $radius; - @if custom-properties.is-custom-prop($radius) { - $radius-value: custom-properties.get-declaration-value($radius); - } - - @if $radius-value != 0 and type-of($radius-value) == 'number' { - .mdc-button__focus-ring { - @include focus-ring.focus-ring-radius( - $ring-radius: $radius-value, - $query: $query - ); - } - } - #{button-ripple.$ripple-target} { @include shape-mixins.radius( $radius, @@ -518,6 +507,8 @@ $disabled-container-color: rgba( $query: $query ); } + + @include _focus-ring-shape($radius, $query); } /// @@ -764,3 +755,54 @@ $disabled-container-color: rgba( } } } + +@mixin _focus-ring-shape($radius, $query: feature-targeting.all()) { + $radius-value: if( + custom-properties.is-custom-prop($radius), + custom-properties.get-declaration-value($radius), + $radius + ); + + .mdc-button__focus-ring { + @if $radius-value != 0 and type-of($radius-value) == 'number' { + @include focus-ring.focus-ring-radius( + $ring-radius: $radius-value, + $query: $query + ); + } + } +} + +@mixin _focus-ring-color($color, $query: feature-targeting.all()) { + $color-value: if( + custom-properties.is-custom-prop($color), + custom-properties.get-declaration-value($color), + $color + ); + + .mdc-button__focus-ring { + @if $color != null { + @include focus-ring.focus-ring-color( + $inner-ring-color: $color-value, + $query: $query + ); + } + } +} + +@mixin _focus-ring-offset($offset, $query: feature-targeting.all()) { + $offset-value: if( + custom-properties.is-custom-prop($offset), + custom-properties.get-declaration-value($offset), + $offset + ); + + .mdc-button__focus-ring { + @if $offset-value != 0 and type-of($offset-value) == 'number' { + @include focus-ring.focus-ring-offset( + $offset: $offset-value, + $query: $query + ); + } + } +} diff --git a/packages/mdc-button/_button-text-theme.scss b/packages/mdc-button/_button-text-theme.scss index 21cac91fb8a..30eeb9c51da 100644 --- a/packages/mdc-button/_button-text-theme.scss +++ b/packages/mdc-button/_button-text-theme.scss @@ -60,6 +60,8 @@ $light-theme: ( with-icon-icon-color: null, with-icon-icon-size: 18px, with-icon-pressed-icon-color: null, + focus-ring-color: null, + focus-ring-offset: 0, ); /// Sets theme based on provided theme configuration. diff --git a/packages/mdc-focus-ring/_focus-ring.scss b/packages/mdc-focus-ring/_focus-ring.scss index 340798b8c8a..d74e72bd85b 100644 --- a/packages/mdc-focus-ring/_focus-ring.scss +++ b/packages/mdc-focus-ring/_focus-ring.scss @@ -38,8 +38,10 @@ $container-outer-padding-default: 2px !default; /// @param $inner-ring-color [$inner-ring-color-default] - Inner focus ring color. /// @param $outer-ring-width [$outer-ring-width-default] - Outer focus ring width. /// @param $outer-ring-color [$outer-ring-color-default] - Outer focus ring color. -/// @param $container-outer-padding [$container-outer-padding-default] - The -/// distance between the focus ring and the container. +/// @param $container-outer-padding-vertical [$container-outer-padding-default] +//// - The vertical distance between the focus ring and the container. +/// @param $container-outer-padding-horizontal [$container-outer-padding-default] +//// - The horizontal distance between the focus ring and the container. @mixin focus-ring( $query: feature-targeting.all(), $ring-radius: $ring-radius-default, @@ -51,22 +53,12 @@ $container-outer-padding-default: 2px !default; $container-outer-padding-horizontal: $container-outer-padding-default ) { $feat-structure: feature-targeting.create-target($query, structure); - $container-size-vertical: 100%; - @if $container-outer-padding-vertical != 0 { - $container-size-vertical: calc( - 100% + #{$container-outer-padding-vertical * 2} - ); - } - $container-size-horizontal: 100%; - @if $container-outer-padding-horizontal != 0 { - $container-size-horizontal: calc( - 100% + #{$container-outer-padding-horizontal * 2} - ); - } + $outer-ring-size: 100%; @if $outer-ring-width > 0 { $outer-ring-size: calc(100% + #{$outer-ring-width * 2}); } + @include feature-targeting.targets($feat-structure) { pointer-events: none; border: $inner-ring-width solid $inner-ring-color; @@ -78,8 +70,6 @@ $container-outer-padding-default: 2px !default; left: 50%; @include rtl.ignore-next-line(); transform: translate(-50%, -50%); - height: $container-size-vertical; - width: $container-size-horizontal; @include dom.forced-colors-mode($exclude-ie11: true) { border-color: CanvasText; @@ -104,19 +94,66 @@ $container-outer-padding-default: 2px !default; } } } + + @include focus-ring-offset( + $container-outer-padding-vertical, + $container-outer-padding-horizontal, + $query: $query + ); } -/// Customizes the color of the button focus ring. + +/// Customizes the color of the focus ring. /// /// @param $inner-ring-color [$inner-ring-color-default] - Inner focus ring color. /// @param $outer-ring-width [$outer-ring-width-default] - Outer focus ring width. @mixin focus-ring-color( $inner-ring-color: $inner-ring-color-default, - $outer-ring-color: $outer-ring-color-default + $outer-ring-color: $outer-ring-color-default, + $query: feature-targeting.all() ) { - border-color: $inner-ring-color; + $feat-structure: feature-targeting.create-target($query, structure); + + @include feature-targeting.targets($feat-structure) { + border-color: $inner-ring-color; - &::after { - border-color: $outer-ring-color; + &::after { + border-color: $outer-ring-color; + } + } +} + +/// Customizes the offset of the focus ring. +/// +/// @param $container-outer-padding-vertical [$container-outer-padding-default] +//// - The vertical distance between the focus ring and the container. +/// @param $container-outer-padding-horizontal [$container-outer-padding-default] +//// - The horizontal distance between the focus ring and the container. +@mixin focus-ring-offset( + $container-outer-padding-vertical: $container-outer-padding-default, + $container-outer-padding-horizontal: $container-outer-padding-default, + $offset: 0, + $query: feature-targeting.all() +) { + $container-size-vertical: 100%; + $container-size-vertical-offset: $container-outer-padding-vertical + $offset * + 2; + @if $container-size-vertical-offset != 0 { + $container-size-vertical: calc(100% + $container-size-vertical-offset * 2); + } + $container-size-horizontal: 100%; + $container-size-horizontal-offset: $container-outer-padding-horizontal + + $offset * 2; + @if $container-size-horizontal-offset != 0 { + $container-size-horizontal: calc( + 100% + $container-size-horizontal-offset * 2 + ); + } + + $feat-structure: feature-targeting.create-target($query, structure); + + @include feature-targeting.targets($feat-structure) { + height: $container-size-vertical; + width: $container-size-horizontal; } }