File: /var/dev/nowruzgan/ketabkhaneh/node_modules/@material/icon-button/_icon-button-theme.scss
//
// Copyright 2021 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.
//
// stylelint-disable selector-class-pattern --
// Selector '.mdc-*' should only be used in this project.
@use 'sass:math';
@use 'sass:map';
@use 'sass:meta';
@use '@material/density/functions' as density-functions;
@use '@material/density/variables' as density-variables;
@use '@material/elevation/elevation-theme';
@use '@material/feature-targeting/feature-targeting';
@use '@material/focus-ring/focus-ring';
@use '@material/ripple/ripple-theme';
@use '@material/rtl/rtl';
@use '@material/dom/dom';
@use '@material/theme/custom-properties';
@use '@material/theme/keys';
@use '@material/theme/state';
@use '@material/theme/theme';
@use '@material/theme/theme-color';
@use '@material/touch-target/mixins' as touch-target-mixins;
$ripple-target: '.mdc-icon-button__ripple';
$icon-size: 24px !default;
$size: 48px !default;
$minimum-height: 28px !default;
$maximum-height: $size !default;
$container-shape: 50%;
$density-scale: density-variables.$default-scale !default;
$density-config: (
size: (
default: $size,
maximum: $maximum-height,
minimum: $minimum-height,
),
) !default;
$_custom-property-prefix: 'icon-button';
$light-theme: (
disabled-icon-color: theme-color.$on-surface,
disabled-icon-opacity: 0.38,
icon-color: theme-color.$primary,
icon-size: $icon-size,
focus-icon-color: theme-color.$primary,
focus-state-layer-color: theme-color.$primary,
focus-state-layer-opacity: 0.12,
hover-icon-color: theme-color.$primary,
hover-state-layer-color: theme-color.$primary,
hover-state-layer-opacity: 0.08,
pressed-icon-color: theme-color.$primary,
pressed-state-layer-color: theme-color.$primary,
pressed-state-layer-opacity: 0.12,
state-layer-size: $size,
focus-ring-color: null,
focus-ring-offset: 0,
);
@mixin theme($theme) {
@include theme.validate-theme($light-theme, $theme);
@include keys.declare-custom-properties(
$theme,
$prefix: $_custom-property-prefix
);
}
@mixin theme-styles($theme) {
@include theme.validate-theme-styles($light-theme, $theme);
$theme: keys.create-theme-properties(
$theme,
$prefix: $_custom-property-prefix
);
@include _state-layer-size($size: map.get($theme, state-layer-size));
@include _icon-size(map.get($theme, icon-size));
@include _disabled-icon-opacity(map.get($theme, disabled-icon-opacity));
@include _icon-color-with-map(
(
default: map.get($theme, icon-color),
disabled: map.get($theme, disabled-icon-color),
focus: map.get($theme, focus-icon-color),
hover: map.get($theme, hover-icon-color),
pressed: map.get($theme, pressed-icon-color),
)
);
// States styles
@include ripple-theme.theme-styles(
(
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),
),
$ripple-target: $ripple-target
);
@include ripple-theme.states-colors(
(
hover: map.get($theme, hover-state-layer-color),
press: map.get($theme, pressed-state-layer-color),
),
$ripple-target: $ripple-target
);
@include _focus-ring-color(map.get($theme, 'focus-ring-color'));
@include _focus-ring-offset(map.get($theme, 'focus-ring-offset'));
}
///
/// Sets the density scale for icon button.
///
/// @param {Number | String} $density-scale - Density scale value for component.
/// Supported density scale values range from `-5` to `0`, with `0` being the default.
///
@mixin density($density-scale, $query: feature-targeting.all()) {
$size: density-functions.prop-value(
$density-config: $density-config,
$density-scale: $density-scale,
$property-name: size,
);
@include size($size, $query: $query);
}
///
/// Sets the size of the icon-button.
///
/// @param {Number} $size - Size value for icon-button.
/// Size will set the width, height, and padding for the overall component.
///
@mixin size($size, $query: feature-targeting.all()) {
$feat-structure: feature-targeting.create-target($query, structure);
@include feature-targeting.targets($feat-structure) {
width: $size;
height: $size;
padding: calc(($size - $icon-size) / 2);
}
&.mdc-icon-button--reduced-size {
$component-size: $size;
// Icon button ripple size is capped at 40px for icon buttons with
// densities -1 and 0 (icon buttons with sizes 44x44 and 48x48px).
// See http://b/192353968 for more info.
@if math.unit($size) == 'px' and ($size >= 40px and $size <= 48px) {
$component-size: 40px;
}
.mdc-icon-button__ripple {
@include feature-targeting.targets($feat-structure) {
width: $component-size;
height: $component-size;
}
@include touch-target-mixins.margin(
$component-height: $component-size,
$component-width: $component-size,
$touch-target-height: $size,
$touch-target-width: $size,
$query: $query
);
}
.mdc-icon-button__focus-ring {
@include feature-targeting.targets($feat-structure) {
max-height: $component-size;
max-width: $component-size;
}
}
}
.mdc-icon-button__touch {
@include touch-target-mixins.touch-target(
$set-width: true,
$query: $query,
$height: $size,
$width: $size
);
}
}
///
/// Sets the width, height and padding of icon button. Also changes the size of
/// the icon itself based on button size.
///
/// @param {Number} $width - Width value for icon-button.
/// @param {Number} $height - Height value for icon-button. (default: $width)
/// @param {Number} $padding - Padding value for icon-button. (default: max($width, $height) / 2)
/// @deprecated
/// This mixin provides too much of low level customization.
/// Please use mdc-icon-button-size instead.
///
@mixin icon-size(
$width,
$height: $width,
$padding: math.div(math.max($width, $height), 2),
$query: feature-targeting.all()
) {
$feat-structure: feature-targeting.create-target($query, structure);
$component-width: $width + $padding * 2;
$component-height: $height + $padding * 2;
@include feature-targeting.targets($feat-structure) {
width: $component-width;
height: $component-height;
padding: $padding;
font-size: math.max($width, $height);
}
svg,
img {
@include feature-targeting.targets($feat-structure) {
width: $width;
height: $height;
}
}
}
///
/// Sets the font color and the ripple color to the provided color value.
/// @param {Color} $color - The desired font and ripple color.
///
@mixin ink-color($color, $query: feature-targeting.all()) {
@if $color {
@include ink-color_($color, $query: $query);
@include ripple-theme.states(
$color,
$query: $query,
$ripple-target: $ripple-target
);
}
}
///
/// Flips icon only in RTL context.
///
@mixin flip-icon-in-rtl($query: feature-targeting.all()) {
$feat-structure: feature-targeting.create-target($query, structure);
.mdc-button__icon {
@include rtl.rtl {
@include feature-targeting.targets($feat-structure) {
@include rtl.ignore-next-line();
transform: rotate(180deg);
}
}
}
}
///
/// Sets the font color to the provided color value for a disabled icon button.
/// @param {Color} $color - The desired font color.
///
@mixin disabled-ink-color($color, $query: feature-targeting.all()) {
@include if-disabled_ {
@include ink-color_($color, $query: $query);
}
}
///
/// Includes ad-hoc high contrast mode support.
///
@mixin high-contrast-mode-shim($query: feature-targeting.all()) {
$feat-structure: feature-targeting.create-target($query, structure);
@include feature-targeting.targets($feat-structure) {
// TODO(b/175806874): Use the DOM border mixin after the ripple is moved
// away from :before to a dedicated element.
outline: solid 3px transparent;
&:focus {
outline: double 5px transparent;
}
}
}
///
/// Sets the font color to the provided color value. This can be wrapped in
/// a state qualifier such as `mdc-icon-button-if-disabled_`.
/// @access private
///
@mixin ink-color_($color, $query: feature-targeting.all()) {
$feat-color: feature-targeting.create-target($query, color);
@include feature-targeting.targets($feat-color) {
@include theme.property(color, $color);
}
}
@mixin _state-layer-size($size) {
@include theme.property(height, $size);
@include theme.property(width, $size);
@if $size {
$value: custom-properties.get-declaration-value($size);
@if type-of($value) == 'number' {
@include size($value);
}
}
}
@mixin _icon-size($size) {
.mdc-button__icon {
@include theme.property(font-size, $size);
}
svg,
img {
@include theme.property(width, $size);
@include theme.property(height, $size);
}
}
///
/// Sets the icon opacity to the given opacity.
/// @access private
///
@mixin _disabled-icon-opacity($opacity) {
&:disabled {
@include theme.property(opacity, $opacity);
}
}
///
/// Sets the icon color to the given color.
/// @param {map} $color-map - The desired icon color, specified as a map of
/// colors with states {default, disabled, focus, hover, pressed} as keys.
/// @access private
///
@mixin _icon-color-with-map($color-map) {
@include ink-color_(state.get-default-state($color-map));
$focus: state.get-focus-state($color-map);
@if $focus {
@include ripple-theme.focus {
@include ink-color_($focus);
}
}
$hover: state.get-hover-state($color-map);
@if $hover {
&:hover {
@include ink-color_($hover);
}
}
$pressed: state.get-pressed-state($color-map);
@if $pressed {
@include ripple-theme.active {
@include ink-color_($pressed);
}
}
$disabled: state.get-disabled-state($color-map);
@if $disabled {
&:disabled {
@include ink-color_($disabled);
}
}
}
@mixin _states-colors($color-map) {
// TODO(b/191298796): support focused & pressed key colors.
$hover: map.get($color-map, hover);
@if $hover {
@include ripple-theme.states-base-color(
$color: $hover,
$ripple-target: $ripple-target
);
}
}
@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
);
@if $color != null {
.mdc-icon-button__focus-ring {
@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
);
@if type-of($offset-value) == 'number' {
.mdc-icon-button__focus-ring {
@include focus-ring.focus-ring-offset(
$offset: $offset-value,
$query: $query
);
}
}
}
///
/// Helps style the icon button in its disabled state.
/// @access private
///
@mixin if-disabled_ {
&:disabled {
@content;
}
}