@use './button-base'; @use '../core/tokens/token-utils'; @use '../core/style/private' as style-private; @use '../core/style/vendor-prefixes'; @use '../core/focus-indicators/private' as focus-indicators-private; @use '../core/tokens/m2/mdc/extended-fab' as tokens-mdc-extended-fab; @use '../core/tokens/m2/mdc/fab' as tokens-mdc-fab; @use '../core/tokens/m2/mat/fab' as tokens-mat-fab; @use '../core/tokens/m2/mdc/fab-small' as tokens-mdc-fab-small; @use '../core/tokens/m2/mat/fab-small' as tokens-mat-fab-small; .mat-mdc-fab-base { @include vendor-prefixes.user-select(none); position: relative; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: 56px; height: 56px; padding: 0; border: none; fill: currentColor; text-decoration: none; cursor: pointer; -moz-appearance: none; -webkit-appearance: none; overflow: visible; transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1), opacity 15ms linear 30ms, transform 270ms 0ms cubic-bezier(0, 0, 0.2, 1); flex-shrink: 0; // Prevent the button from shrinking since it's always supposed to be a circle. @include button-base.mat-private-button-interactive(); @include style-private.private-animation-noop(); &::before { position: absolute; box-sizing: border-box; width: 100%; height: 100%; top: 0; left: 0; border: 1px solid transparent; border-radius: inherit; content: ''; pointer-events: none; } // MDC used to include this and it seems like a lot of apps depend on it. &[hidden] { display: none; } &::-moz-focus-inner { padding: 0; border: 0; } &:active, &:focus { outline: none; } &:hover { cursor: pointer; } & > svg { width: 100%; } // MDC expects the fab icon to contain this HTML content: // ```html // favorite // ``` // However, Angular Material expects a `mat-icon` instead. The following // mixin will style the icons appropriately. // stylelint-disable-next-line selector-class-pattern .mat-icon, .material-icons { transition: transform 180ms 90ms cubic-bezier(0, 0, 0.2, 1); fill: currentColor; will-change: transform; } .mat-focus-indicator::before { $default-border-width: focus-indicators-private.$default-border-width; $border-width: var(--mat-focus-indicator-border-width, #{$default-border-width}); $offset: calc(#{$border-width} + 2px); margin: calc(#{$offset} * -1); } @include button-base.mat-private-button-disabled { // Necessary for interactive disabled buttons. &, &:focus { box-shadow: none; } } } @mixin _fab-elevation($mdc-tokens) { @include token-utils.use-tokens($mdc-tokens...) { @include token-utils.create-token-slot(box-shadow, container-elevation-shadow); &:hover { @include token-utils.create-token-slot(box-shadow, hover-container-elevation-shadow); } &:focus { @include token-utils.create-token-slot(box-shadow, focus-container-elevation-shadow); } &:active, &:focus:active { @include token-utils.create-token-slot(box-shadow, pressed-container-elevation-shadow); } } } @mixin _fab-structure($mdc-tokens, $mat-tokens) { @include token-utils.use-tokens($mdc-tokens...) { @include token-utils.create-token-slot(background-color, container-color); @include token-utils.create-token-slot(border-radius, container-shape); } @include token-utils.use-tokens($mat-tokens...) { @include token-utils.create-token-slot(color, foreground-color, inherit); } @include _fab-elevation($mdc-tokens); @include button-base.mat-private-button-disabled { @include token-utils.use-tokens($mat-tokens...) { @include token-utils.create-token-slot(color, disabled-state-foreground-color); @include token-utils.create-token-slot(background-color, disabled-state-container-color); } } @include button-base.mat-private-button-touch-target(true, $mat-tokens...); @include button-base.mat-private-button-ripple($mat-tokens...); } .mat-mdc-fab { @include _fab-structure( (tokens-mdc-fab.$prefix, tokens-mdc-fab.get-token-slots()), (tokens-mat-fab.$prefix, tokens-mat-fab.get-token-slots()), ); } .mat-mdc-mini-fab { width: 40px; height: 40px; @include _fab-structure( (tokens-mdc-fab-small.$prefix, tokens-mdc-fab-small.get-token-slots()), (tokens-mat-fab-small.$prefix, tokens-mat-fab-small.get-token-slots()), ); } .mat-mdc-extended-fab { $mdc-tokens: (tokens-mdc-extended-fab.$prefix, tokens-mdc-extended-fab.get-token-slots()); // Before tokens MDC included the font smoothing automatically, but with // tokens it doesn't. We add it since it can cause tiny differences in // screenshot tests and it generally looks better. @include vendor-prefixes.smooth-font(); border-radius: 24px; padding-left: 20px; padding-right: 20px; width: auto; max-width: 100%; line-height: normal; @include token-utils.use-tokens($mdc-tokens...) { @include token-utils.create-token-slot(height, container-height); @include token-utils.create-token-slot(border-radius, container-shape); @include token-utils.create-token-slot(font-family, label-text-font); @include token-utils.create-token-slot(font-size, label-text-size); @include token-utils.create-token-slot(font-weight, label-text-weight); @include token-utils.create-token-slot(letter-spacing, label-text-tracking); } @include _fab-elevation($mdc-tokens); @include button-base.mat-private-button-disabled { // Necessary for interactive disabled buttons. &, &:focus { box-shadow: none; } } // stylelint-disable selector-class-pattern // For Extended FAB with text label followed by icon. // We are checking for the a button class because white this is a FAB it // uses the same template as button. [dir='rtl'] & .mdc-button__label + .mat-icon, [dir='rtl'] & .mdc-button__label + .material-icons, > .mat-icon, > .material-icons { margin-left: -8px; margin-right: 12px; } .mdc-button__label + .mat-icon, .mdc-button__label + .material-icons, [dir='rtl'] & > .mat-icon, [dir='rtl'] & > .material-icons { margin-left: 12px; margin-right: -8px; } // stylelint-enable selector-class-pattern // All FABs are square except the extended ones so we // need to set the touch target back to full-width. .mat-mdc-button-touch-target { width: 100%; } }