-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
_validate.scss
130 lines (115 loc) · 3.94 KB
/
_validate.scss
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
118
119
120
121
122
123
124
125
126
127
128
129
130
//
// Copyright 2021 Google LLC
// SPDX-License-Identifier: Apache-2.0
//
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';
@use './string-ext';
/// Validates a theme's tokens and throws an error if incorrect tokens are
/// present or any tokens are missing.
///
/// Use this in internal `theme-styles()` mixins to validate library-provided
/// `$theme` maps and ensure that all tokens are correct and present.
///
/// @example - scss
/// @mixin theme-styles($theme) {
/// $theme: theme.validate-theme-styles($light-theme, $theme);
/// $theme: theme.create-theme-vars($theme, checkbox);
/// }
///
/// @throw If any tokens are invalid or missing.
/// @param {Map|List} $reference-theme - A reference theme Map whose token keys
/// will be used to validate the user-provided theme (or list of tokens).
/// @param {Map} $theme - The theme Map to validate.
/// @return {Map} The validated theme Map.
@function theme-styles($reference-theme, $theme, $require-all: true) {
$valid-tokens: $reference-theme;
@if meta.type-of($reference-theme) == 'map' {
$valid-tokens: map.keys($reference-theme);
}
$theme: _validate-theme-tokens(
$valid-tokens,
$theme,
$require-all: $require-all
);
@return $theme;
}
/// Validates a theme's tokens and values and throws an error if incorrect
/// tokens are present or invalid values are provided.
///
/// Use this in `theme()` mixins to validate user-provided `$theme` maps before
/// providing the value to `theme.create-theme-vars()`.
///
/// @example - scss
/// @mixin theme($theme) {
/// $theme: validate.theme($light-theme, $theme);
/// $theme: theme.create-theme-vars($theme, checkbox);
/// }
///
/// @throw If any tokens or values are invalid.
/// @param {Map|List} $reference-theme - A reference theme Map whose token keys
/// will be used to validate the user-provided theme (or list of tokens).
/// @param {Map} $theme - User-provided theme Map to validate.
/// @return {Map} The validated user-provided theme Map.
@function theme($reference-theme, $theme) {
$valid-tokens: $reference-theme;
@if meta.type-of($reference-theme) == 'map' {
$valid-tokens: map.keys($reference-theme);
}
$theme: _validate-theme-tokens($valid-tokens, $theme, $require-all: false);
@return $theme;
}
/// Validates input for a `theme` mixin and throws an error if incorrect tokens
/// are present or optionally missing if `$require-all` is true.
///
/// @throw If any tokens are invalid or optionally missing.
/// @param {List} $valid-tokens - A List of token keys to validate the theme.
/// @param {Map} $theme - The theme Map to validate.
/// @param {Bool} $require-all [false] - If true, throw an error if the theme
/// is missing tokens from the list.
/// @return {Map} The validated theme Map.
@function _validate-theme-tokens($valid-tokens, $theme, $require-all: false) {
$missing-tokens: ();
$unsupported-tokens: ();
@each $token, $value in $theme {
@if $token != null and list.index($valid-tokens, $token) == null {
$unsupported-tokens: list.append(
$unsupported-tokens,
$token,
$separator: comma
);
}
}
@if $require-all {
// TODO(b/203778922): Remove when type composite tokens are removed
$ignore-suffix: (
// Ignore composite font tokens
'-type'
);
@each $token in $valid-tokens {
$missing: map.get($theme, $token) == null;
@if $missing {
@each $suffix in $ignore-suffix {
@if string-ext.has-suffix($token, $suffix) {
$missing: false;
}
}
}
@if $missing {
$missing-tokens: list.append(
$missing-tokens,
$token,
$separator: comma
);
}
}
}
@if list.length($unsupported-tokens) > 0 {
@error 'The following tokens are invalid: #{$unsupported-tokens}.';
}
@if list.length($missing-tokens) > 0 {
@error 'The following required tokens are missing: #{$missing-tokens}.';
}
@return $theme;
}