From aab95fdabae226c2f65d5052c54506656ae9cbd8 Mon Sep 17 00:00:00 2001 From: 3phase Date: Wed, 30 Oct 2019 17:29:34 +0200 Subject: [PATCH 01/21] fix(chip): Chips are being reordered now correctly #6097 --- projects/igniteui-angular/src/lib/chips/chips-area.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/chips/chips-area.component.ts b/projects/igniteui-angular/src/lib/chips/chips-area.component.ts index b15fc34bb91..ac889166c21 100644 --- a/projects/igniteui-angular/src/lib/chips/chips-area.component.ts +++ b/projects/igniteui-angular/src/lib/chips/chips-area.component.ts @@ -147,7 +147,7 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy * } * ``` */ - @ContentChildren(IgxChipComponent) + @ContentChildren(IgxChipComponent, { descendants: true }) public chipsList: QueryList; private modifiedChipsArray: IgxChipComponent[]; From f0c5efc93669973e5b6b03744172dfe951ca81b5 Mon Sep 17 00:00:00 2001 From: skrustev Date: Mon, 4 Nov 2019 11:22:30 +0200 Subject: [PATCH 02/21] fix(igxDatePicker): Fix opening dropdown/dialog throws error on Ivy. #6114 --- .../igniteui-angular/src/lib/calendar/calendar.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index d1d8781ed75..e76fc64c6ae 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -47,13 +47,13 @@

[@animateChange]="animationAction" (@animateChange.done)="animationDone($event)"> Date: Tue, 5 Nov 2019 16:18:28 +0200 Subject: [PATCH 03/21] chore(paginator): remove duplicate migration for 9 --- .../migrations/update-8_2_6/index.spec.ts | 6 ++-- .../migrations/update-8_2_6/index.ts | 15 +++++++- .../update-9_0_0/changes/theme-props.json | 35 ------------------- 3 files changed, 18 insertions(+), 38 deletions(-) delete mode 100644 projects/igniteui-angular/migrations/update-9_0_0/changes/theme-props.json diff --git a/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts b/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts index 715d533783d..9ed90d1aa18 100644 --- a/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts +++ b/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts @@ -67,7 +67,8 @@ describe('Update 8.2.6', () => { it('should update igx-grid-paginator-theme', done => { appTree.create( '/testSrc/appPrefix/component/test.component.scss', - `$dark-grid-paginator: igx-grid-paginator-theme($color: black); + `@import '~igniteui-angular/lib/core/styles/components/grid-paginator/grid-paginator-component'; + @import '~igniteui-angular/lib/core/styles/components/grid-paginator/grid-paginator-theme'; @include igx-grid-paginator($dark-grid-paginator); .igx-grid-paginator__pager { @include igx-button($dark-button); @@ -77,7 +78,8 @@ describe('Update 8.2.6', () => { const tree = schematicRunner.runSchematic('migration-12', {}, appTree); expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')) .toEqual( - `$dark-grid-paginator: igx-paginator-theme($color: black); + `@import '~igniteui-angular/lib/core/styles/components/paginator/paginator-component'; + @import '~igniteui-angular/lib/core/styles/components/paginator/paginator-theme'; @include igx-paginator($dark-grid-paginator); .igx-grid-paginator__pager { @include igx-button($dark-button); diff --git a/projects/igniteui-angular/migrations/update-8_2_6/index.ts b/projects/igniteui-angular/migrations/update-8_2_6/index.ts index 918b80e432d..e125b5c4c70 100644 --- a/projects/igniteui-angular/migrations/update-8_2_6/index.ts +++ b/projects/igniteui-angular/migrations/update-8_2_6/index.ts @@ -29,11 +29,17 @@ export default function(): Rule { '$_square-shape-pagination']; let globalStyleExt: string; + const gridPaginatorComponentImport = '~igniteui-angular/lib/core/styles/components/grid-paginator/grid-paginator-component'; + const gridPaginatorThemeImport = '~igniteui-angular/lib/core/styles/components/grid-paginator/grid-paginator-theme'; + const paginatorComponentImport = '~igniteui-angular/lib/core/styles/components/paginator/paginator-component'; + const paginatorThemeImport = '~igniteui-angular/lib/core/styles/components/paginator/paginator-theme'; const config = getWorkspace(host); const projects = getProjects(config); context.logger.info(`Applying migration for Ignite UI for Angular to version ${version}`); + const update = new UpdateChanges(__dirname, host, context); + if (config.schematics && config.schematics['@schematics/angular:component']) { // updated projects have global prefix rather than per-project: globalStyleExt = config.schematics['@schematics/angular:component'].styleext; @@ -56,12 +62,19 @@ export default function(): Rule { content = content.split(n).join(newThemes[i]); } }); + if (content.indexOf(gridPaginatorComponentImport) !== -1) { + content = content.replace(gridPaginatorComponentImport, paginatorComponentImport); + host.overwrite(path, content); + } + if (content.indexOf(gridPaginatorThemeImport) !== -1) { + content = content.replace(gridPaginatorThemeImport, paginatorThemeImport); + host.overwrite(path, content); + } host.overwrite(path, content); } }); } - const update = new UpdateChanges(__dirname, host, context); update.applyChanges(); }; } diff --git a/projects/igniteui-angular/migrations/update-9_0_0/changes/theme-props.json b/projects/igniteui-angular/migrations/update-9_0_0/changes/theme-props.json deleted file mode 100644 index ad0ae3cfe31..00000000000 --- a/projects/igniteui-angular/migrations/update-9_0_0/changes/theme-props.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "../../common/schema/theme-props.schema.json", - "changes": [ - { - "name": "$button-background", - "remove": true, - "owner": "igx-grid-toolbar-theme" - }, - { - "name": "$button-text-color", - "remove": true, - "owner": "igx-grid-toolbar-theme" - }, - { - "name": "$button-hover-background", - "remove": true, - "owner": "igx-grid-toolbar-theme" - }, - { - "name": "$button-hover-text-color", - "remove": true, - "owner": "igx-grid-toolbar-theme" - }, - { - "name": "$button-focus-background", - "remove": true, - "owner": "igx-grid-toolbar-theme" - }, - { - "name": "$button-focus-text-color", - "remove": true, - "owner": "igx-grid-toolbar-theme" - } - ] -} From 78ed5b42d30bd2c712f821e6663be24f2e6d764e Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 5 Nov 2019 16:25:34 +0200 Subject: [PATCH 04/21] chore(paginator): enhance migration test --- projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts b/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts index 9ed90d1aa18..dee101fa865 100644 --- a/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts +++ b/projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts @@ -69,6 +69,7 @@ describe('Update 8.2.6', () => { '/testSrc/appPrefix/component/test.component.scss', `@import '~igniteui-angular/lib/core/styles/components/grid-paginator/grid-paginator-component'; @import '~igniteui-angular/lib/core/styles/components/grid-paginator/grid-paginator-theme'; + $dark-grid-paginator: igx-grid-paginator-theme($color: black); @include igx-grid-paginator($dark-grid-paginator); .igx-grid-paginator__pager { @include igx-button($dark-button); @@ -80,6 +81,7 @@ describe('Update 8.2.6', () => { .toEqual( `@import '~igniteui-angular/lib/core/styles/components/paginator/paginator-component'; @import '~igniteui-angular/lib/core/styles/components/paginator/paginator-theme'; + $dark-grid-paginator: igx-paginator-theme($color: black); @include igx-paginator($dark-grid-paginator); .igx-grid-paginator__pager { @include igx-button($dark-button); From 7a45a4799fad087ab39380728c0f7f5989714a8b Mon Sep 17 00:00:00 2001 From: ViktorSlavov Date: Wed, 6 Nov 2019 18:46:11 +0200 Subject: [PATCH 05/21] fix(progress-bar): revert change to progress-bar styles, #6129 --- .../styles/components/progress/_progress-component.scss | 8 ++++---- .../core/styles/components/progress/_progress-theme.scss | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss index cbddc10ef73..876486a5c40 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss @@ -113,15 +113,15 @@ @extend %circular-text !optional; } - @include e(text, $m: hidden) { - @extend %circular-text !optional; - } - @include m(indeterminate) { @extend %circular-display--indeterminate !optional; @include e(outer) { @extend %circular-outer--indeterminate !optional; } + + @include e(text) { + @extend %circular-text--hidden !optional; + } } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss index 2a6e793d516..284d0373462 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss @@ -311,6 +311,10 @@ fill: --var($theme, 'text-color'); } + %circular-text--hidden { + visibility: hidden; + } + @include keyframes('indeterminate-accordion') { from { stroke-dashoffset: 578; From 44e8a8628d8917477233f249c337737c953e0f5a Mon Sep 17 00:00:00 2001 From: ViktorSlavov Date: Thu, 7 Nov 2019 09:53:50 +0200 Subject: [PATCH 06/21] test(progress-bar): check for text visibility in indeterminate bar, #6129 --- .../src/lib/progressbar/circularbar.component.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts index 486ea9a8d06..3a689ffa7ac 100644 --- a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts @@ -450,6 +450,9 @@ describe('IgCircularBar', () => { fix.detectChanges(); expect(bar.classList.contains(CIRCULAR_INDETERMINATE_CLASS)).toEqual(true); + + // Expect text in indeterminate bar to be hidden; + expect(getComputedStyle(bar.querySelector('text').firstElementChild).visibility).toEqual('hidden'); }); }); }); From ebc46c60aedda94907f2fc3439753cc354d90b6b Mon Sep 17 00:00:00 2001 From: MKirova Date: Thu, 7 Nov 2019 15:05:37 +0200 Subject: [PATCH 07/21] fix(igxGrid): Workaround for ivy issue where ContentChildren are re-evaluated after rendering an inner template, resulting in the resetting the columns collection in their original order. Workaround is to apply sorting for the internal unpinned cols collection after re-evaliuation, similarly to what's done to the pinned collection, in order to ensure the order is always correct. --- .../src/lib/grids/grid-base.directive.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 2a3137229d0..47e5f9cf98b 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -3578,9 +3578,8 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements /** * @hidden */ - protected _reorderPinnedColumns(from: IgxColumnComponent, to: IgxColumnComponent, position: DropPosition) { - const pinned = this._pinnedColumns; - let dropIndex = pinned.indexOf(to); + protected _reorderColumns(from: IgxColumnComponent, to: IgxColumnComponent, position: DropPosition, columnCollection: any[]) { + let dropIndex = columnCollection.indexOf(to); if (to.columnGroup) { dropIndex += to.allChildren.length; @@ -3594,9 +3593,8 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements dropIndex++; } - pinned.splice(dropIndex, 0, ...pinned.splice(pinned.indexOf(from), 1)); + columnCollection.splice(dropIndex, 0, ...columnCollection.splice(columnCollection.indexOf(from), 1)); } - /** * @hidden */ @@ -3649,12 +3647,13 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements } if (dropTarget.pinned && column.pinned) { - this._reorderPinnedColumns(column, dropTarget, position); + this._reorderColumns(column, dropTarget, position, this._pinnedColumns); } if (dropTarget.pinned && !column.pinned) { column.pin(); - this._reorderPinnedColumns(column, dropTarget, position); + this._reorderColumns(column, dropTarget, position, this._pinnedColumns); + } if (!dropTarget.pinned && column.pinned) { @@ -3673,6 +3672,10 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements } } + if (!dropTarget.pinned) { + this._reorderColumns(column, dropTarget, position, this._unpinnedColumns); + } + this._moveColumns(column, dropTarget, position); this.notifyChanges(); if (this.hasColumnLayouts) { @@ -4857,7 +4860,9 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements protected reinitPinStates() { this._pinnedColumns = (this.hasColumnGroups) ? this.columnList.filter((c) => c.pinned) : this.columnList.filter((c) => c.pinned).sort((a, b) => this._pinnedColumns.indexOf(a) - this._pinnedColumns.indexOf(b)); - this._unpinnedColumns = this.columnList.filter((c) => !c.pinned); + this._unpinnedColumns = this.hasColumnGroups ? this.columnList.filter((c) => !c.pinned) : + this.columnList.filter((c) => !c.pinned) + .sort((a, b) => this._unpinnedColumns.indexOf(a) - this._unpinnedColumns.indexOf(b)); } /** From 67f990c23154a17b0248fdd92cc752fadfc1a141 Mon Sep 17 00:00:00 2001 From: Diyan Dimitrov Date: Fri, 8 Nov 2019 10:48:35 +0200 Subject: [PATCH 08/21] fix(esf): register filtering svg icons #6149 --- .../excel-style/grid.excel-style-filtering.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/grid.excel-style-filtering.component.ts b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/grid.excel-style-filtering.component.ts index 97ca71797ca..f5261b1e50a 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/grid.excel-style-filtering.component.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/grid.excel-style-filtering.component.ts @@ -137,6 +137,7 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy, AfterView } if (this._column) { + this._column.grid.filteringService.registerSVGIcons(); this.isColumnPinnable = this.column.pinnable; this.init(); From bd3f27e589df470388bfad9350d616ea118446e3 Mon Sep 17 00:00:00 2001 From: Alexander M Date: Fri, 8 Nov 2019 19:28:43 +0200 Subject: [PATCH 09/21] feat(row-drag): Adding igxDragCustomGhost directive --- CHANGELOG.md | 14 ++ .../drag-drop/drag-drop.directive.ts | 4 +- .../src/lib/grids/grid-base.directive.ts | 20 ++ .../lib/grids/grid/grid-row.component.html | 2 +- .../lib/grids/grid/row-drag.directive.spec.ts | 188 +++++++++++++++++- .../hierarchical-grid.component.ts | 11 + .../hierarchical-row.component.html | 2 +- .../src/lib/grids/row-drag.directive.ts | 22 +- .../tree-grid/tree-grid-row.component.html | 2 +- .../grid-row-draggable.sample.html | 6 + .../hierarchical-grid.sample.html | 16 +- 11 files changed, 274 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfd9fbc0edd..df1eb72a3c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,20 @@ All notable changes for each version of this project will be documented in this - `setOffset` method added. It offsets the content along the corresponding axis by the provided amount. - `IgxToggleDirective`: - `setOffset` method added. It offsets the content along the corresponding axis by the provided amount. +- `IgxRowDragGhost` directive is added. It allows providing a custom template for the drag ghost when dragging a row. +```html + + + + + +
+ Moving {{data.ProductName}}! +
+
+
+``` ## 8.2.6 diff --git a/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts b/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts index a670da82696..e3c09745993 100644 --- a/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts @@ -151,6 +151,8 @@ export class IgxDragLocation { }) export class IgxDragDirective implements AfterContentInit, OnDestroy { + protected ghostContext: any = null; + /** * - Save data inside the `igxDrag` directive. This can be set when instancing `igxDrag` on an element. * ```html @@ -1099,7 +1101,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { let dynamicGhostRef; if (this.ghostTemplate) { - dynamicGhostRef = this.viewContainer.createEmbeddedView(this.ghostTemplate); + dynamicGhostRef = this.viewContainer.createEmbeddedView(this.ghostTemplate, this.ghostContext); this.ghostElement = dynamicGhostRef.rootNodes[0]; } else { this.ghostElement = node ? node.cloneNode(true) : this.element.nativeElement.cloneNode(true); diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 319e57bbf18..02bdaf18c55 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -132,6 +132,7 @@ import { IgxGridToolbarCustomContentDirective } from './toolbar/toolbar.directiv import { IgxColumnComponent } from './columns/column.component'; import { IgxColumnGroupComponent } from './columns/column-group.component'; import { IGridSortingStrategy } from '../data-operations/sorting-strategy'; +import { IgxRowDragGhostDirective } from './row-drag.directive'; const MINIMUM_COLUMN_WIDTH = 136; const FILTER_ROW_HEIGHT = 50; @@ -1912,6 +1913,13 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements @ContentChildren(IgxRowSelectorDirective, { read: IgxRowSelectorDirective, descendants: false }) public rowSelectorsTemplates: QueryList; + /** + * @hidden + * @internal + */ + @ContentChildren(IgxRowDragGhostDirective, { read: TemplateRef, descendants: false }) + public dragGhostCustomTemplates: QueryList>; + /** * @hidden */ @@ -3167,6 +3175,18 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements } } + /** + * @hidden + * @internal + */ + public getDragGhostCustomTemplate() { + if (this.dragGhostCustomTemplates && this.dragGhostCustomTemplates.first) { + return this.dragGhostCustomTemplates.first; + } + + return null; + } + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html index 494ebef35bd..cc8eb26ae88 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html @@ -2,7 +2,7 @@
-
+
diff --git a/projects/igniteui-angular/src/lib/grids/grid/row-drag.directive.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/row-drag.directive.spec.ts index c0e1d30ca32..6fca446ac52 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/row-drag.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/row-drag.directive.spec.ts @@ -44,8 +44,10 @@ describe('IgxGrid - Row Drag Tests #grid', () => { TestBed.configureTestingModule({ declarations: [ IgxGridRowDraggableComponent, + IgxGridRowCustomGhostDraggableComponent, IgxGridFeaturesRowDragComponent, IgxHierarchicalGridTestComponent, + IgxHierarchicalGridCustomGhostTestComponent, IgxTreeGridTestComponent ], imports: [ @@ -384,6 +386,33 @@ describe('IgxGrid - Row Drag Tests #grid', () => { const ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW); expect(ghostElements.length).toEqual(0); })); + + it('should correctly create custom ghost element', (async () => { + fixture = TestBed.createComponent(IgxGridRowCustomGhostDraggableComponent); + grid = fixture.componentInstance.instance; + fixture.detectChanges(); + dragIndicatorElements = fixture.debugElement.queryAll(By.css('.' + CSS_CLASS_DRAG_INDICATOR)); + dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective)); + const rowDragDirective = dragRows[1].injector.get(IgxRowDragDirective) as any; + const dragIndicatorElement = dragIndicatorElements[2].nativeElement; + const startPoint: Point = UIInteractions.getPointFromElement(dragIndicatorElement); + const movePoint: Point = UIInteractions.getPointFromElement(rows[4].nativeElement); + const dropPoint: Point = UIInteractions.getPointFromElement(dropAreaElement); + let ghostElements: HTMLCollection; + + await pointerDown(dragIndicatorElement, startPoint, fixture); + await pointerMove(dragIndicatorElement, movePoint, fixture); + await pointerMove(dragIndicatorElement, dropPoint, fixture); + ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW); + expect(ghostElements.length).toEqual(1); + + expect(rowDragDirective.ghostContext.data.ProductName).toEqual('NetAdvantage'); + expect(rowDragDirective.ghostContext.data.ID).toEqual(2); + expect(rowDragDirective.ghostContext.grid).toEqual(grid); + + const ghostText = document.getElementsByClassName(CSS_CLASS_GHOST_ROW)[0].textContent; + expect(ghostText).toEqual(' Moving a row! '); + })); }); describe('Grid Features Integration Tests', () => { let dragGrid: IgxGridComponent; @@ -635,8 +664,8 @@ describe('IgxGrid - Row Drag Tests #grid', () => { expect(row.grid.rowDragging).toBeTruthy(); const ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW); - const ghostElement = ghostElements[0]; - expect(ghostElements.length).toEqual(1); + const ghostElement = ghostElements[1]; + expect(ghostElements.length).toEqual(2); expect(ghostElement.classList.contains(CSS_CLASS_SELECTED_ROW)).toBeFalsy(); await pointerMove(dragIndicatorElement, dropPoint, fixture); @@ -787,7 +816,7 @@ describe('IgxGrid - Row Drag Tests #grid', () => { dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective)); })); - it('should be able to drag row on every hiearchical level', (async () => { + it('should be able to drag row on every hierarchical level', (async () => { // first level row let dragIndicatorElement: Element = dragIndicatorElements[1].nativeElement; let rowToDrag = dragGrid.getRowByIndex(0); @@ -841,6 +870,47 @@ describe('IgxGrid - Row Drag Tests #grid', () => { await pointerUp(dragIndicatorElement, dropPoint, fixture); verifyRowDragEndEvent(nestedChildGrid, rowToDrag, rowDragDirective, false, 1); })); + + it('should correctly create custom ghost element', (async () => { + fixture = TestBed.createComponent(IgxHierarchicalGridCustomGhostTestComponent ); + dragGrid = fixture.componentInstance.hDragGrid; + fixture.detectChanges(); + dragIndicatorElements = fixture.debugElement.queryAll(By.css('.' + CSS_CLASS_DRAG_INDICATOR)); + dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective)); + + // first level row + let dragIndicatorElement: Element = dragIndicatorElements[1].nativeElement; + let rowToDrag = dragGrid.getRowByIndex(0); + let rowDragDirective = dragRows[0].injector.get(IgxRowDragDirective) as any; + + let startPoint: Point = UIInteractions.getPointFromElement(dragIndicatorElement); + const movePoint: Point = UIInteractions.getPointFromElement(dragGrid.getRowByIndex(3).nativeElement); + const dropPoint: Point = UIInteractions.getPointFromElement(dropAreaElement); + + await pointerDown(dragIndicatorElement, startPoint, fixture); + await pointerMove(dragIndicatorElement, movePoint, fixture); + await pointerMove(dragIndicatorElement, dropPoint, fixture); + await pointerUp(dragIndicatorElement, dropPoint, fixture); + + expect(rowDragDirective.ghostContext.data.ProductName).toEqual('Product: A0'); + expect(rowDragDirective.ghostContext.grid).toEqual(dragGrid); + + // second level row + dragIndicatorElement = dragIndicatorElements[8].nativeElement; + const childGrid = dragGrid.hgridAPI.getChildGrids(false)[0]; + rowToDrag = childGrid.getRowByIndex(0); + rowDragDirective = dragRows[4].injector.get(IgxRowDragDirective); + startPoint = UIInteractions.getPointFromElement(dragIndicatorElement); + + await pointerDown(dragIndicatorElement, startPoint, fixture); + await pointerMove(dragIndicatorElement, movePoint, fixture); + await pointerMove(dragIndicatorElement, dropPoint, fixture); + await pointerUp(dragIndicatorElement, dropPoint, fixture); + + expect(rowDragDirective.ghostContext.data.ProductName).toEqual('Product: A0'); + expect(rowDragDirective.ghostContext.data.ChildLevels).toEqual(2); + expect(rowDragDirective.ghostContext.grid).toEqual(childGrid); + })); }); describe('Tree Grid Tests', () => { let dragGrid: IgxTreeGridComponent; @@ -857,7 +927,7 @@ describe('IgxGrid - Row Drag Tests #grid', () => { dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective)); })); - it('should be able to drag row on every hiearchical level', (async () => { + it('should be able to drag row on every hierarchical level', (async () => { // first level row let dragIndicatorElement: Element = dragIndicatorElements[1].nativeElement; let rowToDrag = dragGrid.getRowByIndex(0); @@ -960,6 +1030,65 @@ export class IgxGridRowDraggableComponent extends DataParent { } } +@Component({ + template: ` + + +
+ + Moving a row! +
+
+
+
+
+
+
+ ` +}) +export class IgxGridRowCustomGhostDraggableComponent extends DataParent { + public width = '800px'; + public height = null; + + @ViewChild(IgxGridComponent, { read: IgxGridComponent, static: true }) + public instance: IgxGridComponent; + + @ViewChild('dropArea', { read: IgxDropDirective, static: true }) + public dropArea: IgxDropDirective; + + public enableSorting = false; + public enableFiltering = false; + public enableResizing = false; + public enableEditing = true; + public enableGrouping = true; + public enableRowEditing = true; + public enableRowDraggable = true; + public currentSortExpressions; + + public columnsCreated(column: IgxColumnComponent) { + column.sortable = this.enableSorting; + column.filterable = this.enableFiltering; + column.resizable = this.enableResizing; + column.editable = this.enableEditing; + column.groupable = this.enableGrouping; + } + public onGroupingDoneHandler(sortExpr) { + this.currentSortExpressions = sortExpr; + } + public onRowDrop(args) { + args.cancel = true; + } +} + @Component({ template: ` + + + + +
+ Moving {{data.ProductName}}! +
+
+
+ +
+ Moving {{data.ProductName}}! +
+
+ ` +}) +export class IgxHierarchicalGridCustomGhostTestComponent { + public data; + newData = []; + @ViewChild('hierarchicalDragGrid', { read: IgxHierarchicalGridComponent, static: true }) public hDragGrid: IgxHierarchicalGridComponent; + @ViewChild('rowIsland', { read: IgxRowIslandComponent, static: true }) public rowIsland: IgxRowIslandComponent; + @ViewChild('rowIsland2', { read: IgxRowIslandComponent, static: true }) public rowIsland2: IgxRowIslandComponent; + + constructor() { + this.data = this.generateData(2, 3); + } + generateData(count: number, level: number) { + const prods = []; + const currLevel = level; + let children; + for (let i = 0; i < count; i++) { + const item = { + ID: i, ChildLevels: currLevel, ProductName: 'Product: A' + i, 'Col1': i, + 'Col2': i, 'Col3': i + }; + if (currLevel > 1) { + children = this.generateData(count / 2, currLevel - 1); + const childProp = currLevel === 3 ? 'childData' : 'childData2'; + item[childProp] = children; + } + prods.push(item); + } + return prods; + } +} + @Component({ template: ` diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index 574634f4c3c..f2af5868c63 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -663,6 +663,17 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti } } + /** + * @hidden + * @internal + */ + public getDragGhostCustomTemplate(): TemplateRef { + if (this.parentIsland) { + return this.parentIsland.getDragGhostCustomTemplate(); + } + return super.getDragGhostCustomTemplate(); + } + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html index fd59f9f1cab..04a325b093e 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html @@ -15,7 +15,7 @@ -
+
diff --git a/projects/igniteui-angular/src/lib/grids/row-drag.directive.ts b/projects/igniteui-angular/src/lib/grids/row-drag.directive.ts index be2cbe97dc7..fe874e1cd22 100644 --- a/projects/igniteui-angular/src/lib/grids/row-drag.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/row-drag.directive.ts @@ -1,4 +1,4 @@ -import { Directive, Input, OnDestroy, NgModule } from '@angular/core'; +import { Directive, Input, OnDestroy, NgModule, TemplateRef } from '@angular/core'; import { IgxDragDirective } from '../directives/drag-drop/drag-drop.directive'; import { KEYS } from '../core/utils'; import { fromEvent, Subscription } from 'rxjs'; @@ -100,6 +100,11 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy { protected createGhost(pageX, pageY) { this.row.grid.endEdit(true); this.row.grid.markForCheck(); + this.ghostContext = { + $implicit: this.row.rowData, + data: this.row.rowData, + grid: this.row.grid + }; super.createGhost(pageX, pageY, this.row.nativeElement); const ghost = this.ghostElement; @@ -152,10 +157,21 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy { export class IgxDragIndicatorIconDirective { } +/** + * @hidden + */ +@Directive({ + selector: '[igxRowDragGhost]' +}) + +export class IgxRowDragGhostDirective { + constructor(public templateRef: TemplateRef) { } +} + @NgModule({ - declarations: [IgxRowDragDirective, IgxDragIndicatorIconDirective], + declarations: [IgxRowDragDirective, IgxDragIndicatorIconDirective, IgxRowDragGhostDirective], entryComponents: [], - exports: [IgxRowDragDirective, IgxDragIndicatorIconDirective], + exports: [IgxRowDragDirective, IgxDragIndicatorIconDirective, IgxRowDragGhostDirective], imports: [] }) diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html index 974cc0ed9a1..c5cd511c581 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html @@ -1,5 +1,5 @@ -
+
diff --git a/src/app/grid-row-draggable/grid-row-draggable.sample.html b/src/app/grid-row-draggable/grid-row-draggable.sample.html index 7a52f032a70..18e8d71aba5 100644 --- a/src/app/grid-row-draggable/grid-row-draggable.sample.html +++ b/src/app/grid-row-draggable/grid-row-draggable.sample.html @@ -13,6 +13,12 @@ info + +
+ + Moving {{data.ProductName}}! +
+
Sample One

- @@ -23,12 +23,18 @@

Sample One

add - + + +
+ + Moving child {{data.ProductName}}! +
+
@@ -53,6 +59,12 @@

Sample One

--> + +
+ + Moving parent {{data.ProductName}}! +
+

Sample two

From 2550456203e884aa9f60e0656298e3a81a1006f2 Mon Sep 17 00:00:00 2001 From: 3phase Date: Fri, 8 Nov 2019 21:35:43 +0200 Subject: [PATCH 10/21] fix(igxGrid): Fixes bug after workaround of #6140 --- .../igniteui-angular/src/lib/grids/grid-base.directive.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 6760698f819..080ced421b3 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -3724,8 +3724,14 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements if (!dropTarget.pinned && column.pinned) { column.unpin(); + let list = []; + + if (this.pinnedColumns.indexOf(column) === -1 && this.pinnedColumns.indexOf(dropTarget) === -1) { + list = this._unpinnedColumns; + } else { + list = this._pinnedColumns; + } - const list = this.columnList.toArray(); const fi = list.indexOf(column); const ti = list.indexOf(dropTarget); From 68ddfcb18dd9cd0adde1a155a8134c6f0103d16c Mon Sep 17 00:00:00 2001 From: Vasil Mihalkov Date: Mon, 11 Nov 2019 10:47:14 +0200 Subject: [PATCH 11/21] fix(column): Added prop decorator for column #6004 --- .../src/lib/grids/columns/column.component.ts | 33 ++++++++++++++++++- .../src/lib/grids/grid/grid.component.ts | 4 ++- .../row-island-api.service.ts | 1 + .../hierarchical-grid/row-island.component.ts | 1 + .../grids/tree-grid/tree-grid.component.ts | 4 ++- .../src/lib/grids/watch-changes.ts | 24 ++++++++++++++ 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts index 79466ff4df9..2d781b0e966 100644 --- a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts +++ b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts @@ -12,6 +12,8 @@ import { EventEmitter, } from '@angular/core'; import { notifyChanges } from '../watch-changes'; +import { WatchColumnChanges } from '../watch-changes'; +import { IgxRowIslandAPIService } from '../hierarchical-grid/row-island-api.service'; import { DataType } from '../../data-operations/data-util'; import { DeprecateProperty } from '../../core/deprecateDecorators'; import { @@ -81,6 +83,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() public header = ''; /** @@ -94,6 +97,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @Input() public sortable = false; /** @@ -108,6 +112,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges(true) + @WatchColumnChanges() @Input() groupable = false; /** @@ -118,6 +123,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @Input() get editable(): boolean { // Updating the primary key when grid has transactions (incl. row edit) @@ -160,6 +166,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() public filterable = true; /** @@ -173,6 +180,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @Input() public resizable = false; /** @@ -183,6 +191,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges(true) + @WatchColumnChanges() @Input() get hasSummary() { return this._hasSummary; @@ -210,6 +219,7 @@ export class IgxColumnComponent implements AfterContentInit { *@memberof IgxColumnComponent */ @notifyChanges(true) + @WatchColumnChanges() @Input() get hidden(): boolean { return this._hidden; @@ -257,6 +267,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() disableHiding = false; /** @@ -267,6 +278,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() disablePinning = false; /** @@ -280,6 +292,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @notifyChanges() @Input() public movable = false; @@ -291,6 +304,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges(true) + @WatchColumnChanges() @Input() public get width(): string { return this.widthSetByUser ? this._width : this.defaultWidth; @@ -351,6 +365,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @Input() public maxWidth: string; /** @@ -365,6 +380,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() public set minWidth(value: string) { const minVal = parseFloat(value); @@ -386,6 +402,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() public headerClasses = ''; @@ -400,6 +417,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() public headerGroupClasses = ''; /** @@ -419,6 +437,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() public cellClasses: any; @@ -440,6 +459,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() cellStyles = null; /** @@ -473,6 +493,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() formatter: (value: any) => any; /** @@ -486,6 +507,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @Input() public filteringIgnoreCase = true; /** @@ -499,6 +521,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @Input() public sortingIgnoreCase = true; /** @@ -521,6 +544,7 @@ export class IgxColumnComponent implements AfterContentInit { * ``` * @memberof IgxColumnComponent */ + @WatchColumnChanges() @Input() public get pinned(): boolean { return this._pinned; @@ -579,6 +603,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges(true) + @WatchColumnChanges() @Input() public get summaries(): any { return this._summaries; @@ -611,6 +636,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() public searchable = true; /** @@ -714,6 +740,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input('cellTemplate') get bodyTemplate(): TemplateRef { return this._bodyTemplate; @@ -745,6 +772,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input() get headerTemplate(): TemplateRef { return this._headerTemplate; @@ -777,6 +805,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input('cellEditorTemplate') get inlineEditorTemplate(): TemplateRef { return this._inlineEditorTemplate; @@ -806,6 +835,7 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ @notifyChanges() + @WatchColumnChanges() @Input('filterCellTemplate') get filterCellTemplate(): TemplateRef { return this._filterCellTemplate; @@ -1135,7 +1165,8 @@ export class IgxColumnComponent implements AfterContentInit { @ContentChild(IgxFilterCellTemplateDirective, { read: IgxFilterCellTemplateDirective, static: false }) public filterCellTemplateDirective: IgxFilterCellTemplateDirective; - constructor(public gridAPI: GridBaseAPIService, public cdr: ChangeDetectorRef) { } + constructor(public gridAPI: GridBaseAPIService, public cdr: ChangeDetectorRef, + public rowIslandAPI: IgxRowIslandAPIService) { } /** * @hidden diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts index cfefa0215fb..d9864bc5b1a 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts @@ -24,6 +24,7 @@ import { IgxGridSelectionService, IgxGridCRUDService } from '../selection/select import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service'; import { IgxDragIndicatorIconDirective } from '../row-drag.directive'; import { IgxGridMRLNavigationService } from '../grid-mrl-navigation.service'; +import { IgxRowIslandAPIService } from '../hierarchical-grid/row-island-api.service'; import { FilterMode } from '../common/enums'; import { GridType } from '../common/grid.interface'; @@ -64,7 +65,8 @@ export interface IGroupingDoneEventArgs extends IBaseEventArgs { IgxFilteringService, IgxColumnResizingService, IgxForOfSyncService, - IgxForOfScrollSyncService + IgxForOfScrollSyncService, + IgxRowIslandAPIService ], selector: 'igx-grid', templateUrl: './grid.component.html' diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island-api.service.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island-api.service.ts index e89931a30c8..1c9a24dfb9a 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island-api.service.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island-api.service.ts @@ -3,6 +3,7 @@ import { IgxRowIslandComponent } from './row-island.component'; import { Subject } from 'rxjs'; export class IgxRowIslandAPIService { + public rowIsland: IgxRowIslandComponent; public change: Subject = new Subject(); protected state: Map = new Map(); protected destroyMap: Map> = new Map>(); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts index 378b94cc54a..1c5dd04e1a3 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts @@ -235,6 +235,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective */ ngOnInit() { this.rootGrid = this.hgridAPI.grid; + this.rowIslandAPI.rowIsland = this; } /** diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts index e002ccb4974..36e64053d0a 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts @@ -33,6 +33,7 @@ import { IgxDragIndicatorIconDirective } from '../row-drag.directive'; import { IgxGridNavigationService } from '../grid-navigation.service'; import { GridType } from '../common/grid.interface'; import { IgxColumnComponent } from '../columns/column.component'; +import { IgxRowIslandAPIService } from '../hierarchical-grid/row-island-api.service'; let NEXT_ID = 0; @@ -66,7 +67,8 @@ let NEXT_ID = 0; { provide: IgxGridBaseDirective, useExisting: forwardRef(() => IgxTreeGridComponent) }, IgxFilteringService, IgxForOfSyncService, - IgxForOfScrollSyncService + IgxForOfScrollSyncService, + IgxRowIslandAPIService ] }) export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridType, OnInit, DoCheck, AfterContentInit { diff --git a/projects/igniteui-angular/src/lib/grids/watch-changes.ts b/projects/igniteui-angular/src/lib/grids/watch-changes.ts index d8022c0cf0d..a2d10a4d24c 100644 --- a/projects/igniteui-angular/src/lib/grids/watch-changes.ts +++ b/projects/igniteui-angular/src/lib/grids/watch-changes.ts @@ -31,6 +31,30 @@ export function WatchChanges(): PropertyDecorator { }; } +export function WatchColumnChanges(): PropertyDecorator { + return (target: any, key: string, propDesc?: PropertyDescriptor) => { + const privateKey = '_' + key.toString(); + propDesc = propDesc || { + configurable: true, + enumerable: true, + }; + propDesc.get = propDesc.get || (function (this: any) { return this[privateKey]; }); + const originalSetter = propDesc.set || (function (this: any, val: any) { this[privateKey] = val; }); + + propDesc.set = function (this: any, val: any) { + const init = this._init; + const oldValue = this[key]; + originalSetter.call(this, val); + if (val !== oldValue || (typeof val === 'object' && val === oldValue)) { + if (this.rowIslandAPI.rowIsland) { + this.rowIslandAPI.rowIsland.updateColumnList(); + } + } + }; + return propDesc; + }; +} + export function notifyChanges(repaint = false) { return (_: any, key: string, propDesc?: PropertyDescriptor) => { From b285a86cec1a065a3206fbf6c1cd1b1b8668f2e5 Mon Sep 17 00:00:00 2001 From: Martin Dragnev Date: Mon, 11 Nov 2019 11:47:21 +0200 Subject: [PATCH 12/21] fix(forOf): Updating heightCache after the view is updated. #6058 --- .../src/lib/directives/for-of/for_of.directive.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts b/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts index 4a48a728946..7a00fc5eaeb 100644 --- a/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts @@ -32,7 +32,7 @@ import { VirtualHelperComponent } from './virtual.helper.component'; import { IgxScrollInertiaModule } from './../scroll-inertia/scroll_inertia.directive'; import { IgxForOfSyncService, IgxForOfScrollSyncService } from './for_of.sync.service'; import { Subject } from 'rxjs'; -import { takeUntil, filter, throttleTime } from 'rxjs/operators'; +import { takeUntil, filter, throttleTime, first } from 'rxjs/operators'; import ResizeObserver from 'resize-observer-polyfill'; import { IBaseEventArgs } from '../../core/utils'; import { VirtualHelperBaseDirective } from './base.helper.component'; @@ -746,7 +746,6 @@ export class IgxForOfDirective implements OnInit, OnChanges, DoCheck, OnDestr const diffs = []; let totalDiff = 0; const l = this._embeddedViews.length; - this._embeddedViews.filter(view => !view.destroyed).forEach(view => view.detectChanges()); const rNodes = this._embeddedViews.map(view => view.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE) || view.rootNodes[0].nextElementSibling); for (let i = 0; i < l; i++) { @@ -1561,7 +1560,10 @@ export class IgxGridForOfDirective extends IgxForOfDirective implements On const scrollOffset = this.fixedUpdateAllElements(this._virtScrollTop); this.dc.instance._viewContainer.element.nativeElement.style.top = -(scrollOffset) + 'px'; - this.recalcUpdateSizes(); + + this._zone.onStable.pipe(first()).subscribe( () => { + this.recalcUpdateSizes(); + }); this.cdr.markForCheck(); } From 03edc2db1f91109a19ca8ca5d2745e68f0e509e8 Mon Sep 17 00:00:00 2001 From: Nikolay Alipiev Date: Mon, 11 Nov 2019 22:26:01 +0200 Subject: [PATCH 13/21] fix(schematics): check polyfills in default project #6017 (#6106) --- .../schematics/ng-add/index.spec.ts | 54 ++++++++++--------- .../schematics/ng-add/index.ts | 12 +++-- .../schematics/utils/dependency-handler.ts | 10 ++-- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/projects/igniteui-angular/schematics/ng-add/index.spec.ts b/projects/igniteui-angular/schematics/ng-add/index.spec.ts index 9b5938bfec1..46f48922c56 100644 --- a/projects/igniteui-angular/schematics/ng-add/index.spec.ts +++ b/projects/igniteui-angular/schematics/ng-add/index.spec.ts @@ -9,17 +9,19 @@ describe('ng-add schematics', () => { const collectionPath = path.join(__dirname, '../collection.json'); const runner: SchematicTestRunner = new SchematicTestRunner('cli-schematics', collectionPath); let tree: UnitTestTree; + const sourceRoot = 'testSrc'; const ngJsonConfig = { defaultProject: 'testProj', projects: { testProj: { - sourceRoot: 'src', + sourceRoot: sourceRoot, projectType: ProjectType.Application, architect: { serve: {}, build: { options: { - main: 'src/main.ts', + main: `${sourceRoot}/main.ts`, + polyfills: `${sourceRoot}/polyfills.ts`, scripts: [] } } @@ -42,7 +44,7 @@ describe('ng-add schematics', () => { tree = new UnitTestTree(new EmptyTree()); tree.create('/angular.json', JSON.stringify(ngJsonConfig)); tree.create('/package.json', JSON.stringify(pkgJsonConfig)); - tree.create('src/main.ts', '// test comment'); + tree.create(`${sourceRoot}/main.ts`, '// test comment'); }); it('should create the needed files correctly', () => { @@ -71,7 +73,7 @@ describe('ng-add schematics', () => { it('should add hammer.js to the main.ts file', () => { runner.runSchematic('ng-add', { normalizeCss: false }, tree); - const mainTs = tree.read('src/main.ts').toString(); + const mainTs = tree.read(`${sourceRoot}/main.ts`).toString(); expect(mainTs).toContain('import \'hammerjs\';'); }); @@ -82,12 +84,12 @@ describe('ng-add schematics', () => { tree.overwrite('angular.json', JSON.stringify(workspace)); runner.runSchematic('ng-add', { normalizeCss: false }, tree); - const newContent = tree.read('src/main.ts').toString(); + const newContent = tree.read(`${sourceRoot}/main.ts`).toString(); expect(newContent.split('import \'hammerjs\';\n// test comment').length).toEqual(1); }); it('should not add hammer.js if it exists in main.ts', () => { - const mainTsPath = 'src/main.ts'; + const mainTsPath = `${sourceRoot}/main.ts`; const content = tree.read(mainTsPath).toString(); tree.overwrite(mainTsPath, 'import \'hammerjs\';\n' + content); runner.runSchematic('ng-add', { normalizeCss: false }, tree); @@ -138,54 +140,54 @@ import 'core-js/es6/set'; import 'web-animations-js'; // Run \`npm install --save web-animations-js\`. `; - tree.create('src/polyfills.ts', polyfills); + tree.create(`${sourceRoot}/polyfills.ts`, polyfills); runner.runSchematic('ng-add', { polyfills: true, normalizeCss: false }, tree); - expect(tree.readContent('src/polyfills.ts').replace(/\r\n/g, '\n')).toEqual(result.replace(/\r\n/g, '\n')); + expect(tree.readContent(`${sourceRoot}/polyfills.ts`).replace(/\r\n/g, '\n')).toEqual(result.replace(/\r\n/g, '\n')); }); it('should properly add css reset', () => { - tree.create('src/styles.scss', ''); + tree.create(`${sourceRoot}/styles.scss`, ''); runner.runSchematic('ng-add', { normalizeCss: true }, tree); let pkgJsonData = JSON.parse(tree.readContent('/package.json')); - expect(tree.readContent('src/styles.scss')).toEqual(scssImport); + expect(tree.readContent(`${sourceRoot}/styles.scss`)).toEqual(scssImport); expect(pkgJsonData.dependencies['minireset.css']).toBeTruthy(); resetJsonConfigs(tree); - tree.delete('src/styles.scss'); + tree.delete(`${sourceRoot}/styles.scss`); - tree.create('src/styles.sass', ''); + tree.create(`${sourceRoot}/styles.sass`, ''); runner.runSchematic('ng-add', { normalizeCss: true }, tree); pkgJsonData = JSON.parse(tree.readContent('/package.json')); - expect(tree.readContent('src/styles.sass')).toEqual(scssImport); + expect(tree.readContent(`${sourceRoot}/styles.sass`)).toEqual(scssImport); expect(pkgJsonData.dependencies['minireset.css']).toBeTruthy(); resetJsonConfigs(tree); - tree.delete('src/styles.sass'); + tree.delete(`${sourceRoot}/styles.sass`); - tree.create('src/styles.css', ''); + tree.create(`${sourceRoot}/styles.css`, ''); runner.runSchematic('ng-add', { normalizeCss: true }, tree); pkgJsonData = JSON.parse(tree.readContent('/package.json')); - expect(tree.readContent('src/styles.css')).toBe(''); + expect(tree.readContent(`${sourceRoot}/styles.css`)).toBe(''); expect(pkgJsonData.dependencies['minireset.css']).toBeTruthy(); expect(JSON.parse(tree.readContent('/angular.json')).projects['testProj'].architect.build.options.styles).toContain(cssImport); resetJsonConfigs(tree); - tree.delete('src/styles.css'); + tree.delete(`${sourceRoot}/styles.css`); - tree.create('src/styles.less', ''); + tree.create(`${sourceRoot}/styles.less`, ''); runner.runSchematic('ng-add', { normalizeCss: true }, tree); pkgJsonData = JSON.parse(tree.readContent('/package.json')); - expect(tree.readContent('src/styles.less')).toBe(''); + expect(tree.readContent(`${sourceRoot}/styles.less`)).toBe(''); expect(pkgJsonData.dependencies['minireset.css']).toBeTruthy(); expect(JSON.parse(tree.readContent('/angular.json')).projects['testProj'].architect.build.options.styles).toContain(cssImport); resetJsonConfigs(tree); - tree.delete('src/styles.less'); + tree.delete(`${sourceRoot}/styles.less`); - tree.create('src/styles.styl', ''); + tree.create(`${sourceRoot}/styles.styl`, ''); runner.runSchematic('ng-add', { normalizeCss: true }, tree); pkgJsonData = JSON.parse(tree.readContent('/package.json')); - expect(tree.readContent('src/styles.styl')).toBe(''); + expect(tree.readContent(`${sourceRoot}/styles.styl`)).toBe(''); expect(pkgJsonData.dependencies['minireset.css']).toBeTruthy(); expect(JSON.parse(tree.readContent('/angular.json')).projects['testProj'].architect.build.options.styles).toContain(cssImport); resetJsonConfigs(tree); - tree.delete('src/styles.styl'); + tree.delete(`${sourceRoot}/styles.styl`); }); it('should properly add web animations', () => { @@ -202,7 +204,7 @@ import 'web-animations-js'; // Run \`npm install --save web-animations-js\`. * that is built with AngularCLI v7.3 or above. All else are considered below v7.3. */ it('should enable es5BrowserSupport on projects with ng cli version >= 7.3', () => { - tree.create('src/polyfills.ts', ''); + tree.create(`${sourceRoot}/polyfills.ts`, ''); const newJson: any = JSON.parse(tree.read('/angular.json').toString()); newJson.projects['testProj'].architect.build.options['es5BrowserSupport'] = false; tree.overwrite('/angular.json', JSON.stringify(newJson)); @@ -226,11 +228,11 @@ import 'web-animations-js'; // Run \`npm install --save web-animations-js\`. import 'web-animations-js'; // Run \`npm install --save web-animations-js\`. `; - tree.create('src/polyfills.ts', polyfills); + tree.create(`${sourceRoot}/polyfills.ts`, polyfills); const newJson: any = JSON.parse(tree.read('/angular.json').toString()); newJson.projects['testProj'].architect.build.options['es5BrowserSupport'] = false; tree.overwrite('/angular.json', JSON.stringify(newJson)); runner.runSchematic('ng-add', { polyfills: true }, tree); - expect(tree.readContent('src/polyfills.ts').replace(/\r\n/g, '\n')).toEqual(result.replace(/\r\n/g, '\n')); + expect(tree.readContent(`${sourceRoot}/polyfills.ts`).replace(/\r\n/g, '\n')).toEqual(result.replace(/\r\n/g, '\n')); }); }); diff --git a/projects/igniteui-angular/schematics/ng-add/index.ts b/projects/igniteui-angular/schematics/ng-add/index.ts index 8b1d8aabdc3..1c98738aa59 100644 --- a/projects/igniteui-angular/schematics/ng-add/index.ts +++ b/projects/igniteui-angular/schematics/ng-add/index.ts @@ -1,10 +1,11 @@ import { chain, Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { Options } from '../interfaces/options'; import { installPackageJsonDependencies } from '../utils/package-handler'; -import { logSuccess, addDependencies, overwriteJsonFile, getPropertyFromWorkspace } from '../utils/dependency-handler'; +import { logSuccess, addDependencies, overwriteJsonFile, + getPropertyFromWorkspace, getConfigFile } from '../utils/dependency-handler'; import { addResetCss } from './add-normalize'; -import { getWorkspace } from '@schematics/angular/utility/config'; +import { getWorkspace, getConfig } from '@schematics/angular/utility/config'; import { WorkspaceSchema } from '@schematics/angular/utility/workspace-models'; @@ -17,7 +18,9 @@ function propertyExistsInWorkspace(targetProp: string, workspace: WorkspaceSchem } function enablePolyfills(tree: Tree, context: SchematicContext): string { - const targetFile = 'src/polyfills.ts'; + const workspace = getWorkspace(tree); + const project = workspace.projects[workspace.defaultProject]; + const targetFile = getConfigFile(project, 'polyfills'); if (!tree.exists(targetFile)) { context.logger.warn(`${targetFile} not found. You may need to update polyfills.ts manually.`); return; @@ -50,7 +53,8 @@ function readInput(options: Options): Rule { if (options.polyfills) { const workspace = getWorkspace(tree); const targetProperty = 'es5BrowserSupport'; - const polyfillsFile = 'src/polyfills.ts'; + const project = workspace.projects[workspace.defaultProject]; + const polyfillsFile = getConfigFile(project, 'polyfills'); const propertyExists = propertyExistsInWorkspace(targetProperty, workspace); let polyfillsData = tree.read(polyfillsFile).toString(); if (propertyExists) { diff --git a/projects/igniteui-angular/schematics/utils/dependency-handler.ts b/projects/igniteui-angular/schematics/utils/dependency-handler.ts index d7c945a1ba4..c981bcfb3b8 100644 --- a/projects/igniteui-angular/schematics/utils/dependency-handler.ts +++ b/projects/igniteui-angular/schematics/utils/dependency-handler.ts @@ -26,14 +26,14 @@ function getTargetedProjectOptions(project: WorkspaceProject, targe throw new SchematicsException(`Cannot determine the project's configuration for: ${target}`); } -function getMainFile(project: WorkspaceProject): string { +export function getConfigFile(project: WorkspaceProject, option: string): string { const buildOptions = getTargetedProjectOptions(project, 'build'); - if (!buildOptions.main) { - throw new SchematicsException(`Could not find the project main file inside of the ` + + if (!buildOptions[option]) { + throw new SchematicsException(`Could not find the project ${option} file inside of the ` + `workspace config (${project.sourceRoot})`); } - return buildOptions.main; + return buildOptions[option]; } export function overwriteJsonFile(tree: Tree, targetFile: string, data: any) { @@ -113,7 +113,7 @@ function includeDependencies(pkgJson: any, context: SchematicContext, tree: Tree const workspace = getWorkspace(tree); const project = workspace.projects[workspace.defaultProject]; const projectOptions = getTargetedProjectOptions(project, 'build'); - const mainTsPath = getMainFile(project); + const mainTsPath = getConfigFile(project, 'main'); const hammerImport = 'import \'hammerjs\';\n'; const mainTsContent = tree.read(mainTsPath).toString(); // if there are no elements in the architect.build.options.scripts array that contain hammerjs From d6f9c8470b35797a6e117c79c6dcb80c38e3804a Mon Sep 17 00:00:00 2001 From: Plamena Miteva Date: Tue, 12 Nov 2019 11:32:36 +0200 Subject: [PATCH 14/21] fix(date-picker): remove duplicate call to onChangeCalback #6067 (#6131) --- .../src/lib/date-picker/date-picker.component.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts index 118f6673de9..562c45a00d3 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts @@ -953,7 +953,6 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor this.emitValueChangeEvent(oldValue, this.value ); this.onSelection.emit(date); - this._onChangeCallback(date); } /** @@ -974,7 +973,6 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor if (this.calendar) { this.calendar.deselectDate(); } - this._onChangeCallback(null); } /** @@ -1060,7 +1058,6 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor this.emitValueChangeEvent(oldValue, this.value ); this.calendar.viewDate = date; - this._onChangeCallback(date); this.closeCalendar(); this.onSelection.emit(date); } @@ -1205,7 +1202,6 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor this.emitValueChangeEvent(oldValue, this.value ); this.invalidDate = ''; - this._onChangeCallback(newValue); } else { const args: IDatePickerDisabledDateEventArgs = { datePicker: this, From 33da794b51e8e112a2bec6bea73ea91fd3a70727 Mon Sep 17 00:00:00 2001 From: Damyan Petev Date: Wed, 6 Nov 2019 19:41:30 +0200 Subject: [PATCH 15/21] fix(overlay): prevent extra position calls on scroll using absolute #6130 --- .../src/lib/services/overlay/overlay.spec.ts | 40 +++++++++++++++++++ .../scroll/absolute-scroll-strategy.ts | 10 ++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts index 6c8a5522fc9..fa394494aa3 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts @@ -915,6 +915,46 @@ describe('igxOverlay', () => { expect(scrollStrat.detach).toHaveBeenCalledTimes(1); })); + it('Should only call reposition once on scroll - Absolute.', fakeAsync(async () => { + TestBed.overrideComponent(EmptyPageComponent, { + set: { + styles: [`button { + position: absolute, + bottom: 200%; + }`] + } + }); + await TestBed.compileComponents(); + const fixture = TestBed.createComponent(EmptyPageComponent); + fixture.detectChanges(); + + const scrollStrat = new AbsoluteScrollStrategy(); + const overlaySettings: OverlaySettings = { + positionStrategy: new GlobalPositionStrategy(), + scrollStrategy: scrollStrat, + modal: false, + closeOnOutsideClick: false + }; + const overlay = fixture.componentInstance.overlay; + const scrollSpy = spyOn(scrollStrat, 'onScroll').and.callThrough(); + spyOn(overlay, 'reposition'); + const id = overlay.attach(SimpleDynamicComponent, overlaySettings); + overlay.show(id, overlaySettings); + tick(); + + const content = document.getElementsByClassName(CLASS_OVERLAY_CONTENT)[0]; + content.children[0].dispatchEvent(new Event('scroll')); + expect(scrollSpy).toHaveBeenCalledTimes(1); + expect(overlay.reposition).not.toHaveBeenCalled(); + + document.dispatchEvent(new Event('scroll')); + expect(scrollSpy).toHaveBeenCalledTimes(2); + expect(overlay.reposition).toHaveBeenCalledTimes(1); + expect(overlay.reposition).toHaveBeenCalledWith(id); + + overlay.hide(id); + })); + it('Should properly initialize Scroll Strategy - Close.', fakeAsync(async () => { TestBed.overrideComponent(EmptyPageComponent, { set: { diff --git a/projects/igniteui-angular/src/lib/services/overlay/scroll/absolute-scroll-strategy.ts b/projects/igniteui-angular/src/lib/services/overlay/scroll/absolute-scroll-strategy.ts index f86097b7019..f917de86b07 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/scroll/absolute-scroll-strategy.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/scroll/absolute-scroll-strategy.ts @@ -60,7 +60,13 @@ export class AbsoluteScrollStrategy extends ScrollStrategy { } } - private onScroll = () => { - this._overlayService.repositionAll(); + private onScroll = (e: Event) => { + const overlayInfo = this._overlayService.getOverlayById(this._id); + if (!overlayInfo) { + return; + } + if (!overlayInfo.elementRef.nativeElement.contains(e.target)) { + this._overlayService.reposition(this._id); + } } } From d2cfd8cde5e32aefd73d9211f0ab34a26a826e5b Mon Sep 17 00:00:00 2001 From: Nadia Robakova Date: Wed, 13 Nov 2019 12:29:50 +0200 Subject: [PATCH 16/21] feat(carousel): add carousel indicators template and animations #4268 #6142 (#6110) --- CHANGELOG.md | 26 +- .../src/lib/carousel/README.md | 26 +- .../src/lib/carousel/carousel.component.html | 51 +- .../lib/carousel/carousel.component.spec.ts | 1008 +++++++++++++---- .../src/lib/carousel/carousel.component.ts | 644 ++++++++--- .../src/lib/carousel/carousel.directives.ts | 7 + .../src/lib/carousel/slide.component.html | 11 +- .../src/lib/carousel/slide.component.ts | 158 +++ .../src/lib/core/i18n/carousel-resources.ts | 7 + .../src/lib/core/i18n/resources.ts | 6 +- .../carousel/_carousel-component.scss | 60 +- .../components/carousel/_carousel-theme.scss | 153 ++- .../styles/themes/schemas/dark/_carousel.scss | 2 + .../themes/schemas/light/_carousel.scss | 3 + .../lib/test-utils/ui-interactions.spec.ts | 8 + src/app/carousel/carousel.sample.html | 36 +- src/app/carousel/carousel.sample.ts | 31 +- 17 files changed, 1705 insertions(+), 532 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/carousel/carousel.directives.ts create mode 100644 projects/igniteui-angular/src/lib/carousel/slide.component.ts create mode 100644 projects/igniteui-angular/src/lib/core/i18n/carousel-resources.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index df1eb72a3c2..076082feca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ All notable changes for each version of this project will be documented in this - `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid` - **Behavioral Change** - Pinning columns is no longer automatically prevented when the pinning area would exceed the size of the grid. +- `IgxCarousel`: + - **Breaking Changes** -The carousel slides are no longer array, they are changed to QueryList. + - **Behavioural change** - When slides are more than 5, a label is shown instead of the indicators. The count limit of visible indicators can be changed with the input `maximumIndicatorsCount` + ### New Features - `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`: @@ -25,13 +29,13 @@ All notable changes for each version of this project will be documented in this - `sortingExpressionsChange` event emitter is added, which is fired whenever a change to the sorting expressions has occurred (prior to performing the actual sorting). - `filteringExpressionsTreeChange` event emitter is added, which is fired whenever a change to the filtering expressions has occurred (prior to performing the actual filtering). - `advancedFilteringExpressionsTreeChange` event emitter is added, which is fired whenever a change to the advanced filtering expressions has occurred (prior to performing the actual filtering). -- `IgxGridExcelStyleFilteringComponent` and `IgxAdvancedFilteringDialogComponent` can now be hosted outside of the grid in order to provide the same experience as the built-in filtering UI. -- `IgxOverlayService`: - - `setOffset` method added. It offsets the content along the corresponding axis by the provided amount. -- `IgxToggleDirective`: - - `setOffset` method added. It offsets the content along the corresponding axis by the provided amount. -- `IgxRowDragGhost` directive is added. It allows providing a custom template for the drag ghost when dragging a row. -```html + - `IgxGridExcelStyleFilteringComponent` and `IgxAdvancedFilteringDialogComponent` can now be hosted outside of the grid in order to provide the same experience as the built-in filtering UI. + - `IgxOverlayService`: + - `setOffset` method added. It offsets the content along the corresponding axis by the provided amount. + - `IgxToggleDirective`: + - `setOffset` method added. It offsets the content along the corresponding axis by the provided amount. + - `IgxRowDragGhost` directive is added. It allows providing a custom template for the drag ghost when dragging a row. + ```html @@ -43,7 +47,13 @@ All notable changes for each version of this project will be documented in this -``` + ``` + - `IgxCarousel`: + - `keyboardSupport` input is added, which can be used to enable and disable keyboard navigation + - `maximumIndicatorsCount` input is added, which can be used to set the number of visible indicators + - `indicatorsOrientation` input is added, which can be used to set the position of indicators it can be top or bottom + - `animationType` input is added, which can be used to set animation when changing slides + - `indicatorTemplate` directive is added, which can be used to provide a custom indicator for carousel. If this property is not provided, a default indicator template will be used instead. ## 8.2.6 diff --git a/projects/igniteui-angular/src/lib/carousel/README.md b/projects/igniteui-angular/src/lib/carousel/README.md index 449f2408cea..1121334bfe1 100644 --- a/projects/igniteui-angular/src/lib/carousel/README.md +++ b/projects/igniteui-angular/src/lib/carousel/README.md @@ -2,7 +2,7 @@ A carousel component is used to browse or navigate through a collection of slides - galleries of images, cards, on-boarding tutorials or page-based interfaces. It can be used as a separate full screen element -or inside another component. +or inside another component. A walkthrough of how to get started can be found [here](https://www.infragistics.com/products/ignite-ui-angular/angular/components/carousel.html) # API Summary `igx-carousel` @@ -13,6 +13,10 @@ A walkthrough of how to get started can be found [here](https://www.infragistics | `pause` | boolean | Should the carousel stop playing on user interaction. Defaults to `true`. | | `interval` | number | The amount of time in milliseconds between slides transition. | | `navigation` | boolean | Controls should the carousel render the left/right navigation buttons. Defaults to `true`. | +| `keyboardSupport` | boolean | Controls should the keyboard navigation should be supported. Defaults to `true`. | +| `maximumIndicatorsCount` | number | The number of visible indicators. Defaults to `5`. | +| `indicatorsOrientation` | CarouselIndicatorsOrientation | Controls whether the indicators should be previewed on top or on bottom of carousel. Defaults to `bottom`. | +| `animationType` | CarouselAnimationType | Controls what animation should be played when slides are changing. Defaults to `slide`. | | `total` | number | The number of slides the carousel currently has. | | `current` | number | The index of the slide currently showing. | | `isPlaying` | boolean | Returns whether the carousel is paused/playing. | @@ -31,6 +35,26 @@ A walkthrough of how to get started can be found [here](https://www.infragistics | `get(index: Number)` | IgxSlide or void | Returns the slide with the given index or null. | | `select(slide: IgxSlide, direction: Direction)`| void | Selects the slide and the direction to transition to. Emits `onSlideChanged` event. | +### Keyboard navigation +Keyboard navigation will be enabled when the **IgxCarousel** component is focused and `keyboardSupport` property is set to `true`: +- Arrow keys will navigate through the slides. +- `Home` will focus the first slide inside the carousel view. +- `End` will focus the last slide inside the carousel view. + +### Templates +The **IgxCarousel** supports templating of its indicators + +#### Defining item template: +```html + + ... + + brightness_7 + brightness_5 + + +``` + # API Summary `igx-slide` | Name | Type | Description | |:----------|:-------------:|:------| diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.component.html b/projects/igniteui-angular/src/lib/carousel/carousel.component.html index 8e41c8e6548..4a42a238f33 100644 --- a/projects/igniteui-angular/src/lib/carousel/carousel.component.html +++ b/projects/igniteui-angular/src/lib/carousel/carousel.component.html @@ -1,22 +1,35 @@ -