_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 0%);
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 0;
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 0%
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
outline: none;
119
background-image: radial-gradient(circle, transparent 10%, transparent 0%);
120
background-repeat: no-repeat;
121
background-position: center;
122
background-size: 1000% 1000%;
123
124
&:active {
125
transition-duration: $ripple-active-transition-duration;
126
animation: ripple theme.$ripple-duration theme.$ease-out forwards;
127
background-size: 0% 0%;
128
}
129
}
130
131
@mixin ink-color($color, $on: transparent, $button-style: "none", $hover-alt: false, $opacity-modifier: 0) {
132
@if $button-style == "raised" {
133
$hover-alt: true;
134
}
135
136
@if $button-style == "flat" {
137
box-shadow: none;
138
} @else if $button-style == "outlined" {
139
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
140
} @else if $button-style == "raised" {
141
box-shadow: shadow.$z2;
142
}
143
144
@if $button-style != "none" or $on != transparent {
145
background-color: $on;
146
}
147
148
&:drop(active),
149
&:hover {
150
@if $button-style == "flat" {
151
box-shadow: none;
152
} @else if $button-style == "outlined" {
153
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
154
} @else if $button-style == "raised" {
155
box-shadow: shadow.$z4;
156
}
157
158
background-color: theme-color.hover-overlay($color, $opacity-modifier: $opacity-modifier, $on: $on, $alt: $hover-alt);
159
}
160
161
&:focus {
162
@if $button-style == "flat" {
163
box-shadow: none;
164
} @else if $button-style == "outlined" {
165
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
166
} @else if $button-style == "raised" {
167
box-shadow: shadow.$z4;
168
}
169
170
background-color: theme-color.focus-overlay($color, $opacity-modifier: $opacity-modifier, $on: $on);
171
}
172
173
&:active {
174
@if $button-style == "flat" {
175
box-shadow: none;
176
} @else if $button-style == "outlined" {
177
box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface);
178
} @else if $button-style == "raised" {
179
box-shadow: shadow.$z8;
180
}
181
182
background-image: radial-gradient(circle, theme-color.pressed-overlay($color, $opacity-modifier: $opacity-modifier) 10%, transparent 0%);
183
}
184
}
185
186
@mixin list-item {
187
&:drop(active):not(:active),
188
&:hover:not(:active) {
189
transition-property: $ripple-transition-property, background-color;
190
transition-duration: $ripple-transition-duration, 0ms;
191
}
192
}
193
194
195
@mixin overshoot($side) {
196
$valid-sides: top, bottom, left, right;
197
198
@if not list.index($valid-sides, $side) {
199
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}.";
200
}
201
202
$_position: center $side;
203
204
@if $side == left or $side == right {
205
$_position: $side center;
206
}
207
208
background-image:
209
-gtk-gradient(
210
radial,
211
$_position, 0,
212
$_position, .75,
213
to(rgba(theme-color.$primary, .24)),
214
to(transparent)
215
);
216
217
background-repeat: no-repeat;
218
background-position: $_position;
219
220
background-color: transparent; // reset some properties to be sure to not inherit them somehow
221
border: none; //
222
box-shadow: none; //
223
}
224
225
226
@mixin undershoot($side) {
227
$valid-sides: top, bottom, left, right;
228
229
@if not list.index($valid-sides, $side) {
230
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}.";
231
}
232
233
$_undershoot_color_dark: theme-color.stroke(theme-color.$on-surface);
234
$_undershoot_color_light: transparent;
235
236
$_gradient_dir: left;
237
$_dash_bg_size: 12px 1px;
238
$_gradient_repeat: repeat-x;
239
$_bg_pos: left $side;
240
241
@if $side == left or $side == right {
242
$_gradient_dir: top;
243
$_dash_bg_size: 1px 12px;
244
$_gradient_repeat: repeat-y;
245
$_bg_pos: $side top;
246
}
247
248
background-color: transparent; // shouldn't be needed, but better to be sure
249
250
background-image: linear-gradient(to $_gradient_dir, // this is the dashed line
251
$_undershoot_color_light 50%,
252
$_undershoot_color_dark 50%);
253
254
padding-#{$side}: 1px;
255
background-size: $_dash_bg_size;
256
background-repeat: $_gradient_repeat;
257
background-origin: content-box;
258
background-position: $_bg_pos;
259
}
260