// // Copyright 2022 Google LLC // SPDX-License-Identifier: Apache-2.0 // // stylelint-disable selector-class-pattern -- // Selector '.md3-*' should only be used in this project. // go/keep-sorted start @use 'sass:map'; @use 'sass:meta'; // go/keep-sorted end // go/keep-sorted start @use '../../elevation/lib/elevation'; @use '../../focus/focus-ring'; @use '../../ripple/ripple'; @use '../../sass/shape'; @use '../../sass/theme'; @use '../../sass/touch-target'; // go/keep-sorted end @mixin styles() { :host { display: inline-flex; outline: none; -webkit-tap-highlight-color: transparent; /** * Override vertical-align with shortest value "top". Vertical-align's default * "baseline" value causes buttons to be misaligned next to each other if one * button has an icon and the other does not. */ vertical-align: top; } :host([disabled]) { cursor: default; pointer-events: none; } .md3-fab { display: inline-flex; border: none; outline: none; user-select: none; -webkit-appearance: none; vertical-align: middle; text-decoration: none; align-items: center; justify-content: center; position: relative; z-index: 0; // Needed for elevation and ripple background-color: var(--_container-color); @include focus-ring.theme( ( shape: shape.corners-to-shape-token(--_container-shape), ) ); @include ripple.theme( ( hover-color: var(--_hover-state-layer-color), focus-color: var(--_focus-state-layer-color), pressed-color: var(--_pressed-state-layer-color), hover-opacity: var(--_hover-state-layer-opacity), focus-opacity: var(--_focus-state-layer-opacity), pressed-opacity: var(--_pressed-state-layer-opacity), ) ); @include elevation.theme( ( // TODO: replace duration with animation tokens duration: 280ms, level: var(--_container-elevation), shadow-color: var(--_container-shadow-color), surface-tint: var(--_container-surface-tint-layer-color) ) ); &.md3-fab--lowered { @include elevation.theme( ( level: var(--_lowered-container-elevation), ) ); } // apply elevation in order of focused, hovered, pressed // this ensures a button will have hover elevation after being focused &:focus { @include elevation.theme( ( level: var(--_focus-container-elevation), ) ); &.md3-fab--lowered { @include elevation.theme( ( level: var(--_lowered-focus-container-elevation), ) ); } } &:hover { cursor: pointer; @include elevation.theme( ( level: var(--_hover-container-elevation), ) ); &.md3-fab--lowered { @include elevation.theme( ( level: var(--_lowered-hover-container-elevation), ) ); } } &:active { outline: none; @include elevation.theme( ( level: var(--_pressed-container-elevation), ) ); &.md3-fab--lowered { @include elevation.theme( ( level: var(--_lowered-pressed-container-elevation), ) ); } } } md-elevation { inset: 0; position: absolute; z-index: -1; // Place behind content } .md3-fab__ripple { overflow: hidden; z-index: -1; // Place behind content } .md3-fab, .md3-fab__ripple { border-start-start-radius: var(--_container-shape-start-start); border-start-end-radius: var(--_container-shape-start-end); border-end-start-radius: var(--_container-shape-end-start); border-end-end-radius: var(--_container-shape-end-end); } .md3-fab__icon { display: inline-flex; } .md3-fab__touch { @include touch-target.touch-target(); } .md3-fab__icon ::slotted(*), .md3-fab__icon { color: var(--_icon-color); font-size: var(--_icon-size); height: var(--_icon-size); width: var(--_icon-size); .md3-fab:hover & { color: var(--_hover-icon-color); } .md3-fab:focus & { color: var(--_focus-icon-color); } .md3-fab:active & { color: var(--_pressed-icon-color); } } @media (forced-colors: active) { .md3-fab { // Adjust the focus ring padding to account for the 1px border in HCM. @include focus-ring.theme( ( offset-vertical: 3px, offset-horizontal: 3px, ) ); border: 1px solid ButtonText; } } } @function resolve-tokens($tokens) { $tokens: elevation.resolve-tokens( $tokens, 'container-elevation', 'focus-container-elevation', 'hover-container-elevation', 'pressed-container-elevation', 'lowered-container-elevation', 'lowered-focus-container-elevation', 'lowered-hover-container-elevation', 'lowered-pressed-container-elevation' ); @return $tokens; }