Skip to content

Commit

Permalink
fix(material/button): generate separate tokens for mini fab
Browse files Browse the repository at this point in the history
Currently the mini FAB uses the same tokens as the regular one. This is incorrect and causes inconsistencies in M3. These changes split the mini FAB out into its own set of tokens.
  • Loading branch information
crisbeto committed Jan 22, 2024
1 parent 0cf81f3 commit a496855
Show file tree
Hide file tree
Showing 10 changed files with 359 additions and 60 deletions.
41 changes: 41 additions & 0 deletions src/material-experimental/theming/_custom-tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,47 @@
));
}

/// Generates custom tokens for the mat-mini-fab.
/// @param {Map} $systems The MDC system tokens
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
/// @return {Map} A set of custom tokens for the mat-mini-fab
@function fab-small($systems, $exclude-hardcoded) {
@return ((
foreground-color: map.get($systems, md-sys-color, on-primary-container),
state-layer-color: map.get($systems, md-sys-color, primary-container),
ripple-color: mat.private-safe-color-change(
map.get($systems, md-sys-color, on-primary-container),
$alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)
),
hover-state-layer-opacity: map.get($systems, md-sys-state, hover-state-layer-opacity),
focus-state-layer-opacity: map.get($systems, md-sys-state, focus-state-layer-opacity),
pressed-state-layer-opacity: map.get($systems, md-sys-state, pressed-state-layer-opacity),
disabled-state-container-color: mat.private-safe-color-change(
map.get($systems, md-sys-color, on-surface), $alpha: 0.12),
disabled-state-foreground-color: mat.private-safe-color-change(
map.get($systems, md-sys-color, on-surface), $alpha: 0.38),
), (
// Color variants
primary: (), // Default, no overrides needed.
secondary: (
foreground-color: map.get($systems, md-sys-color, on-secondary-container),
state-layer-color: map.get($systems, md-sys-color, secondary-container),
ripple-color: mat.private-safe-color-change(
map.get($systems, md-sys-color, on-secondary-container),
$alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)
),
),
tertiary: (
foreground-color: map.get($systems, md-sys-color, on-tertiary-container),
state-layer-color: map.get($systems, md-sys-color, tertiary-container),
ripple-color: mat.private-safe-color-change(
map.get($systems, md-sys-color, on-tertiary-container),
$alpha: map.get($systems, md-sys-state, pressed-state-layer-opacity)
),
)
));
}

/// Generates custom tokens for the mat-form-field.
/// @param {Map} $systems The MDC system tokens
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
Expand Down
1 change: 1 addition & 0 deletions src/material-experimental/theming/_m3-density.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ $_density-tokens: (
(mdc, elevated-card): (),
(mdc, extended-fab): (),
(mdc, fab): (),
(mdc, fab-small): (),
(mdc, filled-text-field): (),
(mdc, text-button): (
container-height: (40px, 36px, 32px, 28px),
Expand Down
18 changes: 18 additions & 0 deletions src/material-experimental/theming/_m3-tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,19 @@
),
$token-slots
),
_namespace-tokens(
(mdc, fab-small),
(
mdc-tokens.md-comp-fab-primary-small-values($systems, $exclude-hardcoded),
(
// Color variants
primary: (), // Default, no overrides needed.
secondary: mdc-tokens.md-comp-fab-secondary-small-values($systems, $exclude-hardcoded),
tertiary: mdc-tokens.md-comp-fab-tertiary-small-values($systems, $exclude-hardcoded)
)
),
$token-slots
),
_namespace-tokens(
(mdc, extended-fab),
(
Expand Down Expand Up @@ -703,6 +716,11 @@
custom-tokens.fab($systems, $exclude-hardcoded),
$token-slots
),
_namespace-tokens(
(mat, fab-small),
custom-tokens.fab-small($systems, $exclude-hardcoded),
$token-slots
),
_namespace-tokens(
(mat, form-field),
custom-tokens.form-field($systems, $exclude-hardcoded),
Expand Down
47 changes: 45 additions & 2 deletions src/material/button/_fab-theme.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
@use '@material/fab/fab-theme' as mdc-fab-theme;
@use '@material/fab/fab-small-theme' as mdc-fab-small-theme;
@use '@material/fab/extended-fab-theme' as mdc-extended-fab-theme;
@use '../core/style/sass-utils';
@use '../core/theming/theming';
@use '../core/theming/inspection';
@use '../core/tokens/m2/mdc/fab' as tokens-mdc-fab;
@use '../core/tokens/m2/mdc/fab-small' as tokens-mdc-fab-small;
@use '../core/tokens/m2/mdc/extended-fab' as tokens-mdc-extended-fab;
@use '../core/tokens/m2/mat/fab' as tokens-mat-fab;
@use '../core/tokens/m2/mat/fab-small' as tokens-mat-fab-small;
@use '../core/tokens/token-utils';
@use '../core/typography/typography';

Expand All @@ -20,6 +23,7 @@
// Add default values for tokens not related to color, typography, or density.
@include sass-utils.current-selector-or-root() {
@include mdc-fab-theme.theme(tokens-mdc-fab.get-unthemable-tokens());
@include mdc-fab-small-theme.theme(tokens-mdc-fab-small.get-unthemable-tokens());
@include mdc-extended-fab-theme.theme(
tokens-mdc-extended-fab.get-unthemable-tokens()
);
Expand All @@ -42,6 +46,21 @@
@include token-utils.create-token-values(tokens-mat-fab.$prefix, $mat-tokens);
}

@mixin _fab-small-variant($theme, $palette) {
$mdc-tokens: if($palette,
tokens-mdc-fab-small.private-get-color-palette-color-tokens($theme, $palette),
tokens-mdc-fab-small.get-color-tokens($theme)
);

$mat-tokens: if($palette,
tokens-mat-fab-small.private-get-color-palette-color-tokens($theme, $palette),
tokens-mat-fab-small.get-color-tokens($theme)
);

@include mdc-fab-small-theme.theme($mdc-tokens);
@include token-utils.create-token-values(tokens-mat-fab-small.$prefix, $mat-tokens);
}

/// Outputs color theme styles for the mat-fab.
/// @param {Map} $theme The theme to generate color styles for.
/// @param {ArgList} Additional optional arguments (only supported for M3 themes):
Expand All @@ -54,10 +73,10 @@
@else {
@include sass-utils.current-selector-or-root() {
@include _fab-variant($theme, null);
@include _fab-small-variant($theme, null);
@include mdc-extended-fab-theme.theme(tokens-mdc-extended-fab.get-color-tokens($theme));

.mat-mdc-fab,
.mat-mdc-mini-fab {
.mat-mdc-fab {
&.mat-primary {
@include _fab-variant($theme, primary);
}
Expand All @@ -70,6 +89,20 @@
@include _fab-variant($theme, warn);
}
}

.mat-mdc-mini-fab {
&.mat-primary {
@include _fab-small-variant($theme, primary);
}

&.mat-accent {
@include _fab-small-variant($theme, accent);
}

&.mat-warn {
@include _fab-small-variant($theme, warn);
}
}
}
}
}
Expand All @@ -85,6 +118,8 @@
@include mdc-extended-fab-theme.theme(tokens-mdc-extended-fab.get-typography-tokens($theme));
@include token-utils.create-token-values(tokens-mat-fab.$prefix,
tokens-mat-fab.get-typography-tokens($theme));
@include token-utils.create-token-values(tokens-mat-fab-small.$prefix,
tokens-mat-fab-small.get-typography-tokens($theme));
}
}
}
Expand All @@ -99,6 +134,8 @@
@include sass-utils.current-selector-or-root() {
@include token-utils.create-token-values(tokens-mat-fab.$prefix,
tokens-mat-fab.get-density-tokens($theme));
@include token-utils.create-token-values(tokens-mat-fab-small.$prefix,
tokens-mat-fab-small.get-density-tokens($theme));
}
}
}
Expand Down Expand Up @@ -132,8 +169,14 @@
$mdc-extended-fab-tokens: token-utils.get-tokens-for(
$tokens, tokens-mdc-extended-fab.$prefix, $options...);
$mdc-fab-tokens: token-utils.get-tokens-for($tokens, tokens-mdc-fab.$prefix, $options...);
$mdc-fab-small-tokens: token-utils.get-tokens-for($tokens, tokens-mdc-fab-small.$prefix,
$options...);
$mat-fab-tokens: token-utils.get-tokens-for($tokens, tokens-mat-fab.$prefix, $options...);
$mat-fab-small-tokens: token-utils.get-tokens-for($tokens, tokens-mat-fab-small.$prefix,
$options...);
@include mdc-extended-fab-theme.theme($mdc-extended-fab-tokens);
@include mdc-fab-theme.theme($mdc-fab-tokens);
@include mdc-fab-small-theme.theme($mdc-fab-small-tokens);
@include token-utils.create-token-values(tokens-mat-fab.$prefix, $mat-fab-tokens);
@include token-utils.create-token-values(tokens-mat-fab-small.$prefix, $mat-fab-small-tokens);
}
111 changes: 64 additions & 47 deletions src/material/button/fab.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@use '@material/fab' as mdc-fab;
@use '@material/fab/extended-fab-theme' as mdc-extended-fab-theme;
@use '@material/fab/fab-theme' as mdc-fab-theme;
@use '@material/fab/fab-small-theme' as mdc-fab-small-theme;
@use '@material/typography/typography' as mdc-typography;
@use '@material/theme/custom-properties' as mdc-custom-properties;

Expand All @@ -13,9 +14,12 @@
@use '../core/tokens/m2/mdc/extended-fab' as tokens-mdc-extended-fab;
@use '../core/tokens/m2/mdc/fab' as tokens-mdc-fab;
@use '../core/tokens/m2/mat/fab' as tokens-mat-fab;
@use '../core/tokens/m2/mdc/fab-small' as tokens-mdc-fab-small;
@use '../core/tokens/m2/mat/fab-small' as tokens-mat-fab-small;

@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
$mdc-fab-token-slots: tokens-mdc-fab.get-token-slots();
$mdc-fab-small-token-slots: tokens-mdc-fab-small.get-token-slots();
$mdc-extended-fab-token-slots: tokens-mdc-extended-fab.get-token-slots();
$exclude-tokens: (
// Exclude the elevation tokens here since we output them manually below.
Expand All @@ -30,10 +34,15 @@
// some unnecessary typography styles for the extended FAB.
@include mdc-fab.static-styles($query: mdc-helpers.$mdc-base-styles-query);

.mat-mdc-fab, .mat-mdc-mini-fab {
.mat-mdc-fab {
@include mdc-fab-theme.theme-styles(map.merge($mdc-fab-token-slots, $exclude-tokens));
}

.mat-mdc-mini-fab {
@include mdc-fab-small-theme.theme-styles(
map.merge($mdc-fab-small-token-slots, $exclude-tokens));
}

.mat-mdc-extended-fab {
// Before tokens MDC included the font smoothing automatically, but with
// tokens it doesn't. We add it since it can cause tiny differences in
Expand All @@ -46,47 +55,9 @@

.mat-mdc-fab, .mat-mdc-mini-fab {
@include button-base.mat-private-button-interactive();
@include button-base.mat-private-button-touch-target(true, tokens-mat-fab.$prefix,
tokens-mat-fab.get-token-slots());
@include button-base.mat-private-button-ripple(tokens-mat-fab.$prefix,
tokens-mat-fab.get-token-slots());
@include style-private.private-animation-noop();
flex-shrink: 0; // Prevent the button from shrinking since it's always supposed to be a circle.

@include mdc-helpers.disable-mdc-fallback-declarations {
@include token-utils.use-tokens(tokens-mat-fab.$prefix, tokens-mat-fab.get-token-slots()) {
@include token-utils.create-token-slot(color, foreground-color, inherit);
}
}

@include token-utils.use-tokens(tokens-mdc-fab.$prefix, tokens-mdc-fab.get-token-slots()) {
@include button-base.mat-private-button-elevation(container-elevation);

&:hover {
@include button-base.mat-private-button-elevation(hover-container-elevation);
}

&:focus {
@include button-base.mat-private-button-elevation(focus-container-elevation);
}

&:active, &:focus:active {
@include button-base.mat-private-button-elevation(pressed-container-elevation);
}
}

@include button-base.mat-private-button-disabled {
// Necessary for interactive disabled buttons.
&, &:focus {
box-shadow: none;
}

@include token-utils.use-tokens(tokens-mat-fab.$prefix, tokens-mat-fab.get-token-slots()) {
@include token-utils.create-token-slot(color, disabled-state-foreground-color);
@include token-utils.create-token-slot(background-color, disabled-state-container-color);
}
}

// MDC adds some styles to fab and mini-fab that conflict with some of our focus indicator
// styles and don't actually do anything. This undoes those conflicting styles.
&:not(.mdc-ripple-upgraded):focus::before {
Expand All @@ -111,11 +82,17 @@
$offset: calc(#{$border-width} + 2px);
margin: calc(#{$offset} * -1);
}

@include button-base.mat-private-button-disabled {
// Necessary for interactive disabled buttons.
&, &:focus {
box-shadow: none;
}
}
}

.mat-mdc-extended-fab {
@include token-utils.use-tokens(tokens-mdc-extended-fab.$prefix,
tokens-mdc-extended-fab.get-token-slots()) {
@mixin _fab-elevation($mdc-tokens) {
@include token-utils.use-tokens($mdc-tokens...) {
@include button-base.mat-private-button-elevation(container-elevation);

&:hover {
Expand All @@ -130,6 +107,45 @@
@include button-base.mat-private-button-elevation(pressed-container-elevation);
}
}
}

@mixin _fab-structure($mdc-tokens, $mat-tokens) {
@include button-base.mat-private-button-touch-target(true, $mat-tokens...);
@include button-base.mat-private-button-ripple($mat-tokens...);

@include mdc-helpers.disable-mdc-fallback-declarations {
@include token-utils.use-tokens($mat-tokens...) {
@include token-utils.create-token-slot(color, foreground-color, inherit);
}
}

@include _fab-elevation($mdc-tokens);

@include button-base.mat-private-button-disabled {
@include token-utils.use-tokens($mat-tokens...) {
@include token-utils.create-token-slot(color, disabled-state-foreground-color);
@include token-utils.create-token-slot(background-color, disabled-state-container-color);
}
}
}

.mat-mdc-fab {
@include _fab-structure(
(tokens-mdc-fab.$prefix, tokens-mdc-fab.get-token-slots()),
(tokens-mat-fab.$prefix, tokens-mat-fab.get-token-slots()),
);
}

.mat-mdc-mini-fab {
@include _fab-structure(
(tokens-mdc-fab-small.$prefix, tokens-mdc-fab-small.get-token-slots()),
(tokens-mat-fab-small.$prefix, tokens-mat-fab-small.get-token-slots()),
);
}

.mat-mdc-extended-fab {
@include _fab-elevation((tokens-mdc-extended-fab.$prefix,
tokens-mdc-extended-fab.get-token-slots()));

@include button-base.mat-private-button-disabled {
// Necessary for interactive disabled buttons.
Expand All @@ -146,6 +162,12 @@
);
}

// All FABs are square except the extended ones so we
// need to set the touch target back to full-width.
.mat-mdc-button-touch-target {
width: 100%;
}

// For Extended FAB with text label followed by icon.
// We are checking for the a button class because white this is a FAB it
// uses the same template as button.
Expand All @@ -159,8 +181,3 @@
}
}

// All FABs are square except the extended ones so we
// need to set the touch target back to full-width.
.mat-mdc-extended-fab .mat-mdc-button-touch-target {
width: 100%;
}
Loading

0 comments on commit a496855

Please sign in to comment.