123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- @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...) {
- // stylelint-disable selector-combinator-space-before
- .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);
- }
- // stylelint-enable selector-combinator-space-before
- &: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;
- }
- }
- }
|