mirror of
https://github.com/material-components/material-web.git
synced 2026-03-09 00:09:23 +08:00
266 lines
8.1 KiB
SCSS
266 lines
8.1 KiB
SCSS
//
|
|
// Copyright 2022 Google LLC
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
// go/keep-sorted start
|
|
@use 'sass:list';
|
|
@use 'sass:map';
|
|
// go/keep-sorted end
|
|
// go/keep-sorted start
|
|
@use '../../focus/focus-ring';
|
|
@use '../../ripple/ripple';
|
|
@use '../../tokens';
|
|
// go/keep-sorted end
|
|
|
|
@mixin theme($tokens) {
|
|
$supported-tokens: list.join(
|
|
tokens.$md-comp-fab-supported-tokens,
|
|
(
|
|
'container-shape-start-start',
|
|
'container-shape-start-end',
|
|
'container-shape-end-end',
|
|
'container-shape-end-start',
|
|
'large-container-shape-start-start',
|
|
'large-container-shape-start-end',
|
|
'large-container-shape-end-end',
|
|
'large-container-shape-end-start',
|
|
'small-container-shape-start-start',
|
|
'small-container-shape-start-end',
|
|
'small-container-shape-end-end',
|
|
'small-container-shape-end-start'
|
|
)
|
|
);
|
|
|
|
@each $token, $value in $tokens {
|
|
@if list.index($supported-tokens, $token) == null {
|
|
@error 'Token `#{$token}` is not a supported token.';
|
|
}
|
|
|
|
@if $value {
|
|
--md-fab-#{$token}: #{$value};
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin styles() {
|
|
$tokens: tokens.md-comp-fab-values();
|
|
|
|
:host {
|
|
@each $token, $value in $tokens {
|
|
--_#{$token}: var(--md-fab-#{$token}, #{$value});
|
|
}
|
|
|
|
// Support logical shape properties
|
|
--_container-shape-start-start: var(
|
|
--md-fab-container-shape-start-start,
|
|
var(--_container-shape)
|
|
);
|
|
--_container-shape-start-end: var(
|
|
--md-fab-container-shape-start-end,
|
|
var(--_container-shape)
|
|
);
|
|
--_container-shape-end-end: var(
|
|
--md-fab-container-shape-end-end,
|
|
var(--_container-shape)
|
|
);
|
|
--_container-shape-end-start: var(
|
|
--md-fab-container-shape-end-start,
|
|
var(--_container-shape)
|
|
);
|
|
--_large-container-shape-start-start: var(
|
|
--md-fab-large-container-shape-start-start,
|
|
var(--_large-container-shape)
|
|
);
|
|
--_large-container-shape-start-end: var(
|
|
--md-fab-large-container-shape-start-end,
|
|
var(--_large-container-shape)
|
|
);
|
|
--_large-container-shape-end-end: var(
|
|
--md-fab-large-container-shape-end-end,
|
|
var(--_large-container-shape)
|
|
);
|
|
--_large-container-shape-end-start: var(
|
|
--md-fab-large-container-shape-end-start,
|
|
var(--_large-container-shape)
|
|
);
|
|
--_small-container-shape-start-start: var(
|
|
--md-fab-small-container-shape-start-start,
|
|
var(--_small-container-shape)
|
|
);
|
|
--_small-container-shape-start-end: var(
|
|
--md-fab-small-container-shape-start-end,
|
|
var(--_small-container-shape)
|
|
);
|
|
--_small-container-shape-end-end: var(
|
|
--md-fab-small-container-shape-end-end,
|
|
var(--_small-container-shape)
|
|
);
|
|
--_small-container-shape-end-start: var(
|
|
--md-fab-small-container-shape-end-start,
|
|
var(--_small-container-shape)
|
|
);
|
|
|
|
cursor: pointer;
|
|
}
|
|
|
|
:host([size='small'][touch-target='wrapper']) {
|
|
margin: max(0px, 48px - var(--_small-container-height));
|
|
}
|
|
|
|
.fab {
|
|
@include color(
|
|
(
|
|
'focus-icon-color': var(--_focus-icon-color),
|
|
'hover-icon-color': var(--_hover-icon-color),
|
|
'icon-color': var(--_icon-color),
|
|
'pressed-icon-color': var(--_pressed-icon-color),
|
|
)
|
|
);
|
|
|
|
cursor: inherit;
|
|
|
|
&.primary {
|
|
@include color(
|
|
(
|
|
'container-color': var(--_primary-container-color),
|
|
'focus-icon-color': var(--_primary-focus-icon-color),
|
|
'hover-icon-color': var(--_primary-hover-icon-color),
|
|
'hover-state-layer-color': var(--_primary-hover-state-layer-color),
|
|
'icon-color': var(--_primary-icon-color),
|
|
'pressed-icon-color': var(--_primary-pressed-icon-color),
|
|
'pressed-state-layer-color': var(--_primary-pressed-state-layer-color),
|
|
'label-text-color': var(--_primary-label-text-color),
|
|
'hover-label-text-color': var(--_primary-hover-label-text-color),
|
|
'focus-label-text-color': var(--_primary-focus-label-text-color),
|
|
'pressed-label-text-color': var(--_primary-pressed-label-text-color),
|
|
)
|
|
);
|
|
}
|
|
|
|
&.secondary {
|
|
@include color(
|
|
(
|
|
'container-color': var(--_secondary-container-color),
|
|
'focus-icon-color': var(--_secondary-focus-icon-color),
|
|
'hover-icon-color': var(--_secondary-hover-icon-color),
|
|
'hover-state-layer-color': var(--_secondary-hover-state-layer-color),
|
|
'icon-color': var(--_secondary-icon-color),
|
|
'pressed-icon-color': var(--_secondary-pressed-icon-color),
|
|
'pressed-state-layer-color':
|
|
var(--_secondary-pressed-state-layer-color),
|
|
'label-text-color': var(--_secondary-label-text-color),
|
|
'hover-label-text-color': var(--_secondary-hover-label-text-color),
|
|
'focus-label-text-color': var(--_secondary-focus-label-text-color),
|
|
'pressed-label-text-color': var(--_secondary-pressed-label-text-color),
|
|
)
|
|
);
|
|
}
|
|
|
|
&.tertiary {
|
|
@include color(
|
|
(
|
|
'container-color': var(--_tertiary-container-color),
|
|
'focus-icon-color': var(--_tertiary-focus-icon-color),
|
|
'hover-icon-color': var(--_tertiary-hover-icon-color),
|
|
'hover-state-layer-color': var(--_tertiary-hover-state-layer-color),
|
|
'icon-color': var(--_tertiary-icon-color),
|
|
'pressed-icon-color': var(--_tertiary-pressed-icon-color),
|
|
'pressed-state-layer-color':
|
|
var(--_tertiary-pressed-state-layer-color),
|
|
'label-text-color': var(--_tertiary-label-text-color),
|
|
'hover-label-text-color': var(--_tertiary-hover-label-text-color),
|
|
'focus-label-text-color': var(--_tertiary-focus-label-text-color),
|
|
'pressed-label-text-color': var(--_tertiary-pressed-label-text-color),
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
// The default content is needed because we do a bit of trickery. If there is
|
|
// no slotted icon we need to have `padding-inline: 20px` but if there is, we
|
|
// need `padding-inline: 16px 20px`.
|
|
//
|
|
// So what this approach does is make the margin / padding-inline of the outer
|
|
// button `padding-inline: 16px 20px`, so if there is something slotted, it
|
|
// renders correctly. This default content span then fills the extra `4px`
|
|
// inline spacing if nothing is slotted which effectively makes the button's
|
|
// inline spacing `20px/20px`.
|
|
.fab.extended slot span {
|
|
padding-inline-start: 4px;
|
|
}
|
|
|
|
.fab.small {
|
|
width: var(--_small-container-width);
|
|
height: var(--_small-container-height);
|
|
|
|
.icon ::slotted(*) {
|
|
width: var(--_small-icon-size);
|
|
height: var(--_small-icon-size);
|
|
font-size: var(--_small-icon-size);
|
|
}
|
|
|
|
&,
|
|
.ripple {
|
|
border-start-start-radius: var(--_small-container-shape-start-start);
|
|
border-start-end-radius: var(--_small-container-shape-start-end);
|
|
border-end-start-radius: var(--_small-container-shape-end-start);
|
|
border-end-end-radius: var(--_small-container-shape-end-end);
|
|
}
|
|
|
|
md-focus-ring {
|
|
@include focus-ring.theme(
|
|
(
|
|
'shape-start-start': var(--_small-container-shape-start-start),
|
|
'shape-start-end': var(--_small-container-shape-start-end),
|
|
'shape-end-end': var(--_small-container-shape-end-end),
|
|
'shape-end-start': var(--_small-container-shape-end-start),
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin color($colors) {
|
|
background-color: map.get($colors, 'container-color');
|
|
|
|
@include ripple.theme(
|
|
(
|
|
hover-color: map.get($colors, hover-state-layer-color),
|
|
pressed-color: map.get($colors, pressed-state-layer-color),
|
|
)
|
|
);
|
|
|
|
.icon ::slotted(*) {
|
|
color: map.get($colors, icon-color);
|
|
}
|
|
|
|
&:focus {
|
|
color: map.get($colors, focus-icon-color);
|
|
}
|
|
|
|
&:hover {
|
|
color: map.get($colors, hover-icon-color);
|
|
}
|
|
|
|
&:active {
|
|
color: map.get($colors, pressed-icon-color);
|
|
}
|
|
|
|
.label {
|
|
color: map.get($colors, label-text-color);
|
|
|
|
.fab:hover & {
|
|
color: map.get($colors, hover-label-text-color);
|
|
}
|
|
|
|
.fab:focus & {
|
|
color: map.get($colors, focus-label-text-color);
|
|
}
|
|
|
|
.fab:active & {
|
|
color: map.get($colors, pressed-label-text-color);
|
|
}
|
|
}
|
|
}
|