diff --git a/docs/schematics.en-US.md b/docs/schematics.en-US.md
index 30557180c5..473801eaf5 100644
--- a/docs/schematics.en-US.md
+++ b/docs/schematics.en-US.md
@@ -8,6 +8,12 @@ title: Schematics
Init project with `ng-zorro-antd`.
+Run `ng add ng-zorro-antd` in your project directory, and follow the options to configure.
+
+
+
+You can choose a preset template to create your project, then develop on this basis code.
+
### Command
```bash
@@ -51,54 +57,3 @@ For example, you can generate an login form with the follow command.
```bash
ng g ng-zorro-antd:form-normal-login login
```
-
-### Options
-
-***--entry-component***
-
-Specifies if the component is an entry component of declaring module.
-
-***--export***
-
-Specifies if declaring module exports the component.
-
-***--flat***
-
-Flag to indicate if a dir is created.
-
-***--inline-style (-s)***
-
-Specifies if the style will be in the ts file.
-
-***--inline-template (-t)***
-
-Specifies if the template will be in the ts file.
-
-***--module (-m)***
-
-Allows specification of the declaring module.
-
-***--prefix (-p)***
-
-The prefix to apply to generated selectors.
-
-***--project***
-
-The name of the project.
-
-***--selector***
-
-The selector to use for the component.
-
-***--skip-import***
-
-Flag to skip the module import.
-
-***--spec***
-
-Specifies if a spec file is generated.
-
-***--styleext***
-
-The file extension to be used for style files.
-
diff --git a/docs/schematics.zh-CN.md b/docs/schematics.zh-CN.md
index 465b9290a3..a16f8fbe34 100644
--- a/docs/schematics.zh-CN.md
+++ b/docs/schematics.zh-CN.md
@@ -7,35 +7,13 @@ title: 脚手架
## 项目初始化
-自动完成 `ng-zorro-antd` 的初始化配置,包括引入国际化文件,导入模块,引入样式文件等工作。
+在项目下运行命令 `ng add ng-zorro-antd` 跟随选项便可完成初始化配置,包括引入国际化文件,导入模块,引入样式文件等工作。
-### 命令
-
-```bash
-ng add ng-zorro-antd [options]
-```
-
-### 参数
-
-***--theme***
-
-`ng-zorro-antd` 会在 `src` 目录下生成 `theme.less` 的主题配置文件
-
-详细的配置可以在[自定义主题](/docs/customize-theme/zh)中查看。
-
-***--locale***
-
-初始化配置时增加 `--locale=[语言]` 参数,`ng-zorro-antd` 会自动引入支持的语言包以及 Angular 对应的 [i18n 文件](https://angular.io/guide/i18n)
+
-默认的国际化配置为中文(zh_CN),详细的可配置选项可以在[国际化](/docs/i18n/zh)中查看。
+同时你可以通过选择预设的模板创建一个 Angular 项目,并在此基础上进行开发。
-***--animations***
-
-启用 `BrowserAnimationsModule`
-
-***--gestures***
-
-安装 `hammerjs` 并引入为项目添加手势支持
+
## 生成组件
@@ -52,53 +30,3 @@ ng g ng-zorro-antd:[schematic] [options]
```bash
ng g ng-zorro-antd:form-normal-login login
```
-
-### 参数
-
-***--entry-component***
-
-组件是否在模块的 `entryComponents` 声明
-
-***--export***
-
-组件是否在模块的 `exports` 声明
-
-***--flat***
-
-指定是否创建目录
-
-***--inline-style (-s)***
-
-指定是否使用行内样式
-
-***--inline-template (-t)***
-
-指定是否使用行内模版
-
-***--module (-m)***
-
-指定声明的模块
-
-***--prefix (-p)***
-
-组件选择器前缀
-
-***--project***
-
-指定声明到的项目名
-
-***--selector***
-
-组件的选择器名称
-
-***--skip-import***
-
-指定是否跳过模块引入
-
-***--spec***
-
-指定是否生成 `.spec` 测试文件
-
-***--styleext***
-
-指定样式文件扩展名
diff --git a/schematics/collection.json b/schematics/collection.json
index 647f0d59d9..90fdcfd914 100644
--- a/schematics/collection.json
+++ b/schematics/collection.json
@@ -12,11 +12,21 @@
"factory": "./ng-add/setup-project/index",
"schema": "./ng-add/schema.json"
},
- "boot-page": {
+ "blank": {
"description": "Set up boot page",
"private": true,
- "factory": "./ng-generate/boot-page/index",
- "schema": "./ng-generate/boot-page/schema.json"
+ "factory": "./ng-generate/blank/index",
+ "schema": "./ng-generate/blank/schema.json"
+ },
+ "sidemenu": {
+ "description": "Add Sidebar Navigation Layout in your project.",
+ "factory": "./ng-generate/side-menu/index",
+ "schema": "./ng-generate/side-menu/schema.json"
+ },
+ "topnav": {
+ "description": "Add Top Navigation Layout in your project.",
+ "factory": "./ng-generate/topnav/index",
+ "schema": "./ng-generate/topnav/schema.json"
},
"add-icon-assets": {
"description": "Add icon assets into CLI config",
diff --git a/schematics/ng-add/index.ts b/schematics/ng-add/index.ts
index 38220ba8b8..5f5871ca52 100644
--- a/schematics/ng-add/index.ts
+++ b/schematics/ng-add/index.ts
@@ -17,8 +17,9 @@ export default function(options: Schema): Rule {
context.addTask(new RunSchematicTask('ng-add-setup-project', options), [installTaskId]);
- if (options.bootPage) {
- context.addTask(new RunSchematicTask('boot-page', options));
+ if (options.template) {
+ context.addTask(new RunSchematicTask(options.template, options));
}
+
};
}
diff --git a/schematics/ng-add/schema.json b/schematics/ng-add/schema.json
index e50b80035d..249ab1cbcb 100644
--- a/schematics/ng-add/schema.json
+++ b/schematics/ng-add/schema.json
@@ -16,11 +16,6 @@
"default": false,
"description": "Do not add ng-zorro-antd dependencies to package.json (e.g., --skipPackageJson)"
},
- "bootPage": {
- "type": "boolean",
- "default": true,
- "description": "Set up boot page."
- },
"dynamicIcon": {
"type": "boolean",
"default": false,
@@ -120,6 +115,19 @@
]
}
},
+ "template": {
+ "type": "string",
+ "default": "blank",
+ "description": "Create an Angular project with using preset template.",
+ "x-prompt": {
+ "message": "Choose template to create project:",
+ "type": "list",
+ "items": [
+ "blank",
+ "sidemenu"
+ ]
+ }
+ },
"gestures": {
"type": "boolean",
"default": false,
diff --git a/schematics/ng-add/schema.ts b/schematics/ng-add/schema.ts
index 60866a76b5..e4afe720e8 100644
--- a/schematics/ng-add/schema.ts
+++ b/schematics/ng-add/schema.ts
@@ -35,8 +35,14 @@ export type Locale =
| 'zh_CN'
| 'zh_TW';
+export enum ProjectTemplate {
+ Blank = 'blank',
+ Sidemenu = 'sidemenu',
+ Topnav = 'topnav',
+ None = 'none'
+}
+
export interface Schema {
- bootPage?: boolean;
/** Name of the project to target. */
project?: string;
/** Whether to skip package.json install. */
@@ -47,4 +53,5 @@ export interface Schema {
animations?: boolean;
locale?: Locale;
i18n?: Locale;
+ template?: ProjectTemplate;
}
diff --git a/schematics/ng-generate/boot-page/index.ts b/schematics/ng-generate/blank/index.ts
similarity index 100%
rename from schematics/ng-generate/boot-page/index.ts
rename to schematics/ng-generate/blank/index.ts
diff --git a/schematics/ng-generate/boot-page/schema.json b/schematics/ng-generate/blank/schema.json
similarity index 100%
rename from schematics/ng-generate/boot-page/schema.json
rename to schematics/ng-generate/blank/schema.json
diff --git a/schematics/ng-generate/boot-page/schema.ts b/schematics/ng-generate/blank/schema.ts
similarity index 100%
rename from schematics/ng-generate/boot-page/schema.ts
rename to schematics/ng-generate/blank/schema.ts
diff --git a/schematics/ng-generate/side-menu/files/src/app/app-routing.module.ts.template b/schematics/ng-generate/side-menu/files/src/app/app-routing.module.ts.template
new file mode 100644
index 0000000000..29be260602
--- /dev/null
+++ b/schematics/ng-generate/side-menu/files/src/app/app-routing.module.ts.template
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [
+ { path: '', pathMatch: 'full', redirectTo: '/welcome' },
+ { path: 'welcome', loadChildren: () => import('./pages/welcome/welcome.module').then(m => m.WelcomeModule) }
+];
+
+@NgModule({
+ imports: [RouterModule.forRoot(routes)],
+ exports: [RouterModule]
+})
+export class AppRoutingModule { }
diff --git a/schematics/ng-generate/side-menu/files/src/app/app.component.__style__.template b/schematics/ng-generate/side-menu/files/src/app/app.component.__style__.template
new file mode 100644
index 0000000000..163c43a236
--- /dev/null
+++ b/schematics/ng-generate/side-menu/files/src/app/app.component.__style__.template
@@ -0,0 +1,80 @@
+:host {
+ display: flex;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.app-layout {
+ height: 100vh;
+}
+
+.menu-sidebar {
+ position: relative;
+ z-index: 10;
+ min-height: 100vh;
+ box-shadow: 2px 0 6px rgba(0,21,41,.35);
+}
+
+.header-trigger {
+ height: 64px;
+ padding: 20px 24px;
+ font-size: 20px;
+ cursor: pointer;
+ transition: all .3s,padding 0s;
+}
+
+.trigger:hover {
+ color: #1890ff;
+}
+
+.sidebar-logo {
+ position: relative;
+ height: 64px;
+ padding-left: 24px;
+ overflow: hidden;
+ line-height: 64px;
+ background: #001529;
+ transition: all .3s;
+}
+
+.sidebar-logo img {
+ display: inline-block;
+ height: 32px;
+ width: 32px;
+ vertical-align: middle;
+}
+
+.sidebar-logo h1 {
+ display: inline-block;
+ margin: 0 0 0 20px;
+ color: #fff;
+ font-weight: 600;
+ font-size: 14px;
+ font-family: Avenir,Helvetica Neue,Arial,Helvetica,sans-serif;
+ vertical-align: middle;
+}
+
+nz-header {
+ padding: 0;
+ width: 100%;
+ z-index: 2;
+}
+
+.app-header {
+ position: relative;
+ height: 64px;
+ padding: 0;
+ background: #fff;
+ box-shadow: 0 1px 4px rgba(0,21,41,.08);
+}
+
+nz-content {
+ margin: 24px;
+}
+
+.inner-content {
+ padding: 24px;
+ background: #fff;
+ height: 100%;
+}
diff --git a/schematics/ng-generate/side-menu/files/src/app/app.component.html.template b/schematics/ng-generate/side-menu/files/src/app/app.component.html.template
new file mode 100644
index 0000000000..014c586efe
--- /dev/null
+++ b/schematics/ng-generate/side-menu/files/src/app/app.component.html.template
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/schematics/ng-generate/side-menu/files/src/app/app.component.ts.template b/schematics/ng-generate/side-menu/files/src/app/app.component.ts.template
new file mode 100644
index 0000000000..98a4eedeee
--- /dev/null
+++ b/schematics/ng-generate/side-menu/files/src/app/app.component.ts.template
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: '<%= prefix %>-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.<%= style %>']
+})
+export class AppComponent {
+ isCollapsed = false;
+}
diff --git a/schematics/ng-generate/side-menu/files/src/app/icons-provider.module.ts.template b/schematics/ng-generate/side-menu/files/src/app/icons-provider.module.ts.template
new file mode 100644
index 0000000000..d48bbb024c
--- /dev/null
+++ b/schematics/ng-generate/side-menu/files/src/app/icons-provider.module.ts.template
@@ -0,0 +1,19 @@
+import { NgModule } from '@angular/core';
+import { NZ_ICONS } from 'ng-zorro-antd';
+
+import {
+ MenuFoldOutline,
+ MenuUnfoldOutline,
+ FormOutline,
+ DashboardOutline
+} from '@ant-design/icons-angular/icons';
+
+const icons = [MenuFoldOutline, MenuUnfoldOutline, DashboardOutline, FormOutline];
+
+@NgModule({
+ providers: [
+ { provide: NZ_ICONS, useValue: icons }
+ ]
+})
+export class IconsProviderModule {
+}
diff --git a/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.component.__style__.template b/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.component.__style__.template
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.component.html.template b/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.component.html.template
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.component.ts.template b/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.component.ts.template
new file mode 100644
index 0000000000..d33f473ee9
--- /dev/null
+++ b/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.component.ts.template
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: '<%= prefix %>-welcome',
+ templateUrl: './welcome.component.html',
+ styleUrls: ['./welcome.component.<%= style %>']
+})
+export class WelcomeComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.module.ts.template b/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.module.ts.template
new file mode 100644
index 0000000000..95381f5bba
--- /dev/null
+++ b/schematics/ng-generate/side-menu/files/src/app/pages/welcome/welcome.module.ts.template
@@ -0,0 +1,8 @@
+import { NgModule } from '@angular/core';
+import { WelcomeComponent } from './welcome.component';
+
+@NgModule({
+ declarations: [ WelcomeComponent ],
+ exports: [ WelcomeComponent ]
+})
+export class WelcomeModule { }
diff --git a/schematics/ng-generate/side-menu/index.ts b/schematics/ng-generate/side-menu/index.ts
new file mode 100644
index 0000000000..5898c529c0
--- /dev/null
+++ b/schematics/ng-generate/side-menu/index.ts
@@ -0,0 +1,53 @@
+import { strings } from '@angular-devkit/core';
+import {
+ apply,
+ applyTemplates,
+ chain,
+ forEach,
+ mergeWith,
+ move,
+ url,
+ FileEntry,
+ MergeStrategy,
+ Rule,
+ Tree
+} from '@angular-devkit/schematics';
+import { getProjectFromWorkspace } from '@angular/cdk/schematics';
+import { Style } from '@schematics/angular/application/schema';
+import { getWorkspace } from '@schematics/angular/utility/config';
+import { addModule } from '../../utils/root-module';
+
+import { Schema } from './schema';
+
+export default function(options: Schema): Rule {
+ return (host: Tree) => {
+ const workspace = getWorkspace(host);
+ const project = getProjectFromWorkspace(workspace, options.project);
+ const prefix = options.prefix || project.prefix;
+ const style = options.style || Style.Css;
+ return chain([
+ mergeWith(
+ apply(
+ url('./files/src'), [
+ applyTemplates({
+ prefix,
+ style,
+ ...strings,
+ ...options
+ }),
+ move(project.sourceRoot as string),
+ forEach((fileEntry: FileEntry) => {
+ if (host.exists(fileEntry.path)) {
+ host.overwrite(fileEntry.path, fileEntry.content);
+ }
+ return fileEntry;
+ })
+ ]
+ ),
+ MergeStrategy.Overwrite
+ ),
+ addModule('AppRoutingModule', './app-routing.module'),
+ addModule('IconsProviderModule', './icons-provider.module')
+ ]);
+ }
+}
diff --git a/schematics/ng-generate/side-menu/schema.json b/schematics/ng-generate/side-menu/schema.json
new file mode 100644
index 0000000000..7d43d2c24a
--- /dev/null
+++ b/schematics/ng-generate/side-menu/schema.json
@@ -0,0 +1,33 @@
+{
+ "$schema": "http://json-schema.org/schema",
+ "id": "sidebar-nav",
+ "title": "Sidebar Navigation Layout",
+ "type": "object",
+ "properties": {
+ "project": {
+ "type": "string",
+ "description": "The name of the project.",
+ "$default": {
+ "$source": "projectName"
+ }
+ },
+ "style": {
+ "description": "The file extension or preprocessor to use for style files.",
+ "type": "string",
+ "default": "css",
+ "enum": [
+ "css",
+ "scss",
+ "sass",
+ "less"
+ ]
+ },
+ "prefix": {
+ "type": "string",
+ "format": "html-selector",
+ "description": "A prefix to apply to generated selectors.",
+ "default": "app",
+ "alias": "p"
+ }
+ }
+}
diff --git a/schematics/ng-generate/side-menu/schema.ts b/schematics/ng-generate/side-menu/schema.ts
new file mode 100644
index 0000000000..acb95d53a6
--- /dev/null
+++ b/schematics/ng-generate/side-menu/schema.ts
@@ -0,0 +1,7 @@
+import { Style } from '@schematics/angular/application/schema';
+
+export interface Schema {
+ project: string;
+ style: Style;
+ prefix: string;
+}
diff --git a/schematics/ng-generate/topnav/files/src/app/app-routing.module.ts.template b/schematics/ng-generate/topnav/files/src/app/app-routing.module.ts.template
new file mode 100644
index 0000000000..29be260602
--- /dev/null
+++ b/schematics/ng-generate/topnav/files/src/app/app-routing.module.ts.template
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [
+ { path: '', pathMatch: 'full', redirectTo: '/welcome' },
+ { path: 'welcome', loadChildren: () => import('./pages/welcome/welcome.module').then(m => m.WelcomeModule) }
+];
+
+@NgModule({
+ imports: [RouterModule.forRoot(routes)],
+ exports: [RouterModule]
+})
+export class AppRoutingModule { }
diff --git a/schematics/ng-generate/topnav/files/src/app/app.component.__style__.template b/schematics/ng-generate/topnav/files/src/app/app.component.__style__.template
new file mode 100644
index 0000000000..73a1c7eaf7
--- /dev/null
+++ b/schematics/ng-generate/topnav/files/src/app/app.component.__style__.template
@@ -0,0 +1,46 @@
+:host {
+ display: flex;
+}
+
+.app-layout {
+ height: 100vh;
+}
+
+.top-nav {
+ line-height: 64px;
+}
+
+.logo {
+ float: left;
+ height: 64px;
+ padding-right: 24px;
+ line-height: 64px;
+ background: #001529;
+}
+
+.logo img {
+ display: inline-block;
+ height: 32px;
+ width: 32px;
+ vertical-align: middle;
+}
+
+.logo h1 {
+ display: inline-block;
+ margin: 0 0 0 15px;
+ color: #fff;
+ font-weight: 600;
+ font-size: 20px;
+ font-family: Avenir,Helvetica Neue,Arial,Helvetica,sans-serif;
+ vertical-align: middle;
+}
+
+nz-content {
+ padding: 24px 50px;
+}
+
+.inner-content {
+ padding: 24px;
+ background: #fff;
+ height: 100%;
+}
diff --git a/schematics/ng-generate/topnav/files/src/app/app.component.html.template b/schematics/ng-generate/topnav/files/src/app/app.component.html.template
new file mode 100644
index 0000000000..47d5824ad4
--- /dev/null
+++ b/schematics/ng-generate/topnav/files/src/app/app.component.html.template
@@ -0,0 +1,20 @@
+
+
+
+
+ - Home
+ - Account
+ - Profile
+
+
+
+
+
+
+
+
diff --git a/schematics/ng-generate/topnav/files/src/app/app.component.ts.template b/schematics/ng-generate/topnav/files/src/app/app.component.ts.template
new file mode 100644
index 0000000000..2a4d2c9159
--- /dev/null
+++ b/schematics/ng-generate/topnav/files/src/app/app.component.ts.template
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: '<%= prefix %>-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.<%= style %>']
+})
+export class AppComponent {
+
+}
diff --git a/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.__style__.template b/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.__style__.template
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.html.template b/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.html.template
new file mode 100644
index 0000000000..6b4f37e319
--- /dev/null
+++ b/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.html.template
@@ -0,0 +1 @@
+welcome works!
diff --git a/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.ts.template b/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.ts.template
new file mode 100644
index 0000000000..d33f473ee9
--- /dev/null
+++ b/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.component.ts.template
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: '<%= prefix %>-welcome',
+ templateUrl: './welcome.component.html',
+ styleUrls: ['./welcome.component.<%= style %>']
+})
+export class WelcomeComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.module.ts.template b/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.module.ts.template
new file mode 100644
index 0000000000..95381f5bba
--- /dev/null
+++ b/schematics/ng-generate/topnav/files/src/app/pages/welcome/welcome.module.ts.template
@@ -0,0 +1,8 @@
+import { NgModule } from '@angular/core';
+import { WelcomeComponent } from './welcome.component';
+
+@NgModule({
+ declarations: [ WelcomeComponent ],
+ exports: [ WelcomeComponent ]
+})
+export class WelcomeModule { }
diff --git a/schematics/ng-generate/topnav/index.ts b/schematics/ng-generate/topnav/index.ts
new file mode 100644
index 0000000000..7d4f5593c9
--- /dev/null
+++ b/schematics/ng-generate/topnav/index.ts
@@ -0,0 +1,52 @@
+import { strings } from '@angular-devkit/core';
+import {
+ apply,
+ applyTemplates,
+ chain,
+ forEach,
+ mergeWith,
+ move,
+ url,
+ FileEntry,
+ MergeStrategy,
+ Rule,
+ Tree
+} from '@angular-devkit/schematics';
+import { getProjectFromWorkspace } from '@angular/cdk/schematics';
+import { Style } from '@schematics/angular/application/schema';
+import { getWorkspace } from '@schematics/angular/utility/config';
+import { addModule } from '../../utils/root-module';
+
+import { Schema } from './schema';
+
+export default function(options: Schema): Rule {
+ return (host: Tree) => {
+ const workspace = getWorkspace(host);
+ const project = getProjectFromWorkspace(workspace, options.project);
+ const prefix = options.prefix || project.prefix;
+ const style = options.style || Style.Css;
+ return chain([
+ mergeWith(
+ apply(
+ url('./files/src'), [
+ applyTemplates({
+ prefix,
+ style,
+ ...strings,
+ ...options
+ }),
+ move(project.sourceRoot),
+ forEach((fileEntry: FileEntry) => {
+ if (host.exists(fileEntry.path)) {
+ host.overwrite(fileEntry.path, fileEntry.content);
+ }
+ return fileEntry;
+ })
+ ]
+ ),
+ MergeStrategy.Overwrite
+ ),
+ addModule('AppRoutingModule', './app-routing.module')
+ ]);
+ }
+}
diff --git a/schematics/ng-generate/topnav/schema.json b/schematics/ng-generate/topnav/schema.json
new file mode 100644
index 0000000000..caaa1d0eb8
--- /dev/null
+++ b/schematics/ng-generate/topnav/schema.json
@@ -0,0 +1,34 @@
+{
+ "$schema": "http://json-schema.org/schema",
+ "id": "top-nav",
+ "title": "Top Navigation Layout",
+ "type": "object",
+ "properties": {
+ "project": {
+ "type": "string",
+ "description": "The name of the project.",
+ "$default": {
+ "$source": "projectName"
+ }
+ },
+ "style": {
+ "description": "The file extension or preprocessor to use for style files.",
+ "type": "string",
+ "default": "css",
+ "enum": [
+ "css",
+ "scss",
+ "sass",
+ "less",
+ "styl"
+ ]
+ },
+ "prefix": {
+ "type": "string",
+ "format": "html-selector",
+ "description": "A prefix to apply to generated selectors.",
+ "default": "app",
+ "alias": "p"
+ }
+ }
+}
diff --git a/schematics/ng-generate/topnav/schema.ts b/schematics/ng-generate/topnav/schema.ts
new file mode 100644
index 0000000000..acb95d53a6
--- /dev/null
+++ b/schematics/ng-generate/topnav/schema.ts
@@ -0,0 +1,7 @@
+import { Style } from '@schematics/angular/application/schema';
+
+export interface Schema {
+ project: string;
+ style: Style;
+ prefix: string;
+}
diff --git a/schematics/tsconfig.json b/schematics/tsconfig.json
index 9c0ac514c7..741929b999 100644
--- a/schematics/tsconfig.json
+++ b/schematics/tsconfig.json
@@ -20,6 +20,7 @@
"exclude": [
"**/*.component.ts",
"**/*spec*",
- "template/**/*"
+ "template/**/*",
+ "**/files/**/*"
]
}
\ No newline at end of file
diff --git a/schematics/utils/root-module.ts b/schematics/utils/root-module.ts
new file mode 100644
index 0000000000..d8deefc7f4
--- /dev/null
+++ b/schematics/utils/root-module.ts
@@ -0,0 +1,48 @@
+import { Rule, SchematicsException, Tree } from '@angular-devkit/schematics';
+import { addModuleImportToRootModule, getProjectFromWorkspace, getProjectMainFile } from '@angular/cdk/schematics';
+import { addDeclarationToModule } from '@schematics/angular/utility/ast-utils';
+import { InsertChange } from '@schematics/angular/utility/change';
+import { getWorkspace } from '@schematics/angular/utility/config';
+import { buildRelativePath } from '@schematics/angular/utility/find-module';
+import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils';
+import { ProjectType, WorkspaceProject } from '@schematics/angular/utility/workspace-models';
+import * as ts from 'typescript';
+
+function readIntoSourceFile(host: Tree, modulePath: string): ts.SourceFile {
+ const text = host.read(modulePath);
+ if (text === null) {
+ throw new SchematicsException(`File ${modulePath} does not exist.`);
+ }
+ const sourceText = text.toString('utf-8');
+
+ return ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
+}
+
+export function addModule(moduleName: string, modulePath: string): Rule {
+ return (host: Tree) => {
+ const workspace = getWorkspace(host);
+ const project = getProjectFromWorkspace(workspace) as WorkspaceProject;
+ addModuleImportToRootModule(host, moduleName, modulePath, project);
+ return host;
+ }
+}
+
+export function addDeclaration(componentName: string, componentPath: string): Rule {
+ return (host: Tree) => {
+ const workspace = getWorkspace(host);
+ const project = getProjectFromWorkspace(workspace) as WorkspaceProject;
+ const appModulePath = getAppModulePath(host, getProjectMainFile(project));
+ const source = readIntoSourceFile(host, appModulePath);
+ const relativePath = buildRelativePath(appModulePath, componentPath);
+ const declarationChanges = addDeclarationToModule(source, appModulePath, componentName, relativePath);
+ const declarationRecorder = host.beginUpdate(appModulePath);
+ for (const change of declarationChanges) {
+ if (change instanceof InsertChange) {
+ declarationRecorder.insertLeft(change.pos, change.toAdd);
+ }
+ }
+ host.commitUpdate(declarationRecorder);
+
+ return host;
+ }
+}
diff --git a/scripts/schematics/copy-resources.js b/scripts/schematics/copy-resources.js
index 0e78cf419b..2b493da742 100644
--- a/scripts/schematics/copy-resources.js
+++ b/scripts/schematics/copy-resources.js
@@ -3,7 +3,7 @@ const path = require('path');
const srcPath = path.resolve(__dirname, `../../schematics`);
const targetPath = path.resolve(__dirname, `../../publish/schematics`);
-const copyFilter = (path) => (/files\/__path__/.test(path) || (!/.+\.ts/.test(path)));
+const copyFilter = (path) => (/files\/__path__/.test(path) || !/.+\.ts/.test(path) || /.template$/.test(path));
function mergeDemoCollection() {