|
1 | 1 | @use 'sass:list';
|
2 | 2 | @use 'sass:map';
|
| 3 | +@use 'sass:meta'; |
| 4 | +@use 'sass:string'; |
3 | 5 | @use '@angular/material' as mat;
|
| 6 | +@use './m3-palettes'; |
| 7 | + |
| 8 | +/// Updates an error message by finding `$config` and appending a suffix to it. |
| 9 | +/// @param {List|String} $err The error message. |
| 10 | +/// @param {String} $suffix The suffix to add. |
| 11 | +/// @return {List|String} The updated error message. |
| 12 | +@function _update-dollar-config($err, $suffix) { |
| 13 | + @if meta.type-of($err) == 'list' { |
| 14 | + @for $i from 1 through list.length($err) { |
| 15 | + $err: list.set-nth($err, $i, _update-dollar-config(list.nth($err, $i), $suffix)); |
| 16 | + } |
| 17 | + } |
| 18 | + @else if meta.type-of($err) == 'string' { |
| 19 | + $start: string.index($err, '$config'); |
| 20 | + @if $start { |
| 21 | + $err: string.insert($err, $suffix, $start + 7); |
| 22 | + } |
| 23 | + } |
| 24 | + @return $err; |
| 25 | +} |
| 26 | + |
| 27 | +/// Validates that the given object is an M3 palette. |
| 28 | +/// @param {*} $palette The object to test |
| 29 | +/// @return {Boolean|null} null if it is a valid M3 palette, else true. |
| 30 | +@function _validate-palette($palette) { |
| 31 | + @if not meta.type-of($palette) == 'map' { |
| 32 | + @return true; |
| 33 | + } |
| 34 | + $keys: map.keys($palette); |
| 35 | + $expected-keys: map.keys(m3-palettes.$red-palette); |
| 36 | + @if mat.private-validate-allowed-values($keys, $expected-keys...) or |
| 37 | + mat.private-validate-required-values($keys, $expected-keys...) { |
| 38 | + @return true; |
| 39 | + } |
| 40 | + $nv-keys: map.keys(map.get($palette, neutral-variant)); |
| 41 | + $expected-nv-keys: map.keys(map.get(m3-palettes.$red-palette, neutral-variant)); |
| 42 | + @if mat.private-validate-allowed-values($nv-keys, $expected-nv-keys...) or |
| 43 | + mat.private-validate-required-values($nv-keys, $expected-nv-keys...) { |
| 44 | + @return true; |
| 45 | + } |
| 46 | + @return null; |
| 47 | +} |
4 | 48 |
|
5 | 49 | /// Validates a theme config.
|
6 | 50 | /// @param {Map} $config The config to test.
|
7 | 51 | /// @return {List} null if no error, else the error message
|
8 | 52 | @function validate-theme-config($config) {
|
9 | 53 | $err: mat.private-validate-type($config, 'map', 'null');
|
10 | 54 | @if $err {
|
11 |
| - @return (#{'$config'} #{'should be a color configuration object. Got:'} $config); |
| 55 | + @return (#{'$config should be a configuration object. Got:'} $config); |
12 | 56 | }
|
13 |
| - $err: mat.private-validate-allowed-values(map.keys($config or ()), color, typography, density); |
| 57 | + $allowed: (color, typography, density); |
| 58 | + $err: mat.private-validate-allowed-values(map.keys($config or ()), $allowed...); |
14 | 59 | @if $err {
|
15 |
| - @return (#{'$config'} #{'has unexpected properties:'} $err); |
| 60 | + @return ( |
| 61 | + #{'$config has unexpected properties. Valid properties are'} |
| 62 | + #{'#{$allowed}.'} |
| 63 | + #{'Found:'} |
| 64 | + $err |
| 65 | + ); |
16 | 66 | }
|
17 | 67 | $err: validate-color-config(map.get($config, color));
|
18 | 68 | @if $err {
|
19 |
| - @return list.set-nth($err, 1, #{'#{list.nth($err, 1)}.color'}); |
| 69 | + @return _update-dollar-config($err, '.color'); |
20 | 70 | }
|
21 | 71 | $err: validate-typography-config(map.get($config, typography));
|
22 | 72 | @if $err {
|
23 |
| - @return list.set-nth($err, 1, #{'#{list.nth($err, 1)}.typography'}); |
| 73 | + @return _update-dollar-config($err, '.typography'); |
24 | 74 | }
|
25 | 75 | $err: validate-density-config(map.get($config, density));
|
26 | 76 | @if $err {
|
27 |
| - @return list.set-nth($err, 1, #{'#{list.nth($err, 1)}.density'}); |
| 77 | + @return _update-dollar-config($err, '.density'); |
28 | 78 | }
|
29 | 79 | @return null;
|
30 | 80 | }
|
|
35 | 85 | @function validate-color-config($config) {
|
36 | 86 | $err: mat.private-validate-type($config, 'map', 'null');
|
37 | 87 | @if $err {
|
38 |
| - @return (#{'$config'} #{'should be a color configuration object. Got:'} $config); |
| 88 | + @return (#{'$config should be a color configuration object. Got:'} $config); |
39 | 89 | }
|
40 |
| - $err: mat.private-validate-allowed-values( |
41 |
| - map.keys($config or ()), theme-type, primary, secondary, tertiary); |
| 90 | + $allowed: (theme-type, primary, secondary, tertiary); |
| 91 | + $err: mat.private-validate-allowed-values(map.keys($config or ()), $allowed...); |
42 | 92 | @if $err {
|
43 |
| - @return (#{'$config'} #{'has unexpected properties:'} $err); |
| 93 | + @return ( |
| 94 | + #{'$config has unexpected properties. Valid properties are'} |
| 95 | + #{'#{$allowed}.'} |
| 96 | + #{'Found:'} |
| 97 | + $err |
| 98 | + ); |
| 99 | + } |
| 100 | + @if $config and map.has-key($config, theme-type) and |
| 101 | + not list.index((light, dark), map.get($config, theme-type)) { |
| 102 | + @return ( |
| 103 | + #{'Expected $config.theme-type to be one of: light, dark. Got:'} |
| 104 | + map.get($config, theme-type) |
| 105 | + ); |
| 106 | + } |
| 107 | + @each $palette in (primary, secondary, tertiary) { |
| 108 | + @if $config and map.has-key($config, $palette) { |
| 109 | + $err: _validate-palette(map.get($config, $palette)); |
| 110 | + @if $err { |
| 111 | + @return ( |
| 112 | + #{'Expected $config.#{$palette} to be a valid M3 palette. Got:'} |
| 113 | + map.get($config, $palette) |
| 114 | + ); |
| 115 | + } |
| 116 | + } |
44 | 117 | }
|
45 | 118 | @return null;
|
46 | 119 | }
|
|
51 | 124 | @function validate-typography-config($config) {
|
52 | 125 | $err: mat.private-validate-type($config, 'map', 'null');
|
53 | 126 | @if $err {
|
54 |
| - @return (#{'$config'} #{'should be a typography configuration object. Got:'} $config); |
| 127 | + @return (#{'$config should be a typography configuration object. Got:'} $config); |
55 | 128 | }
|
56 |
| - $err: mat.private-validate-allowed-values( |
57 |
| - map.keys($config or ()), brand-family, plain-family, bold-weight, medium-weight, |
58 |
| - regular-weight); |
| 129 | + $allowed: (brand-family, plain-family, bold-weight, medium-weight, regular-weight); |
| 130 | + $err: mat.private-validate-allowed-values(map.keys($config or ()), $allowed...); |
59 | 131 | @if $err {
|
60 |
| - @return (#{'$config'} #{'has unexpected properties:'} $err); |
| 132 | + @return ( |
| 133 | + #{'$config has unexpected properties. Valid properties are'} |
| 134 | + #{'#{$allowed}.'} |
| 135 | + #{'Found:'} |
| 136 | + $err |
| 137 | + ); |
61 | 138 | }
|
62 | 139 | @return null;
|
63 | 140 | }
|
|
68 | 145 | @function validate-density-config($config) {
|
69 | 146 | $err: mat.private-validate-type($config, 'map', 'null');
|
70 | 147 | @if $err {
|
71 |
| - @return (#{'$config'} #{'should be a density configuration object. Got:'} $config); |
| 148 | + @return (#{'$config should be a density configuration object. Got:'} $config); |
72 | 149 | }
|
73 | 150 | $err: mat.private-validate-allowed-values(map.keys($config or ()), scale);
|
74 | 151 | @if $err {
|
75 |
| - @return (#{'$config'} #{'has unexpected properties:'} $err); |
| 152 | + @return (#{'$config has unexpected properties. Valid properties are: scale. Found:'} $err); |
| 153 | + } |
| 154 | + @if $config and map.has-key($config, scale) { |
| 155 | + $allowed-scales: (0, -1, -2, -3, -4 -5, minimum, maximum); |
| 156 | + @if mat.private-validate-allowed-values(map.get($config, scale), $allowed-scales...) { |
| 157 | + @return ( |
| 158 | + #{'Expected $config.scale to be one of: #{$allowed-scales}. Got:'} |
| 159 | + map.get($config, scale) |
| 160 | + ); |
| 161 | + } |
76 | 162 | }
|
77 | 163 | @return null;
|
78 | 164 | }
|
0 commit comments