Skip to content

Commit 1675ce6

Browse files
committed
refactor(material/card): simplify structural styles (#29325)
Simplifies the structural styles for the card to make them smaller and easier to maintain. (cherry picked from commit 2191cae)
1 parent 8339155 commit 1675ce6

File tree

6 files changed

+149
-129
lines changed

6 files changed

+149
-129
lines changed

src/material/card/_card-theme.scss

Lines changed: 25 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@
88
@use '../core/tokens/m2/mat/card' as tokens-mat-card;
99
@use '../core/tokens/m2/mdc/elevated-card' as tokens-mdc-elevated-card;
1010
@use '../core/tokens/m2/mdc/outlined-card' as tokens-mdc-outlined-card;
11-
@use '@material/card/elevated-card-theme' as mdc-elevated-card-theme;
12-
@use '@material/card/outlined-card-theme' as mdc-outlined-card-theme;
1311

1412
@mixin base($theme) {
1513
@if inspection.get-theme-version($theme) == 1 {
1614
@include _theme-from-tokens(inspection.get-theme-tokens($theme, base));
1715
}
1816
@else {
1917
@include sass-utils.current-selector-or-root() {
20-
@include mdc-elevated-card-theme.theme(tokens-mdc-elevated-card.get-unthemable-tokens());
21-
@include mdc-outlined-card-theme.theme(tokens-mdc-outlined-card.get-unthemable-tokens());
18+
@include token-utils.create-token-values(
19+
tokens-mdc-elevated-card.$prefix, tokens-mdc-elevated-card.get-unthemable-tokens());
20+
@include token-utils.create-token-values(
21+
tokens-mdc-outlined-card.$prefix, tokens-mdc-outlined-card.get-unthemable-tokens());
2222
@include token-utils.create-token-values(
2323
tokens-mat-card.$prefix, tokens-mat-card.get-unthemable-tokens());
2424
}
@@ -30,23 +30,13 @@
3030
@include _theme-from-tokens(inspection.get-theme-tokens($theme, color));
3131
}
3232
@else {
33-
$mdc-elevated-card-color-tokens: token-utils.resolve-elevation(
34-
tokens-mdc-elevated-card.get-color-tokens($theme),
35-
container-elevation,
36-
container-shadow-color
37-
);
38-
$mdc-outlined-card-color-tokens: token-utils.resolve-elevation(
39-
tokens-mdc-outlined-card.get-color-tokens($theme),
40-
container-elevation,
41-
container-shadow-color,
42-
);
43-
$mat-card-color-tokens: tokens-mat-card.get-color-tokens($theme);
44-
45-
// Add values for card tokens.
4633
@include sass-utils.current-selector-or-root() {
47-
@include mdc-elevated-card-theme.theme($mdc-elevated-card-color-tokens);
48-
@include mdc-outlined-card-theme.theme($mdc-outlined-card-color-tokens);
49-
@include token-utils.create-token-values(tokens-mat-card.$prefix, $mat-card-color-tokens);
34+
@include token-utils.create-token-values(tokens-mdc-elevated-card.$prefix,
35+
tokens-mdc-elevated-card.get-color-tokens($theme));
36+
@include token-utils.create-token-values(tokens-mdc-outlined-card.$prefix,
37+
tokens-mdc-outlined-card.get-color-tokens($theme));
38+
@include token-utils.create-token-values(tokens-mat-card.$prefix,
39+
tokens-mat-card.get-color-tokens($theme));
5040
}
5141
}
5242
}
@@ -56,16 +46,13 @@
5646
@include _theme-from-tokens(inspection.get-theme-tokens($theme, typography));
5747
}
5848
@else {
59-
$mdc-elevated-card-typography-tokens: tokens-mdc-elevated-card.get-typography-tokens($theme);
60-
$mdc-outlined-card-typography-tokens: tokens-mdc-outlined-card.get-typography-tokens($theme);
61-
$mat-card-typography-tokens: tokens-mat-card.get-typography-tokens($theme);
62-
63-
// Add values for card tokens.
6449
@include sass-utils.current-selector-or-root() {
65-
@include mdc-elevated-card-theme.theme($mdc-elevated-card-typography-tokens);
66-
@include mdc-outlined-card-theme.theme($mdc-outlined-card-typography-tokens);
6750
@include token-utils.create-token-values(
68-
tokens-mat-card.$prefix, $mat-card-typography-tokens);
51+
tokens-mdc-elevated-card.$prefix, tokens-mdc-elevated-card.get-typography-tokens($theme));
52+
@include token-utils.create-token-values(
53+
tokens-mdc-outlined-card.$prefix, tokens-mdc-outlined-card.get-typography-tokens($theme));
54+
@include token-utils.create-token-values(
55+
tokens-mat-card.$prefix, tokens-mat-card.get-typography-tokens($theme));
6956
}
7057
}
7158
}
@@ -75,15 +62,13 @@
7562
@include _theme-from-tokens(inspection.get-theme-tokens($theme, density));
7663
}
7764
@else {
78-
$mdc-elevated-card-density-tokens: tokens-mdc-elevated-card.get-density-tokens($theme);
79-
$mdc-outlined-card-density-tokens: tokens-mdc-outlined-card.get-density-tokens($theme);
80-
$mat-card-density-tokens: tokens-mat-card.get-density-tokens($theme);
81-
82-
// Add values for card tokens.
8365
@include sass-utils.current-selector-or-root() {
84-
@include mdc-elevated-card-theme.theme($mdc-elevated-card-density-tokens);
85-
@include mdc-outlined-card-theme.theme($mdc-outlined-card-density-tokens);
86-
@include token-utils.create-token-values(tokens-mat-card.$prefix, $mat-card-density-tokens);
66+
@include token-utils.create-token-values(tokens-mdc-elevated-card.$prefix,
67+
tokens-mdc-elevated-card.get-density-tokens($theme));
68+
@include token-utils.create-token-values(tokens-mdc-outlined-card.$prefix,
69+
tokens-mdc-outlined-card.get-density-tokens($theme));
70+
@include token-utils.create-token-values(tokens-mat-card.$prefix,
71+
tokens-mat-card.get-density-tokens($theme));
8772
}
8873
}
8974
}
@@ -121,22 +106,10 @@
121106
@include validation.selector-defined(
122107
'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector');
123108
@if ($tokens != ()) {
124-
$elevated-card-tokens: map.get($tokens, tokens-mdc-elevated-card.$prefix);
125-
// Work around a bug in MDC where the elevation is not resolved to an actual shadow value.
126-
$elevated-card-tokens: token-utils.resolve-elevation(
127-
$elevated-card-tokens,
128-
container-elevation,
129-
container-shadow-color
130-
);
131-
$outlined-card-tokens: map.get($tokens, tokens-mdc-outlined-card.$prefix);
132-
// Work around a bug in MDC where the elevation is not resolved to an actual shadow value.
133-
$outlined-card-tokens: token-utils.resolve-elevation(
134-
$outlined-card-tokens,
135-
container-elevation,
136-
container-shadow-color
137-
);
138-
@include mdc-elevated-card-theme.theme($elevated-card-tokens);
139-
@include mdc-outlined-card-theme.theme($outlined-card-tokens);
109+
@include token-utils.create-token-values(
110+
tokens-mdc-elevated-card.$prefix, map.get($tokens, tokens-mdc-elevated-card.$prefix));
111+
@include token-utils.create-token-values(
112+
tokens-mdc-outlined-card.$prefix, map.get($tokens, tokens-mdc-outlined-card.$prefix));
140113
@include token-utils.create-token-values(
141114
tokens-mat-card.$prefix, map.get($tokens, tokens-mat-card.$prefix));
142115
}

src/material/card/card.scss

Lines changed: 100 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,123 @@
1-
@use 'sass:map';
2-
@use '@material/card' as mdc-card;
3-
@use '@material/card/elevated-card-theme' as mdc-elevated-card-theme;
4-
@use '@material/card/outlined-card-theme' as mdc-outlined-card-theme;
5-
@use '@material/theme/custom-properties' as mdc-custom-properties;
61
@use '../core/tokens/token-utils';
72
@use '../core/tokens/m2/mat/card' as tokens-mat-card;
83
@use '../core/tokens/m2/mdc/elevated-card' as tokens-mdc-elevated-card;
94
@use '../core/tokens/m2/mdc/outlined-card' as tokens-mdc-outlined-card;
105

11-
// TODO(jelbourn): move header and title-group styles to their own files.
12-
@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
13-
$mdc-elevated-card-token-slots: tokens-mdc-elevated-card.get-token-slots();
14-
$mdc-outlined-card-token-slots: tokens-mdc-outlined-card.get-token-slots();
6+
// Size of the `mat-card-header` region custom to Angular Material.
7+
$mat-card-header-size: 40px !default;
8+
9+
// Default padding for text content within a card.
10+
$mat-card-default-padding: 16px !default;
1511

16-
// Add the MDC card static styles.
17-
@include mdc-card.static-styles();
12+
.mat-mdc-card {
13+
display: flex;
14+
flex-direction: column;
15+
box-sizing: border-box;
16+
position: relative;
17+
border-style: solid;
18+
border-width: 0;
19+
20+
@include token-utils.use-tokens(
21+
tokens-mdc-elevated-card.$prefix,
22+
tokens-mdc-elevated-card.get-token-slots()
23+
) {
24+
@include token-utils.create-token-slot(background-color, container-color);
25+
@include token-utils.create-token-slot(border-color, container-color);
26+
@include token-utils.create-token-slot(border-radius, container-shape);
27+
@include token-utils.create-token-slot(box-shadow, container-elevation);
28+
}
1829

19-
.mat-mdc-card {
20-
// Add the official slots for the MDC elevated-card.
21-
@include mdc-elevated-card-theme.theme-styles(map.merge($mdc-elevated-card-token-slots, (
22-
// MDC emits the box-shadow on .mdc-card, so the full selector would be
23-
// `.mat-mdc-card .mdc-card` which is incorrect. We emit the elevation slot ourselves instead.
24-
container-elevation: null,
25-
container-shadow-color: null,
26-
)));
30+
// Transparent card border for high-contrast mode.
31+
&::after {
32+
position: absolute;
33+
top: 0;
34+
left: 0;
35+
width: 100%;
36+
height: 100%;
37+
border: solid 1px transparent;
38+
content: '';
39+
display: block;
40+
pointer-events: none;
41+
box-sizing: border-box;
2742

28-
// Emit the elevation slot directly on .mat-mdc-card.
2943
@include token-utils.use-tokens(
30-
tokens-mdc-elevated-card.$prefix, $mdc-elevated-card-token-slots) {
31-
@include token-utils.create-token-slot(box-shadow, container-elevation);
44+
tokens-mdc-elevated-card.$prefix,
45+
tokens-mdc-elevated-card.get-token-slots()
46+
) {
47+
@include token-utils.create-token-slot(border-radius, container-shape);
3248
}
3349
}
50+
}
3451

35-
.mat-mdc-card-outlined {
36-
// Add the official slots for the MDC outlined-card.
37-
@include mdc-outlined-card-theme.theme-styles(map.merge($mdc-outlined-card-token-slots, (
38-
// MDC emits the box-shadow on .mdc-card, so the full selector would be
39-
// `.mat-mdc-card-outlined .mdc-card` which is incorrect. We emit the elevation slot ourselves
40-
// instead.
41-
container-elevation: null,
42-
container-shadow-color: null,
43-
)));
44-
45-
// Emit the elevation slot directly on .mat-mdc-card-outlined.
46-
@include token-utils.use-tokens(
47-
tokens-mdc-outlined-card.$prefix, $mdc-outlined-card-token-slots) {
48-
@include token-utils.create-token-slot(box-shadow, container-elevation);
49-
}
52+
.mat-mdc-card-outlined {
53+
@include token-utils.use-tokens(
54+
tokens-mdc-outlined-card.$prefix,
55+
tokens-mdc-outlined-card.get-token-slots()
56+
) {
57+
@include token-utils.create-token-slot(background-color, container-color);
58+
@include token-utils.create-token-slot(border-radius, container-shape);
59+
@include token-utils.create-token-slot(border-width, outline-width);
60+
@include token-utils.create-token-slot(border-color, outline-color);
61+
@include token-utils.create-token-slot(box-shadow, container-elevation);
5062
}
5163

52-
// Add slots for custom Angular Material card tokens.
53-
@include token-utils.use-tokens(tokens-mat-card.$prefix, tokens-mat-card.get-token-slots()) {
54-
.mat-mdc-card-title {
55-
@include token-utils.create-token-slot(font-family, title-text-font);
56-
@include token-utils.create-token-slot(line-height, title-text-line-height);
57-
@include token-utils.create-token-slot(font-size, title-text-size);
58-
@include token-utils.create-token-slot(letter-spacing, title-text-tracking);
59-
@include token-utils.create-token-slot(font-weight, title-text-weight);
60-
}
64+
// Outlined card already displays border in high-contrast mode.
65+
// Overwriting styles set above to remove a duplicate border.
66+
&::after {
67+
border: none;
68+
}
69+
}
6170

62-
.mat-mdc-card-subtitle {
63-
@include token-utils.create-token-slot(color, subtitle-text-color);
64-
@include token-utils.create-token-slot(font-family, subtitle-text-font);
65-
@include token-utils.create-token-slot(line-height, subtitle-text-line-height);
66-
@include token-utils.create-token-slot(font-size, subtitle-text-size);
67-
@include token-utils.create-token-slot(letter-spacing, subtitle-text-tracking);
68-
@include token-utils.create-token-slot(font-weight, subtitle-text-weight);
69-
}
71+
.mdc-card__media {
72+
position: relative;
73+
box-sizing: border-box;
74+
background-repeat: no-repeat;
75+
background-position: center;
76+
background-size: cover;
77+
78+
&::before {
79+
display: block;
80+
content: '';
81+
}
82+
83+
&:first-child {
84+
border-top-left-radius: inherit;
85+
border-top-right-radius: inherit;
86+
}
87+
88+
&:last-child {
89+
border-bottom-left-radius: inherit;
90+
border-bottom-right-radius: inherit;
7091
}
7192
}
7293

73-
// Size of the `mat-card-header` region custom to Angular Material.
74-
$mat-card-header-size: 40px !default;
94+
.mat-mdc-card-actions {
95+
display: flex;
96+
flex-direction: row;
97+
align-items: center;
98+
box-sizing: border-box;
99+
min-height: 52px;
100+
padding: 8px;
101+
}
75102

76-
// Default padding for text content within a card.
77-
$mat-card-default-padding: 16px !default;
103+
// Add slots for custom Angular Material card tokens.
104+
@include token-utils.use-tokens(tokens-mat-card.$prefix, tokens-mat-card.get-token-slots()) {
105+
.mat-mdc-card-title {
106+
@include token-utils.create-token-slot(font-family, title-text-font);
107+
@include token-utils.create-token-slot(line-height, title-text-line-height);
108+
@include token-utils.create-token-slot(font-size, title-text-size);
109+
@include token-utils.create-token-slot(letter-spacing, title-text-tracking);
110+
@include token-utils.create-token-slot(font-weight, title-text-weight);
111+
}
78112

79-
.mat-mdc-card {
80-
position: relative;
113+
.mat-mdc-card-subtitle {
114+
@include token-utils.create-token-slot(color, subtitle-text-color);
115+
@include token-utils.create-token-slot(font-family, subtitle-text-font);
116+
@include token-utils.create-token-slot(line-height, subtitle-text-line-height);
117+
@include token-utils.create-token-slot(font-size, subtitle-text-size);
118+
@include token-utils.create-token-slot(letter-spacing, subtitle-text-tracking);
119+
@include token-utils.create-token-slot(font-weight, subtitle-text-weight);
120+
}
81121
}
82122

83123
// Title text and subtitles text within a card. MDC doesn't have pre-made title sections for cards.

src/material/core/tokens/m2/mdc/_elevated-card.scss

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@use '../../../style/elevation';
1+
@use '@material/elevation/elevation-theme' as mdc-elevation;
22
@use '../../../theming/inspection';
33
@use '../../../style/sass-utils';
44
@use '../../token-utils';
@@ -35,6 +35,7 @@ $prefix: (mdc, elevated-card);
3535
pressed-container-elevation: null,
3636
pressed-state-layer-color: null,
3737
pressed-state-layer-opacity: null,
38+
container-shadow-color: null,
3839
// Angular Material does not currently support surface tint.
3940
container-surface-tint-layer-color: null,
4041
// MDC does not seem to use these tokens.
@@ -50,12 +51,7 @@ $prefix: (mdc, elevated-card);
5051
@return (
5152
// The background color of the card.
5253
container-color: inspection.get-theme-color($theme, background, card),
53-
// The elevation level of the card.
54-
// (Part of the color tokens because it needs to be combined with the shadow color to generate
55-
// the final box-shadow).
56-
container-elevation: 1,
57-
// The color of the card's shadow.
58-
container-shadow-color: if($elevation != null, $elevation, elevation.$color),
54+
container-elevation: mdc-elevation.elevation-box-shadow(1),
5955
);
6056
}
6157

src/material/core/tokens/m2/mdc/_outlined-card.scss

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@use '@material/elevation/elevation-theme' as mdc-elevation;
12
@use '../../../style/elevation';
23
@use '../../../theming/inspection';
34
@use '../../../style/sass-utils';
@@ -41,6 +42,7 @@ $prefix: (mdc, outlined-card);
4142
pressed-outline-color: null,
4243
pressed-state-layer-color: null,
4344
pressed-state-layer-opacity: null,
45+
container-shadow-color: null,
4446
// Angular Material does not currently support surface tint.
4547
container-surface-tint-layer-color: null,
4648
// MDC does not seem to use these tokens.
@@ -58,12 +60,7 @@ $prefix: (mdc, outlined-card);
5860
container-color: inspection.get-theme-color($theme, background, card),
5961
// The border color of the card.
6062
outline-color: rgba(inspection.get-theme-color($theme, foreground, base), 0.12),
61-
// The elevation level of the card.
62-
// (Part of the color tokens because it needs to be combined with the shadow color to generate
63-
// the final box-shadow).
64-
container-elevation: 0,
65-
// The color of the card's shadow.
66-
container-shadow-color: if($elevation != null, $elevation, elevation.$color),
63+
container-elevation: mdc-elevation.elevation-box-shadow(0),
6764
);
6865
}
6966

src/material/core/tokens/m3/mdc/_elevated-card.scss

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@use 'sass:map';
2+
@use '@material/elevation/elevation-theme' as mdc-elevation;
13
@use '../../token-utils';
24

35
// The prefix used to generate the fully qualified name for tokens in this file.
@@ -9,7 +11,12 @@ $prefix: (mdc, elevated-card);
911
/// @param {Map} $token-slots Possible token slots
1012
/// @return {Map} A set of tokens for the MDC elevated-card
1113
@function get-tokens($systems, $exclude-hardcoded, $token-slots) {
12-
$mdc-tokens: token-utils.get-mdc-tokens('elevated-card', $systems, $exclude-hardcoded);
14+
$tokens: token-utils.get-mdc-tokens('elevated-card', $systems, $exclude-hardcoded);
15+
$elevation: map.get($tokens, container-elevation);
1316

14-
@return token-utils.namespace-tokens($prefix, $mdc-tokens, $token-slots);
17+
@if ($elevation != null) {
18+
$tokens: map.set($tokens, container-elevation, mdc-elevation.elevation-box-shadow($elevation));
19+
}
20+
21+
@return token-utils.namespace-tokens($prefix, $tokens, $token-slots);
1522
}

0 commit comments

Comments
 (0)