_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 { 13to { 14background-size: 1000% 1000%; 15} 16} 17 18@keyframes ripple-on-slider { 19to { 20background-size: auto, 1000% 1000%; 21} 22} 23 24@keyframes ripple-on-headerbar { 25from { 26background-image: radial-gradient(circle, theme-color.$primary 0%, transparent 0%); 27} 28 29to { 30background-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 { 44transition: theme.$transition, border-image theme.$ripple-duration theme.$ease-out; 45border-image: 46radial-gradient( 47circle closest-corner at center calc(100% - 1px), 48$fc 0%, 49transparent 0% 50) 2 / 0 0 0; 51box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc); 52background-color: theme-color.entry-fill(theme-color.$on-surface); 53color: theme-color.$on-surface; 54caret-color: $fc; 55} 56 57@if $t == hover { 58box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc); 59background-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 { 63box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc); 64background-color: theme-color.focus-overlay(theme-color.$on-surface, $on: theme-color.entry-fill(theme-color.$on-surface)); 65} 66 67@if $t == checked { 68border-image: 69radial-gradient( 70circle closest-corner at center calc(100% - 1px), 71$fc 100%, 72transparent 0% 73) 2 / 0 0 2px; 74box-shadow: inset 0 -1px if($fc == theme-color.$primary, theme-color.stroke(theme-color.$on-surface), $fc); 75background-color: theme-color.focus-overlay(theme-color.$on-surface, $on: theme-color.entry-fill(theme-color.$on-surface)); 76} 77 78@if $t == disabled { 79box-shadow: inset 0 -1px theme-color.disabled-stroke(theme-color.$on-surface); 80background-color: theme-color.entry-fill(theme-color.$on-surface); 81color: theme-color.disabled(theme-color.$on-surface); 82} 83 84@if $t == raised-normal { 85transition: theme.$transition; 86border-image: none; 87box-shadow: shadow.$z1; 88background-color: if($fc == theme-color.$primary, theme-color.$surface-z8, $fc); 89color: if($fc == theme-color.$primary, theme-color.$on-surface, theme-color.on($fc)); 90caret-color: if($fc == theme-color.$primary, $fc, theme-color.on($fc)); 91} 92 93@if $t == raised-hover { 94box-shadow: shadow.$z3; 95} 96 97@if $t == raised-focus { 98border-image: none; 99box-shadow: shadow.$z3; 100} 101 102@if $t == raised-disabled { 103box-shadow: shadow.$z1; 104background-color: theme-color.$surface-z1; 105color: 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 { 115transition-property: $ripple-transition-property; 116transition-duration: $ripple-transition-duration; 117transition-timing-function: theme.$ease-out; 118outline: none; 119background-image: radial-gradient(circle, transparent 10%, transparent 0%); 120background-repeat: no-repeat; 121background-position: center; 122background-size: 1000% 1000%; 123 124&:active { 125transition-duration: $ripple-active-transition-duration; 126animation: ripple theme.$ripple-duration theme.$ease-out forwards; 127background-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" { 137box-shadow: none; 138} @else if $button-style == "outlined" { 139box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface); 140} @else if $button-style == "raised" { 141box-shadow: shadow.$z2; 142} 143 144@if $button-style != "none" or $on != transparent { 145background-color: $on; 146} 147 148&:drop(active), 149&:hover { 150@if $button-style == "flat" { 151box-shadow: none; 152} @else if $button-style == "outlined" { 153box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface); 154} @else if $button-style == "raised" { 155box-shadow: shadow.$z4; 156} 157 158background-color: theme-color.hover-overlay($color, $opacity-modifier: $opacity-modifier, $on: $on, $alt: $hover-alt); 159} 160 161&:focus { 162@if $button-style == "flat" { 163box-shadow: none; 164} @else if $button-style == "outlined" { 165box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface); 166} @else if $button-style == "raised" { 167box-shadow: shadow.$z4; 168} 169 170background-color: theme-color.focus-overlay($color, $opacity-modifier: $opacity-modifier, $on: $on); 171} 172 173&:active { 174@if $button-style == "flat" { 175box-shadow: none; 176} @else if $button-style == "outlined" { 177box-shadow: inset 0 0 0 1px theme-color.stroke(theme-color.$on-surface); 178} @else if $button-style == "raised" { 179box-shadow: shadow.$z8; 180} 181 182background-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) { 189transition-property: $ripple-transition-property, background-color; 190transition-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 208background-image: 209-gtk-gradient( 210radial, 211$_position, 0, 212$_position, .75, 213to(rgba(theme-color.$primary, .24)), 214to(transparent) 215); 216 217background-repeat: no-repeat; 218background-position: $_position; 219 220background-color: transparent; // reset some properties to be sure to not inherit them somehow 221border: none; // 222box-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 248background-color: transparent; // shouldn't be needed, but better to be sure 249 250background-image: linear-gradient(to $_gradient_dir, // this is the dashed line 251$_undershoot_color_light 50%, 252$_undershoot_color_dark 50%); 253 254padding-#{$side}: 1px; 255background-size: $_dash_bg_size; 256background-repeat: $_gradient_repeat; 257background-origin: content-box; 258background-position: $_bg_pos; 259} 260