mirror of
https://github.com/material-components/material-web.git
synced 2026-03-09 00:09:23 +08:00
249 lines
5.9 KiB
SCSS
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'),
|
|
)
|
|
);
|
|
}
|
|
}
|