Skip to content

Commit 423b797

Browse files
authored
Merge pull request #13905 from IgniteUI/mkirova/optional-hammer-time
Make HammerJs optional.
2 parents 8ba4a32 + 0588fb3 commit 423b797

File tree

20 files changed

+175
-56
lines changed

20 files changed

+175
-56
lines changed

.vscode/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
{
88
"type": "node",
99
"request": "launch",
10-
"name": "Launch Node migration tests",
10+
"name": "Launch Node schematics tests",
1111
"args": [
1212
"-r",
1313
"ts-node/register",
1414
"./node_modules/jasmine/bin/jasmine.js",
15+
"./projects/igniteui-angular/schematics/**/*.spec.ts",
1516
"./projects/igniteui-angular/migrations/**/*.spec.ts"
1617
],
1718
"env": {

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ All notable changes for each version of this project will be documented in this
4545
- `rowID` property has been deprecated in the following interfaces: `IGridEditDoneEventArgs`, `IPathSegment`, `IRowToggleEventArgs`, `IPinRowEventArgs`, `IgxAddRowParent` and will be removed in a future version. Use `rowKey` instead.
4646
- `primaryKey` property has been deprecated in the following interfaces: `IRowDataEventArgs`, `IGridEditDoneEventArgs`. Use `rowKey` instead.
4747
- `data` property has been deprecated in the following interfaces: `IRowDataEventArgs`. Use `rowData` instead.
48+
- HammerJS is now an optional dependency, which means apps no longer need to install and include it for related components to work. Touch-specific handling on some components is still dependent on HammerJS setup, but will be disabled without. The setup is now also an option when adding Ignite UI for Angular to existing projects via the `ng add` command.
4849

4950
## 17.0.0
5051
### General

angular.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
"main": "./src/main.ts",
2222
"index": "src/index.html",
2323
"polyfills": [
24-
"zone.js",
25-
"hammerjs"
24+
"zone.js"
2625
],
2726
"tsConfig": "src/tsconfig.app.json",
2827
"assets": [

package-lock.json

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

package.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,15 @@
6161
"@angular/compiler": "^17.2.1",
6262
"@angular/core": "^17.2.1",
6363
"@angular/forms": "^17.2.1",
64-
"@angular/platform-browser": "^17.2.1",
6564
"@angular/platform-browser-dynamic": "^17.2.1",
65+
"@angular/platform-browser": "^17.2.1",
6666
"@angular/platform-server": "^17.2.1",
6767
"@angular/router": "^17.2.1",
6868
"@angular/ssr": "^17.2.0",
6969
"@igniteui/material-icons-extended": "^3.0.0",
70-
"@types/hammerjs": "^2.0.40",
7170
"@types/source-map": "0.5.2",
7271
"express": "^4.18.2",
7372
"fflate": "^0.8.1",
74-
"hammerjs": "^2.0.8",
7573
"igniteui-theming": "^4.4.0",
7674
"igniteui-trial-watermark": "^3.0.2",
7775
"lodash-es": "^4.17.21",
@@ -84,8 +82,8 @@
8482
"@angular-devkit/build-angular": "^17.2.0",
8583
"@angular-devkit/schematics": "^17.2.0",
8684
"@angular-eslint/builder": "^17.2.1",
87-
"@angular-eslint/eslint-plugin": "^17.2.1",
8885
"@angular-eslint/eslint-plugin-template": "^17.2.1",
86+
"@angular-eslint/eslint-plugin": "^17.2.1",
8987
"@angular-eslint/schematics": "^17.2.1",
9088
"@angular-eslint/template-parser": "^17.2.1",
9189
"@angular/cli": "^17.2.0",
@@ -94,6 +92,7 @@
9492
"@angularclass/hmr": "^3.0.0",
9593
"@types/estree": "^1.0.0",
9694
"@types/express": "^4.17.17",
95+
"@types/hammerjs": "^2.0.40",
9796
"@types/jasmine": "^5.1.1",
9897
"@types/jasminewd2": "^2.0.10",
9998
"@types/node": "^20.8.9",
@@ -106,38 +105,39 @@
106105
"eslint": "^8.53.0",
107106
"fs-extra": "^11.1.1",
108107
"globby": "^13.2.2",
109-
"gulp": "^4.0.2",
110108
"gulp-cached": "^1.1.1",
111109
"gulp-concat": "^2.6.1",
112110
"gulp-shell": "^0.6.5",
113111
"gulp-typescript": "^5.0.1",
114112
"gulp-uglify": "^3.0.1",
113+
"gulp": "^4.0.2",
115114
"hammer-simulator": "0.0.1",
115+
"hammerjs": "^2.0.8",
116116
"ig-typedoc-theme": "^5.0.3",
117117
"igniteui-sassdoc-theme": "^1.2.3",
118118
"igniteui-webcomponents": "^4.7.0",
119-
"jasmine": "^5.1.0",
120119
"jasmine-core": "~5.1.2",
121-
"karma": "^6.4.2",
120+
"jasmine": "^5.1.0",
122121
"karma-chrome-launcher": "~3.2.0",
123122
"karma-coverage": "^2.0.3",
124123
"karma-jasmine": "~5.1.0",
125124
"karma-junit-reporter": "^2.0.1",
126125
"karma-parallel": "^0.3.1",
127126
"karma-spec-reporter": "^0.0.36",
127+
"karma": "^6.4.2",
128128
"ng-packagr": "^17.2.0",
129-
"postcss": "^8.4.31",
130129
"postcss-scss": "^4.0.6",
130+
"postcss": "^8.4.31",
131131
"puppeteer": "^22.0.0",
132132
"sass-embedded": "^1.69.1",
133133
"sass-true": "^6.0.1",
134-
"sassdoc": "^2.7.4",
135134
"sassdoc-plugin-localization": "^1.4.3",
136-
"stylelint": "^15.1.0",
135+
"sassdoc": "^2.7.4",
137136
"stylelint-scss": "^4.1.0",
137+
"stylelint": "^15.1.0",
138138
"ts-node": "^10.8.1",
139-
"typedoc": "^0.25.3",
140139
"typedoc-plugin-localization": "^3.0.3",
140+
"typedoc": "^0.25.3",
141141
"typescript": "5.2.2"
142142
}
143143
}

projects/igniteui-angular/package.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@
6969
"tree"
7070
],
7171
"dependencies": {
72-
"@types/hammerjs": "^2.0.40",
73-
"hammerjs": "^2.0.8",
7472
"fflate": "^0.8.1",
7573
"tslib": "^2.3.0",
7674
"igniteui-trial-watermark": "^3.0.2",
@@ -83,7 +81,17 @@
8381
"@angular/common": "17",
8482
"@angular/core": "17",
8583
"@angular/animations": "17",
86-
"@angular/forms": "17"
84+
"@angular/forms": "17",
85+
"hammerjs": "^2.0.8",
86+
"@types/hammerjs": "^2.0.40"
87+
},
88+
"peerDependenciesMeta": {
89+
"hammerjs": {
90+
"optional": true
91+
},
92+
"@types/hammerjs": {
93+
"optional": true
94+
}
8795
},
8896
"igxDevDependencies": {
8997
"@igniteui/angular-schematics": "~17.1.1316-rc.0"

projects/igniteui-angular/schematics/interfaces/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export interface Options {
22
[key: string]: any;
33
polyfills: boolean;
44
resetCss: boolean;
5+
addHammer: boolean;
56
}

projects/igniteui-angular/schematics/ng-add/index.spec.ts

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('ng-add schematics', () => {
7171
it('should add packages to package.json dependencies', async () => {
7272
const expectedDeps = DEPENDENCIES_MAP.filter(dep => dep.target === PackageTarget.REGULAR).map(dep => dep.name);
7373
const expectedDevDeps = DEPENDENCIES_MAP.filter(dep => dep.target === PackageTarget.DEV).map(dep => dep.name);
74-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
74+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
7575
const pkgJsonData = JSON.parse(tree.readContent('/package.json'));
7676
expect(pkgJsonData.dependencies).toBeTruthy();
7777
expect(pkgJsonData.devDependencies).toBeTruthy();
@@ -90,38 +90,60 @@ describe('ng-add schematics', () => {
9090
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
9191
const pkgJsonData = JSON.parse(tree.readContent('/package.json'));
9292
expect(pkgJsonData.dependencies['fflate']).toBeTruthy();
93+
// hammer is optional now.
94+
expect(pkgJsonData.dependencies['hammerjs']).toBeFalsy();
95+
});
96+
97+
it('should add hammerjs dependency to package.json dependencies if addHammer prompt is set.', async () => {
98+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
99+
const pkgJsonData = JSON.parse(tree.readContent('/package.json'));
100+
expect(pkgJsonData.dependencies['fflate']).toBeTruthy();
93101
expect(pkgJsonData.dependencies['hammerjs']).toBeTruthy();
94102
});
95103

96104
it('should NOT add hammer.js to the main.ts file', async () => {
97-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
105+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
98106
const mainTs = tree.read(`${sourceRoot}/main.ts`).toString();
99107
expect(mainTs).not.toContain('import \'hammerjs\';');
100108
});
101109

102110
it('should NOT add hammer.js to the test.ts file', async () => {
103-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
111+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
104112
const testTs = tree.read(`${sourceRoot}/test.ts`).toString();
105113
expect(testTs).not.toContain('import \'hammerjs\';');
106114
});
107115

108-
it('should add hammer.js in angular.json build options under scripts', async () => {
116+
// Hammer is optional now.
117+
it('should not add hammer.js in angular.json build options under scripts', async () => {
109118
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
110119
const ngJsonConfigResult = JSON.parse(tree.read('/angular.json').toString());
120+
expect(ngJsonConfigResult.projects.testProj.architect.build.options.scripts).not.toContain('./node_modules/hammerjs/hammer.min.js');
121+
});
122+
123+
it('should add hammer.js in angular.json build options under scripts if addHammer prompt is set.', async () => {
124+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
125+
const ngJsonConfigResult = JSON.parse(tree.read('/angular.json').toString());
111126
expect(ngJsonConfigResult.projects.testProj.architect.build.options.scripts).toContain('./node_modules/hammerjs/hammer.min.js');
112127
});
113128

114-
it('should add hammer.js in angular.json test options under scripts', async () => {
129+
// Hammer is optional now.
130+
it('should not add hammer.js in angular.json test options under scripts', async () => {
115131
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
116132
const ngJsonConfigResult = JSON.parse(tree.read('/angular.json').toString());
133+
expect(ngJsonConfigResult.projects.testProj.architect.test.options.scripts).not.toContain('./node_modules/hammerjs/hammer.min.js');
134+
});
135+
136+
it('should add hammer.js in angular.json test options under scripts if addHammer prompt is set.', async () => {
137+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
138+
const ngJsonConfigResult = JSON.parse(tree.read('/angular.json').toString());
117139
expect(ngJsonConfigResult.projects.testProj.architect.test.options.scripts).toContain('./node_modules/hammerjs/hammer.min.js');
118140
});
119141

120142
it('should NOT duplicate hammer.js if it exists in angular.json build options', async () => {
121143
const ngJsonConfig1 = JSON.parse(tree.read('/angular.json').toString());
122144
ngJsonConfig1.projects.testProj.architect.build.options.scripts.push('./node_modules/hammerjs/hammer.min.js');
123145
tree.overwrite('/angular.json', JSON.stringify(ngJsonConfig1));
124-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
146+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
125147

126148
const ngJsonConfigResult = JSON.parse(tree.read('/angular.json').toString());
127149
expect(ngJsonConfigResult.projects.testProj.architect.build.options.scripts.length).toBe(1);
@@ -132,7 +154,7 @@ describe('ng-add schematics', () => {
132154
const ngJsonConfig1 = JSON.parse(tree.read('/angular.json').toString());
133155
ngJsonConfig1.projects.testProj.architect.test.options.scripts.push('./node_modules/hammerjs/hammer.min.js');
134156
tree.overwrite('/angular.json', JSON.stringify(ngJsonConfig1));
135-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
157+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
136158

137159
const ngJsonConfigResult = JSON.parse(tree.read('/angular.json').toString());
138160
expect(ngJsonConfigResult.projects.testProj.architect.test.options.scripts.length).toBe(1);
@@ -143,7 +165,7 @@ describe('ng-add schematics', () => {
143165
const ngJsonConfig1 = JSON.parse(tree.read('/angular.json').toString());
144166
ngJsonConfig1.projects.testProj.architect.build.options.scripts.push('./node_modules/hammerjs/hammer.min.js');
145167
tree.overwrite('/angular.json', JSON.stringify(ngJsonConfig1));
146-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
168+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
147169

148170
const newContent = tree.read(`${sourceRoot}/main.ts`).toString();
149171
expect(newContent).toMatch('// test comment');
@@ -153,23 +175,30 @@ describe('ng-add schematics', () => {
153175
const ngJsonConfig1 = JSON.parse(tree.read('/angular.json').toString());
154176
ngJsonConfig1.projects.testProj.architect.test.options.scripts.push('./node_modules/hammerjs/hammer.min.js');
155177
tree.overwrite('/angular.json', JSON.stringify(ngJsonConfig1));
156-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
178+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
157179

158180
const newContent = tree.read(`${sourceRoot}/test.ts`).toString();
159181
expect(newContent).toMatch('// test comment');
160182
});
161183

162-
it('should add hammer.js to package.json dependencies', async () => {
184+
// Hammer is optional now.
185+
it('should not add hammer.js to package.json dependencies', async () => {
163186
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
164187
const pkgJsonData = JSON.parse(tree.readContent('/package.json'));
188+
expect(pkgJsonData.dependencies['hammerjs']).toBeFalsy();
189+
});
190+
191+
it('should add hammer.js to package.json dependencies if addHammer prompt is set.', async () => {
192+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
193+
const pkgJsonData = JSON.parse(tree.readContent('/package.json'));
165194
expect(pkgJsonData.dependencies['hammerjs']).toBeTruthy();
166195
});
167196

168197
it('should NOT add hammer.js to angular.json if it exists in main.ts options', async () => {
169198
const mainTsPath = `${sourceRoot}/main.ts`;
170199
const content = tree.read(mainTsPath).toString();
171200
tree.overwrite(mainTsPath, 'import \'hammerjs\';\n' + content);
172-
await runner.runSchematic('ng-add', { normalizeCss: false }, tree);
201+
await runner.runSchematic('ng-add', { normalizeCss: false, addHammer: true }, tree);
173202

174203
const ngJsonConfigResult = JSON.parse(tree.read('/angular.json').toString());
175204
expect(ngJsonConfigResult.projects.testProj.architect.build.options.scripts.length).toBe(0);
@@ -231,4 +260,3 @@ describe('ng-add schematics', () => {
231260
});
232261

233262
});
234-

projects/igniteui-angular/schematics/ng-add/schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
"description": "Add reset CSS lib",
1010
"default": true,
1111
"x-prompt": "Add CSS library to reset HTML element styles across browsers?"
12+
},
13+
"addHammer": {
14+
"type": "boolean",
15+
"description": "Add HammerJS",
16+
"default": false,
17+
"x-prompt": "Add HammerJS setup for touch-specific interactions support?"
1218
}
1319
},
1420
"required": []

projects/igniteui-angular/schematics/utils/dependency-handler.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ const schematicsPackage = '@igniteui/angular-schematics';
2020
*/
2121
export const DEPENDENCIES_MAP: PackageEntry[] = [
2222
// dependencies
23-
{ name: 'hammerjs', target: PackageTarget.REGULAR },
2423
{ name: 'fflate', target: PackageTarget.REGULAR },
2524
{ name: 'tslib', target: PackageTarget.NONE },
26-
{ name: '@types/hammerjs', target: PackageTarget.DEV },
2725
{ name: 'igniteui-trial-watermark', target: PackageTarget.NONE },
2826
{ name: 'lodash-es', target: PackageTarget.NONE },
2927
{ name: 'uuid', target: PackageTarget.NONE },
3028
{ name: '@igniteui/material-icons-extended', target: PackageTarget.REGULAR },
29+
{ name: 'igniteui-theming', target: PackageTarget.NONE },
3130
// peerDependencies
3231
{ name: '@angular/forms', target: PackageTarget.NONE },
3332
{ name: '@angular/common', target: PackageTarget.NONE },
3433
{ name: '@angular/core', target: PackageTarget.NONE },
3534
{ name: '@angular/animations', target: PackageTarget.NONE },
36-
{ name: 'igniteui-theming', target: PackageTarget.NONE },
35+
{ name: 'hammerjs', target: PackageTarget.REGULAR },
36+
{ name: '@types/hammerjs', target: PackageTarget.DEV },
3737
// igxDevDependencies
3838
{ name: '@igniteui/angular-schematics', target: PackageTarget.DEV }
3939
];
@@ -97,7 +97,7 @@ export const addDependencies = (options: Options) => async (tree: Tree, context:
9797
const workspaceHost = createHost(tree);
9898
const { workspace } = await workspaces.readWorkspace(tree.root.path, workspaceHost);
9999

100-
await includeDependencies(workspaceHost, workspace, pkgJson, context, tree);
100+
await includeDependencies(workspaceHost, workspace, pkgJson, context, tree, options);
101101

102102
await includeStylePreprocessorOptions(workspaceHost, workspace, context, tree);
103103

@@ -192,9 +192,14 @@ const addStylePreprocessorOptions =
192192
}
193193
};
194194

195-
const includeDependencies = async (workspaceHost: workspaces.WorkspaceHost, workspace: workspaces.WorkspaceDefinition, pkgJson: any, context: SchematicContext, tree: Tree): Promise<void> => {
196-
for (const pkg of Object.keys(pkgJson.dependencies)) {
197-
const version = pkgJson.dependencies[pkg];
195+
const includeDependencies = async (workspaceHost: workspaces.WorkspaceHost, workspace: workspaces.WorkspaceDefinition, pkgJson: any, context: SchematicContext, tree: Tree, options: Options): Promise<void> => {
196+
const allDeps = Object.keys(pkgJson.dependencies).concat(Object.keys(pkgJson.peerDependencies));
197+
for (const pkg of allDeps) {
198+
// In case of hammerjs and user prompted to not add hammer, skip
199+
if (pkg === 'hammerjs' && !options.addHammer) {
200+
continue;
201+
}
202+
const version = pkgJson.dependencies[pkg] || pkgJson.peerDependencies[pkg];
198203
const entry = DEPENDENCIES_MAP.find(e => e.name === pkg);
199204
if (!entry || entry.target === PackageTarget.NONE) {
200205
continue;

0 commit comments

Comments
 (0)