// // Copyright 2021 Google Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // stylelint-disable selector-class-pattern -- // Selector '.mdc-*' should only be used in this project. @use '@material/animation/animation'; @use '@material/dom/dom'; @use '@material/elevation/elevation'; @use '@material/ripple/ripple-theme'; @use '@material/ripple/ripple'; @use '@material/focus-ring/focus-ring'; @use '@material/rtl/rtl'; @use '@material/theme/gss'; $animation-duration: 75ms; $icon-exit-duration: 0.4 * $animation-duration; $icon-enter-duration: $animation-duration - $icon-exit-duration; $ripple-target: '.mdc-switch__ripple'; @mixin static-styles() { @include static-styles-without-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); .mdc-switch__focus-ring-wrapper { width: 100%; position: absolute; // IE11 hacks top: 50%; @include rtl.ignore-next-line(); left: 50%; @include rtl.ignore-next-line(); transform: translate(-50%, -50%); // end IE11 hacks } @include ripple-theme.focus { .mdc-switch__focus-ring { @include focus-ring.focus-ring(); } } } } @mixin static-styles-without-ripple() { @include elevation.overlay-common; // COPYBARA_COMMENT_THIS_LINE .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; } } @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; &[hidden] { display: none; } } @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%; // Added for Firefox 94 which broke transparent borders in Windows HCM. // See https://bugzilla.mozilla.org/show_bug.cgi?id=1740924. @include dom.forced-colors-mode($exclude-ie11: true) { border-color: currentColor; } } } @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; // Added for Firefox 94 which broke transparent borders in Windows HCM. // See https://bugzilla.mozilla.org/show_bug.cgi?id=1740924. @include dom.forced-colors-mode($exclude-ie11: true) { border-color: currentColor; } } } @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%; @include rtl.ignore-next-line(); 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 ); }