Skip to content

Commit 2ed91fa

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 f8ba137 commit 2ed91fa

File tree

8 files changed

+119
-2
lines changed

8 files changed

+119
-2
lines changed

goldens/material/card/index.api.md

Lines changed: 1 addition & 1 deletion
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/_card-theme.scss

Lines changed: 22 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/mat/elevated-card' as tokens-mat-elevated-card;
1010
@use '../core/tokens/m2/mat/outlined-card' as tokens-mat-outlined-card;
11+
@use '../core/tokens/m2/mat/filled-card' as tokens-mat-filled-card;
1112

1213
@mixin base($theme) {
1314
@if inspection.get-theme-version($theme) == 1 {
@@ -22,6 +23,10 @@
2223
tokens-mat-outlined-card.$prefix,
2324
tokens-mat-outlined-card.get-unthemable-tokens()
2425
);
26+
@include token-utils.create-token-values-mixed(
27+
tokens-mat-filled-card.$prefix,
28+
tokens-mat-filled-card.get-unthemable-tokens()
29+
);
2530
@include token-utils.create-token-values-mixed(
2631
tokens-mat-card.$prefix,
2732
tokens-mat-card.get-unthemable-tokens()
@@ -43,6 +48,10 @@
4348
tokens-mat-outlined-card.$prefix,
4449
tokens-mat-outlined-card.get-color-tokens($theme)
4550
);
51+
@include token-utils.create-token-values-mixed(
52+
tokens-mat-filled-card.$prefix,
53+
tokens-mat-filled-card.get-color-tokens($theme)
54+
);
4655
@include token-utils.create-token-values-mixed(
4756
tokens-mat-card.$prefix,
4857
tokens-mat-card.get-color-tokens($theme)
@@ -64,6 +73,10 @@
6473
tokens-mat-outlined-card.$prefix,
6574
tokens-mat-outlined-card.get-typography-tokens($theme)
6675
);
76+
@include token-utils.create-token-values-mixed(
77+
tokens-mat-filled-card.$prefix,
78+
tokens-mat-filled-card.get-typography-tokens($theme)
79+
);
6780
@include token-utils.create-token-values-mixed(
6881
tokens-mat-card.$prefix,
6982
tokens-mat-card.get-typography-tokens($theme)
@@ -110,6 +123,11 @@
110123
tokens: tokens-mat-outlined-card.get-token-slots(),
111124
prefix: 'outlined-',
112125
),
126+
(
127+
namespace: tokens-mat-filled-card.$prefix,
128+
tokens: tokens-mat-filled-card.get-token-slots(),
129+
prefix: 'outlined-',
130+
)
113131
);
114132
}
115133

@@ -149,6 +167,10 @@
149167
tokens-mat-outlined-card.$prefix,
150168
map.get($tokens, tokens-mat-outlined-card.$prefix)
151169
);
170+
@include token-utils.create-token-values(
171+
tokens-mat-filled-card.$prefix,
172+
map.get($tokens, tokens-mat-filled-card.$prefix)
173+
);
152174
@include token-utils.create-token-values(
153175
tokens-mat-card.$prefix,
154176
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/mat/elevated-card' as tokens-mat-elevated-card;
44
@use '../core/tokens/m2/mat/outlined-card' as tokens-mat-outlined-card;
5+
@use '../core/tokens/m2/mat/filled-card' as tokens-mat-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-mat-filled-card.$prefix,
75+
tokens-mat-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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@use './mat/text-button' as tokens-mat-text-button;
88
@use './mat/protected-button' as tokens-mat-protected-button;
99
@use './mat/filled-button' as tokens-mat-filled-button;
10+
@use './mat/filled-card' as tokens-mat-filled-card;
1011
@use './mat/outlined-button' as tokens-mat-outlined-button;
1112
@use './mat/dialog' as tokens-mat-dialog;
1213
@use './mat/bottom-sheet' as tokens-mat-bottom-sheet;
@@ -114,6 +115,7 @@
114115
_get-tokens-for-module($theme, tokens-mat-fab),
115116
_get-tokens-for-module($theme, tokens-mat-fab-small),
116117
_get-tokens-for-module($theme, tokens-mat-filled-button),
118+
_get-tokens-for-module($theme, tokens-mat-filled-card),
117119
_get-tokens-for-module($theme, tokens-mat-form-field),
118120
_get-tokens-for-module($theme, tokens-mat-grid-list),
119121
_get-tokens-for-module($theme, tokens-mat-icon-button),
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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: (mat, 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+
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(token-definition.$placeholder-color-config),
47+
get-typography-tokens(token-definition.$placeholder-typography-config),
48+
get-density-tokens(token-definition.$placeholder-density-config)
49+
);
50+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
@use './mat/fab';
1717
@use './mat/fab-small';
1818
@use './mat/filled-button';
19+
@use './mat/filled-card';
1920
@use './mat/filled-text-field';
2021
@use './mat/form-field';
2122
@use './mat/full-pseudo-checkbox';
@@ -78,6 +79,7 @@
7879
fab.get-tokens($systems, $exclude-hardcoded, $token-slots),
7980
fab-small.get-tokens($systems, $exclude-hardcoded, $token-slots),
8081
filled-button.get-tokens($systems, $exclude-hardcoded, $token-slots),
82+
filled-card.get-tokens($systems, $exclude-hardcoded, $token-slots),
8183
filled-text-field.get-tokens($systems, $exclude-hardcoded, $token-slots),
8284
form-field.get-tokens($systems, $exclude-hardcoded, $token-slots),
8385
full-pseudo-checkbox.get-tokens($systems, $exclude-hardcoded, $token-slots),
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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: (mat, 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: (
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 token-definition.namespace-tokens($prefix, $tokens, $token-slots);
27+
}

0 commit comments

Comments
 (0)