diff --git a/goldens/material/chips/index.api.md b/goldens/material/chips/index.api.md
index fdcc60891262..5093bff4245d 100644
--- a/goldens/material/chips/index.api.md
+++ b/goldens/material/chips/index.api.md
@@ -83,6 +83,7 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
_handlePrimaryActionInteraction(): void;
// (undocumented)
_hasFocus(): boolean;
+ _hasInteractiveActions(): boolean;
_hasTrailingIcon(): boolean;
highlighted: boolean;
id: string;
diff --git a/src/material/chips/chip-row.spec.ts b/src/material/chips/chip-row.spec.ts
index 229692a2843d..22c1aa7dcd06 100644
--- a/src/material/chips/chip-row.spec.ts
+++ b/src/material/chips/chip-row.spec.ts
@@ -436,6 +436,43 @@ describe('Row Chips', () => {
}));
});
+ describe('_hasInteractiveActions', () => {
+ it('should return true if the chip has a remove icon', () => {
+ testComponent.removable = true;
+ fixture.changeDetectorRef.markForCheck();
+ fixture.detectChanges();
+ expect(chipInstance._hasInteractiveActions()).toBe(true);
+ });
+
+ it('should return true if the chip has an edit icon', () => {
+ testComponent.editable = true;
+ testComponent.showEditIcon = true;
+ fixture.changeDetectorRef.markForCheck();
+ fixture.detectChanges();
+ expect(chipInstance._hasInteractiveActions()).toBe(true);
+ });
+
+ it('should return true even with a non-interactive trailing icon', () => {
+ testComponent.showTrailingIcon = true;
+ fixture.changeDetectorRef.markForCheck();
+ fixture.detectChanges();
+ expect(chipInstance._hasInteractiveActions()).toBe(true);
+ });
+
+ it('should return false if all actions are non-interactive', () => {
+ // Make primary action non-interactive for testing purposes.
+ chipInstance.primaryAction.isInteractive = false;
+ testComponent.showTrailingIcon = true;
+ testComponent.removable = false; // remove icon is interactive
+ fixture.changeDetectorRef.markForCheck();
+ fixture.detectChanges();
+
+ // The trailing icon is not interactive.
+ expect(chipInstance.trailingIcon.isInteractive).toBe(false);
+ expect(chipInstance._hasInteractiveActions()).toBe(false);
+ });
+ });
+
describe('with edit icon', () => {
beforeEach(async () => {
testComponent.showEditIcon = true;
@@ -507,10 +544,15 @@ describe('Row Chips', () => {
}
{{name}}
-
+ @if (removable) {
+
+ }
@if (useCustomEditInput) {
}
+ @if (showTrailingIcon) {
+ trailing
+ }
@@ -529,6 +571,7 @@ class SingleChip {
editable: boolean = false;
showEditIcon: boolean = false;
useCustomEditInput: boolean = true;
+ showTrailingIcon = false;
ariaLabel: string | null = null;
ariaDescription: string | null = null;
diff --git a/src/material/chips/chip.spec.ts b/src/material/chips/chip.spec.ts
index b9748576396d..750afb2f4db6 100644
--- a/src/material/chips/chip.spec.ts
+++ b/src/material/chips/chip.spec.ts
@@ -117,6 +117,18 @@ describe('MatChip', () => {
expect(primaryAction.hasAttribute('tabindex')).toBe(false);
});
+ it('should disable the ripple if there are no interactive actions', () => {
+ // expect(chipInstance._isRippleDisabled()).toBe(false); TODO(andreyd)
+
+ // Make primary action non-interactive for testing purposes.
+ chipInstance.primaryAction.isInteractive = false;
+ fixture.changeDetectorRef.markForCheck();
+ fixture.detectChanges();
+
+ expect(chipInstance._hasInteractiveActions()).toBe(false);
+ expect(chipInstance._isRippleDisabled()).toBe(true);
+ });
+
it('should return the chip text if value is undefined', () => {
expect(chipInstance.value.trim()).toBe(fixture.componentInstance.name);
});
diff --git a/src/material/chips/chip.ts b/src/material/chips/chip.ts
index 85e2cde30552..eb02fde77b67 100644
--- a/src/material/chips/chip.ts
+++ b/src/material/chips/chip.ts
@@ -327,6 +327,7 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
this.disableRipple ||
this._animationsDisabled ||
this._isBasicChip ||
+ !this._hasInteractiveActions() ||
!!this._globalRippleOptions?.disabled
);
}
@@ -396,6 +397,11 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
// Empty here, but is overwritten in child classes.
}
+ /** Returns whether the chip has any interactive actions. */
+ _hasInteractiveActions(): boolean {
+ return this._getActions().some(a => a.isInteractive);
+ }
+
/** Handles interactions with the edit action of the chip. */
_edit(event: Event) {
// Empty here, but is overwritten in child classes.