// Copyright (C) 2023 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. @import "theme"; // This checkbox element is expected to contain a checkbox type input followed // by an empty span element. // The input is completely hidden and an entirely new checkbox is drawn inside // the span element. This allows us to style it how we like, and also add some // fancy transitions. // The box of the checkbox is a fixed sized span element. The tick is also a // fixed sized rectange rotated 45 degrees with only the bottom and right // borders visible. // When unchecked, the tick size and border width is 0, so the tick is // completely invsible. When we transition to checked, the border size on the // bottom and right sides is immmdiately set to full width, and the tick morphs // into view first by expanding along the x axis first, then expanding up the // y-axis. This has the effect of making the tick look like it's being drawn // onto the page with a pen. // When transitioning from checked to unchecked, the animation plays in reverse, // and the border width is set to 0 right at the end in order to make the tick // completely invisible again. .pf-switch { display: inline-block; position: relative; // Turns this container into a positioned element font-family: $pf-font; font-size: inherit; color: $pf-minimal-foreground; user-select: none; cursor: pointer; padding-left: 32px + 6px; // Hide the default checkbox input { position: absolute; opacity: 0; pointer-events: none; } // The span forms the "box" of the checkbox span { position: absolute; left: 0; top: 0; bottom: 0; margin-top: auto; margin-bottom: auto; height: 16px; width: 32px; border-radius: 8px; transition: background $pf-anim-timing; background: grey; vertical-align: middle; // The :after element forms the "tick" of the checkbox &:after { content: ""; display: block; position: absolute; left: 2px; top: 0; bottom: 0; margin-top: auto; margin-bottom: auto; width: 12px; height: 12px; background: $pf-primary-foreground; box-sizing: border-box; border-radius: 50%; transition: left $pf-anim-timing; } } input:checked + span { background: $pf-primary-background; } input:checked + span:after { left: 18px; } input:focus-visible + span { @include focus; } &.pf-disabled { cursor: not-allowed; color: $pf-minimal-foreground-disabled; span { border-color: $pf-minimal-foreground-disabled; background: $pf-minimal-foreground-disabled; &:after { border-color: $pf-minimal-foreground-disabled; } } input:checked ~ span { border-color: $pf-primary-background-disabled; background: $pf-primary-background-disabled; } } }