Skip to content

Commit cbac7f6

Browse files
authored
refactor(material/fab): change mat-fab to use MDC's token API (#26823)
* refactor(material/button): change mat-fab to use MDC's token API * fixup! refactor(material/button): change mat-fab to use MDC's token API * fixup! refactor(material/button): change mat-fab to use MDC's token API
1 parent c973da2 commit cbac7f6

File tree

5 files changed

+289
-54
lines changed

5 files changed

+289
-54
lines changed

src/material/button/_fab-theme.scss

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,102 @@
11
@use 'sass:map';
22
@use '@material/fab/fab' as mdc-fab;
33
@use '@material/fab/fab-theme' as mdc-fab-theme;
4-
@use '@material/theme/theme-color' as mdc-theme-color;
4+
@use '@material/fab/extended-fab-theme' as mdc-extended-fab-theme;
55

66
@use './button-theme-private';
77
@use '../core/mdc-helpers/mdc-helpers';
88
@use '../core/theming/theming';
9+
@use '../core/tokens/m2/mdc/fab' as tokens-mdc-fab;
10+
@use '../core/tokens/m2/mdc/extended-fab' as tokens-mdc-extended-fab;
911
@use '../core/typography/typography';
1012

11-
@mixin _fab-variant($foreground, $background) {
12-
@include mdc-fab-theme.theme((
13-
container-color: $background,
14-
icon-color: $foreground,
15-
));
13+
@mixin _fab-variant($config, $foreground, $background) {
14+
$color-config: map.merge(
15+
$config,
16+
(
17+
primary: (
18+
default: $background,
19+
default-contrast: $foreground,
20+
),
21+
)
22+
);
23+
$color-tokens: tokens-mdc-fab.get-color-tokens($color-config);
24+
@include mdc-fab-theme.theme($color-tokens);
1625

1726
--mat-mdc-fab-color: #{$foreground};
1827
}
1928

29+
@function white-or-black($color, $is-dark) {
30+
@return if(mdc-helpers.variable-safe-contrast-tone($color, $is-dark) == 'dark', #000, #fff);
31+
}
32+
2033
@mixin color($config-or-theme) {
2134
$config: theming.get-color-config($config-or-theme);
22-
@include mdc-helpers.using-mdc-theme($config) {
23-
$on-surface: mdc-theme-color.prop-value(on-surface);
24-
$is-dark: map.get($config, is-dark);
2535

26-
.mat-mdc-fab, .mat-mdc-mini-fab {
36+
$is-dark: map.get($config, is-dark);
37+
$background: map.get($config, background);
38+
39+
$surface: theming.get-color-from-palette($background, card);
40+
$primary: theming.get-color-from-palette(map.get($config, primary));
41+
$accent: theming.get-color-from-palette(map.get($config, accent));
42+
$warn: theming.get-color-from-palette(map.get($config, warn));
43+
44+
$on-surface: white-or-black($surface, $is-dark);
45+
$on-primary: white-or-black($primary, $is-dark);
46+
$on-accent: white-or-black($accent, $is-dark);
47+
$on-warn: white-or-black($warn, $is-dark);
48+
49+
$disabled: rgba($on-surface, 0.12);
50+
$on-disabled: rgba($on-surface, if(map.get($config, is-dark), 0.5, 0.38));
51+
52+
.mat-mdc-fab,
53+
.mat-mdc-mini-fab {
54+
// TODO(wagnermaciel): The ripple-theme-styles mixin depends heavily on
55+
// being wrapped by using-mdc-theme. This workaround needs to be
56+
// revisited w/ a more holistic solution.
57+
@include mdc-helpers.using-mdc-theme($config) {
2758
@include button-theme-private.ripple-theme-styles($config, true);
59+
}
2860

29-
&.mat-unthemed {
30-
@include _fab-variant($on-surface, mdc-theme-color.prop-value(surface));
31-
}
32-
33-
&.mat-primary {
34-
@include _fab-variant(
35-
mdc-theme-color.prop-value(on-primary),
36-
mdc-theme-color.prop-value(primary)
37-
);
38-
}
39-
40-
&.mat-accent {
41-
@include _fab-variant(
42-
mdc-theme-color.prop-value(on-secondary),
43-
mdc-theme-color.prop-value(secondary)
44-
);
45-
}
46-
47-
&.mat-warn {
48-
@include _fab-variant(
49-
mdc-theme-color.prop-value(on-error),
50-
mdc-theme-color.prop-value(error)
51-
);
52-
}
53-
54-
@include button-theme-private.apply-disabled-style() {
55-
@include _fab-variant(
56-
rgba($on-surface, if(map.get($config, is-dark), 0.5, 0.38)),
57-
rgba($on-surface, 0.12)
58-
);
59-
}
61+
@include button-theme-private.apply-disabled-style() {
62+
@include _fab-variant($config, $on-disabled, $disabled);
63+
}
64+
65+
&.mat-unthemed {
66+
@include _fab-variant($config, $on-surface, $surface);
67+
}
68+
69+
&.mat-primary {
70+
@include _fab-variant($config, $on-primary, $primary);
71+
}
72+
73+
&.mat-accent {
74+
@include _fab-variant($config, $on-accent, $accent);
75+
}
76+
77+
&.mat-warn {
78+
@include _fab-variant($config, $on-warn, $warn);
6079
}
6180
}
6281
}
6382

6483
@mixin typography($config-or-theme) {
6584
$config: typography.private-typography-to-2018-config(
66-
theming.get-typography-config($config-or-theme));
85+
theming.get-typography-config($config-or-theme)
86+
);
87+
6788
@include mdc-helpers.using-mdc-typography($config) {
6889
@include mdc-fab.without-ripple($query: mdc-helpers.$mdc-typography-styles-query);
6990
}
91+
92+
$typography-tokens: tokens-mdc-extended-fab.get-typography-tokens($config);
93+
.mat-mdc-extended-fab {
94+
@include mdc-extended-fab-theme.theme($typography-tokens);
95+
}
7096
}
7197

72-
@mixin density($config-or-theme) {}
98+
@mixin density($config-or-theme) {
99+
}
73100

74101
@mixin theme($theme-or-color-config) {
75102
$theme: theming.private-legacy-get-theme($theme-or-color-config);

src/material/button/fab.scss

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,39 @@
11
@use '@material/fab' as mdc-fab;
2+
@use '@material/fab/extended-fab-theme' as mdc-extended-fab-theme;
3+
@use '@material/fab/fab-theme' as mdc-fab-theme;
24
@use '@material/elevation/elevation-theme' as mdc-elevation-theme;
5+
@use '@material/theme/custom-properties' as mdc-custom-properties;
36

47
@use './button-base';
58
@use '../core/mdc-helpers/mdc-helpers';
69
@use '../core/style/private' as style-private;
710
@use '../core/focus-indicators/private' as focus-indicators-private;
11+
@use '../core/tokens/m2/mdc/extended-fab' as m2-mdc-extended-fab;
12+
@use '../core/tokens/m2/mdc/fab' as m2-mdc-fab;
813

9-
@include mdc-helpers.disable-mdc-fallback-declarations {
10-
@include mdc-fab.without-ripple($query: mdc-helpers.$mdc-base-styles-query);
14+
@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
15+
$mdc-fab-token-slots: m2-mdc-fab.get-token-slots();
16+
$mdc-extended-fab-token-slots: m2-mdc-extended-fab.get-token-slots();
17+
18+
// Add the MDC fab static styles.
19+
@include mdc-fab.static-styles();
20+
21+
// Add default values for tokens that aren't outputted by the theming API.
22+
.mat-mdc-fab, .mat-mdc-mini-fab {
23+
// Add the official slots for the MDC fab.
24+
@include mdc-fab-theme.theme-styles($mdc-fab-token-slots);
25+
26+
// Add default values for tokens that aren't outputted by the theming API.
27+
@include mdc-fab-theme.theme(m2-mdc-fab.get-unthemable-tokens());
28+
}
29+
30+
.mat-mdc-extended-fab {
31+
// Add the official slots for the MDC fab.
32+
@include mdc-extended-fab-theme.theme-styles($mdc-extended-fab-token-slots);
33+
34+
// Add default values for tokens that aren't outputted by the theming API.
35+
@include mdc-extended-fab-theme.theme(m2-mdc-extended-fab.get-unthemable-tokens());
36+
}
1137
}
1238

1339
.mat-mdc-fab, .mat-mdc-mini-fab {
@@ -16,13 +42,6 @@
1642
@include style-private.private-animation-noop();
1743

1844
@include mdc-helpers.disable-mdc-fallback-declarations {
19-
// Theme configuration is copied over from MDC, because it isn't exported
20-
@include mdc-fab.theme-styles(button-base.mat-private-button-remove-ripple((
21-
container-color: transparent,
22-
container-shape: mdc-fab.$shape-radius,
23-
icon-color: inherit,
24-
)));
25-
2645
// TODO(crisbeto): the elevation can be controlled using `container-elevation` in `theme-styles`
2746
// however when it is passed in, MDC throws an error that `container-shadow-color` isn't
2847
// passed in. When `container-shadow-color` is passed in, MDC throws another error, because
@@ -76,8 +95,6 @@
7695
}
7796

7897
.mat-mdc-extended-fab {
79-
@include mdc-fab.extended_($query: mdc-helpers.$mdc-base-styles-query);
80-
8198
& > .mat-icon,
8299
& > .material-icons { // stylelint-disable-line selector-class-pattern
83100
@include mdc-fab.extended-icon-padding(
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
@use '../../../mdc-helpers/mdc-helpers';
2+
@use '../../token-utils';
3+
@use '../../../typography/typography-utils';
4+
5+
@use 'sass:map';
6+
7+
// The prefix used to generate the fully qualified name for tokens in this file.
8+
$prefix: (mdc, extended-fab);
9+
10+
@function get-unthemable-tokens() {
11+
@return (
12+
container-color: null,
13+
container-elevation: null,
14+
container-height: null,
15+
container-shadow-color: null,
16+
container-shape: null,
17+
container-surface-tint-layer-color: null,
18+
focus-container-elevation: null,
19+
focus-icon-color: null,
20+
focus-label-text-color: null,
21+
focus-outline-color: null,
22+
focus-outline-width: null,
23+
focus-state-layer-color: null,
24+
focus-state-layer-opacity: null,
25+
hover-container-elevation: null,
26+
hover-icon-color: null,
27+
hover-label-text-color: null,
28+
hover-state-layer-color: null,
29+
hover-state-layer-opacity: null,
30+
icon-color: null,
31+
icon-size: null,
32+
label-text-color: null,
33+
lowered-container-elevation: null,
34+
lowered-focus-container-elevation: null,
35+
lowered-hover-container-elevation: null,
36+
lowered-pressed-container-elevation: null,
37+
pressed-container-elevation: null,
38+
pressed-icon-color: null,
39+
pressed-label-text-color: null,
40+
pressed-ripple-color: null,
41+
pressed-ripple-opacity: null,
42+
pressed-state-layer-color: null,
43+
pressed-state-layer-opacity: null
44+
);
45+
}
46+
47+
// Tokens that can be configured through Angular Material's color theming API.
48+
@function get-color-tokens($config) {
49+
@return ();
50+
}
51+
52+
// Tokens that can be configured through Angular Material's typography theming API.
53+
@function get-typography-tokens($config) {
54+
// TODO(wagnermaciel): The earlier implementation of the snack bar used MDC's APIs to create the
55+
// typography tokens. As a result, we unintentionally allowed `null` typography configs to be
56+
// passed in. Since there a lot of apps that now depend on this pattern, we need this temporary
57+
// fallback.
58+
@if ($config == null) {
59+
$config: mdc-helpers.private-fallback-typography-from-mdc();
60+
}
61+
@return (
62+
label-text-font: typography-utils.font-family($config, button) or
63+
typography-utils.font-family($config),
64+
label-text-size: typography-utils.font-size($config, button),
65+
label-text-tracking: typography-utils.letter-spacing($config, button),
66+
label-text-weight: typography-utils.font-weight($config, button)
67+
);
68+
}
69+
70+
// Tokens that can be configured through Angular Material's density theming API.
71+
@function get-density-tokens($config) {
72+
@return ();
73+
}
74+
75+
// Combines the tokens generated by the above functions into a single map with placeholder values.
76+
// This is used to create token slots.
77+
@function get-token-slots() {
78+
@return map.merge(
79+
get-unthemable-tokens(),
80+
map.merge(
81+
get-color-tokens(token-utils.$placeholder-color-config),
82+
map.merge(
83+
get-typography-tokens(token-utils.$placeholder-typography-config),
84+
get-density-tokens(token-utils.$placeholder-density-config)
85+
)
86+
)
87+
);
88+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
@use '../../../theming/theming';
2+
@use '../../token-utils';
3+
4+
@use 'sass:map';
5+
6+
// The prefix used to generate the fully qualified name for tokens in this file.
7+
$prefix: (mdc, fab);
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+
$height: 56px;
16+
$mini-height: 40px;
17+
$shape-radius: 50%;
18+
$ripple-target: '.mdc-fab__ripple';
19+
20+
@function get-unthemable-tokens() {
21+
@return (
22+
container-shape: 50%,
23+
icon-size: 24px,
24+
25+
container-elevation: null,
26+
container-height: null,
27+
container-shadow-color: null,
28+
container-surface-tint-layer-color: null,
29+
container-width: null,
30+
31+
focus-container-elevation: null,
32+
focus-icon-color: null,
33+
focus-outline-color: null,
34+
focus-outline-width: null,
35+
focus-state-layer-color: null,
36+
focus-state-layer-opacity: null,
37+
38+
hover-container-elevation: null,
39+
hover-icon-color: null,
40+
hover-state-layer-color: null,
41+
hover-state-layer-opacity: null,
42+
43+
lowered-container-elevation: null,
44+
lowered-focus-container-elevation: null,
45+
lowered-hover-container-elevation: null,
46+
lowered-pressed-container-elevation: null,
47+
48+
pressed-container-elevation: null,
49+
pressed-icon-color: null,
50+
pressed-ripple-color: null,
51+
pressed-ripple-opacity: null,
52+
pressed-state-layer-color: null,
53+
pressed-state-layer-opacity: null
54+
);
55+
}
56+
57+
// Tokens that can be configured through Angular Material's color theming API.
58+
@function get-color-tokens($config) {
59+
$primary: map.get($config, primary);
60+
$surface: theming.get-color-from-palette($primary, default);
61+
$on-surface: theming.get-color-from-palette($primary, default-contrast);
62+
63+
@return (container-color: $surface, icon-color: $on-surface);
64+
}
65+
66+
// Tokens that can be configured through Angular Material's typography theming API.
67+
@function get-typography-tokens($config) {
68+
@return ();
69+
}
70+
71+
// Tokens that can be configured through Angular Material's density theming API.
72+
@function get-density-tokens($config) {
73+
@return ();
74+
}
75+
76+
// Combines the tokens generated by the above functions into a single map with placeholder values.
77+
// This is used to create token slots.
78+
@function get-token-slots() {
79+
@return map.merge(
80+
get-unthemable-tokens(),
81+
map.merge(
82+
get-color-tokens(token-utils.$placeholder-color-config),
83+
map.merge(
84+
get-typography-tokens(token-utils.$placeholder-typography-config),
85+
get-density-tokens(token-utils.$placeholder-density-config)
86+
)
87+
)
88+
);
89+
}

0 commit comments

Comments
 (0)