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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';
@function is-prop-ref($value) {
@if meta.type-of($value) != 'list' {
@return false;
}
@if list.length($value) != 4 {
@return false;
}
@if list.nth($value, 1) != 'prop-ref' {
@return false;
}
@return true;
}
@function def($name, $value: (), $metadata: ()) {
@return ('prop-ref' $name $value $metadata);
}
@function merge($ref, $value) {
@if not is-prop-ref($ref) {
@return $ref;
}
$v: list.nth($ref, 3);
$ref: list.set-nth($ref, 3, map.deep-merge($v, $value));
@return $ref;
}
@function get-deep($name, $value, $key: null, $keys...) {
@if is-prop-ref($value) {
@return get($value, $key, $keys);
}
@if meta.type-of($value) == 'map' and $key != null {
@if meta.type-of($key) != 'string' {
@error 'Expected string, got #{$key}';
}
@return get-deep(#{$name}#{$key}, map.get($value, $key), $keys...);
}
@return $name $value;
}
@function map-to-vars($name, $map) {
@if meta.type-of($map) != 'map' {
@if meta.type-of($name) != 'string' {
@error 'Expected variable name, got #{$name} instead';
}
@return var($name);
}
$out: ();
@each $key, $value in $map {
$out: map.set($out, $key, map-to-vars(#{$name}#{$key}, $value));
}
@return $out;
}
@function get($ref, $key: null, $keys...) {
@if not is-prop-ref($ref) {
@return $ref;
}
$name: list.nth($ref, 2);
$value: get(list.nth($ref, 3));
@if meta.type-of($value) == 'map' {
$res: get-deep($name, $value, $key, $keys...);
$name: list.nth($res, 1);
$value: list.nth($res, 2);
} @else if meta.type-of($value) == 'list' {
$i: 1;
@each $item in $value {
$value: list.set-nth($value, $i, get($item));
$i: $i + 1;
}
}
@return map-to-vars($name, $value);
}
@mixin materialize-helper($name, $value) {
@if meta.type-of($value) == 'map' {
@each $key, $value in $value {
@include materialize-helper(#{$name}#{$key}, $value);
}
} @else {
#{$name}: #{$value};
}
}
@mixin materialize($ref, $match-meta: null) {
@if is-prop-ref($ref) {
$name: list.nth($ref, 2);
$value: get(list.nth($ref, 3));
$meta: get(list.nth($ref, 4));
@if $match-meta == null or list.index($meta, $match-meta) != null {
@include materialize-helper($name, $value);
}
} @else if meta.type-of($ref) == 'list' {
@each $r in $ref {
@if is-prop-ref($r) {
$name: list.nth($r, 2);
$value: get(list.nth($r, 3));
$meta: get(list.nth($r, 4));
@if $match-meta == null or list.index($meta, $match-meta) != null {
@include materialize-helper($name, $value);
}
}
}
}
}
|