|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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; |
|
0 commit comments