From a018fb0ee8ac711e7fba7d0d528fa56f348f6361 Mon Sep 17 00:00:00 2001 From: Jullierme Barros Date: Mon, 22 Jul 2024 10:51:28 -0300 Subject: [PATCH] feat(material/tooltip): replicate tooltipClass to default MatTooltipDefaultOptions (#29467) * feat(material/form-field): replicate tooltipClass to default MatTooltipDefaultOptions The `tooltipClass` property has been added to the default configuration options in `MatTooltipDefaultOptions`. This new property is optional and supports the same syntax as `ngClass`, just like the component's default attribute. As with some existing configurations, if a CSS class is defined directly on the tooltip component, it will automatically override the default class. An example has been added to the `tooltip-demo` file. Additionally, two tests have been created to ensure the solution works as expected. Fixes #29355 * feat(material/form-field): replicate tooltipClass to default MatTooltipDefaultOptions The `tooltipClass` property has been added to the default configuration options in `MatTooltipDefaultOptions`. This new property is optional. As with some existing configurations, if a CSS class is defined directly on the tooltip component, it will automatically override the default class. Two tests have been created to ensure the solution works as expected. Fixes #29355 * feat(material/form-field): replicate tooltipClass to default MatTooltipDefaultOptions The `tooltipClass` property has been added to the default configuration options in `MatTooltipDefaultOptions`. This new property is optional. As with some existing configurations, if a CSS class is defined directly on the tooltip component, it will automatically override the default class. Two tests have been created to ensure the solution works as expected. Fixes #29355 --- src/material/tooltip/tooltip.spec.ts | 81 ++++++++++++++++++++++++++++ src/material/tooltip/tooltip.ts | 10 ++++ 2 files changed, 91 insertions(+) diff --git a/src/material/tooltip/tooltip.spec.ts b/src/material/tooltip/tooltip.spec.ts index 5569df953caa..f6553f8a923d 100644 --- a/src/material/tooltip/tooltip.spec.ts +++ b/src/material/tooltip/tooltip.spec.ts @@ -233,6 +233,65 @@ describe('MDC-based MatTooltip', () => { expect(tooltipDirective._getOverlayPosition().fallback.overlayX).toBe('end'); })); + it('should be able to define a default (global) tooltip class', fakeAsync(() => { + TestBed.resetTestingModule() + .configureTestingModule({ + declarations: [TooltipDemoWithoutTooltipClassBinding], + imports: [MatTooltipModule, OverlayModule], + providers: [ + { + provide: MAT_TOOLTIP_DEFAULT_OPTIONS, + useValue: {tooltipClass: 'my-default-tooltip-class'}, + }, + ], + }) + .compileComponents(); + + const fixture = TestBed.createComponent(TooltipDemoWithoutTooltipClassBinding); + fixture.detectChanges(); + tooltipDirective = fixture.componentInstance.tooltip; + tooltipDirective.show(); + fixture.detectChanges(); + tick(); + const overlayRef = tooltipDirective._overlayRef!; + const tooltipElement = overlayRef.overlayElement.querySelector( + '.mat-mdc-tooltip', + ) as HTMLElement; + + expect(tooltipDirective.tooltipClass).toBe('my-default-tooltip-class'); + expect(tooltipElement.classList).toContain('my-default-tooltip-class'); + })); + + it('should be able to provide tooltip class over the custom default one', fakeAsync(() => { + TestBed.resetTestingModule() + .configureTestingModule({ + declarations: [TooltipDemoWithTooltipClassBinding], + imports: [MatTooltipModule, OverlayModule], + providers: [ + { + provide: MAT_TOOLTIP_DEFAULT_OPTIONS, + useValue: {tooltipClass: 'my-default-tooltip-class'}, + }, + ], + }) + .compileComponents(); + + const fixture = TestBed.createComponent(TooltipDemoWithTooltipClassBinding); + fixture.detectChanges(); + tooltipDirective = fixture.componentInstance.tooltip; + tooltipDirective.show(); + fixture.detectChanges(); + tick(); + const overlayRef = tooltipDirective._overlayRef!; + const tooltipElement = overlayRef.overlayElement.querySelector( + '.mat-mdc-tooltip', + ) as HTMLElement; + + expect(tooltipDirective.tooltipClass).not.toBe('my-default-tooltip-class'); + expect(tooltipElement.classList).not.toContain('my-default-tooltip-class'); + expect(tooltipElement.classList).toContain('fixed-tooltip-class'); + })); + it('should position on the bottom-left by default', fakeAsync(() => { // We don't bind mouse events on mobile devices. if (platform.IOS || platform.ANDROID) { @@ -1660,6 +1719,28 @@ class TooltipDemoWithoutPositionBinding { @ViewChild('button') button: ElementRef; } +@Component({ + selector: 'app', + template: ``, +}) +class TooltipDemoWithoutTooltipClassBinding { + message = initialTooltipMessage; + @ViewChild(MatTooltip) tooltip: MatTooltip; + @ViewChild('button') button: ElementRef; +} + +@Component({ + selector: 'app', + template: ` + + `, +}) +class TooltipDemoWithTooltipClassBinding { + message: any = initialTooltipMessage; + @ViewChild(MatTooltip) tooltip: MatTooltip; + @ViewChild('button') button: ElementRef; +} + @Component({ selector: 'app', styles: `button { width: 500px; height: 500px; }`, diff --git a/src/material/tooltip/tooltip.ts b/src/material/tooltip/tooltip.ts index be12011ed202..428d8a5792fc 100644 --- a/src/material/tooltip/tooltip.ts +++ b/src/material/tooltip/tooltip.ts @@ -147,6 +147,12 @@ export interface MatTooltipDefaultOptions { /** Disables the ability for the user to interact with the tooltip element. */ disableTooltipInteractivity?: boolean; + + /** + * Default classes to be applied to the tooltip. These default classes will not be applied if + * `tooltipClass` is defined directly on the tooltip element, as it will override the default. + */ + tooltipClass?: string | string[]; } /** @@ -389,6 +395,10 @@ export class MatTooltip implements OnDestroy, AfterViewInit { if (_defaultOptions.touchGestures) { this.touchGestures = _defaultOptions.touchGestures; } + + if (_defaultOptions.tooltipClass) { + this.tooltipClass = _defaultOptions.tooltipClass; + } } _dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {