diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 093e4974d285..db0983f2611a 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -131,10 +131,10 @@
# Material experimental package
/src/material-experimental/* @andrewseguin
/src/material-experimental/column-resize/** @andrewseguin
-/src/material-experimental/mdc-tooltip/** @crisbeto
/src/material-experimental/menubar/** @jelbourn
/src/material-experimental/popover-edit/** @andrewseguin
/src/material-experimental/selection/** @andrewseguin
+/src/material-experimental/theming/** @mmalerba
# CDK experimental package
/src/cdk-experimental/* @andrewseguin
diff --git a/.ng-dev/commit-message.mts b/.ng-dev/commit-message.mts
index 1e82ea3e64ac..e1b54802345d 100644
--- a/.ng-dev/commit-message.mts
+++ b/.ng-dev/commit-message.mts
@@ -40,6 +40,10 @@ export const commitMessage: CommitMessageConfig = {
'cdk/tree',
'google-maps',
'material-experimental/column-resize',
+ 'material-experimental/theming',
+ 'material-experimental/menubar',
+ 'material-experimental/popover-edit',
+ 'material-experimental/selection',
'material/button',
'material/card',
'material/checkbox',
@@ -53,12 +57,6 @@ export const commitMessage: CommitMessageConfig = {
'material/snack-bar',
'material/table',
'material/tabs',
- 'material-experimental/menubar',
- 'material-experimental/popover-edit',
- 'material-experimental/selection',
- 'material-moment-adapter',
- 'material-date-fns-adapter',
- 'material-luxon-adapter',
'material/autocomplete',
'material/legacy-autocomplete',
'material/badge',
@@ -110,6 +108,9 @@ export const commitMessage: CommitMessageConfig = {
'material/legacy-tooltip',
'material/tooltip',
'material/tree',
+ 'material-moment-adapter',
+ 'material-date-fns-adapter',
+ 'material-luxon-adapter',
'youtube-player',
],
};
diff --git a/src/dev-app/BUILD.bazel b/src/dev-app/BUILD.bazel
index 2fdc1132ba58..d6412e1750b9 100644
--- a/src/dev-app/BUILD.bazel
+++ b/src/dev-app/BUILD.bazel
@@ -137,6 +137,16 @@ sass_binary(
],
)
+sass_binary(
+ name = "theme_token_api",
+ src = "theme-token-api.scss",
+ deps = [
+ "//src/material:sass_lib",
+ "//src/material-experimental:sass_lib",
+ "//src/material/core:theming_scss_lib",
+ ],
+)
+
# Variables that are going to be inlined into the dev app index.html.
filegroup(
name = "variables",
@@ -154,6 +164,7 @@ filegroup(
"favicon.ico",
"index.html",
":theme",
+ ":theme_token_api",
":variables",
"//src/dev-app/icon:icon_demo_assets",
"@npm//:node_modules/moment/min/moment-with-locales.min.js",
diff --git a/src/dev-app/dev-app.ts b/src/dev-app/dev-app.ts
index 7d9cc94d644d..70a4cb693ad8 100644
--- a/src/dev-app/dev-app.ts
+++ b/src/dev-app/dev-app.ts
@@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {Component, ViewEncapsulation} from '@angular/core';
-import {RouterModule} from '@angular/router';
+import {Component, inject, ViewEncapsulation} from '@angular/core';
+import {ActivatedRoute, RouterModule} from '@angular/router';
import {DevAppLayout} from './dev-app/dev-app-layout';
/** Root component for the dev-app demos. */
@@ -18,4 +18,14 @@ import {DevAppLayout} from './dev-app/dev-app-layout';
standalone: true,
imports: [DevAppLayout, RouterModule],
})
-export class DevApp {}
+export class DevApp {
+ route = inject(ActivatedRoute);
+
+ constructor() {
+ this.route.queryParams.subscribe(q => {
+ (document.querySelector('#theme-styles') as any).href = q.hasOwnProperty('tokenapi')
+ ? 'theme-token-api.css'
+ : 'theme.css';
+ });
+ }
+}
diff --git a/src/dev-app/index.html b/src/dev-app/index.html
index 67ea3ff04fcc..8bb6fe02053c 100644
--- a/src/dev-app/index.html
+++ b/src/dev-app/index.html
@@ -10,7 +10,7 @@
-
+
diff --git a/src/dev-app/theme-token-api.scss b/src/dev-app/theme-token-api.scss
new file mode 100644
index 000000000000..284b1312f249
--- /dev/null
+++ b/src/dev-app/theme-token-api.scss
@@ -0,0 +1,68 @@
+@use '@angular/material' as mat;
+@use '@angular/material-experimental' as matx;
+
+dev-app {
+ &::before {
+ content: 'Using experimental theming API';
+ display: inline-block;
+ position: fixed;
+ z-index: 100;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ padding: 8px;
+ background: red;
+ color: white;
+ }
+}
+
+.demo-unicorn-dark-theme {
+ background: black;
+ color: white;
+}
+
+@include mat.core();
+
+$light-theme: mat.define-light-theme((
+ color: (
+ primary: mat.define-palette(mat.$indigo-palette),
+ accent: mat.define-palette(mat.$pink-palette),
+ ),
+ typography: mat.define-typography-config(),
+ density: 0,
+));
+
+$dark-theme: mat.define-dark-theme((
+ color: (
+ primary: mat.define-palette(mat.$blue-grey-palette),
+ accent: mat.define-palette(mat.$amber-palette, A200, A100, A400),
+ warn: mat.define-palette(mat.$deep-orange-palette),
+ ),
+ typography: mat.define-typography-config(),
+ density: 0,
+));
+
+// Set up light theme.
+
+html {
+ @include matx.theme(
+ $tokens: mat.m2-tokens-from-theme($light-theme),
+ $components: (
+ matx.card(),
+ matx.checkbox(),
+ ));
+}
+
+// Set up dark theme.
+
+.demo-unicorn-dark-theme {
+ @include matx.theme(
+ $tokens: mat.m2-tokens-from-theme($dark-theme),
+ $components: (
+ matx.checkbox((
+ (mdc, checkbox): (
+ selected-checkmark-color: red,
+ )
+ )),
+ ));
+}
diff --git a/src/material-experimental/BUILD.bazel b/src/material-experimental/BUILD.bazel
index 6dbd1275218b..187e01847642 100644
--- a/src/material-experimental/BUILD.bazel
+++ b/src/material-experimental/BUILD.bazel
@@ -19,7 +19,9 @@ ts_library(
sass_library(
name = "theming_scss_lib",
- srcs = MATERIAL_EXPERIMENTAL_SCSS_LIBS,
+ srcs = MATERIAL_EXPERIMENTAL_SCSS_LIBS + [
+ "//src/material-experimental/theming:theming_scss_lib",
+ ],
)
sass_library(
diff --git a/src/material-experimental/_index.scss b/src/material-experimental/_index.scss
index b862e70da073..fd2a45e8fc61 100644
--- a/src/material-experimental/_index.scss
+++ b/src/material-experimental/_index.scss
@@ -4,4 +4,7 @@
@forward './popover-edit/popover-edit-theme' as popover-edit-* show popover-edit-color,
popover-edit-typography, popover-edit-density, popover-edit-theme;
+// Token-based theming API
+@forward './theming/theming' show theme, card, checkbox;
+
// Additional public APIs for individual components
diff --git a/src/material-experimental/theming/BUILD.bazel b/src/material-experimental/theming/BUILD.bazel
new file mode 100644
index 000000000000..dd86907ef7c4
--- /dev/null
+++ b/src/material-experimental/theming/BUILD.bazel
@@ -0,0 +1,9 @@
+load("//tools:defaults.bzl", "sass_library")
+
+package(default_visibility = ["//visibility:public"])
+
+sass_library(
+ name = "theming_scss_lib",
+ srcs = glob(["**/_*.scss"]),
+ deps = ["//src/material:sass_lib"],
+)
diff --git a/src/material-experimental/theming/_theming.scss b/src/material-experimental/theming/_theming.scss
new file mode 100644
index 000000000000..9a6b181d8a8a
--- /dev/null
+++ b/src/material-experimental/theming/_theming.scss
@@ -0,0 +1,134 @@
+@use 'sass:list';
+@use 'sass:map';
+@use 'sass:meta';
+@use '@angular/material' as mat;
+
+/// Whether to throw an error when a required dep is not configured. If false, the dep will be
+/// automatically configured instead.
+$_error-on-missing-dep: false;
+
+/// Applies the theme for the given component configuration.
+/// @param {Map} $tokens A map containing the default values to use for tokens not explicitly
+/// customized in the component config object.
+/// @param {List} $component The component config object to emit theme tokens for.
+/// @output CSS variables representing the theme tokens for this component.
+@mixin _apply-theme($tokens, $component) {
+ $id: map.get($component, id);
+ $tokens: map.deep-merge($tokens, map.get($component, customizations));
+
+ // NOTE: for now we use a hardcoded if-chain, but in the future when first-class mixins are
+ // supported, the configuration data will contain a reference to its own theme mixin.
+ @if $id == 'mat.card' {
+ @include mat.private-apply-card-theme-from-tokens($tokens);
+ }
+ @else if $id == 'mat.checkbox' {
+ @include mat.private-apply-checkbox-theme-from-tokens($tokens);
+ }
+ @else {
+ @error 'Unrecognized component theme: #{id}';
+ }
+}
+
+/// Gets the transitive closure of the given list of component configuration dependencies.
+/// @param {List} $components The list of component config objects to get the transitive deps for.
+/// @param {Map} $configured [()] A map of already configured component IDs. Used for recursion,
+/// should not be passed when calling.
+/// @return {List} The transitive closure of configs for the given $components.
+// TODO(mmalerba): Currently we use the deps to determine if additional tokens, other than the
+// explicitly requested ones need to be emitted, but the deps do not affect the ordering in which
+// the various configs are processed. Before moving out of experimental we should think more about
+// the ordering behavior we want. For the most part the order shouldn't matter, unless we have 2
+// configs trying to set the same token.
+@function _get-transitive-deps($components, $configured: ()) {
+ // Mark the given components as configured.
+ @each $component in $components {
+ $configured: map.set($configured, map.get($component, id), true);
+ }
+ $new-deps: ();
+
+ // Check each of the given components for new deps.
+ @each $component in $components {
+ // Note: Deps are specified as getter functions that return a config object rather than a direct
+ // config object. This allows us to only call the getter if the dep has not yet been configured.
+ // This can be useful if we have 2 components that want to require each other to be configured.
+ // Example: form-field and input. If we used direct config objects in this case, it would cause
+ // infinite co-recursion.
+ @each $dep-getter in mat.private-coerce-to-list(map.get($component, deps)) {
+ $dep: meta.call($dep-getter);
+ $dep-id: map.get($dep, id);
+ @if not (map.has-key($configured, $dep-id)) {
+ @if $_error-on-missing-dep {
+ @error 'Missing theme: `#{map.get($component, id)}` depends on `#{$dep-id}`.' +
+ ' Please configure the theme for `#{$dep-id}` in your call to `mat.theme`';
+ }
+ @else {
+ $configured: map.set($configured, $dep-id, true);
+ $new-deps: list.append($new-deps, $dep);
+ }
+ }
+ }
+ }
+
+ // Append on the new deps to this list of component configurations and return.
+ @if list.length($new-deps) > 0 {
+ $components: list.join($components, _get-transitive-deps($new-deps, $configured));
+ }
+ @return $components;
+}
+
+/// Apply the themes for the given component configs with the given ste of fallback token values.
+/// @param {Map} $tokens A map of fallback values to use for tokens that are not explicitly
+/// customized by one of the component configs.
+/// @param {List} $components The list of component configurations to emit tokens for.
+/// @output CSS variables representing the theme tokens for the given component configs.
+@mixin _theme($tokens, $components) {
+ // Call the theme mixin for each configured component.
+ @each $component in $components {
+ @include _apply-theme($tokens, $component);
+ }
+}
+
+/// Takes the full list of tokens and a list of components to configure, and outputs all theme
+/// tokens for the configured components.
+/// @param {Map} $tokens A map of all tokens for the current design system.
+/// @param {List} $components The list of component configurations to emit tokens for.
+/// @output CSS variables representing the theme tokens for the given component configs.
+// TODO(mmalerba): Consider an alternate API where `$tokens` is not a separate argument,
+// but one of the configs in the `$components` list
+@mixin theme($tokens, $components) {
+ @include _theme($tokens, _get-transitive-deps(mat.private-coerce-to-list($components)));
+}
+
+/// Takes a list of components to configure, and outputs only the theme tokens that are explicitly
+/// customized by the configurations.
+/// @param {List} $components The list of component configurations to emit tokens for.
+/// @output CSS variables representing the theme tokens for the given component configs.
+// TODO(mmalerba): What should we call this?
+// - update-theme
+// - adjust-theme
+// - edit-theme
+// - override-theme
+// - retheme
+@mixin retheme($components) {
+ @include _theme((), $components);
+}
+
+/// Configure the mat-card's theme.
+/// @param {Map} $customizations [()] A map of custom token values to use when theming mat-card.
+@function card($customizations: ()) {
+ @return (
+ id: 'mat.card',
+ customizations: $customizations,
+ deps: (),
+ );
+}
+
+/// Configure the mat-checkbox's theme.
+/// @param {Map} $customizations [()] A map of custom token values to use when theming mat-checkbox.
+@function checkbox($customizations: ()) {
+ @return (
+ id: 'mat.checkbox',
+ customizations: $customizations,
+ deps: (),
+ );
+}
diff --git a/src/material/BUILD.bazel b/src/material/BUILD.bazel
index 26c33fa6d079..f91607ee8367 100644
--- a/src/material/BUILD.bazel
+++ b/src/material/BUILD.bazel
@@ -24,6 +24,7 @@ sass_library(
srcs = [
"_index.scss",
"_theming.scss",
+ "_token-theming.scss",
],
deps = [
"//src/material/core:core_scss_lib",
diff --git a/src/material/_index.scss b/src/material/_index.scss
index 2634a22cc791..53d2b2f165ff 100644
--- a/src/material/_index.scss
+++ b/src/material/_index.scss
@@ -14,6 +14,7 @@
legacy-typography-hierarchy;
@forward './core/typography/typography-utils' show typography-level,
font-size, line-height, font-weight, letter-spacing, font-family, font-shorthand;
+@forward './core/tokens/m2' show m2-tokens-from-theme;
// Private/Internal
@forward './core/density/private/all-density' show all-component-densities;
@@ -37,6 +38,8 @@
@forward './core/style/button-common' as private-button-common-*;
// The form field density mixin needs to be exposed, because the paginator depends on it.
@forward './form-field/form-field-theme' as private-form-field-* show private-form-field-density;
+@forward './token-theming' as private-apply-*;
+@forward './core/style/sass-utils' as private-*;
// Structural
@forward './core/core' show core;
diff --git a/src/material/_token-theming.scss b/src/material/_token-theming.scss
new file mode 100644
index 000000000000..0783e8e5bb06
--- /dev/null
+++ b/src/material/_token-theming.scss
@@ -0,0 +1,2 @@
+@forward './card/card-theme' as card-* show card-theme-from-tokens;
+@forward './checkbox/checkbox-theme' as checkbox-* show checkbox-theme-from-tokens;
diff --git a/src/material/button/_icon-button-theme.scss b/src/material/button/_icon-button-theme.scss
index 8a6e1c41fc3b..9123fff0533f 100644
--- a/src/material/button/_icon-button-theme.scss
+++ b/src/material/button/_icon-button-theme.scss
@@ -1,7 +1,6 @@
@use 'sass:map';
@use 'sass:math';
@use '@material/density/functions' as mdc-density-functions;
-@use '@material/icon-button/mixins' as mdc-icon-button;
@use '@material/icon-button/icon-button-theme' as mdc-icon-button-theme;
@use '@material/theme/theme-color' as mdc-theme-color;
@use '../core/tokens/m2/mdc/icon-button' as tokens-mdc-icon-button;
diff --git a/src/material/card/_card-theme.import.scss b/src/material/card/_card-theme.import.scss
index f9431af5f9e7..367a7bcad08b 100644
--- a/src/material/card/_card-theme.import.scss
+++ b/src/material/card/_card-theme.import.scss
@@ -1,3 +1,3 @@
-@forward 'card-theme' hide color, density, theme, typography;
+@forward 'card-theme' hide color, density, theme, typography, theme-from-tokens;
@forward 'card-theme' as mat-mdc-card-* hide $mat-mdc-card-mdc-card-action-icon-color,
$mat-mdc-card-mdc-card-outline-color;
diff --git a/src/material/card/_card-theme.scss b/src/material/card/_card-theme.scss
index 4d54b95b74f3..2f3eb3cbb71a 100644
--- a/src/material/card/_card-theme.scss
+++ b/src/material/card/_card-theme.scss
@@ -1,3 +1,4 @@
+@use 'sass:map';
@use '../core/theming/theming';
@use '../core/typography/typography';
@use '../core/tokens/token-utils';
@@ -76,3 +77,13 @@
}
}
}
+
+@mixin theme-from-tokens($tokens) {
+ // Add values for card tokens.
+ .mat-mdc-card {
+ @include mdc-elevated-card-theme.theme(map.get($tokens, tokens-mdc-elevated-card.$prefix));
+ @include mdc-outlined-card-theme.theme(map.get($tokens, tokens-mdc-outlined-card.$prefix));
+ @include token-utils.create-token-values(
+ tokens-mat-card.$prefix, map.get($tokens, tokens-mat-card.$prefix));
+ }
+}
diff --git a/src/material/checkbox/_checkbox-theme.import.scss b/src/material/checkbox/_checkbox-theme.import.scss
index 4b578d213a5e..aea7a1d373fb 100644
--- a/src/material/checkbox/_checkbox-theme.import.scss
+++ b/src/material/checkbox/_checkbox-theme.import.scss
@@ -1,5 +1,5 @@
@forward 'checkbox-theme' hide color, density, private-checkbox-styles-with-color, theme,
-typography;
+typography, theme-from-tokens;
@forward 'checkbox-theme' as mat-mdc-* hide $mat-mdc-mdc-checkbox-border-color,
$mat-mdc-mdc-checkbox-disabled-color, mat-mdc-background-focus-density,
mat-mdc-background-focus-indicator-checked-color, mat-mdc-background-focus-indicator-color,
diff --git a/src/material/checkbox/_checkbox-theme.scss b/src/material/checkbox/_checkbox-theme.scss
index ed076353f62c..b46761feeac5 100644
--- a/src/material/checkbox/_checkbox-theme.scss
+++ b/src/material/checkbox/_checkbox-theme.scss
@@ -88,3 +88,12 @@
}
}
}
+
+@mixin theme-from-tokens($tokens) {
+ // TODO(mmalerba): Some of the theme styles above are not represented in terms of tokens,
+ // so this mixin is currently incomplete.
+
+ .mat-mdc-checkbox {
+ @include mdc-checkbox-theme.theme(map.get($tokens, tokens-mdc-checkbox.$prefix));
+ }
+}
diff --git a/src/material/core/style/_sass-utils.scss b/src/material/core/style/_sass-utils.scss
index 19ab313b2f42..af9fb2218cef 100644
--- a/src/material/core/style/_sass-utils.scss
+++ b/src/material/core/style/_sass-utils.scss
@@ -1,7 +1,37 @@
-// Include content under the current selector (&) or the document root if there is no current
-// selector.
+@use 'sass:map';
+@use 'sass:meta';
+
+/// Include content under the current selector (&) or the document root if there is no current
+/// selector.
+/// @param {String} $root [html] The default root selector to use when there is no current selector.
+/// @output The given content under the current selector, or root selector if there is no current
+/// selector.
+/// @content Content to output under the current selector, or root selector if there is no current
+/// selector.
@mixin current-selector-or-root($root: html) {
@at-root #{& or $root} {
@content;
}
}
+
+/// A version of the standard `map.deep-merge` function that takes a variable number of arguments.
+/// Each argument is deep-merged into the final result from left to right.
+/// @param {List} $maps The maps to combine with map.deep-merge
+/// @return {Map} The combined result of successively calling map.deep-merge with each parameter.
+@function deep-merge-all($maps...) {
+ $result: ();
+ @each $map in $maps {
+ $result: map.deep-merge($result, $map);
+ }
+ @return $result;
+}
+
+/// Coerces the given value to a list, by converting any non-list value into a single-item list.
+/// This should be used when dealing with user-passed lists of args to avoid confusing errors,
+/// since Sass treats `($x)` as equivalent to `$x`.
+/// @param {Any} $value The value to coerce to a list.
+/// @return {List} The original $value if it was a list, otherwise a single-item list containing
+/// $value.
+@function coerce-to-list($value) {
+ @return if(meta.type-of($value) != 'list', ($value,), $value);
+}
diff --git a/src/material/core/tokens/_token-utils.scss b/src/material/core/tokens/_token-utils.scss
index 03a266f7fbd2..254e0c97e09b 100644
--- a/src/material/core/tokens/_token-utils.scss
+++ b/src/material/core/tokens/_token-utils.scss
@@ -52,7 +52,7 @@ $_component-prefix: null;
$_component-prefix: '' !global;
@each $item in $rest {
$_component-prefix:
- if($_component-prefix == '', $item, '#{$_component-prefix}-#{$item}') !global;
+ if($_component-prefix == '', $item, '#{$_component-prefix}-#{$item}') !global;
}
@include mdc-custom-properties.configure($varname-prefix: $first) {
@content;
@@ -87,15 +87,6 @@ $_component-prefix: null;
}
}
-// Merges together a list of maps into a single map.
-@function merge-all($maps...) {
- $result: ();
- @each $map in $maps {
- $result: map.merge($result, $map);
- }
- @return $result;
-}
-
// MDC doesn't currently handle elevation tokens properly. As a temporary workaround we can combine
// the elevation and shadow-color tokens into a full box-shadow and use it as the value for the
// elevation token.
diff --git a/src/material/core/tokens/m2/_index.scss b/src/material/core/tokens/m2/_index.scss
new file mode 100644
index 000000000000..da279eb223b3
--- /dev/null
+++ b/src/material/core/tokens/m2/_index.scss
@@ -0,0 +1,84 @@
+@use 'sass:map';
+@use 'sass:meta';
+@use '../../style/sass-utils';
+
+@use './mat/card' as tokens-mat-card;
+@use './mat/radio' as tokens-mat-radio;
+@use './mat/snack-bar' as tokens-mat-snack-bar;
+@use './mat/tab-header' as tokens-mat-tab-header;
+@use './mat/tab-header-with-background' as tokens-mat-tab-header-with-background;
+@use './mdc/checkbox' as tokens-mdc-checkbox;
+@use './mdc/circular-progress' as tokens-mdc-circular-progress;
+@use './mdc/dialog' as tokens-mdc-dialog;
+@use './mdc/elevated-card' as tokens-mdc-elevated-card;
+@use './mdc/icon-button' as tokens-mdc-icon-button;
+@use './mdc/linear-progress' as tokens-mdc-linear-progress;
+@use './mdc/list' as tokens-mdc-list;
+@use './mdc/outlined-card' as tokens-mdc-outlined-card;
+@use './mdc/radio' as tokens-mdc-radio;
+@use './mdc/snack-bar' as tokens-mdc-snack-bar;
+@use './mdc/tab' as tokens-mdc-tab;
+@use './mdc/tab-indicator' as tokens-mdc-tab-indicator;
+
+/// Gets the tokens for the given theme, m2 tokens module, and theming system.
+/// @param {Map} $theme The Angular Material theme object to generate token values from.
+/// @param {String} $module The Sass module containing the token getter functions.
+/// @param {String} $system The theming system to get tokens for. Valid values are: unthemable,
+/// color, typography, density.
+/// @return {Map} The token map by calling the token getter for the given system in the given module
+/// with the given Angular Material theme. Token names are not fully-qualified.
+@function _get-tokens-for-module-and-system($theme, $module, $system) {
+ @if $system == unthemable {
+ @return meta.call(
+ meta.get-function(get-#{$system}-tokens, $module: $module));
+ }
+ @if not map.get($theme, $system) {
+ @return ();
+ }
+ @return meta.call(
+ meta.get-function(get-#{$system}-tokens, $module: $module), map.get($theme, $system));
+}
+
+/// Gets the fully qualified tokens map for the given theme and m2 tokens module.
+/// @param {Map} $theme The Angular Material theme object to generate token values from.
+/// @param {String} $module The Sass module containing the token getter functions.
+/// @return {Map} The token map by calling the token getters in the given module with the given
+/// Angular Material theme. Token names are fully-qualified.
+@function _get-tokens-for-module($theme, $module) {
+ $tokens: sass-utils.deep-merge-all(
+ _get-tokens-for-module-and-system($theme, $module, unthemable),
+ _get-tokens-for-module-and-system($theme, $module, color),
+ _get-tokens-for-module-and-system($theme, $module, typography),
+ _get-tokens-for-module-and-system($theme, $module, density));
+ @return map.set((), map.get(meta.module-variables($module), prefix), $tokens);
+}
+
+/// Gets the full set of M2 tokens for the given theme object.
+/// @param {Map} $theme The Angular Material theme object to generate token values from.
+/// @return {Map} The token map for the given Angular Material theme. Returned format:
+/// (
+/// (fully, qualified, namespace): (
+/// token: value
+/// )
+/// )
+@function m2-tokens-from-theme($theme) {
+ @return sass-utils.deep-merge-all(
+ _get-tokens-for-module($theme, tokens-mat-card),
+ _get-tokens-for-module($theme, tokens-mat-radio),
+ _get-tokens-for-module($theme, tokens-mat-snack-bar),
+ _get-tokens-for-module($theme, tokens-mat-tab-header),
+ _get-tokens-for-module($theme, tokens-mat-tab-header-with-background),
+ _get-tokens-for-module($theme, tokens-mdc-checkbox),
+ _get-tokens-for-module($theme, tokens-mdc-circular-progress),
+ _get-tokens-for-module($theme, tokens-mdc-dialog),
+ _get-tokens-for-module($theme, tokens-mdc-elevated-card),
+ _get-tokens-for-module($theme, tokens-mdc-icon-button),
+ _get-tokens-for-module($theme, tokens-mdc-linear-progress),
+ _get-tokens-for-module($theme, tokens-mdc-list),
+ _get-tokens-for-module($theme, tokens-mdc-outlined-card),
+ _get-tokens-for-module($theme, tokens-mdc-radio),
+ _get-tokens-for-module($theme, tokens-mdc-snack-bar),
+ _get-tokens-for-module($theme, tokens-mdc-tab),
+ _get-tokens-for-module($theme, tokens-mdc-tab-indicator),
+ );
+}
diff --git a/src/material/core/tokens/m2/mat/_card.scss b/src/material/core/tokens/m2/mat/_card.scss
index 7f19a99189a5..5b27c9f1d7c7 100644
--- a/src/material/core/tokens/m2/mat/_card.scss
+++ b/src/material/core/tokens/m2/mat/_card.scss
@@ -2,6 +2,7 @@
@use '../../token-utils';
@use '../../../theming/theming';
@use '../../../typography/typography-utils';
+@use '../../../style/sass-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
$prefix: (mat, card);
@@ -18,7 +19,7 @@ $prefix: (mat, card);
@return (
// Text color of the card's subtitle.
- subtitle-text-color: theming.get-color-from-palette($foreground, secondary-text),
+ subtitle-text-color: theming.get-color-from-palette($foreground, secondary-text),
);
}
@@ -26,27 +27,27 @@ $prefix: (mat, card);
@function get-typography-tokens($config) {
@return (
// Font family of the card's title.
- title-text-font: typography-utils.font-family($config, headline-6)
+ title-text-font: typography-utils.font-family($config, headline-6)
or typography-utils.font-family($config),
// Line height of the card's title.
- title-text-line-height: typography-utils.line-height($config, headline-6),
+ title-text-line-height: typography-utils.line-height($config, headline-6),
// Font size of the card's title.
- title-text-size: typography-utils.font-size($config, headline-6),
+ title-text-size: typography-utils.font-size($config, headline-6),
// Letter spacing of the card's title.
- title-text-tracking: typography-utils.letter-spacing($config, headline-6),
+ title-text-tracking: typography-utils.letter-spacing($config, headline-6),
// Font weight of the card's title.
- title-text-weight: typography-utils.font-weight($config, headline-6),
+ title-text-weight: typography-utils.font-weight($config, headline-6),
// Font family of the card's subtitle.
- subtitle-text-font: typography-utils.font-family($config, subtitle-2)
+ subtitle-text-font: typography-utils.font-family($config, subtitle-2)
or typography-utils.font-family($config),
// Line height of the card's subtitle.
- subtitle-text-line-height: typography-utils.line-height($config, subtitle-2),
+ subtitle-text-line-height: typography-utils.line-height($config, subtitle-2),
// Font size of the card's subtitle.
- subtitle-text-size: typography-utils.font-size($config, subtitle-2),
+ subtitle-text-size: typography-utils.font-size($config, subtitle-2),
// Letter spacing of the card's subtitle.
- subtitle-text-tracking: typography-utils.letter-spacing($config, subtitle-2),
+ subtitle-text-tracking: typography-utils.letter-spacing($config, subtitle-2),
// Font weight of the card's subtitle.
- subtitle-text-weight: typography-utils.font-weight($config, subtitle-2),
+ subtitle-text-weight: typography-utils.font-weight($config, subtitle-2),
);
}
@@ -58,10 +59,10 @@ $prefix: (mat, card);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mat/_radio.scss b/src/material/core/tokens/m2/mat/_radio.scss
index 7555c1c8b00c..eca8bd448037 100644
--- a/src/material/core/tokens/m2/mat/_radio.scss
+++ b/src/material/core/tokens/m2/mat/_radio.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../token-utils';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
$prefix: (mat, radio);
@@ -37,10 +38,10 @@ $prefix: (mat, radio);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mat/_snack-bar.scss b/src/material/core/tokens/m2/mat/_snack-bar.scss
index 10156de32f08..70f704467494 100644
--- a/src/material/core/tokens/m2/mat/_snack-bar.scss
+++ b/src/material/core/tokens/m2/mat/_snack-bar.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../token-utils';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
$prefix: (mat, snack-bar);
@@ -34,10 +35,10 @@ $prefix: (mat, snack-bar);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mat/_tab-header-with-background.scss b/src/material/core/tokens/m2/mat/_tab-header-with-background.scss
index 96db92e5cb76..d332fa7ce7c5 100644
--- a/src/material/core/tokens/m2/mat/_tab-header-with-background.scss
+++ b/src/material/core/tokens/m2/mat/_tab-header-with-background.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../token-utils';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
$prefix: (mat, tab-header-with-background);
@@ -34,10 +35,10 @@ $prefix: (mat, tab-header-with-background);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mat/_tab-header.scss b/src/material/core/tokens/m2/mat/_tab-header.scss
index 4a54c6880cc1..d81f699e7043 100644
--- a/src/material/core/tokens/m2/mat/_tab-header.scss
+++ b/src/material/core/tokens/m2/mat/_tab-header.scss
@@ -2,6 +2,7 @@
@use '../../token-utils';
@use '../../../theming/theming';
@use '../../../typography/typography-utils';
+@use '../../../style/sass-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
$prefix: (mat, tab-header);
@@ -62,7 +63,7 @@ $prefix: (mat, tab-header);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
+ @return sass-utils.deep-merge-all(
get-unthemable-tokens(),
get-color-tokens(token-utils.$placeholder-color-config),
get-typography-tokens(token-utils.$placeholder-typography-config),
diff --git a/src/material/core/tokens/m2/mdc/_checkbox.scss b/src/material/core/tokens/m2/mdc/_checkbox.scss
index 6fcde37aaaee..c0e0f9da633a 100644
--- a/src/material/core/tokens/m2/mdc/_checkbox.scss
+++ b/src/material/core/tokens/m2/mdc/_checkbox.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../../theming/palette';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
@use '@material/theme/theme-color' as mdc-theme-color;
@@ -26,25 +27,25 @@ $prefix: (mdc, checkbox);
@function get-unthemable-tokens() {
@return (
// The color of the checkmark when the checkbox is selected and disabled.
- disabled-selected-checkmark-color: #fff,
+ disabled-selected-checkmark-color: #fff,
// The opacity of the ripple when the checkbox is selected and focused.
- selected-focus-state-layer-opacity: 0.16,
+ selected-focus-state-layer-opacity: 0.16,
// The opacity of the ripple when the checkbox is selected and hovered.
- selected-hover-state-layer-opacity: 0.04,
+ selected-hover-state-layer-opacity: 0.04,
// The opacity of the ripple when the checkbox is selected and pressed.
- selected-pressed-state-layer-opacity: 0.16,
+ selected-pressed-state-layer-opacity: 0.16,
// The opacity of the ripple when the checkbox is unselected and focused.
- unselected-focus-state-layer-opacity: 0.16,
+ unselected-focus-state-layer-opacity: 0.16,
// The opacity of the ripple when the checkbox is unselected and hovered.
- unselected-hover-state-layer-opacity: 0.04,
+ unselected-hover-state-layer-opacity: 0.04,
// The opacity of the ripple when the checkbox is unselected and pressed.
- unselected-pressed-state-layer-opacity: 0.16,
+ unselected-pressed-state-layer-opacity: 0.16,
// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
// MDC currently doesn't output a slot for these tokens.
- disabled-selected-icon-opacity: null,
- disabled-unselected-icon-opacity: null,
+ disabled-selected-icon-opacity: null,
+ disabled-unselected-icon-opacity: null,
);
}
@@ -59,43 +60,43 @@ $prefix: (mdc, checkbox);
$selected-color: theming.get-color-from-palette($accent);
$border-color: theming.get-color-from-palette($foreground, base, 0.54);
$active-border-color:
- theming.get-color-from-palette(palette.$gray-palette, if($is-dark, 200, 900));
+ theming.get-color-from-palette(palette.$gray-palette, if($is-dark, 200, 900));
@return (
// The color of the checkbox fill when the checkbox is selected and disabled.
- disabled-selected-icon-color: $disabled-color,
+ disabled-selected-icon-color: $disabled-color,
// The color of the checkbox border when the checkbox is unselected and disabled.
- disabled-unselected-icon-color: $disabled-color,
+ disabled-unselected-icon-color: $disabled-color,
// The color of the checkmark when the checkbox is selected.
- selected-checkmark-color: _contrast-tone($selected-color, $is-dark),
+ selected-checkmark-color: _contrast-tone($selected-color, $is-dark),
// The color of the checkbox fill when the checkbox is selected and focused.
- selected-focus-icon-color: $selected-color,
+ selected-focus-icon-color: $selected-color,
// The color of the checkbox fill when the checkbox is selected and hovered.
- selected-hover-icon-color: $selected-color,
+ selected-hover-icon-color: $selected-color,
// The color of the checkbox fill when the checkbox is selected.
- selected-icon-color: $selected-color,
+ selected-icon-color: $selected-color,
// The color of the checkbox fill when the checkbox is selected an pressed.
- selected-pressed-icon-color: $selected-color,
+ selected-pressed-icon-color: $selected-color,
// The color of the checkbox border when the checkbox is unselected and focused.
- unselected-focus-icon-color: $active-border-color,
+ unselected-focus-icon-color: $active-border-color,
// The color of the checkbox border when the checkbox is unselected and hovered.
- unselected-hover-icon-color: $active-border-color,
+ unselected-hover-icon-color: $active-border-color,
// The color of the checkbox border when the checkbox is unselected.
- unselected-icon-color: $border-color,
+ unselected-icon-color: $border-color,
// The color of the checkbox border when the checkbox is unselected and pressed.
- unselected-pressed-icon-color: $border-color,
+ unselected-pressed-icon-color: $border-color,
// The color of the ripple when the checkbox is selected and focused.
- selected-focus-state-layer-color: $accent-default,
+ selected-focus-state-layer-color: $accent-default,
// The color of the ripple when the checkbox is selected and hovered.
- selected-hover-state-layer-color: $accent-default,
+ selected-hover-state-layer-color: $accent-default,
// The color of the ripple when the checkbox is selected and pressed.
- selected-pressed-state-layer-color: $accent-default,
+ selected-pressed-state-layer-color: $accent-default,
// The color of the ripple when the checkbox is unselected and focused.
- unselected-focus-state-layer-color: $foreground-base,
+ unselected-focus-state-layer-color: $foreground-base,
// The color of the ripple when the checkbox is unselected and hovered.
- unselected-hover-state-layer-color: $foreground-base,
+ unselected-hover-state-layer-color: $foreground-base,
// The color of the ripple when the checkbox is unselected and pressed.
- unselected-pressed-state-layer-color: $foreground-base,
+ unselected-pressed-state-layer-color: $foreground-base,
);
}
@@ -110,22 +111,22 @@ $prefix: (mdc, checkbox);
@return (
// The diameter of the checkbox's ripple.
- state-layer-size: map.get((
- 0: 40px,
- -1: 36px,
- -2: 32px,
- -3: 28px,
- ), $scale)
+ state-layer-size: map.get((
+ 0: 40px,
+ -1: 36px,
+ -2: 32px,
+ -3: 28px,
+ ), $scale)
);
}
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_chip.scss b/src/material/core/tokens/m2/mdc/_chip.scss
index e4d006d86469..db18f9fa7acd 100644
--- a/src/material/core/tokens/m2/mdc/_chip.scss
+++ b/src/material/core/tokens/m2/mdc/_chip.scss
@@ -1,7 +1,7 @@
-@use 'sass:color';
@use 'sass:map';
@use '../../token-utils';
@use '../../../mdc-helpers/mdc-helpers';
+@use '../../../style/sass-utils';
@use '../../../theming/theming';
@use '../../../typography/typography-utils';
@@ -304,7 +304,7 @@ $prefix: (mdc, chip);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
+ @return sass-utils.deep-merge-all(
get-unthemable-tokens(),
get-color-tokens(token-utils.$placeholder-color-config),
get-typography-tokens(token-utils.$placeholder-typography-config),
diff --git a/src/material/core/tokens/m2/mdc/_circular-progress.scss b/src/material/core/tokens/m2/mdc/_circular-progress.scss
index 108542b4c63e..5c8445bfeead 100644
--- a/src/material/core/tokens/m2/mdc/_circular-progress.scss
+++ b/src/material/core/tokens/m2/mdc/_circular-progress.scss
@@ -1,5 +1,6 @@
@use 'sass:map';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -52,14 +53,10 @@ $prefix: (mdc, circular-progress);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return map.merge(
- get-unthemable-tokens(),
- map.merge(
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
get-color-tokens(token-utils.$placeholder-color-config),
- map.merge(
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
- )
- )
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_dialog.scss b/src/material/core/tokens/m2/mdc/_dialog.scss
index 7dff874feef2..101e344bc8d8 100644
--- a/src/material/core/tokens/m2/mdc/_dialog.scss
+++ b/src/material/core/tokens/m2/mdc/_dialog.scss
@@ -2,6 +2,7 @@
@use '../../../theming/theming';
@use '../../../typography/typography-utils';
@use '../../../mdc-helpers/mdc-helpers';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -21,7 +22,6 @@ $prefix: (mdc, dialog);
container-shadow-color: #000,
// Border radius of the container.
container-shape: 4px,
-
// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
@@ -87,7 +87,6 @@ $prefix: (mdc, dialog);
subhead-size: typography-utils.font-size($config, headline-6),
subhead-weight: typography-utils.font-weight($config, headline-6),
subhead-tracking: typography-utils.letter-spacing($config, headline-6),
-
// Typography of the dialog body text.
supporting-text-font: typography-utils.font-family($config, body-1)
or typography-utils.font-family($config),
@@ -106,10 +105,10 @@ $prefix: (mdc, dialog);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_elevated-card.scss b/src/material/core/tokens/m2/mdc/_elevated-card.scss
index ad72d34894cc..cb70896635a0 100644
--- a/src/material/core/tokens/m2/mdc/_elevated-card.scss
+++ b/src/material/core/tokens/m2/mdc/_elevated-card.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../../style/elevation';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -74,7 +75,7 @@ $prefix: (mdc, elevated-card);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
+ @return sass-utils.deep-merge-all(
get-unthemable-tokens(),
get-color-tokens(token-utils.$placeholder-color-config),
get-typography-tokens(token-utils.$placeholder-typography-config),
diff --git a/src/material/core/tokens/m2/mdc/_icon-button.scss b/src/material/core/tokens/m2/mdc/_icon-button.scss
index d4ff0261e152..3d7c33de437c 100644
--- a/src/material/core/tokens/m2/mdc/_icon-button.scss
+++ b/src/material/core/tokens/m2/mdc/_icon-button.scss
@@ -1,4 +1,4 @@
-@use 'sass:map';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -18,18 +18,14 @@ $prefix: (mdc, icon-button);
// Determines the size of the icon. Name is inaccurate - applies to the whole component,
// not just the state layer.
state-layer-size: 48px,
-
// MDC's icon size applied to svg and img elements inside the component
icon-size: 24px,
-
// Only applies to :disabled icons, but Angular Components uses [disabled] since :disabled
// wouldn't work on tags.
disabled-icon-color: black,
-
// Angular version applies an opacity 1 with a color change, and this only applies with
// :disabled anyways.
disabled-icon-opacity: 0.38,
-
// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
@@ -66,14 +62,10 @@ $prefix: (mdc, icon-button);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return map.merge(
+ @return sass-utils.deep-merge-all(
get-unthemable-tokens(),
- map.merge(
- get-color-tokens(token-utils.$placeholder-color-config),
- map.merge(
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
- )
- )
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_linear-progress.scss b/src/material/core/tokens/m2/mdc/_linear-progress.scss
index 2d9309da4f3a..f8db382857a0 100644
--- a/src/material/core/tokens/m2/mdc/_linear-progress.scss
+++ b/src/material/core/tokens/m2/mdc/_linear-progress.scss
@@ -1,4 +1,5 @@
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
@use 'sass:color';
@use 'sass:map';
@@ -32,9 +33,9 @@ $prefix: (mdc, linear-progress);
// The color of the progress bar's active section.
active-indicator-color: $primary,
track-color: if(
- meta.type-of($primary) == color,
- color.adjust($primary, $alpha: -0.75),
- $primary
+ meta.type-of($primary) == color,
+ color.adjust($primary, $alpha: -0.75),
+ $primary
)
);
}
@@ -52,14 +53,10 @@ $prefix: (mdc, linear-progress);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return map.merge(
- get-unthemable-tokens(),
- map.merge(
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
get-color-tokens(token-utils.$placeholder-color-config),
- map.merge(
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
- )
- )
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_list.scss b/src/material/core/tokens/m2/mdc/_list.scss
index 79b2cccbad1c..f848f59d8c32 100644
--- a/src/material/core/tokens/m2/mdc/_list.scss
+++ b/src/material/core/tokens/m2/mdc/_list.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../../theming/theming';
@use '../../../typography/typography-utils';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -15,69 +16,69 @@ $prefix: (mdc, list);
@function get-unthemable-tokens() {
@return (
// Border radius of list items.
- list-item-container-shape: 0,
+ list-item-container-shape: 0,
// Border radius of the list item's leading avatar.
- list-item-leading-avatar-shape: 50%,
+ list-item-leading-avatar-shape: 50%,
// Background color of list items.
- list-item-container-color: transparent,
+ list-item-container-color: transparent,
// Background color of list items when selected.
- list-item-selected-container-color: transparent,
+ list-item-selected-container-color: transparent,
// Background color of the list item's leading avatar.
- list-item-leading-avatar-color: transparent,
+ list-item-leading-avatar-color: transparent,
// Height & width of the list item's leading icon.
- list-item-leading-icon-size: 24px,
+ list-item-leading-icon-size: 24px,
// Height & width of the list item's leading avatar.
- list-item-leading-avatar-size: 40px,
+ list-item-leading-avatar-size: 40px,
// Height & width of the list item's trailing icon.
- list-item-trailing-icon-size: 24px,
+ list-item-trailing-icon-size: 24px,
// Color of the list item's overlay when the item is disabled.
- list-item-disabled-state-layer-color: transparent,
+ list-item-disabled-state-layer-color: transparent,
// Opacity of the list item's overlay when the item is disabled.
- list-item-disabled-state-layer-opacity: 0,
+ list-item-disabled-state-layer-opacity: 0,
// Opacity of the list item's primary & supporting text when the item is disabled.
- list-item-disabled-label-text-opacity: 0.38,
+ list-item-disabled-label-text-opacity: 0.38,
// Opacity of the list item's leading icon when the item is disabled.
- list-item-disabled-leading-icon-opacity: 0.38,
+ list-item-disabled-leading-icon-opacity: 0.38,
// Opacity of the list item's trailing icon when the item is disabled.
- list-item-disabled-trailing-icon-opacity: 0.38,
+ list-item-disabled-trailing-icon-opacity: 0.38,
// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
// Overline not implemented in Angular Material.
// TODO(mmalerba): Consider implementing in the future.
- list-item-overline-color: null,
- list-item-overline-font: null,
- list-item-overline-line-height: null,
- list-item-overline-size: null,
- list-item-overline-tracking: null,
- list-item-overline-weight: null,
+ list-item-overline-color: null,
+ list-item-overline-font: null,
+ list-item-overline-line-height: null,
+ list-item-overline-size: null,
+ list-item-overline-tracking: null,
+ list-item-overline-weight: null,
// Leading video not implemented in Angular Material.
// TODO(mmalerba): Consider implementing in the future.
- list-item-leading-video-shape: null,
- list-item-leading-video-width: null,
- list-item-leading-video-height: null,
+ list-item-leading-video-shape: null,
+ list-item-leading-video-width: null,
+ list-item-leading-video-height: null,
// Leading image not implemented in Angular Material.
// TODO(mmalerba): Consider implementing in the future.
- list-item-leading-image-width: null,
- list-item-leading-image-height: null,
- list-item-leading-image-shape: null,
+ list-item-leading-image-width: null,
+ list-item-leading-image-height: null,
+ list-item-leading-image-shape: null,
// List divider is not implemented in Angular Material.
// TODO(mmalerba): Maybe mat-divider should be based on these tokens?
- divider-color: null,
- divider-height: null,
+ divider-color: null,
+ divider-height: null,
// Redundant since it is always overridden by one- two- or three- line tokens, omitted to save
// bytes.
- list-item-container-height: null,
+ list-item-container-height: null,
// MDC does not seem to emit any CSS variables for these tokens, may be use in the future.
// TODO(mmalerba): Discuss with MDC if these should be added.
- list-item-container-elevation: null,
- list-item-leading-avatar-label-color: null,
- list-item-leading-avatar-label-font: null,
- list-item-leading-avatar-label-line-height: null,
- list-item-leading-avatar-label-size: null,
- list-item-leading-avatar-label-tracking: null,
- list-item-leading-avatar-label-weight: null,
- list-item-unselected-trailing-icon-color: null,
+ list-item-container-elevation: null,
+ list-item-leading-avatar-label-color: null,
+ list-item-leading-avatar-label-font: null,
+ list-item-leading-avatar-label-line-height: null,
+ list-item-leading-avatar-label-size: null,
+ list-item-leading-avatar-label-tracking: null,
+ list-item-leading-avatar-label-weight: null,
+ list-item-unselected-trailing-icon-color: null,
);
}
@@ -87,44 +88,44 @@ $prefix: (mdc, list);
$is-dark: map.get($config, is-dark);
$foreground-base: theming.get-color-from-palette($foreground, base);
$text-icon-on-background:
- theming.get-color-from-palette($foreground, base, if($is-dark, 0.5, 0.38));
+ theming.get-color-from-palette($foreground, base, if($is-dark, 0.5, 0.38));
@return (
// Text color of the list item primary text.
- list-item-label-text-color: theming.get-color-from-palette($foreground, text),
+ list-item-label-text-color: theming.get-color-from-palette($foreground, text),
// Text color of the list item supporting text.
- list-item-supporting-text-color: theming.get-color-from-palette($foreground, secondary-text),
+ list-item-supporting-text-color: theming.get-color-from-palette($foreground, secondary-text),
// Color of the list item's leading icon.
- list-item-leading-icon-color: $text-icon-on-background,
+ list-item-leading-icon-color: $text-icon-on-background,
// Text color of the list item's trailing text.
- list-item-trailing-supporting-text-color: theming.get-color-from-palette(
- $foreground, hint-text),
+ list-item-trailing-supporting-text-color: theming.get-color-from-palette(
+ $foreground, hint-text),
// Color of the list item's trailing icon.
- list-item-trailing-icon-color: $text-icon-on-background,
+ list-item-trailing-icon-color: $text-icon-on-background,
// Color of the list item's trailing icon when the item is selected.
- list-item-selected-trailing-icon-color: $text-icon-on-background,
+ list-item-selected-trailing-icon-color: $text-icon-on-background,
// Text color of the list item's primary text when the item is disabled.
- list-item-disabled-label-text-color: theming.get-color-from-palette($foreground, base),
+ list-item-disabled-label-text-color: theming.get-color-from-palette($foreground, base),
// Color of the list item's leading icon when the item is disabled.
- list-item-disabled-leading-icon-color: theming.get-color-from-palette($foreground, base),
+ list-item-disabled-leading-icon-color: theming.get-color-from-palette($foreground, base),
// Color of the list item's trailing icon when the item is disabled.
- list-item-disabled-trailing-icon-color: theming.get-color-from-palette($foreground, base),
+ list-item-disabled-trailing-icon-color: theming.get-color-from-palette($foreground, base),
// Color of the list item's primary text when the item is being hovered.
- list-item-hover-label-text-color: theming.get-color-from-palette($foreground, text),
+ list-item-hover-label-text-color: theming.get-color-from-palette($foreground, text),
// Color of the list item's leading icon when the item is being hovered.
- list-item-hover-leading-icon-color: $text-icon-on-background,
+ list-item-hover-leading-icon-color: $text-icon-on-background,
// Color of the list item's trailing icon when the item is being hovered.
- list-item-hover-trailing-icon-color: $text-icon-on-background,
+ list-item-hover-trailing-icon-color: $text-icon-on-background,
// Color of the list item's primary text when the item is focused.
- list-item-focus-label-text-color: theming.get-color-from-palette($foreground, text),
+ list-item-focus-label-text-color: theming.get-color-from-palette($foreground, text),
// Color of the list item's overlay when the item is hovered.
- list-item-hover-state-layer-color: theming.get-color-from-palette($foreground, base),
+ list-item-hover-state-layer-color: theming.get-color-from-palette($foreground, base),
// Opacity of the list item's overlay when the item is hovered.
- list-item-hover-state-layer-opacity: if($is-dark, 0.08, 0.04),
+ list-item-hover-state-layer-opacity: if($is-dark, 0.08, 0.04),
// Color of the list item's overlay when the item is focused.
- list-item-focus-state-layer-color: theming.get-color-from-palette($foreground, base),
+ list-item-focus-state-layer-color: theming.get-color-from-palette($foreground, base),
// Opacity of the list item's overlay when the item is focused.
- list-item-focus-state-layer-opacity: if($is-dark, 0.24, 0.12),
+ list-item-focus-state-layer-opacity: if($is-dark, 0.24, 0.12),
);
}
@@ -132,40 +133,40 @@ $prefix: (mdc, list);
@function get-typography-tokens($config) {
@return (
// Font family of the list item primary text.
- list-item-label-text-font: typography-utils.font-family($config, body-1)
+ list-item-label-text-font: typography-utils.font-family($config, body-1)
or typography-utils.font-family($config),
// Line height of the list item primary text.
- list-item-label-text-line-height: typography-utils.line-height($config, body-1),
+ list-item-label-text-line-height: typography-utils.line-height($config, body-1),
// Font size of the list item primary text.
- list-item-label-text-size: typography-utils.font-size($config, body-1),
+ list-item-label-text-size: typography-utils.font-size($config, body-1),
// Letter spacing of the list item primary text.
- list-item-label-text-tracking: typography-utils.letter-spacing($config, body-1),
+ list-item-label-text-tracking: typography-utils.letter-spacing($config, body-1),
// Font weight of the list item primary text.
- list-item-label-text-weight: typography-utils.font-weight($config, body-1),
+ list-item-label-text-weight: typography-utils.font-weight($config, body-1),
// Font family of the list item supporting text.
- list-item-supporting-text-font: typography-utils.font-family($config, body-2)
+ list-item-supporting-text-font: typography-utils.font-family($config, body-2)
or typography-utils.font-family($config),
// Line height of the list item supporting text.
- list-item-supporting-text-line-height: typography-utils.line-height($config, body-2),
+ list-item-supporting-text-line-height: typography-utils.line-height($config, body-2),
// Font size of the list item supporting text.
- list-item-supporting-text-size: typography-utils.font-size($config, body-2),
+ list-item-supporting-text-size: typography-utils.font-size($config, body-2),
// Letter spacing of the list item supporting text.
- list-item-supporting-text-tracking: typography-utils.letter-spacing($config, body-2),
+ list-item-supporting-text-tracking: typography-utils.letter-spacing($config, body-2),
// Font weight of the list item supporting text.
- list-item-supporting-text-weight: typography-utils.font-weight($config, body-2),
+ list-item-supporting-text-weight: typography-utils.font-weight($config, body-2),
// Font family of the list item's trailing text.
- list-item-trailing-supporting-text-font: typography-utils.font-family($config, caption)
+ list-item-trailing-supporting-text-font: typography-utils.font-family($config, caption)
or typography-utils.font-family($config),
// Line height of the list item's trailing text.
- list-item-trailing-supporting-text-line-height: typography-utils.line-height(
- $config, caption),
+ list-item-trailing-supporting-text-line-height: typography-utils.line-height(
+ $config, caption),
// Font size of the list item's trailing text.
- list-item-trailing-supporting-text-size: typography-utils.font-size($config, caption),
+ list-item-trailing-supporting-text-size: typography-utils.font-size($config, caption),
// Letter spacing color of the list item's trailing text.
- list-item-trailing-supporting-text-tracking: typography-utils.letter-spacing(
- $config, caption),
+ list-item-trailing-supporting-text-tracking: typography-utils.letter-spacing(
+ $config, caption),
// Font weight of the list item's trailing text.
- list-item-trailing-supporting-text-weight: typography-utils.font-weight($config, caption),
+ list-item-trailing-supporting-text-weight: typography-utils.font-weight($config, caption),
);
}
@@ -175,42 +176,42 @@ $prefix: (mdc, list);
@return (
// Height of one line list items.
- list-item-one-line-container-height: map.get((
- 0: 48px,
- -1: 44px,
- -2: 40px,
- -3: 36px,
- -4: 32px,
- -5: 24px,
- ), $scale),
+ list-item-one-line-container-height: map.get((
+ 0: 48px,
+ -1: 44px,
+ -2: 40px,
+ -3: 36px,
+ -4: 32px,
+ -5: 24px,
+ ), $scale),
// Height of two line list items.
- list-item-two-line-container-height: map.get((
- 0: 64px,
- -1: 60px,
- -2: 56px,
- -3: 52px,
- -4: 48px,
- -5: 48px,
- ), $scale),
+ list-item-two-line-container-height: map.get((
+ 0: 64px,
+ -1: 60px,
+ -2: 56px,
+ -3: 52px,
+ -4: 48px,
+ -5: 48px,
+ ), $scale),
// Height of three line list items.
- list-item-three-line-container-height: map.get((
- 0: 88px,
- -1: 84px,
- -2: 80px,
- -3: 76px,
- -4: 72px,
- -5: 56px,
- ), $scale),
+ list-item-three-line-container-height: map.get((
+ 0: 88px,
+ -1: 84px,
+ -2: 80px,
+ -3: 76px,
+ -4: 72px,
+ -5: 56px,
+ ), $scale),
);
}
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_outlined-card.scss b/src/material/core/tokens/m2/mdc/_outlined-card.scss
index 6efdb969634f..595eece7df7f 100644
--- a/src/material/core/tokens/m2/mdc/_outlined-card.scss
+++ b/src/material/core/tokens/m2/mdc/_outlined-card.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../../style/elevation';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -82,7 +83,7 @@ $prefix: (mdc, outlined-card);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
+ @return sass-utils.deep-merge-all(
get-unthemable-tokens(),
get-color-tokens(token-utils.$placeholder-color-config),
get-typography-tokens(token-utils.$placeholder-typography-config),
diff --git a/src/material/core/tokens/m2/mdc/_plain-tooltip.scss b/src/material/core/tokens/m2/mdc/_plain-tooltip.scss
index 1853c15e8f45..3636238f6b82 100644
--- a/src/material/core/tokens/m2/mdc/_plain-tooltip.scss
+++ b/src/material/core/tokens/m2/mdc/_plain-tooltip.scss
@@ -2,6 +2,7 @@
@use '../../../theming/theming';
@use '../../../typography/typography-utils';
@use '../../../mdc-helpers/mdc-helpers';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -67,14 +68,10 @@ $prefix: (mdc, plain-tooltip);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return map.merge(
- get-unthemable-tokens(),
- map.merge(
- get-color-tokens(token-utils.$placeholder-color-config),
- map.merge(
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
- )
- )
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_radio.scss b/src/material/core/tokens/m2/mdc/_radio.scss
index 1b9caace43f8..29879d95c986 100644
--- a/src/material/core/tokens/m2/mdc/_radio.scss
+++ b/src/material/core/tokens/m2/mdc/_radio.scss
@@ -1,6 +1,7 @@
@use 'sass:map';
@use '../../../theming/palette';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -16,12 +17,10 @@ $prefix: (mdc, radio);
@return (
disabled-selected-icon-opacity: 0.38,
disabled-unselected-icon-opacity: 0.38,
-
// This is specified both here and in the density tokens, because it
// determines the size of the radio button itself and there are internal
// tests who don't configure the theme correctly.
state-layer-size: 40px,
-
// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
@@ -85,10 +84,10 @@ $prefix: (mdc, radio);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_snack-bar.scss b/src/material/core/tokens/m2/mdc/_snack-bar.scss
index 6853e5ddfe28..cd191a22fa2e 100644
--- a/src/material/core/tokens/m2/mdc/_snack-bar.scss
+++ b/src/material/core/tokens/m2/mdc/_snack-bar.scss
@@ -5,6 +5,7 @@
@use '../../token-utils';
@use '../../../typography/typography-utils';
@use '../../../mdc-helpers/mdc-helpers';
+@use '../../../style/sass-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
$prefix: (mdc, snackbar);
@@ -19,18 +20,15 @@ $prefix: (mdc, snackbar);
@return (
// Sets the snack bar border radius.
container-shape: 4px,
-
// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
// Removed to match the previous appearance.
supporting-text-tracking: null,
-
// Excluded because they target the wrong DOM node. See the
// comments on the elevation of `.mat-mdc-snack-bar-container`.
container-elevation: null,
container-shadow-color: null,
-
action-focus-label-text-color: null,
action-focus-state-layer-color: null,
action-focus-state-layer-opacity: null,
@@ -99,10 +97,10 @@ $prefix: (mdc, snackbar);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_tab-indicator.scss b/src/material/core/tokens/m2/mdc/_tab-indicator.scss
index 82adb1dbdf89..1b8d0776497e 100644
--- a/src/material/core/tokens/m2/mdc/_tab-indicator.scss
+++ b/src/material/core/tokens/m2/mdc/_tab-indicator.scss
@@ -1,5 +1,6 @@
@use 'sass:map';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -14,7 +15,6 @@ $prefix: (mdc, tab-indicator);
@function get-unthemable-tokens() {
@return (
active-indicator-height: 2px,
-
// Currently set to zero, but used by the gmat styles to make the indicator rounded.
active-indicator-shape: 0,
);
@@ -42,10 +42,10 @@ $prefix: (mdc, tab-indicator);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/m2/mdc/_tab.scss b/src/material/core/tokens/m2/mdc/_tab.scss
index 0c2cb1025d92..3869ef97da2a 100644
--- a/src/material/core/tokens/m2/mdc/_tab.scss
+++ b/src/material/core/tokens/m2/mdc/_tab.scss
@@ -1,5 +1,6 @@
@use 'sass:map';
@use '../../../theming/theming';
+@use '../../../style/sass-utils';
@use '../../token-utils';
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -16,7 +17,6 @@ $prefix: (mdc, tab);
// This is specified both here and in the density tokens, because it determines the size of the
// tab itself and there are internal tests who don't configure the theme correctly.
container-height: 48px,
-
// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
@@ -77,10 +77,10 @@ $prefix: (mdc, tab);
// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
- @return token-utils.merge-all(
- get-unthemable-tokens(),
- get-color-tokens(token-utils.$placeholder-color-config),
- get-typography-tokens(token-utils.$placeholder-typography-config),
- get-density-tokens(token-utils.$placeholder-density-config)
+ @return sass-utils.deep-merge-all(
+ get-unthemable-tokens(),
+ get-color-tokens(token-utils.$placeholder-color-config),
+ get-typography-tokens(token-utils.$placeholder-typography-config),
+ get-density-tokens(token-utils.$placeholder-density-config)
);
}
diff --git a/src/material/core/tokens/tests/test-validate-tokens.scss b/src/material/core/tokens/tests/test-validate-tokens.scss
index af106eb0f0f8..56c5040fbfe5 100644
--- a/src/material/core/tokens/tests/test-validate-tokens.scss
+++ b/src/material/core/tokens/tests/test-validate-tokens.scss
@@ -5,8 +5,8 @@
@use '@material/card/outlined-card-theme' as mdc-outlined-card-theme;
@use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme;
@use '@material/circular-progress/circular-progress-theme' as mdc-circular-progress-theme;
-@use '@material/icon-button/icon-button-theme' as mdc-icon-button-theme;
@use '@material/linear-progress/linear-progress-theme' as mdc-linear-progress-theme;
+@use '@material/icon-button/icon-button-theme' as mdc-icon-button-theme;
@use '@material/list/list-theme' as mdc-list-theme;
@use '@material/tooltip/plain-tooltip-theme' as mdc-plaintip-tooltip-theme;
@use '@material/radio/radio-theme' as mdc-radio-theme;
@@ -17,10 +17,10 @@
@use '@material/theme/validate' as mdc-validate;
@use '../m2/mdc/circular-progress' as tokens-mdc-circular-progress;
+@use '../m2/mdc/linear-progress' as tokens-mdc-linear-progress;
@use '../m2/mdc/elevated-card' as tokens-mdc-elevated-card;
@use '../m2/mdc/icon-button' as tokens-mdc-icon-button;
@use '../m2/mdc/checkbox' as tokens-mdc-checkbox;
-@use '../m2/mdc/linear-progress' as tokens-mdc-linear-progress;
@use '../m2/mdc/list' as tokens-mdc-list;
@use '../m2/mdc/outlined-card' as tokens-mdc-outlined-card;
@use '../m2/mdc/plain-tooltip' as tokens-mdc-plain-tooltip;
diff --git a/src/material/legacy-radio/radio.scss b/src/material/legacy-radio/radio.scss
index 59b8414df1e5..5751e269a599 100644
--- a/src/material/legacy-radio/radio.scss
+++ b/src/material/legacy-radio/radio.scss
@@ -2,7 +2,6 @@
@use '@angular/cdk';
@use '../core/style/variables';
-@use '../core/ripple/ripple';
@use '../core/style/vendor-prefixes';
diff --git a/src/material/legacy-slide-toggle/slide-toggle.scss b/src/material/legacy-slide-toggle/slide-toggle.scss
index e420cb134285..86358134d533 100644
--- a/src/material/legacy-slide-toggle/slide-toggle.scss
+++ b/src/material/legacy-slide-toggle/slide-toggle.scss
@@ -3,7 +3,6 @@
@use '../core/style/vendor-prefixes';
@use '../core/style/variables';
-@use '../core/ripple/ripple';
@use '../core/style/list-common';
$thumb-size: 20px !default;
diff --git a/src/material/slide-toggle/slide-toggle.scss b/src/material/slide-toggle/slide-toggle.scss
index 4163fbe3c45e..4296aaa6a79b 100644
--- a/src/material/slide-toggle/slide-toggle.scss
+++ b/src/material/slide-toggle/slide-toggle.scss
@@ -5,7 +5,7 @@
@use '@material/form-field' as mdc-form-field;
@use '@material/ripple' as mdc-ripple;
@use '../core/mdc-helpers/mdc-helpers';
-@use '../core/style/_layout-common.scss';
+@use '../core/style/layout-common';
@include mdc-helpers.disable-mdc-fallback-declarations {
diff --git a/src/material/stepper/stepper.scss b/src/material/stepper/stepper.scss
index 41c756947198..5d2a70d19970 100644
--- a/src/material/stepper/stepper.scss
+++ b/src/material/stepper/stepper.scss
@@ -1,7 +1,6 @@
@use '@angular/cdk';
@use 'sass:math';
-@use '../core/style/variables';
@use './stepper-variables';
.mat-stepper-vertical,
diff --git a/src/material/tabs/_tabs-theme.scss b/src/material/tabs/_tabs-theme.scss
index 203be33801ec..d4d85fc32382 100644
--- a/src/material/tabs/_tabs-theme.scss
+++ b/src/material/tabs/_tabs-theme.scss
@@ -1,6 +1,5 @@
@use 'sass:map';
@use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme;
-@use '@material/tab' as mdc-tab;
@use '@material/tab/tab-theme' as mdc-tab-theme;
@use '../core/tokens/m2/mdc/tab' as tokens-mdc-tab;
@use '../core/tokens/m2/mdc/tab-indicator' as tokens-mdc-tab-indicator;
diff --git a/tools/stylelint/no-unused-import.ts b/tools/stylelint/no-unused-import.ts
index 4a3761f26b1f..2acfa729b405 100644
--- a/tools/stylelint/no-unused-import.ts
+++ b/tools/stylelint/no-unused-import.ts
@@ -9,6 +9,13 @@ const messages = utils.ruleMessages(ruleName, {
`imports Stylelint rule likely needs to be updated.`,
});
+function stripCommentsAndAtUse(content: string) {
+ return content
+ .replace(/@use.*?;/g, '')
+ .replace(/\/\/.*?\n/g, '')
+ .replace(/\/\*.*?\*\//g, '');
+}
+
/** Stylelint plugin that flags unused `@use` statements. */
const ruleFn: Rule = (isEnabled, _options, context) => {
return (root, result) => {
@@ -16,7 +23,7 @@ const ruleFn: Rule = (isEnabled, _options, context) => {
return;
}
- const fileContent = root.toString();
+ const fileContent = stripCommentsAndAtUse(root.toString());
root.walkAtRules(rule => {
if (rule.name === 'use') {
@@ -30,7 +37,9 @@ const ruleFn: Rule = (isEnabled, _options, context) => {
message: messages.invalid(rule.params),
node: rule,
});
- } else if (!fileContent.includes(namespace + '.')) {
+ } else if (!fileContent.match('[^\\w$@-]' + namespace + '[^\\w-]')) {
+ // We use a broader match than just `${namespace}.`, because this doesn't catch the case
+ // where we use the module as an argument to something like `meta.get-function`.
if (context.fix) {
rule.remove();
} else {