@material/web 2.4.2-nightly.563da62.0 → 2.4.2-nightly.a7ba471.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/sass/ext/_assert.scss +1 -1
- package/sass/ext/_list_ext.scss +114 -0
- package/sass/ext/_map_ext.scss +222 -0
- package/{internal/sass → sass/ext}/_var.scss +79 -91
- package/sass/ext/tests.scss +3 -0
package/package.json
CHANGED
package/sass/ext/_assert.scss
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 Google LLC
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
// Extensions to the go/sass:list built-in module.
|
|
7
|
+
|
|
8
|
+
// go/keep-sorted start by_regex='(.+) prefix_order=sass:
|
|
9
|
+
@use 'sass:list';
|
|
10
|
+
@use 'assert';
|
|
11
|
+
@use 'throw';
|
|
12
|
+
// go/keep-sorted end
|
|
13
|
+
|
|
14
|
+
/// Returns the difference between two lists.
|
|
15
|
+
///
|
|
16
|
+
/// @example scss
|
|
17
|
+
/// $listA: ('apple', 'banana', 'cherry', 'date');
|
|
18
|
+
/// $listB: ('banana', 'cherry', 'apple');
|
|
19
|
+
/// $listC: ('apple', 'banana', 'date');
|
|
20
|
+
///
|
|
21
|
+
/// @debug list_ext.difference($listA, $listB); // ('date')
|
|
22
|
+
/// @debug list_ext.difference($listA, $listC); // ('cherry')
|
|
23
|
+
///
|
|
24
|
+
/// @param {list} $listA - The first list to compare.
|
|
25
|
+
/// @param {list} $listB - The second list to compare.
|
|
26
|
+
/// @return {list} All items in $listA that are not in $listB.
|
|
27
|
+
@function difference($listA, $listB) {
|
|
28
|
+
$listA: assert.is-type($listA, 'list', $source: 'list_ext.difference');
|
|
29
|
+
$listB: assert.is-type($listB, 'list', $source: 'list_ext.difference');
|
|
30
|
+
$error: throw.get-error($listA, $listB);
|
|
31
|
+
@if $error {
|
|
32
|
+
@return $error;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
$result: ();
|
|
36
|
+
@each $item in $listA {
|
|
37
|
+
@if not list.index($listB, $item) {
|
|
38
|
+
$result: list.append($result, $item, list.separator($listA));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
@return $result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// Checks if two lists contain the same elements, regardless of their order.
|
|
45
|
+
///
|
|
46
|
+
/// The function iterates through each list and verifies that every element in
|
|
47
|
+
/// one list is present in the other. The order of elements does not affect the
|
|
48
|
+
/// result.
|
|
49
|
+
///
|
|
50
|
+
/// @example scss
|
|
51
|
+
/// $listA: ('apple', 'banana', 'cherry');
|
|
52
|
+
/// $listB: ('banana', 'cherry', 'apple');
|
|
53
|
+
/// $listC: ('apple', 'banana', 'date');
|
|
54
|
+
///
|
|
55
|
+
/// @debug list_ext.are-equal($listA, $listB); // true
|
|
56
|
+
/// @debug list_ext.are-equal($listA, $listC); // false
|
|
57
|
+
///
|
|
58
|
+
/// @param {list} $listA - The first list to compare.
|
|
59
|
+
/// @param {list} $listB - The second list to compare.
|
|
60
|
+
/// @return {boolean} `true` if the lists contain the same elements, otherwise
|
|
61
|
+
/// `false`.
|
|
62
|
+
@function are-equal($listA, $listB) {
|
|
63
|
+
$listA: assert.is-type($listA, 'list', $source: 'list_ext.are-equal');
|
|
64
|
+
$listB: assert.is-type($listB, 'list', $source: 'list_ext.are-equal');
|
|
65
|
+
$error: throw.get-error($listA, $listB);
|
|
66
|
+
@if $error {
|
|
67
|
+
@return $error;
|
|
68
|
+
}
|
|
69
|
+
@if list.length($listA) != list.length($listB) {
|
|
70
|
+
@return false;
|
|
71
|
+
}
|
|
72
|
+
$result: true;
|
|
73
|
+
@each $key in $listA {
|
|
74
|
+
@if not list.index($listB, $key) {
|
|
75
|
+
$result: false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@each $key in $listB {
|
|
80
|
+
@if not list.index($listA, $key) {
|
|
81
|
+
$result: false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
@return $result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// Returns the intersection of two lists.
|
|
88
|
+
///
|
|
89
|
+
/// @example scss
|
|
90
|
+
/// $listA: ('apple', 'banana', 'cherry', 'date');
|
|
91
|
+
/// $listB: ('banana', 'cherry', 'apple');
|
|
92
|
+
/// $listC: ('apple', 'banana', 'date');
|
|
93
|
+
///
|
|
94
|
+
/// @debug list_ext.intersection($listA, $listB); // ('apple', 'banana', 'cherry')
|
|
95
|
+
/// @debug list_ext.intersection($listA, $listC); // ('apple', 'banana')
|
|
96
|
+
///
|
|
97
|
+
/// @param {list} $listA - The first list to compare.
|
|
98
|
+
/// @param {list} $listB - The second list to compare.
|
|
99
|
+
/// @return {list} All items in $listA that are also in $listB.
|
|
100
|
+
@function intersection($listA, $listB) {
|
|
101
|
+
$listA: assert.is-type($listA, 'list', $source: 'list_ext.intersection');
|
|
102
|
+
$listB: assert.is-type($listB, 'list', $source: 'list_ext.intersection');
|
|
103
|
+
$error: throw.get-error($listA, $listB);
|
|
104
|
+
@if $error {
|
|
105
|
+
@return $error;
|
|
106
|
+
}
|
|
107
|
+
$result: ();
|
|
108
|
+
@each $item in $listA {
|
|
109
|
+
@if list.index($listB, $item) {
|
|
110
|
+
$result: list.append($result, $item, list.separator($listA));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
@return $result;
|
|
114
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 Google LLC
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
// Extensions to the go/sass:map built-in module.
|
|
7
|
+
|
|
8
|
+
// go/keep-sorted start by_regex='(.+) prefix_order=sass:
|
|
9
|
+
@use 'sass:list';
|
|
10
|
+
@use 'sass:map';
|
|
11
|
+
@use 'sass:meta';
|
|
12
|
+
@use 'assert';
|
|
13
|
+
@use 'throw';
|
|
14
|
+
@use 'type';
|
|
15
|
+
// go/keep-sorted end
|
|
16
|
+
|
|
17
|
+
/// The same as `map.get()` but throws an error if the key is not found.
|
|
18
|
+
///
|
|
19
|
+
/// This is useful over `map.get()` when using Sass maps like records, where
|
|
20
|
+
/// the key is expected to exist.
|
|
21
|
+
///
|
|
22
|
+
/// @example scss
|
|
23
|
+
/// $map: (
|
|
24
|
+
/// 'name': 'foo',
|
|
25
|
+
/// 'value': blue,
|
|
26
|
+
/// );
|
|
27
|
+
///
|
|
28
|
+
/// @debug map_ext.get-strict($map, 'name'); // 'foo'
|
|
29
|
+
/// @debug map_ext.get-strict($map, 'bar'); // ERROR: Key "bar" expected but not found in $map: ('name': 'foo', 'value': blue)
|
|
30
|
+
///
|
|
31
|
+
/// @param {map} $map - The map to retrieve the value from.
|
|
32
|
+
/// @param {string} $key - The key of the value to retrieve.
|
|
33
|
+
/// @param {list} $keys - Additional keys to retrieve deeply nested values.
|
|
34
|
+
/// @return {*} The value at the given key.
|
|
35
|
+
/// @throw Error if the key does not exist in the map.
|
|
36
|
+
@function get-strict($map, $key, $keys...) {
|
|
37
|
+
$map: assert.is-type($map, 'map', $source: 'map_ext.get-strict');
|
|
38
|
+
@if throw.get-error($map) {
|
|
39
|
+
@return $map;
|
|
40
|
+
}
|
|
41
|
+
@if not map.has-key($map, $key, $keys...) {
|
|
42
|
+
@return throw.error(
|
|
43
|
+
'Key #{$key} expected but not found in $map: #{meta.inspect($map)}',
|
|
44
|
+
$source: 'map.get-strict'
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@return map.get($map, $key, $keys...);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Splits a Map and returns a List pair with two new Maps: the first with the
|
|
52
|
+
/// provided keys and the second without.
|
|
53
|
+
///
|
|
54
|
+
/// @example scss
|
|
55
|
+
/// $map: (
|
|
56
|
+
/// 'focus': blue,
|
|
57
|
+
/// 'focus-within': blue,
|
|
58
|
+
/// 'hover': teal,
|
|
59
|
+
/// 'active': green,
|
|
60
|
+
/// );
|
|
61
|
+
///
|
|
62
|
+
/// $pair: map_ext.split($map, ('focus', 'focus-within'));
|
|
63
|
+
///
|
|
64
|
+
/// $map-with-focus-keys: list.nth($pair, 1);
|
|
65
|
+
/// @debug $map-with-focus-keys; // ('focus': blue, 'focus-within': blue)
|
|
66
|
+
///
|
|
67
|
+
/// $map-with-remaining-keys: list.nth($pair, 2);
|
|
68
|
+
/// @debug $map-with-remaining-keys; // ('hover': teal, 'active': green)
|
|
69
|
+
///
|
|
70
|
+
/// @param {map} $map - The Map to split.
|
|
71
|
+
/// @param {list} $keys - List of keys to split the Map by.
|
|
72
|
+
/// @return {list} A List pair with two new Maps: the first with the keys
|
|
73
|
+
/// provided, and the second with the remaining keys.
|
|
74
|
+
@function split($map, $keys) {
|
|
75
|
+
@if type.matches($keys, 'string') {
|
|
76
|
+
// A list with a single string `('key')` collapses to a single string type
|
|
77
|
+
// at build time. We can force it to be a list using a list API method.
|
|
78
|
+
// Ex:
|
|
79
|
+
// map_ext.split($map, ('key')) is the same as
|
|
80
|
+
// map_ext.split($map, 'key')
|
|
81
|
+
$keys: list.append((), $keys);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// In Sass, `()` counts as both a map and a list, and always reports its type
|
|
85
|
+
// as a list. If we're given an empty map-list, we don't need to throw a type
|
|
86
|
+
// error.
|
|
87
|
+
$map: assert.is-type($map, 'map|list', $source: 'map_ext.split');
|
|
88
|
+
$keys: assert.is-type($keys, 'list', $source: 'map_ext.split');
|
|
89
|
+
$error: throw.get-error($map, $keys);
|
|
90
|
+
@if not $error and list.length($keys) == 0 {
|
|
91
|
+
$error: throw.error(
|
|
92
|
+
'List of keys to split by are empty',
|
|
93
|
+
$source: 'map_ext.split'
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
@if $error {
|
|
97
|
+
@return $error;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// In Sass, `()` is an empty list. We can force Sass to use map types by
|
|
101
|
+
// creating the map with map APIs. This ensures that even if a map is empty,
|
|
102
|
+
// `meta.type-of()` will report it as a map.
|
|
103
|
+
$map-with-keys: map.merge((), ());
|
|
104
|
+
$map-without-keys: map.merge((), ());
|
|
105
|
+
@each $key, $value in $map {
|
|
106
|
+
$has-key: list.index($keys, $key) != null;
|
|
107
|
+
@if $has-key {
|
|
108
|
+
$map-with-keys: map.set($map-with-keys, $key, $value);
|
|
109
|
+
} @else {
|
|
110
|
+
$map-without-keys: map.set($map-without-keys, $key, $value);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@return ($map-with-keys, $map-without-keys);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// Splits a Map and returns a new Map that only includes the provided keys.
|
|
118
|
+
///
|
|
119
|
+
/// @example scss
|
|
120
|
+
/// $map: (
|
|
121
|
+
/// 'focus': blue,
|
|
122
|
+
/// 'focus-within': blue,
|
|
123
|
+
/// 'hover': teal,
|
|
124
|
+
/// 'active': green,
|
|
125
|
+
/// );
|
|
126
|
+
///
|
|
127
|
+
/// $map-with-focus-keys: map_ext.pick($map, ('focus', 'focus-within'));
|
|
128
|
+
/// @debug $map-with-focus-keys; // ('focus': blue, 'focus-within': blue)
|
|
129
|
+
///
|
|
130
|
+
/// @param {map} $map - The Map to split.
|
|
131
|
+
/// @param {list} $keys - List of keys to include in the new Map.
|
|
132
|
+
/// @return {map} Map with only the keys provided.
|
|
133
|
+
@function pick($map, $keys) {
|
|
134
|
+
$result: split($map, $keys);
|
|
135
|
+
@if throw.get-error($result) {
|
|
136
|
+
@return $result;
|
|
137
|
+
}
|
|
138
|
+
@return list.nth($result, 1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/// Splits a Map and returns a new Map that excludes the provided keys.
|
|
142
|
+
///
|
|
143
|
+
/// @example scss
|
|
144
|
+
/// $map: (
|
|
145
|
+
/// 'focus': blue,
|
|
146
|
+
/// 'focus-within': blue,
|
|
147
|
+
/// 'hover': teal,
|
|
148
|
+
/// 'active': green,
|
|
149
|
+
/// );
|
|
150
|
+
///
|
|
151
|
+
/// $map-without-focus-keys: map_ext.omit($map, ('focus', 'focus-within'));
|
|
152
|
+
/// @debug $map-without-focus-keys; // ('hover': teal, 'active': green)
|
|
153
|
+
///
|
|
154
|
+
/// @param {map} $map - The Map to split.
|
|
155
|
+
/// @param {list} $keys - List of keys to exclude from the new Map.
|
|
156
|
+
/// @return {map} Map without the keys provided.
|
|
157
|
+
@function omit($map, $keys) {
|
|
158
|
+
$result: split($map, $keys);
|
|
159
|
+
@if throw.get-error($result) {
|
|
160
|
+
@return $result;
|
|
161
|
+
}
|
|
162
|
+
@return list.nth($result, 2);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/// Returns the given map with any matching keys renamed according to the
|
|
166
|
+
/// provided Map of keys to rename.
|
|
167
|
+
///
|
|
168
|
+
/// @example scss
|
|
169
|
+
/// $map: ('foo': red);
|
|
170
|
+
///
|
|
171
|
+
/// $new-map: map_ext.rename-keys($map, ('foo': 'bar'));
|
|
172
|
+
/// @debug $new-map; // ('bar': red)
|
|
173
|
+
///
|
|
174
|
+
/// @param {map} $map - The map to rename keys within.
|
|
175
|
+
/// @param {map} $keys-to-rename - A map of keys and their new names.
|
|
176
|
+
/// @return {map} The map with any matching keys renamed.
|
|
177
|
+
@function rename-keys($map, $keys-to-rename) {
|
|
178
|
+
$new-map: omit($map, map.keys($keys-to-rename));
|
|
179
|
+
@if throw.get-error($new-map) {
|
|
180
|
+
@return $new-map;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@each $old-key-name, $new-key-name in $keys-to-rename {
|
|
184
|
+
@if map.has-key($map, $old-key-name) {
|
|
185
|
+
$new-map: map.set($new-map, $new-key-name, map.get($map, $old-key-name));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@return $new-map;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/// Returns a list of keys where $mapB diverges from $mapA.
|
|
193
|
+
/// Divergence occurs when:
|
|
194
|
+
/// 1. A key exists in $mapB but not in $mapA.
|
|
195
|
+
/// 2. A key exists in both maps but with different values.
|
|
196
|
+
///
|
|
197
|
+
/// @example scss
|
|
198
|
+
/// $mapA: ('foo': red, 'bar': yellow, 'baz': 10);
|
|
199
|
+
/// $mapB: ('foo': red, 'bar': green, 'baz': 10, 'fooBar': blue);
|
|
200
|
+
///
|
|
201
|
+
/// $differences: map_ext.difference($mapA, $mapB);
|
|
202
|
+
/// @debug $differences; // ('bar', 'fooBar')
|
|
203
|
+
///
|
|
204
|
+
/// @param {map} $mapA - The reference map.
|
|
205
|
+
/// @param {map} $mapB - The map to compare against the reference.
|
|
206
|
+
/// @return {list} A list of keys where $mapB diverges from $mapA.
|
|
207
|
+
@function difference($mapA, $mapB) {
|
|
208
|
+
$mapA: assert.is-type($mapA, 'map', $source: 'map_ext.difference');
|
|
209
|
+
$mapB: assert.is-type($mapB, 'map', $source: 'map_ext.difference');
|
|
210
|
+
$error: throw.get-error($mapA, $mapB);
|
|
211
|
+
@if $error {
|
|
212
|
+
@return $error;
|
|
213
|
+
}
|
|
214
|
+
$differences: ();
|
|
215
|
+
@each $key, $value in $mapB {
|
|
216
|
+
@if not map.has-key($mapA, $key) or map.get($mapA, $key) != $value {
|
|
217
|
+
$differences: list.append($differences, $key);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@return $differences;
|
|
222
|
+
}
|
|
@@ -3,90 +3,79 @@
|
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
//
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// Utility functions for "var()" custom property string manipulation.
|
|
7
|
+
|
|
8
|
+
// go/keep-sorted start by_regex='(.+) prefix_order=sass:
|
|
7
9
|
@use 'sass:map';
|
|
8
10
|
@use 'sass:meta';
|
|
9
11
|
@use 'sass:string';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@use '
|
|
12
|
+
@use 'assert';
|
|
13
|
+
@use 'string_ext';
|
|
14
|
+
@use 'throw';
|
|
13
15
|
// go/keep-sorted end
|
|
14
16
|
|
|
15
17
|
/// Creates a custom property `var()` string.
|
|
16
18
|
///
|
|
17
|
-
/// @
|
|
19
|
+
/// @example scss
|
|
20
|
+
/// @debug var.create(--foo); // "var(--foo)"
|
|
21
|
+
/// @debug var.create(--foo, 8px); // "var(--foo, 8px)"
|
|
22
|
+
///
|
|
23
|
+
/// @param {string} $name - The name of the custom property.
|
|
18
24
|
/// @param {*} $fallback [null] - Optional `var()` fallback value.
|
|
19
|
-
/// @return {
|
|
25
|
+
/// @return {string} A custom property `var()` string.
|
|
20
26
|
@function create($name, $fallback: null) {
|
|
21
|
-
$name:
|
|
22
|
-
@if $
|
|
23
|
-
@return
|
|
27
|
+
$name: assert.is-type($name, 'string');
|
|
28
|
+
@if throw.get-error($name) {
|
|
29
|
+
@return $name;
|
|
24
30
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
@if not string_ext.starts-with($name, '--') {
|
|
32
|
+
@return throw.error(
|
|
33
|
+
'Custom property names must start with "--". $name: #{meta.inspect($name)}',
|
|
34
|
+
$source: 'var.create'
|
|
35
|
+
);
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
@
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/// Create a custom property variable name.
|
|
36
|
-
///
|
|
37
|
-
/// Providing a custom property name with `--*` will ignore the global prefix.
|
|
38
|
-
///
|
|
39
|
-
/// @example - scss
|
|
40
|
-
/// .foo {
|
|
41
|
-
/// color: var(#{var.create-name(foo)});
|
|
42
|
-
/// background: var(#{var.create-name(--bar)});
|
|
43
|
-
/// }
|
|
44
|
-
///
|
|
45
|
-
/// @example - css
|
|
46
|
-
/// .foo {
|
|
47
|
-
/// color: var(--md-foo);
|
|
48
|
-
/// background: var(--bar);
|
|
49
|
-
/// }
|
|
50
|
-
///
|
|
51
|
-
/// @param {String} $name - The name of the custom property.
|
|
52
|
-
/// @return {String} The full valid CSS custom property variable name.
|
|
53
|
-
@function create-name($name) {
|
|
54
|
-
@if string_ext.starts-with($name, '--') {
|
|
55
|
-
@return $name;
|
|
38
|
+
@if $fallback == null {
|
|
39
|
+
@return var(#{$name});
|
|
56
40
|
}
|
|
57
41
|
|
|
58
|
-
@return
|
|
42
|
+
@return var(#{$name}, #{$fallback});
|
|
59
43
|
}
|
|
60
44
|
|
|
61
45
|
/// Returns the custom property variable name of `var()` string.
|
|
62
46
|
///
|
|
47
|
+
/// @example scss
|
|
48
|
+
/// $var: var(--foo);
|
|
49
|
+
/// @debug var.name($var); // "foo"
|
|
50
|
+
///
|
|
51
|
+
/// @param {string} $var - A custom property `var()` string.
|
|
52
|
+
/// @return {string} The custom property variable name.
|
|
63
53
|
/// @throw If the value is not a custom property.
|
|
64
|
-
/// @param {String} $var - A custom property `var()` string.
|
|
65
|
-
/// @return {String} The custom property variable name.
|
|
66
54
|
@function name($var) {
|
|
67
55
|
$var: _parse-and-validate($var);
|
|
68
|
-
@
|
|
56
|
+
@if throw.get-error($var) {
|
|
57
|
+
@return $var;
|
|
58
|
+
}
|
|
59
|
+
@return map.get($var, 'name');
|
|
69
60
|
}
|
|
70
61
|
|
|
71
62
|
/// Returns the fallback value of a custom property `var()` string. The value
|
|
72
63
|
/// may be null if the `var()` does not have a fallback value.
|
|
73
64
|
///
|
|
74
|
-
/// @example
|
|
75
|
-
/// $
|
|
76
|
-
/// // "var(--bar, 8px)"
|
|
65
|
+
/// @example scss
|
|
66
|
+
/// $var: var(--foo, var(--bar, 8px));
|
|
67
|
+
/// @debug var.fallback($var); // "var(--bar, 8px)"
|
|
77
68
|
///
|
|
78
|
-
/// @
|
|
79
|
-
/// @
|
|
80
|
-
/// @return {String} The fallback value of the `var()` string. May be null if
|
|
69
|
+
/// @param {string} $var - A custom property `var()` string.
|
|
70
|
+
/// @return {string} The fallback value of the `var()` string. May be null if
|
|
81
71
|
/// the `var()` does not have a fallback value.
|
|
72
|
+
/// @throw If the value is not a custom property.
|
|
82
73
|
@function fallback($var) {
|
|
83
74
|
$var: _parse-and-validate($var);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@return create(name($fallback), fallback($fallback));
|
|
75
|
+
@if throw.get-error($var) {
|
|
76
|
+
@return $var;
|
|
87
77
|
}
|
|
88
|
-
|
|
89
|
-
@return $fallback;
|
|
78
|
+
@return map.get($var, 'fallback');
|
|
90
79
|
}
|
|
91
80
|
|
|
92
81
|
/// Returns the deep fallback value of a custom property `var()` string. The
|
|
@@ -95,18 +84,18 @@
|
|
|
95
84
|
/// If a fallback value is another `var()`, this function will return the final
|
|
96
85
|
/// concrete value in the chain.
|
|
97
86
|
///
|
|
98
|
-
/// @example
|
|
99
|
-
/// $
|
|
100
|
-
/// // "8px"
|
|
87
|
+
/// @example scss
|
|
88
|
+
/// $var: var(--foo, var(--bar, 8px));
|
|
89
|
+
/// @debug var.deep-fallback($var); // "8px"
|
|
101
90
|
///
|
|
102
|
-
/// @
|
|
103
|
-
/// @
|
|
104
|
-
/// @return {String} The deep fallback value of the `var()` string. May be null
|
|
91
|
+
/// @param {string} $var - A custom property `var()` string.
|
|
92
|
+
/// @return {string} The deep fallback value of the `var()` string. May be null
|
|
105
93
|
/// if the `var()` does not have a fallback value.
|
|
94
|
+
/// @throw If the value is not a custom property.
|
|
106
95
|
@function deep-fallback($var) {
|
|
107
96
|
$fallback: fallback($var);
|
|
108
|
-
@
|
|
109
|
-
|
|
97
|
+
@while is-var($fallback) {
|
|
98
|
+
$fallback: fallback($fallback);
|
|
110
99
|
}
|
|
111
100
|
|
|
112
101
|
@return $fallback;
|
|
@@ -115,16 +104,17 @@
|
|
|
115
104
|
/// Creates a new custom property `var()` string and returns it with the
|
|
116
105
|
/// specified new fallback value.
|
|
117
106
|
///
|
|
118
|
-
/// @example
|
|
119
|
-
/// $
|
|
120
|
-
///
|
|
107
|
+
/// @example scss
|
|
108
|
+
/// $var: var(--foo, var(--bar, 8px));
|
|
109
|
+
/// $new-var: set-fallback($var, 16px);
|
|
110
|
+
/// @debug $new-var; // "var(--foo, 16px)"
|
|
121
111
|
///
|
|
122
|
-
/// @
|
|
123
|
-
/// @param {String} $var - A custom property `var()` string.
|
|
112
|
+
/// @param {string} $var - A custom property `var()` string.
|
|
124
113
|
/// @param {*} $new-fallback - The new fallback value. May be null to remove a
|
|
125
114
|
/// value.
|
|
126
|
-
/// @return {
|
|
115
|
+
/// @return {string} A custom property `var()` string with the new fallback
|
|
127
116
|
/// value.
|
|
117
|
+
/// @throw If the value is not a custom property.
|
|
128
118
|
@function set-fallback($var, $new-fallback) {
|
|
129
119
|
$name: name($var);
|
|
130
120
|
@return create($name, $new-fallback);
|
|
@@ -136,16 +126,17 @@
|
|
|
136
126
|
/// If the provided `var()` string's fallback value is another `var()`, this
|
|
137
127
|
/// function will set the final fallback value in the chain.
|
|
138
128
|
///
|
|
139
|
-
/// @example
|
|
140
|
-
/// $
|
|
141
|
-
///
|
|
129
|
+
/// @example scss
|
|
130
|
+
/// $var: var(--foo, var(--bar, 8px));
|
|
131
|
+
/// $new-var: var.deep-set-fallback($var, 16px);
|
|
132
|
+
/// @debug $new-var; // "var(--foo, var(--bar, 16px))"
|
|
142
133
|
///
|
|
143
|
-
/// @
|
|
144
|
-
/// @param {String} $var - A custom property `var()` string.
|
|
134
|
+
/// @param {string} $var - A custom property `var()` string.
|
|
145
135
|
/// @param {*} $new-fallback - The new fallback value. May be null to remove a
|
|
146
136
|
/// value.
|
|
147
|
-
/// @return {
|
|
137
|
+
/// @return {string} A custom property `var()` string with the new deep
|
|
148
138
|
/// fallback value.
|
|
139
|
+
/// @throw If the value is not a custom property.
|
|
149
140
|
@function deep-set-fallback($var, $new-fallback) {
|
|
150
141
|
$old-fallback: fallback($var);
|
|
151
142
|
@if is-var($old-fallback) {
|
|
@@ -157,11 +148,12 @@
|
|
|
157
148
|
|
|
158
149
|
/// Indicates whether or not a value is a custom property `var()` string.
|
|
159
150
|
///
|
|
160
|
-
/// @example
|
|
161
|
-
/// $
|
|
151
|
+
/// @example scss
|
|
152
|
+
/// $var: var(--foo);
|
|
153
|
+
/// @debug var.is-var($var); // true
|
|
162
154
|
///
|
|
163
155
|
/// @param {*} $var - The value to test.
|
|
164
|
-
/// @return {
|
|
156
|
+
/// @return {boolean} True if the value is a custom property `var()` string, or
|
|
165
157
|
/// false if not.
|
|
166
158
|
@function is-var($var) {
|
|
167
159
|
@return _parse($var) != null;
|
|
@@ -170,7 +162,7 @@
|
|
|
170
162
|
/// Indicates whether or not a value is a `var()` string.
|
|
171
163
|
///
|
|
172
164
|
/// @param {*} $var - The value to test.
|
|
173
|
-
/// @return {
|
|
165
|
+
/// @return {boolean} True if the value is a custom property `var()` string, or
|
|
174
166
|
/// false if not.
|
|
175
167
|
@function _is-var-string($var) {
|
|
176
168
|
@return meta.type-of($var) == 'string' and
|
|
@@ -181,14 +173,14 @@
|
|
|
181
173
|
/// function returns null if the value is invalid.
|
|
182
174
|
///
|
|
183
175
|
/// @param {*} $var - The value to parse.
|
|
184
|
-
/// @return {
|
|
176
|
+
/// @return {map} A Map containing a string `name` key with the custom property
|
|
185
177
|
/// name and a `fallback` key with the fallback value (which may be null).
|
|
186
178
|
/// The returned Map itself may be null if the provided value is not valid.
|
|
187
179
|
@function _parse($var) {
|
|
188
180
|
@if meta.type-of($var) ==
|
|
189
181
|
'map' and
|
|
190
|
-
map.has-key($var, name) and
|
|
191
|
-
map.has-key($var, fallback)
|
|
182
|
+
map.has-key($var, 'name') and
|
|
183
|
+
map.has-key($var, 'fallback')
|
|
192
184
|
{
|
|
193
185
|
@return $var;
|
|
194
186
|
}
|
|
@@ -207,32 +199,28 @@
|
|
|
207
199
|
@if $comma != null {
|
|
208
200
|
$name: string_ext.trim(string.slice($var, 1, $comma - 1));
|
|
209
201
|
$fallback: string_ext.trim(string.slice($var, $comma + 1));
|
|
210
|
-
@if _is-var-string($fallback) {
|
|
211
|
-
$fallback: _parse($fallback);
|
|
212
|
-
@if $fallback == null {
|
|
213
|
-
// Invalid var() fallback string
|
|
214
|
-
@return null;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
202
|
}
|
|
218
203
|
|
|
219
204
|
@if $name == '' or $fallback == '' {
|
|
220
205
|
@return null;
|
|
221
206
|
}
|
|
222
207
|
|
|
223
|
-
@return (name: $name, fallback: $fallback);
|
|
208
|
+
@return ('name': $name, 'fallback': $fallback);
|
|
224
209
|
}
|
|
225
210
|
|
|
226
211
|
/// Parses a `var()` string into a Map with `name` and `fallback` keys.
|
|
227
212
|
///
|
|
228
|
-
/// @throw If the value is not a custom property.
|
|
229
213
|
/// @param {*} $var - The value to parse.
|
|
230
|
-
/// @return {
|
|
214
|
+
/// @return {map} A Map containing a string `name` key with the custom property
|
|
231
215
|
/// name and a `fallback` key with the fallback value (which may be null).
|
|
216
|
+
/// @throw If the value is not a custom property.
|
|
232
217
|
@function _parse-and-validate($var) {
|
|
233
218
|
$var-map: _parse($var);
|
|
234
219
|
@if $var-map == null {
|
|
235
|
-
@error
|
|
220
|
+
@return throw.error(
|
|
221
|
+
'#{meta.inspect($var)} is not a valid var() string',
|
|
222
|
+
$source: 'var._parse-and-validate'
|
|
223
|
+
);
|
|
236
224
|
}
|
|
237
225
|
|
|
238
226
|
@return $var-map;
|