Skip to content

Commit d1ceb6b

Browse files
committed
fix(material-experimental/theming): fix disabled form field in M3
M3 tokens have two separate values for the disabled state: a solid color and an opacity. These changes combine the two to resolve the issue where the disabled state of form field is a solid dark color.
1 parent bf7e9ef commit d1ceb6b

File tree

1 file changed

+168
-2
lines changed

1 file changed

+168
-2
lines changed

src/material-experimental/theming/_m3-tokens.scss

Lines changed: 168 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@use 'sass:map';
2+
@use 'sass:meta';
23
@use '@angular/material' as mat;
34
@use '@material/tokens/v0_161' as mdc-tokens;
45
@use './m3-density';
@@ -110,6 +111,36 @@
110111
);
111112
}
112113

114+
/// At the time of writing, some color tokens (e.g. disabled state) are defined as a solid color
115+
/// token and a separate opacity token. This function applies the opacity to the color and drops the
116+
/// opacity key from the map. Can be removed once b/213331407 is resolved.
117+
/// @param {Map} $tokens The map of tokens currently being generated
118+
/// @param {Map} $all-tokens A map of all tokens, including hardcoded values
119+
/// @param {List} $pairs Pairs of color token names and their opacities. Should be in the shape of
120+
/// `((color: 'color-key', opacity: 'opacity-key'))`.
121+
/// @return {Map} The initial tokens with the combined color values.
122+
@function _combine-color-tokens($tokens, $opacity-lookup, $pairs) {
123+
$result: $tokens;
124+
125+
@each $pair in $pairs {
126+
$color-key: map.get($pair, color);
127+
$opacity-key: map.get($pair, opacity);
128+
$color: map.get($tokens, $color-key);
129+
$opacity: map.get($opacity-lookup, $opacity-key);
130+
131+
@if meta.type-of($color) == 'color' {
132+
@if meta.type-of($opacity) != 'number' {
133+
@error 'Cannot find valid opacity value for color token "#{$color-key}"';
134+
}
135+
136+
$result: map.remove($result, $opacity-key);
137+
$result: map.set($result, $color-key, rgba($color, $opacity));
138+
}
139+
}
140+
141+
@return $result;
142+
}
143+
113144
/// Renames the official checkbox tokens to match the names actually used in MDC's code (which are
114145
/// different). This is a temporary workaround until MDC updates to use the correct names for the
115146
/// tokens.
@@ -135,6 +166,131 @@
135166
@return _rename-map-keys($tokens, $rename-keys);
136167
}
137168

169+
/// Fixes inconsistent values in the text field color tokens. Applies to both filled and outlined
170+
/// variants.
171+
/// @param {Map} $initial-tokens Map of text field tokens currently being generated.
172+
/// @param {Map} $all-tokens Map of all text field tokens, including hardcoded values.
173+
/// This is necessary in order to do opacity lookups.
174+
/// @return {Map} The given tokens, with the invalid values replaced with valid ones.
175+
@function _fix-text-field-color-tokens($initial-tokens, $all-tokens) {
176+
@return _combine-color-tokens($initial-tokens, $all-tokens, (
177+
(
178+
color: 'disabled-active-indicator-color',
179+
opacity: 'disabled-active-indicator-opacity'
180+
),
181+
(
182+
color: 'disabled-container-color',
183+
opacity: 'disabled-container-opacity'
184+
),
185+
(
186+
color: 'disabled-input-text-color',
187+
opacity: 'disabled-input-text-opacity'
188+
),
189+
(
190+
color: 'disabled-label-text-color',
191+
opacity: 'disabled-label-text-opacity'
192+
),
193+
(
194+
color: 'disabled-leading-icon-color',
195+
opacity: 'disabled-leading-icon-opacity'
196+
),
197+
(
198+
color: 'disabled-supporting-text-color',
199+
opacity: 'disabled-supporting-text-opacity'
200+
),
201+
(
202+
color: 'disabled-trailing-icon-color',
203+
opacity: 'disabled-trailing-icon-opacity'
204+
)
205+
));
206+
}
207+
208+
209+
/// Fixes inconsistent values in the filled text field tokens so that they can produce valid
210+
/// styles.
211+
/// @param {Map} $initial-tokens Map of filled text field tokens currently being generated.
212+
/// @param {Map} $all-tokens Map of all filled text field tokens, including hardcoded values.
213+
/// @return {Map} The given tokens, with the invalid values replaced with valid ones.
214+
@function _fix-filled-text-field-tokens($initial-tokens, $all-tokens) {
215+
$tokens: _combine-color-tokens($initial-tokens, $all-tokens, (
216+
(
217+
color: 'disabled-active-indicator-color',
218+
opacity: 'disabled-active-indicator-opacity'
219+
),
220+
(
221+
color: 'disabled-container-color',
222+
opacity: 'disabled-container-opacity'
223+
),
224+
(
225+
color: 'disabled-input-text-color',
226+
opacity: 'disabled-input-text-opacity'
227+
),
228+
(
229+
color: 'disabled-label-text-color',
230+
opacity: 'disabled-label-text-opacity'
231+
),
232+
(
233+
color: 'disabled-leading-icon-color',
234+
opacity: 'disabled-leading-icon-opacity'
235+
),
236+
(
237+
color: 'disabled-supporting-text-color',
238+
opacity: 'disabled-supporting-text-opacity'
239+
),
240+
(
241+
color: 'disabled-trailing-icon-color',
242+
opacity: 'disabled-trailing-icon-opacity'
243+
)
244+
));
245+
246+
// TODO(crisbeto): also needs to fix the container-shape here.
247+
248+
@return $tokens;
249+
}
250+
251+
/// Fixes inconsistent values in the outlined text field tokens so that they can produce valid
252+
/// styles.
253+
/// @param {Map} $initial-tokens Map of outlined text field tokens currently being generated.
254+
/// @param {Map} $all-tokens Map of all outlined text field tokens, including hardcoded values.
255+
/// This is necessary in order to do opacity lookups.
256+
/// @return {Map} The given tokens, with the invalid values replaced with valid ones.
257+
@function _fix-outlined-text-field-tokens($initial-tokens, $all-tokens) {
258+
@return _combine-color-tokens($initial-tokens, $all-tokens, (
259+
(
260+
color: 'disabled-outline-color',
261+
opacity: 'disabled-outline-opacity'
262+
),
263+
(
264+
color: 'disabled-active-indicator-color',
265+
opacity: 'disabled-active-indicator-opacity'
266+
),
267+
(
268+
color: 'disabled-container-color',
269+
opacity: 'disabled-container-opacity'
270+
),
271+
(
272+
color: 'disabled-input-text-color',
273+
opacity: 'disabled-input-text-opacity'
274+
),
275+
(
276+
color: 'disabled-label-text-color',
277+
opacity: 'disabled-label-text-opacity'
278+
),
279+
(
280+
color: 'disabled-leading-icon-color',
281+
opacity: 'disabled-leading-icon-opacity'
282+
),
283+
(
284+
color: 'disabled-supporting-text-color',
285+
opacity: 'disabled-supporting-text-opacity'
286+
),
287+
(
288+
color: 'disabled-trailing-icon-color',
289+
opacity: 'disabled-trailing-icon-opacity'
290+
)
291+
));
292+
}
293+
138294
/// Generates a set of namespaced tokens for all components.
139295
/// @param {Map} $systems The MDC system tokens
140296
/// @param {Boolean} $include-non-systemized Whether to include non-systemized tokens
@@ -209,7 +365,12 @@
209365
),
210366
_namespace-tokens(
211367
(mdc, filled-text-field),
212-
mdc-tokens.md-comp-filled-text-field-values($systems, $exclude-hardcoded),
368+
_fix-filled-text-field-tokens(
369+
mdc-tokens.md-comp-filled-text-field-values($systems, $exclude-hardcoded),
370+
// Need to pass in the hardcoded values, because they
371+
// include opacities that are used for the disabled state.
372+
mdc-tokens.md-comp-filled-text-field-values($systems, false)
373+
),
213374
$token-slots
214375
),
215376
_namespace-tokens(
@@ -234,7 +395,12 @@
234395
),
235396
_namespace-tokens(
236397
(mdc, outlined-text-field),
237-
mdc-tokens.md-comp-outlined-text-field-values($systems, $exclude-hardcoded),
398+
_fix-outlined-text-field-tokens(
399+
mdc-tokens.md-comp-outlined-text-field-values($systems, $exclude-hardcoded),
400+
// Need to pass in the hardcoded values, because they
401+
// include opacities that are used for the disabled state.
402+
mdc-tokens.md-comp-outlined-text-field-values($systems, false),
403+
),
238404
$token-slots
239405
),
240406
_namespace-tokens(

0 commit comments

Comments
 (0)