257 lines
7.7 KiB
SCSS
257 lines
7.7 KiB
SCSS
|
|
@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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|