Skip to content

Commit f2d5644

Browse files
authored
feat(material-experimental/theming): add M3 menu & divider support (#28144)
* feat(material-experimental/theming): add M3 menu support * feat(material-experimental/theming): add M3 divider support
1 parent cf868a5 commit f2d5644

File tree

8 files changed

+287
-135
lines changed

8 files changed

+287
-135
lines changed

src/dev-app/theme-m3.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ $dark-theme: matx.define-theme(map.set($m3-base-config, color, theme-type, dark)
3838
html {
3939
@include mat.card-theme($light-theme);
4040
@include mat.checkbox-theme($light-theme);
41+
@include mat.divider-theme($light-theme);
4142
@include mat.form-field-theme($light-theme);
4243
@include mat.grid-list-theme($light-theme);
4344
@include mat.icon-theme($light-theme);
4445
@include mat.input-theme($light-theme);
4546
@include mat.list-theme($light-theme);
47+
@include mat.menu-theme($light-theme);
4648
@include mat.progress-bar-theme($light-theme);
4749
@include mat.progress-spinner-theme($light-theme);
4850
@include mat.radio-theme($light-theme);
@@ -68,11 +70,13 @@ html {
6870

6971
@include mat.card-color($dark-theme);
7072
@include mat.checkbox-color($dark-theme);
73+
@include mat.divider-color($dark-theme);
7174
@include mat.form-field-color($dark-theme);
7275
@include mat.grid-list-color($dark-theme);
7376
@include mat.icon-color($dark-theme);
7477
@include mat.input-color($dark-theme);
7578
@include mat.list-color($dark-theme);
79+
@include mat.menu-color($dark-theme);
7680
@include mat.progress-bar-color($dark-theme);
7781
@include mat.progress-spinner-color($dark-theme);
7882
@include mat.radio-color($dark-theme);
@@ -97,11 +101,13 @@ html {
97101
.demo-density-#{$scale} {
98102
@include mat.card-density($scale-theme);
99103
@include mat.checkbox-density($scale-theme);
104+
@include mat.divider-density($scale-theme);
100105
@include mat.form-field-density($scale-theme);
101106
@include mat.grid-list-density($scale-theme);
102107
@include mat.icon-density($scale-theme);
103108
@include mat.input-density($scale-theme);
104109
@include mat.list-density($scale-theme);
110+
@include mat.menu-density($scale-theme);
105111
@include mat.progress-bar-density($scale-theme);
106112
@include mat.progress-spinner-density($scale-theme);
107113
@include mat.radio-density($scale-theme);

src/material-experimental/theming/_custom-tokens.scss

Lines changed: 70 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@
3535
);
3636
}
3737

38+
/// Generates custom tokens for the mat-divider.
39+
/// @param {Map} $systems The MDC system tokens
40+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
41+
/// @return {Map} A set of custom tokens for the mat-divider
42+
@function divider($systems, $exclude-hardcoded) {
43+
@return (
44+
width: _hardcode(1px, $exclude-hardcoded),
45+
color: map.get($systems, md-sys-color, outline-variant),
46+
);
47+
}
48+
3849
/// Generates custom tokens for the mat-form-field.
3950
/// @param {Map} $systems The MDC system tokens
4051
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
@@ -85,48 +96,30 @@
8596
);
8697
}
8798

88-
/// Generates custom tokens for the mat-toolbar.
99+
/// Generates custom tokens for the mat-menu.
89100
/// @param {Map} $systems The MDC system tokens
90101
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
91-
/// @return {Map} A set of custom tokens for the mat-toolbar
92-
@function toolbar($systems, $exclude-hardcoded) {
102+
/// @return {Map} A set of custom tokens for the mat-menu
103+
@function menu($systems, $exclude-hardcoded) {
93104
@return mat.private-merge-all(
94-
_generate-typography-tokens($systems, title-text, title-large),
105+
_generate-typography-tokens($systems, item-label-text, label-large),
95106
(
96-
container-background-color: map.get($systems, md-sys-color, surface),
97-
container-text-color: map.get($systems, md-sys-color, on-surface),
107+
container-shape: _hardcode(4px, $exclude-hardcoded),
108+
item-label-text-color: map.get($systems, md-sys-color, on-surface),
109+
item-icon-color: map.get($systems, md-sys-color, on-surface-variant),
110+
item-hover-state-layer-color: mat.private-safe-color-change(
111+
map.get($systems, md-sys-color, on-surface),
112+
$alpha: map.get($systems, md-sys-state, hover-state-layer-opacity)
113+
),
114+
item-focus-state-layer-color: mat.private-safe-color-change(
115+
map.get($systems, md-sys-color, on-surface),
116+
$alpha: map.get($systems, md-sys-state, focus-state-layer-opacity)
117+
),
118+
container-color: map.get($systems, md-sys-color, surface-container),
98119
)
99120
);
100121
}
101122

102-
/// Generates custom tokens for the mat-slide-toggle.
103-
/// @param {Map} $systems The MDC system tokens
104-
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
105-
/// @return {Map} A set of custom tokens for the mat-slide-toggle
106-
@function slide-toggle($systems, $exclude-hardcoded) {
107-
@return _generate-typography-tokens($systems, label-text, label-large);
108-
}
109-
110-
/// Generates custom tokens for the mat-slider.
111-
/// @param {Map} $systems The MDC system tokens
112-
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
113-
/// @return {Map} A set of custom tokens for the mat-slider
114-
@function slider($systems, $exclude-hardcoded) {
115-
@return (
116-
value-indicator-opacity: _hardcode(1, $exclude-hardcoded),
117-
);
118-
}
119-
120-
/// Generates custom tokens for the mat-snack-bar.
121-
/// @param {Map} $systems The MDC system tokens
122-
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
123-
/// @return {Map} A set of custom tokens for the mat-snack-bar
124-
@function snack-bar($systems, $exclude-hardcoded) {
125-
@return (
126-
button-color: map.get($systems, md-sys-color, inverse-primary),
127-
);
128-
}
129-
130123
/// Generates custom tokens for the mat-radio.
131124
/// @param {Map} $systems The MDC system tokens
132125
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
@@ -166,6 +159,34 @@
166159
);
167160
}
168161

162+
/// Generates custom tokens for the mat-slide-toggle.
163+
/// @param {Map} $systems The MDC system tokens
164+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
165+
/// @return {Map} A set of custom tokens for the mat-slide-toggle
166+
@function slide-toggle($systems, $exclude-hardcoded) {
167+
@return _generate-typography-tokens($systems, label-text, label-large);
168+
}
169+
170+
/// Generates custom tokens for the mat-slider.
171+
/// @param {Map} $systems The MDC system tokens
172+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
173+
/// @return {Map} A set of custom tokens for the mat-slider
174+
@function slider($systems, $exclude-hardcoded) {
175+
@return (
176+
value-indicator-opacity: _hardcode(1, $exclude-hardcoded),
177+
);
178+
}
179+
180+
/// Generates custom tokens for the mat-snack-bar.
181+
/// @param {Map} $systems The MDC system tokens
182+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
183+
/// @return {Map} A set of custom tokens for the mat-snack-bar
184+
@function snack-bar($systems, $exclude-hardcoded) {
185+
@return (
186+
button-color: map.get($systems, md-sys-color, inverse-primary),
187+
);
188+
}
189+
169190
/// Generates custom tokens for the mat-sort.
170191
/// @param {Map} $systems The MDC system tokens
171192
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
@@ -221,7 +242,7 @@
221242
@return mat.private-merge-all(
222243
_generate-typography-tokens($systems, label-text, title-small),
223244
(
224-
disabled-ripple-color: blue, // TODO(mmalerba): Figure out correct value.
245+
disabled-ripple-color: null, // TODO(mmalerba): Figure out correct value.
225246
pagination-icon-color: map.get($systems, md-sys-color, on-surface),
226247
inactive-label-text-color: map.get($systems, md-sys-color, on-surface),
227248
active-label-text-color: map.get($systems, md-sys-color, on-surface),
@@ -270,6 +291,20 @@
270291
);
271292
}
272293

294+
/// Generates custom tokens for the mat-toolbar.
295+
/// @param {Map} $systems The MDC system tokens
296+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
297+
/// @return {Map} A set of custom tokens for the mat-toolbar
298+
@function toolbar($systems, $exclude-hardcoded) {
299+
@return mat.private-merge-all(
300+
_generate-typography-tokens($systems, title-text, title-large),
301+
(
302+
container-background-color: map.get($systems, md-sys-color, surface),
303+
container-text-color: map.get($systems, md-sys-color, on-surface),
304+
)
305+
);
306+
}
307+
273308
/// Generates custom tokens for the mat-tree.
274309
/// @param {Map} $systems The MDC system tokens
275310
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values

src/material-experimental/theming/_m3-density.scss

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,23 @@ $_density-tokens: (
1919
(mdc, checkbox): (
2020
state-layer-size: (40px, 36px, 32px, 28px),
2121
),
22+
(mdc, circular-progress): (),
2223
(mdc, elevated-card): (),
2324
(mdc, filled-text-field): (),
24-
(mdc, outlined-card): (),
25-
(mdc, outlined-text-field): (),
26-
(mdc, slider): (),
27-
(mdc, snackbar): (),
28-
(mdc, plain-tooltip): (),
29-
(mdc, circular-progress): (),
30-
(mdc, radio): (
31-
state-layer-size: (40px, 36px, 32px, 28px),
32-
),
3325
(mdc, linear-progress): (),
3426
(mdc, list): (
3527
list-item-one-line-container-height: (48px, 44px, 40px, 36px, 32px, 24px),
3628
list-item-two-line-container-height: (64px, 60px, 56px, 52px, 48px, 48px),
3729
list-item-three-line-container-height: (88px, 84px, 80px, 76px, 72px, 56px),
3830
),
31+
(mdc, outlined-card): (),
32+
(mdc, outlined-text-field): (),
33+
(mdc, plain-tooltip): (),
34+
(mdc, radio): (
35+
state-layer-size: (40px, 36px, 32px, 28px),
36+
),
37+
(mdc, slider): (),
38+
(mdc, snackbar): (),
3939
(mdc, switch): (),
4040
(mdc, tab): (
4141
container-height: (48px, 44px, 40px, 36px, 32px)
@@ -44,19 +44,17 @@ $_density-tokens: (
4444

4545
// Custom Angular Material tokens
4646
(mat, card): (),
47+
(mat, divider): (),
4748
(mat, form-fild): (),
4849
(mat, grid-list): (),
4950
(mat, icon): (),
50-
(mat, toolbar): (
51-
standard-height: (64px, 60px, 56px, 52px),
52-
mobile-height: (56px, 52px, 48px, 44px),
53-
),
54-
(mat, slider): (),
55-
(mat, snack-bar): (),
51+
(mat, menu): (),
5652
(mat, radio): (),
5753
(mat, ripple): (),
5854
(mat, sidenav): (),
5955
(mat, slide-toggle): (),
56+
(mat, slider): (),
57+
(mat, snack-bar): (),
6058
(mat, sort): (),
6159
(mat, stepper): (
6260
header-height: (72px, 68px, 64px, 60px, 42px),
@@ -67,6 +65,10 @@ $_density-tokens: (
6765
footer-container-height: (52px, 48px, 44px, 40px, 36px),
6866
row-item-container-height: (52px, 48px, 44px, 40px, 36px),
6967
),
68+
(mat, toolbar): (
69+
standard-height: (64px, 60px, 56px, 52px),
70+
mobile-height: (56px, 52px, 48px, 44px),
71+
),
7072
(mat, tree): (
7173
node-min-height: (48px, 44px, 40px, 36px, 28px),
7274
),

src/material-experimental/theming/_m3-palettes.scss

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
1+
@use 'sass:color';
2+
@use 'sass:map';
3+
@use 'sass:math';
4+
5+
/// Estimate a hue using the given previous and next hues.
6+
@function _estimate-hue($hues, $hue, $prev-hue, $next-hue) {
7+
$weight: math.div($next-hue - $hue, $next-hue - $prev-hue) * 100%;
8+
@return color.mix(map.get($hues, $prev-hue), map.get($hues, $next-hue), $weight);
9+
}
10+
11+
// TODO(mmalerba): Remove this and add correct values for these hues.
12+
/// The Material Design spec references some neutral hues that are not generated by
13+
/// https://m3.material.io/theme-builder. For now we use this function to estimate the missing hues
14+
/// by blending the nearest hues that are generated.
15+
@function _patch-missing-hues($palette) {
16+
$neutral: map.get($palette, neutral);
17+
$palette: map.set($palette, neutral, 4, _estimate-hue($neutral, 4, 0, 10));
18+
$palette: map.set($palette, neutral, 6, _estimate-hue($neutral, 6, 0, 10));
19+
$palette: map.set($palette, neutral, 12, _estimate-hue($neutral, 12, 10, 20));
20+
$palette: map.set($palette, neutral, 17, _estimate-hue($neutral, 17, 10, 20));
21+
$palette: map.set($palette, neutral, 22, _estimate-hue($neutral, 22, 20, 25));
22+
$palette: map.set($palette, neutral, 24, _estimate-hue($neutral, 24, 20, 25));
23+
$palette: map.set($palette, neutral, 87, _estimate-hue($neutral, 87, 80, 90));
24+
$palette: map.set($palette, neutral, 92, _estimate-hue($neutral, 92, 90, 95));
25+
$palette: map.set($palette, neutral, 94, _estimate-hue($neutral, 94, 90, 95));
26+
$palette: map.set($palette, neutral, 96, _estimate-hue($neutral, 96, 95, 98));
27+
@return $palette;
28+
}
29+
130
/// Blue color palette to be used as primary, secondary, or tertiary palette.
2-
$blue-palette: (
31+
$blue-palette: _patch-missing-hues((
332
0: #000000,
433
10: #00006e,
534
20: #0001ac,
@@ -52,10 +81,10 @@ $blue-palette: (
5281
99: #fffbff,
5382
100: #ffffff,
5483
),
55-
);
84+
));
5685

5786
/// Cyan color palette to be used as primary, secondary, or tertiary palette.
58-
$cyan-palette: (
87+
$cyan-palette: _patch-missing-hues((
5988
0: #000000,
6089
10: #002020,
6190
20: #003737,
@@ -108,10 +137,10 @@ $cyan-palette: (
108137
99: #f4fefd,
109138
100: #ffffff,
110139
),
111-
);
140+
));
112141

113142
/// Green color palette to be used as primary, secondary, or tertiary palette.
114-
$green-palette: (
143+
$green-palette: _patch-missing-hues((
115144
0: #000000,
116145
10: #002200,
117146
20: #013a00,
@@ -164,10 +193,10 @@ $green-palette: (
164193
99: #f9fef1,
165194
100: #ffffff,
166195
),
167-
);
196+
));
168197

169198
/// Magenta color palette to be used as primary, secondary, or tertiary palette.
170-
$magenta-palette: (
199+
$magenta-palette: _patch-missing-hues((
171200
0: #000000,
172201
10: #380038,
173202
20: #5b005b,
@@ -220,10 +249,10 @@ $magenta-palette: (
220249
99: #fffbff,
221250
100: #ffffff,
222251
),
223-
);
252+
));
224253

225254
/// Orange color palette to be used as primary, secondary, or tertiary palette.
226-
$orange-palette: (
255+
$orange-palette: _patch-missing-hues((
227256
0: #000000,
228257
10: #311300,
229258
20: #502400,
@@ -276,10 +305,10 @@ $orange-palette: (
276305
99: #fffbff,
277306
100: #ffffff,
278307
),
279-
);
308+
));
280309

281310
/// Purple color palette to be used as primary, secondary, or tertiary palette.
282-
$purple-palette: (
311+
$purple-palette: _patch-missing-hues((
283312
0: #000000,
284313
10: #270057,
285314
20: #42008a,
@@ -332,10 +361,10 @@ $purple-palette: (
332361
99: #fffbff,
333362
100: #ffffff,
334363
),
335-
);
364+
));
336365

337366
/// Red color palette to be used as primary, secondary, or tertiary palette.
338-
$red-palette: (
367+
$red-palette: _patch-missing-hues((
339368
0: #000000,
340369
10: #410000,
341370
20: #690100,
@@ -388,10 +417,10 @@ $red-palette: (
388417
99: #fffbff,
389418
100: #ffffff,
390419
),
391-
);
420+
));
392421

393422
/// Yellow color palette to be used as primary, secondary, or tertiary palette.
394-
$yellow-palette: (
423+
$yellow-palette: _patch-missing-hues((
395424
0: #000000,
396425
10: #1d1d00,
397426
20: #323200,
@@ -444,4 +473,4 @@ $yellow-palette: (
444473
99: #fffbff,
445474
100: #ffffff,
446475
),
447-
);
476+
));

0 commit comments

Comments
 (0)