Elizabeth Mitchell ed00d30b1d chore(motion): move to internal
PiperOrigin-RevId: 536448206
2023-05-30 10:50:00 -07:00

356 lines
9.2 KiB
SCSS

//
// Copyright 2022 Google LLC
// SPDX-License-Identifier: Apache-2.0
//
// stylelint-disable selector-class-pattern --
// Selector '.md3-*' should only be used in this project.
// go/keep-sorted start
@use 'sass:map';
// go/keep-sorted end
// go/keep-sorted start
@use '../../internal/motion/animation';
@use '../../ripple/ripple';
// go/keep-sorted end
@mixin styles() {
@keyframes md3-segmented-button-checkmark-selection-draw-in {
from {
stroke-dashoffset: 29.7833385;
}
to {
stroke-dashoffset: 0;
}
}
@keyframes md3-segmented-button-simple-fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes md3-segmented-button-simple-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
:host {
display: inline-flex;
outline: none;
}
.md3-segmented-button {
align-items: center;
background: transparent;
border: none;
border-radius: inherit;
display: flex;
flex: 1;
justify-content: center;
outline: none;
position: relative;
vertical-align: middle;
padding-inline-start: var(--_spacing-leading);
padding-inline-end: var(--_spacing-trailing);
.md3-segmented-button__outline {
border-color: var(--_outline-color);
}
&:disabled .md3-segmented-button__outline {
border-color: var(--_disabled-outline-color);
}
.md3-segmented-button__graphic,
.md3-segmented-button__checkmark,
.md3-segmented-button__icon,
.md3-segmented-button__icon ::slotted([slot='icon']) {
height: var(--_with-icon-icon-size);
width: var(--_with-icon-icon-size);
font-size: var(--_with-icon-icon-size);
}
// Under the following conditions, we need to account for extra space between
// the graphic and the text label/icon content:
//
// 1. A button with an icon and a label.
// 2. A selected button with a label and checkmark.
// 3. A selected button with an icon and checkmark but no label.
//
// We calculate a larger width here instead of using padding or margin for
// two main reasons:
//
// 1. We may need to transition between a zero width and an explicit width.
// 2. Both margin and padding take up space when a node has child content
// even when a zero width is set and overflow is set to hidden.
//
// Because of those reasons, we calculate a new width with the given values.
&.md3-segmented-button--with-icon.md3-segmented-button--with-label,
&.md3-segmented-button--selected.md3-segmented-button--with-label.md3-segmented-button--with-checkmark,
&.md3-segmented-button--selected.md3-segmented-button--without-label.md3-segmented-button--with-checkmark {
.md3-segmented-button__graphic {
// TODO(b/198759625): Use padding token instead of hardcoded 8px value.
width: calc(var(--_with-icon-icon-size) + 8px);
}
}
.md3-segmented-button__label-text {
font: var(--_label-text-type);
}
&.md3-segmented-button--selected:enabled {
.md3-segmented-button__label-text {
color: var(--_selected-label-text-color);
}
&:hover {
.md3-segmented-button__label-text {
color: var(--_selected-hover-label-text-color);
}
}
&:focus {
.md3-segmented-button__label-text {
color: var(--_selected-focus-label-text-color);
}
}
&:active {
.md3-segmented-button__label-text {
color: var(--_selected-pressed-label-text-color);
}
}
}
&.md3-segmented-button--unselected:enabled {
.md3-segmented-button__label-text {
color: var(--_unselected-label-text-color);
}
&:hover {
.md3-segmented-button__label-text {
color: var(--_unselected-hover-label-text-color);
}
}
&:focus {
.md3-segmented-button__label-text {
color: var(--_unselected-focus-label-text-color);
}
}
&:active {
.md3-segmented-button__label-text {
color: var(--_unselected-pressed-label-text-color);
}
}
}
&:disabled {
.md3-segmented-button__label-text {
color: var(--_disabled-label-text-color);
}
}
}
.md3-segmented-button--unselected {
.md3-segmented-button__icon {
color: var(--_unselected-with-icon-icon-color);
}
&:hover {
.md3-segmented-button__icon {
color: var(--_unselected-hover-icon-color);
}
}
&:focus {
.md3-segmented-button__icon {
color: var(--_unselected-focus-icon-color);
}
}
&:active {
.md3-segmented-button__icon {
color: var(--_unselected-pressed-icon-color);
}
}
&:disabled {
.md3-segmented-button__icon {
color: var(--_disabled-icon-color);
}
}
@include ripple.theme(
(
hover-color: var(--_unselected-hover-state-layer-color),
hover-opacity: var(--_hover-state-layer-opacity),
pressed-color: var(--_unselected-pressed-state-layer-color),
pressed-opacity: var(--_pressed-state-layer-opacity),
)
);
}
.md3-segmented-button--selected {
background-color: var(--_selected-container-color);
.md3-segmented-button__icon {
color: var(--_selected-with-icon-icon-color);
}
.md3-segmented-button__checkmark-path {
stroke: var(--_selected-with-icon-icon-color);
}
&:hover {
.md3-segmented-button__checkmark-path {
stroke: var(--_selected-hover-icon-color);
}
}
&:focus {
.md3-segmented-button__checkmark-path {
stroke: var(--_selected-focus-icon-color);
}
}
&:active {
.md3-segmented-button__checkmark-path {
stroke: var(--_selected-pressed-icon-color);
}
}
&:disabled {
.md3-segmented-button__checkmark-path {
stroke: var(--_disabled-icon-color);
}
}
@include ripple.theme(
(
hover-color: var(--_selected-hover-state-layer-color),
hover-opacity: var(--_hover-state-layer-opacity),
pressed-color: var(--_selected-pressed-state-layer-color),
pressed-opacity: var(--_pressed-state-layer-opacity),
)
);
}
.md3-segmented-button:enabled {
cursor: pointer;
}
.md3-segmented-button__focus-ring {
z-index: 1;
}
.md3-segmented-button__ripple {
border-radius: inherit;
z-index: 0;
}
.md3-segmented-button__touch {
position: absolute;
top: 50%;
height: 48px;
left: 50%;
width: 100%;
transform: translate(-50%, -50%);
}
.md3-segmented-button__leading,
.md3-segmented-button__graphic {
display: inline-flex;
justify-content: flex-start;
align-items: center;
}
.md3-segmented-button__graphic {
position: relative;
overflow: hidden;
}
.md3-segmented-button__graphic {
transition: animation.standard(width, 150ms);
}
.md3-segmented-button--unselected.md3-segmented-button--with-label,
.md3-segmented-button--unselected.md3-segmented-button--without-label,
.md3-segmented-button--selected.md3-segmented-button--without-checkmark {
.md3-segmented-button__graphic {
width: 0;
}
}
.md3-segmented-button--unselected .md3-segmented-button__checkmark {
opacity: 0;
}
.md3-segmented-button--selected.md3-segmented-button--with-label {
.md3-segmented-button__icon {
opacity: 0;
}
}
.md3-segmented-button--with-label .md3-segmented-button__checkmark {
display: inline-flex;
position: absolute;
}
.md3-segmented-button__checkmark-path {
stroke-width: 2px;
stroke-dasharray: 29.7833385;
}
.md3-segmented-button--selecting {
.md3-segmented-button__checkmark-path {
// We immediately render the checkmark in the animation start treatment
// because we're using an animation delay. If we didn't have the delay,
// the checkmark would render in the base fully-drawn state during the
// brief animation-delay period which would look wrong.
stroke-dashoffset: 29.7833385;
animation: md3-segmented-button-checkmark-selection-draw-in;
animation-duration: 150ms;
animation-delay: 50ms;
animation-fill-mode: forwards;
animation-timing-function: animation.$standard-easing;
}
&.md3-segmented-button--with-label .md3-segmented-button__icon {
animation: md3-segmented-button-simple-fade-out;
animation-duration: 75ms;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
}
.md3-segmented-button--deselecting {
.md3-segmented-button__checkmark {
animation: md3-segmented-button-simple-fade-out;
animation-duration: 50ms;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
&.md3-segmented-button--with-label .md3-segmented-button__icon {
// We immediately render the icon in the animation start treatment
// because we're using an animation delay. If we didn't have the delay,
// the icon would render with full opacity during the brief
// animation-delay period which would look wrong.
opacity: 0;
animation: md3-segmented-button-simple-fade-in;
animation-delay: 50ms;
animation-duration: 150ms;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
}
}