Skip to content

Commit 552ad87

Browse files
MKirovaMKirova
authored andcommitted
chore(*): Merge from base.
2 parents f19e27e + 7ccedd1 commit 552ad87

File tree

48 files changed

+971
-454
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

+971
-454
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ All notable changes for each version of this project will be documented in this
3333
<igx-column field="Age"></igx-column>
3434
</igx-grid>
3535
```
36+
- Scrolling with the mouse wheel over cells with templates that include scrollable containers now correctly scroll these inner containers before the grid body scrolls.
3637

3738
## 13.0.5
3839

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ You can include Ignite UI for Angular in your project as a dependency using the
218218

219219
- [COVID-19 Dashboard](https://github.com/IgniteUI/COVID-19-Dashboard) - This dynamic dashboard was built using Indigo.Design and Ignite UI for Angular leveraging timely reports data from CSSEGISandData/COVID-19 to create an useful and impactful visualization. Built in a matter of hours, it showcases the Ignite UI Category and Data Charts, Map and List components for Angular and the how easy it is to get those quickly configured and populated with data.
220220

221-
-[Inventory Management App](https://github.com/IgniteUI/InventoryManagementApp) - The Inventory Management App consists of 2 pages: The Products Page and the Dashboard Page. The Products Page contains a grid with product information and includes a number of useful features
221+
- [Inventory Management App](https://github.com/IgniteUI/InventoryManagementApp) - The Inventory Management App consists of 2 pages: The Products Page and the Dashboard Page. The Products Page contains a grid with product information and includes a number of useful features
222222

223223
### Angular apps with ASP.NET Core Web Application
224224
If you consider Angular client side application with ASP.NET Core application you can check out our [ASP.NET-Core-Samples](https://github.com/IgniteUI/ASP.NET-Core-Samples)

projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,10 @@
577577
@extend %igx-grid__tr-pivot-group !optional
578578
}
579579

580+
@include e(tr-header-row) {
581+
@extend %igx-grid__tr-header-row !optional;
582+
}
583+
580584
@include e(tr-pivot, $m: 'columnDimensionLeaf') {
581585
@extend %igx-grid__tr-pivot--columnDimensionLeaf !optional
582586
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3002,6 +3002,14 @@
30023002
}
30033003
}
30043004
}
3005+
3006+
%igx-grid__tr-header-row {
3007+
igx-pivot-row-dimension-header-group {
3008+
igx-pivot-row-dimension-header {
3009+
align-items: center;
3010+
}
3011+
}
3012+
}
30053013
// Pivot grid END
30063014
}
30073015

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

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,10 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
414414

415415
if (this.igxForScrollOrientation === 'vertical') {
416416
this.dc.instance._viewContainer.element.nativeElement.style.top = '0px';
417-
this.scrollComponent = vc.createComponent(VirtualHelperComponent).instance;
417+
this.scrollComponent = this.syncScrollService.getScrollMaster(this.igxForScrollOrientation);
418+
if (!this.scrollComponent || !this.document.contains(this.scrollComponent.elementRef.nativeElement)) {
419+
this.scrollComponent = vc.createComponent(VirtualHelperComponent).instance
420+
}
418421
this._maxHeight = this._calcMaxBrowserHeight();
419422
this.scrollComponent.size = this.igxForOf ? this._calcHeight() : 0;
420423
this.syncScrollService.setScrollMaster(this.igxForScrollOrientation, this.scrollComponent);
@@ -721,6 +724,34 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
721724
return scroll;
722725
}
723726

727+
/**
728+
* Returns the index of the element at the specified offset.
729+
* ```typescript
730+
* this.parentVirtDir.getIndexAtScroll(100);
731+
* ```
732+
*/
733+
public getIndexAtScroll(scrollOffset: number) {
734+
return this.getIndexAt(scrollOffset, this.sizesCache);
735+
}
736+
/**
737+
* Returns whether the target index is outside the view.
738+
* ```typescript
739+
* this.parentVirtDir.isIndexOutsideView(10);
740+
* ```
741+
*/
742+
public isIndexOutsideView(index: number) {
743+
const targetNode = index >= this.state.startIndex && index <= this.state.startIndex + this.state.chunkSize ?
744+
this._embeddedViews.map(view =>
745+
view.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE) || view.rootNodes[0].nextElementSibling)[index - this.state.startIndex] : null;
746+
const rowHeight = this.getSizeAt(index);
747+
const containerSize = parseInt(this.igxForContainerSize, 10);
748+
const containerOffset = -(this.scrollPosition - this.sizesCache[this.state.startIndex]);
749+
const endTopOffset = targetNode ? targetNode.offsetTop + rowHeight + containerOffset : containerSize + rowHeight;
750+
return !targetNode || targetNode.offsetTop < Math.abs(containerOffset)
751+
|| containerSize && endTopOffset - containerSize > 5;
752+
}
753+
754+
724755
/**
725756
* @hidden
726757
* Function that recalculates and updates cache sizes.
@@ -1115,20 +1146,16 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
11151146
protected initSizesCache(items: any[]): number {
11161147
let totalSize = 0;
11171148
let size = 0;
1118-
const dimension = this.igxForScrollOrientation === 'horizontal' ?
1119-
this.igxForSizePropName : 'height';
1149+
const dimension = this.igxForSizePropName || 'height';
11201150
let i = 0;
11211151
this.sizesCache = [];
11221152
this.heightCache = [];
11231153
this.sizesCache.push(0);
11241154
const count = this.isRemote ? this.totalItemCount : items.length;
11251155
for (i; i < count; i++) {
1126-
if (dimension === 'height') {
1127-
// cols[i][dimension] = parseInt(this.igxForItemSize, 10) || 0;
1128-
size = parseInt(this.igxForItemSize, 10) || 0;
1156+
size = this._getItemSize(items[i], dimension);
1157+
if (this.igxForScrollOrientation === 'vertical') {
11291158
this.heightCache.push(size);
1130-
} else {
1131-
size = this._getItemSize(items[i], dimension);
11321159
}
11331160
totalSize += size;
11341161
this.sizesCache.push(totalSize);
@@ -1359,6 +1386,11 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
13591386
this._virtScrollTop = realPercentScrolled * maxVirtScrollTop;
13601387
}
13611388

1389+
protected _getItemSize(item, dimension: string): number {
1390+
const dim = item ? item[dimension] : null;
1391+
return typeof dim === 'number' ? dim : parseInt(this.igxForItemSize, 10) || 0;
1392+
}
1393+
13621394
private _updateVScrollOffset() {
13631395
let scrollOffset = 0;
13641396
let currentScrollTop = this.scrollPosition;
@@ -1380,10 +1412,6 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
13801412
this.dc.instance._viewContainer.element.nativeElement.style.left = -scrollOffset + 'px';
13811413
}
13821414

1383-
private _getItemSize(item, dimension: string): number {
1384-
const dim = item[dimension];
1385-
return typeof dim === 'number' ? dim : parseInt(this.igxForItemSize, 10) || 0;
1386-
}
13871415

13881416
private _adjustScrollPositionAfterSizeChange(sizeDiff) {
13891417
// if data has been changed while container is scrolled
@@ -1439,10 +1467,14 @@ export class IgxGridForOfDirective<T> extends IgxForOfDirective<T> implements On
14391467
* @internal
14401468
*/
14411469
public get sizesCache(): number[] {
1442-
if (this.igxGridForOfUniqueSizeCache || this.syncService.isMaster(this)) {
1470+
if (this.igxForScrollOrientation === 'horizontal') {
1471+
if (this.igxGridForOfUniqueSizeCache || this.syncService.isMaster(this)) {
1472+
return this._sizesCache;
1473+
}
1474+
return this.syncService.sizesCache(this.igxForScrollOrientation);
1475+
} else {
14431476
return this._sizesCache;
14441477
}
1445-
return this.syncService.sizesCache(this.igxForScrollOrientation);
14461478
}
14471479
/**
14481480
* @hidden
@@ -1453,7 +1485,7 @@ export class IgxGridForOfDirective<T> extends IgxForOfDirective<T> implements On
14531485
}
14541486

14551487
protected get itemsDimension() {
1456-
return this.igxForScrollOrientation === 'horizontal' ? this.igxForSizePropName : 'height';
1488+
return this.igxForSizePropName || 'height';
14571489
}
14581490

14591491
/**
@@ -1581,10 +1613,9 @@ export class IgxGridForOfDirective<T> extends IgxForOfDirective<T> implements On
15811613

15821614
protected getItemSize(item) {
15831615
let size = 0;
1584-
const dimension = this.igxForScrollOrientation === 'horizontal' ?
1585-
this.igxForSizePropName : 'height';
1586-
if (dimension === 'height') {
1587-
size = parseInt(this.igxForItemSize, 10) || 0;
1616+
const dimension = this.igxForSizePropName || 'height';
1617+
if (this.igxForScrollOrientation === 'vertical') {
1618+
size = this._getItemSize(item, dimension);
15881619
if (item && item.summaries) {
15891620
size = item.max;
15901621
} else if (item && item.groups && item.height) {
@@ -1597,7 +1628,7 @@ export class IgxGridForOfDirective<T> extends IgxForOfDirective<T> implements On
15971628
}
15981629

15991630
protected initSizesCache(items: any[]): number {
1600-
if (!this.syncService.isMaster(this)) {
1631+
if (!this.syncService.isMaster(this) && this.igxForScrollOrientation === 'horizontal') {
16011632
const masterSizesCache = this.syncService.sizesCache(this.igxForScrollOrientation);
16021633
return masterSizesCache[masterSizesCache.length - 1];
16031634
}
@@ -1610,7 +1641,7 @@ export class IgxGridForOfDirective<T> extends IgxForOfDirective<T> implements On
16101641
const count = this.isRemote ? this.totalItemCount : items.length;
16111642
for (i; i < count; i++) {
16121643
size = this.getItemSize(items[i]);
1613-
if (this.itemsDimension === 'height') {
1644+
if (this.igxForScrollOrientation === 'vertical') {
16141645
this.heightCache.push(size);
16151646
}
16161647
totalSize += size;
@@ -1747,10 +1778,15 @@ export class IgxGridForOfDirective<T> extends IgxForOfDirective<T> implements On
17471778
* @hidden
17481779
*/
17491780
protected _calcMaxChunkSize(): number {
1750-
if (this.syncService.isMaster(this)) {
1781+
if (this.igxForScrollOrientation === 'horizontal') {
1782+
if (this.syncService.isMaster(this)) {
1783+
return super._calcMaxChunkSize();
1784+
}
1785+
return this.syncService.chunkSize(this.igxForScrollOrientation);
1786+
} else {
17511787
return super._calcMaxChunkSize();
17521788
}
1753-
return this.syncService.chunkSize(this.igxForScrollOrientation);
1789+
17541790
}
17551791
}
17561792

projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ export class IgxScrollInertiaDirective implements OnInit, OnDestroy {
138138
scrollDeltaY = this.calcAxisCoords(deltaScaledY, -1, 1);
139139
}
140140

141+
if (evt.composedPath && this.didChildScroll(evt, scrollDeltaX, scrollDeltaY)) {
142+
return;
143+
}
144+
141145
if (scrollDeltaX && this.IgxScrollInertiaDirection === 'horizontal') {
142146
const nextLeft = this._startX + scrollDeltaX * scrollStep;
143147
if (!smoothing) {
@@ -186,6 +190,36 @@ export class IgxScrollInertiaDirective implements OnInit, OnDestroy {
186190
}
187191
}
188192

193+
/**
194+
* @hidden
195+
* Checks if the wheel event would have scrolled an element under the display container
196+
* in DOM tree so that it can correctly be ignored until that element can no longer be scrolled.
197+
*/
198+
protected didChildScroll(evt, scrollDeltaX, scrollDeltaY): boolean {
199+
const path = evt.composedPath();
200+
let i = 0;
201+
while (i < path.length && path[i].localName !== 'igx-display-container') {
202+
const e = path[i++];
203+
if (e.scrollHeight > e.clientHeight) {
204+
if (scrollDeltaY > 0 && e.scrollHeight - Math.abs(Math.round(e.scrollTop)) !== e.clientHeight) {
205+
return true;
206+
}
207+
if (scrollDeltaY < 0 && e.scrollTop !== 0) {
208+
return true;
209+
}
210+
}
211+
if (e.scrollWidth > e.clientWidth) {
212+
if (scrollDeltaX > 0 && e.scrollWidth - Math.abs(Math.round(e.scrollLeft)) !== e.clientWidth) {
213+
return true;
214+
}
215+
if (scrollDeltaX < 0 && e.scrollLeft !== 0) {
216+
return true;
217+
}
218+
}
219+
}
220+
return false;
221+
}
222+
189223
/**
190224
* @hidden
191225
* Function that is called the first moment we start interacting with the content on a touch device

projects/igniteui-angular/src/lib/grids/columns/column.component.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy
17901790
*/
17911791
public getGridTemplate(isRow: boolean): string {
17921792
if (isRow) {
1793-
const rowsCount = this.grid.multiRowLayoutRowSize;
1793+
const rowsCount = !this.grid.isPivot ? this.grid.multiRowLayoutRowSize : this.children.length - 1;
17941794
return `repeat(${rowsCount},1fr)`;
17951795
} else {
17961796
return this.getColumnSizesString(this.children);
@@ -2312,23 +2312,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy
23122312
* Returns the width and padding of a header cell.
23132313
*/
23142314
public getHeaderCellWidths() {
2315-
const range = this.grid.document.createRange();
2316-
2317-
// We do not cover cases where there are children with width 100% and etc,
2318-
// because then we try to get new column size, based on header content, which is sized based on column size...
2319-
const headerWidth = this.platform.getNodeSizeViaRange(range,
2320-
this.headerCell.nativeElement,
2321-
this.headerGroup.nativeElement);
2322-
2323-
const headerStyle = this.grid.document.defaultView.getComputedStyle(this.headerCell.nativeElement);
2324-
const headerPadding = parseFloat(headerStyle.paddingLeft) + parseFloat(headerStyle.paddingRight) +
2325-
parseFloat(headerStyle.borderRightWidth);
2326-
2327-
// Take into consideration the header group element, since column pinning applies borders to it if its not a columnGroup.
2328-
const headerGroupStyle = this.grid.document.defaultView.getComputedStyle(this.headerGroup.nativeElement);
2329-
const borderSize = !this.parent ? parseFloat(headerGroupStyle.borderRightWidth) + parseFloat(headerGroupStyle.borderLeftWidth) : 0;
2330-
2331-
return { width: Math.ceil(headerWidth), padding: Math.ceil(headerPadding + borderSize) };
2315+
return this.grid.getHeaderCellWidth(this.headerCell.nativeElement);
23322316
}
23332317

23342318
/**

projects/igniteui-angular/src/lib/grids/common/grid.interface.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export interface RowType {
9797
parent?: RowType;
9898
hasChildren?: boolean;
9999
treeRow? : ITreeGridRecord;
100-
addRowUI?: any;
100+
addRowUI?: boolean;
101101
focused?: boolean;
102102
grid: GridType;
103103
onRowSelectorClick?: (event: MouseEvent) => void;
@@ -404,6 +404,7 @@ export interface GridType extends IGridDataBindable {
404404
hasColumnGroups: boolean;
405405
hasEditableColumns: boolean;
406406
uniqueColumnValuesStrategy: (column: ColumnType, tree: FilteringExpressionsTree, done: (values: any[]) => void) => void;
407+
getHeaderCellWidth: (element: HTMLElement) => ISizeInfo;
407408

408409
cdr: ChangeDetectorRef;
409410
document: Document;
@@ -644,3 +645,8 @@ export interface GridSVGIcon {
644645
name: string;
645646
value: string;
646647
}
648+
649+
export interface ISizeInfo {
650+
width: number,
651+
padding: number
652+
}

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import { FilteringLogic, IFilteringExpression } from '../data-operations/filteri
4343
import { IGroupByRecord } from '../data-operations/groupby-record.interface';
4444
import { IgxGridForOfDirective } from '../directives/for-of/for_of.directive';
4545
import { IgxTextHighlightDirective } from '../directives/text-highlight/text-highlight.directive';
46-
import { IgxSummaryOperand, ISummaryExpression } from './summaries/grid-summary';
46+
import { ISummaryExpression } from './summaries/grid-summary';
4747
import { RowEditPositionStrategy, IPinningConfig } from './grid.common';
4848
import { IgxGridToolbarComponent } from './toolbar/grid-toolbar.component';
4949
import { IgxRowDirective } from './row.directive';
@@ -123,7 +123,7 @@ import {
123123
IPinColumnCancellableEventArgs
124124
} from './common/events';
125125
import { IgxAdvancedFilteringDialogComponent } from './filtering/advanced-filtering/advanced-filtering-dialog.component';
126-
import { ColumnType, GridServiceType, GridType, IGX_GRID_SERVICE_BASE, RowType } from './common/grid.interface';
126+
import { ColumnType, GridServiceType, GridType, IGX_GRID_SERVICE_BASE, ISizeInfo, RowType } from './common/grid.interface';
127127
import { DropPosition } from './moving/moving.service';
128128
import { IgxHeadSelectorDirective, IgxRowSelectorDirective } from './selection/row-selectors';
129129
import { IgxColumnComponent } from './columns/column.component';
@@ -2960,7 +2960,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
29602960
@Inject(IGX_GRID_SERVICE_BASE) public gridAPI: GridServiceType,
29612961
protected transactionFactory: IgxFlatTransactionFactory,
29622962
private elementRef: ElementRef<HTMLElement>,
2963-
private zone: NgZone,
2963+
protected zone: NgZone,
29642964
@Inject(DOCUMENT) public document: any,
29652965
public cdr: ChangeDetectorRef,
29662966
protected resolver: ComponentFactoryResolver,
@@ -3883,6 +3883,26 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
38833883
return this.width === null || diff >= 0;
38843884
}
38853885

3886+
/**
3887+
* @hidden @internal
3888+
* Gets the header cell inner width for auto-sizing.
3889+
*/
3890+
public getHeaderCellWidth(element: HTMLElement): ISizeInfo {
3891+
const range = this.document.createRange();
3892+
const headerWidth = this.platform.getNodeSizeViaRange(range,
3893+
element,
3894+
element.parentElement);
3895+
3896+
const headerStyle = this.document.defaultView.getComputedStyle(element);
3897+
const headerPadding = parseFloat(headerStyle.paddingLeft) + parseFloat(headerStyle.paddingRight) +
3898+
parseFloat(headerStyle.borderRightWidth);
3899+
3900+
// Take into consideration the header group element, since column pinning applies borders to it if its not a columnGroup.
3901+
const headerGroupStyle = this.document.defaultView.getComputedStyle(element.parentElement);
3902+
const borderSize = parseFloat(headerGroupStyle.borderRightWidth) + parseFloat(headerGroupStyle.borderLeftWidth);
3903+
return { width: Math.ceil(headerWidth), padding: Math.ceil(headerPadding + borderSize) };
3904+
}
3905+
38863906
/**
38873907
* @hidden @internal
38883908
* Gets the combined width of the columns that are specific to the enabled grid features. They are fixed.
@@ -6738,7 +6758,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
67386758

67396759
// eslint-disable-next-line prefer-const
67406760
for (let [row, set] of selectionMap) {
6741-
row = this.paginator && source === this.filteredSortedData ? row + (this.paginator.perPage * this.paginator.page) : row;
6761+
row = this.paginator && (this.pagingMode === GridPagingMode.Local && source === this.filteredSortedData) ? row + (this.paginator.perPage * this.paginator.page) : row;
67426762
row = isRemote ? row - this.virtualizationState.startIndex : row;
67436763
if (!source[row] || source[row].detailsData !== undefined) {
67446764
continue;
@@ -6980,7 +7000,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
69807000
this.cdr.markForCheck();
69817001
}
69827002

6983-
private verticalScrollHandler(event) {
7003+
protected verticalScrollHandler(event) {
69847004
this.verticalScrollContainer.onScroll(event);
69857005
this.disableTransitions = true;
69867006

0 commit comments

Comments
 (0)