2024-03-05 13:24:40 -08:00

249 lines
5.9 KiB
SCSS

//
// Copyright 2022 Google LLC
// SPDX-License-Identifier: Apache-2.0
//
// go/keep-sorted start
@use 'sass:map';
// go/keep-sorted end
// go/keep-sorted start
@use '../../elevation/elevation';
@use '../../focus/focus-ring';
@use '../../ripple/ripple';
@use '../../tokens';
@use './fab';
// go/keep-sorted end
$_md-sys-motion: tokens.md-sys-motion-values();
@mixin styles() {
:host {
@include ripple.theme(
(
hover-opacity: var(--_hover-state-layer-opacity),
pressed-opacity: var(--_pressed-state-layer-opacity),
)
);
display: inline-flex;
-webkit-tap-highlight-color: transparent;
}
:host([size='medium'][touch-target='wrapper']) {
margin: max(0px, 48px - var(--_container-height));
}
:host([size='large'][touch-target='wrapper']) {
margin: max(0px, 48px - var(--_large-container-height));
}
.fab,
.icon,
.icon ::slotted(*) {
display: flex;
}
.fab {
align-items: center;
justify-content: center;
vertical-align: middle;
padding: 0;
position: relative;
height: var(--_container-height);
transition-property: background-color;
border-width: 0px;
outline: none;
// Required for elevation and ripple to stay below content
z-index: 0;
// Override the user-agent text-transform: none of <button>
text-transform: inherit;
&.extended {
width: inherit;
box-sizing: border-box;
padding-inline-start: 16px;
padding-inline-end: 20px;
}
&:not(.extended) {
width: var(--_container-width);
}
&.large {
width: var(--_large-container-width);
height: var(--_large-container-height);
.icon ::slotted(*) {
width: var(--_large-icon-size);
height: var(--_large-icon-size);
font-size: var(--_large-icon-size);
}
&,
.ripple {
border-start-start-radius: var(--_large-container-shape-start-start);
border-start-end-radius: var(--_large-container-shape-start-end);
border-end-start-radius: var(--_large-container-shape-end-start);
border-end-end-radius: var(--_large-container-shape-end-end);
}
md-focus-ring {
@include focus-ring.theme(
(
'shape-start-start': var(--_large-container-shape-start-start),
'shape-start-end': var(--_large-container-shape-start-end),
'shape-end-end': var(--_large-container-shape-end-end),
'shape-end-start': var(--_large-container-shape-end-start),
)
);
}
}
@include _elevation(
(
'default': var(--_container-elevation),
'focus': var(--_focus-container-elevation),
'hover': var(--_hover-container-elevation),
'pressed': var(--_pressed-container-elevation),
),
var(--_container-shadow-color)
);
&.lowered {
background-color: var(--_lowered-container-color);
@include _elevation(
(
'default': var(--_lowered-container-elevation),
'focus': var(--_lowered-focus-container-elevation),
'hover': var(--_lowered-hover-container-elevation),
'pressed': var(--_lowered-pressed-container-elevation),
)
);
}
@include fab.color(
(
'container-color': var(--_container-color),
'hover-state-layer-color': var(--_hover-state-layer-color),
'pressed-state-layer-color': var(--_pressed-state-layer-color),
'label-text-color': var(--_label-text-color),
'hover-label-text-color': var(--_hover-label-text-color),
'focus-label-text-color': var(--_focus-label-text-color),
'pressed-label-text-color': var(--_pressed-label-text-color),
)
);
}
.label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: var(--_label-text-font);
font-size: var(--_label-text-size);
line-height: var(--_label-text-line-height);
font-weight: var(--_label-text-weight);
}
.fab.extended .icon ::slotted(*) {
margin-inline-end: 12px;
}
.ripple {
overflow: hidden;
}
.ripple,
md-elevation {
// puts both behind content
z-index: -1;
}
.touch-target {
position: absolute;
top: 50%;
height: 48px;
left: 50%;
width: 48px;
transform: translate(-50%, -50%);
}
:host([touch-target='none']) .touch-target {
display: none;
}
md-elevation,
.fab {
// TODO: replace duration with animation tokens
transition-duration: 280ms;
transition-timing-function: map.get($_md-sys-motion, 'easing-emphasized');
}
.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);
}
md-focus-ring {
@include focus-ring.theme(
(
'shape-start-start': var(--_container-shape-start-start),
'shape-start-end': var(--_container-shape-start-end),
'shape-end-end': var(--_container-shape-end-end),
'shape-end-start': var(--_container-shape-end-start),
)
);
}
.icon ::slotted(*) {
width: var(--_icon-size);
height: var(--_icon-size);
font-size: var(--_icon-size);
}
}
@mixin _elevation($states, $shadow-color: null) {
@include elevation.theme(
(
'level': map.get($states, 'default'),
)
);
@if $shadow-color {
@include elevation.theme(
(
'shadow-color': $shadow-color,
)
);
}
// apply elevation in order of focused, hovered, pressed, disabled
// this ensures a button will have hover elevation after being focused
&:focus {
@include elevation.theme(
(
'level': map.get($states, 'focus'),
)
);
}
&:hover {
@include elevation.theme(
(
'level': map.get($states, 'hover'),
)
);
}
&:active {
@include elevation.theme(
(
'level': map.get($states, 'pressed'),
)
);
}
}