Skip to content

Commit 186fe52

Browse files
committed
feat(material/card): support filled variant
this commit add `filled` variant for material card which provides subtle seperation from background and has less emphasis than elevated or outlined cards fixes #29840
1 parent 6ac4c1a commit 186fe52

File tree

10 files changed

+125
-2
lines changed

10 files changed

+125
-2
lines changed

goldens/material/card/index.api.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class MatCardActions {
3232
}
3333

3434
// @public (undocumented)
35-
export type MatCardAppearance = 'outlined' | 'raised';
35+
export type MatCardAppearance = 'outlined' | 'raised' | 'filled';
3636

3737
// @public
3838
export class MatCardAvatar {

src/material/card/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ sass_library(
1515
srcs = [
1616
"_m3-card.scss",
1717
"_m3-elevated-card.scss",
18+
"_m3-filled-card.scss",
1819
"_m3-outlined-card.scss",
1920
],
2021
deps = [
@@ -28,6 +29,7 @@ sass_library(
2829
srcs = [
2930
"_m2-card.scss",
3031
"_m2-elevated-card.scss",
32+
"_m2-filled-card.scss",
3133
"_m2-outlined-card.scss",
3234
],
3335
deps = [

src/material/card/_card-theme.scss

+26
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
@use './m2-card';
99
@use './m2-elevated-card';
1010
@use './m2-outlined-card';
11+
@use './m2-filled-card';
1112

1213
@mixin base($theme) {
1314
@if inspection.get-theme-version($theme) == 1 {
@@ -22,6 +23,10 @@
2223
m2-outlined-card.$prefix,
2324
m2-outlined-card.get-unthemable-tokens()
2425
);
26+
@include token-utils.create-token-values-mixed(
27+
m2-filled-card.$prefix,
28+
m2-filled-card.get-unthemable-tokens()
29+
);
2530
@include token-utils.create-token-values-mixed(
2631
m2-card.$prefix,
2732
m2-card.get-unthemable-tokens()
@@ -43,6 +48,10 @@
4348
m2-outlined-card.$prefix,
4449
m2-outlined-card.get-color-tokens($theme)
4550
);
51+
@include token-utils.create-token-values-mixed(
52+
m2-filled-card.$prefix,
53+
m2-filled-card.get-color-tokens($theme)
54+
);
4655
@include token-utils.create-token-values-mixed(
4756
m2-card.$prefix,
4857
m2-card.get-color-tokens($theme)
@@ -64,6 +73,10 @@
6473
m2-outlined-card.$prefix,
6574
m2-outlined-card.get-typography-tokens($theme)
6675
);
76+
@include token-utils.create-token-values-mixed(
77+
m2-filled-card.$prefix,
78+
m2-filled-card.get-typography-tokens($theme)
79+
);
6780
@include token-utils.create-token-values-mixed(
6881
m2-card.$prefix,
6982
m2-card.get-typography-tokens($theme)
@@ -85,6 +98,10 @@
8598
m2-outlined-card.$prefix,
8699
m2-outlined-card.get-density-tokens($theme)
87100
);
101+
@include token-utils.create-token-values-mixed(
102+
m2-filled-card.$prefix,
103+
m2-filled-card.get-density-tokens($theme)
104+
);
88105
@include token-utils.create-token-values-mixed(
89106
m2-card.$prefix,
90107
m2-card.get-density-tokens($theme)
@@ -110,6 +127,11 @@
110127
tokens: m2-outlined-card.get-token-slots(),
111128
prefix: 'outlined-',
112129
),
130+
(
131+
namespace: m2-filled-card.$prefix,
132+
tokens: m2-filled-card.get-token-slots(),
133+
prefix: 'filled-',
134+
)
113135
);
114136
}
115137

@@ -149,6 +171,10 @@
149171
m2-outlined-card.$prefix,
150172
map.get($tokens, m2-outlined-card.$prefix)
151173
);
174+
@include token-utils.create-token-values(
175+
m2-filled-card.$prefix,
176+
map.get($tokens, m2-filled-card.$prefix)
177+
);
152178
@include token-utils.create-token-values(
153179
m2-card.$prefix,
154180
map.get($tokens, m2-card.$prefix)
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
@use '../core/theming/inspection';
2+
@use '../core/style/elevation';
3+
@use '../core/style/sass-utils';
4+
@use '../core/tokens/m2-utils';
5+
6+
// The prefix used to generate the fully qualified name for tokens in this file.
7+
$prefix: (mat, card-filled);
8+
9+
// Tokens that can't be configured through Angular Material's current theming API,
10+
// but may be in a future version of the theming API.
11+
//
12+
// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`.
13+
// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in
14+
// our CSS.
15+
@function get-unthemable-tokens() {
16+
@return (
17+
container-shape: 4px,
18+
);
19+
}
20+
21+
// Tokens that can be configured through Angular Material's color theming API.
22+
@function get-color-tokens($theme) {
23+
$elevation: inspection.get-theme-color($theme, foreground, elevation);
24+
25+
@return (
26+
container-color: inspection.get-theme-color($theme, background, card),
27+
container-elevation: elevation.get-box-shadow(0),
28+
);
29+
}
30+
31+
// Tokens that can be configured through Angular Material's typography theming API.
32+
@function get-typography-tokens($theme) {
33+
@return ();
34+
}
35+
36+
// Tokens that can be configured through Angular Material's density theming API.
37+
@function get-density-tokens($theme) {
38+
@return ();
39+
}
40+
41+
// Combines the tokens generated by the above functions into a single map with placeholder values.
42+
// This is used to create token slots.
43+
@function get-token-slots() {
44+
@return sass-utils.deep-merge-all(
45+
get-unthemable-tokens(),
46+
get-color-tokens(m2-utils.$placeholder-color-config),
47+
get-typography-tokens(m2-utils.$placeholder-typography-config),
48+
get-density-tokens(m2-utils.$placeholder-density-config)
49+
);
50+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@use 'sass:map';
2+
@use '../core/style/elevation';
3+
@use '../core/tokens/m3-utils';
4+
5+
// The prefix used to generate the fully qualified name for tokens in this file.
6+
$prefix: (mat, card-filled);
7+
8+
/// Generates the tokens for MDC filled-card
9+
/// @param {Map} $systems The MDC system tokens
10+
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
11+
/// @param {Map} $token-slots Possible token slots
12+
/// @return {Map} A set of tokens for the MDC filled-card
13+
@function get-tokens($systems, $exclude-hardcoded, $token-slots) {
14+
$tokens: (
15+
container-color: map.get($systems, md-sys-color, surface-container-highest),
16+
container-elevation: map.get($systems, md-sys-elevation, level0),
17+
container-shape: map.get($systems, md-sys-shape, corner-medium),
18+
);
19+
20+
$elevation: map.get($tokens, container-elevation);
21+
22+
@if ($elevation != null) {
23+
$tokens: map.set($tokens, container-elevation, elevation.get-box-shadow($elevation));
24+
}
25+
26+
@return m3-utils.namespace($prefix, $tokens, $token-slots);
27+
}

src/material/card/card.scss

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
@use './m2-card';
33
@use './m2-elevated-card';
44
@use './m2-outlined-card';
5+
@use './m2-filled-card';
56

67
// Size of the `mat-card-header` region custom to Angular Material.
78
$mat-card-header-size: 40px !default;
@@ -62,6 +63,16 @@ $mat-card-default-padding: 16px !default;
6263
}
6364
}
6465

66+
.mat-mdc-card-filled {
67+
@include token-utils.use-tokens(
68+
m2-filled-card.$prefix, m2-filled-card.get-token-slots()
69+
) {
70+
background-color: token-utils.slot(container-color);
71+
border-radius: token-utils.slot(container-shape);
72+
box-shadow: token-utils.slot(container-elevation);
73+
}
74+
}
75+
6576
.mdc-card__media {
6677
position: relative;
6778
box-sizing: border-box;

src/material/card/card.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
inject,
1717
} from '@angular/core';
1818

19-
export type MatCardAppearance = 'outlined' | 'raised';
19+
export type MatCardAppearance = 'outlined' | 'raised' | 'filled';
2020

2121
/** Object that can be used to configure the default options for the card module. */
2222
export interface MatCardConfig {
@@ -41,6 +41,8 @@ export const MAT_CARD_CONFIG = new InjectionToken<MatCardConfig>('MAT_CARD_CONFI
4141
'class': 'mat-mdc-card mdc-card',
4242
'[class.mat-mdc-card-outlined]': 'appearance === "outlined"',
4343
'[class.mdc-card--outlined]': 'appearance === "outlined"',
44+
'[class.mat-mdc-card-filled]': 'appearance === "filled"',
45+
'[class.mdc-card--filled]': 'appearance === "filled"',
4446
},
4547
exportAs: 'matCard',
4648
encapsulation: ViewEncapsulation.None,

src/material/core/tokens/_density.scss

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ $_density-tokens: (
4444
touch-target-display: (block, block, none, none),
4545
container-height: (40px, 36px, 32px, 28px),
4646
),
47+
(mat, filled-card): (),
4748
(mat, filled-text-field): (),
4849
(mat, form-field): (
4950
container-height: (56px, 52px, 48px, 44px, 40px, 36px),

src/material/core/tokens/_m2-tokens.scss

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
@use '../../button/m2-tonal-button';
1616
@use '../../card/m2-card';
1717
@use '../../card/m2-elevated-card';
18+
@use '../../card/m2-filled-card';
1819
@use '../../card/m2-outlined-card';
1920
@use '../../checkbox/m2-checkbox';
2021
@use '../../chips/m2-chip';
@@ -116,6 +117,7 @@
116117
_get-tokens-for-module($theme, m2-fab),
117118
_get-tokens-for-module($theme, m2-fab-small),
118119
_get-tokens-for-module($theme, m2-filled-button),
120+
_get-tokens-for-module($theme, m2-filled-card),
119121
_get-tokens-for-module($theme, m2-filled-text-field),
120122
_get-tokens-for-module($theme, m2-form-field),
121123
_get-tokens-for-module($theme, m2-full-pseudo-checkbox),

src/material/core/tokens/_m3-tokens.scss

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
@use '../../button/m3-fab';
77
@use '../../button/m3-fab-small';
88
@use '../../button/m3-filled-button';
9+
@use '../../card/m3-filled-card';
910
@use '../../button/m3-icon-button';
1011
@use '../../button/m3-outlined-button';
1112
@use '../../button/m3-protected-button';
@@ -441,6 +442,7 @@ $system-variables-prefix) {
441442
m3-fab-small.get-tokens($systems, $exclude-hardcoded, $token-slots),
442443
m3-fab.get-tokens($systems, $exclude-hardcoded, $token-slots),
443444
m3-filled-button.get-tokens($systems, $exclude-hardcoded, $token-slots),
445+
m3-filled-card.get-tokens($systems, $exclude-hardcoded, $token-slots),
444446
m3-filled-text-field.get-tokens($systems, $exclude-hardcoded, $token-slots),
445447
m3-form-field.get-tokens($systems, $exclude-hardcoded, $token-slots),
446448
m3-full-pseudo-checkbox.get-tokens($systems, $exclude-hardcoded, $token-slots),

0 commit comments

Comments
 (0)