Skip to content

Commit 1526744

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 1526744

File tree

6 files changed

+129
-2
lines changed

6 files changed

+129
-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: 10 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 {
@@ -110,6 +111,11 @@
110111
tokens: tokens-mat-outlined-card.get-token-slots(),
111112
prefix: 'outlined-',
112113
),
114+
(
115+
namespace: tokens-mat-filled-card.$prefix,
116+
tokens: tokens-mat-filled-card.get-token-slots(),
117+
prefix: 'outlined-',
118+
)
113119
);
114120
}
115121

@@ -149,6 +155,10 @@
149155
tokens-mat-outlined-card.$prefix,
150156
map.get($tokens, tokens-mat-outlined-card.$prefix)
151157
);
158+
@include token-utils.create-token-values(
159+
tokens-mdc-filled-card.$prefix,
160+
map.get($tokens, tokens-mdc-filled-card.$prefix)
161+
);
152162
@include token-utils.create-token-values(
153163
tokens-mat-card.$prefix,
154164
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/mdc/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-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,
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+
}
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+
}

0 commit comments

Comments
 (0)