// Copyright 2016 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. @import "@material/animation/functions"; @import "@material/elevation/mixins"; @import "@material/elevation/variables"; @import "@material/feature-targeting/functions"; @import "@material/feature-targeting/mixins"; @import "@material/ripple/mixins"; @import "@material/ripple/variables"; @import "@material/theme/functions"; @import "@material/theme/mixins"; @import "@material/shape/mixins"; @import "@material/shape/functions"; @import "@material/rtl/mixins"; @import "@material/typography/mixins"; @import "./variables"; $mdc-fab-ripple-target: ".mdc-fab__ripple"; @mixin mdc-fab-core-styles($query: mdc-feature-all()) { @include mdc-fab-without-ripple($query); @include mdc-fab-ripple($query); } @mixin mdc-fab-without-ripple($query: mdc-feature-all()) { // postcss-bem-linter: define fab .mdc-fab { @include mdc-fab-base_($query: $query); @include mdc-fab-container-color(secondary, $query: $query); @include mdc-fab-icon-size(24px, $query: $query); @include mdc-fab-ink-color(on-secondary, $query: $query); } .mdc-fab--mini { @include mdc-fab--mini_($query: $query); } .mdc-fab--extended { @include mdc-fab--extended_($query: $query); } .mdc-fab__label { @include mdc-fab--label_($query: $query); } .mdc-fab__icon { @include mdc-fab__icon_($query: $query); } // Increase specificity for FAB icon styles that need to override styles defined for .material-icons // (which is loaded separately so the order of CSS definitions is not guaranteed) .mdc-fab .mdc-fab__icon { @include mdc-fab__icon-overrides_($query: $query); } .mdc-fab--exited { @include mdc-fab--exited_($query: $query); } // postcss-bem-linter: end } @mixin mdc-fab-ripple($query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); @include mdc-ripple-common($query); // postcss-bem-linter: define fab .mdc-fab { @include mdc-ripple-surface( $query: $query, $ripple-target: $mdc-fab-ripple-target); @include mdc-ripple-radius-bounded( $query: $query, $ripple-target: $mdc-fab-ripple-target); @include mdc-states( on-secondary, $query: $query, $ripple-target: $mdc-fab-ripple-target); // stylelint-disable-next-line plugin/selector-bem-pattern #{$mdc-fab-ripple-target} { @include mdc-ripple-target-common($query: $query); overflow: hidden; } } // postcss-bem-linter: end } @mixin mdc-fab-accessible($container-color, $query: mdc-feature-all()) { @include mdc-fab-container-color($container-color, $query: $query); $fill-tone: mdc-theme-tone($container-color); @if ($fill-tone == "dark") { @include mdc-fab-ink-color(text-primary-on-dark, $query: $query); @include mdc-states( text-primary-on-dark, $query: $query, $ripple-target: $mdc-fab-ripple-target); } @else { @include mdc-fab-ink-color(text-primary-on-light, $query: $query); @include mdc-states( text-primary-on-light, $query: $query, $ripple-target: $mdc-fab-ripple-target); } } @mixin mdc-fab-container-color($color, $query: mdc-feature-all()) { $feat-color: mdc-feature-create-target($query, color); @include mdc-feature-targets($feat-color) { @include mdc-theme-prop(background-color, $color, $edgeOptOut: true); } } @mixin mdc-fab-icon-size($width, $height: $width, $query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); .mdc-fab__icon { @include mdc-feature-targets($feat-structure) { width: $width; height: $height; font-size: $height; } } } @mixin mdc-fab-ink-color($color, $query: mdc-feature-all()) { $feat-color: mdc-feature-create-target($query, color); @include mdc-feature-targets($feat-color) { @include mdc-theme-prop(color, $color); } } @mixin mdc-fab-extended-fluid($query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { width: 100%; } } @mixin mdc-fab-extended-padding($icon-padding, $label-padding, $query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); @include mdc-fab-extended-label-padding($label-padding, $query: $query); // Offsets the outer label padding by deducting it from icon padding. .mdc-fab__icon { @include mdc-feature-targets($feat-structure) { @include mdc-rtl-reflexive-property(margin, $icon-padding - $label-padding, $icon-padding); } } // For Extended FAB with text label followed by icon. .mdc-fab__label + .mdc-fab__icon { @include mdc-feature-targets($feat-structure) { @include mdc-rtl-reflexive-property(margin, $icon-padding, $icon-padding - $label-padding); } } } @mixin mdc-fab-extended-label-padding($label-padding, $query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { padding: 0 $label-padding; } } @mixin mdc-fab-shape-radius($radius, $rtl-reflexive: false, $query: mdc-feature-all()) { &:not(.mdc-fab--extended) { @include mdc-shape-radius($radius, $rtl-reflexive, $query: $query); #{$mdc-fab-ripple-target} { @include mdc-shape-radius($radius, $rtl-reflexive, $query: $query); } } } @mixin mdc-fab-extended-shape-radius($radius, $rtl-reflexive: false, $query: mdc-feature-all()) { @include mdc-shape-radius( mdc-shape-resolve-percentage-radius($mdc-fab-extended-height, $radius), $rtl-reflexive, $query: $query ); #{$mdc-fab-ripple-target} { @include mdc-shape-radius( mdc-shape-resolve-percentage-radius($mdc-fab-extended-height, $radius), $rtl-reflexive, $query: $query ); } } $mdc-fab-icon-enter-delay_: 90ms; $mdc-fab-icon-enter-duration_: 180ms; @mixin mdc-fab-base_($query: mdc-feature-all()) { @include mdc-elevation(6, $query: $query); @include mdc-fab-shape-radius(50%, $query: $query); $feat-animation: mdc-feature-create-target($query, animation); $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { display: inline-flex; position: relative; align-items: center; justify-content: center; box-sizing: border-box; width: $mdc-fab-height; height: $mdc-fab-height; padding: 0; border: none; fill: currentColor; text-decoration: none; cursor: pointer; user-select: none; -moz-appearance: none; -webkit-appearance: none; } @include mdc-feature-targets($feat-animation) { transition: box-shadow $mdc-elevation-transition-duration $mdc-elevation-transition-timing-function, opacity 15ms linear 30ms, mdc-animation-enter(transform, $mdc-fab-icon-enter-duration_ + $mdc-fab-icon-enter-delay_); } &::-moz-focus-inner { @include mdc-feature-targets($feat-structure) { padding: 0; border: 0; } } &:hover, &:focus { @include mdc-elevation(8, $query: $query); } &:active { @include mdc-elevation(12, $query: $query); } &:active, &:focus { // TODO(acdvorak): Should this be paired with states and/or ripple? We don't want to disable outline // (an accessibility/usability feature) unless we're confident that there is also a visual indication that the // element has focus. If the client has customized the DOM in some unexpected way, and is certain that another // element will receive focus instead, they can always override this property manually in their CSS. @include mdc-feature-targets($feat-structure) { outline: none; } } &:hover { @include mdc-feature-targets($feat-structure) { cursor: pointer; } } // This allows for using SVGs within them to align properly in all browsers. // Can remove once: https://bugzilla.mozilla.org/show_bug.cgi?id=1294515 is resolved. // stylelint-disable selector-max-type // postcss-bem-linter: ignore > svg { @include mdc-feature-targets($feat-structure) { width: 100%; } } // stylelint-enable selector-max-type } @mixin mdc-fab--mini_($query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { width: $mdc-fab-mini-height; height: $mdc-fab-mini-height; } } @mixin mdc-fab--extended_($query: mdc-feature-all()) { @include mdc-typography(button, $query: $query); @include mdc-fab-extended-shape-radius(50%, $query: $query); @include mdc-fab-extended-padding($mdc-fab-extended-icon-padding, $mdc-fab-extended-label-padding, $query: $query); $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { width: auto; max-width: 100%; height: $mdc-fab-extended-height; } } @mixin mdc-fab__icon_($query: mdc-feature-all()) { $feat-animation: mdc-feature-create-target($query, animation); $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-animation) { transition: mdc-animation-enter(transform, $mdc-fab-icon-enter-duration_, $mdc-fab-icon-enter-delay_); } @include mdc-feature-targets($feat-structure) { fill: currentColor; will-change: transform; } } @mixin mdc-fab__label_($query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { justify-content: flex-start; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } } @mixin mdc-fab__icon-overrides_($query: mdc-feature-all()) { $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { display: inline-flex; align-items: center; justify-content: center; } } @mixin mdc-fab--exited_($query: mdc-feature-all()) { $feat-animation: mdc-feature-create-target($query, animation); $feat-structure: mdc-feature-create-target($query, structure); @include mdc-feature-targets($feat-structure) { transform: scale(0); opacity: 0; } @include mdc-feature-targets($feat-animation) { transition: opacity 15ms linear 150ms, mdc-animation-exit-permanent(transform, 180ms); } .mdc-fab__icon { @include mdc-feature-targets($feat-structure) { transform: scale(0); } @include mdc-feature-targets($feat-animation) { transition: mdc-animation-exit-permanent(transform, 135ms); } } }