Skip to content

Commit

Permalink
feat(material/theming): Add APIs to get typography info from theme
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba committed Aug 14, 2023
1 parent 1a85dd2 commit f52e979
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/material/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,4 @@ list-density, list-base;

// New theming APIs, currently in development:
@forward './core/theming/inspection' as private-* show private-get-theme-version,
private-get-theme-type, private-get-theme-color;
private-get-theme-type, private-get-theme-color, private-get-theme-typography;
50 changes: 50 additions & 0 deletions src/material/core/theming/_inspection.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@

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

$_m3-typescales: (
display-large,
display-medium,
display-small,
headline-large,
headline-medium,
headline-small,
title-large,
title-medium,
title-small,
label-large,
label-medium,
label-small,
body-large,
body-medium,
body-small,
);

$_typography-properties: (font, font-family, line-height, font-size, letter-spacing, font-weight);

/// Validates that the given value is a versioned theme object.
/// @param {Any} $theme The theme object to validate.
/// @return {Boolean|Null} true if the theme has errors, else null.
Expand Down Expand Up @@ -99,6 +119,36 @@ $_internals: _mat-theming-internals-do-not-access;
@return $result;
}

/// Gets a typography value from a theme object.
/// @param {Map} $theme The theme
/// @param {String} $typescale The typescale name.
/// @param {String} $property The CSS font property to get
/// (font, font-family, font-size, font-weight, line-height, or letter-spacing).
/// @return {*} The value of the requested font property.
@function get-theme-typography($theme, $typescale, $property: font) {
$err: _validate-theme-object($theme);
@if $err {
// TODO(mmalerba): implement for old style theme objects.
@error #{'get-theme-typography does not support legacy theme objects.'};
}
@if not list.index($_m3-typescales, $typescale) {
@error #{'Valid typescales are: #{$_m3-typescales}. Got:'} $typescale;
}
@if not list.index($_typography-properties, $property) {
@error #{'Valid typography properties are: #{$_typography-properties}. Got:'} $property;
}
$property-key: map.get((
font: '',
font-family: '-font',
line-height: '-line-height',
font-size: '-size',
letter-spacing: '-tracking',
font-weight: '-weight'
), $property);
$token-name: '#{$typescale}#{$property-key}';
@return map.get($theme, $_internals, typography-tokens, (mdc, typography), $token-name);
}

/// Gets the set of tokens from the given theme, limited to those affected by the requested theming
/// systems.
/// @param {Map} $theme The theme to get tokens from.
Expand Down
70 changes: 56 additions & 14 deletions src/material/core/theming/tests/theming-inspection-api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ describe('theming inspection api', () => {
transpile(`
$theme: ${defineM2Theme()};
div {
content: mat.private-get-theme-version($theme);
--theme-version: #{mat.private-get-theme-version($theme)};
}
`),
).toMatch(/content: 0;/);
).toMatch('--theme-version: 0;');
});
});

Expand All @@ -139,40 +139,40 @@ describe('theming inspection api', () => {
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-version($theme);
--theme-version: #{mat.private-get-theme-version($theme)};
}
`),
).toMatch(/content: 1;/);
).toMatch('--theme-version: 1;');
});

it('should get theme type', () => {
expect(
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-type($theme);
--theme-type: #{mat.private-get-theme-type($theme)};
}
`),
).toMatch(/content: light;/);
).toMatch('--theme-type: light;');
});

it('should get role color', () => {
expect(
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-color($theme, primary-container);
color: mat.private-get-theme-color($theme, primary-container);
}
`),
).toMatch(/content: #e0e0ff;/);
).toMatch('color: #e0e0ff;');
});

it('should error on invalid color role', () => {
expect(() =>
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-color($theme, fake-role);
color: mat.private-get-theme-color($theme, fake-role);
}
`),
).toThrowError(/Valid color roles are.*Got: fake-role/);
Expand All @@ -183,18 +183,18 @@ describe('theming inspection api', () => {
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-color($theme, tertiary, 20);
color: mat.private-get-theme-color($theme, tertiary, 20);
}
`),
).toMatch(/content: #323200;/);
).toMatch('color: #323200;');
});

it('should error on invalid color palette', () => {
expect(() =>
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-color($theme, fake-palette, 20);
color: mat.private-get-theme-color($theme, fake-palette, 20);
}
`),
).toThrowError(/Valid palettes are.*Got: fake-palette/);
Expand All @@ -205,7 +205,7 @@ describe('theming inspection api', () => {
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-color($theme, neutral, 11);
color: mat.private-get-theme-color($theme, neutral, 11);
}
`),
).toThrowError(/Valid hues for neutral are.*Got: 11/);
Expand All @@ -216,10 +216,52 @@ describe('theming inspection api', () => {
transpile(`
$theme: ${defineM3Theme()};
div {
content: mat.private-get-theme-color($theme);
color: mat.private-get-theme-color($theme);
}
`),
).toThrowError(/Expected 2 or 3 arguments. Got: 1/);
});

it('should get typography properties from theme', () => {
const css = transpile(`
$theme: ${defineM3Theme()};
div {
font: mat.private-get-theme-typography($theme, headline-large);
font-family: mat.private-get-theme-typography($theme, headline-large, font-family);
font-size: mat.private-get-theme-typography($theme, headline-large, font-size);
font-weight: mat.private-get-theme-typography($theme, headline-large, font-weight);
line-height: mat.private-get-theme-typography($theme, headline-large, line-height);
letter-spacing: mat.private-get-theme-typography($theme, headline-large, letter-spacing);
}
`);
expect(css).toMatch('font: 400 2rem / 2.5rem Google Sans;');
expect(css).toMatch('font-family: Google Sans;');
expect(css).toMatch('font-size: 2rem;');
expect(css).toMatch('font-weight: 400;');
expect(css).toMatch('line-height: 2.5rem;');
expect(css).toMatch('letter-spacing: 0rem;');
});
});

it('should error on invalid typescale', () => {
expect(() =>
transpile(`
$theme: ${defineM3Theme()};
div {
font: mat.private-get-theme-typography($theme, subtitle-large);
}
`),
).toThrowError(/Valid typescales are:.*Got: subtitle-large/);
});

it('should error on invalid typography property', () => {
expect(() =>
transpile(`
$theme: ${defineM3Theme()};
div {
font: mat.private-get-theme-typography($theme, body-small, text-transform);
}
`),
).toThrowError(/Valid typography properties are:.*Got: text-transform/);
});
});

0 comments on commit f52e979

Please sign in to comment.