Skip to content

Commit ea7c32a

Browse files
authored
Merge branch '21.1.x' into iminchev/fix-16493
2 parents 6f4f716 + a68d01e commit ea7c32a

9 files changed

Lines changed: 125 additions & 16 deletions

File tree

projects/igniteui-angular/combo/src/combo/combo.component.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,6 +1866,40 @@ describe('igxCombo', () => {
18661866
expect(document.activeElement).toEqual(combo.comboInput.nativeElement);
18671867
expect(combo.selection.length).toEqual(0);
18681868
}));
1869+
it('should stop Escape keydown event propagation when the dropdown is open', fakeAsync(() => {
1870+
const escapeEvent = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true });
1871+
spyOn(escapeEvent, 'stopPropagation');
1872+
1873+
combo.comboInput.nativeElement.focus();
1874+
fixture.detectChanges();
1875+
1876+
combo.toggle();
1877+
fixture.detectChanges();
1878+
expect(combo.collapsed).toBeFalsy();
1879+
1880+
combo.onEscape(escapeEvent);
1881+
tick();
1882+
fixture.detectChanges();
1883+
1884+
expect(escapeEvent.stopPropagation).toHaveBeenCalled();
1885+
}));
1886+
it('should stop Escape key propagation when the combo is collapsed and has a selection', fakeAsync(() => {
1887+
combo.comboInput.nativeElement.focus();
1888+
fixture.detectChanges();
1889+
1890+
combo.select([combo.data[0][combo.valueKey]]);
1891+
expect(combo.selection.length).toEqual(1);
1892+
fixture.detectChanges();
1893+
1894+
const keyEvent = new KeyboardEvent('keydown', { key: 'Escape' });
1895+
const stopPropSpy = spyOn(keyEvent, 'stopPropagation');
1896+
1897+
combo.onEscape(keyEvent);
1898+
tick();
1899+
fixture.detectChanges();
1900+
1901+
expect(stopPropSpy).toHaveBeenCalledTimes(1);
1902+
}));
18691903
it('should close the combo and preserve the focus when Escape key is pressed', fakeAsync(() => {
18701904
combo.comboInput.nativeElement.focus();
18711905
fixture.detectChanges();

projects/igniteui-angular/combo/src/combo/combo.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
187187

188188
@HostListener('keydown.Escape', ['$event'])
189189
public onEscape(event: Event) {
190+
event.stopPropagation();
190191
if (this.collapsed) {
191192
this.deselectAllItems(true, event);
192193
}

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

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
Directive, OnInit, OnDestroy, Output, ElementRef, ViewContainerRef,
2+
Directive, OnInit, OnDestroy, Output, ViewContainerRef,
33
Input, EventEmitter, booleanAttribute, TemplateRef, ComponentRef, Renderer2,
44
EnvironmentInjector,
55
createComponent,
@@ -380,6 +380,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
380380
private _positionSettings: PositionSettings = TooltipPositionSettings;
381381
private _showTriggers = new Set(['pointerenter']);
382382
private _hideTriggers = new Set(['pointerleave', 'click']);
383+
private _pendingShowTrigger: string | null = null;
383384

384385
private _abortController = new AbortController();
385386

@@ -400,15 +401,20 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
400401
/**
401402
* @hidden
402403
*/
403-
public onShow(): void {
404-
this._checksBeforeShowing(() => this._showOnInteraction());
404+
public onShow(event?: Event): void {
405+
this._checksBeforeShowing(() => this._showOnInteraction(event));
405406
}
406407

407408
/**
408409
* @hidden
409410
*/
410-
public onHide(): void {
411-
if (this.tooltipDisabled || this.target.collapsed) {
411+
public onHide(event?: Event): void {
412+
if (this.target.collapsed) {
413+
this._cancelPendingShow(event);
414+
return;
415+
}
416+
417+
if (this.tooltipDisabled) {
412418
return;
413419
}
414420

@@ -538,7 +544,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
538544
}, withDelay ? this.hideDelay : 0);
539545
}
540546

541-
private _showTooltip(withDelay: boolean, withEvents: boolean): void {
547+
private _showTooltip(withDelay: boolean, withEvents: boolean, triggerEvent?: Event): void {
542548
if (!this.target.collapsed && !this._isForceClosed) {
543549
return;
544550
}
@@ -555,17 +561,19 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
555561
}
556562

557563
this._evaluateStickyState();
564+
this._pendingShowTrigger = triggerEvent?.type ?? null;
558565

559566
this.target.timeoutId = setTimeout(() => {
560567
// Call open() of IgxTooltipDirective
568+
this._pendingShowTrigger = null;
561569
this.target.open(this._mergedOverlaySettings);
562570
}, withDelay ? this.showDelay : 0);
563571
}
564572

565573

566-
private _showOnInteraction(): void {
574+
private _showOnInteraction(triggerEvent?: Event): void {
567575
this._stopTimeoutAndAnimation();
568-
this._showTooltip(true, true);
576+
this._showTooltip(true, true, triggerEvent);
569577
}
570578

571579
private _hideOnInteraction(): void {
@@ -594,6 +602,26 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
594602
this.target.stopAnimations();
595603
}
596604

605+
/**
606+
* Used when a hide trigger occurs before the tooltip opens.
607+
* Clears the pending timeout and resets the tracked show trigger
608+
* so the tooltip does not open after the user has already left the target.
609+
*/
610+
private _cancelPendingShow(event?: Event): void {
611+
if (!this.target.timeoutId) {
612+
return;
613+
}
614+
615+
// Keep same-event show/hide trigger combinations acting as toggle behavior.
616+
if (event?.type && event.type === this._pendingShowTrigger) {
617+
return;
618+
}
619+
620+
clearTimeout(this.target.timeoutId);
621+
this.target.timeoutId = null;
622+
this._pendingShowTrigger = null;
623+
}
624+
597625
/**
598626
* Used when a single tooltip is used for multiple targets.
599627
*/

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,19 @@ describe('IgxTooltip', () => {
519519
flush();
520520
verifyTooltipVisibility(tooltipNativeElement, tooltipTarget, false);
521521
}));
522+
523+
it('should not open when pointer leaves before the show delay elapses', fakeAsync(() => {
524+
tooltipTarget.showDelay = 500;
525+
fix.detectChanges();
526+
527+
hoverElement(button);
528+
tick(300);
529+
verifyTooltipVisibility(tooltipNativeElement, tooltipTarget, false);
530+
531+
unhoverElement(button);
532+
tick(300);
533+
verifyTooltipVisibility(tooltipNativeElement, tooltipTarget, false);
534+
}));
522535
});
523536
});
524537

projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5162,7 +5162,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => {
51625162
// Verify the calendar is scrolled to previous month.
51635163
const headerLabel = document.querySelector('igx-calendar').querySelector('.igx-calendar-picker__date') as HTMLElement;
51645164
const today = new Date();
5165-
const prevMonth = new Date(today.setMonth(today.getMonth() - 1));
5165+
const prevMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);
51665166
const monthName = prevMonth.toLocaleString('default', { month: 'short' });
51675167
expect(headerLabel.innerText.trim()).toMatch(`${monthName}`);
51685168
}));

projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,38 @@ describe('IgxSimpleCombo', () => {
11341134
expect(combo.selection).not.toBeDefined();
11351135
}));
11361136

1137+
it('should stop Escape keydown event propagation when the dropdown is open', fakeAsync(() => {
1138+
const escapeEvent = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true });
1139+
spyOn(escapeEvent, 'stopPropagation');
1140+
1141+
combo.open();
1142+
fixture.detectChanges();
1143+
expect(combo.collapsed).toBeFalsy();
1144+
1145+
combo.handleKeyDown(escapeEvent);
1146+
tick();
1147+
fixture.detectChanges();
1148+
1149+
expect(escapeEvent.stopPropagation).toHaveBeenCalled();
1150+
}));
1151+
1152+
it('should stop Escape key propagation when the combo is collapsed and has a selection', fakeAsync(() => {
1153+
combo.comboInput.nativeElement.focus();
1154+
fixture.detectChanges();
1155+
1156+
combo.select(combo.data[2][combo.valueKey]);
1157+
fixture.detectChanges();
1158+
expect(combo.selection).toBeDefined();
1159+
1160+
const keyEvent = new KeyboardEvent('keydown', { key: 'Escape' });
1161+
const stopPropSpy = spyOn(keyEvent, 'stopPropagation');
1162+
1163+
combo.handleKeyDown(keyEvent);
1164+
fixture.detectChanges();
1165+
1166+
expect(stopPropSpy).toHaveBeenCalledTimes(1);
1167+
}));
1168+
11371169
it('should clear the selection on tab/blur if the search text does not match any value', () => {
11381170
// allowCustomValues does not matter
11391171
combo.select(combo.data[2][combo.valueKey]);

projects/igniteui-angular/simple-combo/src/simple-combo/simple-combo.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
350350
}
351351
}
352352
if (event.key === this.platformUtil.KEYMAP.ESCAPE) {
353+
event.stopPropagation();
353354
if (this.collapsed) {
354355
const oldSelection = this.selection;
355356
this.clearSelection(true);

skills/igniteui-angular-components/references/directives.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { IgxIconComponent } from 'igniteui-angular/icon';
2323
```html
2424
<!-- Text buttons -->
2525
<button igxButton="flat">Flat</button>
26-
<button igxButton="raised">Raised</button>
26+
<button igxButton="contained">Contained</button>
2727
<button igxButton="outlined">Outlined</button>
2828
<button igxButton="fab">
2929
<igx-icon>add</igx-icon>
@@ -35,10 +35,10 @@ import { IgxIconComponent } from 'igniteui-angular/icon';
3535
<button igxIconButton="contained"><igx-icon>save</igx-icon></button>
3636

3737
<!-- Disabled state -->
38-
<button igxButton="raised" [disabled]="isLoading()">Submit</button>
38+
<button igxButton="contained" [disabled]="isLoading()">Submit</button>
3939
```
4040

41-
Button variants for `igxButton`: `'flat'`, `'raised'`, `'outlined'`, `'fab'`.
41+
Button variants for `igxButton`: `'flat'`, `'contained'`, `'outlined'`, `'fab'`.
4242
Button variants for `igxIconButton`: `'flat'`, `'outlined'`, `'contained'`.
4343

4444
## Button Group
@@ -166,14 +166,14 @@ import { IgxRippleDirective } from 'igniteui-angular/directives';
166166

167167
```html
168168
<!-- Add to any clickable element for Material-style ink ripple -->
169-
<button igxButton="raised" igxRipple>Click me</button>
169+
<button igxButton="contained" igxRipple>Click me</button>
170170
<div igxRipple igxRippleTarget=".my-class" class="custom-surface">Interactive div</div>
171171
```
172172

173173
Inputs: `[igxRipple]` (ripple color), `[igxRippleCentered]` (always start from center), `[igxRippleDisabled]`.
174174

175175
```html
176-
<button igxButton="raised" igxRipple="#ff4081" [igxRippleCentered]="true">Pink ripple</button>
176+
<button igxButton="contained" igxRipple="#ff4081" [igxRippleCentered]="true">Pink ripple</button>
177177
```
178178

179179
## Tooltip

skills/igniteui-angular-components/references/feedback.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ import { IgxButtonDirective } from 'igniteui-angular/directives';
3434
<p>Are you sure you want to delete this item? This action cannot be undone.</p>
3535
<div igxDialogActions>
3636
<button igxButton="flat" (click)="confirmDialog.close()">Cancel</button>
37-
<button igxButton="raised" (click)="deleteItem(); confirmDialog.close()">Delete</button>
37+
<button igxButton="contained" (click)="deleteItem(); confirmDialog.close()">Delete</button>
3838
</div>
3939
</igx-dialog>
4040

41-
<button igxButton="raised" (click)="confirmDialog.open()">Delete Item</button>
41+
<button igxButton="contained" (click)="confirmDialog.open()">Delete Item</button>
4242
```
4343

4444
Programmatic control:

0 commit comments

Comments
 (0)