Skip to content

Commit 87e3ba7

Browse files
committed
fix(material-experimental/theming): Make M3 work with typography-hierarchy
1 parent b6e0b20 commit 87e3ba7

File tree

2 files changed

+129
-4
lines changed

2 files changed

+129
-4
lines changed

src/dev-app/theme-m3.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ html {
3939
// @include matx.popover-edit-theme($light-theme);
4040
}
4141

42-
// TODO(mmalerba): Support M3 for typography hierarchy.
43-
// @include mat.typography-hierarchy($light-theme);
42+
@include mat.typography-hierarchy($light-theme);
4443

4544
.demo-strong-focus {
4645
// Note: we can theme the indicators directly through `strong-focus-indicators` as well.
@@ -77,9 +76,10 @@ $density-scales: (-1, -2, -3, -4, minimum, maximum);
7776
}
7877
}
7978

80-
// Enable back-compat CSS for color="..." API.
79+
// Enable back-compat CSS for color="..." API & typography hierarchy.
8180
.demo-color-api-back-compat {
8281
@include matx.color-variants-back-compat($light-theme);
82+
@include mat.typography-hierarchy($light-theme, $back-compat: true);
8383

8484
&.demo-unicorn-dark-theme {
8585
@include matx.color-variants-back-compat($dark-theme);

src/material/core/typography/_typography.scss

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
@use 'sass:list';
2+
@use 'sass:map';
3+
@use 'sass:string';
14
@use 'typography-utils';
25
@use '../theming/inspection';
36
@use './versioning';
@@ -8,11 +11,133 @@
811
@forward './definition';
912
@forward './versioning';
1013

14+
@mixin typography-hierarchy($theme, $selector: '.mat-typography', $back-compat: false) {
15+
@if inspection.get-theme-version($theme) == 1 {
16+
@include _m3-typography-hierarchy($theme, $selector, $back-compat);
17+
}
18+
@else {
19+
@include _m2-typography-hierarchy($theme, $selector);
20+
}
21+
}
22+
23+
@function _get-selector($selectors, $prefix) {
24+
$result: ();
25+
@each $selector in $selectors {
26+
// Don't add "naked" tag selectors, and don't nest prefix selector.
27+
@if string.index($selector, '.') == 1 {
28+
$result: list.append($result, $selector, $separator: comma);
29+
}
30+
// Don't nest the prefix selector in itself.
31+
@if $selector != $prefix {
32+
$result: list.append($result, '#{$prefix} #{$selector}', $separator: comma);
33+
}
34+
}
35+
@return $result;
36+
}
37+
38+
@mixin _m3-typography-level($theme, $selector-prefix, $level, $selectors, $margin: null) {
39+
#{_get-selector($selectors, $selector-prefix)} {
40+
// TODO(mmalerba): When we expose system tokens as CSS vars, we should change this to emit token
41+
// slots.
42+
font: inspection.get-theme-typography($theme, $level, font);
43+
letter-spacing: inspection.get-theme-typography($theme, $level, letter-spacing);
44+
@if $margin != null {
45+
margin: 0 0 $margin;
46+
}
47+
}
48+
}
49+
50+
@mixin _m3-typography-hierarchy($theme, $selector-prefix, $add-m2-selectors) {
51+
$levels: (
52+
display-large: (
53+
selectors: ('.mat-display-large', 'h1'),
54+
m2-selectors: ('.mat-h1', '.mat-headline-1'),
55+
margin: 0.5em
56+
),
57+
display-medium: (
58+
selectors: ('.mat-display-medium', 'h2'),
59+
m2-selectors: ('.mat-h2', '.mat-headline-2'),
60+
margin: 0.5em
61+
),
62+
display-small: (
63+
selectors: ('.mat-display-small', 'h3'),
64+
m2-selectors: ('.mat-h3', '.mat-headline-3'),
65+
margin: 0.5em
66+
),
67+
headline-large: (
68+
selectors: ('.mat-headline-large', 'h4'),
69+
m2-selectors: ('.mat-h4', '.mat-headline-4'),
70+
margin: 0.5em
71+
),
72+
headline-medium: (
73+
selectors: ('.mat-headline-medium', 'h5'),
74+
m2-selectors: ('.mat-h5', '.mat-headline-5'),
75+
margin: 0.5em
76+
),
77+
headline-small: (
78+
selectors: ('.mat-headline-small', 'h6'),
79+
m2-selectors: ('.mat-h6', '.mat-headline-6'),
80+
margin: 0.5em
81+
),
82+
title-large: (
83+
selectors: ('.mat-title-large'),
84+
m2-selectors: ('.mat-subtitle-1'),
85+
),
86+
title-medium: (
87+
selectors: ('.mat-title-medium'),
88+
m2-selectors: ('.mat-subtitle-2'),
89+
),
90+
title-small: (
91+
selectors: ('.mat-title-small')
92+
),
93+
body-large: (
94+
selectors: ('.mat-body-large', $selector-prefix),
95+
m2-selectors: ('.mat-body', '.mat-body-strong', '.mat-body-2'),
96+
),
97+
body-medium: (
98+
selectors: ('.mat-body-medium')
99+
),
100+
body-small: (
101+
selectors: ('.mat-body-small')
102+
),
103+
label-large: (
104+
selectors: ('.mat-label-large')
105+
),
106+
label-medium: (
107+
selectors: ('.mat-label-medium')
108+
),
109+
label-small: (
110+
selectors: ('.mat-label-small'),
111+
m2-selectors: ('.mat-small', '.mat-caption')
112+
),
113+
);
114+
115+
@each $level, $options in $levels {
116+
@if $add-m2-selectors {
117+
$options: map.set($options, selectors,
118+
list.join(map.get($options, selectors), map.get($options, m2-selectors) or ()));
119+
}
120+
$options: map.remove($options, m2-selectors);
121+
122+
// Apply styles for the level.
123+
@include _m3-typography-level($theme, $selector-prefix, $level, $options...);
124+
125+
// Also style <p> inside body-large.
126+
@if $level == body-large {
127+
#{_get-selector(map.get($options, selectors), $selector-prefix)} {
128+
p {
129+
margin: 0 0 0.75em;
130+
}
131+
}
132+
}
133+
}
134+
}
135+
11136
/// Emits baseline typographic styles based on a given config.
12137
/// @param {Map} $config-or-theme A typography config for an entire theme.
13138
/// @param {String} $selector Ancestor selector under which native elements, such as h1, will
14139
/// be styled.
15-
@mixin typography-hierarchy($theme, $selector: '.mat-typography') {
140+
@mixin _m2-typography-hierarchy($theme, $selector) {
16141
// Note that it seems redundant to prefix the class rules with the `$selector`, however it's
17142
// necessary if we want to allow people to overwrite the tag selectors. This is due to
18143
// selectors like `#{$selector} h1` being more specific than ones like `.mat-title`.

0 commit comments

Comments
 (0)