Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(material/button): simplify FAB structural styles #29353

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions src/material/button/_fab-theme.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
@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';
Expand All @@ -21,13 +18,13 @@
@include _theme-from-tokens(inspection.get-theme-tokens($theme, base));
}
@else {
// 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()
);
@include token-utils.create-token-values(
tokens-mdc-fab.$prefix, tokens-mdc-fab.get-unthemable-tokens());
@include token-utils.create-token-values(
tokens-mdc-fab-small.$prefix, tokens-mdc-fab-small.get-unthemable-tokens());
@include token-utils.create-token-values(
tokens-mdc-extended-fab.$prefix, tokens-mdc-extended-fab.get-unthemable-tokens());
}
}
}
Expand All @@ -43,7 +40,7 @@
tokens-mat-fab.get-color-tokens($theme)
);

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

Expand All @@ -58,7 +55,7 @@
tokens-mat-fab-small.get-color-tokens($theme)
);

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

Expand All @@ -75,7 +72,8 @@
@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));
@include token-utils.create-token-values(
tokens-mdc-extended-fab.$prefix, tokens-mdc-extended-fab.get-color-tokens($theme));

.mat-mdc-fab {
&.mat-primary {
Expand Down Expand Up @@ -116,7 +114,8 @@
}
@else {
@include sass-utils.current-selector-or-root() {
@include mdc-extended-fab-theme.theme(tokens-mdc-extended-fab.get-typography-tokens($theme));
@include token-utils.create-token-values(tokens-mdc-extended-fab.$prefix,
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,
Expand Down Expand Up @@ -190,9 +189,10 @@
$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-mdc-extended-fab.$prefix,
$mdc-extended-fab-tokens);
@include token-utils.create-token-values(tokens-mdc-fab.$prefix, $mdc-fab-tokens);
@include token-utils.create-token-values(tokens-mdc-fab-small.$prefix, $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);
}
4 changes: 2 additions & 2 deletions src/material/button/button-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ const HOST_SELECTOR_MDC_CLASS_PAIR: {attribute: string; mdcClasses: string[]}[]
},
{
attribute: 'mat-fab',
mdcClasses: ['mdc-fab', 'mat-mdc-fab'],
mdcClasses: ['mdc-fab', 'mat-mdc-fab-base', 'mat-mdc-fab'],
},
{
attribute: 'mat-mini-fab',
mdcClasses: ['mdc-fab', 'mdc-fab--mini', 'mat-mdc-mini-fab'],
mdcClasses: ['mdc-fab', 'mat-mdc-fab-base', 'mdc-fab--mini', 'mat-mdc-mini-fab'],
},
{
attribute: 'mat-icon-button',
Expand Down
182 changes: 107 additions & 75 deletions src/material/button/fab.scss
Original file line number Diff line number Diff line change
@@ -1,68 +1,70 @@
@use 'sass:map';
@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;

@use './button-base';
@use '../core/mdc-helpers/mdc-helpers';
@use '../core/tokens/token-utils';
@use '../core/style/private' as style-private;
@use '../core/style/vendor-prefixes';
@use '../core/focus-indicators/private' as focus-indicators-private;
@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.
container-elevation: null,
focus-container-elevation: null,
hover-container-elevation: null,
pressed-container-elevation: null,
container-shadow-color: null,
);
.mat-mdc-fab-base {
@include button-base.mat-private-button-interactive();
@include style-private.private-animation-noop();
@include vendor-prefixes.user-select(none);
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: 56px;
height: 56px;
padding: 0;
border: none;
fill: currentColor;
text-decoration: none;
cursor: pointer;
-moz-appearance: none;
-webkit-appearance: none;
overflow: visible;
transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1), opacity 15ms linear 30ms,
transform 270ms 0ms cubic-bezier(0, 0, 0.2, 1);
flex-shrink: 0; // Prevent the button from shrinking since it's always supposed to be a circle.

// Note: it's important to pass the query here, otherwise MDC generates
// some unnecessary typography styles for the extended FAB.
@include mdc-fab.static-styles($query: mdc-helpers.$mdc-base-styles-query);
&::before {
position: absolute;
box-sizing: border-box;
width: 100%;
height: 100%;
top: 0;
left: 0;
border: 1px solid transparent;
border-radius: inherit;
content: '';
pointer-events: none;
}

.mat-mdc-fab {
@include mdc-fab-theme.theme-styles(map.merge($mdc-fab-token-slots, $exclude-tokens));
// MDC used to include this and it seems like a lot of apps depend on it.
&[hidden] {
display: none;
}

.mat-mdc-mini-fab {
@include mdc-fab-small-theme.theme-styles(
map.merge($mdc-fab-small-token-slots, $exclude-tokens));
&::-moz-focus-inner {
padding: 0;
border: 0;
}

.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
// screenshot tests and it generally looks better.
@include mdc-typography.smooth-font();
@include mdc-extended-fab-theme.theme-styles(
map.merge($mdc-extended-fab-token-slots, $exclude-tokens));
&:active, &:focus {
outline: none;
}
}

.mat-mdc-fab, .mat-mdc-mini-fab {
@include button-base.mat-private-button-interactive();
@include style-private.private-animation-noop();
flex-shrink: 0; // Prevent the button from shrinking since it's always supposed to be a circle.
&:hover {
cursor: pointer;
}

// 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 {
background: transparent;
opacity: 1;
& > svg {
width: 100%;
}

// MDC expects the fab icon to contain this HTML content:
Expand All @@ -73,7 +75,9 @@
// mixin will style the icons appropriately.
// stylelint-disable-next-line selector-class-pattern
.mat-icon, .material-icons {
@include mdc-fab.icon_();
transition: transform 180ms 90ms cubic-bezier(0, 0, 0.2, 1);
fill: currentColor;
will-change: transform;
}

.mat-mdc-focus-indicator::before {
Expand All @@ -93,18 +97,18 @@

@mixin _fab-elevation($mdc-tokens) {
@include token-utils.use-tokens($mdc-tokens...) {
@include button-base.mat-private-button-elevation(container-elevation);
@include token-utils.create-token-slot(box-shadow, container-elevation-shadow);

&:hover {
@include button-base.mat-private-button-elevation(hover-container-elevation);
@include token-utils.create-token-slot(box-shadow, hover-container-elevation-shadow);
}

&:focus {
@include button-base.mat-private-button-elevation(focus-container-elevation);
@include token-utils.create-token-slot(box-shadow, focus-container-elevation-shadow);
}

&:active, &:focus:active {
@include button-base.mat-private-button-elevation(pressed-container-elevation);
@include token-utils.create-token-slot(box-shadow, pressed-container-elevation-shadow);
}
}
}
Expand All @@ -113,10 +117,13 @@
@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 token-utils.use-tokens($mdc-tokens...) {
@include token-utils.create-token-slot(background-color, container-color);
@include token-utils.create-token-slot(border-radius, container-shape);
}

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

@include _fab-elevation($mdc-tokens);
Expand All @@ -137,15 +144,30 @@
}

.mat-mdc-mini-fab {
width: 40px;
height: 40px;

@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()));
$mdc-tokens: (tokens-mdc-extended-fab.$prefix, tokens-mdc-extended-fab.get-token-slots());

// Before tokens MDC included the font smoothing automatically, but with
// tokens it doesn't. We add it since it can cause tiny differences in
// screenshot tests and it generally looks better.
@include vendor-prefixes.smooth-font();
border-radius: 24px;
padding-left: 20px;
padding-right: 20px;
width: auto;
max-width: 100%;
line-height: normal;

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

@include button-base.mat-private-button-disabled {
// Necessary for interactive disabled buttons.
Expand All @@ -154,30 +176,40 @@
}
}

& > .mat-icon,
& > .material-icons { // stylelint-disable-line selector-class-pattern
@include mdc-fab.extended-icon-padding(
mdc-fab.$extended-icon-padding,
mdc-fab.$extended-label-padding
);
@include token-utils.use-tokens($mdc-tokens...) {
@include token-utils.create-token-slot(height, container-height);
@include token-utils.create-token-slot(border-radius, container-shape);
@include token-utils.create-token-slot(font-family, label-text-font);
@include token-utils.create-token-slot(font-size, label-text-size);
@include token-utils.create-token-slot(font-weight, label-text-weight);
@include token-utils.create-token-slot(letter-spacing, label-text-tracking);
}

// stylelint-disable selector-class-pattern
// 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.
[dir='rtl'] & .mdc-button__label + .mat-icon,
[dir='rtl'] & .mdc-button__label + .material-icons,
> .mat-icon,
> .material-icons {
margin-left: -8px;
margin-right: 12px;
}

.mdc-button__label + .mat-icon,
.mdc-button__label + .material-icons,
[dir='rtl'] & > .mat-icon,
[dir='rtl'] & > .material-icons {
margin-left: 12px;
margin-right: -8px;
}
// stylelint-enable selector-class-pattern

// 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.
// stylelint-disable-next-line selector-class-pattern
.mdc-button__label + .mat-icon, .mdc-button__label + .material-icons {
@include mdc-fab.extended-icon-padding(
mdc-fab.$extended-icon-padding,
mdc-fab.$extended-label-padding,
$is-icon-at-end: true
);
}
}

17 changes: 11 additions & 6 deletions src/material/core/tokens/m2/mdc/_extended-fab.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@use '@material/elevation/elevation-theme' as mdc-elevation;
@use '../../token-utils';
@use '../../../theming/inspection';

Expand Down Expand Up @@ -38,18 +39,22 @@ $prefix: (mdc, extended-fab);
pressed-ripple-color: null,
pressed-ripple-opacity: null,
pressed-state-layer-color: null,
pressed-state-layer-opacity: null
pressed-state-layer-opacity: null,
container-elevation: null,
focus-container-elevation: null,
hover-container-elevation: null,
pressed-container-elevation: null,
container-shadow-color: null,
);
}

// Tokens that can be configured through Angular Material's color theming API.
@function get-color-tokens($theme) {
@return (
container-elevation: 6,
focus-container-elevation: 8,
hover-container-elevation: 8,
pressed-container-elevation: 12,
container-shadow-color: #000,
container-elevation-shadow: mdc-elevation.elevation-box-shadow(6),
focus-container-elevation-shadow: mdc-elevation.elevation-box-shadow(8),
hover-container-elevation-shadow: mdc-elevation.elevation-box-shadow(8),
pressed-container-elevation-shadow: mdc-elevation.elevation-box-shadow(12),
);
}

Expand Down
Loading
Loading