Skip to content

Commit 37648cf

Browse files
authored
fix(material/chips): static chips should disable ripple (#31652)
1 parent 24e191a commit 37648cf

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

goldens/material/chips/index.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
8484
_handlePrimaryActionInteraction(): void;
8585
// (undocumented)
8686
_hasFocus(): boolean;
87+
_hasInteractiveActions(): boolean;
8788
_hasTrailingIcon(): boolean;
8889
highlighted: boolean;
8990
id: string;

src/material/chips/chip-row.spec.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,43 @@ describe('Row Chips', () => {
436436
}));
437437
});
438438

439+
describe('_hasInteractiveActions', () => {
440+
it('should return true if the chip has a remove icon', () => {
441+
testComponent.removable = true;
442+
fixture.changeDetectorRef.markForCheck();
443+
fixture.detectChanges();
444+
expect(chipInstance._hasInteractiveActions()).toBe(true);
445+
});
446+
447+
it('should return true if the chip has an edit icon', () => {
448+
testComponent.editable = true;
449+
testComponent.showEditIcon = true;
450+
fixture.changeDetectorRef.markForCheck();
451+
fixture.detectChanges();
452+
expect(chipInstance._hasInteractiveActions()).toBe(true);
453+
});
454+
455+
it('should return true even with a non-interactive trailing icon', () => {
456+
testComponent.showTrailingIcon = true;
457+
fixture.changeDetectorRef.markForCheck();
458+
fixture.detectChanges();
459+
expect(chipInstance._hasInteractiveActions()).toBe(true);
460+
});
461+
462+
it('should return false if all actions are non-interactive', () => {
463+
// Make primary action non-interactive for testing purposes.
464+
chipInstance.primaryAction.isInteractive = false;
465+
testComponent.showTrailingIcon = true;
466+
testComponent.removable = false; // remove icon is interactive
467+
fixture.changeDetectorRef.markForCheck();
468+
fixture.detectChanges();
469+
470+
// The trailing icon is not interactive.
471+
expect(chipInstance.trailingIcon.isInteractive).toBe(false);
472+
expect(chipInstance._hasInteractiveActions()).toBe(false);
473+
});
474+
});
475+
439476
describe('with edit icon', () => {
440477
beforeEach(async () => {
441478
testComponent.showEditIcon = true;
@@ -507,10 +544,15 @@ describe('Row Chips', () => {
507544
<button matChipEdit>edit</button>
508545
}
509546
{{name}}
510-
<button matChipRemove>x</button>
547+
@if (removable) {
548+
<button matChipRemove>x</button>
549+
}
511550
@if (useCustomEditInput) {
512551
<span class="projected-edit-input" matChipEditInput></span>
513552
}
553+
@if (showTrailingIcon) {
554+
<span matChipTrailingIcon>trailing</span>
555+
}
514556
</mat-chip-row>
515557
<input matInput [matChipInputFor]="chipGrid" #chipInput>
516558
</div>
@@ -529,6 +571,7 @@ class SingleChip {
529571
editable: boolean = false;
530572
showEditIcon: boolean = false;
531573
useCustomEditInput: boolean = true;
574+
showTrailingIcon = false;
532575
ariaLabel: string | null = null;
533576
ariaDescription: string | null = null;
534577

src/material/chips/chip.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ describe('MatChip', () => {
117117
expect(primaryAction.hasAttribute('tabindex')).toBe(false);
118118
});
119119

120+
it('should disable the ripple if there are no interactive actions', () => {
121+
// expect(chipInstance._isRippleDisabled()).toBe(false); TODO(andreyd)
122+
123+
// Make primary action non-interactive for testing purposes.
124+
chipInstance.primaryAction.isInteractive = false;
125+
fixture.changeDetectorRef.markForCheck();
126+
fixture.detectChanges();
127+
128+
expect(chipInstance._hasInteractiveActions()).toBe(false);
129+
expect(chipInstance._isRippleDisabled()).toBe(true);
130+
});
131+
120132
it('should return the chip text if value is undefined', () => {
121133
expect(chipInstance.value.trim()).toBe(fixture.componentInstance.name);
122134
});

src/material/chips/chip.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
331331
this.disableRipple ||
332332
this._animationsDisabled ||
333333
this._isBasicChip ||
334+
!this._hasInteractiveActions() ||
334335
!!this._globalRippleOptions?.disabled
335336
);
336337
}
@@ -400,6 +401,11 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
400401
// Empty here, but is overwritten in child classes.
401402
}
402403

404+
/** Returns whether the chip has any interactive actions. */
405+
_hasInteractiveActions(): boolean {
406+
return this._getActions().some(a => a.isInteractive);
407+
}
408+
403409
/** Handles interactions with the edit action of the chip. */
404410
_edit(event: Event) {
405411
// Empty here, but is overwritten in child classes.

0 commit comments

Comments
 (0)