Skip to content

Commit 5b4c989

Browse files
authored
Merge pull request #17363 from IgniteUI/master
Back-merging a left-over fix
2 parents 4568ddd + 51bab3f commit 5b4c989

8 files changed

Lines changed: 94 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ All notable changes for each version of this project will be documented in this
7272

7373
### General
7474

75+
- **Touch Gestures (HammerJS)** _(optional)_
76+
- `HammerModule`, previously exported from `@angular/platform-browser`, is no longer available in Angular 22. Touch gesture support (Slider, Drag & Drop, Carousel swipe, Navigation Drawer) is optional. To enable it, install the `hammerjs` package and add it to the `scripts` array in your project's `angular.json`:
77+
```bash
78+
npm install hammerjs
79+
```
80+
```json
81+
// angular.json — inside your project's architect.build.options
82+
"scripts": ["./node_modules/hammerjs/hammer.min.js"]
83+
```
84+
7585
- `IgxSelectComponent`
7686
- The default positioning strategy has changed from the internal overlap strategy to `AutoPositionStrategy`. The dropdown now opens below (or above, if there is not enough space) the input element, consistent with other connected components.
7787
- Added `IgxSelectOverlapPositionStrategy` - a new publicly exported strategy that preserves the previous behavior of aligning the selected item's text over the input text. To opt into the previous overlap behavior:

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,6 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
10661066
this.scrollFocus(embView.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE)
10671067
|| embView.rootNodes[0].nextElementSibling);
10681068
const view = container.detach(0);
1069-
// embView and view both refer to the same collections
10701069
this.updateTemplateContext(embView.context, i);
10711070

10721071
// Because in Elements the whole parent div (containing data-index) gets removed (possibly due to being disconnected). In Angular it just gets moved.
@@ -1092,7 +1091,6 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
10921091
|| embView.rootNodes[0].nextElementSibling);
10931092
// embView and view both refer to the same collections
10941093
const view = container.detach(container.length - 1);
1095-
10961094
this.updateTemplateContext(embView.context, i);
10971095
view.detectChanges();
10981096

projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,8 @@
276276
<ng-content select="igx-column,igc-column,igx-column-group,igc-column-group,igx-action-strip,igc-action-strip"></ng-content>
277277
<ng-content select="igx-row-island,igc-row-island"></ng-content>
278278
}
279+
280+
<!-- Lifecycle placeholder used to determine when the grid gets connected/disconnected from the DOM, for example as a result of virtualization or caching. -->
281+
<igc-lifecycle-placeholder (igcConnected)="onLifecyclePlaceholderConnected()"
282+
(igcDisconnected)="onLifecyclePlaceholderDisconnected()">
283+
</igc-lifecycle-placeholder>

projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { IgxIconComponent } from 'igniteui-angular/icon';
3636
import { EntityType, FieldType, IFilteringExpressionsTree, IgxOverlayOutletDirective, flatten, IGridResourceStrings } from 'igniteui-angular/core';
3737
import { IgxPaginatorToken } from 'igniteui-angular/paginator';
3838
import { IgxGridCellMergePipe, IgxGridComponent, IgxGridFilteringPipe, IgxGridSortingPipe, IgxGridUnmergeActivePipe } from 'igniteui-angular/grids/grid';
39+
import { registerLifecyclePlaceholderElement } from './lifecycle-placeholder-element';
3940

4041
let NEXT_ID = 0;
4142

@@ -647,6 +648,9 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
647648
* @hidden
648649
*/
649650
public override ngOnInit() {
651+
if (this.platform.isBrowser) {
652+
registerLifecyclePlaceholderElement();
653+
}
650654
// this.expansionStatesChange.pipe(takeUntil(this.destroy$)).subscribe((value: Map<any, boolean>) => {
651655
// const res = Array.from(value.entries()).filter(({1: v}) => v === true).map(([k]) => k);
652656
// });
@@ -659,6 +663,26 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
659663
super.ngOnInit();
660664
}
661665

666+
// Event that triggers when element gets connected back to the DOM.
667+
// Used to determine when to reopen a previously closed row editing overlay.
668+
protected onLifecyclePlaceholderConnected(): void {
669+
if (this.rowEditable && this.crudService.rowInEditMode && this.rowEditingOverlay &&
670+
this.rowEditingOverlay.collapsed) {
671+
// Row is in edit mode, but overlay is closed - reopen.
672+
this.openRowOverlay(this.crudService.rowInEditMode.id);
673+
}
674+
675+
}
676+
677+
// Event that triggers when element gets disconnected from the DOM, for example as a result of virtualization or caching.
678+
// Used to determine when to close the row editing overlay.
679+
protected onLifecyclePlaceholderDisconnected(): void {
680+
if (this.rowEditable && this.crudService.rowInEditMode && this.rowEditingOverlay) {
681+
// disconnected from DOM (possibly cached) & row was in edit mode - close overlay.
682+
this.closeRowEditingOverlay();
683+
}
684+
}
685+
662686
/**
663687
* @hidden
664688
*/
@@ -1239,15 +1263,15 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
12391263
{
12401264
name: null,
12411265
fields: filterableFields.map(f => ({
1242-
field: f.field,
1243-
dataType: f.dataType,
1244-
header: f.header,
1245-
editorOptions: f.editorOptions,
1246-
filters: f.filters,
1247-
pipeArgs: f.pipeArgs,
1248-
defaultTimeFormat: f.defaultTimeFormat,
1249-
defaultDateTimeFormat: f.defaultDateTimeFormat
1250-
})) as FieldType[]
1266+
field: f.field,
1267+
dataType: f.dataType,
1268+
header: f.header,
1269+
editorOptions: f.editorOptions,
1270+
filters: f.filters,
1271+
pipeArgs: f.pipeArgs,
1272+
defaultTimeFormat: f.defaultTimeFormat,
1273+
defaultDateTimeFormat: f.defaultDateTimeFormat
1274+
})) as FieldType[]
12511275
}
12521276
];
12531277

@@ -1256,7 +1280,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
12561280
this.data[0][rowIsland.key][0] : null;
12571281
return acc.concat(this.generateChildEntity(rowIsland, childFirstRowData));
12581282
}
1259-
, []);
1283+
, []);
12601284
}
12611285

12621286
return entities;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const LIFECYCLE_PLACEHOLDER_TAG = 'igc-lifecycle-placeholder';
2+
const LIFECYCLE_CONNECTED_EVENT = 'igcConnected';
3+
const LIFECYCLE_DISCONNECTED_EVENT = 'igcDisconnected';
4+
5+
/** @hidden @internal */
6+
export function registerLifecyclePlaceholderElement(): void {
7+
if (typeof customElements === 'undefined' || typeof HTMLElement === 'undefined' ||
8+
typeof CustomEvent === 'undefined' || customElements.get(LIFECYCLE_PLACEHOLDER_TAG)) {
9+
return;
10+
}
11+
12+
class LifecyclePlaceholderElement extends HTMLElement {
13+
public connectedCallback(): void {
14+
this.dispatchEvent(new CustomEvent(LIFECYCLE_CONNECTED_EVENT));
15+
}
16+
17+
public disconnectedCallback(): void {
18+
this.dispatchEvent(new CustomEvent(LIFECYCLE_DISCONNECTED_EVENT));
19+
}
20+
}
21+
22+
customElements.define(LIFECYCLE_PLACEHOLDER_TAG, LifecyclePlaceholderElement);
23+
}

skills/igniteui-angular-components/references/directives.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,14 @@ onDrop(event: IDropDroppedEventArgs) {
254254
Key drag events: `(dragStart)`, `(dragMove)`, `(dragEnd)`, `(dragClick)`, `(ghostCreate)`, `(ghostDestroy)`, `(transitioned)`.
255255
Key drop events: `(enter)`, `(leave)`, `(over)`, `(dropped)`.
256256

257-
> **NOTE:** For touch-based drag, add `importProvidersFrom(HammerModule)` to `app.config.ts` providers.
257+
> **NOTE (optional):** For touch-based drag, install `hammerjs` and add it to the `scripts` array in `angular.json`.
258+
> ```bash
259+
> npm install hammerjs
260+
> ```
261+
> ```json
262+
> // angular.json — inside your project's architect.build.options
263+
> "scripts": ["./node_modules/hammerjs/hammer.min.js"]
264+
> ```
258265
259266
## See Also
260267

skills/igniteui-angular-components/references/setup.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,17 @@ export const appConfig: ApplicationConfig = {
4343
| Provider | Package | Required for |
4444
|---|---|---|
4545
| `provideAnimations()` | `@angular/platform-browser/animations` | **All overlay and animated components** — Dialog, Combo, Select, Dropdown, Date/Time Picker, Snackbar, Toast, Banner, Navigation Drawer, Carousel, Overlay service |
46-
| `importProvidersFrom(HammerModule)` | `@angular/platform-browser` | OPTIONAL — touch gestures (Slider, Drag & Drop, swipe) |
46+
47+
> **Touch gestures** (Optional) (Slider, Drag & Drop, swipe) - To enable touch gesture support, install the `hammerjs` package and add it to the `scripts` array in your `angular.json`:
48+
>
49+
> ```bash
50+
> npm install hammerjs
51+
> ```
52+
>
53+
> ```json
54+
> // angular.json — inside your project's architect.build.options
55+
> "scripts": ["./node_modules/hammerjs/hammer.min.js"]
56+
> ```
4757
4858
> **`provideAnimationsAsync()`** lazy-loads the animations module — prefer it for SSR or when optimizing initial bundle size:
4959
> ```typescript

src/app/hierarchical-grid/hierarchical-grid.sample.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,12 @@ <h4 class="sample-title">Sample two</h4>
150150
<igx-grid-toolbar-exporter></igx-grid-toolbar-exporter>
151151
</igx-grid-toolbar-actions>
152152
</igx-grid-toolbar>
153-
<igx-row-island [key]="'childData'" [autoGenerate]="true" [rowSelection]='selectionMode' [batchEditing]="true" [rowEditable]="true"
153+
<igx-row-island [rowEditable]="true" [primaryKey]="'ID'" [key]="'childData'" [autoGenerate]="true" [rowSelection]='selectionMode' [batchEditing]="true" [rowEditable]="true"
154154
[allowFiltering]="true">
155-
<igx-row-island [key]="'childData'" [autoGenerate]="true" [rowSelection]='selectionMode' [batchEditing]="true" [rowEditable]="true"
155+
<igx-row-island [rowEditable]="true" [primaryKey]="'ID'" [key]="'childData'" [autoGenerate]="true" [rowSelection]='selectionMode' [batchEditing]="true" [rowEditable]="true"
156156
[allowFiltering]="true"></igx-row-island>
157157
</igx-row-island>
158-
<igx-row-island [key]="'childData2'" [autoGenerate]="true" [allowFiltering]="true"></igx-row-island>
158+
<igx-row-island [rowEditable]="true" [primaryKey]="'ID'" [key]="'childData2'" [autoGenerate]="true" [allowFiltering]="true"></igx-row-island>
159159
</igx-hierarchical-grid>
160160

161161

0 commit comments

Comments
 (0)