Skip to content

Commit

Permalink
fix(material/slide-toggle): increase clickable area
Browse files Browse the repository at this point in the history
Fixes that the clickable area of the slide toggle was only on the `button` itself and the `label` which meant that there was some space above and below the label which isn't clickable.

Fixes #29483.
  • Loading branch information
crisbeto committed Jul 30, 2024
1 parent fd47a0e commit c42022b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 15 deletions.
31 changes: 16 additions & 15 deletions src/material/slide-toggle/slide-toggle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@use '../core/tokens/m2/mat/switch' as tokens-mat-switch;
@use '../core/tokens/m2/mdc/switch' as tokens-mdc-switch;
@use '../core/tokens/token-utils';
@use '../core/style/vendor-prefixes';

$_mdc-slots: (tokens-mdc-switch.$prefix, tokens-mdc-switch.get-token-slots());
$_mat-slots: (tokens-mat-switch.$prefix, tokens-mat-switch.get-token-slots());
Expand All @@ -12,7 +13,6 @@ $_interactive-disabled-selector: '.mat-mdc-slide-toggle-disabled-interactive.mdc
align-items: center;
background: none;
border: none;
cursor: pointer;
display: inline-flex;
flex-shrink: 0;
margin: 0;
Expand All @@ -21,15 +21,6 @@ $_interactive-disabled-selector: '.mat-mdc-slide-toggle-disabled-interactive.mdc
padding: 0;
position: relative;

&.mdc-switch--disabled {
cursor: default;
pointer-events: none;
}

&.mat-mdc-slide-toggle-disabled-interactive {
pointer-events: auto;
}

@include token-utils.use-tokens($_mdc-slots...) {
@include token-utils.create-token-slot(width, track-width);
}
Expand Down Expand Up @@ -503,8 +494,23 @@ $_interactive-disabled-selector: '.mat-mdc-slide-toggle-disabled-interactive.mdc
}

.mat-mdc-slide-toggle {
@include vendor-prefixes.user-select(none);
display: inline-block;
-webkit-tap-highlight-color: transparent;
cursor: pointer;

&:has(.mdc-switch--disabled) {
pointer-events: none;
cursor: auto;
}

&:has(.mat-mdc-slide-toggle-disabled-interactive) {
pointer-events: auto;
}

button, label {
cursor: inherit;
}

// Remove the native outline since we use the ripple for focus indication.
outline: 0;
Expand Down Expand Up @@ -564,11 +570,6 @@ $_interactive-disabled-selector: '.mat-mdc-slide-toggle-disabled-interactive.mdc
}
}

// If our slide-toggle is enabled the cursor on label should appear as a pointer.
.mdc-switch:enabled + .mdc-label {
cursor: pointer;
}

// TODO(wagnermaciel): Use our custom token system to emit this css rule.
.mdc-switch--disabled + label {
color: var(--mdc-switch-disabled-label-text-color);
Expand Down
9 changes: 9 additions & 0 deletions src/material/slide-toggle/slide-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ let nextUniqueId = 0;
'[class.mat-mdc-slide-toggle-checked]': 'checked',
'[class._mat-animation-noopable]': '_noopAnimations',
'[class]': 'color ? "mat-" + color : ""',
'(click)': '_handleHostClick($event)',
},
exportAs: 'matSlideToggle',
encapsulation: ViewEncapsulation.None,
Expand Down Expand Up @@ -319,4 +320,12 @@ export class MatSlideToggle
// `aria-labelledby`, because the button gets flagged as not having a label by tools like axe.
return this.ariaLabel ? null : this._labelId;
}

protected _handleHostClick(event: MouseEvent) {
// Treat any clicks on the container as clicks on the button element.
const switchEl = this._switchElement?.nativeElement;
if (switchEl && !switchEl.contains(event.target as HTMLElement)) {
this._handleClick();
}
}
}
2 changes: 2 additions & 0 deletions tools/public_api_guard/material/slide-toggle.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ export class MatSlideToggle implements OnDestroy, AfterContentInit, OnChanges, C
// (undocumented)
_getAriaLabelledBy(): string | null;
_handleClick(): void;
// (undocumented)
protected _handleHostClick(event: MouseEvent): void;
hideIcon: boolean;
id: string;
get inputId(): string;
Expand Down

0 comments on commit c42022b

Please sign in to comment.