Skip to content

Commit f52e979

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

File tree

3 files changed

+107
-15
lines changed

3 files changed

+107
-15
lines changed

src/material/_index.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,4 @@ list-density, list-base;
145145

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

src/material/core/theming/_inspection.scss

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@
66

77
$_internals: _mat-theming-internals-do-not-access;
88

9+
$_m3-typescales: (
10+
display-large,
11+
display-medium,
12+
display-small,
13+
headline-large,
14+
headline-medium,
15+
headline-small,
16+
title-large,
17+
title-medium,
18+
title-small,
19+
label-large,
20+
label-medium,
21+
label-small,
22+
body-large,
23+
body-medium,
24+
body-small,
25+
);
26+
27+
$_typography-properties: (font, font-family, line-height, font-size, letter-spacing, font-weight);
28+
929
/// Validates that the given value is a versioned theme object.
1030
/// @param {Any} $theme The theme object to validate.
1131
/// @return {Boolean|Null} true if the theme has errors, else null.
@@ -99,6 +119,36 @@ $_internals: _mat-theming-internals-do-not-access;
99119
@return $result;
100120
}
101121

122+
/// Gets a typography value from a theme object.
123+
/// @param {Map} $theme The theme
124+
/// @param {String} $typescale The typescale name.
125+
/// @param {String} $property The CSS font property to get
126+
/// (font, font-family, font-size, font-weight, line-height, or letter-spacing).
127+
/// @return {*} The value of the requested font property.
128+
@function get-theme-typography($theme, $typescale, $property: font) {
129+
$err: _validate-theme-object($theme);
130+
@if $err {
131+
// TODO(mmalerba): implement for old style theme objects.
132+
@error #{'get-theme-typography does not support legacy theme objects.'};
133+
}
134+
@if not list.index($_m3-typescales, $typescale) {
135+
@error #{'Valid typescales are: #{$_m3-typescales}. Got:'} $typescale;
136+
}
137+
@if not list.index($_typography-properties, $property) {
138+
@error #{'Valid typography properties are: #{$_typography-properties}. Got:'} $property;
139+
}
140+
$property-key: map.get((
141+
font: '',
142+
font-family: '-font',
143+
line-height: '-line-height',
144+
font-size: '-size',
145+
letter-spacing: '-tracking',
146+
font-weight: '-weight'
147+
), $property);
148+
$token-name: '#{$typescale}#{$property-key}';
149+
@return map.get($theme, $_internals, typography-tokens, (mdc, typography), $token-name);
150+
}
151+
102152
/// Gets the set of tokens from the given theme, limited to those affected by the requested theming
103153
/// systems.
104154
/// @param {Map} $theme The theme to get tokens from.

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

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ describe('theming inspection api', () => {
126126
transpile(`
127127
$theme: ${defineM2Theme()};
128128
div {
129-
content: mat.private-get-theme-version($theme);
129+
--theme-version: #{mat.private-get-theme-version($theme)};
130130
}
131131
`),
132-
).toMatch(/content: 0;/);
132+
).toMatch('--theme-version: 0;');
133133
});
134134
});
135135

@@ -139,40 +139,40 @@ describe('theming inspection api', () => {
139139
transpile(`
140140
$theme: ${defineM3Theme()};
141141
div {
142-
content: mat.private-get-theme-version($theme);
142+
--theme-version: #{mat.private-get-theme-version($theme)};
143143
}
144144
`),
145-
).toMatch(/content: 1;/);
145+
).toMatch('--theme-version: 1;');
146146
});
147147

148148
it('should get theme type', () => {
149149
expect(
150150
transpile(`
151151
$theme: ${defineM3Theme()};
152152
div {
153-
content: mat.private-get-theme-type($theme);
153+
--theme-type: #{mat.private-get-theme-type($theme)};
154154
}
155155
`),
156-
).toMatch(/content: light;/);
156+
).toMatch('--theme-type: light;');
157157
});
158158

159159
it('should get role color', () => {
160160
expect(
161161
transpile(`
162162
$theme: ${defineM3Theme()};
163163
div {
164-
content: mat.private-get-theme-color($theme, primary-container);
164+
color: mat.private-get-theme-color($theme, primary-container);
165165
}
166166
`),
167-
).toMatch(/content: #e0e0ff;/);
167+
).toMatch('color: #e0e0ff;');
168168
});
169169

170170
it('should error on invalid color role', () => {
171171
expect(() =>
172172
transpile(`
173173
$theme: ${defineM3Theme()};
174174
div {
175-
content: mat.private-get-theme-color($theme, fake-role);
175+
color: mat.private-get-theme-color($theme, fake-role);
176176
}
177177
`),
178178
).toThrowError(/Valid color roles are.*Got: fake-role/);
@@ -183,18 +183,18 @@ describe('theming inspection api', () => {
183183
transpile(`
184184
$theme: ${defineM3Theme()};
185185
div {
186-
content: mat.private-get-theme-color($theme, tertiary, 20);
186+
color: mat.private-get-theme-color($theme, tertiary, 20);
187187
}
188188
`),
189-
).toMatch(/content: #323200;/);
189+
).toMatch('color: #323200;');
190190
});
191191

192192
it('should error on invalid color palette', () => {
193193
expect(() =>
194194
transpile(`
195195
$theme: ${defineM3Theme()};
196196
div {
197-
content: mat.private-get-theme-color($theme, fake-palette, 20);
197+
color: mat.private-get-theme-color($theme, fake-palette, 20);
198198
}
199199
`),
200200
).toThrowError(/Valid palettes are.*Got: fake-palette/);
@@ -205,7 +205,7 @@ describe('theming inspection api', () => {
205205
transpile(`
206206
$theme: ${defineM3Theme()};
207207
div {
208-
content: mat.private-get-theme-color($theme, neutral, 11);
208+
color: mat.private-get-theme-color($theme, neutral, 11);
209209
}
210210
`),
211211
).toThrowError(/Valid hues for neutral are.*Got: 11/);
@@ -216,10 +216,52 @@ describe('theming inspection api', () => {
216216
transpile(`
217217
$theme: ${defineM3Theme()};
218218
div {
219-
content: mat.private-get-theme-color($theme);
219+
color: mat.private-get-theme-color($theme);
220220
}
221221
`),
222222
).toThrowError(/Expected 2 or 3 arguments. Got: 1/);
223223
});
224+
225+
it('should get typography properties from theme', () => {
226+
const css = transpile(`
227+
$theme: ${defineM3Theme()};
228+
div {
229+
font: mat.private-get-theme-typography($theme, headline-large);
230+
font-family: mat.private-get-theme-typography($theme, headline-large, font-family);
231+
font-size: mat.private-get-theme-typography($theme, headline-large, font-size);
232+
font-weight: mat.private-get-theme-typography($theme, headline-large, font-weight);
233+
line-height: mat.private-get-theme-typography($theme, headline-large, line-height);
234+
letter-spacing: mat.private-get-theme-typography($theme, headline-large, letter-spacing);
235+
}
236+
`);
237+
expect(css).toMatch('font: 400 2rem / 2.5rem Google Sans;');
238+
expect(css).toMatch('font-family: Google Sans;');
239+
expect(css).toMatch('font-size: 2rem;');
240+
expect(css).toMatch('font-weight: 400;');
241+
expect(css).toMatch('line-height: 2.5rem;');
242+
expect(css).toMatch('letter-spacing: 0rem;');
243+
});
244+
});
245+
246+
it('should error on invalid typescale', () => {
247+
expect(() =>
248+
transpile(`
249+
$theme: ${defineM3Theme()};
250+
div {
251+
font: mat.private-get-theme-typography($theme, subtitle-large);
252+
}
253+
`),
254+
).toThrowError(/Valid typescales are:.*Got: subtitle-large/);
255+
});
256+
257+
it('should error on invalid typography property', () => {
258+
expect(() =>
259+
transpile(`
260+
$theme: ${defineM3Theme()};
261+
div {
262+
font: mat.private-get-theme-typography($theme, body-small, text-transform);
263+
}
264+
`),
265+
).toThrowError(/Valid typography properties are:.*Got: text-transform/);
224266
});
225267
});

0 commit comments

Comments
 (0)