Skip to content

Commit dc072b3

Browse files
authored
Merge branch 'master' into mdragnev/fix-7209
2 parents aac513c + 720f0e8 commit dc072b3

20 files changed

+186
-152
lines changed

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,21 +1216,19 @@ describe('igxCombo', () => {
12161216
fixture.detectChanges();
12171217
let items = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`));
12181218
let lastItem = items[items.length - 1].componentInstance;
1219-
let lastItemIndex = lastItem.index;
12201219
expect(lastItem).toBeDefined();
12211220
lastItem.clicked(mockClick);
12221221
await wait(30);
12231222
fixture.detectChanges();
1224-
expect(dropdown.focusedItem.index).toEqual(lastItemIndex);
1223+
expect(dropdown.focusedItem).toEqual(lastItem);
12251224
dropdown.navigateItem(-1);
12261225
await wait(30);
12271226
fixture.detectChanges();
12281227
expect(virtualMockDOWN).toHaveBeenCalledTimes(0);
1229-
lastItemIndex = lastItem.index;
12301228
lastItem.clicked(mockClick);
12311229
await wait(30);
12321230
fixture.detectChanges();
1233-
expect(dropdown.focusedItem.index).toEqual(lastItemIndex);
1231+
expect(dropdown.focusedItem).toEqual(lastItem);
12341232
dropdown.navigateNext();
12351233
await wait(30);
12361234
fixture.detectChanges();

projects/igniteui-angular/src/lib/core/styles/components/card/_card-component.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@
6767

6868
@include b(igx-card-content) {
6969
@extend %igx-card-content !optional;
70-
71-
@include e(text) {
72-
@extend %igx-card-content-text !optional;
73-
}
7470
}
7571

7672
@include b(igx-card-actions) {

projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss

Lines changed: 6 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -123,43 +123,14 @@
123123

124124
$variant: map-get($theme, 'variant');
125125
$not-material-theme: $variant != 'material';
126-
$bootstrap-theme: $variant == 'bootstrap';
127-
128-
// Bootstrap card spacing
129-
// if you need to change the spacing for the bootstrap card, please, change only $bs-spacing-val.
130-
// All the margin will automatically calculate accordingly in order to keep the right proportion.
131-
$bs-spacing-val: rem(20px);
132-
$bs-margin-media: $bs-spacing-val;
133-
$bs-margin-heading: rem(12px);
134-
$bs-margin-heading-difference: calc(#{$bs-spacing-val} - #{$bs-margin-heading});
135-
$bs-margin-content: rem(16px);
136-
$bs-margin-actions: $bs-spacing-val;
137-
138-
$card-heading-padding: map-get((
139-
material: rem(16px),
140-
fluent: rem(16px),
141-
bootstrap: 0 $bs-spacing-val,
142-
), $variant);
143-
144-
$card-heading-compact-padding: map-get((
145-
material: rem(16px, 16px),
146-
fluent: rem(16px, 16px),
147-
bootstrap: 0 $bs-spacing-val,
148-
), $variant);
149-
150-
$card-content-padding: map-get((
151-
material: rem(14px),
152-
fluent: rem(14px),
153-
bootstrap: 0 $bs-spacing-val,
154-
), $variant);
155-
156-
$card-actions-padding: map-get((
157-
material: rem(8px),
158-
fluent: rem(8px),
159-
bootstrap: 0 $bs-spacing-val,
160-
), $variant);
126+
127+
$card-heading-padding: rem(16px);
128+
$card-heading-compact-padding: rem(16px, 16px);
129+
$card-content-padding: rem(14px);
130+
$card-actions-padding: rem(8px);
161131

162132
$card-tgroup-margin: 0 em(16px);
133+
163134
$card-transitions: box-shadow .3s cubic-bezier(.25, .8, .25, 1);
164135
$left: if-ltr(left, right);
165136
$right: if-ltr(right, left);
@@ -204,21 +175,9 @@
204175
width: 100%;
205176
padding: $card-heading-padding;
206177
color: --var($theme, 'header-text-color');
207-
@if $bootstrap-theme {
208-
margin-bottom: $bs-margin-heading;
209-
210-
&:first-child {
211-
padding-top: $bs-spacing-val;
212-
}
213-
214-
&:last-child {
215-
margin-bottom: calc(#{$bs-margin-heading-difference} + #{$bs-margin-heading});
216-
}
217-
}
218178

219179
&:empty {
220180
display: block;
221-
min-height: $bs-spacing-val;
222181
padding: 0;
223182
}
224183
}
@@ -277,31 +236,12 @@
277236
flex: 1 1 auto;
278237
padding: $card-content-padding;
279238
color: --var($theme, 'content-text-color');
280-
281-
@if $bootstrap-theme {
282-
margin-bottom: $bs-margin-content;
283-
284-
&:first-child {
285-
padding-top: $bs-spacing-val;
286-
}
287-
288-
&:last-child {
289-
margin-bottom: calc(#{$bs-margin-heading-difference} + #{$bs-margin-heading});
290-
}
291-
}
292239
}
293240

294241
%igx-card-media {
295242
display: block;
296243
overflow: hidden;
297244
line-height: 0;
298-
@if $bootstrap-theme {
299-
margin-bottom: $bs-margin-media;
300-
301-
&:last-child {
302-
margin-bottom: 0;
303-
}
304-
}
305245

306246
> * {
307247
width: 100%;
@@ -323,13 +263,6 @@
323263
flex: 0 1 auto;
324264
align-items: center;
325265
padding: $card-actions-padding;
326-
@if $bootstrap-theme {
327-
margin-bottom: $bs-margin-actions;
328-
329-
&:first-child {
330-
padding-top: $bs-spacing-val;
331-
}
332-
}
333266

334267
[igxButton] ~ [igxButton] {
335268
margin-#{$left}: rem(8px);

projects/igniteui-angular/src/lib/core/styles/components/dialog/_dialog-theme.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
}
149149

150150
%igx-dialog-title {
151+
display: flex;
151152
color: --var($theme, 'title-color');
152153
padding: $dialog-title-padding;
153154

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

Lines changed: 86 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
TemplateRef,
2323
TrackByFunction,
2424
ViewContainerRef,
25-
ViewRef,
2625
AfterViewInit
2726
} from '@angular/core';
2827

@@ -850,27 +849,89 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
850849
this.sizesCache,
851850
0
852851
);
852+
853853
if (newStart + this.state.chunkSize > count) {
854854
newStart = count - this.state.chunkSize;
855855
}
856+
857+
const prevStart = this.state.startIndex;
856858
const diff = newStart - this.state.startIndex;
857859
this.state.startIndex = newStart;
860+
858861
if (diff) {
859862
this.onChunkPreload.emit(this.state);
860863
if (!this.isRemote) {
861-
this.fixedApplyScroll();
864+
865+
// recalculate and apply page size.
866+
if (diff && Math.abs(diff) <= this.MAX_PERF_SCROLL_DIFF) {
867+
diff > 0 ? this.moveApplyScrollNext(prevStart) : this.moveApplyScrollPrev(prevStart);
868+
} else {
869+
this.fixedApplyScroll();
870+
}
862871
}
863872
}
873+
864874
return inScrollTop - this.sizesCache[this.state.startIndex];
865875
}
866876

877+
/**
878+
* @hidden
879+
* The function applies an optimized state change for scrolling down/right employing context change with view rearrangement
880+
*/
881+
protected moveApplyScrollNext(prevIndex: number): void {
882+
const start = prevIndex + this.state.chunkSize;
883+
const end = start + this.state.startIndex - prevIndex;
884+
const container = this.dc.instance._vcr as ViewContainerRef;
885+
886+
for (let i = start; i < end && this.igxForOf[i] !== undefined; i++) {
887+
const embView = this._embeddedViews.shift();
888+
this.scrollFocus(embView.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE)
889+
|| embView.rootNodes[0].nextElementSibling);
890+
const view = container.detach(0);
891+
892+
this.updateTemplateContext(embView.context, i);
893+
container.insert(view);
894+
this._embeddedViews.push(embView);
895+
}
896+
}
897+
898+
/**
899+
* @hidden
900+
* The function applies an optimized state change for scrolling up/left employing context change with view rearrangement
901+
*/
902+
protected moveApplyScrollPrev(prevIndex: number): void {
903+
const container = this.dc.instance._vcr as ViewContainerRef;
904+
for (let i = prevIndex - 1; i >= this.state.startIndex && this.igxForOf[i] !== undefined; i--) {
905+
const embView = this._embeddedViews.pop();
906+
this.scrollFocus(embView.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE)
907+
|| embView.rootNodes[0].nextElementSibling);
908+
const view = container.detach(container.length - 1);
909+
910+
this.updateTemplateContext(embView.context, i);
911+
container.insert(view, 0);
912+
this._embeddedViews.unshift(embView);
913+
}
914+
}
915+
867916
/**
868917
* @hidden
869918
*/
870919
protected getContextIndex(input) {
871920
return this.isRemote ? this.state.startIndex + this.igxForOf.indexOf(input) : this.igxForOf.indexOf(input);
872921
}
873922

923+
/**
924+
* @hidden
925+
* Function which updates the passed context of an embedded view with the provided index
926+
* from the view container.
927+
* Often, called while handling a scroll event.
928+
*/
929+
protected updateTemplateContext(context: any, index: number = 0): void {
930+
context.$implicit = this.igxForOf[index];
931+
context.index = this.getContextIndex(this.igxForOf[index]);
932+
context.count = this.igxForOf.length;
933+
}
934+
874935
/**
875936
* @hidden
876937
* The function applies an optimized state change through context change for each view
@@ -879,12 +940,28 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
879940
let j = 0;
880941
const endIndex = this.state.startIndex + this.state.chunkSize;
881942
for (let i = this.state.startIndex; i < endIndex && this.igxForOf[i] !== undefined; i++) {
882-
const input = this.igxForOf[i];
883943
const embView = this._embeddedViews[j++];
884-
const cntx = (embView as EmbeddedViewRef<any>).context;
885-
cntx.$implicit = input;
886-
cntx.index = this.getContextIndex(input);
887-
cntx.count = this.igxForOf.length;
944+
this.updateTemplateContext(embView.context, i);
945+
}
946+
}
947+
948+
/**
949+
* @hidden
950+
* @internal
951+
*
952+
* Clears focus inside the virtualized container on small scroll swaps.
953+
*/
954+
protected scrollFocus(node?: HTMLElement): void {
955+
const activeElement = document.activeElement as HTMLElement;
956+
957+
// Remove focus in case the the active element is inside the view container.
958+
// Otherwise we hit an exception while doing the 'small' scrolls swapping.
959+
// For more information:
960+
//
961+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild
962+
// https://bugs.chromium.org/p/chromium/issues/detail?id=432392
963+
if (node && node.contains(document.activeElement)) {
964+
activeElement.blur();
888965
}
889966
}
890967

@@ -950,12 +1027,8 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
9501027
endIndex = this.igxForOf.length;
9511028
}
9521029
for (let i = startIndex; i < endIndex && this.igxForOf[i] !== undefined; i++) {
953-
const input = this.igxForOf[i];
9541030
const embView = embeddedViewCopy.shift();
955-
const cntx = (embView as EmbeddedViewRef<any>).context;
956-
cntx.$implicit = input;
957-
cntx.index = this.getContextIndex(input);
958-
cntx.count = this.igxForOf.length;
1031+
this.updateTemplateContext(embView.context, i);
9591032
}
9601033
if (prevChunkSize !== this.state.chunkSize) {
9611034
this.onChunkLoad.emit(this.state);
@@ -1612,12 +1685,8 @@ export class IgxGridForOfDirective<T> extends IgxForOfDirective<T> implements On
16121685
}
16131686

16141687
for (let i = startIndex; i < endIndex && this.igxForOf[i] !== undefined; i++) {
1615-
const input = this.igxForOf[i];
16161688
const embView = embeddedViewCopy.shift();
1617-
const cntx = (embView as EmbeddedViewRef<any>).context;
1618-
cntx.$implicit = input;
1619-
cntx.index = this.getContextIndex(input);
1620-
cntx.count = this.igxForOf.length;
1689+
this.updateTemplateContext(embView.context, i);
16211690
}
16221691
if (prevChunkSize !== this.state.chunkSize) {
16231692
this.onChunkLoad.emit(this.state);

projects/igniteui-angular/src/lib/grids/cell.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@
1111
<ng-template #inlineEditor let-cell="cell">
1212
<ng-container *ngIf="column.dataType === 'string'">
1313
<igx-input-group displayDensity="compact">
14-
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="focused" />
14+
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="true" />
1515
</igx-input-group>
1616
</ng-container>
1717
<ng-container *ngIf="column.dataType === 'number'">
1818
<igx-input-group displayDensity="compact">
19-
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="focused" type="number">
19+
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="true" type="number">
2020
</igx-input-group>
2121
</ng-container>
2222
<ng-container *ngIf="column.dataType === 'boolean'">
2323
<igx-checkbox (change)="editValue = $event.checked" [value]="editValue" [checked]="editValue"
24-
[igxFocus]="focused" [disableRipple]="true"></igx-checkbox>
24+
[igxFocus]="true" [disableRipple]="true"></igx-checkbox>
2525
</ng-container>
2626
<ng-container *ngIf="column.dataType === 'date'">
2727
<igx-date-picker [style.width.%]="100" [outlet]="grid.outletDirective" mode="dropdown"
28-
[locale]="grid.locale" [(value)]="editValue" [igxFocus]="focused" [labelVisibility]="false">
28+
[locale]="grid.locale" [(value)]="editValue" [igxFocus]="true" [labelVisibility]="false">
2929
</igx-date-picker>
3030
</ng-container>
3131
</ng-template>

projects/igniteui-angular/src/lib/grids/cell.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
666666
}
667667
}
668668
crud.end();
669-
this.grid.tbody.nativeElement.focus();
669+
this.grid.tbody.nativeElement.focus({ preventScroll: true });
670670
this.grid.notifyChanges();
671671
crud.begin(this);
672672
return;

projects/igniteui-angular/src/lib/grids/common/events.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { IgxGridCellComponent } from '../cell.component';
77
import { IgxColumnComponent } from '../columns/column.component';
88
import { IgxGridBaseDirective } from '../grid-base.directive';
99
import { IgxRowDirective } from '../row.directive';
10-
10+
export { GridSelectionRange } from '../selection/selection.service';
1111

1212
export interface IGridClipboardEvent {
1313
data: any[];

0 commit comments

Comments
 (0)