-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(schematics): add shell schematic #9883
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Angular Material Schematics | ||
A collection of Schemaatics for Angular Material. | ||
|
||
## Collection | ||
- [Shell](shell/README.md) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,12 @@ | ||
// This is the root config file where the schematics are defined. | ||
{ | ||
"$schema": "./node_modules/@angular-devkit/schematics/collection-schema.json", | ||
"schematics": {} | ||
"schematics": { | ||
"materialShell": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI we're probably going to change this name at some point but it's still TBD There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding an alias for it gives this error: |
||
"description": "Create a Material shell", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you expand the description to something like "Adds Angular Material to an application without changing any templates"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the record, comments are technically not supported in JSON. ;P There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
"factory": "./shell/index", | ||
"schema": "./shell/schema.json", | ||
"aliases": [ "material-shell" ] | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Material Shell | ||
Adds Angular Material and its depedencies and pre-configures the application. | ||
|
||
It does the following: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could omit the "It does the following: " ; the list by itself is good |
||
|
||
- Adds Material and CDK to `package.json` | ||
- Adds Material Icons Stylesheet to `index.html` | ||
- Adds Roboto Font to `index.html` | ||
- Ensure `BrowserAnimationsModule` is installed and included in root module | ||
- Adds pre-configured theme to `.angular-cli.json` file | ||
|
||
Command: `ng generate material-shell --collection=material-schematics` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { | ||
Rule, | ||
SchematicContext, | ||
Tree, | ||
chain, | ||
noop, | ||
SchematicsException | ||
} from '@angular-devkit/schematics'; | ||
import {Schema} from './schema'; | ||
import {materialVersion, cdkVersion, angularVersion} from '../utils/lib-versions'; | ||
import {getConfig} from '../utils/devkit-utils/config'; | ||
import {addModuleImportToRootModule} from '../utils/ast'; | ||
import {addHeadLink} from '../utils/html'; | ||
import {addPackageToPackageJson} from '../utils/package'; | ||
|
||
/** | ||
* Scaffolds the basics of a Angular Material application, this includes: | ||
* - Add Packages to package.json | ||
* - Adds pre-built themes to styles.ext | ||
* - Adds Browser Animation to app.momdule | ||
*/ | ||
export default function(options: Schema): Rule { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you have to use a default export? These are generally strongly discouraged / banned inside Google (and these schematics will someday be used inside Google) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hansl - All of the schematics seem to use default exports (ref: https://github.com/angular/devkit/blob/master/packages/schematics/angular/app-shell/index.ts#L313). Thoughts on @jelbourn comment? |
||
return chain([ | ||
options && options.skipPackageJson ? noop() : addMaterialToPackageJson(options), | ||
addImportToStyles(options), | ||
addAnimationRootConfig(), | ||
addFontsToIndex() | ||
]); | ||
} | ||
|
||
/** | ||
* Add material, cdk, annimations to package.json | ||
*/ | ||
function addMaterialToPackageJson(options: Schema) { | ||
return (host: Tree) => { | ||
addPackageToPackageJson(host, 'dependencies', '@angular/cdk', cdkVersion); | ||
addPackageToPackageJson(host, 'dependencies', '@angular/material', materialVersion); | ||
addPackageToPackageJson(host, 'dependencies', '@angular/animations', angularVersion); | ||
return host; | ||
}; | ||
} | ||
|
||
/** | ||
* Add pre-built styles to style.ext file | ||
*/ | ||
function addImportToStyles(options: Schema) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return (host: Tree) => { | ||
const config = getConfig(host); | ||
config.apps.forEach(app => { | ||
const themeName = options && options.theme ? options.theme : 'indigo-pink'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about making it create a custom theme file by default? I believe that most people will want to customize the theme to one of the non-standard options, so it will be one less step when they want to swap it out. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ya, I'll add an option for custom theme :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jelbourn - Custom theme requires SCSS be enabled. If they don't have this do we want to configure it for them automatically? |
||
const themeSrc = `../node_modules/@angular/material/prebuilt-themes/${themeName}.css`; | ||
const hasCurrentTheme = app.styles.find((s: string) => s.indexOf(themeSrc) > -1); | ||
const hasOtherTheme = app.styles.find((s: string) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer breaking at the higher syntactic level: const hasOtherTheme =
app.styles.find((s: string) => s.indexOf('@angular/material/prebuilt-themes') > -1); |
||
s.indexOf('@angular/material/prebuilt-themes') > -1); | ||
|
||
if (!hasCurrentTheme && !hasOtherTheme) { | ||
app.styles.splice(0, 0, themeSrc); | ||
} | ||
|
||
if (hasOtherTheme) { | ||
throw new SchematicsException(`Another theme is already defined.`); | ||
} | ||
}); | ||
host.overwrite('.angular-cli.json', JSON.stringify(config, null, 2)); | ||
return host; | ||
}; | ||
} | ||
|
||
/** | ||
* Add browser animation module to app.module | ||
*/ | ||
function addAnimationRootConfig() { | ||
return (host: Tree) => { | ||
addModuleImportToRootModule(host, | ||
'BrowserAnimationsModule', '@angular/platform-browser/animations'); | ||
return host; | ||
}; | ||
} | ||
|
||
/** | ||
* Adds fonts to the index.ext file | ||
*/ | ||
function addFontsToIndex() { | ||
return (host: Tree) => { | ||
addHeadLink(host, | ||
`<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">`); | ||
addHeadLink(host, | ||
`<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">`); | ||
return host; | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import {Tree} from '@angular-devkit/schematics'; | ||
import {SchematicTestRunner} from '@angular-devkit/schematics/testing'; | ||
import {join} from 'path'; | ||
import {getFileContent} from '@schematics/angular/utility/test'; | ||
import {createTestApp} from '../utils/testing'; | ||
import {getConfig} from '@schematics/angular/utility/config'; | ||
import {getIndexHtmlPath} from '../utils/ast'; | ||
|
||
const collectionPath = join(__dirname, '../collection.json'); | ||
|
||
describe('material-shell-schematic', () => { | ||
let runner: SchematicTestRunner; | ||
let appTree: Tree; | ||
|
||
beforeEach(() => { | ||
appTree = createTestApp(); | ||
runner = new SchematicTestRunner('schematics', collectionPath); | ||
}); | ||
|
||
it('should update package.json', () => { | ||
const tree = runner.runSchematic('materialShell', {}, appTree); | ||
const packageJson = JSON.parse(getFileContent(tree, '/package.json')); | ||
|
||
expect(packageJson.dependencies['@angular/material']).toBeDefined(); | ||
expect(packageJson.dependencies['@angular/cdk']).toBeDefined(); | ||
}); | ||
|
||
it('should add default theme', () => { | ||
const tree = runner.runSchematic('materialShell', {}, appTree); | ||
const config = getConfig(tree); | ||
config.apps.forEach(app => { | ||
expect(app.styles).toContain( | ||
'../node_modules/@angular/material/prebuilt-themes/indigo-pink.css'); | ||
}); | ||
}); | ||
|
||
it('should add font links', () => { | ||
const tree = runner.runSchematic('materialShell', {}, appTree); | ||
const indexPath = getIndexHtmlPath(tree); | ||
const buffer = tree.read(indexPath); | ||
const indexSrc = buffer.toString(); | ||
expect(indexSrc.indexOf('fonts.googleapis.com')).toBeGreaterThan(-1); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Schemaatics
-> typo