Skip to content

Schematic improvements #11191

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 14 commits into from
Jun 11, 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
27 changes: 26 additions & 1 deletion src/lib/schematics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,29 @@
A collection of Schematics for Angular Material.

## Collection
- [Shell](shell/README.md)

### Install
Adds Angular Material and its depedencies and pre-configures the application.

- 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.json` file OR adds custom theme scaffolding to `styles.scss`

Command: `ng add @angular/material`

### Dashboard
Creates a responive card grid list component.

Command: `ng g @angular/material:dashboard my-dashboard`

### Nav
Creates a navigation component with a responsive sidenav.

Command: `ng g @angular/material:nav my-nav`

### Table
Creates a table component with sorting and paginator.

Command: `ng g @angular/material:table my-table`
19 changes: 9 additions & 10 deletions src/lib/schematics/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,30 @@
// Adds Angular Material to an application without changing any templates
"ng-add": {
"description": "Adds Angular Material to the application without affecting any templates",
"factory": "./shell",
"schema": "./shell/schema.json",
"aliases": ["material-shell"]
"factory": "./install",
"schema": "./install/schema.json",
"aliases": ["material-shell", "materialShell"]
},

// Create a dashboard component
"materialDashboard": {
"dashboard": {
Copy link
Member

Choose a reason for hiding this comment

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

We should keep the old name as an alias

"description": "Create a card-based dashboard component",
"factory": "./dashboard/index",
"schema": "./dashboard/schema.json",
"aliases": [ "material-dashboard" ]
"aliases": ["material-dashboard", "materialDashboard"]
},
// Creates a table component
"materialTable": {
"table": {
"description": "Create a component that displays data with a data-table",
"factory": "./table/index",
"schema": "./table/schema.json",
"aliases": [ "material-table" ]
"aliases": ["material-table", "materialTable"]
},
// Creates toolbar and navigation components
"materialNav": {
"nav": {
"description": "Create a component with a responsive sidenav for navigation",
"factory": "./nav/index",
"schema": "./nav/schema.json",
"aliases": [ "material-nav" ]
"aliases": ["material-nav", "materialNav"]
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Component<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection !== 'Default') { %>, ChangeDetectionStrategy<% }%> } from '@angular/core';
import { map } from 'rxjs/operators';
import { Breakpoints, BreakpointState, BreakpointObserver } from '@angular/cdk/layout';

@Component({
selector: '<%= selector %>',<% if(inlineTemplate) { %>
Expand Down Expand Up @@ -59,10 +61,26 @@ import { Component<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
export class <%= classify(name) %>Component {
cards = [
{ title: 'Card 1', cols: 2, rows: 1 },
{ title: 'Card 2', cols: 1, rows: 1 },
{ title: 'Card 3', cols: 1, rows: 2 },
{ title: 'Card 4', cols: 1, rows: 1 }
];
/** Based on the screen size, switch from standard to one column per row */
cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
Copy link
Member

Choose a reason for hiding this comment

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

The cols property of the grid-list itself should probably also change

map(({ matches }) => {
if (matches) {
return [
{ title: 'Card 1', cols: 1, rows: 1 },
{ title: 'Card 2', cols: 1, rows: 1 },
{ title: 'Card 3', cols: 1, rows: 1 },
{ title: 'Card 4', cols: 1, rows: 1 }
];
}

return [
{ title: 'Card 1', cols: 2, rows: 1 },
{ title: 'Card 2', cols: 1, rows: 1 },
{ title: 'Card 3', cols: 1, rows: 2 },
{ title: 'Card 4', cols: 1, rows: 1 }
];
})
);

constructor(private breakpointObserver: BreakpointObserver) {}
}
3 changes: 2 additions & 1 deletion src/lib/schematics/dashboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {addModuleImportToModule, findModuleFromOptions} from '../utils/ast';
import {buildComponent} from '../utils/devkit-utils/component';

/**
* Scaffolds a new navigation component.
* Scaffolds a new dashboard component.
* Internally it bootstraps the base component schematic
*/
export default function(options: Schema): Rule {
Expand All @@ -25,6 +25,7 @@ function addNavModulesToModule(options: Schema) {
addModuleImportToModule(host, modulePath, 'MatMenuModule', '@angular/material');
addModuleImportToModule(host, modulePath, 'MatIconModule', '@angular/material');
addModuleImportToModule(host, modulePath, 'MatButtonModule', '@angular/material');
addModuleImportToModule(host, modulePath, 'LayoutModule', '@angular/cdk/layout');
return host;
};
}
2 changes: 1 addition & 1 deletion src/lib/schematics/dashboard/index_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('material-dashboard-schematic', () => {
});

it('should create dashboard files and add them to module', () => {
const tree = runner.runSchematic('materialDashboard', { ...options }, createTestApp());
const tree = runner.runSchematic('dashboard', { ...options }, createTestApp());
const files = tree.files;

expect(files).toContain('/src/app/foo/foo.component.css');
Expand Down
9 changes: 5 additions & 4 deletions src/lib/schematics/dashboard/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
"project": {
"type": "string",
"description": "The name of the project.",
"visible": false
"visible": false,
"$default": {
"$source": "projectName"
}
},
"name": {
"type": "string",
Expand Down Expand Up @@ -90,7 +93,5 @@
"description": "Specifies if declaring module exports the component."
}
},
"required": [
"name"
]
"required": []
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {addModuleImportToRootModule, getStylesPath} from '../utils/ast';
import {InsertChange} from '../utils/devkit-utils/change';
import {getProjectFromWorkspace, getWorkspace} from '../utils/devkit-utils/config';
import {addHeadLink} from '../utils/html';
import {angularVersion, cdkVersion, materialVersion} from '../utils/lib-versions';
import {angularVersion, materialVersion} from '../utils/lib-versions';
import {addPackageToPackageJson} from '../utils/package';
import {Schema} from './schema';
import {addThemeToAppStyles} from './theming';
Expand All @@ -29,7 +29,7 @@ export default function(options: Schema): Rule {
/** Add material, cdk, annimations to package.json if not already present. */
function addMaterialToPackageJson() {
return (host: Tree, context: SchematicContext) => {
addPackageToPackageJson(host, 'dependencies', '@angular/cdk', cdkVersion);
addPackageToPackageJson(host, 'dependencies', '@angular/cdk', materialVersion);
addPackageToPackageJson(host, 'dependencies', '@angular/material', materialVersion);
addPackageToPackageJson(host, 'dependencies', '@angular/animations', angularVersion);
context.addTask(new NodePackageInstallTask());
Expand Down Expand Up @@ -80,7 +80,8 @@ function addBodyMarginToStyles(options: Schema) {
const buffer = host.read(stylesPath);
if (buffer) {
const src = buffer.toString();
const insertion = new InsertChange(stylesPath, src.length, `\nbody { margin: 0; }\n`);
const insertion = new InsertChange(stylesPath, src.length,
`\nhtml, body { height: 100%; }\nbody { margin: 0; font-family: 'Roboto', sans-serif; }\n`);
const recorder = host.beginUpdate(stylesPath);
recorder.insertLeft(insertion.pos, insertion.toAdd);
host.commitUpdate(recorder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ describe('material-shell-schematic', () => {
});

it('should update package.json', () => {
const tree = runner.runSchematic('materialShell', {}, appTree);
const tree = runner.runSchematic('install', {}, 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 tree = runner.runSchematic('shell', {}, appTree);
const config: any = getConfig(tree);
config.apps.forEach(app => {
expect(app.styles).toContain(
Expand All @@ -37,7 +37,7 @@ describe('material-shell-schematic', () => {
});

it('should add custom theme', () => {
const tree = runner.runSchematic('materialShell', {
const tree = runner.runSchematic('install', {
theme: 'custom'
}, appTree);

Expand All @@ -53,7 +53,7 @@ describe('material-shell-schematic', () => {
});

it('should add font links', () => {
const tree = runner.runSchematic('materialShell', {}, appTree);
const tree = runner.runSchematic('install', {}, appTree);
const config: any = getConfig(tree);
const workspace = getWorkspace(tree);
const project = getProjectFromWorkspace(workspace, config.project.name);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "http://json-schema.org/schema",
"id": "SchematicsMaterialShell",
"title": "Material Shell Options Schema",
"id": "SchematicsMaterialInstall",
"title": "Material Install Options Schema",
"type": "object",
"properties": {
"skipPackageJson": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@

.sidenav {
width: 200px;
box-shadow: 3px 0 6px rgba(0,0,0,.24);
}

.mat-toolbar.mat-primary {
position: sticky;
Copy link
Member

Choose a reason for hiding this comment

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

Should we really be using position: sticky? The browser support isn't great and fixed should be able to get the job done for an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We actually use position sticky on the material docs site. Supports seems decent just missing IE11.

top: 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
*ngIf="isHandset$ | async">
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>
<span>Application Title</span>
<span><%= project %></span>
</mat-toolbar>
<!-- Add Content Here -->
</mat-sidenav-content>
</mat-sidenav-container>
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ import { map } from 'rxjs/operators';
*ngIf="isHandset$ | async">
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>
<span>Application Title</span>
<span><%= project %></span>
</mat-toolbar>
<!-- Add Content Here -->
</mat-sidenav-content>
</mat-sidenav-container>
`,<% } else { %>
Expand All @@ -45,7 +46,11 @@ import { map } from 'rxjs/operators';

.sidenav {
width: 200px;
box-shadow: 3px 0 6px rgba(0,0,0,.24);
}

.mat-toolbar.mat-primary {
position: sticky;
top: 0;
}
`
]<% } else { %>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/schematics/nav/index_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('material-nav-schematic', () => {
});

it('should create nav files and add them to module', () => {
const tree = runner.runSchematic('materialNav', { ...options }, createTestApp());
const tree = runner.runSchematic('nav', { ...options }, createTestApp());
const files = tree.files;

expect(files).toContain('/src/app/foo/foo.component.css');
Expand All @@ -42,7 +42,7 @@ describe('material-nav-schematic', () => {
});

it('should add nav imports to module', () => {
const tree = runner.runSchematic('materialNav', { ...options }, createTestApp());
const tree = runner.runSchematic('nav', { ...options }, createTestApp());
const moduleContent = getFileContent(tree, '/src/app/app.module.ts');

expect(moduleContent).toContain('LayoutModule');
Expand Down
9 changes: 5 additions & 4 deletions src/lib/schematics/nav/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
"project": {
"type": "string",
"description": "The name of the project.",
"visible": false
"visible": false,
"$default": {
"$source": "projectName"
}
},
"name": {
"type": "string",
Expand Down Expand Up @@ -90,7 +93,5 @@
"description": "Specifies if declaring module exports the component."
}
},
"required": [
"name"
]
"required": []
}
10 changes: 0 additions & 10 deletions src/lib/schematics/shell/README.md

This file was deleted.

5 changes: 0 additions & 5 deletions src/lib/schematics/table/README.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
<div class="mat-elevation-z8">
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">

<table mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
Copy link
Member

Choose a reason for hiding this comment

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

Didn't @andrewseguin already change this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

He changed the one in the component, not the one in the html file.

<!-- Id Column -->
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header>Id</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.id}}</mat-cell>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Id</th>
<td mat-cell *matCellDef="let row">{{row.id}}</td>
</ng-container>

<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
<td mat-cell *matCellDef="let row">{{row.name}}</td>
</ng-container>

<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

<mat-paginator #paginator
[length]="dataSource.data.length"
Expand Down
4 changes: 2 additions & 2 deletions src/lib/schematics/table/index_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('material-table-schematic', () => {
});

it('should create table files and add them to module', () => {
const tree = runner.runSchematic('materialTable', { ...options }, createTestApp());
const tree = runner.runSchematic('table', { ...options }, createTestApp());
const files = tree.files;

expect(files).toContain('/src/app/foo/foo.component.css');
Expand All @@ -50,7 +50,7 @@ describe('material-table-schematic', () => {
});

it('should add table imports to module', () => {
const tree = runner.runSchematic('materialTable', { ...options }, createTestApp());
const tree = runner.runSchematic('table', { ...options }, createTestApp());
const moduleContent = getFileContent(tree, '/src/app/app.module.ts');

expect(moduleContent).toContain('MatTableModule');
Expand Down
Loading