Skip to content

Use classList.toggle #23273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions src/cdk/a11y/focus-monitor/focus-monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,14 +308,6 @@ export class FocusMonitor implements OnDestroy {
return doc.defaultView || window;
}

private _toggleClass(element: Element, className: string, shouldSet: boolean) {
if (shouldSet) {
element.classList.add(className);
} else {
element.classList.remove(className);
}
}

private _getFocusOrigin(focusEventTarget: HTMLElement | null): FocusOrigin {
if (this._origin) {
// If the origin was realized via a touch interaction, we need to perform additional checks
Expand Down Expand Up @@ -368,11 +360,11 @@ export class FocusMonitor implements OnDestroy {
* @param origin The focus origin.
*/
private _setClasses(element: HTMLElement, origin?: FocusOrigin): void {
this._toggleClass(element, 'cdk-focused', !!origin);
this._toggleClass(element, 'cdk-touch-focused', origin === 'touch');
this._toggleClass(element, 'cdk-keyboard-focused', origin === 'keyboard');
this._toggleClass(element, 'cdk-mouse-focused', origin === 'mouse');
this._toggleClass(element, 'cdk-program-focused', origin === 'program');
element.classList.toggle('cdk-focused', !!origin);
element.classList.toggle('cdk-touch-focused', origin === 'touch');
element.classList.toggle('cdk-keyboard-focused', origin === 'keyboard');
element.classList.toggle('cdk-mouse-focused', origin === 'mouse');
element.classList.toggle('cdk-program-focused', origin === 'program');
}

/**
Expand Down
12 changes: 4 additions & 8 deletions src/cdk/overlay/overlay-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,15 +469,11 @@ export class OverlayRef implements PortalOutlet, OverlayReference {

/** Toggles a single CSS class or an array of classes on an element. */
private _toggleClasses(element: HTMLElement, cssClasses: string | string[], isAdd: boolean) {
const classList = element.classList;
const classes = coerceArray(cssClasses || []).filter(c => !!c);

coerceArray(cssClasses).forEach(cssClass => {
// We can't do a spread here, because IE doesn't support setting multiple classes.
// Also trying to add an empty string to a DOMTokenList will throw.
if (cssClass) {
isAdd ? classList.add(cssClass) : classList.remove(cssClass);
}
});
if (classes.length) {
isAdd ? element.classList.add(...classes) : element.classList.remove(...classes);
}
}

/** Detaches the overlay content next time the zone stabilizes. */
Expand Down
9 changes: 9 additions & 0 deletions src/cdk/overlay/overlay.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,17 @@ describe('Overlay', () => {
const overlayRef = overlay.create();
overlayRef.attach(componentPortal);

// Empty string
expect(() => overlayRef.addPanelClass('')).not.toThrow();
expect(() => overlayRef.removePanelClass('')).not.toThrow();

// Empty array
expect(() => overlayRef.addPanelClass([])).not.toThrow();
expect(() => overlayRef.removePanelClass([])).not.toThrow();

// Array containing only the empty string
expect(() => overlayRef.addPanelClass([''])).not.toThrow();
expect(() => overlayRef.removePanelClass([''])).not.toThrow();
});

describe('positioning', () => {
Expand Down
6 changes: 1 addition & 5 deletions src/dev-app/connected-overlay/connected-overlay-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,7 @@ export class ConnectedOverlayDemo {
const box = document.querySelector<HTMLElement>('.cdk-overlay-connected-position-bounding-box');

if (box) {
if (showBoundingBox) {
box.classList.add('demo-bounding-box-visible');
} else {
box.classList.remove('demo-bounding-box-visible');
}
box.classList.toggle('demo-bounding-box-visible', showBoundingBox);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,7 @@ export class MatSnackBarContainer extends BasePortalOutlet
}

private _setClass(cssClass: string, active: boolean) {
const classList = this._elementRef.nativeElement.classList;
active ? classList.add(cssClass) : classList.remove(cssClass);
this._elementRef.nativeElement.classList.toggle(cssClass, active);
}

/** Applies the user-configured CSS classes to the snack bar. */
Expand Down
1 change: 1 addition & 0 deletions src/material/bottom-sheet/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ng_module(
"//src:dev_mode_types",
"//src/cdk/a11y",
"//src/cdk/bidi",
"//src/cdk/coercion",
"//src/cdk/keycodes",
"//src/cdk/layout",
"//src/cdk/overlay",
Expand Down
55 changes: 24 additions & 31 deletions src/material/bottom-sheet/bottom-sheet-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,37 @@
* found in the LICENSE file at https://angular.io/license
*/

import {AnimationEvent} from '@angular/animations';
import {FocusTrap, FocusTrapFactory, InteractivityChecker} from '@angular/cdk/a11y';
import {coerceArray} from '@angular/cdk/coercion';
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
import {_getFocusedElementPierceShadowDom} from '@angular/cdk/platform';
import {
BasePortalOutlet,
CdkPortalOutlet,
ComponentPortal,
DomPortal,
TemplatePortal,
} from '@angular/cdk/portal';
import {DOCUMENT} from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ComponentRef,
EmbeddedViewRef,
ViewChild,
OnDestroy,
ElementRef,
ChangeDetectionStrategy,
ViewEncapsulation,
ChangeDetectorRef,
EmbeddedViewRef,
EventEmitter,
Inject,
Optional,
NgZone,
OnDestroy,
Optional,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import {AnimationEvent} from '@angular/animations';
import {
BasePortalOutlet,
ComponentPortal,
TemplatePortal,
CdkPortalOutlet,
DomPortal,
} from '@angular/cdk/portal';
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
import {MatBottomSheetConfig} from './bottom-sheet-config';
import {matBottomSheetAnimations} from './bottom-sheet-animations';
import {Subscription} from 'rxjs';
import {DOCUMENT} from '@angular/common';
import {FocusTrap, FocusTrapFactory, InteractivityChecker} from '@angular/cdk/a11y';
import {_getFocusedElementPierceShadowDom} from '@angular/cdk/platform';
import {matBottomSheetAnimations} from './bottom-sheet-animations';
import {MatBottomSheetConfig} from './bottom-sheet-config';

// TODO(crisbeto): consolidate some logic between this, MatDialog and MatSnackBar

Expand Down Expand Up @@ -178,8 +179,7 @@ export class MatBottomSheetContainer extends BasePortalOutlet implements OnDestr
}

private _toggleClass(cssClass: string, add: boolean) {
const classList = this._elementRef.nativeElement.classList;
add ? classList.add(cssClass) : classList.remove(cssClass);
this._elementRef.nativeElement.classList.toggle(cssClass, add);
}

private _validatePortalAttached() {
Expand All @@ -190,14 +190,7 @@ export class MatBottomSheetContainer extends BasePortalOutlet implements OnDestr

private _setPanelClass() {
const element: HTMLElement = this._elementRef.nativeElement;
const panelClass = this.bottomSheetConfig.panelClass;

if (Array.isArray(panelClass)) {
// Note that we can't use a spread here, because IE doesn't support multiple arguments.
panelClass.forEach(cssClass => element.classList.add(cssClass));
} else if (panelClass) {
element.classList.add(panelClass);
}
element.classList.add(...coerceArray(this.bottomSheetConfig.panelClass || []));
}

/**
Expand Down
3 changes: 1 addition & 2 deletions src/material/core/line/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ export function setLines(lines: QueryList<unknown>, element: ElementRef<HTMLElem

/** Adds or removes a class from an element. */
function setClass(element: ElementRef<HTMLElement>, className: string, isAdd: boolean): void {
const classList = element.nativeElement.classList;
isAdd ? classList.add(className) : classList.remove(className);
element.nativeElement.classList.toggle(className, isAdd);
}

@NgModule({
Expand Down
3 changes: 1 addition & 2 deletions src/material/snack-bar/snack-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ export class MatSnackBar implements OnDestroy {
this._breakpointObserver.observe(Breakpoints.HandsetPortrait).pipe(
takeUntil(overlayRef.detachments())
).subscribe(state => {
const classList = overlayRef.overlayElement.classList;
state.matches ? classList.add(this.handsetCssClass) : classList.remove(this.handsetCssClass);
overlayRef.overlayElement.classList.toggle(this.handsetCssClass, state.matches);
});

if (config.announcementMessage) {
Expand Down
46 changes: 0 additions & 46 deletions tools/tslint-rules/classListSignaturesRule.ts

This file was deleted.

1 change: 0 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@
"setters-after-getters": true,
"ng-on-changes-property-access": true,
"require-breaking-change-version": true,
"class-list-signatures": true,
"no-nested-ternary": true,
"prefer-const-enum": true,
"no-lifecycle-invocation": [true, "**/!(*.spec).ts"],
Expand Down