Skip to content

Commit b70e7f7

Browse files
authored
Merge branch 'master' into SKrastev/fix-4896-master
2 parents 4cd5d2f + d403c0f commit b70e7f7

33 files changed

+529
-372
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ All notable changes for each version of this project will be documented in this
1919
- **Breaking Change** `onClose` event is renamed to `onClosed`.
2020
- **Behavioral Change** - action buttons are now available in the dropdown mode.
2121
- **Feature** `igxDatePicker` and `igxTimePicker` now provide the ability for adding custom action buttons. Read up more information in [igxDatePicker ReadMe](https://github.com/IgniteUI/igniteui-angular/tree/master/projects/igniteui-angular/src/lib/date-picker/README.md) or [igxTimePicker ReadMe](https://github.com/IgniteUI/igniteui-angular/tree/master/projects/igniteui-angular/src/lib/time-picker/README.md)
22+
- `IgxToggleAction` / `IgxTooltip`: Removed the deprecated `closeOnOutsideClick` Input that has been superseded by `overlaySettings` in 6.2.0.
2223

2324
- `IgxList` - The list component has been refactored. It now includes several new supporting directives:
2425
- `igxListThumbnail` - Use it to mark the target as list thumbnail which will be automatically positioned as a first item in the list item;

projects/igniteui-angular/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"@angular/core": "^8.0.0",
7676
"@angular/animations": "^8.0.0",
7777
"@angular/forms": "^8.0.0",
78+
"node-sass": "^4.9.0",
7879
"web-animations-js": "^2.3.1"
7980
},
8081
"devDependencies": {

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import { IgxComboFilterConditionPipe, IgxComboFilteringPipe, IgxComboGroupingPip
3434
import { OverlaySettings, AbsoluteScrollStrategy } from '../services';
3535
import { Subject, Subscription } from 'rxjs';
3636
import { takeUntil } from 'rxjs/operators';
37-
import { DeprecateProperty } from '../core/deprecateDecorators';
3837
import { DefaultSortingStrategy, ISortingStrategy } from '../data-operations/sorting-strategy';
3938
import { DisplayDensityBase, DisplayDensityToken, IDisplayDensityOptions } from '../core/density';
4039
import { IGX_COMBO_COMPONENT, IgxComboBase } from './combo.common';

projects/igniteui-angular/src/lib/core/grid-selection.ts

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ interface ISelectionKeyboardState {
3333

3434
interface ISelectionPointerState extends ISelectionKeyboardState {
3535
ctrl: boolean;
36+
primaryButton: boolean;
3637
}
3738

3839
type SelectionState = ISelectionKeyboardState | ISelectionPointerState;
@@ -105,7 +106,7 @@ export class IgxGridCRUDService {
105106
}
106107

107108
sameRow(rowID): boolean {
108-
return this.row.id === rowID;
109+
return this.row && this.row.id === rowID;
109110
}
110111

111112
sameCell(cell: IgxCell): boolean {
@@ -209,6 +210,7 @@ export class IgxGridSelectionService {
209210
selection = new Map<number, Set<number>>();
210211
temp = new Map<number, Set<number>>();
211212
_ranges: Set<string> = new Set<string>();
213+
_selectionRange: Range;
212214

213215

214216
/**
@@ -218,9 +220,7 @@ export class IgxGridSelectionService {
218220
get ranges(): GridSelectionRange[] {
219221

220222
// The last action was keyboard + shift selection -> add it
221-
if (this.keyboardState.range) {
222-
this._ranges.add(JSON.stringify(this.keyboardState.range));
223-
}
223+
this.addKeyboardRange();
224224

225225
const ranges = Array.from(this._ranges).map(range => JSON.parse(range));
226226

@@ -232,6 +232,14 @@ export class IgxGridSelectionService {
232232
return ranges;
233233
}
234234

235+
get primaryButton(): boolean {
236+
return this.pointerState.primaryButton;
237+
}
238+
239+
set primaryButton(value: boolean) {
240+
this.pointerState.primaryButton = value;
241+
}
242+
235243
constructor(private zone: NgZone) {
236244
this.initPointerState();
237245
this.initKeyboardState();
@@ -255,6 +263,7 @@ export class IgxGridSelectionService {
255263
this.pointerState.ctrl = false;
256264
this.pointerState.shift = false;
257265
this.pointerState.range = null;
266+
this.pointerState.primaryButton = true;
258267
}
259268

260269
/**
@@ -268,6 +277,15 @@ export class IgxGridSelectionService {
268277
this._ranges.add(JSON.stringify(this.generateRange(node)));
269278
}
270279

280+
/**
281+
* Adds the active keyboard range selection (if any) to the `ranges` meta.
282+
*/
283+
addKeyboardRange(): void {
284+
if (this.keyboardState.range) {
285+
this._ranges.add(JSON.stringify(this.keyboardState.range));
286+
}
287+
}
288+
271289
remove(node: ISelectionNode): void {
272290
if (this.selection.has(node.row)) {
273291
this.selection.get(node.row).delete(node.column);
@@ -287,13 +305,22 @@ export class IgxGridSelectionService {
287305
return this.isActiveNode(node) || this.isInMap(node);
288306
}
289307

290-
isActiveNode(node: ISelectionNode): boolean {
308+
isActiveNode(node: ISelectionNode, mrl = false): boolean {
291309
if (this.activeElement) {
292-
return this.activeElement.column === node.column && this.activeElement.row === node.row;
310+
const isActive = this.activeElement.column === node.column && this.activeElement.row === node.row;
311+
if (mrl) {
312+
const layout = this.activeElement.layout;
313+
return isActive && this.isActiveLayout(layout, node.layout);
314+
}
315+
return isActive;
293316
}
294317
return false;
295318
}
296319

320+
isActiveLayout(current: IMultiRowLayoutNode, target: IMultiRowLayoutNode): boolean {
321+
return current.columnVisibleIndex === target.columnVisibleIndex;
322+
}
323+
297324
addRangeMeta(node: ISelectionNode, state?: SelectionState): void {
298325
this._ranges.add(JSON.stringify(this.generateRange(node, state)));
299326
}
@@ -329,7 +356,7 @@ export class IgxGridSelectionService {
329356
/**
330357
*
331358
*/
332-
keyboardStateOnKeydown(node: ISelectionNode, shift: boolean, shiftTab: boolean) {
359+
keyboardStateOnKeydown(node: ISelectionNode, shift: boolean, shiftTab: boolean): void {
333360
this.keyboardState.active = true;
334361
this.initPointerState();
335362
this.keyboardState.shift = shift && !shiftTab;
@@ -363,10 +390,7 @@ export class IgxGridSelectionService {
363390

364391
pointerDown(node: ISelectionNode, shift: boolean, ctrl: boolean): void {
365392

366-
if (this.keyboardState.range) {
367-
this._ranges.add(JSON.stringify(this.keyboardState.range));
368-
}
369-
393+
this.addKeyboardRange();
370394
this.initKeyboardState();
371395
this.pointerState.ctrl = ctrl;
372396
this.pointerState.shift = shift;
@@ -379,7 +403,7 @@ export class IgxGridSelectionService {
379403
if (shift) {
380404
// No previously 'clicked' node. Use the last active node.
381405
if (!this.pointerState.node) {
382-
this.pointerState.node = this.activeElement;
406+
this.pointerState.node = this.activeElement || node;
383407
}
384408
this.pointerDownShiftKey(node);
385409
this.clearTextSelection();
@@ -414,8 +438,9 @@ export class IgxGridSelectionService {
414438
}
415439
}
416440

417-
pointerEnter(node: ISelectionNode, dragEnabled: boolean): boolean {
418-
this.dragMode = dragEnabled;
441+
pointerEnter(node: ISelectionNode, event: PointerEvent): boolean {
442+
// https://www.w3.org/TR/pointerevents/#the-button-property
443+
this.dragMode = event.buttons === 1 && event.button === -1;
419444
if (!this.dragMode) {
420445
return false;
421446
}
@@ -428,13 +453,14 @@ export class IgxGridSelectionService {
428453
this.pointerState.node = node;
429454
}
430455

431-
this.pointerState.ctrl ? this.blah(node, this.pointerState) :
456+
this.pointerState.ctrl ? this.selectRange(node, this.pointerState, this.temp) :
432457
this.dragSelect(node, this.pointerState);
433458
return true;
434459
}
435460

436461
pointerUp(node: ISelectionNode, emitter: EventEmitter<GridSelectionRange>): boolean {
437462
if (this.dragMode) {
463+
this.restoreTextSelection();
438464
this.addRangeMeta(node, this.pointerState);
439465
this.mergeMap(this.selection, this.temp);
440466
this.zone.runTask(() => emitter.emit(this.generateRange(node, this.pointerState)));
@@ -445,6 +471,7 @@ export class IgxGridSelectionService {
445471

446472
if (this.pointerState.shift) {
447473
this.clearTextSelection();
474+
this.restoreTextSelection();
448475
emitter.emit(this.generateRange(node, this.pointerState));
449476
this.addRangeMeta(node, this.pointerState);
450477
return true;
@@ -454,23 +481,15 @@ export class IgxGridSelectionService {
454481
return false;
455482
}
456483

457-
selectRange(node: ISelectionNode, state: SelectionState) {
458-
const { rowStart, rowEnd, columnStart, columnEnd } = this.generateRange(node, state);
459-
for (let i = rowStart; i <= rowEnd; i++) {
460-
for (let j = columnStart as number; j <= columnEnd; j++) {
461-
this.selection.has(i) ? this.selection.get(i).add(j) :
462-
this.selection.set(i, new Set<number>()).get(i).add(j);
463-
}
484+
selectRange(node: ISelectionNode, state: SelectionState, collection: Map<number, Set<number>> = this.selection): void {
485+
if (collection === this.temp) {
486+
collection.clear();
464487
}
465-
}
466-
467-
blah(node: ISelectionNode, state: SelectionState) {
468-
this.temp.clear();
469488
const { rowStart, rowEnd, columnStart, columnEnd } = this.generateRange(node, state);
470489
for (let i = rowStart; i <= rowEnd; i++) {
471490
for (let j = columnStart as number; j <= columnEnd; j++) {
472-
this.temp.has(i) ? this.temp.get(i).add(j) :
473-
this.temp.set(i, new Set<number>()).get(i).add(j);
491+
collection.has(i) ? collection.get(i).add(j) :
492+
collection.set(i, new Set<number>()).get(i).add(j);
474493
}
475494
}
476495
}
@@ -488,10 +507,28 @@ export class IgxGridSelectionService {
488507
this._ranges.clear();
489508
}
490509

491-
clearTextSelection() {
510+
clearTextSelection(): void {
492511
const selection = window.getSelection();
493-
if (selection) {
512+
if (selection.rangeCount) {
513+
this._selectionRange = selection.getRangeAt(0);
514+
this._selectionRange.collapse(true);
494515
selection.removeAllRanges();
495516
}
496517
}
518+
519+
restoreTextSelection(): void {
520+
const selection = window.getSelection();
521+
if (!selection.rangeCount) {
522+
selection.addRange(this._selectionRange);
523+
}
524+
}
525+
526+
_moveSelectionChrome(node: Node) {
527+
const selection = window.getSelection();
528+
selection.removeAllRanges();
529+
const range = new Range();
530+
range.selectNode(node);
531+
range.collapse(true);
532+
selection.addRange(range);
533+
}
497534
}

projects/igniteui-angular/src/lib/core/utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
*@hidden
33
*/
4-
export function cloneArray(array, deep?: boolean) {
4+
export function cloneArray(array: any[], deep?: boolean) {
55
const arr = [];
66
if (!array) {
77
return arr;
@@ -226,6 +226,13 @@ export function isFirefox(): boolean {
226226
return firefoxBrowser;
227227
}
228228

229+
/**
230+
* @hidden
231+
*/
232+
export function isLeftClick(event: PointerEvent) {
233+
return event.button === 0;
234+
}
235+
229236
/** @hidden */
230237
export function isNavigationKey(key: string): boolean {
231238
return ['down', 'up', 'left', 'right', 'arrowdown', 'arrowup', 'arrowleft', 'arrowright',

projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ class DataGenerator {
11031103
for (let j = 0; j < numCols; j++) {
11041104
cols.push({
11051105
field: j.toString(),
1106-
width: j % 8 < 2 ? 100 : (j % 6 + 0.25) * 125
1106+
width: j % 8 < 2 ? 100 : Math.floor((j % 6 + 0.25) * 125)
11071107
});
11081108
}
11091109

projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,8 +1195,8 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
11951195
}
11961196

11971197
private _getItemSize(item, dimension: string): number {
1198-
const hasDimension = (item[dimension] !== null && item[dimension] !== undefined);
1199-
return hasDimension ? parseInt(item[dimension], 10) : this.igxForItemSize;
1198+
const dim = item[dimension];
1199+
return typeof dim === 'number' ? dim : this.igxForItemSize;
12001200
}
12011201
}
12021202

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ Providing reference from custom component which has already been registered into
9999
| `igxToggleAction`| `IToggleView` \| `string` | Determines the target that have to be controled. |
100100
| `overlaySettings` | `OverlaySettings`| Passes `igxOverlay` settings for applicable targets (`igxToggle`) that control positioning, interaction and scroll behavior.
101101
| `igxToggleOutlet` | `IgxOverlayOutletDirective` \| `ElementRef`| Determines where the target overlay element should be attached. Shortcut for `overlaySettings.outlet`.
102-
| `closeOnOutsideClick`| `Boolean` | **Deprecated.** Determines if passed Component/Directive have to be closed when it is clicked outside. |
103102

104103
# IgxOverlayOutlet Directive
105104

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

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { filter, takeUntil } from 'rxjs/operators';
2020
import { Subscription, Subject, MonoTypeOperatorFunction } from 'rxjs';
2121
import { OverlayClosingEventArgs } from '../../services/overlay/utilities';
2222
import { CancelableEventArgs, CancelableBrowserEventArgs } from '../../core/utils';
23-
import { DeprecateProperty } from '../../core/deprecateDecorators';
2423

2524
@Directive({
2625
exportAs: 'toggle',
@@ -346,30 +345,6 @@ export class IgxToggleActionDirective implements OnInit {
346345
@Input()
347346
public overlaySettings: OverlaySettings;
348347

349-
private _closeOnOutsideClick: boolean;
350-
/**
351-
* DEPRECATED. Determines whether the toggle should close when you click outside.
352-
*
353-
* ```typescript
354-
* // get
355-
* let closesOnOutsideClick = this.toggle.closeOnOutsideClick;
356-
* ```
357-
*/
358-
@Input()
359-
@DeprecateProperty(`igxToggleAction 'closeOnOutsideClick' input is deprecated. Use 'overlaySettings' input object instead.`)
360-
public get closeOnOutsideClick(): boolean {
361-
return this._closeOnOutsideClick;
362-
}
363-
/**
364-
* ```html
365-
* <!--set-->
366-
* <div igxToggleAction [closeOnOutsideClick]="'true'"></div>
367-
* ```
368-
*/
369-
public set closeOnOutsideClick(v: boolean) {
370-
this._closeOnOutsideClick = v;
371-
}
372-
373348
/**
374349
* Determines where the toggle element overlay should be attached.
375350
*
@@ -424,9 +399,6 @@ export class IgxToggleActionDirective implements OnInit {
424399
*/
425400
@HostListener('click')
426401
public onClick() {
427-
if (this._closeOnOutsideClick !== undefined) {
428-
this._overlayDefaults.closeOnOutsideClick = this._closeOnOutsideClick;
429-
}
430402
if (this.outlet) {
431403
this._overlayDefaults.outlet = this.outlet;
432404
}

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,6 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
199199
}
200200

201201
private checkOutletAndOutsideClick() {
202-
if (this.closeOnOutsideClick !== undefined) {
203-
this._overlayDefaults.closeOnOutsideClick = this.closeOnOutsideClick;
204-
}
205202
if (this.outlet) {
206203
this._overlayDefaults.outlet = this.outlet;
207204
}

0 commit comments

Comments
 (0)