Skip to content

Commit 3e0985a

Browse files
Merge pull request #16281 from IgniteUI/rivanova/fix-16273-20.1.x
fix(tooltip): do not create arrow in SSR mode - 20.1.x
2 parents b126b07 + 6485307 commit 3e0985a

File tree

3 files changed

+47
-34
lines changed

3 files changed

+47
-34
lines changed

projects/igniteui-angular/src/lib/directives/tooltip/tooltip-target.directive.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import {
22
Directive, OnInit, OnDestroy, Output, ElementRef, Optional, ViewContainerRef, HostListener,
3-
Input, EventEmitter, booleanAttribute, TemplateRef, ComponentRef, Renderer2, OnChanges, SimpleChanges,
3+
Input, EventEmitter, booleanAttribute, TemplateRef, ComponentRef, Renderer2,
44
EnvironmentInjector,
55
createComponent,
6+
AfterViewInit,
67
} from '@angular/core';
78
import { Subject } from 'rxjs';
89
import { takeUntil } from 'rxjs/operators';
@@ -45,7 +46,7 @@ export interface ITooltipHideEventArgs extends IBaseEventArgs {
4546
selector: '[igxTooltipTarget]',
4647
standalone: true
4748
})
48-
export class IgxTooltipTargetDirective extends IgxToggleActionDirective implements OnChanges, OnInit, OnDestroy {
49+
export class IgxTooltipTargetDirective extends IgxToggleActionDirective implements OnInit, AfterViewInit, OnDestroy {
4950
/**
5051
* Gets/sets the amount of milliseconds that should pass before showing the tooltip.
5152
*
@@ -101,7 +102,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
101102
*/
102103
@Input()
103104
public set hasArrow(value: boolean) {
104-
if (this.target) {
105+
if (this.target && this.target.arrow) {
105106
this.target.arrow.style.display = value ? '' : 'none';
106107
}
107108
this._hasArrow = value;
@@ -397,16 +398,6 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
397398
}
398399
}
399400

400-
401-
/**
402-
* @hidden
403-
*/
404-
public ngOnChanges(changes: SimpleChanges): void {
405-
if (changes['hasArrow']) {
406-
this.target.arrow.style.display = changes['hasArrow'].currentValue ? '' : 'none';
407-
}
408-
}
409-
410401
/**
411402
* @hidden
412403
*/
@@ -433,6 +424,15 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
433424
this.nativeElement.addEventListener('touchstart', this.onTouchStart = this.onTouchStart.bind(this), { passive: true });
434425
}
435426

427+
/**
428+
* @hidden
429+
*/
430+
public ngAfterViewInit(): void {
431+
if (this.target && this.target.arrow) {
432+
this.target.arrow.style.display = this.hasArrow ? '' : 'none';
433+
}
434+
}
435+
436436
/**
437437
* @hidden
438438
*/

projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import {
22
Directive, ElementRef, Input, ChangeDetectorRef, Optional, HostBinding, Inject,
33
OnDestroy, inject, DOCUMENT, HostListener,
4+
Renderer2,
5+
AfterViewInit,
46
} from '@angular/core';
57
import { IgxOverlayService } from '../../services/overlay/overlay';
68
import { IgxNavigationService } from '../../core/navigation';
79
import { IgxToggleDirective } from '../toggle/toggle.directive';
810
import { IgxTooltipTargetDirective } from './tooltip-target.directive';
911
import { Subject, takeUntil } from 'rxjs';
12+
import { PlatformUtil } from '../../core/utils';
1013

1114
let NEXT_ID = 0;
1215
/**
@@ -28,7 +31,7 @@ let NEXT_ID = 0;
2831
selector: '[igxTooltip]',
2932
standalone: true
3033
})
31-
export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy {
34+
export class IgxTooltipDirective extends IgxToggleDirective implements AfterViewInit, OnDestroy {
3235
/**
3336
* @hidden
3437
*/
@@ -116,6 +119,8 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy
116119
private _role: 'tooltip' | 'status' = 'tooltip';
117120
private _destroy$ = new Subject<boolean>();
118121
private _document = inject(DOCUMENT);
122+
private _renderer = inject(Renderer2);
123+
private _platformUtil = inject(PlatformUtil);
119124

120125
/** @hidden */
121126
constructor(
@@ -133,8 +138,13 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy
133138
this.closed.pipe(takeUntil(this._destroy$)).subscribe(() => {
134139
this._document.removeEventListener('touchstart', this.onDocumentTouchStart);
135140
});
141+
}
136142

137-
this._createArrow();
143+
/** @hidden */
144+
public ngAfterViewInit(): void {
145+
if (this._platformUtil.isBrowser) {
146+
this._createArrow();
147+
}
138148
}
139149

140150
/** @hidden */
@@ -144,7 +154,10 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy
144154
this._document.removeEventListener('touchstart', this.onDocumentTouchStart);
145155
this._destroy$.next(true);
146156
this._destroy$.complete();
147-
this._removeArrow();
157+
158+
if (this.arrow) {
159+
this._removeArrow();
160+
}
148161
}
149162

150163
/**
@@ -192,10 +205,10 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy
192205
}
193206

194207
private _createArrow(): void {
195-
this._arrowEl = document.createElement('span');
196-
this._arrowEl.style.position = 'absolute';
197-
this._arrowEl.setAttribute('data-arrow', 'true');
198-
this.element.appendChild(this._arrowEl);
208+
this._arrowEl = this._renderer.createElement('span');
209+
this._renderer.setStyle(this._arrowEl, 'position', 'absolute');
210+
this._renderer.setAttribute(this._arrowEl, 'data-arrow', 'true');
211+
this._renderer.appendChild(this.element, this._arrowEl);
199212
}
200213

201214
private _removeArrow(): void {

projects/igniteui-angular/src/lib/grids/grid/grid-validation.spec.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,8 @@ describe('IgxGrid - Validation #grid', () => {
167167
cell = grid.gridAPI.get_cell_by_visible_index(1, 1);
168168
//min length should be 4
169169
GridFunctions.verifyCellValid(cell, false);
170-
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[1].textContent;
171-
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
170+
const errorMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
171+
expect(errorMessage).toEqual(' Entry should be at least 4 character(s) long ');
172172
});
173173

174174
it('should mark invalid cell with igx-grid__td--invalid class and show the related error cell template when the field contains "."', () => {
@@ -186,8 +186,8 @@ describe('IgxGrid - Validation #grid', () => {
186186
cell = grid.gridAPI.get_cell_by_visible_index(1, 4);
187187
//min length should be 4
188188
GridFunctions.verifyCellValid(cell, false);
189-
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[1].textContent;
190-
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
189+
const errorMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
190+
expect(errorMessage).toEqual(' Entry should be at least 4 character(s) long ');
191191
});
192192

193193
it('should show the error message on error icon hover and when the invalid cell becomes active.', fakeAsync(() => {
@@ -204,8 +204,8 @@ describe('IgxGrid - Validation #grid', () => {
204204
//min length should be 4
205205
GridFunctions.verifyCellValid(cell, false);
206206
GridSelectionFunctions.verifyCellActive(cell, true);
207-
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[1].textContent;
208-
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
207+
const errorMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
208+
expect(errorMessage).toEqual(' Entry should be at least 4 character(s) long ');
209209

210210
const overlayService = TestBed.inject(IgxOverlayService);
211211
const info = overlayService.getOverlayById(cell.errorTooltip.first.overlayId);
@@ -390,8 +390,8 @@ describe('IgxGrid - Validation #grid', () => {
390390
cell = grid.gridAPI.get_cell_by_visible_index(1, 1);
391391
//bob cannot be the name
392392
GridFunctions.verifyCellValid(cell, false);
393-
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[1].textContent;
394-
expect(erorrMessage).toEqual(' This name is forbidden. ');
393+
const errorMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
394+
expect(errorMessage).toEqual(' This name is forbidden. ');
395395

396396
cell.editMode = true;
397397
cell.update('test');
@@ -425,8 +425,8 @@ describe('IgxGrid - Validation #grid', () => {
425425
fixture.detectChanges();
426426

427427
GridFunctions.verifyCellValid(cell, false);
428-
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[1].textContent;
429-
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
428+
const errorMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
429+
expect(errorMessage).toEqual(' Entry should be at least 4 character(s) long ');
430430
});
431431

432432
it('should trigger validation on change when using custom editor bound via editValue.', () => {
@@ -444,8 +444,8 @@ describe('IgxGrid - Validation #grid', () => {
444444
fixture.detectChanges();
445445

446446
GridFunctions.verifyCellValid(cell, false);
447-
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[1].textContent;
448-
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
447+
const errorMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
448+
expect(errorMessage).toEqual(' Entry should be at least 4 character(s) long ');
449449
});
450450

451451
it('should trigger validation on blur when using custom editor bound via editValue.', () => {
@@ -472,8 +472,8 @@ describe('IgxGrid - Validation #grid', () => {
472472
grid.crudService.endEdit(true);
473473
fixture.detectChanges();
474474
GridFunctions.verifyCellValid(cell, false);
475-
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[1].textContent;
476-
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
475+
const errorMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
476+
expect(errorMessage).toEqual(' Entry should be at least 4 character(s) long ');
477477
});
478478
});
479479

0 commit comments

Comments
 (0)