mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(ng-add): set up gestures in CLI projects (#12734)
Introduces a new option for the `ng-add` schematic that enables automatic set up of HammerJS in the CLI project. By default, gestures will be set up if someone runs `ng add @angular/material`.
This commit is contained in:
committed by
Jeremy Elbourn
parent
dad0ed0a6a
commit
b919a48643
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
@@ -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.');
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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:
|
||||
@@ -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),
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
"enum": ["indigo-pink", "deeppurple-amber", "pink-bluegrey", "purple-green", "custom"],
|
||||
"default": "indigo-pink",
|
||||
"description": "The theme to apply"
|
||||
},
|
||||
"gestures": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Whether gesture support should be set up or not."
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user