Skip to content

Commit f9788e2

Browse files
authored
Merge branch '19.2.x' into gedinakova/fix-activate-highlight-15735-19.2
2 parents e048a8a + 8374b56 commit f9788e2

File tree

179 files changed

+988
-1051
lines changed

Some content is hidden

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

179 files changed

+988
-1051
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ Some of the Angular chart types included are: [Polar chart](https://www.infragis
108108
|stepper|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/stepper/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/stepper)|13.0.0|
109109
|switch|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/switch/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/switch)|2.0.0|||||
110110
|tabs|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/tabs/tabs/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/tabs)|5.1.0||||
111+
|tile manager|:white_check_mark:||[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/tile-manager)|19.2.0||||
111112
|time picker|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/time-picker/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/time-picker)|5.3.0||||
112113
|toast|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/toast/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/toast)|5.1.0||||
113114
|tree|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/tree/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/tree)|12.0.0||||
@@ -162,6 +163,8 @@ Some of the Angular chart types included are: [Polar chart](https://www.infragis
162163
|18.1.0|22-Jul-24|[Milestone #33](https://github.com/IgniteUI/igniteui-angular/blob/master/ROADMAP.md#milestone-33-due-by-jul-2024)|
163164
|18.2.0|25-Oct-24|[Milestone #34](https://github.com/IgniteUI/igniteui-angular/blob/master/ROADMAP.md#milestone-34-version-182-released-oct-25th-2024)|
164165
|19.0.0|25-Nov-24|[Milestone #35](https://github.com/IgniteUI/igniteui-angular/blob/master/ROADMAP.md#milestone-35-version-190-released-nov-25th-2024)|
166+
|19.1.0|27-Feb-25|[Milestone #36](https://github.com/IgniteUI/igniteui-angular/blob/master/ROADMAP.md#milestone-36--version-191-released-feb-27th-2025)|
167+
|19.2.0|16-Apr-25|[Milestone #37]()|
165168

166169

167170
### Components available in [igniteui-angular-charts](https://www.npmjs.com/package/igniteui-angular-charts)

angular.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,17 @@
191191
"zone.js/testing",
192192
"hammerjs"
193193
],
194+
"styles": [
195+
"src/styles/styles.scss"
196+
],
197+
"assets": [
198+
"projects/igniteui-angular/src/assets"
199+
],
200+
"stylePreprocessorOptions": {
201+
"includePaths": [
202+
"node_modules"
203+
]
204+
},
194205
"tsConfig": "projects/igniteui-angular/tsconfig.spec.json",
195206
"karmaConfig": "projects/igniteui-angular/karma.conf.js"
196207
}

package-lock.json

Lines changed: 173 additions & 164 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,17 @@
5858
},
5959
"private": true,
6060
"dependencies": {
61-
"@angular/animations": "^19.2.3",
62-
"@angular/common": "^19.2.3",
63-
"@angular/compiler": "^19.2.3",
64-
"@angular/core": "^19.2.3",
65-
"@angular/elements": "^19.2.3",
66-
"@angular/forms": "^19.2.3",
67-
"@angular/platform-browser": "^19.2.3",
68-
"@angular/platform-browser-dynamic": "^19.2.3",
69-
"@angular/platform-server": "^19.2.3",
70-
"@angular/router": "^19.2.3",
71-
"@angular/ssr": "^19.2.4",
61+
"@angular/animations": "^19.2.5",
62+
"@angular/common": "^19.2.5",
63+
"@angular/compiler": "^19.2.5",
64+
"@angular/core": "^19.2.5",
65+
"@angular/elements": "^19.2.5",
66+
"@angular/forms": "^19.2.5",
67+
"@angular/platform-browser": "^19.2.5",
68+
"@angular/platform-browser-dynamic": "^19.2.5",
69+
"@angular/platform-server": "^19.2.5",
70+
"@angular/router": "^19.2.5",
71+
"@angular/ssr": "^19.2.6",
7272
"@igniteui/material-icons-extended": "^3.1.0",
7373
"@lit-labs/ssr-dom-shim": "^1.3.0",
7474
"@types/source-map": "0.5.2",
@@ -82,16 +82,16 @@
8282
"zone.js": "~0.15.0"
8383
},
8484
"devDependencies": {
85-
"@angular-devkit/build-angular": "^19.2.4",
86-
"@angular-devkit/schematics": "^19.2.4",
85+
"@angular-devkit/build-angular": "^19.2.6",
86+
"@angular-devkit/schematics": "^19.2.6",
8787
"@angular-eslint/builder": "^19.3.0",
8888
"@angular-eslint/eslint-plugin": "^19.3.0",
8989
"@angular-eslint/eslint-plugin-template": "^19.3.0",
9090
"@angular-eslint/schematics": "^19.3.0",
9191
"@angular-eslint/template-parser": "^19.3.0",
92-
"@angular/cli": "^19.2.4",
93-
"@angular/compiler-cli": "^19.2.3",
94-
"@angular/language-service": "^19.2.3",
92+
"@angular/cli": "^19.2.6",
93+
"@angular/compiler-cli": "^19.2.5",
94+
"@angular/language-service": "^19.2.5",
9595
"@angularclass/hmr": "^3.0.0",
9696
"@microsoft/signalr": "^7.0.12",
9797
"@types/estree": "^1.0.0",
@@ -131,11 +131,11 @@
131131
"karma-parallel": "^0.3.1",
132132
"karma-spec-reporter": "^0.0.36",
133133
"lit-html": "^3.2.1",
134-
"ng-packagr": "^19.2.0",
134+
"ng-packagr": "^19.2.1",
135135
"postcss": "^8.5.1",
136136
"postcss-scss": "^4.0.6",
137137
"prettier": "^3.3.3",
138-
"puppeteer": "^24.4.0",
138+
"puppeteer": "^24.5.0",
139139
"sass-embedded": "^1.83.4",
140140
"sass-true": "^8.1.0",
141141
"sassdoc": "^2.7.4",

projects/igniteui-angular-elements/src/app/custom-strategy.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,29 @@ describe('Elements: ', () => {
141141
expect(paginator.totalRecords).toEqual(gridEl.data.length);
142142
});
143143

144+
it(`should correctly apply column template when set through event`, async () => {
145+
const gridEl = document.createElement("igc-grid");
146+
147+
const columnID = document.createElement("igc-column");
148+
columnID.setAttribute("field", "ProductID");
149+
gridEl.appendChild(columnID);
150+
const columnName = document.createElement("igc-column");
151+
columnName.setAttribute("field", "ProductName");
152+
gridEl.appendChild(columnName);
153+
154+
gridEl.data = SampleTestData.foodProductData();
155+
gridEl.addEventListener("columnInit", (args: CustomEvent<any>) => {
156+
args.detail.headerTemplate = (ctx) => html`<span>Templated ${args.detail.field}</span>`;
157+
});
158+
testContainer.appendChild(gridEl);
159+
160+
// TODO: Better way to wait - potentially expose the queue or observable for update on the strategy
161+
await firstValueFrom(timer(10 /* SCHEDULE_DELAY */ * 2));
162+
163+
const header = document.getElementsByTagName("igx-grid-header").item(0) as HTMLElement;
164+
expect(header.innerText).toEqual('Templated ProductID');
165+
});
166+
144167
it(`should initialize pivot grid with state persistence component`, async () => {
145168
const gridEl = document.createElement("igc-pivot-grid");
146169

projects/igniteui-angular-elements/src/app/custom-strategy.ts

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { ApplicationRef, ChangeDetectorRef, ComponentFactory, ComponentRef, DestroyRef, Injector, OnChanges, QueryList, Type, ViewContainerRef, reflectComponentType } from '@angular/core';
1+
import { ApplicationRef, ChangeDetectorRef, ComponentFactory, ComponentRef, DestroyRef, EventEmitter, Injector, OnChanges, QueryList, Type, ViewContainerRef, reflectComponentType } from '@angular/core';
22
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3-
import { NgElement } from '@angular/elements';
4-
import { fromEvent } from 'rxjs';
5-
import { takeUntil } from 'rxjs/operators';
3+
import { NgElement, NgElementStrategyEvent } from '@angular/elements';
4+
import { fromEvent, Observable } from 'rxjs';
5+
import { map, takeUntil } from 'rxjs/operators';
66
import { ComponentConfig, ContentQueryMeta } from './component-config';
77

88
import { ComponentNgElementStrategy, ComponentNgElementStrategyFactory, extractProjectableNodes, isFunction } from './ng-element-strategy';
@@ -29,6 +29,8 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
2929
/** Cached child instances per query prop. Used for dynamic components's child templates that normally persist in Angular runtime */
3030
protected cachedChildComponents: Map<string, ComponentRef<any>[]> = new Map();
3131
private setComponentRef: (value: ComponentRef<any>) => void;
32+
/** The maximum depth at which event arguments are processed and angular components wrapped with Proxies, that handle template set */
33+
private maxEventProxyDepth = 3;
3234

3335
/**
3436
* Resolvable component reference.
@@ -405,6 +407,94 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
405407
super.disconnect();
406408
}
407409
}
410+
411+
//#region Handle event args that return reference to components, since they return angular ref and not custom elements.
412+
/** Sets up listeners for the component's outputs so that the events stream emits the events. */
413+
protected override initializeOutputs(componentRef: ComponentRef<any>): void {
414+
const eventEmitters: Observable<NgElementStrategyEvent>[] = this._componentFactory.outputs.map(
415+
({ propName, templateName }) => {
416+
const emitter: EventEmitter<any> = componentRef.instance[propName];
417+
return emitter.pipe(map((value: any) => ({ name: templateName, value: this.patchOutputComponents(propName, value) })));
418+
},
419+
);
420+
421+
(this as any).eventEmitters.next(eventEmitters);
422+
}
423+
424+
protected patchOutputComponents(eventName: string, eventArgs: any) {
425+
// Single out only `columnInit` event for now. If more events pop up will require a config generation.
426+
if (eventName !== "columnInit") {
427+
return eventArgs;
428+
}
429+
return this.createProxyForComponentValue(eventArgs, 1).value;
430+
}
431+
432+
/**
433+
* Nested search of event args that contain angular components and replace them with proxies.
434+
* If event args are array of angular component instances should return array of proxies of each of those instances.
435+
* If event args are object that has a single property being angular component should return same object except the angular component being a proxy of itself.
436+
*/
437+
protected createProxyForComponentValue(value: any, depth: number): { value: any, hasProxies: boolean } {
438+
if (depth > this.maxEventProxyDepth) {
439+
return { value, hasProxies: false };
440+
}
441+
442+
let hasProxies = false;
443+
// TO DO!: Not very reliable as it is a very internal API and could be subject to change. If something comes up, should be changed.
444+
if (value?.__ngContext__) {
445+
const componentConfig = this.config.find((info: ComponentConfig) => value.constructor === info.component);
446+
if (componentConfig?.templateProps) {
447+
return { value: this.createElementsComponentProxy(value, componentConfig), hasProxies: true };
448+
}
449+
} else if (Array.isArray(value)) {
450+
if (!value[0]) {
451+
return { value, hasProxies: false };
452+
} else {
453+
// For array limit their parsing to first level and check if first item has created proxy inside.
454+
const firstItem = this.createProxyForComponentValue(value[0], this.maxEventProxyDepth);
455+
if (firstItem.hasProxies) {
456+
const mappedArray = value.slice(1, value.length).map(item => this.createProxyForComponentValue(item, depth + 1));
457+
mappedArray.unshift(firstItem);
458+
return { value: mappedArray, hasProxies: true };
459+
}
460+
}
461+
} else if (typeof value === "object" && Object.entries(value).length && !(value instanceof Event)) {
462+
for (const [key, item] of Object.entries(value)) {
463+
if (!item) {
464+
value[key] = item;
465+
} else {
466+
const parsedItem = this.createProxyForComponentValue(item, depth + 1);
467+
value[key] = parsedItem.value;
468+
hasProxies = parsedItem.hasProxies || hasProxies;
469+
}
470+
}
471+
}
472+
473+
return { value, hasProxies };
474+
}
475+
476+
/** Create proxy for a component that handles setting template props, making sure it provides correct TemplateRef and not Lit template */
477+
protected createElementsComponentProxy(component: any, config: ComponentConfig) {
478+
const parentThis = this;
479+
return new Proxy(component, {
480+
set(target: any, prop: string, newValue: any) {
481+
// For now handle only template props
482+
if (config.templateProps.includes(prop)) {
483+
const oldRef = target[prop];
484+
const oldValue = oldRef && parentThis.templateWrapper.getTemplateFunction(oldRef);
485+
if (oldValue === newValue) {
486+
newValue = oldRef;
487+
} else {
488+
newValue = parentThis.templateWrapper.addTemplate(newValue);
489+
}
490+
}
491+
target[prop] = newValue;
492+
493+
return true;
494+
}
495+
});
496+
}
497+
//#endregion
408498
}
409499

410500
/**

projects/igniteui-angular-elements/src/index.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,9 @@ <h3 class="ig-typography__h6">Flat Grid (MRL column layout)</h3>
324324
<igc-pivot-grid id="pivotgrid1" default-expand-state="true" row-selection="single"></igc-pivot-grid>
325325

326326
<script src="assets/data/pivot-data.js"></script>
327-
<script>
327+
<script type="module">
328+
import { html, nothing } from "/lit-html.js";
329+
328330
document.addEventListener('DOMContentLoaded', () => {
329331
const clear = (el) => el === 0 || Boolean(el);
330332
pivotgrid1.pivotConfiguration = {
@@ -413,6 +415,10 @@ <h3 class="ig-typography__h6">Flat Grid (MRL column layout)</h3>
413415
};
414416
});
415417
pivotgrid1.data = pivotData;
418+
pivotgrid1.addEventListener("columnInit", (args) => {
419+
const col = args.detail;
420+
col.headerTemplate = (ctx) => html`<span>${col.field}_</span>`;
421+
});
416422
</script>
417423
<!-- END IgxPivotGridComponent -->
418424

projects/igniteui-angular/karma.conf.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ module.exports = function (config) {
1010
files: [
1111
{ pattern: '../../node_modules/hammerjs/hammer.min.js', watched: false },
1212
{ pattern: '../../node_modules/hammer-simulator/index.js', watched: false },
13-
{ pattern: './test.css', watched: false },
14-
{ pattern: '../../dist/igniteui-angular/styles/igniteui-angular.css', watched: false }
13+
{ pattern: './test.css', watched: false }
1514
],
1615
plugins: [
1716
'karma-parallel',

projects/igniteui-angular/karma.watch.conf.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ module.exports = function (config) {
88
files: [
99
{ pattern: '../../node_modules/hammerjs/hammer.min.js', watched: false },
1010
{ pattern: '../../node_modules/hammer-simulator/index.js', watched: false },
11-
{ pattern: './test.css', watched: false },
12-
{ pattern: '../../dist/igniteui-angular/styles/igniteui-angular.css', watched: false }
11+
{ pattern: './test.css', watched: false }
1312
],
1413
plugins: [
1514
'karma-jasmine',
6.01 KB
Loading

0 commit comments

Comments
 (0)