mirror of
https://github.com/material-components/material-web.git
synced 2026-03-09 00:09:23 +08:00
306 lines
6.1 KiB
SCSS
306 lines
6.1 KiB
SCSS
/**
|
|
* @license
|
|
* Copyright 2021 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
// stylelint-disable selector-class-pattern --
|
|
// Selector '.mdc-*' should only be used in this project.
|
|
|
|
@use '@material/animation/animation';
|
|
@use '@material/elevation/elevation';
|
|
@use '@material/ripple/ripple';
|
|
@use '@material/rtl/rtl';
|
|
@use '@material/theme/gss';
|
|
|
|
// PUBLIC PROPERTIES
|
|
|
|
$animation-duration: 75ms;
|
|
$icon-exit-duration: 0.4 * $animation-duration;
|
|
$icon-enter-duration: $animation-duration - $icon-exit-duration;
|
|
$ripple-target: '.mdc-switch__ripple';
|
|
|
|
// PUBLIC API
|
|
|
|
@mixin static-styles() {
|
|
@include static-styles-without-ripple();
|
|
|
|
// with ripple
|
|
.mdc-switch {
|
|
// @include ripple.common; // COPYBARA_COMMENT_THIS_LINE
|
|
@include ripple.surface($ripple-target: $ripple-target);
|
|
@include ripple.radius-unbounded($ripple-target: $ripple-target);
|
|
}
|
|
}
|
|
|
|
@mixin static-styles-without-ripple() {
|
|
// @include elevation.overlay-common; // COPYBARA_COMMENT_THIS_LINE
|
|
:host {
|
|
display: inline-flex;
|
|
outline: none;
|
|
}
|
|
|
|
.mdc-switch {
|
|
@include _root;
|
|
|
|
&:disabled {
|
|
@include _disabled;
|
|
}
|
|
}
|
|
|
|
.mdc-switch__track {
|
|
@include _track;
|
|
@include _track-off;
|
|
|
|
.mdc-switch--selected & {
|
|
@include _track-on;
|
|
}
|
|
}
|
|
|
|
.mdc-switch__handle-track {
|
|
@include _handle-track;
|
|
@include _handle-track-off;
|
|
|
|
.mdc-switch--selected & {
|
|
@include _handle-track-on;
|
|
}
|
|
}
|
|
|
|
.mdc-switch__handle {
|
|
@include _handle;
|
|
}
|
|
|
|
.mdc-switch__shadow {
|
|
@include _shadow;
|
|
}
|
|
|
|
.mdc-elevation-overlay {
|
|
@include _overlay;
|
|
}
|
|
|
|
.mdc-switch__ripple {
|
|
@include _ripple;
|
|
|
|
.mdc-switch:disabled & {
|
|
@include _ripple-disabled;
|
|
}
|
|
}
|
|
|
|
.mdc-switch__icons {
|
|
@include _icons;
|
|
}
|
|
|
|
.mdc-switch__icon {
|
|
@include _icon;
|
|
@include _icon-hidden;
|
|
}
|
|
|
|
.mdc-switch--selected .mdc-switch__icon--on,
|
|
.mdc-switch--unselected .mdc-switch__icon--off {
|
|
@include _icon-visible;
|
|
}
|
|
|
|
input {
|
|
@include _input;
|
|
}
|
|
}
|
|
|
|
// PRIVATE API
|
|
|
|
@mixin _input() {
|
|
display: none;
|
|
}
|
|
|
|
@mixin _root() {
|
|
align-items: center;
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
flex-shrink: 0; // Stop from collapsing in flex containers
|
|
margin: 0;
|
|
outline: none;
|
|
overflow: visible;
|
|
padding: 0;
|
|
position: relative;
|
|
}
|
|
|
|
@mixin _disabled() {
|
|
cursor: default;
|
|
pointer-events: none;
|
|
}
|
|
|
|
@mixin _track() {
|
|
overflow: hidden;
|
|
position: relative;
|
|
width: 100%;
|
|
|
|
&::before,
|
|
&::after {
|
|
border: 1px solid transparent; // high contrast mode
|
|
border-radius: inherit;
|
|
box-sizing: border-box;
|
|
content: '';
|
|
height: 100%;
|
|
@include gss.annotate($noflip: true);
|
|
left: 0;
|
|
position: absolute;
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
@mixin _track-on() {
|
|
&::before {
|
|
transition: animation.exit-temporary(transform, $animation-duration);
|
|
transform: translateX(100%);
|
|
@include rtl.rtl {
|
|
transform: translateX(-100%);
|
|
}
|
|
}
|
|
|
|
&::after {
|
|
transition: animation.enter(transform, $animation-duration);
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
@mixin _track-off() {
|
|
&::before {
|
|
transition: animation.enter(transform, $animation-duration);
|
|
transform: translateX(0);
|
|
}
|
|
|
|
&::after {
|
|
transition: animation.exit-temporary(transform, $animation-duration);
|
|
transform: translateX(-100%);
|
|
@include rtl.rtl {
|
|
transform: translateX(100%);
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin _handle-track() {
|
|
height: 100%;
|
|
// The handle track is used to move the handle across the width of the switch
|
|
// and may overflow the bounds of the component. It should not be used for
|
|
// pointer events.
|
|
pointer-events: none;
|
|
position: absolute;
|
|
top: 0; // Needed for IE11
|
|
transition: animation.standard(transform, $animation-duration);
|
|
// IE11 needs explicit left/right
|
|
@include rtl.reflexive(left, 0, right, auto);
|
|
}
|
|
|
|
@mixin _handle-track-on() {
|
|
transform: translateX(100%);
|
|
|
|
@include rtl.rtl {
|
|
transform: translateX(-100%);
|
|
}
|
|
}
|
|
|
|
@mixin _handle-track-off() {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
@mixin _handle() {
|
|
display: flex;
|
|
pointer-events: auto;
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
// IE11 needs explicit left/right
|
|
@include rtl.reflexive(left, 0, right, auto);
|
|
|
|
&::before,
|
|
&::after {
|
|
border: 1px solid transparent; // high contrast mode
|
|
border-radius: inherit;
|
|
box-sizing: border-box;
|
|
content: '';
|
|
width: 100%;
|
|
height: 100%;
|
|
@include gss.annotate($noflip: true);
|
|
left: 0;
|
|
position: absolute;
|
|
top: 0; // IE11 fix
|
|
transition: animation.standard(background-color, $animation-duration),
|
|
animation.standard(border-color, $animation-duration);
|
|
// Move the handle background colors beneath the shadow overlay color,
|
|
// rather than move the overlay on top of the handle with a positive
|
|
// z-index, which would require moving all other content on top of the
|
|
// overlay with an even greater z-index.
|
|
z-index: -1;
|
|
}
|
|
}
|
|
|
|
@mixin _shadow() {
|
|
border-radius: inherit;
|
|
bottom: 0;
|
|
@include gss.annotate($noflip: true);
|
|
left: 0;
|
|
position: absolute;
|
|
@include gss.annotate($noflip: true);
|
|
right: 0;
|
|
top: 0;
|
|
}
|
|
|
|
@mixin _overlay() {
|
|
bottom: 0;
|
|
@include gss.annotate($noflip: true);
|
|
left: 0;
|
|
@include gss.annotate($noflip: true);
|
|
right: 0;
|
|
top: 0;
|
|
}
|
|
|
|
@mixin _ripple() {
|
|
@include gss.annotate($noflip: true);
|
|
left: 50%;
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
// Move ripple beneath shadow overlay and handle background colors (see
|
|
// handle() mixin for explanation).
|
|
z-index: -1;
|
|
}
|
|
|
|
@mixin _ripple-disabled() {
|
|
display: none;
|
|
}
|
|
|
|
@mixin _icons() {
|
|
height: 100%;
|
|
position: relative;
|
|
width: 100%;
|
|
z-index: 1;
|
|
}
|
|
|
|
@mixin _icon() {
|
|
bottom: 0;
|
|
@include gss.annotate($noflip: true);
|
|
left: 0;
|
|
// IE11 needs top/right/bottom/left + margin instead of translate(-50%, -50%)
|
|
// because of SVG centering issues
|
|
margin: auto;
|
|
position: absolute;
|
|
@include gss.annotate($noflip: true);
|
|
right: 0;
|
|
top: 0;
|
|
}
|
|
|
|
@mixin _icon-hidden() {
|
|
opacity: 0;
|
|
transition: animation.exit-permanent(opacity, $icon-exit-duration);
|
|
}
|
|
|
|
@mixin _icon-visible() {
|
|
opacity: 1;
|
|
transition: animation.enter(
|
|
opacity,
|
|
$icon-enter-duration,
|
|
$delay: $icon-exit-duration
|
|
);
|
|
}
|