Skip to content

Commit d479e1a

Browse files
authored
refactor(material/dialog): switch to tokens API (#26846)
Reworks the dialog to use the new tokens API.
1 parent a2ebcbc commit d479e1a

File tree

5 files changed

+182
-90
lines changed

5 files changed

+182
-90
lines changed

src/material/core/mdc-helpers/_mdc-helpers.scss

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ $mat-typography-mdc-level-mappings: (
8484
}
8585

8686
// Converts an MDC typography level config to an Angular Material one.
87-
@function typography-config-level-from-mdc($mdc-level) {
87+
@function typography-config-level-from-mdc($mdc-level, $font-family: null) {
8888
$mdc-level-config: map.get(mdc-typography.$styles, $mdc-level);
8989

90-
// Explicitly set the font family to null since we'll apply it globally
90+
// Explicitly default the font family to null since we'll apply it globally
9191
// through the `define-typgraphy-config`/`define-legacy-typography-config`.
9292
@return typography.define-typography-level(
93-
$font-family: null,
93+
$font-family: $font-family,
9494
$font-size: map.get($mdc-level-config, font-size),
9595
$line-height: map.get($mdc-level-config, line-height),
9696
$font-weight: map.get($mdc-level-config, font-weight),
@@ -226,6 +226,34 @@ $mat-typography-mdc-level-mappings: (
226226
mdc-typography.$styles: $orig-mdc-typography-styles;
227227
}
228228

229+
// Function to create an Angular Material typography config from MDC's predefined typography levels.
230+
// This is used for components where we accidentally ended up supporting null typography configs
231+
// that were silently falling back to MDC's typography. At the moment of writing this includes
232+
// `dialog`, `slider` and `tooltip`.
233+
// Important! We shouldn't introduce any new usages of this pattern and we should eventually clean
234+
// up any existing usages.
235+
@function private-fallback-typography-from-mdc() {
236+
// This is very close to what we have in `define-typography-config`, but we can't use it here,
237+
// because it would cause a circular import and moving it here doesn't make sense.
238+
$font-family: mdc-typography.$font-family;
239+
@return (
240+
font-family: $font-family,
241+
headline-1: typography-config-level-from-mdc(headline1, $font-family),
242+
headline-2: typography-config-level-from-mdc(headline2, $font-family),
243+
headline-3: typography-config-level-from-mdc(headline3, $font-family),
244+
headline-4: typography-config-level-from-mdc(headline4, $font-family),
245+
headline-5: typography-config-level-from-mdc(headline5, $font-family),
246+
headline-6: typography-config-level-from-mdc(headline6, $font-family),
247+
subtitle-1: typography-config-level-from-mdc(subtitle1, $font-family),
248+
subtitle-2: typography-config-level-from-mdc(subtitle2, $font-family),
249+
body-1: typography-config-level-from-mdc(body1, $font-family),
250+
body-2: typography-config-level-from-mdc(body2, $font-family),
251+
caption: typography-config-level-from-mdc(caption, $font-family),
252+
button: typography-config-level-from-mdc(button, $font-family),
253+
overline: typography-config-level-from-mdc(overline, $font-family),
254+
);
255+
}
256+
229257
// Disables MDC's CSS custom property fallbacks for the specified mixin content.
230258
@mixin disable-mdc-fallback-declarations {
231259
$previous-value: mdc-theme-css.$enable-fallback-declarations;

src/material/core/tokens/_token-utils.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ $_placeholder-typography-level-config: mdc-helpers.typography-config-level-from-
2525
// Placeholder typography config that can be passed to token getter functions when generating token
2626
// slots.
2727
$placeholder-typography-config: (
28-
font-family: Roboto,
28+
font-family: 'Roboto, sans-serif',
2929
headline-1: $_placeholder-typography-level-config,
3030
headline-2: $_placeholder-typography-level-config,
3131
headline-3: $_placeholder-typography-level-config,
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
@use 'sass:map';
2+
@use '../../../theming/theming';
3+
@use '../../../typography/typography-utils';
4+
@use '../../../mdc-helpers/mdc-helpers';
5+
@use '../../token-utils';
6+
7+
// The prefix used to generate the fully qualified name for tokens in this file.
8+
$prefix: (mdc, dialog);
9+
10+
// Tokens that can't be configured through Angular Material's current theming API,
11+
// but may be in a future version of the theming API.
12+
//
13+
// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`.
14+
// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in
15+
// our CSS.
16+
@function get-unthemable-tokens() {
17+
@return (
18+
// Height of the container's elevation.
19+
container-elevation: 24,
20+
// Color of the elevation shadow.
21+
container-shadow-color: #000,
22+
// Border radius of the container.
23+
container-shape: 4px,
24+
25+
// =============================================================================================
26+
// = TOKENS NOT USED IN ANGULAR MATERIAL =
27+
// =============================================================================================
28+
with-divider-divider-height: null,
29+
with-divider-divider-color: null,
30+
with-icon-icon-size: null,
31+
with-icon-icon-color: null,
32+
action-label-text-font: null,
33+
action-label-text-line-height: null,
34+
action-label-text-size: null,
35+
action-label-text-weight: null,
36+
action-label-text-tracking: null,
37+
action-label-text-color: null,
38+
action-hover-state-layer-color: null,
39+
action-hover-state-layer-opacity: null,
40+
action-hover-label-text-color: null,
41+
action-focus-state-layer-color: null,
42+
action-focus-state-layer-opacity: null,
43+
action-focus-label-text-color: null,
44+
action-pressed-state-layer-color: null,
45+
action-pressed-state-layer-opacity: null,
46+
action-pressed-label-text-color: null,
47+
headline-color: null,
48+
headline-font: null,
49+
headline-line-height: null,
50+
headline-size: null,
51+
headline-tracking: null,
52+
headline-weight: null,
53+
);
54+
}
55+
56+
// Tokens that can be configured through Angular Material's color theming API.
57+
@function get-color-tokens($config) {
58+
$is-dark: map.get($config, 'is-dark');
59+
$background: map.get($config, background);
60+
$on-surface: if($is-dark, #fff, #000);
61+
62+
@return (
63+
// Background color of the container.
64+
container-color: theming.get-color-from-palette($background, dialog),
65+
// Color of the dialog header.
66+
subhead-color: rgba($on-surface, 0.87),
67+
// Color of the dialog body text.
68+
supporting-text-color: rgba($on-surface, 0.6),
69+
);
70+
}
71+
72+
// Tokens that can be configured through Angular Material's typography theming API.
73+
@function get-typography-tokens($config) {
74+
// TODO(crisbeto): The earlier implementation of the dialog used MDC's APIs to create the
75+
// typography tokens. As a result, we unintentionally allowed `null` typography configs to be
76+
// passed in. Since there a lot of apps that now depend on this pattern, we need this temporary
77+
// fallback.
78+
@if ($config == null) {
79+
$config: mdc-helpers.private-fallback-typography-from-mdc();
80+
}
81+
82+
@return (
83+
// Typography of the dialog header.
84+
subhead-font: typography-utils.font-family($config, headline-6)
85+
or typography-utils.font-family($config),
86+
subhead-line-height: typography-utils.line-height($config, headline-6),
87+
subhead-size: typography-utils.font-size($config, headline-6),
88+
subhead-weight: typography-utils.font-weight($config, headline-6),
89+
subhead-tracking: typography-utils.letter-spacing($config, headline-6),
90+
91+
// Typography of the dialog body text.
92+
supporting-text-font: typography-utils.font-family($config, body-1)
93+
or typography-utils.font-family($config),
94+
supporting-text-line-height: typography-utils.line-height($config, body-1),
95+
supporting-text-size: typography-utils.font-size($config, body-1),
96+
supporting-text-weight: typography-utils.font-weight($config, body-1),
97+
supporting-text-tracking: typography-utils.letter-spacing($config, body-1),
98+
);
99+
}
100+
101+
// Tokens that can be configured through Angular Material's density theming API.
102+
@function get-density-tokens($config) {
103+
@return ();
104+
}
105+
106+
// Combines the tokens generated by the above functions into a single map with placeholder values.
107+
// This is used to create token slots.
108+
@function get-token-slots() {
109+
@return token-utils.merge-all(
110+
get-unthemable-tokens(),
111+
get-color-tokens(token-utils.$placeholder-color-config),
112+
get-typography-tokens(token-utils.$placeholder-typography-config),
113+
get-density-tokens(token-utils.$placeholder-density-config)
114+
);
115+
}

src/material/dialog/_dialog-theme.scss

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,22 @@
1-
@use 'sass:map';
2-
@use '@material/dialog' as mdc-dialog;
31
@use '@material/dialog/dialog-theme' as mdc-dialog-theme;
4-
@use '@material/theme/theme-color' as mdc-theme-color;
5-
@use '@material/typography' as mdc-typography;
2+
@use '../core/tokens/m2/mdc/dialog' as tokens-mdc-dialog;
63
@use '../core/theming/theming';
7-
@use '../core/mdc-helpers/mdc-helpers';
84
@use '../core/typography/typography';
95

106
@mixin color($config-or-theme) {
117
$config: theming.get-color-config($config-or-theme);
12-
$background: map.get($config, background);
138

14-
@include mdc-helpers.using-mdc-theme($config) {
15-
.mat-mdc-dialog-container {
16-
$on-surface: mdc-theme-color.$on-surface;
17-
$text-emphasis-high: mdc-theme-color.text-emphasis(high);
18-
$text-emphasis-medium: mdc-theme-color.text-emphasis(medium);
19-
20-
@include mdc-dialog-theme.theme((
21-
container-color: theming.get-color-from-palette($background, dialog),
22-
with-divider-divider-color: rgba($on-surface, mdc-dialog.$scroll-divider-opacity),
23-
subhead-color: rgba($on-surface, $text-emphasis-high),
24-
supporting-text-color: rgba($on-surface, $text-emphasis-medium),
25-
));
26-
}
9+
.mat-mdc-dialog-container {
10+
@include mdc-dialog-theme.theme(tokens-mdc-dialog.get-color-tokens($config));
2711
}
2812
}
2913

3014
@mixin typography($config-or-theme) {
3115
$config: typography.private-typography-to-2018-config(
3216
theming.get-typography-config($config-or-theme));
33-
@include mdc-helpers.using-mdc-typography($config) {
34-
.mat-mdc-dialog-container {
35-
$styles: mdc-typography.$styles;
36-
$headline6: map.get($styles, headline6);
3717

38-
@include mdc-dialog-theme.theme((
39-
subhead-font: map.get($headline6, font-family),
40-
subhead-line-height: map.get($styles, headline6, line-height),
41-
subhead-size: map.get($styles, headline6, font-size),
42-
subhead-weight: map.get($styles, headline6, font-weight),
43-
subhead-tracking: map.get($styles, headline6, letter-spacing),
44-
45-
supporting-text-font: map.get($styles, body1, font-family),
46-
supporting-text-line-height: map.get($styles, body1, line-height),
47-
supporting-text-size: map.get($styles, body1, font-size),
48-
supporting-text-weight: map.get($styles, body1, font-weight),
49-
supporting-text-tracking: map.get($styles, body1, letter-spacing),
50-
));
51-
}
18+
.mat-mdc-dialog-container {
19+
@include mdc-dialog-theme.theme(tokens-mdc-dialog.get-typography-tokens($config));
5220
}
5321
}
5422

src/material/dialog/dialog.scss

Lines changed: 30 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,9 @@
11
@use '@material/dialog' as mdc-dialog;
2-
@use '@material/dialog/variables' as mdc-dialog-variables;
32
@use '@material/dialog/dialog-theme' as mdc-dialog-theme;
4-
@use './mdc-dialog-structure-overrides';
3+
@use '@material/theme/custom-properties' as mdc-custom-properties;
4+
@use '../core/tokens/m2/mdc/dialog' as tokens-mdc-dialog;
55
@use '../core/mdc-helpers/mdc-helpers';
6-
7-
// Theme map with values for variables that will be overriden in the theme.
8-
// MDC's theming system requires non-null values for the slots to be inserted
9-
// and included as default values.
10-
$_dialog-initial-theme: (
11-
// Color
12-
container-color: white,
13-
container-elevation: 24,
14-
container-shadow-color: black,
15-
with-divider-divider-color: black,
16-
subhead-color: black,
17-
supporting-text-color: black,
18-
19-
// Typography
20-
subhead-font: 'Arial',
21-
subhead-line-height: 14px,
22-
subhead-size: 14px,
23-
subhead-weight: 500,
24-
subhead-tracking: 1px,
25-
supporting-text-font: 'Arial',
26-
supporting-text-line-height: 14px,
27-
supporting-text-size: 14px,
28-
supporting-text-weight: 500,
29-
supporting-text-tracking: 1px,
30-
31-
// Structure
32-
container-shape: mdc-dialog-variables.$shape-radius,
33-
);
6+
@use './mdc-dialog-structure-overrides';
347

358
// Dialog content max height. This has been copied from the standard dialog
369
// and is needed to make the dialog content scrollable.
@@ -39,32 +12,40 @@ $mat-dialog-content-max-height: 65vh !default;
3912
// don't expose this value as variable.
4013
$mat-dialog-button-horizontal-margin: 8px !default;
4114

15+
// Note that we disable fallback declarations, but we don't disable fallback
16+
// values, because there are a lot of internal apps that don't include a proper
17+
// theme in their tests.
4218
@include mdc-helpers.disable-mdc-fallback-declarations {
4319
@include mdc-dialog.static-styles($query: mdc-helpers.$mdc-base-styles-query);
44-
}
20+
@include mdc-dialog-structure-overrides.private-dialog-structure-overrides(
21+
$mat-dialog-content-max-height);
4522

46-
@include mdc-dialog-structure-overrides.private-dialog-structure-overrides(
47-
$mat-dialog-content-max-height);
23+
.mat-mdc-dialog-container {
24+
// Add default values for MDC dialog tokens that aren't outputted by the theming API.
25+
@include mdc-dialog-theme.theme(tokens-mdc-dialog.get-unthemable-tokens());
4826

49-
.mat-mdc-dialog-container {
50-
// Apply the theming slots to the container using an initial set of
51-
// values that will be overridden in the theme styles.
52-
@include mdc-helpers.disable-mdc-fallback-declarations {
53-
@include mdc-dialog-theme.theme-styles($_dialog-initial-theme);
54-
}
27+
// Apply the theming slots to the container using an initial set of
28+
// values that will be overridden in the theme styles.
29+
@include mdc-dialog-theme.theme-styles(tokens-mdc-dialog.get-token-slots());
5530

56-
// The dialog container is focusable. We remove the default outline shown in browsers.
57-
outline: 0;
31+
// MDC's `theme-styles` generates a variable called `--mdc-dialog-container-elevation-shadow`
32+
// (note the `--shadow`) while it uses `--mdc-dialog-container-elevation` to assign the
33+
// `box-shadow`. Remap it so the token value is picked up.
34+
--mdc-dialog-container-elevation: var(--mdc-dialog-container-elevation-shadow);
5835

59-
.mdc-dialog__container {
60-
transition-duration: var(--mat-dialog-transition-duration, 0ms);
61-
}
36+
// The dialog container is focusable. We remove the default outline shown in browsers.
37+
outline: 0;
6238

63-
// Angular Material supports disabling all animations when NoopAnimationsModule is imported.
64-
// TODO(devversion): Look into using MDC's Sass queries to separate the animation styles and
65-
// conditionally add them. Consider the size cost and churn when deciding whether to switch.
66-
&._mat-animation-noopable .mdc-dialog__container {
67-
transition: none;
39+
.mdc-dialog__container {
40+
transition-duration: var(--mat-dialog-transition-duration, 0ms);
41+
}
42+
43+
// Angular Material supports disabling all animations when NoopAnimationsModule is imported.
44+
// TODO(devversion): Look into using MDC's Sass queries to separate the animation styles and
45+
// conditionally add them. Consider the size cost and churn when deciding whether to switch.
46+
&._mat-animation-noopable .mdc-dialog__container {
47+
transition: none;
48+
}
6849
}
6950
}
7051

0 commit comments

Comments
 (0)