Skip to content

Commit

Permalink
feat(material/theming): add support for M2 themes to theme inspection…
Browse files Browse the repository at this point in the history
… API
  • Loading branch information
mmalerba committed Aug 24, 2023
1 parent 291b9db commit 685b585
Show file tree
Hide file tree
Showing 3 changed files with 336 additions and 62 deletions.
150 changes: 88 additions & 62 deletions src/material/core/theming/_inspection.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// This file contains functions used to inspect Angular Material theme objects.

@use 'sass:list';
@use 'sass:map';
@use '../style/validation';
@use './m2-inspection';

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

Expand Down Expand Up @@ -48,15 +47,19 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac
/// @param {Map} $theme The theme
/// @return {String} The type of theme (either `light` or `dark`).
@function get-theme-type($theme) {
$err: _validate-theme-object($theme);
@if $err {
// TODO(mmalerba): implement for old style theme objects.
@error #{'get-theme-type does not support legacy theme objects.'};
$version: get-theme-version($theme);
@if $version == 0 {
@return m2-inspection.get-theme-type($theme);
}
@if not theme-has($theme, color) {
@error 'Color information is not available on this theme.';
@else if $version == 1 {
@if not theme-has($theme, color) {
@error 'Color information is not available on this theme.';
}
@return map.get($theme, $_internals, theme-type) or light;
}
@else {
@error #{'Unrecognized theme version:'} $version;
}
@return map.get($theme, $_internals, theme-type) or light;
}

/// Gets a color from a theme object. This function can take 2 or 3 arguments. If 2 arguments are
Expand All @@ -70,14 +73,26 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac
/// interpreted as a palette name).
/// @return {Color} The requested theme color.
@function get-theme-color($theme, $args...) {
$version: get-theme-version($theme);
$args-count: list.length($args);
@if $args-count == 1 {
@return _get-theme-role-color($theme, $args...);
@if $args-count != 1 and $args-count != 2 {
@error #{'Expected 2 or 3 arguments. Got:'} $args-count + 1;
}
@else if $args-count == 2 {
@return _get-theme-palette-color($theme, $args...);

@if $version == 0 {
@return m2-inspection.get-theme-color($theme, $args...);
}
@else if $version == 1 {
@if $args-count == 1 {
@return _get-theme-role-color($theme, $args...);
}
@else if $args-count == 2 {
@return _get-theme-palette-color($theme, $args...);
}
}
@else {
@error #{'Unrecognized theme version:'} $version;
}
@error #{'Expected 2 or 3 arguments. Got:'} $args-count + 1;
}

/// Gets a role color from a theme object.
Expand Down Expand Up @@ -136,72 +151,83 @@ $_typography-properties: (font, font-family, line-height, font-size, letter-spac
/// (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 theme-has($theme, typography) {
@error 'Typography information is not available on this theme.';
}
@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);
$version: get-theme-version($theme);
@if $version == 0 {
@return m2-inspection.get-theme-typography($theme, $typescale, $property);
}
@else if $version == 1 {
@if not theme-has($theme, typography) {
@error 'Typography information is not available on this theme.';
}
@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);
}
@else {
@error #{'Unrecognized theme version:'} $version;
}
}

/// Gets the density scale from a theme object.
/// @param {Map} $theme The theme
/// @return {Number} The density scale.
@function get-theme-density($theme) {
$err: _validate-theme-object($theme);
@if $err {
// TODO(mmalerba): implement for old style theme objects.
@error #{'get-theme-density does not support legacy theme objects.'};
$version: get-theme-version($theme);
@if $version == 0 {
@return m2-inspection.get-theme-density($theme);
}
@else if $version == 1 {
@if not theme-has($theme, density) {
@error 'Density information is not available on this theme.';
}
@return map.get($theme, $_internals, density-scale);
}
@if not theme-has($theme, density) {
@error 'Density information is not available on this theme.';
@else {
@error #{'Unrecognized theme version:'} $version;
}
@return map.get($theme, $_internals, density-scale);
}

/// Checks whether the theme has information about given theming system.
/// @param {Map} $theme The theme
/// @param {String} $system The system to check
/// @param {Boolean} Whether the theme has information about the system.
@function theme-has($theme, $system) {
$err: _validate-theme-object($theme);
@if $err {
// TODO(mmalerba): implement for old style theme objects.
@error #{'get-theme-density does not support legacy theme objects.'};
}
@if $system == base {
@return map.get($theme, $_internals, base-tokens) != null;
}
@if $system == color {
@return map.get($theme, $_internals, color-tokens) != null and
$version: get-theme-version($theme);
@if $version == 0 {
@return m2-inspection.theme-has($theme, $system);
}
@else if $version == 1 {
@if $system == base {
@return map.get($theme, $_internals, base-tokens) != null;
}
@if $system == color {
@return map.get($theme, $_internals, color-tokens) != null and
map.get($theme, $_internals, theme-type) != null and
map.get($theme, $_internals, palettes) != null;
}
@if $system == typography {
@return map.get($theme, $_internals, typography-tokens) != null;
}
@if $system == density {
@return map.get($theme, $_internals, density-scale) != null;
}
@error 'Valid systems are: base, color, typography, density. Got:' $system; }
@else {
@error #{'Unrecognized theme version:'} $version;
}
@if $system == typography {
@return map.get($theme, $_internals, typography-tokens) != null;
}
@if $system == density {
@return map.get($theme, $_internals, density-scale) != null;
}
@error 'Valid systems are: base, color, typography, density. Got:' $system;
}

/// Gets the set of tokens from the given theme, limited to those affected by the requested theming
Expand Down
104 changes: 104 additions & 0 deletions src/material/core/theming/_m2-inspection.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
@use 'sass:list';
@use 'sass:map';
@use './theming';
@use '../typography/typography-utils';

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

/// Gets the type of theme represented by a theme object (light or dark).
/// @param {Map} $theme The theme
/// @return {String} The type of theme (either `light` or `dark`).
@function get-theme-type($theme) {
@if not theme-has($theme, color) {
@error 'Color information is not available on this theme.';
}
$colors: theming.get-color-config($theme);
@return if(map.get($colors, is-dark), dark, light);
}

/// Gets a color from a theme object. This function can take 2 or 3 arguments. If 2 arguments are
/// passed, the second argument is treated as the name of a color role. If 3 arguments are passed,
/// the second argument is treated as the name of a color palette (primary, secondary, etc.) and the
/// third is treated as the palette hue (10, 50, etc.)
/// @param {Map} $theme The theme
/// @param {String} $palette-name The name of a color palette.
/// @param {Number} $hue The palette hue to get (passing this argument means the second argument is
/// interpreted as a palette name).
/// @return {Color} The requested theme color.
@function get-theme-color($theme, $palette-name, $args...) {
@if not theme-has($theme, color) {
@error 'Color information is not available on this theme.';
}
$colors: theming.get-color-config($theme);
$palette: map.get($colors, $palette-name);
@if not $palette {
@error 'Unrecognized palette name:' $palette-name;
}
@return theming.get-color-from-palette($palette, $args...);
}

/// 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) {
@if not theme-has($theme, typography) {
@error 'Typography information is not available on this theme.';
}
$typography: theming.get-typography-config($theme);
@if $property == font {
$font-weight: typography-utils.font-weight($typography, $typescale);
$font-size: typography-utils.font-size($typography, $typescale);
$line-height: typography-utils.line-height($typography, $typescale);
$font-family: typography-utils.font-family($typography, $typescale);
@return ($font-weight list.slash($font-size, $line-height) $font-family);
}
@else if $property == font-family {
@return typography-utils.font-family($typography, $typescale);
}
@else if $property == font-size {
@return typography-utils.font-size($typography, $typescale);
}
@else if $property == font-weight {
@return typography-utils.font-weight($typography, $typescale);
}
@else if $property == line-height {
@return typography-utils.line-height($typography, $typescale);
}
@else if $property == letter-spacing {
@return typography-utils.letter-spacing($typography, $typescale);
}
@else {
@error #{'Valid typography properties are: #{$_typography-properties}. Got:'} $property;
}
}

/// Gets the density scale from a theme object.
/// @param {Map} $theme The theme
/// @return {Number} The density scale.
@function get-theme-density($theme) {
@if not theme-has($theme, density) {
@error 'Density information is not available on this theme.';
}
$scale: theming.get-density-config($theme);
@return theming.clamp-density($scale, -5);
}

@function theme-has($theme, $system) {
$theme: theming.private-legacy-get-theme($theme);
@if $system == base {
@return true;
}
@if $system == color {
@return theming.get-color-config($theme) != null;
}
@if $system == typography {
@return theming.get-typography-config($theme) != null;
}
@if $system == density {
@return theming.get-density-config($theme, $default: null) != null;
}
@error 'Valid systems are: base, color, typography, density. Got:' $system;
}
Loading

0 comments on commit 685b585

Please sign in to comment.