123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- @use '../core/tokens/token-utils';
- @use '../core/style/layout-common';
- // Adds styles necessary to provide stateful interactions with the button. This includes providing
- // content for the state container's ::before and ::after so that they can be given a background
- // color and opacity for states like hover, active, and focus. Additionally, adds styles to the
- // ripple and state container so that they fill the button, match the border radius, and avoid
- // pointer events.
- @mixin mat-private-button-interactive($focus-indicator-inherits-shape: true) {
- -webkit-tap-highlight-color: transparent;
- // The ripple container should match the bounds of the entire button.
- .mat-mdc-button-ripple,
- .mat-mdc-button-persistent-ripple,
- .mat-mdc-button-persistent-ripple::before {
- @include layout-common.fill;
- // Disable pointer events for the ripple container and state overlay because the container
- // will overlay the user content and we don't want to disable mouse events on the user content.
- // Pointer events can be safely disabled because the ripple trigger element is the host element.
- pointer-events: none;
- // Inherit the border radius from the parent so that state overlay and ripples don't exceed the
- // parent button boundaries. Note that an inherited border radius does not work properly if
- // the actual button element does have a border because it causes the inner content to be
- // smaller. We have special logic for stroked buttons to handle this scenario.
- border-radius: inherit;
- }
- // This style used to be applied by the MatRipple
- // directive, which is no longer attached to this element.
- .mat-mdc-button-ripple {
- overflow: hidden;
- }
- // We use ::before so that we can reuse some of MDC's theming.
- .mat-mdc-button-persistent-ripple::before {
- content: '';
- opacity: 0;
- }
- // The content should appear over the state and ripple layers, otherwise they may adversely affect
- // the accessibility of the text content.
- .mdc-button__label,
- .mat-icon {
- z-index: 1;
- position: relative;
- }
- // The focus indicator should match the bounds of the entire button.
- .mat-focus-indicator {
- @include layout-common.fill();
- @if ($focus-indicator-inherits-shape) {
- border-radius: inherit;
- }
- }
- &:focus > .mat-focus-indicator::before {
- content: '';
- @if ($focus-indicator-inherits-shape) {
- border-radius: inherit;
- }
- }
- }
- @mixin mat-private-button-ripple($prefix, $slots) {
- @include token-utils.use-tokens($prefix, $slots) {
- .mat-ripple-element {
- @include token-utils.create-token-slot(background-color, ripple-color);
- }
- .mat-mdc-button-persistent-ripple::before {
- @include token-utils.create-token-slot(background-color, state-layer-color);
- }
- &.mat-mdc-button-disabled .mat-mdc-button-persistent-ripple::before {
- @include token-utils.create-token-slot(background-color, disabled-state-layer-color);
- }
- &:hover > .mat-mdc-button-persistent-ripple::before {
- @include token-utils.create-token-slot(opacity, hover-state-layer-opacity);
- }
- &.cdk-program-focused,
- &.cdk-keyboard-focused,
- &.mat-mdc-button-disabled-interactive:focus {
- > .mat-mdc-button-persistent-ripple::before {
- @include token-utils.create-token-slot(opacity, focus-state-layer-opacity);
- }
- }
- &:active > .mat-mdc-button-persistent-ripple::before {
- @include token-utils.create-token-slot(opacity, pressed-state-layer-opacity);
- }
- }
- }
- // MDC's disabled buttons define a default cursor with pointer-events none. However, they select
- // :disabled for this, which does not affect anchor tags.
- // TODO(andrewseguin): Discuss with the MDC team about a mixin we can call for applying this style,
- // and note that having pointer-events may have unintended side-effects, e.g. allowing the user
- // to click the target underneath the button.
- @mixin mat-private-button-disabled() {
- // `[disabled]` shouldn't be necessary, but we keep it to maintain
- // compatibility with apps setting it through host bindings.
- &[disabled],
- &.mat-mdc-button-disabled {
- cursor: default;
- pointer-events: none;
- @content;
- }
- &.mat-mdc-button-disabled-interactive {
- pointer-events: auto;
- }
- }
- // Adds an elevation shadow to a button.
- @mixin mat-private-button-elevation($token-name) {
- // MDC outputs a variable that is the same as the token name, but suffixed with `-shadow`.
- box-shadow: token-utils.get-token-variable($token-name + '-shadow');
- }
- @mixin mat-private-button-touch-target($is-square, $prefix, $slots) {
- .mat-mdc-button-touch-target {
- position: absolute;
- top: 50%;
- height: 48px;
- @if $is-square {
- left: 50%;
- width: 48px;
- transform: translate(-50%, -50%);
- } @else {
- left: 0;
- right: 0;
- transform: translateY(-50%);
- }
- @include token-utils.use-tokens($prefix, $slots) {
- @include token-utils.create-token-slot(display, touch-target-display);
- }
- }
- }
- @mixin mat-private-button-horizontal-layout($prefix, $slots, $has-with-icon-padding) {
- @include token-utils.use-tokens($prefix, $slots) {
- $icon-spacing: token-utils.get-token-variable(icon-spacing, true);
- $icon-offset: token-utils.get-token-variable(icon-offset, true);
- @if ($has-with-icon-padding) {
- $with-icon-horizontal-padding:
- token-utils.get-token-variable(with-icon-horizontal-padding, true);
- // stylelint-disable-next-line selector-class-pattern
- &:has(.material-icons, mat-icon, [matButtonIcon]) {
- padding: 0 $with-icon-horizontal-padding;
- }
- }
- // MDC expects button icons to contain this HTML content:
- // ```html
- // <span class="mdc-button__icon material-icons">favorite</span>
- // ```
- // However, Angular Material expects a `mat-icon` instead. The following
- // styles will lay out the icons appropriately.
- & > .mat-icon {
- margin-right: $icon-spacing;
- margin-left: $icon-offset;
- [dir='rtl'] & {
- margin-right: $icon-offset;
- margin-left: $icon-spacing;
- }
- }
- .mdc-button__label + .mat-icon {
- margin-right: $icon-offset;
- margin-left: $icon-spacing;
- [dir='rtl'] & {
- margin-right: $icon-spacing;
- margin-left: $icon-offset;
- }
- }
- }
- }
|