_drawing.scss
ASCII text
1
// generic drawing of more complex things
2
3
@use "sass:list";
4
@use "../../theme";
5
@use "../../theme-color";
6
@use "../../shadow";
7
8
//
9
// Ripple keyframes
10
//
11
12
@keyframes ripple {
13
to {
14
background-size: 1000% 1000%;
15
}
16
}
17
18
@keyframes ripple-on-slider {
19
to {
20
background-size: auto, 1000% 1000%;
21
}
22
}
23
24
@keyframes ripple-on-headerbar {
25
from {
26
background-image: radial-gradient(circle, theme-color.$primary 0%, transparent 0%);
27
}
28
29
to {
30
background-image: radial-gradient(circle, theme-color.$primary 100%, transparent 100%);
31
}
32
}
33
34
35
@mixin entry($t, $fc: theme-color.$primary) {
36
//
37
// entry
38
//
39
// $t: entry type
40
// $fc: focus color
41
//
42
43
@if $t == normal {
44
transition: theme.$transition, border-image theme.$ripple-duration theme.$ease-out;
45
border-image:
46
radial-gradient(
47
circle closest-corner at center calc(100% - 1px),
48
$fc 0%,
49
transparent 0%
50
) 2 / 0 0 0px;
51
box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc);
52
background-color: theme-color.entry-fill(theme-color.$on-surface);
53
color: theme-color.$on-surface;
54
caret-color: $fc;
55
}
56
57
@if $t == hover {
58
box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc);
59
background-color: theme-color.hover-overlay(theme-color.$on-surface, $on: theme-color.entry-fill(theme-color.$on-surface), $alt: true);
60
}
61
62
@if $t == focus {
63
box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc);
64
background-color: theme-color.focus-overlay(theme-color.$on-surface, $on: theme-color.entry-fill(theme-color.$on-surface));
65
}
66
67
@if $t == checked {
68
border-image:
69
radial-gradient(
70
circle closest-corner at center calc(100% - 1px),
71
$fc 100%,
72
transparent 100%
73
) 2 / 0 0 2px;
74
box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc);
75
background-color: theme-color.focus-overlay(theme-color.$on-surface, $on: theme-color.entry-fill(theme-color.$on-surface));
76
}
77
78
@if $t == disabled {
79
box-shadow: inset 0 -1px theme-color.disabled-stroke(theme-color.$on-surface);
80
background-color: theme-color.entry-fill(theme-color.$on-surface);
81
color: theme-color.disabled(theme-color.$on-surface);
82
}
83
84
@if $t == raised-normal {
85
transition: theme.$transition;
86
border-image: none;
87
box-shadow: shadow.$z1;
88
background-color: if($fc == theme-color.$primary, theme-color.$surface-z8, $fc);
89
color: if($fc == theme-color.$primary, theme-color.$on-surface, theme-color.on($fc));
90
caret-color: if($fc == theme-color.$primary, $fc, theme-color.on($fc));
91
}
92
93
@if $t == raised-hover {
94
box-shadow: shadow.$z3;
95
}
96
97
@if $t == raised-focus {
98
border-image: none;
99
box-shadow: shadow.$z3;
100
}
101
102
@if $t == raised-disabled {
103
box-shadow: shadow.$z1;
104
background-color: theme-color.$surface-z1;
105
color: theme-color.disabled(theme-color.$on-surface);
106
}
107
}
108
109
110
$ripple-transition-property: all, border-image, background-size, background-image;
111
$ripple-transition-duration: theme.$state-duration, theme.$ripple-duration, theme.$ripple-fade-out-duration, theme.$ripple-opacity-fade-out-duration;
112
$ripple-active-transition-duration: theme.$state-duration, theme.$ripple-duration, 0ms, 0ms;
113
114
%ripple {
115
transition-property: $ripple-transition-property;
116
transition-duration: $ripple-transition-duration;
117
transition-timing-function: theme.$ease-out;
118
background-image: radial-gradient(circle, transparent 10%, transparent 10%);
119
background-repeat: no-repeat;
120
background-position: center;
121
background-size: 1000% 1000%;
122
123
&:active {
124
transition-duration: $ripple-active-transition-duration;
125
animation: ripple theme.$ripple-duration theme.$ease-out forwards;
126
background-size: 0% 0%;
127
}
128
}
129
130
@mixin ink-color($color, $on: transparent, $button-style: "none", $hover-alt: false, $opacity-modifier: 0) {
131
@if $button-style == "raised" {
132
$hover-alt: true;
133
}
134
135
@if $button-style == "flat" {
136
box-shadow: none;
137
} @else if $button-style == "outlined" {
138
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
139
} @else if $button-style == "raised" {
140
box-shadow: shadow.$z2;
141
}
142
143
@if $button-style != "none" or $on != transparent {
144
background-color: $on;
145
}
146
147
&:drop(active),
148
&:hover {
149
@if $button-style == "flat" {
150
box-shadow: none;
151
} @else if $button-style == "outlined" {
152
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
153
} @else if $button-style == "raised" {
154
box-shadow: shadow.$z4;
155
}
156
157
background-color: theme-color.hover-overlay($color, $opacity-modifier: $opacity-modifier, $on: $on, $alt: $hover-alt);
158
}
159
160
&:focus {
161
@if $button-style == "flat" {
162
box-shadow: none;
163
} @else if $button-style == "outlined" {
164
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
165
} @else if $button-style == "raised" {
166
box-shadow: shadow.$z4;
167
}
168
169
background-color: theme-color.focus-overlay($color, $opacity-modifier: $opacity-modifier, $on: $on);
170
}
171
172
&:active {
173
@if $button-style == "flat" {
174
box-shadow: none;
175
} @else if $button-style == "outlined" {
176
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
177
} @else if $button-style == "raised" {
178
box-shadow: shadow.$z8;
179
}
180
181
background-image: radial-gradient(circle, theme-color.pressed-overlay($color, $opacity-modifier: $opacity-modifier) 10%, transparent 10%);
182
}
183
}
184
185
@mixin list-item {
186
&:drop(active):not(:active),
187
&:hover:not(:active) {
188
transition-property: $ripple-transition-property, background-color;
189
transition-duration: $ripple-transition-duration, 0ms;
190
}
191
}
192
193
194
@mixin overshoot($position) {
195
$valid-positions: top, bottom, left, right;
196
197
@if not list.index($valid-positions, $position) {
198
@error "#{$position} is not a valid position. Expected one of #{$valid-positions}.";
199
}
200
201
$background-size: 200% 75%;
202
203
@if $position == left or $position == right {
204
$background-size: 75% 200%;
205
}
206
207
background-image:
208
radial-gradient(
209
farthest-side at $position,
210
rgba(theme-color.$primary, .24) 99%, // For better antialiasing
211
rgba(theme-color.$primary, 0) 100% // Don't use transparent i.e. rgba(0, 0, 0, 0)
212
);
213
background-size: $background-size;
214
background-repeat: no-repeat;
215
background-position: $position;
216
}
217
218
219
@mixin undershoot($side) {
220
$valid-sides: top, bottom, left, right;
221
222
@if not list.index($valid-sides, $side) {
223
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}.";
224
}
225
226
$_undershoot_color_dark: theme-color.stroke(theme-color.$on-surface);
227
$_undershoot_color_light: transparent;
228
229
$_gradient_dir: left;
230
$_dash_bg_size: 12px 1px;
231
$_gradient_repeat: repeat-x;
232
$_bg_pos: left $side;
233
234
@if $side == left or $side == right {
235
$_gradient_dir: top;
236
$_dash_bg_size: 1px 12px;
237
$_gradient_repeat: repeat-y;
238
$_bg_pos: $side top;
239
}
240
241
background-color: transparent; // shouldn't be needed, but better to be sure
242
243
background-image: linear-gradient(to $_gradient_dir, // this is the dashed line
244
$_undershoot_color_light 50%,
245
$_undershoot_color_dark 50%);
246
247
margin-#{$side}: 1px;
248
background-size: $_dash_bg_size;
249
background-repeat: $_gradient_repeat;
250
background-origin: content-box;
251
background-position: $_bg_pos;
252
}
253