Skip to content

Commit 8c3cdb2

Browse files
committed
Merge branch '19.2.x' of https://github.com/IgniteUI/igniteui-angular into mkirkova/feat-combo-toggle-button-19.2.x
2 parents ce454bf + 9f7be75 commit 8c3cdb2

37 files changed

+863
-144
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes for each version of this project will be documented in this file.
44

5+
## 19.2.15
6+
### General
7+
- `IgxSimpleCombo`
8+
- Added `disableFiltering` to the `IgxSimpleCombo`, which enables/disables the filtering in the list. The default is `false`. With this introduction, `filteringOptions.filterable` is no longer used.
9+
- `IgxCombo`, `IgxSimpleCombo`
10+
- Removed deprecated `filteringOptions.filterable` option.
11+
512
## 19.2.0
613

714
### General

projects/igniteui-angular-elements/src/app/wrapper/template-ref-wrapper.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ElementRef, EmbeddedViewRef, Injector, TemplateRef } from '@angular/core';
2+
import { getUUID } from '../../../../igniteui-angular/src/lib/grids/common/random';
23

34
const CONTEXT_PROP = 'context';
45
const IMPLICIT_PROP = 'implicit';
@@ -71,7 +72,7 @@ export class TemplateRefWrapper<C extends object> extends TemplateRef<C> {
7172
root = viewRef.rootNodes[0];
7273

7374
contentContext = new TemplateRefWrapperContentContext();
74-
contentId = crypto.randomUUID();
75+
contentId = getUUID();
7576
contentContext._id = contentId;
7677
root._id = contentId;
7778
contentContext.root = root;

projects/igniteui-angular/migrations/migration-collection.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,11 @@
226226
"version": "19.2.0",
227227
"description": "Updates Ignite UI for Angular from v19.1.0 to v19.2.0",
228228
"factory": "./update-19_2_0"
229+
},
230+
"migration-46": {
231+
"version": "19.2.15",
232+
"description": "Updates Ignite UI for Angular from v19.2.0 to v19.2.15",
233+
"factory": "./update-19_2_15"
229234
}
230235
}
231236
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import * as path from 'path';
2+
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
3+
import { setupTestTree } from '../common/setup.spec';
4+
5+
describe('Migration 19.2.15 - Replace filteringOptions.filterable', () => {
6+
let appTree: UnitTestTree;
7+
const runner = new SchematicTestRunner(
8+
'ig-migrate',
9+
path.join(__dirname, '../migration-collection.json')
10+
);
11+
const migrationName = 'migration-46';
12+
const makeTemplate = (name: string) => `/testSrc/appPrefix/component/${name}.component.html`;
13+
const makeScript = (name: string) => `/testSrc/appPrefix/component/${name}.component.ts`;
14+
const components = ['igx-simple-combo', 'igx-combo'];
15+
16+
17+
18+
beforeEach(() => {
19+
appTree = setupTestTree();
20+
});
21+
22+
it('should replace simple inline filteringOptions.filterable true with default behavior of the simple combo', async () => {
23+
components.forEach(async component =>{
24+
const input = `<${component} [filteringOptions]="{ filterable: true }"></${component}>`;
25+
appTree.create(makeTemplate(`${component}-inline-true`), input);
26+
27+
const tree = await runner.runSchematic(migrationName, {}, appTree);
28+
const output = tree.readContent(makeTemplate(`${component}-inline-true`));
29+
30+
expect(output).not.toContain('[disableFiltering]');
31+
expect(output).not.toContain('filterable');
32+
});
33+
});
34+
35+
it('should handle mixed object literal correctly', async () => {
36+
components.forEach(async component =>{
37+
const input = `<${component} [filteringOptions]="{ filterable: false, caseSensitive: true }"></${component}>`;
38+
appTree.create(makeTemplate(`${component}-inline2`), input);
39+
40+
const tree = await runner.runSchematic(migrationName, {}, appTree);
41+
const output = tree.readContent(makeTemplate(`${component}-inline2`));
42+
43+
expect(output).toContain(`[disableFiltering]="true"`);
44+
expect(output).toContain(`[filteringOptions]="{ caseSensitive: true }"`);
45+
});
46+
});
47+
48+
it('should warn on variable reference', async () => {
49+
components.forEach(async component =>{
50+
const input = `<${component} [filteringOptions]="filterOpts""></${component}>`;
51+
const warnMsg = "Manual migration needed: please use 'disableFiltering' instead of filteringOptions.filterable." +
52+
"Since it has been deprecated.'";
53+
54+
appTree.create(makeTemplate(`${component}-referenceInTsFile`), input);
55+
56+
const tree = await runner.runSchematic(migrationName, {}, appTree);
57+
const output = tree.readContent(makeTemplate(`${component}-referenceInTsFile`));
58+
59+
expect(output).toContain('[filteringOptions]');
60+
expect(output).toContain(warnMsg);
61+
});
62+
});
63+
64+
it('should skip adding new [disableFiltering] if already present on igx-combo', async () => {
65+
const input = `<igx-combo [disableFiltering]="true" [filteringOptions]="{ filterable: false }"></igx-combo>`;
66+
appTree.create(makeTemplate('combo-has-disableFiltering'), input);
67+
68+
const tree = await runner.runSchematic(migrationName, {}, appTree);
69+
const output = tree.readContent(makeTemplate('combo-has-disableFiltering'));
70+
71+
const occurrences = (output.match(/\[disableFiltering\]/g) || []).length;
72+
73+
expect(occurrences).toBe(1);
74+
expect(output).not.toContain('filterable');
75+
});
76+
77+
// TS file tests
78+
79+
it('should insert warning comment before `.filteringOptions.filterable = ...` assignment', async () => {
80+
const input = `this.igxCombo.filteringOptions.filterable = false;`;
81+
const expectedComment = "// Manual migration needed: please use 'disableFiltering' instead of filteringOptions.filterable." +
82+
"Since it has been deprecated.'";
83+
84+
appTree.create(makeScript('tsWarnOnDirectAssignment'), input);
85+
86+
const tree = await runner.runSchematic(migrationName, {}, appTree);
87+
const output = tree.readContent(makeScript('tsWarnOnDirectAssignment'));
88+
89+
expect(output).toContain(expectedComment);
90+
expect(output).toContain('this.igxCombo.filteringOptions.filterable = false;');
91+
});
92+
93+
it('should insert warning comment before `.filteringOptions = { ... }` assignment', async () => {
94+
const input = `this.igxCombo.filteringOptions = { filterable: false, caseSensitive: true };`;
95+
const expectedComment = "// Manual migration needed: please use 'disableFiltering' instead of filteringOptions.filterable." +
96+
"Since it has been deprecated.'";
97+
98+
appTree.create(makeScript('tsWarnOnObjectAssignment'), input);
99+
100+
const tree = await runner.runSchematic(migrationName, {}, appTree);
101+
const output = tree.readContent(makeScript('tsWarnOnObjectAssignment'));
102+
103+
expect(output).toContain(expectedComment);
104+
expect(output).toContain('this.igxCombo.filteringOptions = { filterable: false, caseSensitive: true };');
105+
});
106+
107+
108+
});
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { Element } from '@angular/compiler';
2+
import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
3+
import { UpdateChanges } from '../common/UpdateChanges';
4+
import {
5+
FileChange,
6+
findElementNodes,
7+
getSourceOffset,
8+
parseFile
9+
} from '../common/util';
10+
import { nativeImport } from 'igniteui-angular/migrations/common/import-helper.js';
11+
12+
const version = '19.2.15';
13+
14+
export default (): Rule => async (host: Tree, context: SchematicContext) => {
15+
context.logger.info(
16+
`Applying migration for Ignite UI for Angular to version ${version}`
17+
);
18+
19+
const { HtmlParser } = await nativeImport('@angular/compiler') as typeof import('@angular/compiler');
20+
21+
const update = new UpdateChanges(__dirname, host, context);
22+
const changes = new Map<string, FileChange[]>();
23+
const parser = new HtmlParser();
24+
25+
const warnMsg = "Manual migration needed: please use 'disableFiltering' instead of filteringOptions.filterable." +
26+
"Since it has been deprecated.'";
27+
28+
const applyChanges = () => {
29+
for (const [path, fileChanges] of changes.entries()) {
30+
let content = host.read(path).toString();
31+
fileChanges.sort((a, b) => b.position - a.position).forEach(c => {
32+
content = c.apply(content);
33+
});
34+
host.overwrite(path, content);
35+
}
36+
};
37+
38+
const addChange = (path: string, change: FileChange) => {
39+
if (!changes.has(path)) {
40+
changes.set(path, []);
41+
}
42+
changes.get(path).push(change);
43+
};
44+
45+
const COMBO_TAGS = ['igx-simple-combo', 'igx-combo'];
46+
47+
for (const path of update.templateFiles) {
48+
const nodes = findElementNodes(parseFile(parser, host, path), COMBO_TAGS);
49+
50+
for (const node of nodes) {
51+
if (!(node instanceof Element)) continue;
52+
53+
const hasDisableFiltering = node.attrs.some(a => a.name.includes('disableFiltering'));
54+
const attr = node.attrs.find(a => a.name === '[filteringOptions]');
55+
if (!attr) continue;
56+
57+
const attrVal = attr.value.trim();
58+
const offset = getSourceOffset(node);
59+
const file = offset.file;
60+
61+
let replacementText = '';
62+
63+
if (attrVal.startsWith('{')) {
64+
// inline object literal
65+
const normalized = attrVal
66+
.replace(/'/g, '"')
67+
.replace(/([{,]\s*)(\w+)\s*:/g, '$1"$2":');
68+
const parsed = JSON.parse(normalized);
69+
const filterable = parsed.filterable;
70+
71+
if (filterable === false && !hasDisableFiltering) {
72+
replacementText += `[disableFiltering]="true"`;
73+
}
74+
75+
const remaining = { ...parsed };
76+
delete remaining.filterable;
77+
const remainingProps = Object.entries(remaining)
78+
.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)
79+
.join(', ');
80+
81+
if (remainingProps.length > 0) {
82+
replacementText += ` [filteringOptions]="{ ${remainingProps} }"`;
83+
}
84+
85+
// Replace whole [filteringOptions] attribute
86+
const match = node.sourceSpan.toString().match(/\[filteringOptions\]="([^"]+)"/);
87+
if (match) {
88+
const attrText = match[0];
89+
const attrPos = file.content.indexOf(attrText, offset.startTag.start);
90+
addChange(file.url, new FileChange(attrPos, replacementText, attrText, 'replace'));
91+
}
92+
} else {
93+
// log for manual TS edit
94+
const comment = `\n<!-- ${warnMsg} -->\n`;
95+
addChange(file.url, new FileChange(offset.startTag.end, comment));
96+
}
97+
}
98+
}
99+
100+
applyChanges();
101+
102+
for (const path of update.tsFiles) {
103+
const content = host.read(path).toString();
104+
const lines = content.split('\n');
105+
const newLines: string[] = [];
106+
107+
108+
let modified = false;
109+
110+
for (const line of lines) {
111+
if (
112+
/\.filteringOptions\.filterable\s*=/.test(line) ||
113+
/\.filteringOptions\s*=/.test(line)
114+
) {
115+
newLines.push('// ' + warnMsg);
116+
modified = true;
117+
}
118+
newLines.push(line);
119+
}
120+
121+
if (modified) {
122+
host.overwrite(path, newLines.join('\n'));
123+
}
124+
}
125+
126+
update.applyChanges();
127+
};

projects/igniteui-angular/src/lib/combo/combo.common.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,6 @@ export const enum DataTypes {
9595
export interface IComboFilteringOptions {
9696
/** Defines filtering case-sensitivity */
9797
caseSensitive?: boolean;
98-
/**
99-
* Defines whether filtering is allowed
100-
* @deprecated in version 18.2.0. Use the `disableFiltering` property instead.
101-
*/
102-
filterable?: boolean;
10398
/** Defines optional key to filter against complex list items. Default to displayKey if provided.*/
10499
filteringKey?: string;
105100
}
@@ -123,6 +118,18 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh
123118
@Input({ transform: booleanAttribute })
124119
public showSearchCaseIcon = false;
125120

121+
/**
122+
* Enables/disables filtering in the list. The default is `false`.
123+
*/
124+
@Input({ transform: booleanAttribute })
125+
public get disableFiltering(): boolean {
126+
return this._disableFiltering;
127+
}
128+
public set disableFiltering(value: boolean) {
129+
this._disableFiltering = value;
130+
}
131+
132+
126133
/**
127134
* Set custom overlay settings that control how the combo's list of items is displayed.
128135
* Set:
@@ -945,6 +952,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh
945952
protected computedStyles;
946953

947954
private _id: string = `igx-combo-${NEXT_ID++}`;
955+
private _disableFiltering = false;
948956
private _type = null;
949957
private _dataType = '';
950958
private _itemHeight = undefined;

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,6 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
128128
@Input({ transform: booleanAttribute })
129129
public autoFocusSearch = true;
130130

131-
/**
132-
* Enables/disables filtering in the list. The default is `false`.
133-
*/
134-
@Input({ transform: booleanAttribute })
135-
public get disableFiltering(): boolean {
136-
return this._disableFiltering || this.filteringOptions.filterable === false;
137-
}
138-
public set disableFiltering(value: boolean) {
139-
this._disableFiltering = value;
140-
}
141-
142131
/**
143132
* Defines the placeholder value for the combo dropdown search field
144133
*
@@ -184,7 +173,6 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
184173
protected _prevInputValue = '';
185174

186175
private _displayText: string;
187-
private _disableFiltering = false;
188176

189177
constructor(
190178
elementRef: ElementRef,

projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,8 @@
660660
inner-size: $inner-size,
661661
theme: map.get($schema, '_meta', 'theme'),
662662
_meta: map.merge(if($meta, $meta, ()), (
663-
variant: map.get($schema, '_meta', 'theme')
663+
variant: map.get($schema, '_meta', 'theme'),
664+
theme-variant: map.get($schema, '_meta', 'variant')
664665
)),
665666
));
666667
}

projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
/// @param {Map} $theme - The calendar theme used to style the component.
1515
@mixin date-picker($theme) {
1616
$variant: map.get($theme, '_meta', 'variant');
17+
$theme-variant: map.get($theme, '_meta', 'theme-variant');
1718
$bootstrap-theme: $variant == 'bootstrap';
1819
$border-shadow: 0 0 0 rem(1px) var-get($theme, 'border-color');
1920

@@ -26,11 +27,17 @@
2627

2728
%date-picker {
2829
// TODO move the shadow in the schemas
29-
box-shadow: $border-shadow, elevation(24),;
30+
box-shadow: $border-shadow, elevation(24);
3031
border-radius: var-get($theme, 'border-radius');
3132
background: var-get($theme, 'content-background');
3233
overflow: hidden;
3334

35+
@if $variant == 'indigo' and $theme-variant == 'light' {
36+
box-shadow: $border-shadow, elevation(5);
37+
} @else if $variant == 'indigo' and $theme-variant == 'dark' {
38+
box-shadow: $border-shadow, elevation(7);
39+
}
40+
3441
igx-calendar,
3542
%days-view,
3643
%months-view,

0 commit comments

Comments
 (0)