Skip to content

Commit 80d5fd3

Browse files
authored
Merge branch '8.2.x' into mkirova/fix-5683-8.2.x
2 parents 9a54ee5 + 6c348ca commit 80d5fd3

File tree

48 files changed

+708
-186
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+708
-186
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ Next example shows how you can use the Fluent theme.
2424
}
2525
```
2626

27+
### Theme Changes
28+
`igx-badge-theme` - Removed the `$disable-shadow` property to mitigate confusion when specifying `$shadow` explicitly.
29+
2730
For more information about the theming please read our [documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/themes/index.html)
2831

2932
### New Features
@@ -64,6 +67,8 @@ For more information about the theming please read our [documentation](https://w
6467
- introduced a new `readonly` property that doesn't allow user interaction to change the state, but keeps the default active style. Intended for integration in complex controls that handle the interaction and control the checkbox instead through binding.
6568
- `IgxOverlay`
6669
- introduced a new `ContainerPositionStrategy`. The new strategy positions the element inside the containing outlet based on the directions passed in trough PositionSettings.
70+
- `IgxChip`
71+
- add `onSelectionDone` event that is triggered after all animations and transitions related to selection have ended.
6772

6873
### General
6974
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"$schema": "../../common/schema/theme-props.schema.json",
3+
"changes": [{
4+
"name": "$disable-shadow",
5+
"remove": true,
6+
"owner": "igx-badge-theme"
7+
}]
8+
}

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

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export class IgxCarouselComponent implements OnDestroy {
107107
* Sets the time `interval` in milliseconds before the slide changes.
108108
* If not set, the carousel will not change `slides` automatically.
109109
* ```html
110-
* <igx-carousel [interval] = "1000"></carousel>
110+
* <igx-carousel [interval] = "1000"></igx-carousel>
111111
* ```
112112
* @memberof IgxCarouselComponent
113113
*/
@@ -512,12 +512,12 @@ export class IgxCarouselComponent implements OnDestroy {
512512
})
513513

514514
export class IgxSlideComponent implements OnInit, OnDestroy {
515-
515+
private _active;
516516
/**
517517
* Gets/sets the `index` of the slide inside the carousel.
518518
* ```html
519519
* <igx-carousel>
520-
* <igx-slide index = "1"</igx-slide>
520+
* <igx-slide index = "1"></igx-slide>
521521
* <igx-carousel>
522522
* ```
523523
* @memberOf IgxSlideComponent
@@ -528,7 +528,7 @@ export class IgxSlideComponent implements OnInit, OnDestroy {
528528
* Gets/sets the target `direction` for the slide.
529529
* ```html
530530
* <igx-carousel>
531-
* <igx-slide direction="NEXT"</igx-slide>
531+
* <igx-slide direction="NEXT"></igx-slide>
532532
* <igx-carousel>
533533
* ```
534534
* @memberOf IgxSlideComponent
@@ -538,13 +538,31 @@ export class IgxSlideComponent implements OnInit, OnDestroy {
538538
* Gets/sets the `active` state of the slide.
539539
* ```html
540540
* <igx-carousel>
541-
* <igx-slide [active] ="false"</igx-slide>
541+
* <igx-slide [active] ="false"></igx-slide>
542+
* <igx-carousel>
543+
* ```
544+
*
545+
* Two-way data binding.
546+
* ```html
547+
* <igx-carousel>
548+
* <igx-slide [(active)] ="model.isActive"></igx-slide>
542549
* <igx-carousel>
543550
* ```
544551
* @memberof IgxSlideComponent
545552
*/
546553
@HostBinding('class.active')
547-
@Input() public active: boolean;
554+
@Input()
555+
public get active(): boolean {
556+
return this._active;
557+
}
558+
public set active(value) {
559+
this._active = value;
560+
this.activeChange.emit(this._active);
561+
}
562+
/**
563+
*@hidden
564+
*/
565+
@Output() public activeChange = new EventEmitter<boolean>();
548566

549567
constructor(private carousel: IgxCarouselComponent) { }
550568
/**

projects/igniteui-angular/src/lib/chips/chip.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
(enter)="onChipDragEnterHandler($event)"
1313
(dropped)="onChipDrop($event)">
1414

15-
<div [ngClass]="selectClass(selected)">
15+
<div [ngClass]="selectClass(selected)" (transitionend)="onSelectTransitionDone($event)">
1616
<ng-container *ngTemplateOutlet="selectIconTemplate"></ng-container>
1717
</div>
1818

projects/igniteui-angular/src/lib/chips/chip.component.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,23 @@ export class IgxChipComponent extends DisplayDensityBase {
165165
* ```html
166166
* <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" [selected]="true">
167167
* ```
168+
*
169+
* Two-way data binding:
170+
* ```html
171+
* <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" [(selected)]="model.isSelected">
172+
* ```
168173
*/
169174
@Input()
170175
public set selected(newValue: boolean) {
171176
this.changeSelection(newValue);
172177
}
173178

179+
/**
180+
*@hidden
181+
*/
182+
@Output()
183+
public selectedChange = new EventEmitter<boolean>();
184+
174185
/**
175186
* Returns if the `IgxChipComponent` is selected.
176187
* ```typescript
@@ -281,12 +292,26 @@ export class IgxChipComponent extends DisplayDensityBase {
281292
* }
282293
* ```
283294
* ```html
284-
* <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onSelection)="chipSelect($event)">
295+
* <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" (onSelection)="chipSelect($event)">
285296
* ```
286297
*/
287298
@Output()
288299
public onSelection = new EventEmitter<IChipSelectEventArgs>();
289300

301+
/**
302+
* Emits event when the `IgxChipComponent` is selected/deselected and any related animations and transitions also end.
303+
* ```typescript
304+
* chipSelectEnd(event: IBaseChipEventArgs){
305+
* let selectedChip = event.owner;
306+
* }
307+
* ```
308+
* ```html
309+
* <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" (onSelectionDone)="chipSelectEnd($event)">
310+
* ```
311+
*/
312+
@Output()
313+
public onSelectionDone = new EventEmitter<IBaseChipEventArgs>();
314+
290315
/**
291316
* Emits an event when the `IgxChipComponent` keyboard navigation is being used.
292317
* Returns the focused/selected `IgxChipComponent`, whether the event should be canceled,
@@ -424,17 +449,29 @@ export class IgxChipComponent extends DisplayDensityBase {
424449
if (!onSelectArgs.cancel) {
425450
this.renderer.addClass(this.chipArea.nativeElement, this._selectedItemClass);
426451
this._selected = newValue;
452+
this.selectedChange.emit(this._selected);
427453
}
428454
} else if (!newValue && this._selected) {
429455
this.onSelection.emit(onSelectArgs);
430456

431457
if (!onSelectArgs.cancel) {
432458
this.renderer.removeClass(this.chipArea.nativeElement, this._selectedItemClass);
433459
this._selected = newValue;
460+
this.selectedChange.emit(this._selected);
434461
}
435462
}
436463
}
437464

465+
public onSelectTransitionDone(event) {
466+
if (event.propertyName === 'width' && !!event.target.tagName) {
467+
// Trigger onSelectionDone on when `width` property is changed and the target is valid element(not comment).
468+
this.onSelectionDone.emit({
469+
owner: this,
470+
originalEvent: event
471+
});
472+
}
473+
}
474+
438475
/**
439476
* @hidden
440477
*/

projects/igniteui-angular/src/lib/chips/chip.spec.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { IgxPrefixDirective } from './../directives/prefix/prefix.directive';
1313
import { IgxLabelDirective } from './../directives/label/label.directive';
1414
import { IgxSuffixDirective } from './../directives/suffix/suffix.directive';
1515
import { DisplayDensity } from '../core/displayDensity';
16-
import { UIInteractions} from '../test-utils/ui-interactions.spec';
16+
import { UIInteractions, wait} from '../test-utils/ui-interactions.spec';
1717
import { configureTestSuite } from '../test-utils/configure-suite';
1818

1919
@Component({
@@ -398,13 +398,14 @@ describe('IgxChip', () => {
398398
});
399399
});
400400

401-
it('should fire onSelection event when selectable is true', () => {
401+
it('should fire onSelection event when selectable is true', (async() => {
402402
const fix = TestBed.createComponent(TestChipComponent);
403403
fix.detectChanges();
404404

405405
const secondChipComp = fix.componentInstance.chips.toArray()[1];
406406

407407
spyOn(secondChipComp.onSelection, 'emit');
408+
spyOn(secondChipComp.onSelectionDone, 'emit');
408409
secondChipComp.chipArea.nativeElement.focus();
409410

410411
const keyEvent = new KeyboardEvent('keydown', {
@@ -413,7 +414,11 @@ describe('IgxChip', () => {
413414
secondChipComp.chipArea.nativeElement.dispatchEvent(keyEvent);
414415
fix.detectChanges();
415416
expect(secondChipComp.onSelection.emit).toHaveBeenCalled();
416-
});
417+
expect(secondChipComp.onSelectionDone.emit).not.toHaveBeenCalled();
418+
419+
await wait(400);
420+
expect(secondChipComp.onSelectionDone.emit).toHaveBeenCalled();
421+
}));
417422

418423
it('should not fire onSelection event when selectable is false', () => {
419424
const fix = TestBed.createComponent(TestChipComponent);
@@ -422,6 +427,7 @@ describe('IgxChip', () => {
422427
const firstChipComp = fix.componentInstance.chips.toArray()[0];
423428

424429
spyOn(firstChipComp.onSelection, 'emit');
430+
spyOn(firstChipComp.onSelectionDone, 'emit');
425431
firstChipComp.elementRef.nativeElement.focus();
426432

427433
const keyEvent = new KeyboardEvent('keydown', {
@@ -430,6 +436,7 @@ describe('IgxChip', () => {
430436
firstChipComp.elementRef.nativeElement.dispatchEvent(keyEvent);
431437
fix.detectChanges();
432438
expect(firstChipComp.onSelection.emit).toHaveBeenCalledTimes(0);
439+
expect(firstChipComp.onSelectionDone.emit).toHaveBeenCalledTimes(0);
433440
});
434441

435442
it('should not fire onSelection event when the remove button is clicked', () => {
@@ -439,6 +446,7 @@ describe('IgxChip', () => {
439446
const secondChipComp = fix.componentInstance.chips.toArray()[1];
440447

441448
spyOn(secondChipComp.onSelection, 'emit');
449+
spyOn(secondChipComp.onSelectionDone, 'emit');
442450

443451
const chipRemoveButton = secondChipComp.elementRef.nativeElement.querySelectorAll('.' + CHIP_REMOVE_BUTTON)[0];
444452
const removeBtnTop = chipRemoveButton.getBoundingClientRect().top;
@@ -450,5 +458,6 @@ describe('IgxChip', () => {
450458
fix.detectChanges();
451459

452460
expect(secondChipComp.onSelection.emit).not.toHaveBeenCalled();
461+
expect(secondChipComp.onSelectionDone.emit).not.toHaveBeenCalled();
453462
});
454463
});

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

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,8 @@ describe('igxCombo', () => {
960960
// Combo selection is now based on valueKey:
961961
// if valueKey is specified, only the key will be written in the selection (not the whole data entry)
962962
const itemID = combo.valueKey !== null && combo.value !== undefined ?
963-
combo.data[itemIndex][combo.valueKey] :
964-
combo.data[itemIndex];
963+
combo.data[itemIndex][combo.valueKey] :
964+
combo.data[itemIndex];
965965
expect(combo.isItemSelected(itemID)).toBeTruthy();
966966
expect(combo.selectedItems()[selectedItemIndex]).toEqual(itemID);
967967
}
@@ -971,8 +971,8 @@ describe('igxCombo', () => {
971971
itemIndex: number) {
972972
const checkbox = getCheckbox(dropdownElement, itemIndex);
973973
const itemID = combo.valueKey !== null && combo.value !== undefined ?
974-
combo.data[itemIndex][combo.valueKey] :
975-
combo.data[itemIndex];
974+
combo.data[itemIndex][combo.valueKey] :
975+
combo.data[itemIndex];
976976
expect(checkbox.classList.contains(CSS_CLASS_CHECKED)).toBeFalsy();
977977
expect(combo.isItemSelected(itemID)).toBeFalsy();
978978
}
@@ -2286,6 +2286,37 @@ describe('igxCombo', () => {
22862286
}, 20);
22872287
}, 10);
22882288
});
2289+
2290+
it('Should bind combo data to remote data and clear selection properly', async (done) => {
2291+
const fixture = TestBed.createComponent(IgxComboRemoteDataComponent);
2292+
fixture.detectChanges();
2293+
const combo = fixture.componentInstance.instance;
2294+
let selectedItems = [combo.data[0], combo.data[1]];
2295+
const spyObj = jasmine.createSpyObj('event', ['stopPropagation']);
2296+
combo.toggle();
2297+
combo.selectItems([selectedItems[0][combo.valueKey], selectedItems[1][combo.valueKey]]);
2298+
expect(combo.value).toEqual(`${selectedItems[0][combo.displayKey]}, ${selectedItems[1][combo.displayKey]}`);
2299+
expect(combo.selectedItems()).toEqual([selectedItems[0][combo.valueKey], selectedItems[1][combo.valueKey]]);
2300+
// Clear items while they are in view
2301+
combo.handleClearItems(spyObj);
2302+
expect(combo.selectedItems()).toEqual([]);
2303+
expect(combo.value).toBe('');
2304+
selectedItems = [combo.data[2], combo.data[3]];
2305+
combo.selectItems([selectedItems[0][combo.valueKey], selectedItems[1][combo.valueKey]]);
2306+
expect(combo.value).toEqual(`${selectedItems[0][combo.displayKey]}, ${selectedItems[1][combo.displayKey]}`);
2307+
2308+
// Scroll selected items out of view
2309+
combo.virtualScrollContainer.scrollTo(40);
2310+
await wait(60);
2311+
fixture.detectChanges();
2312+
combo.handleClearItems(spyObj);
2313+
expect(combo.selectedItems()).toEqual([]);
2314+
expect(combo.value).toBe('');
2315+
combo.selectItems([combo.data[7][combo.valueKey]]);
2316+
expect(combo.value).toBe(combo.data[7][combo.displayKey]);
2317+
done();
2318+
});
2319+
22892320
it('Should render empty template when combo data source is not set', fakeAsync(() => {
22902321
const fixture = TestBed.createComponent(IgxComboEmptyTestComponent);
22912322
fixture.detectChanges();
@@ -3214,7 +3245,7 @@ describe('igxCombo', () => {
32143245
expect(fixture.componentInstance.comboSelectedItems).toEqual([...data].splice(1, 3));
32153246
}));
32163247

3217-
it('Should properly initialize when used in a Template form control', fakeAsync (() => {
3248+
it('Should properly initialize when used in a Template form control', fakeAsync(() => {
32183249
const fix = TestBed.createComponent(IgxComboInTemplatedFormComponent);
32193250
fix.detectChanges();
32203251
tick();

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,14 +1108,14 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
11081108

11091109
/** Contains key-value pairs of the selected valueKeys and their resp. displayKeys */
11101110
private registerRemoteEntries(ids: any[], add = true) {
1111-
const selection = this.getValueDisplayPairs(ids);
11121111
if (add) {
1112+
const selection = this.getValueDisplayPairs(ids);
11131113
for (const entry of selection) {
11141114
this._remoteSelection[entry[this.valueKey]] = entry[this.displayKey];
11151115
}
11161116
} else {
1117-
for (const entry of selection) {
1118-
delete this._remoteSelection[entry[this.valueKey]];
1117+
for (const entry of ids) {
1118+
delete this._remoteSelection[entry];
11191119
}
11201120
}
11211121
}

projects/igniteui-angular/src/lib/core/styles/components/badge/_badge-theme.scss

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
/// @param {Color} $text-color [null] - The text color used.
1616
/// @param {Color} $border-color [null] - The border color used.
1717
/// @param {Color} $background-color [null] - The background color used.
18-
/// @param {Bool} $disable-shadow [true] - Sets the badge shadow visibility.
1918
/// @param {Bool} $disable-border [true] - Sets the badge border visibility.
2019
/// @param {box-shadow} $shadow [null] - Sets a shadow to be used for the badge.
2120
/// @param {border-radius} $border-radius [null] - The border radius used for badge component.
@@ -52,7 +51,6 @@
5251
$background-color: null,
5352
$shadow: null,
5453
55-
$disable-shadow: true,
5654
$disable-border: true
5755
) {
5856
$name: 'igx-badge';
@@ -77,10 +75,6 @@
7775
$shadow: igx-elevation($elevations, $elevation);
7876
}
7977

80-
@if $disable-shadow {
81-
$shadow: none;
82-
}
83-
8478
@return extend($theme, (
8579
name: $name,
8680
palette: $palette,

projects/igniteui-angular/src/lib/core/styles/components/grid/_excel-filtering-theme.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
/// @requires --var
1313
@mixin _excel-filtering($theme, $palette) {
1414
%grid-excel-filter {
15-
height: rem(15px);
1615
display: block;
1716
}
1817

0 commit comments

Comments
 (0)