Skip to content

Commit 1a85dd2

Browse files
committed
feat(material/theming): Add APIs to get color info from theme
1 parent a7dbf08 commit 1a85dd2

File tree

4 files changed

+174
-16
lines changed

4 files changed

+174
-16
lines changed

src/material-experimental/theming/_definition.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ $theme-version: 1;
4646
$internals: (
4747
theme-version: $theme-version,
4848
theme-type: $type,
49+
palettes: (
50+
primary: map.remove($primary, neutral-variant),
51+
secondary: map.remove($secondary, neutral-variant),
52+
tertiary: map.remove($tertiary, neutral-variant),
53+
neutral: m3-palettes.$neutral-palette,
54+
neutral-variant: map.get($primary, neutral-variant),
55+
error: m3-palettes.$red-palette
56+
),
4957
color-tokens: m3-tokens.generate-color-tokens($type, $primary, $secondary, $tertiary,
5058
m3-palettes.$neutral-palette, m3-palettes.$red-palette)
5159
)

src/material/_index.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,5 @@ list-density, list-base;
144144
$private-mdc-theme-styles-query, $private-mdc-typography-styles-query;
145145

146146
// New theming APIs, currently in development:
147-
@forward './core/theming/inspection' as private-* show private-get-theme-version;
147+
@forward './core/theming/inspection' as private-* show private-get-theme-version,
148+
private-get-theme-type, private-get-theme-color;

src/material/core/theming/_inspection.scss

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,81 @@ $_internals: _mat-theming-internals-do-not-access;
2424
@return if($err, 0, map.get($theme, $_internals, theme-version) or 0);
2525
}
2626

27+
/// Gets the type of theme represented by a theme object (light or dark).
28+
/// @param {Map} $theme The theme
29+
/// @return {String} The type of theme (either `light` or `dark`).
30+
@function get-theme-type($theme) {
31+
$err: _validate-theme-object($theme);
32+
@if $err {
33+
// TODO(mmalerba): implement for old style theme objects.
34+
@error #{'get-theme-type does not support legacy theme objects.'};
35+
}
36+
@return map.get($theme, $_internals, theme-type) or light;
37+
}
38+
39+
/// Gets a color from a theme object. This function can take 2 or 3 arguments. If 2 arguments are
40+
/// passed, the second argument is treated as the name of a color role. If 3 arguments are passed,
41+
/// the second argument is treated as the name of a color palette (primary, secondary, etc.) and the
42+
/// third is treated as the palette hue (10, 50, etc.)
43+
/// @param {Map} $theme The theme
44+
/// @param {String} $color-role-or-palette-name The name of the color role to get, or the name of a
45+
/// color palette.
46+
/// @param {Number} $hue The palette hue to get (passing this argument means the second argument is
47+
/// interpreted as a palette name).
48+
/// @return {Color} The requested theme color.
49+
@function get-theme-color($theme, $args...) {
50+
$args-count: list.length($args);
51+
@if $args-count == 1 {
52+
@return _get-theme-role-color($theme, $args...);
53+
} @else if $args-count == 2 {
54+
@return _get-theme-palette-color($theme, $args...);
55+
}
56+
@error #{'Expected 2 or 3 arguments. Got:'} $args-count + 1;
57+
}
58+
59+
/// Gets a role color from a theme object.
60+
/// @param {Map} $theme The theme
61+
/// @param {String} $color-role-name The name of the color role to get.
62+
/// @return {Color} The requested role color.
63+
@function _get-theme-role-color($theme, $color-role-name) {
64+
$err: _validate-theme-object($theme);
65+
@if $err {
66+
// TODO(mmalerba): implement for old style theme objects.
67+
@error #{'get-theme-color does not support legacy theme objects.'};
68+
}
69+
$color-roles: map.get($theme, $_internals, color-tokens, (mdc, theme));
70+
$result: map.get($color-roles, $color-role-name);
71+
@if not $result {
72+
@error #{'Valid color roles are: #{map.keys($color-roles)}. Got:'} $color-role-name;
73+
}
74+
@return $result;
75+
}
76+
77+
/// Gets a palette color from a theme object.
78+
/// @param {Map} $theme The theme
79+
/// @param {String} $palette-name The name of the palette to get the color from.
80+
/// @param {Number} $hue The hue to read from the palette.
81+
/// @return {Color} The requested palette color.
82+
@function _get-theme-palette-color($theme, $palette-name, $hue) {
83+
$err: _validate-theme-object($theme);
84+
@if $err {
85+
// TODO(mmalerba): implement for old style theme objects.
86+
@error #{'get-theme-color does not support legacy theme objects.'};
87+
}
88+
$palettes: map.get($theme, $_internals, palettes);
89+
$palette: map.get($palettes, $palette-name);
90+
@if not $palette {
91+
$supported-palettes: map.keys($palettes);
92+
@error #{'Valid palettes are: #{$supported-palettes}. Got:'} $palette-name;
93+
}
94+
$result: map.get($palette, $hue);
95+
@if not $result {
96+
$supported-hues: map.keys($palette);
97+
@error #{'Valid hues for'} $palette-name #{'are: #{$supported-hues}. Got:'} $hue;
98+
}
99+
@return $result;
100+
}
101+
27102
/// Gets the set of tokens from the given theme, limited to those affected by the requested theming
28103
/// systems.
29104
/// @param {Map} $theme The theme to get tokens from.
@@ -38,9 +113,8 @@ $_internals: _mat-theming-internals-do-not-access;
38113
}
39114
$err: validation.validate-allowed-values($systems, color, typography, density, base);
40115
@if $err {
41-
@error
42-
#{'Expected $systems to contain valid system names (color, typographt, density, or base).'}
43-
#{'Got invalid system names:'} $err;
116+
@error #{'Expected $systems to contain valid system names (color, typography, density, or'}
117+
#{'base). Got invalid system names:'} $err;
44118
}
45119
$result: ();
46120
@each $system in $systems {

src/material/core/theming/tests/theming-inspection-api.spec.ts

Lines changed: 87 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,12 @@ describe('theming inspection api', () => {
124124
it('should get theme version', () => {
125125
expect(
126126
transpile(`
127-
$theme: ${defineM2Theme()};
128-
129-
div {
130-
content: mat.private-get-theme-version($theme);
131-
}
132-
`),
133-
).toMatch('content: 0;');
127+
$theme: ${defineM2Theme()};
128+
div {
129+
content: mat.private-get-theme-version($theme);
130+
}
131+
`),
132+
).toMatch(/content: 0;/);
134133
});
135134
});
136135

@@ -139,12 +138,88 @@ describe('theming inspection api', () => {
139138
expect(
140139
transpile(`
141140
$theme: ${defineM3Theme()};
141+
div {
142+
content: mat.private-get-theme-version($theme);
143+
}
144+
`),
145+
).toMatch(/content: 1;/);
146+
});
147+
148+
it('should get theme type', () => {
149+
expect(
150+
transpile(`
151+
$theme: ${defineM3Theme()};
152+
div {
153+
content: mat.private-get-theme-type($theme);
154+
}
155+
`),
156+
).toMatch(/content: light;/);
157+
});
158+
159+
it('should get role color', () => {
160+
expect(
161+
transpile(`
162+
$theme: ${defineM3Theme()};
163+
div {
164+
content: mat.private-get-theme-color($theme, primary-container);
165+
}
166+
`),
167+
).toMatch(/content: #e0e0ff;/);
168+
});
169+
170+
it('should error on invalid color role', () => {
171+
expect(() =>
172+
transpile(`
173+
$theme: ${defineM3Theme()};
174+
div {
175+
content: mat.private-get-theme-color($theme, fake-role);
176+
}
177+
`),
178+
).toThrowError(/Valid color roles are.*Got: fake-role/);
179+
});
180+
181+
it('should get palette color', () => {
182+
expect(
183+
transpile(`
184+
$theme: ${defineM3Theme()};
185+
div {
186+
content: mat.private-get-theme-color($theme, tertiary, 20);
187+
}
188+
`),
189+
).toMatch(/content: #323200;/);
190+
});
191+
192+
it('should error on invalid color palette', () => {
193+
expect(() =>
194+
transpile(`
195+
$theme: ${defineM3Theme()};
196+
div {
197+
content: mat.private-get-theme-color($theme, fake-palette, 20);
198+
}
199+
`),
200+
).toThrowError(/Valid palettes are.*Got: fake-palette/);
201+
});
202+
203+
it('should error on invalid color hue', () => {
204+
expect(() =>
205+
transpile(`
206+
$theme: ${defineM3Theme()};
207+
div {
208+
content: mat.private-get-theme-color($theme, neutral, 11);
209+
}
210+
`),
211+
).toThrowError(/Valid hues for neutral are.*Got: 11/);
212+
});
142213

143-
div {
144-
content: mat.private-get-theme-version($theme);
145-
}
146-
`),
147-
).toMatch('content: 1;');
214+
it('should error on wrong number of get-color-theme args', () => {
215+
expect(() =>
216+
transpile(`
217+
$theme: ${defineM3Theme()};
218+
div {
219+
content: mat.private-get-theme-color($theme);
220+
}
221+
`),
222+
).toThrowError(/Expected 2 or 3 arguments. Got: 1/);
148223
});
149224
});
150225
});

0 commit comments

Comments
 (0)