Skip to content

refactor(material/radio): switch to tokens API #26876

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

Merged
merged 1 commit into from
Apr 3, 2023
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
46 changes: 46 additions & 0 deletions src/material/core/tokens/m2/mat/_radio.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@use 'sass:map';
@use '../../token-utils';
@use '../../../theming/theming';

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

// 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 ();
}

// Tokens that can be configured through Angular Material's color theming API.
@function get-color-tokens($config) {
$foreground: map.get($config, foreground);
$is-dark: map.get($config, is-dark);
$accent: map.get($config, accent);

@return (
ripple-color: if($is-dark, #fff, #000),
checked-ripple-color: theming.get-color-from-palette($accent, default),
disabled-label-color: theming.get-color-from-palette($foreground, disabled-text),
);
}

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

// Tokens that can be configured through Angular Material's density theming API.
@function get-density-tokens($config) {
@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 token-utils.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)
);
}
94 changes: 94 additions & 0 deletions src/material/core/tokens/m2/mdc/_radio.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
@use 'sass:map';
@use '../../../theming/palette';
@use '../../../theming/theming';
@use '../../token-utils';

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

// Tokens that can't be configured through Angular Material's current theming API,
// but may be in a future version of the theming API.
//
// Tokens that are available in MDC, but not used in Angular Material should be mapped to `null`.
// `null` indicates that we are intentionally choosing not to emit a slot or value for the token in
// our CSS.
@function get-unthemable-tokens() {
@return (
disabled-selected-icon-opacity: 0.38,
disabled-unselected-icon-opacity: 0.38,

// This is specified both here and in the density tokens, because it
// determines the size of the radio button itself and there are internal
// tests who don't configure the theme correctly.
state-layer-size: 40px,

// =============================================================================================
// = TOKENS NOT USED IN ANGULAR MATERIAL =
// =============================================================================================
selected-focus-state-layer-color: null,
selected-focus-state-layer-opacity: null,
selected-hover-state-layer-color: null,
selected-hover-state-layer-opacity: null,
selected-pressed-state-layer-color: null,
selected-pressed-state-layer-opacity: null,
unselected-focus-icon-color: null,
unselected-focus-state-layer-color: null,
unselected-focus-state-layer-opacity: null,
unselected-hover-state-layer-color: null,
unselected-hover-state-layer-opacity: null,
unselected-pressed-state-layer-color: null,
unselected-pressed-state-layer-opacity: null,
);
}

// Tokens that can be configured through Angular Material's color theming API.
@function get-color-tokens($config) {
$accent: map.get($config, accent);
$is-dark: map.get($config, is-dark);
$accent-color: theming.get-color-from-palette($accent, default);
$on-surface: if($is-dark, #fff, #000);
$icon-color: theming.get-color-from-palette(palette.$gray-palette, if($is-dark, 200, 900));

@return (
disabled-selected-icon-color: $on-surface,
disabled-unselected-icon-color: $on-surface,
unselected-hover-icon-color: $icon-color,
unselected-icon-color: rgba($on-surface, 0.54),
unselected-pressed-icon-color: rgba($on-surface, 0.54),
selected-focus-icon-color: $accent-color,
selected-hover-icon-color: $accent-color,
selected-icon-color: $accent-color,
selected-pressed-icon-color: $accent-color,
);
}

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

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

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

// 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 token-utils.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)
);
}
7 changes: 7 additions & 0 deletions src/material/core/tokens/tests/test-validate-tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@use '@material/icon-button/icon-button-theme' as mdc-icon-button-theme;
@use '@material/linear-progress/linear-progress-theme' as mdc-linear-progress-theme;
@use '@material/list/list-theme' as mdc-list-theme;
@use '@material/radio/radio-theme' as mdc-radio-theme;
@use '@material/theme/validate' as mdc-validate;

@use '../m2/mdc/circular-progress' as tokens-mdc-circular-progress;
Expand All @@ -17,6 +18,7 @@
@use '../m2/mdc/linear-progress' as tokens-mdc-linear-progress;
@use '../m2/mdc/list' as tokens-mdc-list;
@use '../m2/mdc/outlined-card' as tokens-mdc-outlined-card;
@use '../m2/mdc/radio' as tokens-mdc-radio;

@mixin validate-slots($component, $slots, $reference) {
@debug 'Validating #{$component}...';
Expand Down Expand Up @@ -65,3 +67,8 @@
$slots: tokens-mdc-linear-progress.get-token-slots(),
$reference: mdc-linear-progress-theme.$light-theme
);
@include validate-slots(
$component: 'm2.mdc.radio',
$slots: tokens-mdc-radio.get-token-slots(),
$reference: mdc-radio-theme.$light-theme
);
43 changes: 20 additions & 23 deletions src/material/list/_list-theme.scss
Original file line number Diff line number Diff line change
@@ -1,62 +1,59 @@
@use 'sass:map';
@use '@material/list/evolution-mixins';
@use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme;
@use '@material/radio/radio-theme' as mdc-radio-theme;
@use '@material/list/list-theme' as mdc-list-theme;

@use '../core/theming/theming';
@use '../core/tokens/m2/mdc/checkbox' as tokens-mdc-checkbox;
@use '../core/tokens/m2/mdc/radio' as tokens-mdc-radio;
@use '../core/tokens/m2/mdc/list' as tokens-mdc-list;
@use '../core/typography/typography';
@use '../core/typography/typography-utils';
@use '../core/mdc-helpers/mdc-helpers';
@use '../radio/radio-private';

@mixin color($config-or-theme) {
$config: theming.get-color-config($config-or-theme);
$primary: map.get($config, primary);
$accent: map.get($config, accent);
$warn: map.get($config, warn);
$mdc-list-color-tokens: tokens-mdc-list.get-color-tokens($config);
$inner-control-primary: map.merge($config, (accent: $primary));
$inner-control-accent: map.merge($config, (accent: $accent));
$inner-control-warn: map.merge($config, (accent: $warn));


// Add values for MDC list tokens.
.mat-mdc-list-base {
@include mdc-list-theme.theme($mdc-list-color-tokens);
}

// TODO(mmalerba): This should use MDC radio's token API instead.
@include mdc-helpers.using-mdc-theme($config) {
.mdc-list-item__start,
.mdc-list-item__end {
@include mdc-radio-theme.theme(tokens-mdc-radio.get-color-tokens($inner-control-primary));
}

.mat-accent {
.mdc-list-item__start,
.mdc-list-item__end {
@include radio-private.private-radio-color($config, theming.get-color-from-palette($primary));
}

.mat-accent {
.mdc-list-item__start,
.mdc-list-item__end {
@include radio-private.private-radio-color(
$config, theming.get-color-from-palette($accent));
}
@include mdc-radio-theme.theme(tokens-mdc-radio.get-color-tokens($inner-control-accent));
}
}

.mat-warn {
.mdc-list-item__start,
.mdc-list-item__end {
@include radio-private.private-radio-color($config, theming.get-color-from-palette($warn));
}
.mat-warn {
.mdc-list-item__start,
.mdc-list-item__end {
@include mdc-radio-theme.theme(tokens-mdc-radio.get-color-tokens($inner-control-warn));
}
}

.mat-mdc-list-option {
$primary-config: map.merge($config, (accent: $primary));
@include mdc-checkbox-theme.theme(tokens-mdc-checkbox.get-color-tokens($primary-config));
@include mdc-checkbox-theme.theme(tokens-mdc-checkbox.get-color-tokens($inner-control-primary));
}
.mat-mdc-list-option.mat-accent {
@include mdc-checkbox-theme.theme(tokens-mdc-checkbox.get-color-tokens($config));
@include mdc-checkbox-theme.theme(tokens-mdc-checkbox.get-color-tokens($inner-control-accent));
}
.mat-mdc-list-option.mat-warn {
$warn-config: map.merge($config, (accent: $warn));
@include mdc-checkbox-theme.theme(tokens-mdc-checkbox.get-color-tokens($warn-config));
@include mdc-checkbox-theme.theme(tokens-mdc-checkbox.get-color-tokens($inner-control-warn));
}

// There is no token for activated color on nav list.
Expand Down
18 changes: 2 additions & 16 deletions src/material/list/list-option.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
@use 'sass:map';
@use '@material/checkbox/checkbox' as mdc-checkbox;
@use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme;
@use '@material/radio/radio' as mdc-radio;
@use '@material/radio/radio-theme' as mdc-radio-theme;

@use '../core/mdc-helpers/mdc-helpers';
@use '../core/tokens/m2/mdc/checkbox' as tokens-mdc-checkbox;
@use '../radio/radio-private';
@use '../core/tokens/m2/mdc/radio' as tokens-mdc-radio;
@use './list-option-trailing-avatar-compat';
@use './list-item-hcm-indicator';

Expand All @@ -29,16 +28,6 @@
}
}

$without-ripple-config: (
// Since this checkbox/radio isn't interactive, we can exclude the focus/hover/press styles.
selected-focus-icon-color: null,
selected-hover-icon-color: null,
selected-pressed-icon-color: null,
unselected-focus-icon-color: null,
unselected-hover-icon-color: null,
unselected-pressed-icon-color: null,
);

// We can't use the MDC checkbox here directly, because this checkbox is purely
// decorative and including the MDC one will bring in unnecessary JS.
.mdc-checkbox {
Expand All @@ -50,14 +39,11 @@
// We can't use the MDC radio here directly, because this radio is purely
// decorative and including the MDC one will bring in unnecessary JS.
.mdc-radio {
$config: map.merge(radio-private.$private-radio-theme-config, $without-ripple-config);

// MDC theme styles also include structural styles so we have to include the theme at least
// once here. The values will be overwritten by our own theme file afterwards.
@include mdc-radio-theme.theme-styles($config);
@include mdc-radio-theme.theme-styles(tokens-mdc-radio.get-token-slots());
}


// The internal checkbox/radio is purely decorative, but because it's an `input`, the user can
// still focus it by tabbing or clicking. Furthermore, `mat-list-option` has the `option` role
// which doesn't allow a nested `input`. We use `display: none` both to remove it from the tab
Expand Down
60 changes: 0 additions & 60 deletions src/material/radio/_radio-private.scss

This file was deleted.

Loading