sass-references/angular-material/material/radio/_radio-common.scss

257 lines
7.7 KiB
SCSS
Raw Normal View History

2024-12-06 10:42:08 +08:00
@use '../core/tokens/m2/mdc/radio' as tokens-mdc-radio;
@use '../core/tokens/token-utils';
$_icon-size: 20px;
@function _enter-transition($name) {
@return $name 90ms cubic-bezier(0, 0, 0.2, 1);
}
@function _exit-transition($name) {
@return $name 90ms cubic-bezier(0.4, 0, 0.6, 1);
}
// Structural styles for a radio button. Shared with the selection list.
@mixin radio-structure($is-interactive) {
$tokens: tokens-mdc-radio.$prefix, tokens-mdc-radio.get-token-slots();
.mdc-radio {
display: inline-block;
position: relative;
flex: 0 0 auto;
box-sizing: content-box;
width: $_icon-size;
height: $_icon-size;
cursor: pointer;
// This is something we inherited from MDC, but it shouldn't be necessary.
// Removing it will likely lead to screenshot diffs.
will-change: opacity, transform, border-color, color;
@include token-utils.use-tokens($tokens...) {
$size-token: token-utils.get-token-variable(state-layer-size);
padding: calc((#{$size-token} - #{$_icon-size}) / 2);
}
@if ($is-interactive) {
// MDC's hover indication comes from their ripple which we don't use.
&:hover .mdc-radio__native-control:not([disabled]):not(:focus) {
& ~ .mdc-radio__background::before {
opacity: 0.04;
transform: scale(1);
}
}
&:hover .mdc-radio__native-control:not([disabled]) ~ .mdc-radio__background {
.mdc-radio__outer-circle {
@include token-utils.use-tokens($tokens...) {
@include token-utils.create-token-slot(border-color, unselected-hover-icon-color);
}
}
}
&:hover .mdc-radio__native-control:enabled:checked + .mdc-radio__background {
.mdc-radio__outer-circle,
.mdc-radio__inner-circle {
@include token-utils.use-tokens($tokens...) {
@include token-utils.create-token-slot(border-color, selected-hover-icon-color);
}
}
}
&:active .mdc-radio__native-control:enabled:not(:checked) + .mdc-radio__background {
.mdc-radio__outer-circle {
@include token-utils.use-tokens($tokens...) {
@include token-utils.create-token-slot(border-color, unselected-pressed-icon-color);
}
}
}
&:active .mdc-radio__native-control:enabled:checked + .mdc-radio__background {
.mdc-radio__outer-circle,
.mdc-radio__inner-circle {
@include token-utils.use-tokens($tokens...) {
@include token-utils.create-token-slot(border-color, selected-pressed-icon-color);
}
}
}
}
}
.mdc-radio__background {
display: inline-block;
position: relative;
box-sizing: border-box;
width: $_icon-size;
height: $_icon-size;
&::before {
position: absolute;
transform: scale(0, 0);
border-radius: 50%;
opacity: 0;
pointer-events: none;
content: '';
transition: _exit-transition(opacity), _exit-transition(transform);
@include token-utils.use-tokens($tokens...) {
$size: token-utils.get-token-variable(state-layer-size);
$offset: calc(-1 * (#{$size} - #{$_icon-size}) / 2);
width: $size;
height: $size;
top: $offset;
left: $offset;
}
}
}
.mdc-radio__outer-circle {
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
width: 100%;
height: 100%;
border-width: 2px;
border-style: solid;
border-radius: 50%;
transition: _exit-transition(border-color);
}
.mdc-radio__inner-circle {
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
width: 100%;
height: 100%;
transform: scale(0, 0);
border-width: 10px;
border-style: solid;
border-radius: 50%;
transition: _exit-transition(transform), _exit-transition(border-color);
}
.mdc-radio__native-control {
position: absolute;
margin: 0;
padding: 0;
opacity: 0;
top: 0;
right: 0;
left: 0;
cursor: inherit;
z-index: 1;
@include token-utils.use-tokens($tokens...) {
@include token-utils.create-token-slot(width, state-layer-size);
@include token-utils.create-token-slot(height, state-layer-size);
}
&:checked, &:disabled {
+ .mdc-radio__background {
transition: _enter-transition(opacity), _enter-transition(transform);
.mdc-radio__outer-circle {
transition: _enter-transition(border-color);
}
.mdc-radio__inner-circle {
transition: _enter-transition(transform), _enter-transition(border-color);
}
}
}
@if ($is-interactive) {
&:focus + .mdc-radio__background::before {
transform: scale(1);
opacity: 0.12;
transition: _enter-transition(opacity), _enter-transition(transform);
}
}
&:disabled {
@include token-utils.use-tokens($tokens...) {
&:not(:checked) + .mdc-radio__background .mdc-radio__outer-circle {
@include token-utils.create-token-slot(border-color, disabled-unselected-icon-color);
@include token-utils.create-token-slot(opacity, disabled-unselected-icon-opacity);
}
+ .mdc-radio__background {
cursor: default;
.mdc-radio__inner-circle,
.mdc-radio__outer-circle {
@include token-utils.create-token-slot(border-color, disabled-selected-icon-color);
@include token-utils.create-token-slot(opacity, disabled-selected-icon-opacity);
}
}
}
}
&:enabled {
@include token-utils.use-tokens($tokens...) {
&:not(:checked) + .mdc-radio__background .mdc-radio__outer-circle {
@include token-utils.create-token-slot(border-color, unselected-icon-color);
}
&:checked + .mdc-radio__background {
.mdc-radio__outer-circle,
.mdc-radio__inner-circle {
@include token-utils.create-token-slot(border-color, selected-icon-color);
}
}
@if ($is-interactive) {
&:focus:checked + .mdc-radio__background {
.mdc-radio__inner-circle,
.mdc-radio__outer-circle {
@include token-utils.create-token-slot(border-color, selected-focus-icon-color);
}
}
}
}
}
&:checked + .mdc-radio__background .mdc-radio__inner-circle {
transform: scale(0.5);
transition: _enter-transition(transform), _enter-transition(border-color);
}
}
@if ($is-interactive) {
&.mat-mdc-radio-disabled-interactive .mdc-radio--disabled {
pointer-events: auto;
@include token-utils.use-tokens($tokens...) {
.mdc-radio__native-control:not(:checked) + .mdc-radio__background .mdc-radio__outer-circle {
@include token-utils.create-token-slot(border-color, disabled-unselected-icon-color);
@include token-utils.create-token-slot(opacity, disabled-unselected-icon-opacity);
}
&:hover .mdc-radio__native-control:checked + .mdc-radio__background,
.mdc-radio__native-control:checked:focus + .mdc-radio__background,
.mdc-radio__native-control + .mdc-radio__background {
.mdc-radio__inner-circle,
.mdc-radio__outer-circle {
@include token-utils.create-token-slot(border-color, disabled-selected-icon-color);
@include token-utils.create-token-slot(opacity, disabled-selected-icon-opacity);
}
}
}
}
}
}
// Conditionally disables the animations of the radio button.
@mixin radio-noop-animations() {
&._mat-animation-noopable {
.mdc-radio__background::before,
.mdc-radio__outer-circle,
.mdc-radio__inner-circle {
// Needs to be `!important`, because MDC's selectors are really specific.
transition: none !important;
}
}
}