Skip to content

Commit 07225d2

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 371446a commit 07225d2

File tree

8 files changed

+155
-4
lines changed

8 files changed

+155
-4
lines changed

src/material/card/_card-theme.scss

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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 '../core/tokens/m2/mdc/filled-card' as tokens-mdc-filled-card;
1112

1213
@mixin base($theme) {
1314
@if inspection.get-theme-version($theme) == 1 {
@@ -22,6 +23,10 @@
2223
tokens-mdc-outlined-card.$prefix,
2324
tokens-mdc-outlined-card.get-unthemable-tokens()
2425
);
26+
@include token-utils.create-token-values(
27+
tokens-mdc-filled-card.$prefix,
28+
tokens-mdc-filled-card.get-unthemable-tokens()
29+
);
2530
@include token-utils.create-token-values(
2631
tokens-mat-card.$prefix,
2732
tokens-mat-card.get-unthemable-tokens()
@@ -43,6 +48,10 @@
4348
tokens-mdc-outlined-card.$prefix,
4449
tokens-mdc-outlined-card.get-color-tokens($theme)
4550
);
51+
@include token-utils.create-token-values(
52+
tokens-mdc-filled-card.$prefix,
53+
tokens-mdc-filled-card.get-color-tokens($theme)
54+
);
4655
@include token-utils.create-token-values(
4756
tokens-mat-card.$prefix,
4857
tokens-mat-card.get-color-tokens($theme)
@@ -64,6 +73,10 @@
6473
tokens-mdc-outlined-card.$prefix,
6574
tokens-mdc-outlined-card.get-typography-tokens($theme)
6675
);
76+
@include token-utils.create-token-values(
77+
tokens-mdc-filled-card.$prefix,
78+
tokens-mdc-filled-card.get-typography-tokens($theme)
79+
);
6780
@include token-utils.create-token-values(
6881
tokens-mat-card.$prefix,
6982
tokens-mat-card.get-typography-tokens($theme)
@@ -85,6 +98,14 @@
8598
tokens-mdc-outlined-card.$prefix,
8699
tokens-mdc-outlined-card.get-density-tokens($theme)
87100
);
101+
@include token-utils.create-token-values(
102+
tokens-mdc-outlined-card.$prefix,
103+
tokens-mdc-outlined-card.get-density-tokens($theme)
104+
);
105+
@include token-utils.create-token-values(
106+
tokens-mdc-filled-card.$prefix,
107+
tokens-mdc-filled-card.get-density-tokens($theme)
108+
);
88109
@include token-utils.create-token-values(
89110
tokens-mat-card.$prefix,
90111
tokens-mat-card.get-density-tokens($theme)
@@ -109,6 +130,11 @@
109130
namespace: tokens-mdc-outlined-card.$prefix,
110131
tokens: tokens-mdc-outlined-card.get-token-slots(),
111132
prefix: 'outlined-',
133+
),
134+
(
135+
namespace: tokens-mdc-filled-card.$prefix,
136+
tokens: tokens-mdc-filled-card.get-token-slots(),
137+
prefix: 'outlined-',
112138
)
113139
);
114140
}
@@ -145,6 +171,10 @@
145171
tokens-mdc-outlined-card.$prefix,
146172
map.get($tokens, tokens-mdc-outlined-card.$prefix)
147173
);
174+
@include token-utils.create-token-values(
175+
tokens-mdc-filled-card.$prefix,
176+
map.get($tokens, tokens-mdc-filled-card.$prefix)
177+
);
148178
@include token-utils.create-token-values(
149179
tokens-mat-card.$prefix,
150180
map.get($tokens, tokens-mat-card.$prefix)

src/material/card/card.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
@use '../core/tokens/m2/mat/card' as tokens-mat-card;
33
@use '../core/tokens/m2/mdc/elevated-card' as tokens-mdc-elevated-card;
44
@use '../core/tokens/m2/mdc/outlined-card' as tokens-mdc-outlined-card;
5+
@use '../core/tokens/m2/mdc/filled-card' as tokens-mdc-filled-card;
56

67
// Size of the `mat-card-header` region custom to Angular Material.
78
$mat-card-header-size: 40px !default;
@@ -68,6 +69,17 @@ $mat-card-default-padding: 16px !default;
6869
}
6970
}
7071

72+
.mat-mdc-card-filled {
73+
@include token-utils.use-tokens(
74+
tokens-mdc-filled-card.$prefix,
75+
tokens-mdc-filled-card.get-token-slots()
76+
) {
77+
@include token-utils.create-token-slot(background-color, container-color);
78+
@include token-utils.create-token-slot(border-radius, container-shape);
79+
@include token-utils.create-token-slot(box-shadow, container-elevation);
80+
}
81+
}
82+
7183
.mdc-card__media {
7284
position: relative;
7385
box-sizing: border-box;

src/material/card/card.ts

Lines changed: 3 additions & 1 deletion
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/m2/_index.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
@use './mdc/switch' as tokens-mdc-switch;
7171
@use './mdc/secondary-navigation-tab' as tokens-mdc-secondary-navigation-tab;
7272
@use './mdc/tab-indicator' as tokens-mdc-tab-indicator;
73+
@use './mdc/filled-card' as tokens-mdc-filled-card;
7374
@use '../../theming/inspection';
7475

7576
/// Gets the tokens for the given theme, m2 tokens module, and theming system.
@@ -182,6 +183,7 @@
182183
_get-tokens-for-module($theme, tokens-mdc-switch),
183184
_get-tokens-for-module($theme, tokens-mdc-tab-indicator),
184185
_get-tokens-for-module($theme, tokens-mdc-secondary-navigation-tab),
185-
_get-tokens-for-module($theme, tokens-mdc-text-button)
186+
_get-tokens-for-module($theme, tokens-mdc-text-button),
187+
_get-tokens-for-module($theme, tokens-mdc-filled-card),
186188
);
187189
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
@use '../../../style/elevation';
2+
@use '../../../theming/inspection';
3+
@use '../../../style/sass-utils';
4+
@use '../../token-definition';
5+
6+
// The prefix used to generate the fully qualified name for tokens in this file.
7+
$prefix: (mdc, filled-card);
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+
// The border-radius of the card.
18+
container-shape: 4px,
19+
// =============================================================================================
20+
// = TOKENS NOT USED IN ANGULAR MATERIAL =
21+
// =============================================================================================
22+
// Angular Material's card is not an interactive element, and therefore does not support states.
23+
disabled-container-elevation: null,
24+
disabled-outline-color: null,
25+
disabled-outline-opacity: null,
26+
dragged-container-elevation: null,
27+
dragged-outline-color: null,
28+
dragged-state-layer-color: null,
29+
dragged-state-layer-opacity: null,
30+
focus-container-elevation: null,
31+
focus-outline-color: null,
32+
focus-state-layer-color: null,
33+
focus-state-layer-opacity: null,
34+
hover-container-elevation: null,
35+
hover-outline-color: null,
36+
hover-state-layer-color: null,
37+
hover-state-layer-opacity: null,
38+
pressed-container-elevation: null,
39+
pressed-outline-color: null,
40+
pressed-state-layer-color: null,
41+
pressed-state-layer-opacity: null,
42+
container-shadow-color: null,
43+
// Angular Material does not currently support surface tint.
44+
container-surface-tint-layer-color: null,
45+
// MDC does not seem to use these tokens.
46+
icon-color: null,
47+
icon-size: null,
48+
);
49+
}
50+
51+
// Tokens that can be configured through Angular Material's color theming API.
52+
@function get-color-tokens($theme) {
53+
$elevation: inspection.get-theme-color($theme, foreground, elevation);
54+
55+
@return (
56+
// The background color of the card.
57+
container-color: inspection.get-theme-color($theme, background, card),
58+
container-elevation: elevation.get-box-shadow(0),
59+
);
60+
}
61+
62+
// Tokens that can be configured through Angular Material's typography theming API.
63+
@function get-typography-tokens($theme) {
64+
@return ();
65+
}
66+
67+
// Tokens that can be configured through Angular Material's density theming API.
68+
@function get-density-tokens($theme) {
69+
@return ();
70+
}
71+
72+
// Combines the tokens generated by the above functions into a single map with placeholder values.
73+
// This is used to create token slots.
74+
@function get-token-slots() {
75+
@return sass-utils.deep-merge-all(
76+
get-unthemable-tokens(),
77+
get-color-tokens(token-definition.$placeholder-color-config),
78+
get-typography-tokens(token-definition.$placeholder-typography-config),
79+
get-density-tokens(token-definition.$placeholder-density-config)
80+
);
81+
}

src/material/core/tokens/m3/_index.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
@use './mdc/switch' as tokens-mdc-switch;
6969
@use './mdc/secondary-navigation-tab' as tokens-mdc-secondary-navigation-tab;
7070
@use './mdc/tab-indicator' as tokens-mdc-tab-indicator;
71+
@use './mdc/filled-card' as tokens-mdc-filled-card;
7172

7273
$_module-names: (
7374
// Custom tokens
@@ -140,7 +141,8 @@ $_module-names: (
140141
tokens-mdc-snack-bar,
141142
tokens-mdc-switch,
142143
tokens-mdc-secondary-navigation-tab,
143-
tokens-mdc-tab-indicator
144+
tokens-mdc-tab-indicator,
145+
tokens-mdc-filled-card,
144146
);
145147

146148
/// Gets the full set of M3 tokens for the given theme object.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@use 'sass:map';
2+
@use '../../../style/elevation';
3+
@use '../../token-definition';
4+
5+
// The prefix used to generate the fully qualified name for tokens in this file.
6+
$prefix: (mdc, filled-card);
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: token-definition.get-mdc-tokens('filled-card', $systems, $exclude-hardcoded);
15+
$elevation: map.get($tokens, container-elevation);
16+
17+
@if ($elevation != null) {
18+
$tokens: map.set($tokens, container-elevation, elevation.get-box-shadow($elevation));
19+
}
20+
21+
@return token-definition.namespace-tokens($prefix, $tokens, $token-slots);
22+
}

tools/public_api_guard/material/card.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export class MatCardActions {
3333
}
3434

3535
// @public (undocumented)
36-
export type MatCardAppearance = 'outlined' | 'raised';
36+
export type MatCardAppearance = 'outlined' | 'raised' | 'filled';
3737

3838
// @public
3939
export class MatCardAvatar {

0 commit comments

Comments
 (0)