Skip to content

Commit

Permalink
fix(material/slide-toggle): fix m3 slide-toggle handle (#28503)
Browse files Browse the repository at this point in the history
* fix(material/slide-toggle): boilerplate for m3 custom tokens

* create a custom-tokens function
* set up theme mixins to create custom token values
* create an m2 mat- tokens file
* added a new namespace in _m3-tokens.scss
* appended the new tokens to m2-tokens-from-theme

* fix(material/slide-toggle): fix m3 width, height, and margin
  • Loading branch information
wagnermaciel authored Feb 1, 2024
1 parent f20e4ed commit d799c04
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 7 deletions.
19 changes: 19 additions & 0 deletions src/material-experimental/theming/_custom-tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,25 @@
));
}

/// Generates custom tokens for the mat-slide-toggle.
/// @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-slide-toggle
@function switch($systems, $exclude-hardcoded) {
@return ((
unselected-handle-size: 16px,
selected-handle-size: 24px,
with-icon-handle-size: 24px,
pressed-handle-size: 28px,
selected-handle-horizontal-margin: 0 24px,
selected-with-icon-handle-horizontal-margin: 0 24px,
selected-pressed-handle-horizontal-margin: 0 22px,
unselected-handle-horizontal-margin: 0 8px,
unselected-with-icon-handle-horizontal-margin: 0 4px,
unselected-pressed-handle-horizontal-margin: 0 2px,
), ());
}

/// Generates custom tokens for the mat-snack-bar.
/// @param {Map} $systems The MDC system tokens
/// @param {Boolean} $exclude-hardcoded Whether to exclude hardcoded token values
Expand Down
5 changes: 5 additions & 0 deletions src/material-experimental/theming/_m3-tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,11 @@
custom-tokens.stepper($systems, $exclude-hardcoded),
$token-slots
),
_namespace-tokens(
(mat, switch),
custom-tokens.switch($systems, $exclude-hardcoded),
$token-slots
),
_namespace-tokens(
(mat, tab-header),
custom-tokens.tab-header($systems, $exclude-hardcoded),
Expand Down
2 changes: 2 additions & 0 deletions src/material/core/tokens/m2/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@use './mat/select' as tokens-mat-select;
@use './mat/sidenav' as tokens-mat-sidenav;
@use './mat/slider' as tokens-mat-slider;
@use './mat/switch' as tokens-mat-switch;
@use './mat/snack-bar' as tokens-mat-snack-bar;
@use './mat/sort' as tokens-mat-sort;
@use './mat/standard-button-toggle' as tokens-mat-button-toggle;
Expand Down Expand Up @@ -142,6 +143,7 @@
_get-tokens-for-module($theme, tokens-mat-select),
_get-tokens-for-module($theme, tokens-mat-sidenav),
_get-tokens-for-module($theme, tokens-mat-slider),
_get-tokens-for-module($theme, tokens-mat-switch),
_get-tokens-for-module($theme, tokens-mat-snack-bar),
_get-tokens-for-module($theme, tokens-mat-sort),
_get-tokens-for-module($theme, tokens-mat-stepper),
Expand Down
49 changes: 49 additions & 0 deletions src/material/core/tokens/m2/mat/_switch.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@use '../../token-utils';
@use '../../../style/sass-utils';

// The prefix used to generate the fully qualified name for tokens in this file.
$prefix: (mat, switch);

// Tokens that can't be configured through Angular Material's current theming API,
// but may be in a future version of the theming API.
@function get-unthemable-tokens() {
@return (
unselected-handle-size: 20px,
selected-handle-size: 20px,
pressed-handle-size: 20px,
with-icon-handle-size: 20px,

selected-handle-horizontal-margin: 0,
selected-with-icon-handle-horizontal-margin: 0,
selected-pressed-handle-horizontal-margin: 0,
unselected-handle-horizontal-margin: 0,
unselected-with-icon-handle-horizontal-margin: 0,
unselected-pressed-handle-horizontal-margin: 0,
);
}

// Tokens that can be configured through Angular Material's color theming API.
@function get-color-tokens($theme) {
@return ();
}

// Tokens that can be configured through Angular Material's typography theming API.
@function get-typography-tokens($theme) {
@return ();
}

// Tokens that can be configured through Angular Material's density theming API.
@function get-density-tokens($theme) {
@return ();
}

// Combines the tokens generated by the above functions into a single map with placeholder values.
// This is used to create token slots.
@function get-token-slots() {
@return sass-utils.deep-merge-all(
get-unthemable-tokens(),
get-color-tokens(token-utils.$placeholder-color-config),
get-typography-tokens(token-utils.$placeholder-typography-config),
get-density-tokens(token-utils.$placeholder-density-config)
);
}
27 changes: 20 additions & 7 deletions src/material/slide-toggle/_slide-toggle-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@use '../core/tokens/token-utils';
@use '../core/typography/typography';
@use '../core/tokens/m2/mdc/form-field' as tokens-mdc-form-field;
@use '../core/tokens/m2/mat/switch' as tokens-mat-switch;
@use '../core/tokens/m2/mdc/switch' as tokens-mdc-switch;

/// Outputs base theme styles (styles not dependent on the color, typography, or density settings)
Expand All @@ -17,7 +18,10 @@
}
@else {
@include sass-utils.current-selector-or-root() {
@include mdc-switch-theme.theme(tokens-mdc-switch.get-unthemable-tokens());
$mat-tokens: tokens-mat-switch.get-unthemable-tokens();
$mdc-tokens: tokens-mdc-switch.get-unthemable-tokens();
@include mdc-switch-theme.theme($mdc-tokens);
@include token-utils.create-token-values(tokens-mat-switch.$prefix, $mat-tokens);
}
}
}
Expand All @@ -33,11 +37,13 @@
}
@else {
$is-dark: inspection.get-theme-type($theme) == dark;
$mdc-switch-color-tokens: tokens-mdc-switch.get-color-tokens($theme);
$mat-tokens: tokens-mat-switch.get-color-tokens($theme);
$mdc-tokens: tokens-mdc-switch.get-color-tokens($theme);

// Add values for MDC slide toggles tokens
@include sass-utils.current-selector-or-root() {
@include mdc-switch-theme.theme($mdc-switch-color-tokens);
@include mdc-switch-theme.theme($mdc-tokens);
@include token-utils.create-token-values(tokens-mat-switch.$prefix, $mat-tokens);

// TODO(wagnermaciel): Use our token system to define this css variable.
--mdc-switch-disabled-label-text-color: #{inspection.get-theme-color(
Expand Down Expand Up @@ -71,11 +77,13 @@
@include _theme-from-tokens(inspection.get-theme-tokens($theme, typography));
}
@else {
$mdc-switch-typography-tokens: tokens-mdc-switch.get-typography-tokens($theme);
$mat-tokens: tokens-mat-switch.get-typography-tokens($theme);
$mdc-tokens: tokens-mdc-switch.get-typography-tokens($theme);

// Add values for MDC slide toggle tokens
@include sass-utils.current-selector-or-root() {
@include mdc-switch-theme.theme($mdc-switch-typography-tokens);
@include mdc-switch-theme.theme($mdc-tokens);
@include token-utils.create-token-values(tokens-mat-switch.$prefix, $mat-tokens);

.mat-mdc-slide-toggle {
@include mdc-form-field-theme.theme(tokens-mdc-form-field.get-typography-tokens($theme));
Expand All @@ -92,6 +100,8 @@
}
@else {
@include sass-utils.current-selector-or-root() {
$mat-tokens: tokens-mat-switch.get-density-tokens($theme);
$mdc-tokens: tokens-mdc-switch.get-density-tokens($theme);
@include mdc-switch-theme.theme(tokens-mdc-switch.get-density-tokens($theme));
}
}
Expand Down Expand Up @@ -123,10 +133,13 @@
}

@mixin _theme-from-tokens($tokens, $options...) {
$mdc-switch-tokens: token-utils.get-tokens-for($tokens, tokens-mdc-switch.$prefix, $options...);
// Don't pass $options here, since the mdc-form-field doesn't support color options,
// only the mdc-switch does.
$mdc-form-field-tokens: token-utils.get-tokens-for($tokens, tokens-mdc-form-field.$prefix);
@include mdc-switch-theme.theme($mdc-switch-tokens);
$mat-switch-tokens: token-utils.get-tokens-for($tokens, tokens-mat-switch.$prefix);
$mdc-switch-tokens: token-utils.get-tokens-for($tokens, tokens-mdc-switch.$prefix, $options...);

@include mdc-form-field-theme.theme($mdc-form-field-tokens);
@include mdc-switch-theme.theme($mdc-switch-tokens);
@include token-utils.create-token-values(tokens-mat-switch.$prefix, $mat-switch-tokens);
}
66 changes: 66 additions & 0 deletions src/material/slide-toggle/slide-toggle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
@use '@material/ripple' as mdc-ripple;
@use '../core/style/layout-common';
@use '@material/theme/custom-properties' as mdc-custom-properties;
@use '../core/tokens/m2/mat/switch' as m2-mat-switch;
@use '../core/tokens/m2/mdc/switch' as m2-mdc-switch;
@use '../core/tokens/token-utils';

@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
$mdc-switch-token-slots: m2-mdc-switch.get-token-slots();
Expand Down Expand Up @@ -115,3 +117,67 @@
cursor: pointer;
}
}

// Used for M3 animations. Does not affect the M2 slide-toggle
// because the width and height are static, and the margin is unused.
.mdc-switch__handle {
transition:
width 75ms cubic-bezier(0.4, 0, 0.2, 1),
height 75ms cubic-bezier(0.4, 0, 0.2, 1),
margin 75ms cubic-bezier(0.4, 0, 0.2, 1);
}

@include token-utils.use-tokens(m2-mat-switch.$prefix, m2-mat-switch.get-token-slots()) {
.mat-mdc-slide-toggle {
.mdc-switch--unselected .mdc-switch__handle {
@include token-utils.create-token-slot(width, unselected-handle-size);
@include token-utils.create-token-slot(height, unselected-handle-size);
}

.mdc-switch--selected .mdc-switch__handle {
@include token-utils.create-token-slot(width, selected-handle-size);
@include token-utils.create-token-slot(height, selected-handle-size);
}

.mdc-switch__handle:has(.mdc-switch__icons) {
@include token-utils.create-token-slot(width, with-icon-handle-size);
@include token-utils.create-token-slot(height, with-icon-handle-size);
}

&:active .mdc-switch:not(.mdc-switch--disabled) .mdc-switch__handle {
@include token-utils.create-token-slot(width, pressed-handle-size);
@include token-utils.create-token-slot(height, pressed-handle-size);
}
}
}

@include token-utils.use-tokens(m2-mat-switch.$prefix, m2-mat-switch.get-token-slots()) {
.mat-mdc-slide-toggle {
.mdc-switch--selected .mdc-switch__handle {
@include token-utils.create-token-slot(margin, selected-handle-horizontal-margin);

&:has(.mdc-switch__icons) {
@include token-utils.create-token-slot(margin, selected-with-icon-handle-horizontal-margin);
}
}

.mdc-switch--unselected .mdc-switch__handle {
@include token-utils.create-token-slot(margin, unselected-handle-horizontal-margin);

&:has(.mdc-switch__icons) {
@include token-utils.create-token-slot(
margin,
unselected-with-icon-handle-horizontal-margin,
);
}
}

&:active .mdc-switch--selected:not(.mdc-switch--disabled) .mdc-switch__handle {
@include token-utils.create-token-slot(margin, selected-pressed-handle-horizontal-margin);
}

&:active .mdc-switch--unselected:not(.mdc-switch--disabled) .mdc-switch__handle {
@include token-utils.create-token-slot(margin, unselected-pressed-handle-horizontal-margin);
}
}
}

0 comments on commit d799c04

Please sign in to comment.