xref: /aosp_15_r20/development/tools/winscope/src/app/components/bottomnav/drawer.scss (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
1/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17@use '@angular/cdk';
18
19$drawer-content-z-index: 1;
20$drawer-side-drawer-z-index: 2;
21$drawer-backdrop-z-index: 3;
22$drawer-over-drawer-z-index: 4;
23
24// Mixin that creates a new stacking context.
25// see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
26@mixin drawer-stacking-context($z-index: 1) {
27  position: relative;
28
29  // Use a z-index to create a new stacking context. (We can't use transform because it breaks fixed
30  // positioning inside of the transformed element).
31  z-index: $z-index;
32}
33
34.mat-drawer-container {
35  // We need a stacking context here so that the backdrop and drawers are clipped to the
36  // MatDrawerContainer. This creates a new z-index stack so we use low numbered z-indices.
37  // We create another stacking context in the '.mat-drawer-content' and in each drawer so that
38  // the application content does not get messed up with our own CSS.
39  @include drawer-stacking-context();
40
41  box-sizing: border-box;
42  -webkit-overflow-scrolling: touch;
43
44  // Need this to take up space in the layout.
45  display: block;
46
47  // Hide the drawers when they're closed.
48  overflow: hidden;
49
50  // TODO(hansl): Update this with a more robust solution.
51  &[fullscreen] {
52    top: 0;
53    left: 0;
54    right: 0;
55    bottom: 0;
56    position: absolute;
57
58    &.mat-drawer-container-has-open {
59      overflow: hidden;
60    }
61  }
62
63  // When the consumer explicitly enabled the backdrop,
64  // we have to pull the side drawers above it.
65  &.mat-drawer-container-explicit-backdrop .mat-drawer-side {
66    z-index: $drawer-backdrop-z-index;
67  }
68
69  // Note that the `NoopAnimationsModule` is being handled inside of the component code.
70  &.ng-animate-disabled, .ng-animate-disabled & {
71    .mat-drawer-backdrop, .mat-drawer-content {
72      transition: none;
73    }
74  }
75}
76
77.mat-drawer-backdrop {
78  top: 0;
79  left: 0;
80  right: 0;
81  bottom: 0;
82  position: absolute;
83
84  display: block;
85
86  // Because of the new stacking context, the z-index stack is new and we can use our own
87  // numbers.
88  z-index: $drawer-backdrop-z-index;
89
90  // We use 'visibility: hidden | visible' because 'display: none' will not animate any
91  // transitions, while visibility will interpolate transitions properly.
92  // see https://developer.mozilla.org/en-US/docs/Web/CSS/visibility, the Interpolation
93  // section.
94  visibility: hidden;
95
96  &.mat-drawer-shown {
97    visibility: visible;
98  }
99
100  .mat-drawer-transition & {
101    transition: {
102      duration: 400ms;
103      timing-function: cubic-bezier(0.25, 0.8, 0.25, 1);
104      property: background-color, visibility;
105    }
106  }
107
108  @include cdk.high-contrast(active, off) {
109    opacity: 0.5;
110  }
111}
112
113.mat-drawer-content {
114  @include drawer-stacking-context($drawer-content-z-index);
115
116  display: block;
117  height: 100%;
118  overflow: auto;
119
120  .mat-drawer-transition & {
121    transition: {
122      duration: 400ms;
123      timing-function: cubic-bezier(0.25, 0.8, 0.25, 1);
124      property: transform, margin-left, margin-right;
125    }
126  }
127}
128
129.mat-drawer {
130  $high-contrast-border: solid 1px currentColor;
131
132  @include drawer-stacking-context($drawer-over-drawer-z-index);
133
134  display: block;
135  position: absolute;
136  top: 0;
137  bottom: 0;
138  z-index: 3;
139  outline: 0;
140  box-sizing: border-box;
141  overflow-y: auto; // TODO(kara): revisit scrolling behavior for drawers
142  transform: translate3d(-100%, 0, 0);
143
144  &, [dir='rtl'] &.mat-drawer-end {
145    @include cdk.high-contrast(active, off) {
146      border-right: $high-contrast-border;
147    }
148  }
149
150  [dir='rtl'] &, &.mat-drawer-end {
151    @include cdk.high-contrast(active, off) {
152      border-left: $high-contrast-border;
153      border-right: none;
154    }
155  }
156
157  &.mat-drawer-side {
158    z-index: $drawer-side-drawer-z-index;
159  }
160
161  &.mat-drawer-end {
162    right: 0;
163    transform: translate3d(100%, 0, 0);
164  }
165
166  [dir='rtl'] & {
167    transform: translate3d(100%, 0, 0);
168
169    &.mat-drawer-end {
170      left: 0;
171      right: auto;
172      transform: translate3d(-100%, 0, 0);
173    }
174  }
175
176  // Usually the `visibility: hidden` added by the animation is enough to prevent focus from
177  // entering the hidden drawer content, but children with their own `visibility` can override it.
178  // This is a fallback that completely hides the content when the element becomes hidden.
179  // Note that we can't do this in the animation definition, because the style gets recomputed too
180  // late, breaking the animation because Angular didn't have time to figure out the target
181  // transform. This can also be achieved with JS, but it has issues when starting an
182  // animation before the previous one has finished.
183  &[style*='visibility: hidden'] {
184    display: none;
185  }
186}
187
188// Note that this div isn't strictly necessary on all browsers, however we need it in
189// order to avoid a layout issue in Chrome. The issue is that in RTL mode the browser doesn't
190// account for the sidenav's scrollbar while positioning, which ends up pushing it partially
191// out of the screen. We work around the issue by having the scrollbar be on this inner container.
192.mat-drawer-inner-container {
193  width: 100%;
194  height: 100%;
195  overflow: auto;
196  -webkit-overflow-scrolling: touch;
197}
198
199.mat-sidenav-fixed {
200  position: fixed;
201}