Skip to content

feat(ng-add): set up gestures in CLI projects #12734

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion guides/schematics.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This schematic will:
- Add Prebuilt or Setup Custom Theme
- Add Roboto fonts to your index.html
- Apply simple CSS reset to body

- Install and load `hammerjs` for gestures in your project.

## Generator Schematics
In addition to the install schematic, Angular Material has three schematics it comes packaged with:
Expand Down
41 changes: 41 additions & 0 deletions src/lib/schematics/install/gestures/hammerjs-import.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Rule, Tree} from '@angular-devkit/schematics';
import {getWorkspace} from '@schematics/angular/utility/config';
import {getProjectFromWorkspace} from '../../utils/get-project';
import {Schema} from '../schema';
import {getProjectMainFile} from './project-main-file';

const hammerjsImportStatement = `import 'hammerjs';`;

/** Adds HammerJS to the main file of the specified Angular CLI project. */
export function addHammerJsToMain(options: Schema): Rule {
return (host: Tree) => {
const workspace = getWorkspace(host);
const project = getProjectFromWorkspace(workspace, options.project);
const mainFile = getProjectMainFile(project);

const recorder = host.beginUpdate(mainFile);
const buffer = host.read(mainFile);

if (!buffer) {
return console.error(`Could not read the project main file (${mainFile}). Please manually ` +
`import HammerJS in your main TypeScript file.`);
}

const fileContent = buffer.toString('utf8');

if (fileContent.includes(hammerjsImportStatement)) {
return console.log(`HammerJS is already imported in the project main file (${mainFile}).`);
}

recorder.insertRight(0, `${hammerjsImportStatement}\n`);
host.commitUpdate(recorder);
};
}
22 changes: 22 additions & 0 deletions src/lib/schematics/install/gestures/project-main-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {SchematicsException} from '@angular-devkit/schematics';
import {WorkspaceProject} from '@schematics/angular/utility/config';

/** Looks for the main TypeScript file in the given project and returns its path. */
export function getProjectMainFile(project: WorkspaceProject): string {
const buildTarget = project.architect.build.options;

if (buildTarget.main) {
return buildTarget.main;
}

throw new SchematicsException(
'Could not find the project main file inside of the workspace config.');
}
28 changes: 28 additions & 0 deletions src/lib/schematics/install/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,19 @@ describe('material-install-schematic', () => {

expect(packageJson.dependencies['@angular/material']).toBeDefined();
expect(packageJson.dependencies['@angular/cdk']).toBeDefined();
expect(packageJson.dependencies['hammerjs']).toBeDefined();
expect(packageJson.dependencies['@angular/animations']).toBe(angularCoreVersion,
'Expected the @angular/animations package to have the same version as @angular/core.');
});

it('should add hammerjs import to project main file', () => {
const tree = runner.runSchematic('ng-add', {}, appTree);
const fileContent = getFileContent(tree, '/projects/material/src/main.ts');

expect(fileContent).toContain(`import 'hammerjs';`,
'Expected the project main file to contain a HammerJS import.');
});

it('should add default theme', () => {
const tree = runner.runSchematic('ng-add', {}, appTree);

Expand Down Expand Up @@ -106,4 +115,23 @@ describe('material-install-schematic', () => {
expect(htmlContent).toContain(
'body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }');
});

describe('gestures disabled', () => {

it('should not add hammerjs to package.json', () => {
const tree = runner.runSchematic('ng-add', {gestures: false}, appTree);
const packageJson = JSON.parse(getFileContent(tree, '/package.json'));

expect(packageJson.dependencies['hammerjs'])
.toBeUndefined(`Expected 'hammerjs' to be not added to the package.json`);
});

it('should not add hammerjs import to project main file', () => {
const tree = runner.runSchematic('ng-add', {gestures: false}, appTree);
const fileContent = getFileContent(tree, '/projects/material/src/main.ts');

expect(fileContent).not.toContain(`import 'hammerjs';`,
'Expected the project main file to not contain a HammerJS import.');
});
});
});
12 changes: 9 additions & 3 deletions src/lib/schematics/install/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import {getProjectFromWorkspace} from '../utils/get-project';
import {addPackageToPackageJson, getPackageVersionFromPackageJson} from '../utils/package-json';
import {getProjectStyleFile} from '../utils/project-style-file';
import {addFontsToIndex} from './fonts/material-fonts';
import {addHammerJsToMain} from './gestures/hammerjs-import';
import {Schema} from './schema';
import {addThemeToAppStyles} from './theming/theming';
import {materialVersion, requiredAngularVersionRange} from './version-names';
import {hammerjsVersion, materialVersion, requiredAngularVersionRange} from './version-names';

/**
* Scaffolds the basics of a Angular Material application, this includes:
Expand All @@ -39,7 +40,8 @@ export default function(options: Schema): Rule {
}

return chain([
options && options.skipPackageJson ? noop() : addMaterialToPackageJson(),
options && options.skipPackageJson ? noop() : addMaterialToPackageJson(options),
options && options.gestures ? addHammerJsToMain(options) : noop(),
addThemeToAppStyles(options),
addAnimationRootConfig(options),
addFontsToIndex(options),
Expand All @@ -48,7 +50,7 @@ export default function(options: Schema): Rule {
}

/** Add material, cdk, animations to package.json if not already present. */
function addMaterialToPackageJson() {
function addMaterialToPackageJson(options: Schema) {
return (host: Tree, context: SchematicContext) => {
// Version tag of the `@angular/core` dependency that has been loaded from the `package.json`
// of the CLI project. This tag should be preferred because all Angular dependencies should
Expand All @@ -60,6 +62,10 @@ function addMaterialToPackageJson() {
addPackageToPackageJson(host, 'dependencies', '@angular/animations',
ngCoreVersionTag || requiredAngularVersionRange);

if (options.gestures) {
addPackageToPackageJson(host, 'dependencies', 'hammerjs', hammerjsVersion);
}

context.addTask(new NodePackageInstallTask());

return host;
Expand Down
5 changes: 5 additions & 0 deletions src/lib/schematics/install/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
"enum": ["indigo-pink", "deeppurple-amber", "pink-bluegrey", "purple-green", "custom"],
"default": "indigo-pink",
"description": "The theme to apply"
},
"gestures": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document this in schematics.md?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added it to the bullet-points. Note that the schematics.md file is kind of outdated (misses the tree schematic etc.).

I want to improve that guide soon and also mention the different options for disabling gestures, creating a custom theme and more -- So there will be a follow-up.

"type": "boolean",
"default": true,
"description": "Whether gesture support should be set up or not."
}
},
"required": []
Expand Down
3 changes: 3 additions & 0 deletions src/lib/schematics/install/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export interface Schema {
/** Whether to skip package.json install. */
skipPackageJson: boolean;

/** Whether gesture support should be set up or not. */
gestures: boolean;

/** Name of pre-built theme to install. */
theme: 'indigo-pink' | 'deeppurple-amber' | 'pink-bluegrey' | 'purple-green' | 'custom';

Expand Down
3 changes: 3 additions & 0 deletions src/lib/schematics/install/version-names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export const materialVersion =
*/
export const requiredAngularVersionRange = '0.0.0-NG';

/** HammerJS version that should be installed if gestures will be set up. */
export const hammerjsVersion = '^2.0.8';

/** Loads the full version from the given Angular package gracefully. */
function loadPackageVersionGracefully(packageName: string): string | null {
try {
Expand Down