xref: /aosp_15_r20/external/perfetto/ui/src/assets/widgets/switch.scss (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1// Copyright (C) 2023 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15@import "theme";
16
17// This checkbox element is expected to contain a checkbox type input followed
18// by an empty span element.
19// The input is completely hidden and an entirely new checkbox is drawn inside
20// the span element. This allows us to style it how we like, and also add some
21// fancy transitions.
22// The box of the checkbox is a fixed sized span element. The tick is also a
23// fixed sized rectange rotated 45 degrees with only the bottom and right
24// borders visible.
25// When unchecked, the tick size and border width is 0, so the tick is
26// completely invsible. When we transition to checked, the border size on the
27// bottom and right sides is immmdiately set to full width, and the tick morphs
28// into view first by expanding along the x axis first, then expanding up the
29// y-axis. This has the effect of making the tick look like it's being drawn
30// onto the page with a pen.
31// When transitioning from checked to unchecked, the animation plays in reverse,
32// and the border width is set to 0 right at the end in order to make the tick
33// completely invisible again.
34.pf-switch {
35  display: inline-block;
36  position: relative; // Turns this container into a positioned element
37  font-family: $pf-font;
38  font-size: inherit;
39  color: $pf-minimal-foreground;
40  user-select: none;
41  cursor: pointer;
42  padding-left: 32px + 6px;
43
44  // Hide the default checkbox
45  input {
46    position: absolute;
47    opacity: 0;
48    pointer-events: none;
49  }
50
51  // The span forms the "box" of the checkbox
52  span {
53    position: absolute;
54    left: 0;
55    top: 0;
56    bottom: 0;
57    margin-top: auto;
58    margin-bottom: auto;
59    height: 16px;
60    width: 32px;
61    border-radius: 8px;
62    transition: background $pf-anim-timing;
63    background: grey;
64    vertical-align: middle;
65
66    // The :after element forms the "tick" of the checkbox
67    &:after {
68      content: "";
69      display: block;
70      position: absolute;
71      left: 2px;
72      top: 0;
73      bottom: 0;
74      margin-top: auto;
75      margin-bottom: auto;
76      width: 12px;
77      height: 12px;
78      background: $pf-primary-foreground;
79      box-sizing: border-box;
80      border-radius: 50%;
81      transition: left $pf-anim-timing;
82    }
83  }
84
85  input:checked + span {
86    background: $pf-primary-background;
87  }
88
89  input:checked + span:after {
90    left: 18px;
91  }
92
93  input:focus-visible + span {
94    @include focus;
95  }
96
97  &.pf-disabled {
98    cursor: not-allowed;
99    color: $pf-minimal-foreground-disabled;
100
101    span {
102      border-color: $pf-minimal-foreground-disabled;
103      background: $pf-minimal-foreground-disabled;
104      &:after {
105        border-color: $pf-minimal-foreground-disabled;
106      }
107    }
108
109    input:checked ~ span {
110      border-color: $pf-primary-background-disabled;
111      background: $pf-primary-background-disabled;
112    }
113  }
114}
115