sass-references/angular-material/material/core/theming/tests/test-theming-api.scss

287 lines
14 KiB
SCSS

@use 'sass:map';
@use '../../density/private/all-density';
@use '../../color/all-color';
@use '../../typography/all-typography';
@use '../all-theme';
@use '../../typography/typography';
@use '../theming';
@use '../../m2/typography' as m2-typography;
@use '../../m2/palette' as m2-palette;
@use '../../m2/theming' as m2-theming;
// Disable theme style duplication warnings. This test intentionally generates
// the same themes multiple times.
theming.$theme-ignore-duplication-warnings: true;
// A new way to configure themes has been introduced. This Sass file ensures that the theming
// API is backwards compatible, so that the old pattern for configuring themes can be still
// used. The Sass compilation of this file will fail if one of the tests/assertions fails.
$primary: m2-theming.define-palette(m2-palette.$blue-palette);
$accent: m2-theming.define-palette(m2-palette.$grey-palette);
$warn: m2-theming.define-palette(m2-palette.$indigo-palette);
$default-warn: m2-theming.define-palette(m2-palette.$red-palette);
// Asserts that a given value matches the expected value. If not, an error is
// thrown with the given error message.
@mixin assert($value, $expected, $error-msg) {
@if $value != $expected {
@error 'Expected "#{$value}" to be "#{$expected}". #{$error-msg}';
}
}
// Asserts that the specified color configuration is configured properly.
@mixin assert-color-config($config, $primary, $accent, $warn, $is-dark) {
$color: map.get($config, color);
@include assert(map.get($color, primary), $primary,
'Primary palette does not match expected palette.');
@include assert(map.get($color, accent), $accent,
'Accent palette does not match expected palette.');
@include assert(map.get($color, warn), $warn,
'Warn palette does not match expected palette.');
@include assert(map.get($color, is-dark), $is-dark,
'Expected color config `is-dark` to be: #{$is-dark}');
}
$legacy-light-theme: m2-theming.define-light-theme($primary, $accent, $warn);
$legacy-dark-theme: m2-theming.define-dark-theme($primary, $accent, $warn);
$legacy-light-theme-default-warn: m2-theming.define-light-theme($primary, $accent);
$legacy-dark-theme-default-warn: m2-theming.define-dark-theme($primary, $accent);
$new-api-light-theme: m2-theming.define-light-theme((
color: (primary: $primary, accent: $accent, warn: $warn)
));
$new-api-dark-theme: m2-theming.define-dark-theme((
color: (primary: $primary, accent: $accent, warn: $warn)
));
$new-api-light-theme-default-warn: m2-theming.define-light-theme((
color: (primary: $primary, accent: $accent)
));
$new-api-dark-theme-default-warn: m2-theming.define-dark-theme((
color: (primary: $primary, accent: $accent)
));
$light-theme-only-density: m2-theming.define-light-theme((density: -2));
$dark-theme-only-density: m2-theming.define-dark-theme((density: -2));
$typography-config: m2-typography.define-typography-config();
$light-theme-only-typography: m2-theming.define-light-theme((typography: $typography-config));
$dark-theme-only-typography: m2-theming.define-dark-theme((typography: $typography-config));
// Test which ensures that constructed themes by default do not set configurations
// for the individual parts of the theming system (color, density, typography).
@mixin test-default-theming-system-configs() {
$themes: ($legacy-light-theme, $legacy-dark-theme, $new-api-light-theme, $new-api-dark-theme);
@each $theme in $themes {
@include assert(map.has-key($theme, color), true,
'Expected color to be explicitly configured.');
@include assert(map.has-key($theme, typography), false,
'Expected typography to be not explicitly configured.');
@include assert(map.has-key($theme, density), false,
'Expected density to be not explicitly configured.');
}
@include assert(map.has-key($light-theme-only-density, color), false,
'Expected color to be not explicitly configured.');
@include assert(map.has-key($dark-theme-only-density, color), false,
'Expected color to be not explicitly configured.');
}
// Test which ensures that constructed themes have the proper color configurations
// as specified in the `mat-light-theme` and `mat-dark-theme` functions.
@mixin test-create-color-config() {
@include assert-color-config($legacy-light-theme, $primary, $accent, $warn, false);
@include assert-color-config($legacy-dark-theme, $primary, $accent, $warn, true);
@include assert-color-config($legacy-light-theme-default-warn, $primary, $accent,
$default-warn, false);
@include assert-color-config($legacy-dark-theme-default-warn, $primary, $accent,
$default-warn, true);
@include assert-color-config($new-api-light-theme, $primary, $accent, $warn, false);
@include assert-color-config($new-api-dark-theme, $primary, $accent, $warn, true);
@include assert-color-config($new-api-light-theme-default-warn, $primary, $accent,
$default-warn, false);
@include assert-color-config($new-api-dark-theme-default-warn, $primary, $accent,
$default-warn, true);
}
// Test which ensures that constructed themes pass through the specified
// density and typography configurations.
@mixin test-density-typography-config-pass-through() {
@include assert(map.get($light-theme-only-density, density), -2,
'Expected density config to be included in theme.');
@include assert(map.get($dark-theme-only-density, density), -2,
'Expected density config to be included in theme.');
@include assert(map.get($light-theme-only-typography, typography), $typography-config,
'Expected typography config to be included in theme.');
@include assert(map.get($dark-theme-only-typography, typography), $typography-config,
'Expected typography config to be included in theme.');
}
// Test which ensures that color configurations can be properly read from
// theme objects passed to individual component theme mixins.
@mixin test-get-color-config() {
$color-config: map.get($legacy-light-theme, color);
$no-color-light-theme: m2-theming.define-light-theme((color: null));
$no-color-dark-theme: m2-theming.define-dark-theme((color: null));
@include assert(m2-theming.get-color-config($color-config), $color-config,
'Expected that passing a color config to a theme will work for backwards compatibility.');
// For legacy constructed themes, the color configuration is the actual `$theme` object.
// This is done for backwards compatibility because developers could modify colors directly
// by updating immediate properties on the `$theme` object.
@include assert(m2-theming.get-color-config($legacy-light-theme), $legacy-light-theme,
'Expected that the theme object is used for the color configuration.');
@include assert(m2-theming.get-color-config($new-api-dark-theme),
map.get($new-api-dark-theme, color),
'Expected that a color config can be read from a theme object.');
@include assert(m2-theming.get-color-config($light-theme-only-density), null,
'Expected that by default, no color configuration is used.');
@include assert(m2-theming.get-color-config($no-color-light-theme), null,
'Expected that no color configuration can be explicitly specified.');
@include assert(m2-theming.get-color-config($no-color-dark-theme), null,
'Expected that no color configuration can be explicitly specified.');
}
// Test which ensures that density configurations can be properly read from
// theme objects passed to individual component theme mixins.
@mixin test-get-density-config() {
$density-config: map.get($light-theme-only-density, density);
$no-density-light-theme: m2-theming.define-light-theme((density: null));
$no-density-dark-theme: m2-theming.define-dark-theme((density: null));
@include assert(m2-theming.get-density-config($light-theme-only-density), -2,
'Expected that a density config can be read from a theme object.');
@include assert(m2-theming.get-density-config($light-theme-only-typography), 0,
'Expected that by default, the density system will be configured.');
@include assert(m2-theming.get-density-config($no-density-light-theme), null,
'Expected that no density configuration can be explicitly specified.');
@include assert(m2-theming.get-density-config($no-density-dark-theme), null,
'Expected that no density configuration can be explicitly specified.');
}
// Test which ensures that typography configurations can be properly read from
// theme objects passed to individual component theme mixins.
@mixin test-get-typography-config() {
$no-typography-light-theme: m2-theming.define-light-theme((density: null));
$no-typography-dark-theme: m2-theming.define-dark-theme((density: null));
@include assert(m2-theming.get-typography-config($light-theme-only-typography),
$typography-config, 'Expected that a typography config can be read from a theme object.');
@include assert(m2-theming.get-typography-config($legacy-light-theme), null,
'Expected that by default, no typography configuration is used.');
@include assert(m2-theming.get-typography-config($no-typography-light-theme), null,
'Expected that no typography configuration can be explicitly specified.');
@include assert(m2-theming.get-typography-config($no-typography-dark-theme), null,
'Expected that no typography configuration can be explicitly specified.');
}
// Test which ensures that all Angular Material theme mixins accept a theme
// object without throwing any exception.
@mixin test-theme-mixins-successful-compilation() {
@include all-theme.all-component-themes($legacy-light-theme);
@include all-theme.all-component-themes($legacy-light-theme-default-warn);
@include all-theme.all-component-themes($legacy-dark-theme);
@include all-theme.all-component-themes($legacy-dark-theme-default-warn);
@include all-theme.all-component-themes($new-api-light-theme);
@include all-theme.all-component-themes($new-api-light-theme-default-warn);
@include all-theme.all-component-themes($new-api-dark-theme);
@include all-theme.all-component-themes($new-api-dark-theme-default-warn);
@include all-theme.all-component-themes($light-theme-only-density);
@include all-theme.all-component-themes($dark-theme-only-density);
@include all-theme.all-component-themes($light-theme-only-typography);
@include all-theme.all-component-themes($dark-theme-only-typography);
}
// Custom theme mixin used by the custom theme backwards compatibility test.
// This replicates a custom theme that expects legacy theme objects.
@mixin _my-custom-theme-legacy($theme) {
.demo-custom-comp {
border-color: m2-theming.get-color-from-palette(map.get($theme, primary));
}
}
@mixin _my-custom-theme-new-api-color($config-or-theme) {
$config: m2-theming.get-color-config($config-or-theme);
.demo-custom-comp {
border-color: m2-theming.get-color-from-palette(map.get($config, primary));
}
}
@mixin _my-custom-theme-new-api-density($config-or-theme) {
$density-scale: m2-theming.get-density-config($config-or-theme);
.demo-custom-comp {
// Simulates logic for computing density according to the Material Design
// specification.
height: 48 - (4px * $density-scale);
}
}
// Custom theme mixin used by the custom theme backwards compatibility test.
@mixin _my-custom-theme-new-api($theme-or-color-config) {
$theme: theming.private-legacy-get-theme($theme-or-color-config);
$color: m2-theming.get-color-config($theme);
$density: m2-theming.get-density-config($theme);
@if $color != null {
@include _my-custom-theme-new-api-color($color);
}
@if $density != null {
@include _my-custom-theme-new-api-density($density);
}
}
@mixin test-custom-theme-backwards-compatibility() {
@include _my-custom-theme-legacy($legacy-light-theme);
@include _my-custom-theme-legacy($legacy-dark-theme);
@include _my-custom-theme-legacy($new-api-light-theme);
@include _my-custom-theme-legacy($new-api-dark-theme);
@include _my-custom-theme-new-api($legacy-light-theme);
@include _my-custom-theme-new-api($legacy-dark-theme);
@include _my-custom-theme-new-api($new-api-light-theme);
@include _my-custom-theme-new-api($new-api-dark-theme);
}
// Test which ensures that either theme objects, or individual system configurations
// can be passed to the all-density, all-typography or all-color mixins.
@mixin test-all-theme-mixins-arguments() {
$test-themes: (
$legacy-light-theme,
$legacy-dark-theme,
$new-api-light-theme,
$new-api-dark-theme
);
@each $theme in $test-themes {
@include all-typography.all-component-typographies($theme);
@include all-color.all-component-colors($theme);
@include all-density.all-component-densities($theme);
}
@include all-typography.all-component-typographies(
map.get($light-theme-only-typography, typography));
@include all-typography.all-component-typographies($light-theme-only-typography);
@include all-density.all-component-densities(map.get($light-theme-only-density, density));
@include all-density.all-component-densities($light-theme-only-density);
}
@mixin test-individual-system-mixins-unwrap() {
@include _my-custom-theme-new-api-color($new-api-dark-theme);
@include _my-custom-theme-new-api-color(map.get($new-api-dark-theme, color));
@include _my-custom-theme-new-api($new-api-dark-theme);
@include _my-custom-theme-new-api(map.get($new-api-dark-theme, color));
@include all-theme.all-component-themes($new-api-dark-theme);
@include all-theme.all-component-themes(map.get($new-api-dark-theme, color));
}
// Include all tests. Sass will throw if one of the tests fails.
@include test-create-color-config();
@include test-default-theming-system-configs();
@include test-density-typography-config-pass-through();
@include test-theme-mixins-successful-compilation();
@include test-get-color-config();
@include test-get-density-config();
@include test-get-typography-config();
@include test-custom-theme-backwards-compatibility();
@include test-all-theme-mixins-arguments();
@include test-individual-system-mixins-unwrap();