@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@material/web",
3
- "version": "2.4.2-nightly.563da62.0",
3
+ "version": "2.4.2-nightly.a7ba471.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -54,7 +54,7 @@
54
54
  /// returned, otherwise an error is thrown.
55
55
  ///
56
56
  /// @example scss
57
- /// @function get-or-throw($map, $key) {
57
+ /// @function get-strict($map, $key) {
58
58
  /// @return assert.not-type(
59
59
  /// map.get($map, $key),
60
60
  /// 'null',
@@ -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
- // go/keep-sorted start
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
- // go/keep-sorted end
11
- // go/keep-sorted start
12
- @use '../../sass/ext/string_ext';
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
- /// @param {String} $name - The name of the custom property.
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 {String} A custom property `var()` string.
25
+ /// @return {string} A custom property `var()` string.
20
26
  @function create($name, $fallback: null) {
21
- $name: create-name($name);
22
- @if $fallback == null {
23
- @return var(#{$name});
27
+ $name: assert.is-type($name, 'string');
28
+ @if throw.get-error($name) {
29
+ @return $name;
24
30
  }
25
-
26
- @if is-var($fallback) {
27
- $fallback-name: name($fallback);
28
- $fallback-fallback: fallback($fallback);
29
- @return var(#{$name}, create($fallback-name, $fallback-fallback));
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
- @return var(#{$name}, $fallback);
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 string.unquote('--md-#{$name}');
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
- @return map.get($var, name);
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 - scss
75
- /// $fallback: var.fallback(var(--foo, var(--bar, 8px));
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
- /// @throw If the value is not a custom property.
79
- /// @param {String} $var - A custom property `var()` string.
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
- $fallback: map.get($var, fallback);
85
- @if is-var($fallback) {
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 - scss
99
- /// $fallback: var.deep-fallback(var(--foo, var(--bar, 8px));
100
- /// // "8px"
87
+ /// @example scss
88
+ /// $var: var(--foo, var(--bar, 8px));
89
+ /// @debug var.deep-fallback($var); // "8px"
101
90
  ///
102
- /// @throw If the value is not a custom property.
103
- /// @param {String} $var - A custom property `var()` string.
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
- @if is-var($fallback) {
109
- @return deep-fallback($fallback);
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 - scss
119
- /// $new-var: set-fallback(var(--foo, var(--bar, 8px)), 16px);
120
- /// // "var(--foo, 16px)"
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
- /// @throw If the value is not a custom property.
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 {String} A custom property `var()` string with the new fallback
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 - scss
140
- /// $new-var: deep-set-fallback(var(--foo, var(--bar, 8px)), 16px);
141
- /// // "var(--foo, var(--bar, 16px))"
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
- /// @throw If the value is not a custom property.
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 {String} A custom property `var()` string with the new deep
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 - scss
161
- /// $is-var: var.is-var('var(--foo)'); // true
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 {Bool} True if the value is a custom property `var()` string, or
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 {Bool} True if the value is a custom property `var()` string, or
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 {Map} A Map containing a string `name` key with the custom property
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 {Map} A Map containing a string `name` key with the custom property
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 '"#{$var}" is not a valid var() string';
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;
@@ -9,7 +9,10 @@
9
9
 
10
10
  // go/keep-sorted start
11
11
  @use 'assert_test';
12
+ @use 'list_ext_test';
13
+ @use 'map_ext_test';
12
14
  @use 'string_ext_test';
13
15
  @use 'throw_test';
14
16
  @use 'type_test';
17
+ @use 'var_test';
15
18
  // go/keep-sorted end