Skip to content

Commit 90dad98

Browse files
Merge branch 'master' into ikitanov/fix-16088
2 parents 96f3c93 + c6eb931 commit 90dad98

31 files changed

+1686
-285
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,23 @@ All notable changes for each version of this project will be documented in this
2020
- `IgxPredefinedRangesAreaComponent`
2121
- Added new component for rendering the predefined or custom ranges inside the calendar of the `IgxDateRangePicker`
2222

23+
- `IgxOverlay`
24+
- Position Settings now accept a new optional `offset` input property of type `number`. Used to set the offset of the element from the target in pixels.
25+
26+
- `IgxTooltip`
27+
- The tooltip now remains open while interacting with it.
28+
- `IgxTooltipTarget`
29+
- Introduced several new properties to enhance customization of tooltip content and behavior. Those include `positionSettings`, `hasArrow`, `sticky`, `closeButtonTemplate`. For detailed usage and examples, please refer to the Tooltip [README](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/directives/tooltip/README.md).
30+
31+
2332
### General
2433
- `IgxDropDown` now exposes a `role` input property, allowing users to customize the role attribute based on the use case. The default is `listbox`.
2534

35+
- `IgxTooltipTarget`
36+
- **Behavioral Changes**
37+
- The `showDelay` input property now defaults to `200`.
38+
- The `hideDelay` input property now defaults to `300`.
39+
- The `showTooltip` and `hideTooltip` methods do not take `showDelay`/`hideDelay` into account.
2640

2741
## 20.0.6
2842
### General

projects/igniteui-angular/src/lib/core/styles/components/tooltip/_tooltip-component.scss

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@
1010

1111
@extend %tooltip-display !optional;
1212

13+
@include m(top) {
14+
@extend %arrow--top !optional;
15+
}
16+
17+
@include m(bottom) {
18+
@extend %arrow--bottom !optional;
19+
}
20+
21+
@include m(left) {
22+
@extend %arrow--left !optional;
23+
}
24+
25+
@include m(right) {
26+
@extend %arrow--right !optional;
27+
}
28+
1329
@include m(hidden) {
1430
@extend %tooltip--hidden !optional;
1531
}

projects/igniteui-angular/src/lib/core/styles/components/tooltip/_tooltip-theme.scss

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,58 @@
88
@include css-vars($theme);
99
$variant: map.get($theme, '_meta', 'theme');
1010

11+
$transparent-border: rem(4px) solid transparent;
12+
$color-border: rem(4px) solid var-get($theme, 'background');
13+
1114
%tooltip-display {
12-
display: inline-flex;
13-
justify-content: center;
14-
flex-flow: column wrap;
15+
display: flex;
16+
align-items: flex-start;
17+
text-align: start;
1518
background: var-get($theme, 'background');
1619
color: var-get($theme, 'text-color');
1720
border-radius: var-get($theme, 'border-radius');
1821
box-shadow: map.get($theme, 'shadow');
19-
margin: 0 auto;
20-
padding: 0 rem(8px);
22+
padding: rem(4px) rem(8px);
23+
gap: rem(8px);
2124
min-height: rem(24px);
25+
min-width: rem(24px);
26+
max-width: 200px;
27+
width: fit-content;
28+
29+
igx-icon {
30+
--component-size: 1;
31+
}
2232

23-
@if $variant == 'indigo' {
24-
padding: rem(4px) rem(8px);
33+
igx-tooltip-close-button {
34+
display: flex;
35+
cursor: default;
2536
}
2637
}
2738

39+
%arrow--top {
40+
border-left: $transparent-border;
41+
border-right: $transparent-border;
42+
border-top: $color-border;
43+
}
44+
45+
%arrow--bottom {
46+
border-left: $transparent-border;
47+
border-right: $transparent-border;
48+
border-bottom: $color-border;
49+
}
50+
51+
%arrow--left {
52+
border-top: $transparent-border;
53+
border-bottom: $transparent-border;
54+
border-left: $color-border;
55+
}
56+
57+
%arrow--right {
58+
border-top: $transparent-border;
59+
border-bottom: $transparent-border;
60+
border-right: $color-border;
61+
}
62+
2863
%tooltip--hidden {
2964
display: none;
3065
}
@@ -45,6 +80,7 @@
4580
}
4681
} @else {
4782
%tooltip-display {
83+
line-height: rem(16px);
4884
font-size: rem(10px);
4985
font-weight: 600;
5086
}

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</ng-template>
1717

1818
<ng-template #defIcon>
19-
<igx-icon family="default" name="date_range" [attr.aria-hidden]="true"></igx-icon>
19+
<igx-icon family="default" name="date_range"></igx-icon>
2020
</ng-template>
2121

2222
<ng-template #defDateSeparatorTemplate>{{ dateSeparator }}</ng-template>

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,26 @@ describe('IgxDateRangePicker', () => {
12771277
expect(dateRange.opening.emit).toHaveBeenCalledTimes(0);
12781278
expect(dateRange.opened.emit).toHaveBeenCalledTimes(0);
12791279
}));
1280+
1281+
it('should keep the calendar open when input is focused by click and while typing', fakeAsync(() => {
1282+
fixture.componentInstance.dateRange.open();
1283+
fixture.detectChanges();
1284+
tick(DEBOUNCE_TIME);
1285+
1286+
startInput.triggerEventHandler('focus', {});
1287+
fixture.detectChanges();
1288+
UIInteractions.simulateClickAndSelectEvent(startInput.nativeElement);
1289+
fixture.detectChanges();
1290+
tick(DEBOUNCE_TIME);
1291+
1292+
expect(dateRange.collapsed).toBeFalsy();
1293+
1294+
UIInteractions.simulateTyping('01/10/202', startInput);
1295+
fixture.detectChanges();
1296+
tick(DEBOUNCE_TIME);
1297+
1298+
expect(dateRange.collapsed).toBeFalsy();
1299+
}));
12801300
});
12811301

12821302
it('should focus the last focused input after the calendar closes - dropdown', fakeAsync(() => {

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,11 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective
810810
this.opened.emit({ owner: this });
811811
});
812812

813-
this._overlayService.closing.pipe(...this._overlaySubFilter).subscribe((e) => {
813+
this._overlayService.closing.pipe(...this._overlaySubFilter).subscribe((e: OverlayCancelableEventArgs) => {
814+
const isEscape = e.event && (e.event as KeyboardEvent).key === this.platform.KEYMAP.ESCAPE;
815+
if (this.isProjectedInputTarget(e.event) && !isEscape) {
816+
e.cancel = true;
817+
}
814818
this.handleClosing(e as OverlayCancelableEventArgs);
815819
});
816820

@@ -824,6 +828,16 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective
824828
});
825829
}
826830

831+
private isProjectedInputTarget(event: Event): boolean {
832+
if (!this.hasProjectedInputs || !event) {
833+
return false;
834+
}
835+
const path = event.composed ? event.composedPath() : [event.target];
836+
return this.projectedInputs.some(i =>
837+
path.includes(i.dateTimeEditor.nativeElement)
838+
);
839+
}
840+
827841
private updateValue(value: DateRange) {
828842
this._value = value ? value : null;
829843
this.updateInputs();

projects/igniteui-angular/src/lib/directives/tooltip/README.md

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,99 @@ Since the **IgxTooltip** directive extends the **IgxToggle** directive and there
100100
| tooltipDisabled | boolean | Specifies if the tooltip should not show when hovering its target with the mouse. (defaults to false) |
101101
| tooltipHidden | boolean | Indicates if the tooltip is currently hidden. |
102102
| nativeElement | any | Reference to the native element of the directive. |
103+
| positionSettings | PositionSettings | Controls the position and animation settings used by the tooltip. |
104+
| hasArrow | boolean | Controls whether to display an arrow indicator for the tooltip. Defaults to `false`. |
105+
| sticky | boolean | When set to `true`, the tooltip renders a default close icon `x`. The tooltip remains visible until the user closes it via the close icon `x` or `Esc` key. Defaults to `false`. |
106+
| closeButtonTemplate | TemplateRef<any> | Allows templating the default close icon `x`. |
107+
108+
#### Templating the close button
109+
110+
```html
111+
<igx-icon [igxTooltipTarget]="tooltipRef" [closeButtonTemplate]="customClose">
112+
info
113+
</igx-icon>
114+
115+
<span #tooltipRef="tooltip" igxTooltip>
116+
Hello there, I am a tooltip!
117+
</span>
118+
119+
<ng-template #customClose>
120+
<button igxButton>Close</button>
121+
</ng-template>
122+
```
103123

104124
### Methods
105125
| Name | Type | Arguments | Description |
106126
| :--- |:--- | :--- | :--- |
107-
| showTooltip | void | N/A | Shows the tooltip after the amount of ms specified by the `showDelay` property. |
108-
| hideTooltip | void | N/A | Hides the tooltip after the amount of ms specified by the `hideDelay` property. |
127+
| showTooltip | void | N/A | Shows the tooltip. |
128+
| hideTooltip | void | N/A | Hides the tooltip. |
109129

110130
### Events
111131
|Name|Description|Cancelable|Event arguments|
112132
|--|--|--|--|
113133
| tooltipShow | Emitted when the tooltip starts showing. (This event is fired before the start of the countdown to showing the tooltip.) | True | ITooltipShowEventArgs |
114134
| tooltipHide | Emitted when the tooltip starts hiding. (This event is fired before the start of the countdown to hiding the tooltip.) | True | ITooltipHideEventArgs |
135+
136+
### Notes
137+
138+
The `IgxTooltipTarget` uses the `TooltipPositionStrategy` to position the tooltip and arrow element. If a custom position strategy is used (`overlaySettings.positionStrategy`) and `hasArrow` is set to `true`, the custom strategy should extend the `TooltipPositionStrategy`. Otherwise, the arrow will not be displayed.
139+
140+
The arrow element is positioned based on the provided position settings. If the directions and starting points do not correspond to any of the predefined position values, the arrow is positioned in the top middle side of the tooltip (default tooltip position `bottom`).
141+
142+
143+
| Position     | Horizontal Direction          | Horizontal Start Point         | Vertical Direction            | Vertical Start Point           |
144+
|--------------|-------------------------------|--------------------------------|-------------------------------|--------------------------------|
145+
| top          | HorizontalAlignment.Center    | HorizontalAlignment.Center     | VerticalAlignment.Top         | VerticalAlignment.Top          |
146+
| top-start    | HorizontalAlignment.Right     | HorizontalAlignment.Left       | VerticalAlignment.Top         | VerticalAlignment.Top          |
147+
| top-end      | HorizontalAlignment.Left      | HorizontalAlignment.Right      | VerticalAlignment.Top         | VerticalAlignment.Top          |
148+
| bottom       | HorizontalAlignment.Center    | HorizontalAlignment.Center     | VerticalAlignment.Bottom      | VerticalAlignment.Bottom       |
149+
| bottom-start | HorizontalAlignment.Right     | HorizontalAlignment.Left       | VerticalAlignment.Bottom      | VerticalAlignment.Bottom       |
150+
| bottom-end   | HorizontalAlignment.Left      | HorizontalAlignment.Right      | VerticalAlignment.Bottom      | VerticalAlignment.Bottom       |
151+
| right        | HorizontalAlignment.Right     | HorizontalAlignment.Right      | VerticalAlignment.Middle      | VerticalAlignment.Middle       |
152+
| right-start  | HorizontalAlignment.Right     | HorizontalAlignment.Right      | VerticalAlignment.Bottom      | VerticalAlignment.Top          |
153+
| right-end    | HorizontalAlignment.Right     | HorizontalAlignment.Right      | VerticalAlignment.Top         | VerticalAlignment.Bottom       |
154+
| left         | HorizontalAlignment.Left      | HorizontalAlignment.Left       | VerticalAlignment.Middle      | VerticalAlignment.Middle       |
155+
| left-start   | HorizontalAlignment.Left      | HorizontalAlignment.Left       | VerticalAlignment.Bottom      | VerticalAlignment.Top          |
156+
| left-end     | HorizontalAlignment.Left      | HorizontalAlignment.Left       | VerticalAlignment.Top         | VerticalAlignment.Bottom       |
157+
158+
159+
#### Customizing the arrow's position
160+
161+
The arrow's position can be customized by overriding the `positionArrow(arrow: HTMLElement, arrowFit: ArrowFit)` method.
162+
163+
For example:
164+
165+
```ts
166+
export class CustomStrategy extends TooltipPositioningStrategy {
167+
constructor(settings?: PositionSettings) {
168+
super(settings);
169+
}
170+
171+
public override positionArrow(arrow: HTMLElement, arrowFit: ArrowFit): void {
172+
Object.assign(arrow.style, {
173+
left: '-0.25rem',
174+
transform: 'rotate(-45deg)',
175+
[arrowFit.direction]: '-0.25rem',
176+
});
177+
}
178+
}
179+
180+
public overlaySettings: OverlaySettings = {
181+
positionStrategy: new CustomStrategy({
182+
horizontalDirection: HorizontalAlignment.Right,
183+
horizontalStartPoint: HorizontalAlignment.Right,
184+
verticalDirection: VerticalAlignment.Bottom,
185+
verticalStartPoint: VerticalAlignment.Bottom,
186+
})
187+
};
188+
```
189+
190+
```html
191+
<igx-icon [igxTooltipTarget]="tooltipRef" [hasArrow]="true" [overlaySettings]="overlaySettings">
192+
info
193+
</igx-icon>
194+
195+
<span #tooltipRef="tooltip" igxTooltip>
196+
Hello there, I am a tooltip!
197+
</span>
198+
```

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { IgxTooltipDirective } from './tooltip.directive';
33

44
export * from './tooltip.directive';
55
export * from './tooltip-target.directive';
6+
export { ArrowFit, TooltipPositionStrategy } from './tooltip.common';
67

78
/* NOTE: Tooltip directives collection for ease-of-use import in standalone components scenario */
89
export const IGX_TOOLTIP_DIRECTIVES = [
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Component, Output, EventEmitter, HostListener, Input, TemplateRef } from '@angular/core';
2+
import { IgxIconComponent } from '../../icon/icon.component';
3+
import { CommonModule } from '@angular/common';
4+
5+
@Component({
6+
selector: 'igx-tooltip-close-button',
7+
template: `
8+
<ng-container *ngIf="customTemplate; else defaultTemplate">
9+
<ng-container *ngTemplateOutlet="customTemplate"></ng-container>
10+
</ng-container>
11+
<ng-template #defaultTemplate>
12+
<igx-icon aria-hidden="true" family="default" name="close"></igx-icon>
13+
</ng-template>
14+
`,
15+
imports: [IgxIconComponent, CommonModule],
16+
})
17+
export class IgxTooltipCloseButtonComponent {
18+
@Input()
19+
public customTemplate: TemplateRef<any>;
20+
21+
@Output()
22+
public clicked = new EventEmitter<void>();
23+
24+
@HostListener('click')
25+
public handleClick() {
26+
this.clicked.emit();
27+
}
28+
}

0 commit comments

Comments
 (0)