Skip to content

Commit

Permalink
fix(material/button): calculate icon button padding based on tokens
Browse files Browse the repository at this point in the history
Uses token values to calculate the padding for icon buttons, instead of doing it statically.
  • Loading branch information
crisbeto committed Jan 16, 2024
1 parent 1e48cd4 commit e05795d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
22 changes: 17 additions & 5 deletions src/material/button/icon-button.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@use 'sass:map';
@use '@material/icon-button/icon-button' as mdc-icon-button;
@use '@material/icon-button/icon-button-theme' as mdc-icon-button-theme;
@use '@material/theme/custom-properties' as mdc-custom-properties;
Expand All @@ -18,15 +19,14 @@

.mat-mdc-icon-button {
// Add the official slots for the MDC component.
@include mdc-icon-button-theme.theme-styles($token-slots);
@include mdc-icon-button-theme.theme-styles(map.merge($token-slots, (
// Exclude the state layer size since we'll re-emit it below with a default value.
state-layer-size: null,
)));
}
}

.mat-mdc-icon-button {
// Not all applications import the theming which would apply a default padding.
// TODO: Determine how to enforce theming exists, otherwise padding will be unset.
padding: 12px;

// Border radius is inherited by ripple to know its shape. Set to 50% so the ripple is round.
border-radius: 50%;

Expand All @@ -42,6 +42,18 @@

@include token-utils.use-tokens(
tokens-mdc-icon-button.$prefix, tokens-mdc-icon-button.get-token-slots()) {
$button-size: var(#{token-utils.get-token-variable(state-layer-size)}, 48px);
$icon-size: var(#{token-utils.get-token-variable(icon-size)}, 24px);

// We emit these tokens ourselves here so we can provide a default value.
// This avoids a lot internal breakages in apps that didn't include the icon button theme.
width: $button-size;
height: $button-size;

// Note: this is wrapped in an interpolation, because of an internal lint rule that bans
// interpolations in `calc`, even though this is the only way to achieve what we're looking for.
padding: #{calc(#{calc(#{$button-size} - #{$icon-size})} / 2)};

// Icon size used to be placed on the host element. Now, in `theme-styles` it is placed on
// the unused `.mdc-button__icon` class. Explicitly set the font-size here.
@include token-utils.create-token-slot(font-size, icon-size);
Expand Down
22 changes: 15 additions & 7 deletions src/material/core/tokens/m2/mdc/_icon-button.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@use 'sass:map';
@use '../../../style/sass-utils';
@use '../../../theming/theming';
@use '../../../theming/inspection';
@use '../../token-utils';

Expand All @@ -13,12 +15,6 @@ $prefix: (mdc, icon-button);
// our CSS.
@function get-unthemable-tokens() {
@return (
// =============================================================================================
// = TOKENS THAT SHOULD NOT BE CUSTOMIZABLE =
// =============================================================================================
// Determines the size of the icon. Name is inaccurate - applies to the whole component,
// not just the state layer.
state-layer-size: 48px,
// MDC's icon size applied to svg and img elements inside the component
icon-size: 24px,

Expand Down Expand Up @@ -68,7 +64,19 @@ $prefix: (mdc, icon-button);

// Tokens that can be configured through Angular Material's density theming API.
@function get-density-tokens($theme) {
@return ();
$scale: theming.clamp-density(inspection.get-theme-density($theme), -5);

@return (
// The diameter of the checkbox's ripple.
state-layer-size: map.get((
0: 48px,
-1: 44px,
-2: 40px,
-3: 36px,
-4: 32px,
-5: 28px,
), $scale)
);
}

// Combines the tokens generated by the above functions into a single map with placeholder values.
Expand Down

0 comments on commit e05795d

Please sign in to comment.