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