-
Notifications
You must be signed in to change notification settings - Fork 0
/
_index.scss
87 lines (75 loc) · 3.46 KB
/
_index.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// _
// | |
// ___ __ _ ___ ___ ______| | ___ _ __ _ __
// / __|/ _` / __/ __|______| |/ _ \ '__| '_ \
// \__ \ (_| \__ \__ \ | | __/ | | |_) |
// |___/\__,_|___/___/ |_|\___|_| | .__/
// | |
// |_|
// TODO:
// add function-exists() checks for peerDependencies
@function --sl-strip($n){
@return if(unitless($n), $n, $n / (0 * $n + 1));
}
@function --sl-normalize($val) {
@return --sl-strip($val) / if(unit($val) == '%', 100, 1);
}
@function --sl-relativize($val, $ref, $rem-px: 16) {
$val-unit: unit($val);
@if index('em' '%', $val-unit) { @return --sl-normalize( $val); }
$ref-unit: unit($ref);
@if $val-unit == $ref-unit { @return $val/$ref; }
@if $ref-unit == 'px' and $val-unit == 'rem' { $ref: (--sl-strip($ref) / $rem-px); }
@if $val-unit == 'px' and $ref-unit == 'rem' { $ref: (--sl-strip($ref) * $rem-px); }
@if not unitless($ref) { $ref: --sl-strip($ref); }
@return --sl-strip($val) / $ref;
}
@function --sl-safe-unit($n) {
@if not type-of($n) == 'number' { @return throw-error('lerp(): argument #{$n} invalid; must be a number'); }
@return unit($n);
}
$--sl-mult-vs-val: (
// vw/h/min/max: px, rem (because em and % refer to unknown intermediary)
'vw': 'px' 'rem',
'vh': 'px' 'rem',
'vmin': 'px' 'rem',
'vmax': 'px' 'rem',
// %: px, rem, %, (em, conditionally; but we'll say no)
'%': 'px' 'rem' '%',
// em: px, rem, %, em
'em': 'px' 'rem' '%' 'em',
);
@function lerp($table, $domain: 100vw, $rem-px: 16) {
// $domain unit must be em, %, or one of vw, vh, vmin, vmax
@if not index(map-keys($--sl-mult-vs-val), --sl-safe-unit($domain)) {
@return throw-error('lerp($table, $domain: 100vw, $rem-px: 16): $domain [#{$domain}] invalid; unit must be one of the following: #{map-keys($--sl-mult-vs-val)}'); }
$keys: map-keys($table);
$vals: map-values($table);
$key-1: nth($keys, 1);
$key-2: nth($keys, 2);
// $key units must be px or rem
@if not index('rem' 'px', --sl-safe-unit($key-1)) {
@return throw-error('lerp($table, $domain: 100vw, $rem-px: 16): $table key [#{$key-1}] invalid; unit must be rem or px'); }
@if not index('rem' 'px', --sl-safe-unit($key-2)) {
@return throw-error('lerp($table, $domain: 100vw, $rem-px: 16): $table key [#{$key-2}] invalid; unit must be rem or px'); }
$val-1: nth($vals, 1);
$val-2: nth($vals, 2);
// $val units depend on $domain unit
$val-units: map-get($--sl-mult-vs-val, unit($domain));
@if not index($val-units, --sl-safe-unit($val-1)) {
@return throw-error('lerp($table, $domain: 100vw, $rem-px: 16): $table $val [#{$val-1}] invalid for $domain #{$domain}; unit must be one of the following: #{$val-units}'); }
@if not index($val-units, --sl-safe-unit($val-2)) {
@return throw-error('lerp($table, $domain: 100vw, $rem-px: 16): $table $val [#{$val-2}] invalid for $domain #{$domain}; unit must be one of the following: #{$val-units}'); }
// calculate
$key-2: --sl-relativize($key-2, $key-1, $rem-px) * $key-1;
$val-1: --sl-relativize($val-1, $key-1, $rem-px);
@if index('em' '%', unit($val-2)) {
$val-2: --sl-relativize($key-2, $key-1, $rem-px) * --sl-normalize( $val-2);
} @else {
$val-2: --sl-relativize($val-2, $key-1, $rem-px);
}
$slope: ($val-2 - $val-1) * $key-1 / ($key-2 - $key-1);
$offset: ($val-1 - $slope) * $key-1;
// use sass-calc add, in order to flip if offset is negative
@return add($slope * $domain, $offset);
}