// // Copyright 2020 Google Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // Selector '.mdc-*' should only be used in this project. // stylelint-disable selector-class-pattern -- // Internal styling for Chip MDC component. @use 'sass:map'; @use 'sass:meta'; @use 'sass:math'; @use 'sass:color'; @use '@material/dom/dom'; @use '@material/density/density'; @use '@material/feature-targeting/feature-targeting'; @use '@material/shape/shape'; @use '@material/ripple/ripple-theme'; @use '@material/rtl/rtl'; @use '@material/theme/theme'; @use '@material/theme/keys'; @use '@material/elevation/elevation-theme'; @use '@material/tokens/resolvers'; @use '@material/theme/state'; @use '@material/theme/theme-color'; @use '@material/typography/typography'; $height: 32px; $minimum-height: 24px; $maximum-height: $height; $density-scale: density.$default-scale; $density-config: ( height: ( default: $height, maximum: $maximum-height, minimum: $minimum-height, ), ); $radius: math.div($height, 2); $type-scale: body2; $container-color: color.mix( theme-color.prop-value(on-surface), theme-color.prop-value(surface), 12% ); $text-label-color: rgba(theme-color.prop-value(on-surface), 0.87); $icon-color: rgba(theme-color.prop-value(on-surface), 0.87); $checkmark-color: rgba(theme-color.prop-value(on-surface), 0.87); $trailing-action-color: rgba(theme-color.prop-value(on-surface), 0.87); $ripple-color: on-surface; $checkmark-size: 20px; $leading-icon-size: 20px; $trailing-action-size: 18px; $leading-padding: 12px; $trailing-padding: 12px; $avatar-size: 24px; $avatar-leading-padding: 4px; $avatar-trailing-padding: 8px; $graphic-leading-padding: 6px; $graphic-trailing-padding: 6px; $trailing-action-leading-padding: 8px; $trailing-action-trailing-padding: 8px; $ripple-target: '.mdc-evolution-chip__ripple'; $ripple-target-primary: '.mdc-evolution-chip__ripple--primary'; $ripple-target-trailing: '.mdc-evolution-chip__ripple--trailing'; // Filter chip colors $filter-selected-container-color: color.mix( theme-color.prop-value(on-surface), $container-color, 8% ); $light-theme: ( container-elevation: null, container-height: null, container-shadow-color: null, container-shape: null, disabled-label-text-color: null, disabled-label-text-opacity: null, disabled-outline-color: null, disabled-outline-opacity: null, elevated-container-color: null, elevated-container-elevation: null, elevated-container-shadow-color: null, container-surface-tint-layer-color: null, elevated-disabled-container-color: null, elevated-disabled-container-elevation: null, elevated-disabled-container-opacity: null, elevated-focus-container-elevation: null, elevated-hover-container-elevation: null, elevated-pressed-container-elevation: null, elevated-selected-container-color: null, elevated-selected-container-elevation: null, elevated-unselected-container-color: null, flat-container-elevation: null, flat-disabled-outline-color: null, flat-disabled-outline-opacity: null, flat-disabled-selected-container-color: null, flat-disabled-selected-container-opacity: null, flat-disabled-selected-outline-color: null, flat-disabled-selected-outline-opacity: null, flat-disabled-unselected-outline-color: null, flat-disabled-unselected-outline-opacity: null, flat-focus-outline-color: null, flat-outline-color: null, flat-outline-width: null, flat-selected-container-color: null, flat-selected-focus-container-elevation: null, flat-selected-hover-container-elevation: null, flat-selected-outline-color: null, flat-selected-outline-width: null, flat-selected-pressed-container-elevation: null, flat-unselected-focus-container-elevation: null, flat-unselected-focus-outline-color: null, flat-unselected-hover-container-elevation: null, flat-unselected-outline-color: null, flat-unselected-outline-width: null, flat-unselected-pressed-container-elevation: null, focus-label-text-color: null, focus-outline-color: null, focus-state-layer-color: null, focus-state-layer-opacity: null, hover-label-text-color: null, hover-state-layer-color: null, hover-state-layer-opacity: null, label-text-color: null, label-text-font: null, label-text-line-height: null, label-text-size: null, label-text-tracking: null, label-text-weight: null, outline-color: null, outline-width: null, pressed-label-text-color: null, pressed-state-layer-color: null, pressed-state-layer-opacity: null, selected-focus-label-text-color: null, selected-focus-state-layer-color: null, selected-focus-state-layer-opacity: null, selected-hover-label-text-color: null, selected-hover-state-layer-color: null, selected-hover-state-layer-opacity: null, selected-label-text-color: null, selected-pressed-label-text-color: null, selected-pressed-state-layer-color: null, selected-pressed-state-layer-opacity: null, unselected-focus-label-text-color: null, unselected-focus-state-layer-color: null, unselected-focus-state-layer-opacity: null, unselected-hover-label-text-color: null, unselected-hover-state-layer-color: null, unselected-hover-state-layer-opacity: null, unselected-label-text-color: null, unselected-pressed-label-text-color: null, unselected-pressed-state-layer-color: null, unselected-pressed-state-layer-opacity: null, with-avatar-avatar-shape: null, with-avatar-avatar-size: null, with-avatar-disabled-avatar-opacity: null, with-icon-disabled-icon-color: null, with-icon-disabled-icon-opacity: null, with-icon-focus-icon-color: null, with-icon-hover-icon-color: null, with-icon-icon-color: null, with-icon-icon-size: null, with-icon-pressed-icon-color: null, with-icon-selected-focus-icon-color: null, with-icon-selected-hover-icon-color: null, with-icon-selected-icon-color: null, with-icon-selected-pressed-icon-color: null, with-icon-unselected-focus-icon-color: null, with-icon-unselected-hover-icon-color: null, with-icon-unselected-icon-color: null, with-icon-unselected-pressed-icon-color: null, with-leading-icon-disabled-leading-icon-color: null, with-leading-icon-disabled-leading-icon-opacity: null, with-leading-icon-focus-leading-icon-color: null, with-leading-icon-hover-leading-icon-color: null, with-leading-icon-leading-icon-color: null, with-leading-icon-leading-icon-size: null, with-leading-icon-pressed-leading-icon-color: null, with-trailing-icon-disabled-trailing-icon-color: null, with-trailing-icon-disabled-trailing-icon-opacity: null, with-trailing-icon-focus-trailing-icon-color: null, with-trailing-icon-hover-trailing-icon-color: null, with-trailing-icon-pressed-trailing-icon-color: null, with-trailing-icon-trailing-icon-color: null, with-trailing-icon-trailing-icon-size: null, ); $_custom-property-prefix: 'chip'; // TODO(b/259513131): Move theme resolution to variant theme // and remove custom property declaration when all customers are ready to be migrated @mixin theme($theme, $resolvers: resolvers.$material) { @include theme.validate-theme($light-theme, $theme); $theme: resolve-theme($theme, $resolvers: $resolvers); @include keys.declare-custom-properties( $theme, $prefix: $_custom-property-prefix ); } // TODO(b/259513131): Move theme resolution to variant theme // and remove custom property declaration when all customers are ready to be migrated @mixin theme-styles($theme, $resolvers: resolvers.$material) { @include theme.validate-theme-styles($light-theme, $theme); $theme: resolve-theme($theme, $resolvers: $resolvers); $theme: keys.create-theme-properties( $theme, $prefix: $_custom-property-prefix ); @include _container-shape(map.get($theme, container-shape)); .mdc-evolution-chip__icon--primary { @include shape.radius(map.get($theme, with-avatar-avatar-shape)); } @include graphic-size(map.get($theme, with-avatar-avatar-size)); @include height(map.get($theme, container-height)); @include elevation-theme.overlay-container-color( map.get($theme, container-surface-tint-layer-color) ); @include _container-elevation( $map: ( default: map.get($theme, container-elevation), ) ); @include _container-elevation( $map: ( enabled: map.get($theme, flat-container-elevation), ) ); @include _container-elevation( $map: ( enabled: map.get($theme, elevated-container-elevation), disabled: map.get($theme, elevated-disabled-container-elevation), hover: map.get($theme, elevated-hover-container-elevation), focus: map.get($theme, elevated-focus-container-elevation), pressed: map.get($theme, elevated-pressed-container-elevation), ) ); &.mdc-evolution-chip--selected { @include _container-elevation( ( enabled: map.get($theme, elevated-selected-container-elevation), disabled: map.get($theme, elevated-selected-disabled-container-elevation), hover: map.get($theme, elevated-selected-hover-container-elevation), focus: map.get($theme, elevated-selected-focus-container-elevation), pressed: map.get($theme, elevated-selected-pressed-container-elevation), ) ); @include _container-elevation( ( enabled: map.get($theme, flat-selected-container-elevation), disabled: map.get($theme, flat-selected-disabled-container-elevation), hover: map.get($theme, flat-selected-hover-container-elevation), focus: map.get($theme, flat-selected-focus-container-elevation), pressed: map.get($theme, flat-selected-pressed-container-elevation), ) ); } &:not(.mdc-evolution-chip--selected) { @include _container-elevation( ( enabled: map.get($theme, flat-unselected-container-elevation), disabled: map.get($theme, flat-unselected-disabled-container-elevation), hover: map.get($theme, flat-unselected-hover-container-elevation), focus: map.get($theme, flat-unselected-focus-container-elevation), pressed: map.get($theme, flat-unselected-pressed-container-elevation), ) ); } @include outline-color( ( enabled: map.get($theme, outline-color), focus: map.get($theme, focus-outline-color), disabled: map.get($theme, disabled-outline-color), ) ); @include outline-color( ( enabled: map.get($theme, flat-outline-color), focus: map.get($theme, flat-focus-outline-color), disabled: map.get($theme, flat-disabled-outline-color), ) ); @include selected-outline-color( ( enabled: map.get($theme, flat-selected-outline-color), disabled: map.get($theme, flat-disabled-selected-outline-color), ) ); &:not(.mdc-evolution-chip--selected) { @include outline-color( ( disabled: map.get($theme, flat-disabled-unselected-outline-color), focus: map.get($theme, flat-unselected-focus-outline-color), enabled: map.get($theme, flat-unselected-outline-color), ) ); } @include outline-width(map.get($theme, outline-width)); @include outline-width(map.get($theme, flat-outline-width)); &.mdc-evolution-chip--selected { @include outline-width(map.get($theme, flat-selected-outline-width)); } &:not(.mdc-evolution-chip--selected) { @include outline-width(map.get($theme, flat-unselected-outline-width)); } @include container-color( ( enabled: map.get($theme, elevated-container-color), disabled: map.get($theme, elevated-disabled-container-color), ) ); @include selected-container-color( ( enabled: map.get($theme, elevated-selected-container-color), disabled: map.get($theme, elevated-disabled-container-color), ) ); // TODO(b/255716167) Separate theme-styles mixin for hairline and elevated chip variants. @include selected-container-color( ( enabled: map.get($theme, flat-selected-container-color), disabled: map.get($theme, flat-disabled-selected-container-color), ) ); &:not(.mdc-evolution-chip--selected) { @include container-color( ( enabled: map.get($theme, elevated-unselected-container-color), ) ); } .mdc-evolution-chip__text-label { @include typography.theme-styles( ( font: map.get($theme, label-text-font), line-height: map.get($theme, label-text-line-height), size: map.get($theme, label-text-size), weight: map.get($theme, label-text-weight), tracking: map.get($theme, label-text-tracking), ) ); } @include text-label-color( ( enabled: map.get($theme, label-text-color), hover: map.get($theme, hover-label-text-color), focus: map.get($theme, focus-label-text-color), pressed: map.get($theme, pressed-label-text-color), disabled: map.get($theme, disabled-label-text-color), ) ); @include selected-text-label-color( ( enabled: map.get($theme, selected-label-text-color), hover: map.get($theme, selected-hover-label-text-color), focus: map.get($theme, selected-focus-label-text-color), pressed: map.get($theme, selected-pressed-label-text-color), disabled: map.get($theme, disabled-label-text-color), ) ); &:not(.mdc-evolution-chip--selected) { @include text-label-color( ( enabled: map.get($theme, unselected-label-text-color), hover: map.get($theme, unselected-hover-label-text-color), focus: map.get($theme, unselected-focus-label-text-color), pressed: map.get($theme, unselected-pressed-label-text-color), disabled: map.get($theme, unselected-disabled-label-text-color), ) ); } @include icon-size(map.get($theme, with-icon-icon-size)); @include icon-color( ( enabled: map.get($theme, with-icon-icon-color), disabled: map.get($theme, with-icon-disabled-icon-color), hover: map.get($theme, with-icon-hover-icon-color), focus: map.get($theme, with-icon-focus-icon-color), pressed: map.get($theme, with-icon-pressed-icon-color), ) ); @include checkmark-color( ( enabled: map.get($theme, with-icon-selected-icon-color), disabled: map.get($theme, with-icon-disabled-icon-color), hover: map.get($theme, with-icon-selected-hover-icon-color), focus: map.get($theme, with-icon-selected-focus-icon-color), pressed: map.get($theme, with-icon-selected-pressed-icon-color), ) ); &:not(.mdc-evolution-chip--selected) { @include icon-color( ( enabled: map.get($theme, with-icon-unselected-icon-color), disabled: map.get($theme, with-icon-unselected-disabled-icon-color), hover: map.get($theme, with-icon-unselected-hover-icon-color), focus: map.get($theme, with-icon-unselected-focus-icon-color), pressed: map.get($theme, with-icon-unselected-pressed-icon-color), ) ); } @include icon-color( ( disabled: map.get($theme, with-leading-icon-disabled-leading-icon-color), focus: map.get($theme, with-leading-icon-focus-leading-icon-color), hover: map.get($theme, with-leading-icon-hover-leading-icon-color), enabled: map.get($theme, with-leading-icon-leading-icon-color), pressed: map.get($theme, with-leading-icon-pressed-leading-icon-color), ) ); @include trailing-action-color( ( disabled: map.get($theme, with-trailing-icon-disabled-trailing-icon-color), focus: map.get($theme, with-trailing-icon-focus-trailing-icon-color), hover: map.get($theme, with-trailing-icon-hover-trailing-icon-color), enabled: map.get($theme, with-trailing-icon-trailing-icon-color), pressed: map.get($theme, with-trailing-icon-pressed-trailing-icon-color), ) ); @include _ripple-theme( ( focus-state-layer-color: map.get($theme, focus-state-layer-color), focus-state-layer-opacity: map.get($theme, focus-state-layer-opacity), hover-state-layer-color: map.get($theme, hover-state-layer-color), hover-state-layer-opacity: map.get($theme, hover-state-layer-opacity), pressed-state-layer-color: map.get($theme, pressed-state-layer-color), pressed-state-layer-opacity: map.get($theme, pressed-state-layer-opacity), ) ); &.mdc-evolution-chip--selected { @include _ripple-theme( ( focus-state-layer-color: map.get($theme, selected-focus-state-layer-color), focus-state-layer-opacity: map.get($theme, selected-focus-state-layer-opacity), hover-state-layer-color: map.get($theme, selected-hover-state-layer-color), hover-state-layer-opacity: map.get($theme, selected-hover-state-layer-opacity), pressed-state-layer-color: map.get($theme, selected-pressed-state-layer-color), pressed-state-layer-opacity: map.get($theme, selected-pressed-state-layer-opacity), ) ); } &:not(.mdc-evolution-chip--selected) { @include _ripple-theme( ( focus-state-layer-color: map.get($theme, unselected-focus-state-layer-color), focus-state-layer-opacity: map.get($theme, unselected-focus-state-layer-opacity), hover-state-layer-color: map.get($theme, unselected-hover-state-layer-color), hover-state-layer-opacity: map.get($theme, unselected-hover-state-layer-opacity), pressed-state-layer-color: map.get($theme, unselected-pressed-state-layer-color), pressed-state-layer-opacity: map.get($theme, unselected-pressed-state-layer-opacity), ) ); } } @function resolve-theme($theme, $resolvers) { $elevation-resolver: map.get($resolvers, elevation); @if $elevation-resolver == null { @return $theme; } $elevation-pairs: ( container-shadow-color: ( container-elevation, ), flat-container-shadow-color: ( flat-container-elevation, ), elevated-container-shadow-color: ( elevated-container-elevation, elevated-disabled-container-elevation, elevated-focus-container-elevation, elevated-hover-container-elevation, elevated-pressed-container-elevation, elevated-selected-container-elevation, elevated-selected-disabled-container-elevation, elevated-selected-focus-container-elevation, elevated-selected-hover-container-elevation, elevated-selected-pressed-container-elevation, flat-selected-focus-container-elevation, flat-selected-hover-container-elevation, flat-selected-pressed-container-elevation, flat-unselected-focus-container-elevation, flat-unselected-hover-container-elevation, flat-unselected-pressed-container-elevation, ), ); @each $shadow-color-key, $elevation-keys in $elevation-pairs { $shadow-color: map.get($theme, $shadow-color-key); @if $shadow-color != null { @each $key in $elevation-keys { $elevation: map.get($theme, $key); @if $elevation != null { $resolved-value: meta.call( $elevation-resolver, $elevation: $elevation, $shadow-color: $shadow-color ); // Update the key with the resolved value. $theme: map.set($theme, $key, $resolved-value); } } } } @return $theme; } @mixin _ripple-theme($ripple-theme) { .mdc-evolution-chip__action--primary { @include ripple-theme.internal-theme-styles( ( focus-state-layer-color: map.get($ripple-theme, focus-state-layer-color), focus-state-layer-opacity: map.get($ripple-theme, focus-state-layer-opacity), hover-state-layer-color: map.get($ripple-theme, hover-state-layer-color), hover-state-layer-opacity: map.get($ripple-theme, hover-state-layer-opacity), pressed-state-layer-color: map.get($ripple-theme, pressed-state-layer-color), pressed-state-layer-opacity: map.get($ripple-theme, pressed-state-layer-opacity), ), $ripple-target: $ripple-target ); } } /// /// Sets the ripple color of the chip. /// @param {Color} $color - The color of the ripple. /// @param {Map} $opacity-map [null] - The optional opacity map for the states. /// @mixin ripple-color( $color, $opacity-map: null, $query: feature-targeting.all() ) { @include _ripple-color($color, $opacity-map, $query); } /// /// Sets the selected ripple color of the chip. /// @param {Color} $color - The color of the ripple. /// @param {Map} $opacity-map [null] - The optional opacity map for the states. /// @mixin selected-ripple-color( $color, $opacity-map: null, $query: feature-targeting.all() ) { &.mdc-evolution-chip--selected { @include ripple-color($color, $opacity-map, $query: $query); } } @mixin _ripple-color($color, $opacity-map, $query) { .mdc-evolution-chip__action--primary { @include ripple-theme.states( $color: $color, $opacity-map: $opacity-map, $query: $query, $ripple-target: $ripple-target ); } } /// /// Sets the ripple color of the chip's trailing action. /// @param {Color} $color - The color of the ripple. /// @param {Map} $opacity-map [null] - The optional opacity map for the states. /// @mixin trailing-action-ripple-color( $color, $opacity-map: null, $query: feature-targeting.all() ) { .mdc-evolution-chip__action--trailing { @include ripple-theme.states( $color: $color, $opacity-map: $opacity-map, $query: $query, $ripple-target: $ripple-target ); } } /// /// Sets the size of the trailing action's ripple. /// @param {Number} $size - The size of the ripple. /// @mixin trailing-action-ripple-size($size, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__ripple--trailing { @include feature-targeting.targets($feat-structure) { @include theme.property(height, $size); @include theme.property(width, $size); } } } /// /// Sets the density scale for the chip. /// @param {Number | String} $density-scale - Density scale value for component. /// Supported density scale values are `-2`, `-1`, `0`. /// @mixin density($density-scale, $query: feature-targeting.all()) { $height: density.prop-value( $density-config: $density-config, $density-scale: $density-scale, $property-name: height, ); @include height($height, $query: $query); @if $density-scale != 0 { @include _reset-touch-target($query: $query); } } /// /// Resets touch target-related styles. This is called from the density mixin to /// automatically remove the increased touch target, since dense components /// don't have the same default a11y requirements. /// @access private /// @mixin _reset-touch-target($query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__action-touch { @include feature-targeting.targets($feat-structure) { display: none; } } } /// /// Sets custom height for the chip. /// @param {Number} $height - The height of the chip. /// @mixin height($height, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); @include feature-targeting.targets($feat-structure) { @include theme.property(height, $height); } } @mixin _container-shape($radius) { @include shape.radius($radius); #{$ripple-target} { @include shape.radius($radius); } .mdc-evolution-chip__action--primary:before { @include shape.radius($radius); } } /// /// Sets the shape radius of the chip. /// @param {Number|List} $radius - Shape radius in `border-radius` CSS format. /// @param {Boolean} $rtl-reflexive - True flips radius corners in RTL. /// @mixin shape-radius( $radius, $rtl-reflexive: false, $density-scale: $density-scale, $query: feature-targeting.all() ) { $height: density.prop-value( $density-config: $density-config, $density-scale: $density-scale, $property-name: height, ); @include shape.radius( $radius, $rtl-reflexive, $component-height: $height, $query: $query ); #{$ripple-target} { @include shape.radius( $radius, $rtl-reflexive, $component-height: $height, $query: $query ); } .mdc-evolution-chip__action--primary:before { @include shape.radius( $radius, $rtl-reflexive, $component-height: $height, $query: $query ); } .mdc-evolution-chip__icon--primary { @include shape.radius( $radius, $rtl-reflexive, $component-height: $height, $query: $query ); } } /// /// Sets the width of the chip outline. /// @param {Number} $width - The width of the chip outline. /// @mixin outline-width($width, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__action--primary:before { @include feature-targeting.targets($feat-structure) { @include theme.property(border-width, $width); } } } /// /// Customizes the outline color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `enabled`, `focus`, `disabled`. /// /// @example /// @include outline-color(blue); /// @include outline-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The outline's color or a state Map /// @mixin outline-color($color-or-map, $query: feature-targeting.all()) { @include _outline-color(state.get-default-state($color-or-map), $query); &:not(.mdc-evolution-chip--disabled) { @include _outline-color(state.get-enabled-state($color-or-map), $query); } @include _focus-outline-color(state.get-focus-state($color-or-map), $query); &.mdc-evolution-chip--disabled { @include _outline-color(state.get-disabled-state($color-or-map), $query); } } /// /// Customizes the selected outline color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `enabled`, `focus`, `disabled`. /// /// @example /// @include selected-outline-color(blue); /// @include selected-outline-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The outline's color or a state Map /// @mixin selected-outline-color($color-or-map, $query: feature-targeting.all()) { &.mdc-evolution-chip--selected { @include outline-color($color-or-map, $query: $query); } } @mixin _outline-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__action--primary:before { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(border-color, $color); } // TODO(b/206694742): Find a better solution. @if $color == transparent { @include dom.forced-colors-mode($exclude-ie11: true) { @include theme.property(border-color, CanvasText); } } } } } @mixin _focus-outline-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational) { @include ripple-theme.focus() { &:before { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(border-color, $color); } } } } } } /// /// Sets the style of the chip outline. /// @param {String} $style - The style of the chip outline. /// @mixin outline-style($style, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__action--primary:before { @include feature-targeting.targets($feat-structure) { @include theme.property(border-style, $style); } } } /// /// Customizes the container color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `enabled`, `disabled`. /// /// @example /// @include container-color(blue); /// @include container-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The container's color or a state Map /// @mixin container-color($color-or-map, $query: feature-targeting.all()) { @include _container-color(state.get-default-state($color-or-map), $query); &:not(.mdc-evolution-chip--disabled) { @include _container-color(state.get-enabled-state($color-or-map), $query); } &.mdc-evolution-chip--disabled { @include _container-color(state.get-disabled-state($color-or-map), $query); } } /// /// Customizes the selected container color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `enabled`, `disabled`. /// /// @example /// @include selected-container-color(blue); /// @include selected-container-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The container's color or a state Map /// @mixin selected-container-color( $color-or-map, $query: feature-targeting.all() ) { &.mdc-evolution-chip--selected { @include container-color($color-or-map, $query: $query); } } @mixin _container-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(background-color, $color); } } } /// /// Customizes the text label color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `enabled`, `hover`, `focus`, `disabled`. /// /// @example /// @include text-label-color(blue); /// @include text-label-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The label's color or a state Map /// @mixin text-label-color($color-or-map, $query: feature-targeting.all()) { @include _text-label-color(state.get-default-state($color-or-map), $query); &:not(.mdc-evolution-chip--disabled) { @include _text-label-color(state.get-enabled-state($color-or-map), $query); } .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational):hover { @include _text-label-color(state.get-hover-state($color-or-map), $query); } .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational) { @include ripple-theme.focus() { @include _text-label-color(state.get-focus-state($color-or-map), $query); } } &.mdc-evolution-chip--disabled { @include _text-label-color(state.get-disabled-state($color-or-map), $query); } } /// /// Customizes the selected text label color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `hover`, `focus`, `disabled`. /// /// @example /// @include selected-text-label-color(blue); /// @include selected-text-label-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The label's color or a state Map /// @mixin selected-text-label-color( $color-or-map, $query: feature-targeting.all() ) { &.mdc-evolution-chip--selected { @include text-label-color($color-or-map, $query: $query); } } @mixin _text-label-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__text-label { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(color, $color); } } } } /// /// Sets the type scale of the text label. /// @param {String} $type-scale - The type scale of the text label. /// @mixin text-label-type-scale($type-scale, $query: feature-targeting.all()) { .mdc-evolution-chip__text-label { @include typography.typography($type-scale, $query: $query); } } /// /// Sets the size of the graphic. /// @param {Number} $size - The size of the graphic. /// @mixin graphic-size($size, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); // Expose the width as a readable custom property that can be used when // computing the chip bounding client rect as an additive value for the chip // width. This solves for selectable chips without icons growing/shrinking as // they toggle their selected state. The ripple dimensions will have been // computed based on the unselected bounding client react which will not have // enough horizontal space to account for the growth in width. &.mdc-evolution-chip--selectable:not(.mdc-evolution-chip--with-primary-icon) { @if $size { @include theme.property(--mdc-chip-graphic-selected-width, $size); } } .mdc-evolution-chip__graphic { @include feature-targeting.targets($feat-structure) { @include theme.property(height, $size); @include theme.property(width, $size); @include theme.property(font-size, $size); } } } /// /// Customizes the icon color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `enabled`, `focus`, `disabled`. /// /// @example /// @include icon-color(blue); /// @include icon-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The icon's color or a state Map /// @mixin icon-color($color-or-map, $query: feature-targeting.all()) { @include _icon-color(state.get-default-state($color-or-map), $query); &:not(.mdc-evolution-chip--disabled) { @include _icon-color(state.get-enabled-state($color-or-map), $query); } .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational):hover { @include _icon-color(state.get-hover-state($color-or-map), $query); } .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational) { @include ripple-theme.focus() { @include _icon-color(state.get-focus-state($color-or-map), $query); } } &.mdc-evolution-chip--disabled { @include _icon-color(state.get-disabled-state($color-or-map), $query); } } @mixin _icon-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__icon--primary { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(color, $color); } } } } /// /// Customizes the icon container color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `hover`, `focus`, `disabled`. /// /// @example /// @include icon-container-color(blue); /// @include icon-container-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The icon's container color or a state Map /// @mixin icon-container-color($color-or-map, $query: feature-targeting.all()) { @include _icon-container-color( state.get-default-state($color-or-map), $query ); .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational):hover { @include _icon-container-color( state.get-hover-state($color-or-map), $query ); } .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational) { @include ripple-theme.focus() { @include _icon-container-color( state.get-focus-state($color-or-map), $query ); } } &.mdc-evolution-chip--disabled { @include _icon-container-color( state.get-disabled-state($color-or-map), $query ); } } @mixin _icon-container-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__icon--primary { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(background-color, $color); } } } } /// /// Sets the size of the icon. /// @param {Number} $size - The size of the icon. /// @mixin icon-size($size, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__icon--primary { @include feature-targeting.targets($feat-structure) { @include theme.property(height, $size); @include theme.property(width, $size); @include theme.property(font-size, $size); } } } /// /// Sets the size of the trailing action. /// @param {Number} $size - The size of the trailing action. /// @mixin trailing-action-size($size, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__icon--trailing { @include feature-targeting.targets($feat-structure) { @include theme.property(height, $size); @include theme.property(width, $size); @include theme.property(font-size, $size); } } } /// /// Customizes the trailing action color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `hover`, `focus`, `disabled`. /// /// @example /// @include trailing-action-color(blue); /// @include trailing-action-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The trailing action's color or a state Map /// @mixin trailing-action-color($color-or-map, $query: feature-targeting.all()) { @include _trailing-action-color( state.get-default-state($color-or-map), $query ); &:not(.mdc-evolution-chip--disabled) { @include _trailing-action-color( state.get-enabled-state($color-or-map), $query ); } .mdc-evolution-chip__action--trailing:hover { @include _trailing-action-color( state.get-hover-state($color-or-map), $query ); } .mdc-evolution-chip__action--trailing { @include ripple-theme.focus() { @include _trailing-action-color( state.get-focus-state($color-or-map), $query ); } } &.mdc-evolution-chip--disabled { @include _trailing-action-color( state.get-disabled-state($color-or-map), $query ); } } @mixin _trailing-action-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__icon--trailing { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(color, $color); } } } } /// /// Sets the size of the checkmark. /// @param {Number} $size - The size of the checkmark. /// @mixin checkmark-size($size, $query: feature-targeting.all()) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__checkmark { @include feature-targeting.targets($feat-structure) { @include theme.property(height, $size); @include theme.property(width, $size); } } } /// /// Customizes the checkmark color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `enabled`, `hover`, `focus`, `disabled`. /// /// @example /// @include checkmark-color(blue); /// @include checkmark-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The checkmark's color or a state Map /// @mixin checkmark-color($color-or-map, $query: feature-targeting.all()) { @include _checkmark-color(state.get-default-state($color-or-map), $query); &:not(.mdc-evolution-chip--disabled) { @include _checkmark-color(state.get-enabled-state($color-or-map), $query); } .mdc-evolution-chip__action--primary:not(.mdc-evolution-chip__action--presentational):hover { @include _checkmark-color(state.get-hover-state($color-or-map), $query); } .mdc-evolution-chip__action--primary { @include ripple-theme.focus() { @include _checkmark-color(state.get-focus-state($color-or-map), $query); } } &.mdc-evolution-chip--disabled { @include _checkmark-color(state.get-disabled-state($color-or-map), $query); } } @mixin _checkmark-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__checkmark { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(color, $color); } } } } /// /// Customizes the checkmark container color, using a Color or state Map. /// - To set only the default color, provide a single Color. /// - To set one or more state colors, provide a state Map with optional keys. /// - Supported state Map keys: `default`, `hover`, `focus`, `disabled`. /// /// @example /// @include checkmark-container-color(blue); /// @include checkmark-container-color((disabled: gray)); /// /// @param {Color | Map} $color-or-map - The checkmark container's color or a state Map /// @mixin checkmark-container-color( $color-or-map, $query: feature-targeting.all() ) { @include _checkmark-container-color( state.get-default-state($color-or-map), $query ); &.mdc-evolution-chip--disabled { @include _checkmark-container-color( state.get-disabled-state($color-or-map), $query ); } } @mixin _checkmark-container-color($color, $query: feature-targeting.all()) { $feat-color: feature-targeting.create-target($query, color); .mdc-evolution-chip__checkmark-background { @include feature-targeting.targets($feat-color) { @if $color { @include theme.property(background-color, $color); } } } } /// /// Sets the horizontal padding for the chip. /// @param {Number} $leading - The leading padding for the chip. /// @param {Number} $trailing [$leading] - The trailing padding for the chip. /// @mixin horizontal-padding( $leading, $trailing: $leading, $query: feature-targeting.all() ) { $feat-structure: feature-targeting.create-target($query, structure); .mdc-evolution-chip__action--primary { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property(padding, $leading, $trailing); } } } /// /// Sets the horizontal padding for chips with a graphic. /// @param {Number} $graphic-leading - The leading padding for the graphic. /// @param {Number} $graphic-trailing - The trailing padding for the graphic. /// @param {Number} $primary-trailing - The trailing padding for the primary action. /// @mixin with-graphic-horizontal-padding( $graphic-leading, $graphic-trailing, $primary-trailing, $query: feature-targeting.all() ) { $feat-structure: feature-targeting.create-target($query, structure); &.mdc-evolution-chip--with-primary-graphic { .mdc-evolution-chip__graphic { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property( padding, $graphic-leading, $graphic-trailing ); } } .mdc-evolution-chip__action--primary { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property(padding, 0, $primary-trailing); } } } } /// /// Sets the horizontal padding for chips with a trailing action. /// @param {Number} $primary-leading - The leading padding for the primary action. /// @param {Number} $trailing-action-leading - The leading padding for the trailing action. /// @param {Number} $trailing-action-trailing - The trailing padding for the trailing action. /// @mixin with-trailing-action-horizontal-padding( $primary-leading, $trailing-action-leading, $trailing-action-trailing, $query: feature-targeting.all() ) { $feat-structure: feature-targeting.create-target($query, structure); &.mdc-evolution-chip--with-trailing-action { .mdc-evolution-chip__action--trailing { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property( padding, $trailing-action-leading, $trailing-action-trailing ); } } #{$ripple-target-trailing} { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-position(left, $trailing-action-leading); } } .mdc-evolution-chip__action--primary { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property(padding, $primary-leading, 0); } } } } /// /// Sets the horizontal padding for chips with a graphic and trailing action. /// @param {Number} $graphic-leading - The leading padding for the graphic. /// @param {Number} $graphic-trailing - The trailing padding for the graphic. /// @param {Number} $trailing-action-leading - The leading padding for the trailing action. /// @param {Number} $trailing-action-trailing - The trailing padding for the trailing action. /// @mixin with-graphic-and-trailing-action-horizontal-padding( $graphic-leading, $graphic-trailing, $trailing-action-leading, $trailing-action-trailing, $query: feature-targeting.all() ) { $feat-structure: feature-targeting.create-target($query, structure); &.mdc-evolution-chip--with-primary-graphic.mdc-evolution-chip--with-trailing-action { .mdc-evolution-chip__graphic { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property( padding, $graphic-leading, $graphic-trailing ); } } .mdc-evolution-chip__action--trailing { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property( padding, $trailing-action-leading, $trailing-action-trailing ); } } #{$ripple-target-trailing} { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-position(left, $trailing-action-leading); } } .mdc-evolution-chip__action--primary { @include feature-targeting.targets($feat-structure) { @include rtl.reflexive-property(padding, 0, 0); } } } } @mixin _container-elevation-theme($theme) { @if map.get($theme, shadow) { @include elevation-theme.shadow(map.get($theme, shadow)); } @if map.get($theme, overlay-opacity) { @include elevation-theme.overlay-opacity(map.get($theme, overlay-opacity)); } // TODO(b/260053182): Remove setting overlay color after migration of customers @if map.get($theme, overlay-color) { @include elevation-theme.overlay-container-color( map.get($theme, overlay-color) ); } } // TODO(b/259913622): Use elevation's theme-style() mixin. @mixin _container-elevation($map) { $default-state: state.get-default-state($map); @if $default-state { @include _container-elevation-theme($default-state); } &:not(.mdc-evolution-chip--disabled) { $enabled-state: state.get-enabled-state($map); @if $enabled-state { @include _container-elevation-theme($enabled-state); } } @include ripple-theme.hover() { $hover-state: state.get-hover-state($map); @if $hover-state { @include _container-elevation-theme($hover-state); } } @include ripple-theme.focus() { $focus-state: state.get-focus-state($map); @if $focus-state { @include _container-elevation-theme($focus-state); } } @include ripple-theme.pressed() { $pressed-state: state.get-pressed-state($map); @if $pressed-state { @include _container-elevation-theme($pressed-state); } } &.mdc-evolution-chip--disabled { $disabled-state: state.get-disabled-state($map); @if $disabled-state { @include _container-elevation-theme($disabled-state); } } } @mixin button-cursor($cursor) { .mdc-evolution-chip__action { cursor: $cursor; } }