├── .angular-cli.json ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── demo ├── bs-config.json └── src │ ├── app │ ├── app.component.ts │ ├── app.module.ts │ ├── home.component.ts │ ├── nz-card │ │ ├── basic.component.ts │ │ ├── column.component.ts │ │ ├── compatible.component.ts │ │ ├── customized.component.ts │ │ ├── grid.component.ts │ │ ├── inner.component.ts │ │ ├── loading.component.ts │ │ ├── more.component.ts │ │ ├── no-padding.component.ts │ │ ├── noborder.component.ts │ │ ├── nz-card.component.ts │ │ ├── simple.component.ts │ │ └── tab.component.ts │ ├── nz-divider │ │ ├── horizontal.component.ts │ │ ├── nz-divider.component.ts │ │ └── vertical.component.ts │ ├── nz-icon │ │ └── nz-icon.component.ts │ ├── nz-list │ │ ├── basic.component.ts │ │ ├── grid.component.ts │ │ ├── loadmore.component.ts │ │ ├── nz-list.component.ts │ │ ├── responsive.component.ts │ │ ├── simple.component.ts │ │ └── vertical.component.ts │ └── nz-radio-extra │ │ └── nz-radio-extra.component.ts │ ├── assets │ ├── bootstrap.min.css │ └── fork.png │ ├── environments │ ├── environment.prod.ts │ └── environment.ts │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── tsconfig.json │ └── typings.d.ts ├── gulpfile.js ├── karma.conf.js ├── package-lock.json ├── package.json ├── protractor.conf.js ├── rollup.config.js ├── scripts ├── inline-resources.js ├── test.ts └── typings.d.ts ├── src ├── index.ts ├── nz-card │ ├── index.md │ ├── index.ts │ ├── nz-card-action.component.ts │ ├── nz-card-grid.directive.ts │ ├── nz-card-meta.component.ts │ ├── nz-card-tab.component.ts │ ├── nz-card.component.html │ ├── nz-card.component.ts │ ├── nz-card.module.ts │ └── style │ │ ├── index.less │ │ └── patch.less ├── nz-divider │ ├── index.md │ ├── index.ts │ ├── nz-divider.component.ts │ ├── nz-divider.module.ts │ └── style │ │ ├── index.less │ │ ├── index.tsx │ │ └── patch.less ├── nz-icon │ ├── index.md │ ├── index.ts │ ├── nz-icon.component.ts │ ├── nz-icon.module.ts │ └── style │ │ ├── index.tsx │ │ └── patch.less ├── nz-list │ ├── index.md │ ├── index.ts │ ├── nz-list-item-action.component.ts │ ├── nz-list-item-meta.component.ts │ ├── nz-list-item.component.ts │ ├── nz-list.component.ts │ ├── nz-list.module.ts │ └── style │ │ ├── index.less │ │ └── patch.less ├── nz-radio-extra │ ├── index.md │ ├── index.ts │ ├── nz-radio-extra.component.ts │ ├── nz-radio-extra.module.ts │ └── style │ │ └── index.less ├── spec │ └── component.spec.ts ├── style │ ├── color │ │ ├── bezierEasing.less │ │ ├── colorPalette.less │ │ ├── colors.less │ │ └── tinyColor.less │ ├── core │ │ ├── base.less │ │ ├── iconfont.less │ │ ├── index.less │ │ ├── motion.less │ │ └── motion │ │ │ ├── fade.less │ │ │ ├── move.less │ │ │ ├── other.less │ │ │ ├── slide.less │ │ │ ├── swing.less │ │ │ └── zoom.less │ ├── index.less │ ├── index.tsx │ ├── mixins │ │ ├── clearfix.less │ │ ├── compatibility.less │ │ ├── iconfont.less │ │ ├── index.less │ │ ├── motion.less │ │ ├── opacity.less │ │ ├── reset.less │ │ └── size.less │ ├── themes │ │ └── default.less │ ├── v2-compatible-reset.less │ └── v2-compatible-reset.tsx ├── tsconfig.json ├── tsconfig.spec.json └── util │ └── convert.ts ├── tsconfig.publish.json └── tslint.json /.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "ng-zorro-antd-extra" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "demo/src", 9 | "outDir": "demo/dist", 10 | "assets": [ 11 | "assets" 12 | ], 13 | "index": "index.html", 14 | "main": "main.ts", 15 | "polyfills": "polyfills.ts", 16 | "test": "../../scripts/test.ts", 17 | "tsconfig": "tsconfig.json", 18 | "testTsconfig": "../../src/tsconfig.spec.json", 19 | "prefix": "nz", 20 | "serviceWorker": false, 21 | "styles": [ 22 | ], 23 | "scripts": [], 24 | "environmentSource": "environments/environment.ts", 25 | "environments": { 26 | "dev": "environments/environment.ts", 27 | "prod": "environments/environment.prod.ts" 28 | } 29 | } 30 | ], 31 | "e2e": { 32 | "protractor": { 33 | "config": "protractor.conf.js" 34 | } 35 | }, 36 | "test": { 37 | "karma": { 38 | "config": "karma.conf.js" 39 | } 40 | }, 41 | "defaults": { 42 | "styleExt": "less", 43 | "component": {} 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 4 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | ## Bug Report or Feature Request (mark with an `x`) 13 | ``` 14 | - [ ] bug report -> please search issues before submitting 15 | - [ ] feature request 16 | ``` 17 | 18 | ### Versions. 19 | 24 | 25 | ### Repro steps. 重现步骤 26 | 31 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## PR Checklist 2 | Please check if your PR fulfills the following requirements: 3 | 4 | - [ ] The commit message follows our guidelines: https://github.com/cipchk/ng-alain/blob/master/CONTRIBUTING.md#commit 5 | - [ ] Tests for the changes have been added (for bug fixes / features) 6 | - [ ] Docs have been added / updated (for bug fixes / features) 7 | 8 | 9 | ## PR Type 10 | What kind of change does this PR introduce? 11 | 12 | 13 | ``` 14 | [ ] Bugfix 15 | [ ] Feature 16 | [ ] Code style update (formatting, local variables) 17 | [ ] Refactoring (no functional changes, no api changes) 18 | [ ] Build related changes 19 | [ ] CI related changes 20 | [ ] Documentation content changes 21 | [ ] Application (the showcase website) / infrastructure changes 22 | [ ] Other... Please describe: 23 | ``` 24 | 25 | ## What is the current behavior? 26 | 27 | 28 | Issue Number: N/A 29 | 30 | 31 | ## What is the new behavior? 32 | 33 | 34 | ## Does this PR introduce a breaking change? 35 | ``` 36 | [ ] Yes 37 | [ ] No 38 | ``` 39 | 40 | 41 | 42 | 43 | ## Other information 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directory 2 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 3 | /node_modules 4 | npm-debug.log 5 | package-lock.json 6 | .tmp 7 | .ng_build 8 | .lib 9 | 10 | # WebStorm 11 | .idea 12 | .vscode 13 | 14 | # ignore build and dist for now 15 | /demo/dist 16 | /dist 17 | /coverage 18 | 19 | # ignore inline compiling 20 | /logs 21 | 22 | # AoT generated files 23 | factories 24 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | .tsdrc 30 | 31 | #IntelliJ configuration files 32 | .idea 33 | 34 | dist 35 | dev 36 | docs 37 | lib 38 | test 39 | tmp 40 | 41 | Thumbs.db 42 | .DS_Store 43 | 44 | *.ts 45 | !*.d.ts 46 | 47 | src/app/example* 48 | src/public 49 | typings 50 | *_spec.* 51 | CONTRIBUTING.md 52 | gulpfile.ts 53 | favicon.ico 54 | karma-shim.js 55 | karma.conf.js 56 | make.js 57 | protractor.conf.js 58 | test-main.js 59 | tsconfig.json 60 | tslint.json 61 | typedoc.json 62 | typings.json 63 | webpack.config.js 64 | *.yml 65 | .jshintrc 66 | .editorconfig 67 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | 5 | script: 6 | - npm run pretest 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present 卡色 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ng-zorro-antd-extra 2 | 3 | `ng-zorro-antd` extra episode! 4 | 5 | > so as to consider future compatibility in ng-zorro-antd 3.x, `ng-list-antd` was changed to `ng-zorro-antd-extra`. 6 | 7 | [![NPM version](https://img.shields.io/npm/v/ng-zorro-antd-extra.svg)](https://www.npmjs.com/package/ng-zorro-antd-extra) 8 | [![Build Status](https://travis-ci.org/cipchk/ng-zorro-antd-extra.svg?branch=master)](https://travis-ci.org/cipchk/ng-zorro-antd-extra) 9 | 10 | ## Demo 11 | 12 | [Live Demo](https://cipchk.github.io/ng-zorro-antd-extra) 13 | 14 | ## Dependencies 15 | 16 | + `ng-zorro-antd` **^0.6.0** 17 | 18 | ## INCLUCE COMPONENTS 19 | 20 | | Name | API | Status | 21 | | ------- | ------------- | -------- | 22 | | `nz-list` | [link](./src/nz-list/index.md) | Finished | 23 | | `nz-card` | [link](./src/nz-card/index.md) | Finished | 24 | | `nz-divider` | [link](./src/nz-divider/index.md) | Finished | 25 | | `nz-icon` | [link](./src/nz-icon/index.md) | Finished | 26 | | `nz-radio-extra` | [link](./src/nz-radio-extra/index.md) | ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **Deprecated** | 27 | 28 | ## Usage & Installation 29 | 30 | Install `ng-zorro-antd-extra` from `npm` 31 | 32 | ``` 33 | npm install ng-zorro-antd-extra --save 34 | ``` 35 | 36 | Import the `NzListModule` in to your root `AppModule`. 37 | 38 | **Important:** Don't use `NgZorroAntdModule.forRoot()` load all modules, should be like [app.modules.ts](./demo/src/app/app.module.ts) method. 39 | 40 | ```typescript 41 | import { NgZorroAntdExtraModule } from 'ng-zorro-antd-extra'; 42 | // or 43 | // import { NzListModule, NzCardModule, NzDividerModule } from 'ng-zorro-antd-extra'; 44 | 45 | @NgModule({ 46 | imports: [ 47 | NgZorroAntdExtraModule.forRoot() 48 | ] 49 | }) 50 | export class AppModule { } 51 | ``` 52 | 53 | ## Troubleshooting 54 | 55 | Please follow this guidelines when reporting bugs and feature requests: 56 | 57 | 1. Use [GitHub Issues](https://github.com/cipchk/ng-zorro-antd-extra/issues) board to report bugs and feature requests (not our email address) 58 | 2. Please **always** write steps to reproduce the error. That way we can focus on fixing the bug, not scratching our heads trying to reproduce it. 59 | 60 | Thanks for understanding! 61 | 62 | ### License 63 | 64 | The MIT License (see the [LICENSE](https://github.com/cipchk/ng-zorro-antd-extra/blob/master/LICENSE) file for the full text) 65 | -------------------------------------------------------------------------------- /demo/bs-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 4200, 3 | "server": { "baseDir": "./demo/dist" } 4 | } 5 | -------------------------------------------------------------------------------- /demo/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 6 | 31 |

ng-zorro-antd extra episode!

32 |
33 | `, 34 | encapsulation: ViewEncapsulation.None 35 | }) 36 | export class AppComponent { 37 | } 38 | -------------------------------------------------------------------------------- /demo/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 4 | import { CommonModule } from '@angular/common'; 5 | import { FormsModule } from '@angular/forms'; 6 | import { HttpClientModule } from '@angular/common/http'; 7 | import { Routes, RouterModule } from '@angular/router'; 8 | 9 | import { NgZorroAntdExtraModule } from '../../../src/index'; 10 | 11 | // region: zorro modules 12 | 13 | import { 14 | // LoggerModule, 15 | // NzLocaleModule, 16 | NzButtonModule, 17 | NzAlertModule, 18 | NzBadgeModule, 19 | // NzCalendarModule, 20 | NzCascaderModule, 21 | NzCheckboxModule, 22 | NzDatePickerModule, 23 | NzFormModule, 24 | NzInputModule, 25 | NzInputNumberModule, 26 | NzGridModule, 27 | NzMessageModule, 28 | NzModalModule, 29 | NzNotificationModule, 30 | NzPaginationModule, 31 | NzPopconfirmModule, 32 | NzPopoverModule, 33 | NzRadioModule, 34 | NzRateModule, 35 | NzSelectModule, 36 | NzSpinModule, 37 | NzSliderModule, 38 | NzSwitchModule, 39 | NzProgressModule, 40 | NzTableModule, 41 | NzTabsModule, 42 | NzTagModule, 43 | NzTimePickerModule, 44 | NzUtilModule, 45 | NzStepsModule, 46 | NzDropDownModule, 47 | NzMenuModule, 48 | NzBreadCrumbModule, 49 | NzLayoutModule, 50 | NzRootModule, 51 | NzCarouselModule, 52 | // NzCardModule, 53 | NzCollapseModule, 54 | NzTimelineModule, 55 | NzToolTipModule, 56 | // NzBackTopModule, 57 | // NzAffixModule, 58 | // NzAnchorModule, 59 | NzAvatarModule, 60 | // SERVICES 61 | NzNotificationService, 62 | NzMessageService 63 | } from 'ng-zorro-antd'; 64 | const ZORROMODULES = [ 65 | // LoggerModule, 66 | // NzLocaleModule, 67 | NzButtonModule, 68 | NzAlertModule, 69 | NzBadgeModule, 70 | // NzCalendarModule, 71 | NzCascaderModule, 72 | NzCheckboxModule, 73 | NzDatePickerModule, 74 | NzFormModule, 75 | NzInputModule, 76 | NzInputNumberModule, 77 | NzGridModule, 78 | NzMessageModule, 79 | NzModalModule, 80 | NzNotificationModule, 81 | NzPaginationModule, 82 | NzPopconfirmModule, 83 | NzPopoverModule, 84 | NzRadioModule, 85 | NzRateModule, 86 | NzSelectModule, 87 | NzSpinModule, 88 | NzSliderModule, 89 | NzSwitchModule, 90 | NzProgressModule, 91 | NzTableModule, 92 | NzTabsModule, 93 | NzTagModule, 94 | NzTimePickerModule, 95 | NzUtilModule, 96 | NzStepsModule, 97 | NzDropDownModule, 98 | NzMenuModule, 99 | NzBreadCrumbModule, 100 | NzLayoutModule, 101 | NzRootModule, 102 | NzCarouselModule, 103 | // NzCardModule, 104 | NzCollapseModule, 105 | NzTimelineModule, 106 | NzToolTipModule, 107 | // NzBackTopModule, 108 | // NzAffixModule, 109 | // NzAnchorModule, 110 | NzAvatarModule 111 | ]; 112 | // endregion 113 | 114 | import { DemoHomeComponent } from './home.component'; 115 | 116 | import { AppComponent } from './app.component'; 117 | 118 | // nz-list 119 | import { DemoNzListComponent } from './nz-list/nz-list.component'; 120 | import { DemoNzListBasicComponent } from './nz-list/basic.component'; 121 | import { DemoNzListSimpleComponent } from './nz-list/simple.component'; 122 | import { DemoNzListLoadMoreComponent } from './nz-list/loadmore.component'; 123 | import { DemoNzListVerticalComponent } from './nz-list/vertical.component'; 124 | import { DemoNzListGridComponent } from './nz-list/grid.component'; 125 | import { DemoNzListResponsiveComponent } from './nz-list/responsive.component'; 126 | // nz-card 127 | import { DemoNzCardComponent } from './nz-card/nz-card.component'; 128 | import { DemoNzCardBasicComponent } from './nz-card/basic.component'; 129 | import { DemoNzCardTabComponent } from './nz-card/tab.component'; 130 | import { DemoNzCardInnerComponent } from './nz-card/inner.component'; 131 | import { DemoNzCardNoBoarderComponent } from './nz-card/noborder.component'; 132 | import { DemoNzCardSimpleComponent } from './nz-card/simple.component'; 133 | import { DemoNzCardCustomizedComponent } from './nz-card/customized.component'; 134 | import { DemoNzCardColumnComponent } from './nz-card/column.component'; 135 | import { DemoNzCardLoadingComponent } from './nz-card/loading.component'; 136 | import { DemoNzCardGridComponent } from './nz-card/grid.component'; 137 | import { DemoNzCardMoreComponent } from './nz-card/more.component'; 138 | import { DemoNzCardNoPaddingComponent } from './nz-card/no-padding.component'; 139 | import { DemoNzCardCompatibleComponent } from './nz-card/compatible.component'; 140 | // nz-divider 141 | import { DemoNzDividerComponent } from './nz-divider/nz-divider.component'; 142 | import { DemoNzDividerHorizontalComponent } from './nz-divider/horizontal.component'; 143 | import { DemoNzDividerVerticalComponent } from './nz-divider/vertical.component'; 144 | // nz-icon 145 | import { DemoNzIconComponent } from './nz-icon/nz-icon.component'; 146 | // nz-radio-extra 147 | import { DemoNzRadioExtraComponent } from './nz-radio-extra/nz-radio-extra.component'; 148 | 149 | @NgModule({ 150 | imports: [ 151 | BrowserModule, 152 | CommonModule, 153 | HttpClientModule, 154 | FormsModule, 155 | 156 | RouterModule.forRoot([ 157 | { path: '', component: DemoHomeComponent }, 158 | { path: 'list', component: DemoNzListComponent }, 159 | { path: 'card', component: DemoNzCardComponent }, 160 | { path: 'divider', component: DemoNzDividerComponent }, 161 | { path: 'icon', component: DemoNzIconComponent }, 162 | { path: 'radio-extra', component: DemoNzRadioExtraComponent } 163 | ], { useHash: true }), 164 | 165 | BrowserAnimationsModule, 166 | ...ZORROMODULES, 167 | NgZorroAntdExtraModule.forRoot() 168 | ], 169 | declarations: [ 170 | AppComponent, 171 | DemoHomeComponent, 172 | // nz-list 173 | DemoNzListComponent, 174 | DemoNzListSimpleComponent, 175 | DemoNzListBasicComponent, 176 | DemoNzListLoadMoreComponent, 177 | DemoNzListVerticalComponent, 178 | DemoNzListGridComponent, 179 | DemoNzListResponsiveComponent, 180 | // nz-card 181 | DemoNzCardComponent, 182 | DemoNzCardBasicComponent, 183 | DemoNzCardNoBoarderComponent, 184 | DemoNzCardSimpleComponent, 185 | DemoNzCardCustomizedComponent, 186 | DemoNzCardColumnComponent, 187 | DemoNzCardLoadingComponent, 188 | DemoNzCardGridComponent, 189 | DemoNzCardTabComponent, 190 | DemoNzCardInnerComponent, 191 | DemoNzCardMoreComponent, 192 | DemoNzCardCompatibleComponent, 193 | DemoNzCardNoPaddingComponent, 194 | // nz-divider 195 | DemoNzDividerComponent, 196 | DemoNzDividerHorizontalComponent, 197 | DemoNzDividerVerticalComponent, 198 | // nz-icon 199 | DemoNzIconComponent, 200 | // nz-radio 201 | DemoNzRadioExtraComponent 202 | ], 203 | providers: [ 204 | // Services 205 | NzNotificationService, 206 | NzMessageService 207 | ], 208 | bootstrap: [AppComponent] 209 | }) 210 | 211 | export class AppDemoModule { 212 | } 213 | -------------------------------------------------------------------------------- /demo/src/app/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-home', 5 | template: ` 6 | 7 | nz-list 8 | nz-card 9 | nz-divider 10 | nz-icon 11 | nz-radio-extra 12 | 13 | ` 14 | }) 15 | export class DemoHomeComponent { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/basic.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-basic', 5 | template: ` 6 |

Basic source

7 | 8 |

Card content

9 |

Card content

10 |

Card content

11 |
12 | ` 13 | }) 14 | export class DemoNzCardBasicComponent { 15 | } 16 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/column.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-column', 5 | template: ` 6 |

Card in column source

7 |
8 |
9 |
10 | 11 |

Card content

12 |
13 |
14 |
15 | 16 |

Card content

17 |
18 |
19 |
20 | 21 |

Card content

22 |
23 |
24 |
25 |
26 | ` 27 | }) 28 | export class DemoNzCardColumnComponent { 29 | } 30 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/compatible.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-compatible', 5 | template: ` 6 |

Compatible 2.x Not Recommended!! source

7 | 8 | Card title 9 | 10 |

Card content

11 |

Card content

12 |

Card content

13 |
14 |
15 | ` 16 | }) 17 | export class DemoNzCardCompatibleComponent { 18 | } 19 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/customized.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-customized', 5 | template: ` 6 |

customized source

7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | ` 17 | }) 18 | export class DemoNzCardCustomizedComponent { 19 | } 20 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/grid.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-grid', 5 | template: ` 6 |

grid source

7 | 8 |
Content
9 |
Content
10 |
Content
11 |
Content
12 |
Content
13 |
Content
14 |
Content
15 |
Content
16 |
17 | ` 18 | }) 19 | export class DemoNzCardGridComponent { 20 | } 21 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/inner.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | import { NzMessageService } from 'ng-zorro-antd'; 3 | 4 | @Component({ 5 | selector: 'demo-nz-card-inner', 6 | template: ` 7 |

inner source

8 | 9 |
Group title
10 | 11 | 12 | More 13 | 14 | Inner Card content 15 | 16 | 17 | 18 | More 19 | 20 | Inner Card content 21 | 22 |
23 | ` 24 | }) 25 | export class DemoNzCardInnerComponent { 26 | tabs = [ 27 | { 28 | name: 'Tab 1' 29 | }, 30 | { 31 | name: 'Tab 2' 32 | } 33 | ]; 34 | constructor(public msg: NzMessageService) {} 35 | 36 | closeTab(tab: any) { 37 | console.log(tab); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/loading.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-loading', 5 | template: ` 6 |

Loading source

7 | 8 | Whatever content 9 | 10 | ` 11 | }) 12 | export class DemoNzCardLoadingComponent { 13 | } 14 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/more.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | import { NzMessageService } from 'ng-zorro-antd'; 3 | 4 | @Component({ 5 | selector: 'demo-nz-card-more', 6 | template: ` 7 |

Support more content configuration source

8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | ` 22 | }) 23 | export class DemoNzCardMoreComponent { 24 | constructor(public msg: NzMessageService) {} 25 | } 26 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/no-padding.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-no-padding', 5 | template: ` 6 |

No padding source

7 | 8 |

Card content

9 |

我是无边距的

10 |

Card content

11 |
12 | ` 13 | }) 14 | export class DemoNzCardNoPaddingComponent { 15 | } 16 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/noborder.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-noborder', 5 | template: ` 6 |

No border source

7 |
8 | 9 |

Card content

10 |

Card content

11 |

Card content

12 |
13 |
14 | ` 15 | }) 16 | export class DemoNzCardNoBoarderComponent { 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/nz-card.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-card', 5 | template: ` 6 |
7 |
8 | 9 |
10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 |
18 |
19 | 20 |
21 |
22 | 23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 | 36 |
37 |
38 | 39 |
40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 |
48 |
49 | 50 |
51 |
52 |
53 |
54 | ` 55 | }) 56 | export class DemoNzCardComponent { 57 | 58 | } 59 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/simple.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-card-simple', 5 | template: ` 6 |

simple source

7 | 8 |

Card content

9 |

Card content

10 |

Card content

11 |
12 | ` 13 | }) 14 | export class DemoNzCardSimpleComponent { 15 | } 16 | -------------------------------------------------------------------------------- /demo/src/app/nz-card/tab.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | import { NzMessageService } from 'ng-zorro-antd'; 3 | 4 | @Component({ 5 | selector: 'demo-nz-card-tab', 6 | template: ` 7 |

tab source

8 | 9 | 10 | More 11 | 12 | 13 | tab1 content 14 | 15 | 16 | tab2 content 17 | 18 | 19 | 20 | 21 | 22 | {{tab.name}} 23 | 24 | 25 | tab1 content 26 | 27 | 28 | ` 29 | }) 30 | export class DemoNzCardTabComponent { 31 | tabs = [ 32 | { 33 | name: 'Tab 1' 34 | }, 35 | { 36 | name: 'Tab 2' 37 | } 38 | ]; 39 | constructor(public msg: NzMessageService) {} 40 | 41 | closeTab(tab: any) { 42 | console.log(tab); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /demo/src/app/nz-divider/horizontal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-divider-horizontal', 5 | template: ` 6 |

Horizontal source

7 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo.

8 | 9 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo.

10 | 11 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo.

12 | 13 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo.

14 | ` 15 | }) 16 | export class DemoNzDividerHorizontalComponent { 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/app/nz-divider/nz-divider.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-divider', 5 | template: ` 6 |
7 |
8 | 9 |
10 |
11 | 12 |
13 |
14 | ` 15 | }) 16 | export class DemoNzDividerComponent { 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/app/nz-divider/vertical.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | import { NzMessageService } from 'ng-zorro-antd'; 3 | 4 | @Component({ 5 | selector: 'demo-nz-divider-vertical', 6 | template: ` 7 |

Vertical source

8 | Text 9 | 10 | Link 11 | 12 | Link 13 | ` 14 | }) 15 | export class DemoNzDividerVerticalComponent { 16 | constructor(public msg: NzMessageService) {} 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/app/nz-icon/nz-icon.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-icon', 5 | template: ` 6 | 7 |

8 | cipchk 9 |

10 | ` 11 | }) 12 | export class DemoNzIconComponent { 13 | } 14 | -------------------------------------------------------------------------------- /demo/src/app/nz-list/basic.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-list-basic', 5 | template: ` 6 | 7 | Basic list source 8 | 9 | 10 | 11 | 12 | 16 | 17 | {{item.title}} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ` 26 | }) 27 | export class DemoNzListBasicComponent { 28 | data = [ 29 | { 30 | title: 'Ant Design Title 1' 31 | }, 32 | { 33 | title: 'Ant Design Title 2' 34 | }, 35 | { 36 | title: 'Ant Design Title 3' 37 | }, 38 | { 39 | title: 'Ant Design Title 4' 40 | } 41 | ]; 42 | } 43 | -------------------------------------------------------------------------------- /demo/src/app/nz-list/grid.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-list-grid', 5 | template: ` 6 | 7 | Grid source 8 | 9 | 10 | 11 | 12 | 13 | {{item.title}} 14 | Card content 15 | 16 | 17 | 18 | 19 | 20 | 21 | ` 22 | }) 23 | export class DemoNzListGridComponent { 24 | data = [ 25 | { 26 | title: 'Title 1', 27 | }, 28 | { 29 | title: 'Title 2', 30 | }, 31 | { 32 | title: 'Title 3', 33 | }, 34 | { 35 | title: 'Title 4', 36 | }, 37 | ]; 38 | } 39 | -------------------------------------------------------------------------------- /demo/src/app/nz-list/loadmore.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { NzMessageService } from 'ng-zorro-antd'; 4 | 5 | const fakeDataUrl = 'https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo'; 6 | 7 | @Component({ 8 | selector: 'demo-nz-list-loadmore', 9 | template: ` 10 | 11 | Loadmore source 12 | 13 | 14 | 15 | 16 | edit 17 | more 18 | 22 | 23 | {{item.name.last}} 24 | 25 | 26 |
content
27 |
28 |
29 | 30 |
31 | 32 | 33 |
34 |
35 |
36 |
37 |
38 | ` 39 | }) 40 | export class DemoNzListLoadMoreComponent implements OnInit { 41 | data = []; 42 | loading = false; 43 | loadingMore = false; 44 | showLoadMore = false; 45 | pi = 1; 46 | ps = 5; 47 | show_max_pi = 5; 48 | 49 | constructor(private http: HttpClient, private msg: NzMessageService) {} 50 | 51 | ngOnInit() { 52 | this.getData(); 53 | } 54 | 55 | getData() { 56 | if (this.pi === 1) 57 | this.loading = true; 58 | else 59 | this.loadingMore = true; 60 | 61 | this.http.get(fakeDataUrl).subscribe((res: any) => { 62 | if (this.pi === 1) { 63 | this.data = res.results; 64 | this.loading = false; 65 | } else { 66 | this.data = this.data.concat(res.results); 67 | this.loadingMore = false; 68 | } 69 | this.showLoadMore = this.pi <= this.show_max_pi; 70 | }); 71 | } 72 | 73 | handleLoadMore() { 74 | ++this.pi; 75 | this.getData(); 76 | } 77 | 78 | edit(item: any) { 79 | this.msg.success(item.email); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /demo/src/app/nz-list/nz-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-list', 5 | template: ` 6 | 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 | 17 | 18 | ` 19 | }) 20 | export class DemoNzListComponent { 21 | } 22 | -------------------------------------------------------------------------------- /demo/src/app/nz-list/responsive.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-list-responsive', 5 | template: ` 6 | 7 | Responsive source 8 | 9 | 10 | 11 | 12 | 13 | {{item.title}} 14 | Card content 15 | 16 | 17 | 18 | 19 | 20 | 21 | ` 22 | }) 23 | export class DemoNzListResponsiveComponent { 24 | data = [ 25 | { 26 | title: 'Title 1', 27 | }, 28 | { 29 | title: 'Title 2', 30 | }, 31 | { 32 | title: 'Title 3', 33 | }, 34 | { 35 | title: 'Title 4', 36 | }, 37 | { 38 | title: 'Title 5', 39 | }, 40 | { 41 | title: 'Title 6', 42 | }, 43 | ]; 44 | } 45 | -------------------------------------------------------------------------------- /demo/src/app/nz-list/simple.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-list-simple', 5 | template: ` 6 | 7 | Simple list source 8 | 9 |
10 |
11 |

Default Size

12 | 14 | 15 | {{item}} 16 | 17 | 18 |
19 |
20 |

Small Size

21 | 23 | 24 | {{item}} 25 | 26 | 27 |
28 |
29 |

Large Size

30 | 32 | 33 | {{item}} 34 | 35 | 36 |
37 |
38 |
39 |
40 | ` 41 | }) 42 | export class DemoNzListSimpleComponent { 43 | data = [ 44 | 'Racing car sprays burning fuel into crowd.', 45 | 'Japanese princess to wed commoner.', 46 | 'Australian walks 100km after outback crash.', 47 | 'Man charged over missing wedding girl.', 48 | 'Los Angeles battles huge wildfires.' 49 | ]; 50 | 51 | loading = false; 52 | 53 | setLoading() { 54 | this.loading = true; 55 | setTimeout(() => this.loading = false, 1500); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /demo/src/app/nz-list/vertical.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-list-vertical', 5 | template: ` 6 | 7 | Vertical source 8 | 9 | 10 | 11 | 12 | 156 13 | 156 14 | 2 15 | 19 | {{item.title}} 20 | 21 | 22 | logo 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | ` 33 | }) 34 | export class DemoNzListVerticalComponent { 35 | data = new Array(5).fill({}).map((i, index) => { 36 | return { 37 | href: 'http://ant.design', 38 | title: `ant design part ${index}`, 39 | avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', 40 | description: 'Ant Design, a design language for background applications, is refined by Ant UED Team.', 41 | content: 'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.', 42 | }; 43 | }); 44 | } 45 | -------------------------------------------------------------------------------- /demo/src/app/nz-radio-extra/nz-radio-extra.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'demo-nz-radio-extra', 5 | template: ` 6 |

7 | 8 | result: {{ret}} 9 |

10 | 11 | ` 12 | }) 13 | export class DemoNzRadioExtraComponent { 14 | ret = false; 15 | } 16 | -------------------------------------------------------------------------------- /demo/src/assets/fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cipchk/ng-zorro-antd-extra/72b344f6a857b2b6dfe9497f0e140b3ef7b337a7/demo/src/assets/fork.png -------------------------------------------------------------------------------- /demo/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /demo/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /demo/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ng-zorro-antd-extra | ng-zorro-antd extra episode! 7 | 8 | 9 | 10 | 11 | 28 | 29 | 30 | 31 |
32 | Loading... 33 |
34 | 35 | Fork me on GitHub 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /demo/src/main.ts: -------------------------------------------------------------------------------- 1 | import './polyfills.ts'; 2 | 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | import { enableProdMode } from '@angular/core'; 5 | import { environment } from './environments/environment'; 6 | import { AppDemoModule } from './app/app.module'; 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic().bootstrapModule(AppDemoModule); 13 | -------------------------------------------------------------------------------- /demo/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | import 'core-js/es6/symbol'; 23 | import 'core-js/es6/object'; 24 | import 'core-js/es6/function'; 25 | import 'core-js/es6/parse-int'; 26 | import 'core-js/es6/parse-float'; 27 | import 'core-js/es6/number'; 28 | import 'core-js/es6/math'; 29 | import 'core-js/es6/string'; 30 | import 'core-js/es6/date'; 31 | import 'core-js/es6/array'; 32 | import 'core-js/es6/regexp'; 33 | import 'core-js/es6/map'; 34 | import 'core-js/es6/weak-map'; 35 | import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Required to support Web Animations `@angular/platform-browser/animations`. 51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 52 | **/ 53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 54 | 55 | 56 | 57 | /*************************************************************************************************** 58 | * Zone JS is required by Angular itself. 59 | */ 60 | import 'zone.js/dist/zone'; // Included with Angular CLI. 61 | 62 | 63 | 64 | /*************************************************************************************************** 65 | * APPLICATION IMPORTS 66 | */ 67 | 68 | /** 69 | * Date, currency, decimal and percent pipes. 70 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 71 | */ 72 | // import 'intl'; // Run `npm install --save intl`. 73 | /** 74 | * Need to import at least one locale-data with intl. 75 | */ 76 | // import 'intl/locale-data/jsonp/en'; 77 | -------------------------------------------------------------------------------- /demo/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": false, 4 | "emitDecoratorMetadata": true, 5 | "experimentalDecorators": true, 6 | "lib": ["es2017", "dom"], 7 | "types": [ 8 | "jasmine", 9 | "webpack" 10 | ], 11 | "mapRoot": "./", 12 | "module": "es6", 13 | "moduleResolution": "node", 14 | "outDir": "../temp/out-tsc", 15 | "sourceMap": true, 16 | "target": "es5", 17 | "typeRoots": [ 18 | "../node_modules/@types" 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /demo/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | 7 | declare namespace jasmine { 8 | interface Matchers { 9 | toHaveCssClass(expected: any): boolean; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const rollup = require('gulp-rollup'); 3 | const rename = require('gulp-rename'); 4 | const replace = require('gulp-replace'); 5 | const less = require('gulp-less'); 6 | const bump = require('gulp-bump'); 7 | const inline_recources = require('./scripts/inline-resources'); 8 | // @ts-ignore 9 | const VERSION = require('./package.json').version; 10 | 11 | const paths = { 12 | build: './.ng_build', 13 | lib: './.lib' 14 | }; 15 | 16 | gulp.task('copy-sources', copySources); 17 | gulp.task('inline-resources', copyResources); 18 | // @ts-ignore 19 | gulp.task('bundle', bundleUmd); 20 | gulp.task('bump', bumpVersions); 21 | 22 | function bumpVersions() { 23 | gulp.src([ './package.json'], {base: './'}) 24 | .pipe(bump({ 25 | version: VERSION 26 | })) 27 | .pipe(gulp.dest('./')); 28 | } 29 | function copySources() { 30 | gulp.src('./src/**/*') 31 | .pipe(gulp.dest(paths.build)) 32 | .on('end', replaceLessWithCSS) 33 | ; 34 | } 35 | 36 | function replaceLessWithCSS() { 37 | gulp.src(`${paths.build}/**/*.ts`) 38 | .pipe(replace('.less', '.css')) 39 | .pipe(gulp.dest(paths.build)) 40 | .on('end', compileLess); 41 | } 42 | 43 | function compileLess() { 44 | gulp.src([ 45 | `${paths.build}/**/*.less` 46 | ]) 47 | .pipe(less()) 48 | .pipe(gulp.dest(paths.build)); 49 | } 50 | 51 | function copyResources() { 52 | gulp.src([ 53 | `./LICENSE`, 54 | `./README.md`, 55 | `./rollup.config.js`, 56 | `./package.json`, 57 | `${paths.build}/**/*.html`, 58 | `${paths.build}/**/*.css`, 59 | `${paths.build}/**/*.less` 60 | ]) 61 | .pipe(gulp.dest(paths.lib)) 62 | .on('end', () => inline_recources(paths.lib)); 63 | } 64 | 65 | function bundleUmd() { 66 | bundle(`${paths.lib}/`); 67 | } 68 | 69 | function bundle(path) { 70 | const config = require(path + 'rollup.config.js'); 71 | gulp.src(path + `**/*.js`) 72 | .pipe(rollup(Object.assign({}, config, { 73 | name: config.name, 74 | input: `${path}index.js` 75 | }))) 76 | .pipe(rename(config.output)) 77 | .pipe(gulp.dest(`${path}bundles`)); 78 | } 79 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/0.13/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | files: [ 19 | { pattern: './scripts/test.ts', watched: false } 20 | ], 21 | preprocessors: { 22 | './scripts/test.ts': ['@angular/cli'] 23 | }, 24 | mime: { 25 | 'text/x-typescript': ['ts','tsx'] 26 | }, 27 | coverageIstanbulReporter: { 28 | reports: [ 'html', 'lcovonly' ], 29 | fixWebpackSourcePaths: true 30 | }, 31 | angularCli: { 32 | environment: 'dev' 33 | }, 34 | reporters: config.angularCli && config.angularCli.codeCoverage 35 | ? ['progress', 'coverage-istanbul'] 36 | : ['progress', 'kjhtml'], 37 | port: 9876, 38 | colors: true, 39 | logLevel: config.LOG_INFO, 40 | autoWatch: true, 41 | browsers: ['Chrome'], 42 | singleRun: false 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-zorro-antd-extra", 3 | "version": "1.1.7", 4 | "main": "./bundles/ng-zorro-antd-extra.umd.js", 5 | "typings": "index.d.ts", 6 | "description": "ng-zorro-antd extra episode!", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/cipchk/ng-zorro-antd-extra.git" 10 | }, 11 | "keywords": [ 12 | "ng-zorro-antd-extra", 13 | "list antd", 14 | "antd" 15 | ], 16 | "author": "cipchk ", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/cipchk/ng-zorro-antd-extra/issues" 20 | }, 21 | "homepage": "https://github.com/cipchk/ng-zorro-antd-extra#readme", 22 | "scripts": { 23 | "demo.serve": "run-s build link demo.build", 24 | "demo.gh-pages": "run-s build demo.build demo.deploy", 25 | "demo.build": "ng build -prod", 26 | "demo.deploy": "gh-pages -d demo/dist", 27 | "link": "ngm link -p src --here", 28 | "lint": "exit 0", 29 | "build": "ngm build -p src --clean", 30 | "build.watch": "ngm build -p src --watch --skip-bundles", 31 | "pretest": "run-s lint build link", 32 | "test": "ng test -sr", 33 | "test-coverage": "ng test -sr -cc", 34 | "prepush": "npm run lint", 35 | "clean:tmp": "rimraf .ng_build .ng_compiled", 36 | "clean:tmp:lib": "npm run clean:tmp && rimraf .lib", 37 | "build:copy-sources": "gulp copy-sources", 38 | "build:inline-resources": "gulp inline-resources", 39 | "build:ts": "tsc -p tsconfig.publish.json && ngc -p tsconfig.publish.json", 40 | "build:bundle": "gulp bundle", 41 | "build:package": "npm-run-all -s clean:tmp:lib build:copy-sources build:ts build:inline-resources build:bundle clean:tmp", 42 | "version:bump": "gulp bump", 43 | "release:prepare": "npm run build:package", 44 | "release:validity": "npm run version:bump && npm run release:prepare", 45 | "release": "npm run version:bump && npm run release:prepare && npm publish --access=public .lib" 46 | }, 47 | "dependencies": {}, 48 | "peerDependencies": { 49 | "@angular/common": ">=4.3.x || >5.x", 50 | "@angular/core": ">=4.3.x || >5.x", 51 | "@angular/compiler": ">=4.3.x || >5.x", 52 | "rxjs": ">5.x", 53 | "typescript": ">=2.3.x", 54 | "ng-zorro-antd": ">0.5.x" 55 | }, 56 | "devDependencies": { 57 | "@angular/animations": "^5.0.0", 58 | "@angular/cli": "^1.5.0", 59 | "@angular/common": "^5.0.0", 60 | "@angular/compiler": "^5.0.0", 61 | "@angular/compiler-cli": "^5.0.0", 62 | "@angular/core": "^5.0.0", 63 | "@angular/forms": "^5.0.0", 64 | "@angular/http": "^5.0.0", 65 | "@angular/language-service": "^5.0.0", 66 | "@angular/platform-browser": "^5.0.0", 67 | "@angular/platform-browser-dynamic": "^5.0.0", 68 | "@angular/router": "^5.0.0", 69 | "@types/jasmine": "~2.6.0", 70 | "@types/jasminewd2": "~2.0.3", 71 | "@types/node": "~6.0.60", 72 | "@types/webpack": "^3.0.14", 73 | "codelyzer": "~3.2.0", 74 | "core-js": "^2.4.1", 75 | "gulp": "^3.9.1", 76 | "gulp-bump": "^2.8.0", 77 | "gulp-clean": "^0.3.2", 78 | "gulp-clean-css": "^3.2.0", 79 | "gulp-cli": "^1.3.0", 80 | "gulp-connect": "^5.0.0", 81 | "gulp-dom": "^0.9.17", 82 | "gulp-flatten": "^0.3.1", 83 | "gulp-if": "^2.0.2", 84 | "gulp-less": "^3.3.2", 85 | "gulp-markdown": "^1.2.0", 86 | "gulp-rename": "^1.2.2", 87 | "gulp-replace": "^0.6.0", 88 | "gulp-rollup": "^2.15.0", 89 | "gulp-transform": "^1.1.0", 90 | "jasmine-core": "~2.6.2", 91 | "jasmine-spec-reporter": "~4.1.0", 92 | "karma": "~1.7.0", 93 | "karma-chrome-launcher": "~2.1.1", 94 | "karma-cli": "~1.0.1", 95 | "karma-coverage-istanbul-reporter": "^1.2.1", 96 | "karma-jasmine": "~1.1.0", 97 | "karma-jasmine-html-reporter": "^0.2.2", 98 | "ng-zorro-antd": "^0.6.0", 99 | "ngm-cli": "^0.8.3", 100 | "npm-run-all": "^4.1.1", 101 | "protractor": "~5.1.2", 102 | "rimraf": "^2.6.2", 103 | "rollup-plugin-node-resolve": "^3.0.0", 104 | "rollup-plugin-replace": "^2.0.0", 105 | "rxjs": "^5.5.2", 106 | "ts-node": "~3.2.0", 107 | "tslint": "~5.7.0", 108 | "typescript": "~2.4.2", 109 | "zone.js": "^0.8.14" 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | beforeLaunch: function() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | }, 27 | onPrepare() { 28 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | const resolve = require('rollup-plugin-node-resolve'); 2 | const replace = require('rollup-plugin-replace'); 3 | 4 | const globals = { 5 | '@angular/core': 'ng.core', 6 | '@angular/common': 'ng.common', 7 | '@angular/platform-browser': 'ng.platformBrowser', 8 | '@angular/router': 'ng.router', 9 | '@angular/forms': 'ng.forms', 10 | '@angular/common/http': 'ng.common.http', 11 | 12 | 'ng-zorro-antd': 'ngZorro.antd', 13 | 14 | 'rxjs/observable/fromEvent': 'Rx.Observable' 15 | }; 16 | 17 | module.exports = { 18 | sourcemap: true, 19 | rollup: require('rollup'), 20 | context: 'this', 21 | name: 'ngZorro.antd_extra', 22 | output: 'ng-zorro-antd-extra.umd.js', 23 | format: 'umd', 24 | plugins: [ 25 | replace({ "import * as moment": "import moment" }), 26 | resolve({ 27 | jsnext: true, 28 | main: true 29 | }) 30 | ], 31 | external: Object.keys(globals), 32 | globals: globals 33 | }; 34 | -------------------------------------------------------------------------------- /scripts/inline-resources.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | const glob = require('glob'); 8 | 9 | /** 10 | * Simple Promiseify function that takes a Node API and return a version that supports promises. 11 | * We use promises instead of synchronized functions to make the process less I/O bound and 12 | * faster. It also simplify the code. 13 | */ 14 | function promiseify(fn) { 15 | return function () { 16 | const args = [].slice.call(arguments, 0); 17 | return new Promise((resolve, reject) => { 18 | fn.apply(this, args.concat([function (err, value) { 19 | if (err) { 20 | reject(err); 21 | } else { 22 | resolve(value); 23 | } 24 | }])); 25 | }); 26 | }; 27 | } 28 | 29 | const readFile = promiseify(fs.readFile); 30 | const writeFile = promiseify(fs.writeFile); 31 | 32 | 33 | function inlineResources(globs) { 34 | if (typeof globs == 'string') { 35 | globs = [globs]; 36 | } 37 | 38 | /** 39 | * For every argument, inline the templates and styles under it and write the new file. 40 | */ 41 | return Promise.all(globs.map(pattern => { 42 | if (pattern.indexOf('*') < 0) { 43 | // Argument is a directory target, add glob patterns to include every files. 44 | pattern = path.join(pattern, '**', '*'); 45 | } 46 | 47 | const files = glob.sync(pattern, {}) 48 | .filter(name => /\.js$/.test(name)); // Matches only JavaScript files. 49 | 50 | // Generate all files content with inlined templates. 51 | return Promise.all(files.map(filePath => { 52 | return readFile(filePath, 'utf-8') 53 | .then(content => inlineResourcesFromString(content, url => { 54 | return path.join(path.dirname(filePath), url); 55 | })) 56 | .then(content => writeFile(filePath, content)) 57 | .catch(err => { 58 | console.error('An error occurred: ', err); 59 | }); 60 | })); 61 | })); 62 | } 63 | 64 | /** 65 | * Inline resources from a string content. 66 | * @param content {string} The source file's content. 67 | * @param urlResolver {Function} A resolver that takes a URL and return a path. 68 | * @returns {string} The content with resources inlined. 69 | */ 70 | function inlineResourcesFromString(content, urlResolver) { 71 | // Curry through the inlining functions. 72 | return [ 73 | inlineTemplate, 74 | inlineStyle, 75 | removeModuleId 76 | ].reduce((content, fn) => fn(content, urlResolver), content); 77 | } 78 | 79 | if (require.main === module) { 80 | inlineResources(process.argv.slice(2)); 81 | } 82 | 83 | 84 | /** 85 | * Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and 86 | * replace with `template: ...` (with the content of the file included). 87 | * @param content {string} The source file's content. 88 | * @param urlResolver {Function} A resolver that takes a URL and return a path. 89 | * @return {string} The content with all templates inlined. 90 | */ 91 | function inlineTemplate(content, urlResolver) { 92 | return content.replace(/templateUrl:\s*'([^']+?\.html)'/g, function (m, templateUrl) { 93 | const templateFile = urlResolver(templateUrl); 94 | const templateContent = fs.readFileSync(templateFile, 'utf-8'); 95 | const shortenedTemplate = templateContent 96 | .replace(/([\n\r]\s*)+/gm, ' ') 97 | .replace(/"/g, '\\"'); 98 | return `template: "${shortenedTemplate}"`; 99 | }); 100 | } 101 | 102 | 103 | /** 104 | * Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and 105 | * replace with `styles: [...]` (with the content of the file included). 106 | * @param urlResolver {Function} A resolver that takes a URL and return a path. 107 | * @param content {string} The source file's content. 108 | * @return {string} The content with all styles inlined. 109 | */ 110 | function inlineStyle(content, urlResolver) { 111 | return content.replace(/styleUrls:\s*(\[[\s\S]*?\])/gm, function (m, styleUrls) { 112 | const urls = eval(styleUrls); 113 | return 'styles: [' + 114 | urls.map(styleUrl => { 115 | const styleFile = urlResolver(styleUrl); 116 | const styleContent = fs.readFileSync(styleFile, 'utf-8'); 117 | const shortenedStyle = styleContent 118 | .replace(/([\n\r]\s*)+/gm, ' ') 119 | .replace(/content: "([^"]+)"/g, 'content: "\\$1"') 120 | .replace(/"/g, '\\"'); 121 | return `"${shortenedStyle}"`; 122 | }) 123 | .join(',\n') + 124 | ']'; 125 | }); 126 | } 127 | 128 | 129 | /** 130 | * Remove every mention of `moduleId: module.id`. 131 | * @param content {string} The source file's content. 132 | * @returns {string} The content with all moduleId: mentions removed. 133 | */ 134 | function removeModuleId(content) { 135 | return content.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, ''); 136 | } 137 | 138 | 139 | module.exports = inlineResources; 140 | module.exports.inlineResourcesFromString = inlineResourcesFromString; 141 | -------------------------------------------------------------------------------- /scripts/test.ts: -------------------------------------------------------------------------------- 1 | import '../demo/src/polyfills.ts'; 2 | 3 | import 'zone.js/dist/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | import { getTestBed } from '@angular/core/testing'; 10 | import { 11 | BrowserDynamicTestingModule, 12 | platformBrowserDynamicTesting 13 | } from '@angular/platform-browser-dynamic/testing'; 14 | 15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 16 | declare var __karma__: any; 17 | declare var require: any; 18 | 19 | // Prevent Karma from running prematurely. 20 | __karma__.loaded = Function.prototype; 21 | 22 | // First, initialize the Angular testing environment. 23 | getTestBed().initTestEnvironment( 24 | BrowserDynamicTestingModule, 25 | platformBrowserDynamicTesting() 26 | ); 27 | // Then we find all the tests. 28 | const context = require.context('../demo/src', true, /\.spec\.ts/); 29 | // And load the modules. 30 | context.keys().map(context); 31 | 32 | const context2 = require.context('../src/spec', true, /\.spec\.ts/); 33 | context2.keys().map(context2); 34 | // Finally, start Karma to run the tests. 35 | __karma__.start(); 36 | -------------------------------------------------------------------------------- /scripts/typings.d.ts: -------------------------------------------------------------------------------- 1 | // Typings reference file, you can add your own global typings here 2 | // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html 3 | // tslint:disable 4 | declare const System: any; 5 | declare const ENV: string; 6 | // google code-prettify 7 | declare const PR: any; 8 | 9 | declare module jasmine { 10 | interface Matchers { 11 | toHaveCssClass(expected: any): boolean; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ModuleWithProviders } from '@angular/core'; 2 | 3 | import { NzListModule } from './nz-list/nz-list.module'; 4 | import { NzCardModule } from './nz-card/nz-card.module'; 5 | import { NzDividerModule } from './nz-divider/nz-divider.module'; 6 | import { NzIconModule } from './nz-icon/nz-icon.module'; 7 | import { NzRadioExtraModule } from './nz-radio-extra/nz-radio-extra.module'; 8 | 9 | export * from './nz-list'; 10 | export * from './nz-card'; 11 | export * from './nz-divider'; 12 | export * from './nz-icon'; 13 | export * from './nz-radio-extra'; 14 | 15 | const MODULES = [ 16 | NzListModule, 17 | NzCardModule, 18 | NzDividerModule, 19 | NzIconModule, 20 | NzRadioExtraModule 21 | ]; 22 | 23 | @NgModule({ 24 | imports: MODULES, 25 | exports: MODULES 26 | }) 27 | export class NgZorroAntdExtraRootModule { 28 | } 29 | 30 | @NgModule({ exports: MODULES }) 31 | export class NgZorroAntdExtraModule { 32 | public static forRoot(): ModuleWithProviders { 33 | return { ngModule: NgZorroAntdExtraRootModule }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/nz-card/index.md: -------------------------------------------------------------------------------- 1 | > 由于组件名可能跟 2.x 会有所冲突,因此建议[按需加载](../../demo/src/app/app.module.ts) `ng-zorro-antd` 并排除 `nz-card`。 2 | 3 | ## API 4 | 5 | ### `nz-card` 6 | 7 | | Name | Type | Default | Summary | 8 | | ------- | ------------- | ----- | ----- | 9 | | nzBordered | `Boolean` | `true` | 是否有边框 | 10 | | [过期] nzNoHovering | `boolean` | `false` | 取消鼠标移过浮起,已过期请使用 `nzHoverable` | 11 | | nzHoverable | `Boolean` | - | 鼠标移过浮起 | 12 | | nzLoading | `boolean` | | 是否显示加载状态 | 13 | | nzType | `inner` | | 卡片类型,可设置为 `inner` 或 不设置 | 14 | | nzTitle | `string, TemplateRef` | | 卡片标题 | 15 | | [过期] #title | `TemplateRef` | | 卡片标题,请尽可能使用 `nzTitle` | 16 | | #extra | `TemplateRef` | | 卡片右上角的操作区域 | 17 | | #cover | `TemplateRef` | | 卡片封面区域 | 18 | | #body | `TemplateRef` | | 内容区域,默认情况下也可以无须指定,因为 `` 内容都被认为是内容区域 | 19 | | nzBodyStyle | `Object` | | 内容区域样式列表 | 20 | | nzTabSelectedIndex | `number` | | 默认激活的Tab Index | 21 | | nzTabChange | `EventEmitter` | | 点击选项卡事件回调,当内容包括 `nz-card-tab` 组件时有效 | 22 | | nzNoPadding | `boolean` | | 无内边距 `body`,虽 antd for react 无该属性,但实际项目中它很常用 | 23 | 24 | ### `nz-card-action` 25 | 26 | 操作区域组件,放置在内容区域中,使用方式见示例。 27 | 28 | ### `nz-card-grid` 29 | 30 | 网格型内嵌卡片。 31 | 32 | ### `nz-card-tab` 33 | 34 | 卡片选项卡组件,放置在内容区域中,使用方式见示例。 其中 `` 为选项卡内容。 35 | 36 | | Name | Type | Default | Summary | 37 | | ------- | ------------- | ----- | ----- | 38 | | nzTabHeading | `string, TemplateRef` | | 选项卡标题 | 39 | 40 | ### `nz-card-meta` 41 | 42 | | Name | Type | Default | Summary | 43 | | ------- | ------------- | ----- | ----- | 44 | | nzAvatar | `string, TemplateRef` | | 头像/图标 | 45 | | nzTitle | `string, TemplateRef` | | 标题内容 | 46 | | nzDescription | `string, TemplateRef` | | 描述内容 | 47 | 48 | ## DEMO 49 | 50 | ```html 51 | 52 |

Card content

53 |

Card content

54 |

Card content

55 |
56 | ``` 57 | -------------------------------------------------------------------------------- /src/nz-card/index.ts: -------------------------------------------------------------------------------- 1 | export { NzCardComponent } from './nz-card.component'; 2 | export { NzCardTabComponent } from './nz-card-tab.component'; 3 | export { NzCardMetaComponent } from './nz-card-meta.component'; 4 | export { NzCardGridDirective } from './nz-card-grid.directive'; 5 | export { NzCardActionComponent } from './nz-card-action.component'; 6 | export { NzCardModule } from './nz-card.module'; 7 | -------------------------------------------------------------------------------- /src/nz-card/nz-card-action.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, TemplateRef, ViewChild } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'nz-card-action', 5 | template: `` 6 | }) 7 | export class NzCardActionComponent { 8 | 9 | @ViewChild('tpl') tpl: TemplateRef; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/nz-card/nz-card-grid.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostBinding } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[nz-card-grid]' 5 | }) 6 | export class NzCardGridDirective { 7 | @HostBinding('class.ant-card-grid') _nzCardGrid = true; 8 | } 9 | -------------------------------------------------------------------------------- /src/nz-card/nz-card-meta.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ContentChild, TemplateRef, HostBinding } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'nz-card-meta', 5 | template: ` 6 |
7 |
8 | 9 |
10 |
11 |
12 | {{ _title }} 13 |
14 |
15 | {{ _desc }} 16 |
17 |
18 |
19 | ` 20 | }) 21 | export class NzCardMetaComponent { 22 | 23 | @HostBinding('class.ant-card-meta') 24 | _nzListItemMeta = true; 25 | 26 | avatar = false; 27 | _avatar = ''; 28 | _avatarTpl: TemplateRef; 29 | @Input() 30 | set nzAvatar(value: string | TemplateRef) { 31 | if (value instanceof TemplateRef) 32 | this._avatarTpl = value; 33 | else 34 | this._avatar = value; 35 | 36 | this.avatar = !!value; 37 | } 38 | 39 | title = false; 40 | _title = ''; 41 | _titleTpl: TemplateRef; 42 | @Input() 43 | set nzTitle(value: string | TemplateRef) { 44 | if (value instanceof TemplateRef) 45 | this._titleTpl = value; 46 | else 47 | this._title = value; 48 | 49 | this.title = !!value; 50 | } 51 | 52 | desc = false; 53 | _desc = ''; 54 | _descTpl: TemplateRef; 55 | @Input() 56 | set nzDescription(value: string | TemplateRef) { 57 | if (value instanceof TemplateRef) 58 | this._descTpl = value; 59 | else 60 | this._desc = value; 61 | 62 | this.desc = !!value; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/nz-card/nz-card-tab.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, TemplateRef, Input, ViewChild } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'nz-card-tab', 5 | template: `` 6 | }) 7 | export class NzCardTabComponent { 8 | 9 | // region: fieds 10 | 11 | _title = ''; 12 | _titleTpl: TemplateRef; 13 | @Input() 14 | set nzTabHeading(value: string | TemplateRef) { 15 | if (value instanceof TemplateRef) 16 | this._titleTpl = value; 17 | else 18 | this._title = value; 19 | } 20 | 21 | // endregion 22 | 23 | @ViewChild('titleTpl') titleTpl: TemplateRef; 24 | 25 | @ViewChild('contentTpl') contentTpl: TemplateRef; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/nz-card/nz-card.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | {{ _title }} 5 |
6 |
7 | 8 |
9 |
10 | 11 | 12 | 13 | {{ i._title }} 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |

22 |

23 | 24 | 25 |

26 |

27 | 28 | 29 |

30 |

31 | 32 | 33 |

34 |

35 | 36 | 37 | 38 |

39 |
40 |
41 |
42 | 43 | 44 |
45 |
    46 |
  • 47 | 48 |
  • 49 |
50 | -------------------------------------------------------------------------------- /src/nz-card/nz-card.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation, TemplateRef, Input, ContentChildren, QueryList, OnInit, AfterViewInit, ElementRef, Renderer2, OnChanges, SimpleChanges, ContentChild, EventEmitter, Output } from '@angular/core'; 2 | import { NzCardTabComponent } from './nz-card-tab.component'; 3 | import { NzCardGridDirective } from './nz-card-grid.directive'; 4 | import { NzCardActionComponent } from './nz-card-action.component'; 5 | 6 | @Component({ 7 | selector: 'nz-card', 8 | templateUrl: './nz-card.component.html', 9 | styleUrls: [ 10 | './style/index.less', 11 | './style/patch.less' 12 | ], 13 | encapsulation: ViewEncapsulation.None 14 | }) 15 | export class NzCardComponent implements OnInit, OnChanges, AfterViewInit { 16 | 17 | // region: fieds 18 | 19 | @Input() nzLoading = false; 20 | 21 | @Input() nzBordered = true; 22 | 23 | @Input() nzHoverable: boolean; 24 | 25 | @Input() nzNoPadding: boolean; 26 | 27 | @Input() nzBodyStyle: Object; 28 | 29 | // @deprecated 过期属性,请使用 `nzHoverable` 30 | @Input() nzNoHovering: boolean; 31 | 32 | @Input() nzType?: 'inner'; 33 | 34 | _titleHas = false; 35 | _title = ''; 36 | _titleTpl: TemplateRef; 37 | @Input() 38 | set nzTitle(value: string | TemplateRef) { 39 | if (value instanceof TemplateRef) 40 | this._titleTpl = value; 41 | else 42 | this._title = value; 43 | 44 | this._titleHas = !!value; 45 | } 46 | 47 | // @deprecated 过期属性,请使用 `nzTitle` 48 | @ContentChild('title') title: TemplateRef; 49 | 50 | @ContentChild('extra') extra: TemplateRef; 51 | 52 | @ContentChild('cover') cover: TemplateRef; 53 | 54 | @ContentChild('body') body: TemplateRef; 55 | 56 | @Input() nzTabSelectedIndex = 0; 57 | 58 | @Output() nzTabChange: EventEmitter = new EventEmitter(true); 59 | 60 | @ContentChildren(NzCardTabComponent) tabList: QueryList; 61 | 62 | @ContentChildren(NzCardGridDirective) gridList: QueryList; 63 | 64 | @ContentChildren(NzCardActionComponent) actionList: QueryList; 65 | 66 | _tabContent: TemplateRef; 67 | 68 | // endregion 69 | 70 | // region: set class 71 | 72 | _prefixCls = 'ant-card'; 73 | _classList: string[] = []; 74 | 75 | // For 2.x compatible 76 | getCompatibleHoverable() { 77 | const status = typeof this.nzHoverable !== 'undefined' && this.nzHoverable !== false; 78 | if (typeof this.nzNoHovering !== 'undefined') { 79 | return !this.nzNoHovering || status; 80 | } 81 | return status; 82 | } 83 | 84 | _setClassMap() { 85 | this._classList.forEach(cls => this._renderer.removeClass(this._el.nativeElement, cls)); 86 | 87 | this._classList = [ 88 | this._prefixCls, 89 | this.nzLoading && `${this._prefixCls}-loading`, 90 | typeof this.nzBordered !== 'undefined' && this.nzBordered !== false && `${this._prefixCls}-bordered`, 91 | this.getCompatibleHoverable() && `${this._prefixCls}-hoverable`, 92 | typeof this.nzNoPadding !== 'undefined' && this.nzNoPadding !== false && `${this._prefixCls}-no-padding`, 93 | // padding-transition 94 | // transition 95 | this.gridList && this.gridList.length && `${this._prefixCls}-contain-grid`, 96 | this.tabList && this.tabList.length && `${this._prefixCls}-contain-tabs`, 97 | !!this.nzType && `${this._prefixCls}-type-${this.nzType}` 98 | ].filter(item => !!item); 99 | 100 | this._classList.forEach(cls => this._renderer.addClass(this._el.nativeElement, cls)); 101 | } 102 | 103 | // endregion 104 | 105 | constructor(private _el: ElementRef, private _renderer: Renderer2) { } 106 | 107 | ngOnInit() { 108 | } 109 | 110 | ngAfterViewInit(): void { 111 | this._setClassMap(); 112 | // 若在此进行 `body` 赋值会导致变化检测问题,因此 `setTimeout` 只是一个小技巧罢了 113 | setTimeout(() => { 114 | if (!this.body && this.tabList && this.tabList.length > 0) 115 | this.body = this.tabList.first.contentTpl; 116 | }); 117 | } 118 | 119 | ngOnChanges(changes: SimpleChanges): void { 120 | this._setClassMap(); 121 | } 122 | 123 | _tabChange(value: any) { 124 | this.body = this.tabList.find((item, idx) => idx === value.index).contentTpl; 125 | this.nzTabChange.emit(value); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/nz-card/nz-card.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NzSpinModule, NzTabsModule, NzAvatarModule } from 'ng-zorro-antd'; 4 | 5 | import { NzCardComponent } from './nz-card.component'; 6 | import { NzCardTabComponent } from './nz-card-tab.component'; 7 | import { NzCardMetaComponent } from './nz-card-meta.component'; 8 | import { NzCardGridDirective } from './nz-card-grid.directive'; 9 | import { NzCardActionComponent } from './nz-card-action.component'; 10 | 11 | @NgModule({ 12 | imports: [ CommonModule, NzSpinModule, NzTabsModule, NzAvatarModule ], 13 | declarations: [ NzCardComponent, NzCardTabComponent, NzCardMetaComponent, NzCardGridDirective, NzCardActionComponent ], 14 | exports: [ NzCardComponent, NzCardTabComponent, NzCardMetaComponent, NzCardGridDirective, NzCardActionComponent ] 15 | }) 16 | export class NzCardModule { 17 | } 18 | -------------------------------------------------------------------------------- /src/nz-card/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../style/themes/default"; 2 | @import "../../style/mixins/index"; 3 | 4 | @card-prefix-cls: ~"@{ant-prefix}-card"; 5 | @card-head-height: 48px; 6 | 7 | .@{card-prefix-cls} { 8 | .reset-component; 9 | background: @component-background; 10 | border-radius: @border-radius-sm; 11 | position: relative; 12 | transition: all .3s; 13 | 14 | &-hoverable { 15 | cursor: pointer; 16 | &:hover { 17 | box-shadow: @card-shadow; 18 | border-color: rgba(0, 0, 0, 0.09); 19 | } 20 | } 21 | 22 | &-bordered { 23 | border: @border-width-base @border-style-base @border-color-split; 24 | } 25 | 26 | &-head { 27 | background: @card-head-background; 28 | border-bottom: @border-width-base @border-style-base @border-color-split; 29 | padding: 0 @card-padding-base; 30 | border-radius: @border-radius-sm @border-radius-sm 0 0; 31 | .clearfix; 32 | margin-bottom: -1px; // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png 33 | min-height: @card-head-height; 34 | 35 | &-wrapper { 36 | display: flex; 37 | } 38 | 39 | &-title { 40 | font-size: @font-size-lg; 41 | padding: @card-head-padding 0; 42 | text-overflow: ellipsis; 43 | overflow: hidden; 44 | white-space: nowrap; 45 | color: @card-head-color; 46 | font-weight: 500; 47 | display: inline-block; 48 | flex: 1; 49 | } 50 | 51 | .@{ant-prefix}-tabs { 52 | margin-bottom: -17px; 53 | clear: both; 54 | 55 | &-bar { 56 | border-bottom: @border-width-base @border-style-base @border-color-split; 57 | } 58 | } 59 | } 60 | 61 | &-extra { 62 | float: right; 63 | padding: @card-head-padding + 1.5px 0; 64 | text-align: right; 65 | // https://stackoverflow.com/a/22429853/3040605 66 | margin-left: auto; 67 | } 68 | 69 | &-body { 70 | padding: @card-padding-base; 71 | .clearfix; 72 | } 73 | 74 | &-contain-grid &-body { 75 | margin: -1px 0 0 -1px; 76 | padding: 0; 77 | } 78 | 79 | &-grid { 80 | border-radius: 0; 81 | border: 0; 82 | box-shadow: 1px 0 0 0 @border-color-split, 0 1px 0 0 @border-color-split, 1px 1px 0 0 @border-color-split, 1px 0 0 0 @border-color-split inset, 0 1px 0 0 @border-color-split inset; 83 | width: 33.33%; 84 | float: left; 85 | padding: @card-padding-base; 86 | transition: all .3s; 87 | &:hover { 88 | position: relative; 89 | z-index: 1; 90 | box-shadow: @box-shadow-base; 91 | } 92 | } 93 | 94 | &-contain-tabs &-head-title { 95 | padding-bottom: 0; 96 | min-height: @card-head-height - @card-head-padding; 97 | } 98 | 99 | &-contain-tabs &-extra { 100 | padding-bottom: 0; 101 | } 102 | 103 | &-cover > * { 104 | width: 100%; 105 | display: block; 106 | } 107 | 108 | &-actions { 109 | border-top: @border-width-base @border-style-base @border-color-split; 110 | background: @card-actions-background; 111 | .clearfix; 112 | list-style: none; 113 | margin: 0; 114 | padding: 0; 115 | 116 | & > li { 117 | float: left; 118 | text-align: center; 119 | margin: 12px 0; 120 | color: @text-color-secondary; 121 | 122 | & > span { 123 | display: inline-block; 124 | font-size: 14px; 125 | cursor: pointer; 126 | line-height: 22px; 127 | min-width: 32px; 128 | position: relative; 129 | 130 | &:hover { 131 | color: @primary-color; 132 | transition: color .3s; 133 | } 134 | 135 | & > .anticon { 136 | font-size: 16px; 137 | } 138 | 139 | a { 140 | color: @text-color-secondary; 141 | 142 | &:hover { 143 | color: @primary-color; 144 | } 145 | } 146 | } 147 | 148 | &:not(:last-child) { 149 | border-right: @border-width-base @border-style-base @border-color-split; 150 | } 151 | } 152 | } 153 | 154 | &-wider-padding &-head { 155 | padding: 0 @card-padding-wider; 156 | } 157 | 158 | &-wider-padding &-body { 159 | padding: @card-padding-base @card-padding-wider; 160 | } 161 | 162 | &-padding-transition &-head, 163 | &-padding-transition &-body { 164 | transition: padding .3s; 165 | } 166 | 167 | &-padding-transition &-extra { 168 | transition: right .3s; 169 | } 170 | 171 | &-type-inner &-head { 172 | padding: 0 @card-padding-base; 173 | background: @background-color-light; 174 | 175 | &-title { 176 | padding: @card-inner-head-padding 0; 177 | font-size: @font-size-base; 178 | } 179 | } 180 | 181 | &-type-inner &-body { 182 | padding: 16px @card-padding-base; 183 | } 184 | 185 | &-type-inner &-extra { 186 | padding: @card-inner-head-padding + 1.5px 0; 187 | } 188 | 189 | &-meta { 190 | margin: -4px 0; 191 | 192 | &-content { 193 | display: table-row; 194 | } 195 | 196 | &-avatar { 197 | padding-right: 16px; 198 | display: table-cell; 199 | } 200 | 201 | &-detail { 202 | display: table-cell; 203 | vertical-align: top; 204 | position: relative; 205 | 206 | & > div:not(:last-child) { 207 | margin-bottom: 8px; 208 | } 209 | } 210 | 211 | &-title { 212 | font-size: @font-size-lg; 213 | text-overflow: ellipsis; 214 | width: 100%; 215 | overflow: hidden; 216 | white-space: nowrap; 217 | color: @card-head-color; 218 | font-weight: 500; 219 | } 220 | 221 | &-description { 222 | color: @text-color-secondary; 223 | } 224 | } 225 | 226 | &-loading &-body { 227 | user-select: none; 228 | padding: 0; 229 | } 230 | 231 | &-loading-content { 232 | padding: @card-padding-base; 233 | p { 234 | margin: 0; 235 | } 236 | } 237 | 238 | &-loading-block { 239 | display: inline-block; 240 | margin: 5px 2% 0 0; 241 | height: 14px; 242 | border-radius: @border-radius-sm; 243 | background: linear-gradient(90deg, rgba(207, 216, 220, .2), rgba(207, 216, 220, .4), rgba(207, 216, 220, .2)); 244 | animation: card-loading 1.4s ease infinite; 245 | background-size: 600% 600%; 246 | } 247 | } 248 | 249 | @keyframes card-loading { 250 | 0%, 251 | 100% { 252 | background-position: 0 50%; 253 | } 254 | 50% { 255 | background-position: 100% 50%; 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /src/nz-card/style/patch.less: -------------------------------------------------------------------------------- 1 | nz-card { 2 | &, 3 | nz-card-meta { 4 | display: block; 5 | } 6 | 7 | // body 无边距 8 | &.ant-card-no-padding { 9 | .ant-card-body { 10 | padding: 0; 11 | } 12 | } 13 | 14 | // 2.x:并没有 `large` 标签,因此:暂时解决方案 15 | .ant-tabs-large .ant-tabs-tab { 16 | padding: 16px; 17 | } 18 | .ant-tabs-nav .ant-tabs-tab-active { 19 | font-weight: 500; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/nz-divider/index.md: -------------------------------------------------------------------------------- 1 | ## API 2 | 3 | ### `nz-divider` 4 | 5 | | Name | Type | Default | Summary | 6 | | ------- | ------------- | ----- | ----- | 7 | | nzTitle | `string, TemplateRef` | | 文本标题 | 8 | | nzType | `horizontal,vertical` | `horizontal` | direction type of divider | 9 | | nzDashed | `Boolean` | `false` | whether line is dasded | 10 | 11 | ## DEMO 12 | 13 | ```html 14 | 15 | 16 | 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /src/nz-divider/index.ts: -------------------------------------------------------------------------------- 1 | export { NzDividerComponent } from './nz-divider.component'; 2 | export { NzDividerModule } from './nz-divider.module'; 3 | -------------------------------------------------------------------------------- /src/nz-divider/nz-divider.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation, TemplateRef, Input, ElementRef, Renderer2, OnChanges, SimpleChanges, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'nz-divider', 5 | template: ` 6 | 7 | {{ _title }} 8 | 9 | `, 10 | styleUrls: [ 11 | './style/index.less', 12 | './style/patch.less' 13 | ], 14 | encapsulation: ViewEncapsulation.None 15 | }) 16 | export class NzDividerComponent implements OnChanges, OnInit { 17 | 18 | // region fields 19 | 20 | title = false; 21 | _title = ''; 22 | _titleTpl: TemplateRef; 23 | @Input() 24 | set nzTitle(value: string | TemplateRef) { 25 | if (value instanceof TemplateRef) 26 | this._titleTpl = value; 27 | else 28 | this._title = value; 29 | this.title = !!value; 30 | } 31 | 32 | @Input() nzType: 'horizontal' | 'vertical' = 'horizontal'; 33 | 34 | @Input() nzDashed = false; 35 | 36 | // endregion 37 | 38 | _classMap: string[] = []; 39 | setClass() { 40 | this._classMap.forEach(cls => this.renderer.removeClass(this.el.nativeElement, cls)); 41 | 42 | this._classMap = [ 'ant-divider', `ant-divider-${this.nzType}` ]; 43 | 44 | if (this.title) 45 | this._classMap.push(`ant-divider-with-text`); 46 | 47 | if (typeof this.nzDashed !== 'undefined' && this.nzDashed !== false) 48 | this._classMap.push(`ant-divider-dashed`); 49 | 50 | this._classMap.forEach(cls => this.renderer.addClass(this.el.nativeElement, cls)); 51 | } 52 | 53 | constructor(private el: ElementRef, private renderer: Renderer2) {} 54 | 55 | ngOnChanges(changes: SimpleChanges): void { 56 | this.setClass(); 57 | } 58 | 59 | ngOnInit() { 60 | this.setClass(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/nz-divider/nz-divider.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { NzDividerComponent } from './nz-divider.component'; 5 | 6 | @NgModule({ 7 | imports: [ CommonModule ], 8 | declarations: [ NzDividerComponent ], 9 | exports: [ NzDividerComponent ] 10 | }) 11 | export class NzDividerModule { 12 | } 13 | -------------------------------------------------------------------------------- /src/nz-divider/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../style/themes/default"; 2 | @import "../../style/mixins/index"; 3 | 4 | @divider-prefix-cls: ~"@{ant-prefix}-divider"; 5 | 6 | .@{divider-prefix-cls} { 7 | .reset-component; 8 | background: @border-color-split; 9 | 10 | &, // for compatiable 11 | &-vertical { 12 | margin: 0 8px; 13 | display: inline-block; 14 | height: 0.9em; 15 | width: 1px; 16 | vertical-align: middle; 17 | position: relative; 18 | top: -0.06em; 19 | } 20 | &-horizontal { 21 | display: block; 22 | height: 1px; 23 | width: 100%; 24 | margin: 24px 0; 25 | } 26 | &-horizontal&-with-text { 27 | display: table; 28 | white-space: nowrap; 29 | text-align: center; 30 | background: transparent; 31 | font-weight: 500; 32 | color: @heading-color; 33 | font-size: @font-size-lg; 34 | margin: 16px 0; 35 | 36 | &:before, 37 | &:after { 38 | content: ''; 39 | display: table-cell; 40 | position: relative; 41 | top: 50%; 42 | width: 50%; 43 | border-top: 1px solid @border-color-split; 44 | transform: translateY(50%); 45 | } 46 | } 47 | 48 | &-inner-text { 49 | display: inline-block; 50 | padding: 0 24px; 51 | } 52 | 53 | &-dashed { 54 | background: none; 55 | border-top: 1px dashed @border-color-split; 56 | } 57 | 58 | &-horizontal&-with-text&-dashed { 59 | border-top: 0; 60 | &:before, 61 | &:after { 62 | border-style: dashed none none; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/nz-divider/style/index.tsx: -------------------------------------------------------------------------------- 1 | import '../../style/index.less'; 2 | import './index.less'; 3 | -------------------------------------------------------------------------------- /src/nz-divider/style/patch.less: -------------------------------------------------------------------------------- 1 | nz-divider { 2 | display: block; 3 | } 4 | -------------------------------------------------------------------------------- /src/nz-icon/index.md: -------------------------------------------------------------------------------- 1 | ## API 2 | 3 | ### `nz-icon` 4 | 5 | | Name | Type | Default | Summary | 6 | | ------- | ------------- | ----- | ----- | 7 | | nzSpin | `boolean` | `false` | Rotate icon with animation | 8 | | nzType | `string` | - | Type of ant design icon | 9 | 10 | ## DEMO 11 | 12 | ```html 13 | 14 | 15 | ``` 16 | -------------------------------------------------------------------------------- /src/nz-icon/index.ts: -------------------------------------------------------------------------------- 1 | export { NzIconComponent } from './nz-icon.component'; 2 | export { NzIconModule } from './nz-icon.module'; 3 | -------------------------------------------------------------------------------- /src/nz-icon/nz-icon.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation, Input, ElementRef, Renderer2, SimpleChanges, OnChanges } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'nz-icon', 5 | template: ``, 6 | styleUrls: [ 7 | './style/patch.less' 8 | ], 9 | encapsulation: ViewEncapsulation.None 10 | }) 11 | export class NzIconComponent implements OnChanges { 12 | 13 | @Input() nzSpin = false; 14 | 15 | @Input() nzType: string; 16 | 17 | _classMap: string[] = []; 18 | setClass() { 19 | this._classMap.forEach(cls => this.renderer.removeClass(this.el.nativeElement, cls)); 20 | 21 | this._classMap = [ 'anticon' ]; 22 | 23 | if (typeof this.nzSpin !== 'undefined' && this.nzSpin !== false) 24 | this._classMap.push(`anticon-spin`); 25 | 26 | if (this.nzType) this._classMap.push(`anticon-${this.nzType}`); 27 | 28 | this._classMap.forEach(cls => this.renderer.addClass(this.el.nativeElement, cls)); 29 | } 30 | 31 | constructor(private el: ElementRef, private renderer: Renderer2) {} 32 | 33 | ngOnChanges(changes: SimpleChanges): void { 34 | this.setClass(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/nz-icon/nz-icon.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { NzIconComponent } from './nz-icon.component'; 5 | 6 | @NgModule({ 7 | imports: [ CommonModule ], 8 | declarations: [ NzIconComponent ], 9 | exports: [ NzIconComponent ] 10 | }) 11 | export class NzIconModule { 12 | } 13 | -------------------------------------------------------------------------------- /src/nz-icon/style/index.tsx: -------------------------------------------------------------------------------- 1 | import '../../style/index.less'; 2 | -------------------------------------------------------------------------------- /src/nz-icon/style/patch.less: -------------------------------------------------------------------------------- 1 | nz-icon { 2 | display: inline-block; 3 | } 4 | -------------------------------------------------------------------------------- /src/nz-list/index.md: -------------------------------------------------------------------------------- 1 | ## API 2 | 3 | ### `nz-list` 4 | 5 | | Name | Type | Default | Summary | 6 | | ------- | ------------- | ----- | ----- | 7 | | nzDataSource | `any[]` | | Data record array to be displayed | 8 | | nzBordered | `boolean` | `false` | Toggles rendering of the border around the list | 9 | | nzGrid | `NzListGrid` | | The grid type of list. You can set grid to something like `{ gutter: 16, span: 6 }` | 10 | | item | `TemplateRef` | | List item renderer | 11 | | nzHeader | `string, TemplateRef` | | List header renderer | 12 | | nzFooter | `string, TemplateRef` | | List footer renderer | 13 | | nzSize | `default,small,large` | `default` | Size of list | 14 | | nzItemLayout | `horizontal,vertical` | `horizontal` | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | 15 | | nzLoading | `boolean` | | Shows a loading indicator while the contents of the list are being fetched | 16 | | loadMore | `TemplateRef` | | Shows a load more content | 17 | | pagination | `TemplateRef` | | Shows a pagination content | 18 | | nzSplit | `boolean` | | Toggles rendering of the split under the list item | 19 | 20 | ### `NzListGrid` 21 | 22 | | Name | Type | Default | Summary | 23 | | ------- | ------------- | ----- | ----- | 24 | | span | `number` | | raster number of cells to occupy, 0 corresponds to `display: none` | 25 | | gutter | `number` | | spacing between grids | 26 | | xs | `number` | | `<768px` and also default setting, could be a `span` value or an object containing above props | 27 | | sm | `number` | | `≥768px`, could be a `span` value or an object containing above props | 28 | | md | `number` | | `≥992px`, could be a `span` value or an object containing above props | 29 | | lg | `number` | | `≥1200px`, could be a `span` value or an object containing above props | 30 | | xl | `number` | | `≥1600px`, could be a `span` value or an object containing above props | 31 | | xxl | `number` | | only supported antd 3.x | 32 | 33 | ### `nz-list-item` 34 | 35 | | Name | Type | Default | Summary | 36 | | ------- | ------------- | ----- | ----- | 37 | | nzContent | `string, TemplateRef` | | Content renderer | 38 | | nzExtra | `string, TemplateRef` | | The extra content of list item. If `itemLayout` is `vertical`, shows the content on right, otherwise shows content on the far right. | 39 | 40 | ### `nz-list-item-action` 41 | 42 | The actions content of list item. If itemLayout is vertical, shows the content on bottom, otherwise shows content on the far right. 43 | 44 | ### `nz-list-item-meta` 45 | 46 | | Name | Type | Default | Summary | 47 | | ------- | ------------- | ----- | ----- | 48 | | nzAvatar | `string, TemplateRef` | | The avatar of list item | 49 | | nzDescription | `string, TemplateRef` | | The description of list item | 50 | | nzTitle | `string, TemplateRef` | | The title of list item | 51 | 52 | ## DEMO 53 | 54 | ```typescript 55 | import { Component, OnInit, ViewEncapsulation } from '@angular/core'; 56 | 57 | @Component({ 58 | selector: 'demo-basic', 59 | template: ` 60 | 61 | 62 | 63 | 67 | 68 | {{item.title}} 69 | 70 | 71 | 72 | 73 | 74 | ` 75 | }) 76 | export class DemoBasicComponent { 77 | data = [ 78 | { 79 | title: 'Ant Design Title 1' 80 | }, 81 | { 82 | title: 'Ant Design Title 2' 83 | }, 84 | { 85 | title: 'Ant Design Title 3' 86 | }, 87 | { 88 | title: 'Ant Design Title 4' 89 | } 90 | ]; 91 | } 92 | ``` 93 | -------------------------------------------------------------------------------- /src/nz-list/index.ts: -------------------------------------------------------------------------------- 1 | export { NzListItemActionComponent } from './nz-list-item-action.component'; 2 | export { NzListItemMetaComponent } from './nz-list-item-meta.component'; 3 | export { NzListItemComponent } from './nz-list-item.component'; 4 | export { NzListComponent, NzListGrid } from './nz-list.component'; 5 | export { NzListModule } from './nz-list.module'; 6 | -------------------------------------------------------------------------------- /src/nz-list/nz-list-item-action.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, TemplateRef, ViewChild } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'nz-list-item-action', 5 | template: `` 6 | }) 7 | export class NzListItemActionComponent { 8 | 9 | @ViewChild('template') template: TemplateRef; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/nz-list/nz-list-item-meta.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ContentChild, TemplateRef, HostBinding } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'nz-list-item-meta', 5 | template: ` 6 |
7 | 8 |
9 |
10 |

11 | {{ _title }} 12 |

13 |
14 | {{ _desc }} 15 |
16 |
17 | ` 18 | }) 19 | export class NzListItemMetaComponent { 20 | 21 | @HostBinding('class.ant-list-item-meta') 22 | _nzListItemMeta = true; 23 | 24 | avatar = false; 25 | _avatar = ''; 26 | _avatarTpl: TemplateRef; 27 | @Input() 28 | set nzAvatar(value: string | TemplateRef) { 29 | if (value instanceof TemplateRef) 30 | this._avatarTpl = value; 31 | else 32 | this._avatar = value; 33 | 34 | this.avatar = !!value; 35 | } 36 | 37 | title = false; 38 | _title = ''; 39 | _titleTpl: TemplateRef; 40 | @Input() 41 | set nzTitle(value: string | TemplateRef) { 42 | if (value instanceof TemplateRef) 43 | this._titleTpl = value; 44 | else 45 | this._title = value; 46 | 47 | this.title = !!value; 48 | } 49 | 50 | desc = false; 51 | _desc = ''; 52 | _descTpl: TemplateRef; 53 | @Input() 54 | set nzDescription(value: string | TemplateRef) { 55 | if (value instanceof TemplateRef) 56 | this._descTpl = value; 57 | else 58 | this._desc = value; 59 | 60 | this.desc = !!value; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/nz-list/nz-list-item.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ContentChild, TemplateRef, HostBinding, QueryList, ContentChildren } from '@angular/core'; 2 | import { NzListItemActionComponent } from './nz-list-item-action.component'; 3 | 4 | @Component({ 5 | selector: 'nz-list-item', 6 | template: ` 7 | 8 | 9 |
10 | {{ _content }} 11 |
12 |
13 | 14 |
    15 |
  • 16 | 17 | 18 |
  • 19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 |
29 | {{ _extra }} 30 |
31 |
32 | ` 33 | }) 34 | export class NzListItemComponent { 35 | 36 | @HostBinding('class.ant-list-item') 37 | _nzListItem = true; 38 | 39 | @ContentChildren(NzListItemActionComponent) _actions: QueryList; 40 | 41 | content = false; 42 | _content = ''; 43 | _contentTpl: TemplateRef; 44 | @Input() 45 | set nzContent(value: string | TemplateRef) { 46 | if (value instanceof TemplateRef) 47 | this._contentTpl = value; 48 | else 49 | this._content = value; 50 | 51 | this.content = !!value; 52 | } 53 | 54 | extra = false; 55 | _extra = ''; 56 | _extraTpl: TemplateRef; 57 | @Input() 58 | set nzExtra(value: string | TemplateRef) { 59 | if (value instanceof TemplateRef) 60 | this._extraTpl = value; 61 | else 62 | this._extra = value; 63 | 64 | this.extra = !!value; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/nz-list/nz-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation, Input, TemplateRef, ContentChild, ElementRef, Renderer2, OnChanges, SimpleChanges, OnInit } from '@angular/core'; 2 | 3 | export interface NzListGrid { 4 | /** 列数 */ 5 | span?: number; 6 | /** 栅格间隔 */ 7 | gutter?: number; 8 | /** `<576px` 展示的列数 */ 9 | xs?: number; 10 | /** `≥576px` 展示的列数 */ 11 | sm?: number; 12 | /** `≥768px` 展示的列数 */ 13 | md?: number; 14 | /** `≥992px` 展示的列数 */ 15 | lg?: number; 16 | /** `≥1200px` 展示的列数 */ 17 | xl?: number; 18 | /** `≥1600px` 展示的列数,暂不支持2.x antd */ 19 | xxl?: number; 20 | } 21 | 22 | @Component({ 23 | selector: 'nz-list', 24 | template: ` 25 | 26 | 27 | 30 | 31 | 32 |
33 | {{ _header }} 34 |
35 | 36 |
37 |
39 | 42 |
43 |
44 |
45 | 46 | 47 |
48 | 49 |
50 | 53 | `, 54 | styleUrls: [ 55 | './style/index.less', 56 | './style/patch.less' 57 | ], 58 | encapsulation: ViewEncapsulation.None 59 | }) 60 | export class NzListComponent implements OnChanges, OnInit { 61 | 62 | // region: fields 63 | @Input() nzDataSource: any[] = []; 64 | @Input() nzBordered = false; 65 | @Input() nzGrid: NzListGrid; 66 | 67 | header = false; 68 | _header = ''; 69 | _headerTpl: TemplateRef; 70 | @Input() 71 | set nzHeader(value: string | TemplateRef) { 72 | if (value instanceof TemplateRef) 73 | this._headerTpl = value; 74 | else 75 | this._header = value; 76 | 77 | this.header = !!value; 78 | } 79 | 80 | footer = false; 81 | _footer = ''; 82 | _footerTpl: TemplateRef; 83 | @Input() 84 | set nzFooter(value: string | TemplateRef) { 85 | if (value instanceof TemplateRef) 86 | this._footerTpl = value; 87 | else 88 | this._footer = value; 89 | 90 | this.footer = !!value; 91 | } 92 | 93 | @ContentChild('item') nzItem: TemplateRef; 94 | @Input() nzSize: 'default' | 'small' | 'large' = 'default'; 95 | @Input() nzItemLayout: 'vertical' | 'horizontal' = 'horizontal'; 96 | @Input() nzLoading = false; 97 | @ContentChild('loadMore') nzLoadMore: TemplateRef; 98 | @ContentChild('pagination') nzPagination: TemplateRef; 99 | @Input() nzSplit = true; 100 | // endregion 101 | 102 | // region: styles 103 | 104 | _prefixCls = 'ant-list'; 105 | _classList: string[] = []; 106 | 107 | _setClassMap() { 108 | this._classList.forEach(cls => this._renderer.removeClass(this._el.nativeElement, cls)); 109 | 110 | this._classList = [ 111 | this._prefixCls, 112 | this.nzItemLayout === 'vertical' && `${this._prefixCls}-vertical`, 113 | this.nzSize === 'large' && `${this._prefixCls}-lg`, 114 | this.nzSize === 'small' && `${this._prefixCls}-sm`, 115 | this.nzSplit && `${this._prefixCls}-split`, 116 | this.nzBordered && `${this._prefixCls}-bordered`, 117 | this.nzLoading && `${this._prefixCls}-loading`, 118 | this.nzGrid && `${this._prefixCls}-grid`, 119 | !!(this.nzLoadMore || this.nzPagination || this.nzFooter) && `${this._prefixCls}-something-after-last-item` 120 | ].filter(item => !!item); 121 | 122 | this._classList.forEach(cls => this._renderer.addClass(this._el.nativeElement, cls)); 123 | } 124 | 125 | // endregion 126 | 127 | constructor(private _el: ElementRef, private _renderer: Renderer2) { } 128 | 129 | ngOnInit(): void { 130 | } 131 | 132 | ngOnChanges(changes: SimpleChanges): void { 133 | this._setClassMap(); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/nz-list/nz-list.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NzSpinModule, NzGridModule, NzAvatarModule } from 'ng-zorro-antd'; 4 | 5 | import { NzListComponent } from './nz-list.component'; 6 | import { NzListItemComponent } from './nz-list-item.component'; 7 | import { NzListItemActionComponent } from './nz-list-item-action.component'; 8 | import { NzListItemMetaComponent } from './nz-list-item-meta.component'; 9 | 10 | @NgModule({ 11 | imports: [ CommonModule, NzSpinModule, NzGridModule, NzAvatarModule ], 12 | declarations: [ NzListComponent, NzListItemComponent, NzListItemMetaComponent, NzListItemActionComponent ], 13 | exports: [ NzListComponent, NzListItemComponent, NzListItemMetaComponent, NzListItemActionComponent ] 14 | }) 15 | export class NzListModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/nz-list/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../style/themes/default"; 2 | @import "../../style/mixins/index"; 3 | 4 | @list-prefix-cls: ~"@{ant-prefix}-list"; 5 | 6 | .@{list-prefix-cls} { 7 | .reset-component; 8 | position: relative; 9 | * { 10 | outline: none; 11 | } 12 | &-pagination { 13 | margin-top: 24px; 14 | text-align: right; 15 | } 16 | &-more { 17 | margin-top: 12px; 18 | text-align: center; 19 | button { 20 | padding-left: 32px; 21 | padding-right: 32px; 22 | } 23 | } 24 | &-spin { 25 | text-align: center; 26 | min-height: 40px; 27 | } 28 | &-item { 29 | align-items: center; 30 | display: flex; 31 | padding-top: 12px; 32 | padding-bottom: 12px; 33 | &-meta { 34 | align-items: flex-start; 35 | display: flex; 36 | font-size: 0; 37 | &-avatar { 38 | flex: 0; 39 | margin-right: 16px; 40 | } 41 | &-content { 42 | flex: 1 0; 43 | } 44 | &-title { 45 | color: @text-color; 46 | margin-bottom: 4px; 47 | font-size: @font-size-base; 48 | line-height: 22px; 49 | > a { 50 | color: @text-color; 51 | transition: all .3s; 52 | &:hover { 53 | color: @primary-color; 54 | } 55 | } 56 | } 57 | &-description { 58 | color: @text-color-secondary; 59 | font-size: @font-size-base; 60 | line-height: 22px; 61 | } 62 | } 63 | &-content { 64 | display: flex; 65 | flex: 1; 66 | justify-content: flex-end; 67 | } 68 | &-content-single { 69 | justify-content: flex-start; 70 | } 71 | &-action { 72 | font-size: 0; 73 | flex: 0 0 auto; 74 | margin-left: 48px; 75 | padding: 0; 76 | list-style: none; 77 | & > li { 78 | display: inline-block; 79 | color: @text-color-secondary; 80 | cursor: pointer; 81 | padding: 0 8px; 82 | position: relative; 83 | font-size: @font-size-base; 84 | line-height: 22px; 85 | text-align: center; 86 | } 87 | & > li:first-child { 88 | padding-left: 0; 89 | } 90 | &-split { 91 | background-color: @border-color-split; 92 | margin-top: -7px; 93 | position: absolute; 94 | top: 50%; 95 | right: 0; 96 | width: 1px; 97 | height: 14px; 98 | } 99 | } 100 | &-main { 101 | display: flex; 102 | flex: 1; 103 | } 104 | &-extra { 105 | flex: 0; 106 | } 107 | } 108 | &-header, 109 | &-footer { 110 | padding-top: 12px; 111 | padding-bottom: 12px; 112 | } 113 | } 114 | 115 | .@{list-prefix-cls}-split { 116 | .@{list-prefix-cls}-item { 117 | border-bottom: 1px solid @border-color-split; 118 | &:last-child { 119 | border-bottom: none; 120 | } 121 | } 122 | .@{list-prefix-cls}-header { 123 | border-bottom: 1px solid @border-color-split; 124 | } 125 | } 126 | 127 | .@{list-prefix-cls}-loading { 128 | .@{ant-prefix}-spin-nested-loading { 129 | min-height: 32px; 130 | } 131 | } 132 | 133 | .@{list-prefix-cls}-bordered { 134 | border-radius: @border-radius-base; 135 | border: 1px solid @border-color-base; 136 | .@{list-prefix-cls}-header { 137 | padding-left: 24px; 138 | padding-right: 24px; 139 | } 140 | .@{list-prefix-cls}-footer { 141 | padding-left: 24px; 142 | padding-right: 24px; 143 | } 144 | .@{list-prefix-cls}-item { 145 | border-bottom: 1px solid @border-color-split; 146 | padding-left: 24px; 147 | padding-right: 24px; 148 | } 149 | } 150 | 151 | .@{list-prefix-cls}-something-after-last-item .@{list-prefix-cls}-item:last-child { 152 | border-bottom: 1px solid @border-color-split; 153 | } 154 | 155 | .@{list-prefix-cls}-bordered.@{list-prefix-cls}-lg { 156 | .@{list-prefix-cls}-header, .@{list-prefix-cls}-footer { 157 | padding: 16px 24px; 158 | } 159 | } 160 | 161 | .@{list-prefix-cls}-bordered.@{list-prefix-cls}-sm { 162 | .@{list-prefix-cls}-item { 163 | padding-left: 16px; 164 | padding-right: 16px; 165 | } 166 | .@{list-prefix-cls}-header, .@{list-prefix-cls}-footer { 167 | padding: 8px 16px; 168 | } 169 | } 170 | 171 | .@{list-prefix-cls}-lg { 172 | .@{list-prefix-cls}-item { 173 | padding-top: 16px; 174 | padding-bottom: 16px; 175 | } 176 | } 177 | 178 | .@{list-prefix-cls}-sm { 179 | .@{list-prefix-cls}-item { 180 | padding-top: 8px; 181 | padding-bottom: 8px; 182 | } 183 | } 184 | 185 | .@{list-prefix-cls}-vertical { 186 | .@{list-prefix-cls}-item { 187 | display: block; 188 | &-extra-wrap { 189 | display: flex; 190 | } 191 | &-main { 192 | display: block; 193 | flex: 1; 194 | } 195 | &-extra { 196 | margin-left: 58px; 197 | flex: 0; 198 | } 199 | &-meta { 200 | margin-bottom: 16px; 201 | &-avatar { 202 | display: none; 203 | } 204 | &-title { 205 | color: @heading-color; 206 | margin-bottom: 12px; 207 | font-size: @font-size-lg; 208 | line-height: 24px; 209 | } 210 | } 211 | &-content { 212 | display: block; 213 | color: @text-color; 214 | font-size: @font-size-base; 215 | margin-bottom: 16px; 216 | } 217 | &-action { 218 | margin-left: auto; 219 | & > li { 220 | padding: 0 16px; 221 | } 222 | & > li:first-child { 223 | padding-left: 0; 224 | } 225 | } 226 | } 227 | } 228 | 229 | .@{list-prefix-cls}-grid { 230 | .@{list-prefix-cls}-item { 231 | border-bottom: none; 232 | padding-top: 0; 233 | padding-bottom: 0; 234 | margin-bottom: 20px; 235 | &-content { 236 | display: block; 237 | } 238 | } 239 | } 240 | 241 | .@{list-prefix-cls}-empty { 242 | color: @text-color-secondary; 243 | padding: 16px 0; 244 | font-size: 12px; 245 | text-align: center; 246 | } 247 | 248 | @media screen and (max-width: @screen-md) { 249 | .@{list-prefix-cls} { 250 | &-item { 251 | &-action { 252 | margin-left: 24px; 253 | } 254 | } 255 | } 256 | 257 | .@{list-prefix-cls}-vertical { 258 | .@{list-prefix-cls}-item { 259 | &-extra { 260 | margin-left: 24px; 261 | } 262 | } 263 | } 264 | } 265 | 266 | @media screen and (max-width: @screen-xs) { 267 | .@{list-prefix-cls} { 268 | &-item { 269 | flex-wrap: wrap; 270 | &-action { 271 | margin-left: 12px; 272 | } 273 | } 274 | } 275 | 276 | .@{list-prefix-cls}-vertical { 277 | .@{list-prefix-cls}-item { 278 | &-extra-wrap { 279 | flex-wrap: wrap-reverse; 280 | } 281 | &-main { 282 | min-width: 220px; 283 | } 284 | &-extra { 285 | margin-left: 0; 286 | } 287 | } 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /src/nz-list/style/patch.less: -------------------------------------------------------------------------------- 1 | nz-list, 2 | nz-list-item, 3 | nz-list-item-meta { 4 | display: block; 5 | } 6 | 7 | nz-list nz-spin { 8 | display: block; 9 | } 10 | -------------------------------------------------------------------------------- /src/nz-radio-extra/index.md: -------------------------------------------------------------------------------- 1 | # Deprecated,原先 nz-radio 已支持 2 | 3 | ## API 4 | 5 | 一个简单的单选框视觉上效果,用于暂时解决 [#770](https://github.com/NG-ZORRO/ng-zorro-antd/issues/770) 的问题。 6 | 7 | ### `nz-radio-extra` 8 | 9 | | Name | Type | Default | Summary | 10 | | ------- | ------------- | ----- | ----- | 11 | | ngModel | `boolean` | | | 12 | | nzValue | `boolean` | | | 13 | | nzDisabled | `boolean` | | | 14 | -------------------------------------------------------------------------------- /src/nz-radio-extra/index.ts: -------------------------------------------------------------------------------- 1 | export { NzRadioExtraComponent } from './nz-radio-extra.component'; 2 | export { NzRadioExtraModule } from './nz-radio-extra.module'; 3 | -------------------------------------------------------------------------------- /src/nz-radio-extra/nz-radio-extra.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | ElementRef, 4 | HostBinding, 5 | HostListener, 6 | Input, 7 | OnInit, 8 | Renderer2, 9 | ViewEncapsulation, 10 | forwardRef, 11 | } from '@angular/core'; 12 | 13 | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; 14 | import { toBoolean, deprecation } from '../util/convert'; 15 | 16 | @Component({ 17 | selector : '[nz-radio-extra]', 18 | encapsulation: ViewEncapsulation.None, 19 | template : ` 20 | 21 | 22 | 23 | 24 | 25 | `, 26 | providers : [ 27 | { 28 | provide : NG_VALUE_ACCESSOR, 29 | useExisting: forwardRef(() => NzRadioExtraComponent), 30 | multi : true 31 | } 32 | ], 33 | styleUrls : [ 34 | './style/index.less' 35 | ] 36 | }) 37 | export class NzRadioExtraComponent implements OnInit, ControlValueAccessor { 38 | private _checked = false; 39 | private _disabled = false; 40 | private _focused = false; 41 | _el: HTMLElement; 42 | _classMap: any; 43 | _value: string; 44 | _prefixCls = 'ant-radio'; 45 | _innerPrefixCls = `${this._prefixCls}-inner`; 46 | _inputPrefixCls = `${this._prefixCls}-input`; 47 | // ngModel Access 48 | onChange: any = Function.prototype; 49 | onTouched: any = Function.prototype; 50 | 51 | @Input() 52 | @HostBinding('class.ant-radio-wrapper-checked') 53 | set nzChecked(value: boolean) { 54 | this._checked = toBoolean(value); 55 | this.setClassMap(); 56 | } 57 | 58 | get nzChecked(): boolean { 59 | return this._checked; 60 | } 61 | 62 | @Input() 63 | get nzValue(): string { 64 | return this._value; 65 | } 66 | 67 | set nzValue(value: string) { 68 | if (this._value === value) { 69 | return; 70 | } 71 | this._value = value; 72 | } 73 | 74 | @Input() 75 | @HostBinding('class.ant-radio-wrapper-disabled') 76 | set nzDisabled(value: boolean) { 77 | this._disabled = toBoolean(value); 78 | this.setClassMap(); 79 | } 80 | 81 | get nzDisabled(): boolean { 82 | return this._disabled; 83 | } 84 | 85 | @HostListener('click', [ '$event' ]) 86 | onClick(e: MouseEvent): void { 87 | e.preventDefault(); 88 | if (!this._disabled) { 89 | // this._checked = true; 90 | this.updateValue(!this._checked); 91 | } 92 | } 93 | 94 | nzFocus(): void { 95 | this._focused = true; 96 | this.setClassMap(); 97 | } 98 | 99 | nzBlur(): void { 100 | this._focused = false; 101 | this.setClassMap(); 102 | } 103 | 104 | setClassMap(): void { 105 | this._classMap = { 106 | [this._prefixCls] : true, 107 | [`${this._prefixCls}-checked`] : this._checked, 108 | [`${this._prefixCls}-focused`] : this._focused, 109 | [`${this._prefixCls}-disabled`]: this._disabled 110 | }; 111 | } 112 | 113 | constructor(private _elementRef: ElementRef, public _renderer: Renderer2) { 114 | deprecation(`nz-radio 已支持允许独立使用\n https://ng.ant.design/#/components/radio`); 115 | this._el = this._elementRef.nativeElement; 116 | } 117 | 118 | ngOnInit(): void { 119 | this._renderer.addClass(this._el, `${this._prefixCls}-wrapper`); 120 | this.setClassMap(); 121 | } 122 | 123 | updateValue(value: boolean): void { 124 | if (value === this._checked) { 125 | return; 126 | } 127 | this.onChange(value); 128 | this._checked = value; 129 | this.setClassMap(); 130 | } 131 | 132 | writeValue(value: any): void { 133 | this._checked = value; 134 | this.setClassMap(); 135 | } 136 | 137 | registerOnChange(fn: (_: any) => {}): void { 138 | this.onChange = fn; 139 | } 140 | 141 | registerOnTouched(fn: () => {}): void { 142 | this.onTouched = fn; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/nz-radio-extra/nz-radio-extra.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule } from '@angular/forms'; 4 | // import { NzSpinModule, NzGridModule, NzAvatarModule } from 'ng-zorro-antd'; 5 | 6 | import { NzRadioExtraComponent } from './nz-radio-extra.component'; 7 | 8 | @NgModule({ 9 | imports: [ CommonModule, FormsModule ], 10 | declarations: [ NzRadioExtraComponent ], 11 | exports: [ NzRadioExtraComponent ] 12 | }) 13 | export class NzRadioExtraModule { 14 | } 15 | -------------------------------------------------------------------------------- /src/nz-radio-extra/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../style/themes/default"; 2 | @import "../../style/mixins/index"; 3 | 4 | @radio-prefix-cls: ~"@{ant-prefix}-radio"; 5 | @radio-group-prefix-cls: ~"@{radio-prefix-cls}-group"; 6 | @radio-inner-prefix-cls: ~"@{radio-prefix-cls}-inner"; 7 | @radio-duration: .3s; 8 | 9 | .@{radio-group-prefix-cls} { 10 | display: inline-block; 11 | font-size: @font-size-base; 12 | } 13 | 14 | // 一般状态 15 | .@{radio-prefix-cls}-wrapper { 16 | font-size: @font-size-base; 17 | display: inline-block; 18 | position: relative; 19 | white-space: nowrap; 20 | margin-right: 8px; 21 | cursor: pointer; 22 | } 23 | 24 | .@{radio-prefix-cls} { 25 | white-space: nowrap; 26 | outline: none; 27 | display: inline-block; 28 | position: relative; 29 | line-height: 1; 30 | vertical-align: text-bottom; 31 | cursor: pointer; 32 | .@{radio-prefix-cls}-wrapper:hover &, 33 | &:hover, 34 | &-focused { 35 | .@{radio-inner-prefix-cls} { 36 | border-color: @primary-color; 37 | } 38 | } 39 | &-checked:after { 40 | position: absolute; 41 | top: 0; 42 | left: 0; 43 | width: 100%; 44 | height: 100%; 45 | border-radius: 50%; 46 | border: 1px solid @primary-color; 47 | content: ''; 48 | animation: antRadioEffect 0.36s ease-in-out; 49 | animation-fill-mode: both; 50 | visibility: hidden; 51 | } 52 | &:hover:after, 53 | .@{radio-prefix-cls}-wrapper:hover &:after { 54 | visibility: visible; 55 | } 56 | &-inner { 57 | &:after { 58 | position: absolute; 59 | width: 6px; 60 | height: 6px; 61 | left: 3px; 62 | top: 3px; 63 | border-radius: @border-radius-base; 64 | display: table; 65 | border-top: 0; 66 | border-left: 0; 67 | content: ' '; 68 | background-color: @primary-color; 69 | opacity: 0; 70 | transform: scale(0); 71 | transition: all @radio-duration @ease-in-out-circ; 72 | } 73 | 74 | position: relative; 75 | top: 0; 76 | left: 0; 77 | display: block; 78 | width: 14px; 79 | height: 14px; 80 | border-width: 1px; 81 | border-style: solid; 82 | border-radius: 14px; 83 | border-color: @border-color-base; 84 | background-color: @radio-button-bg; 85 | transition: all @radio-duration; 86 | } 87 | 88 | &-input { 89 | position: absolute; 90 | left: 0; 91 | z-index: 1; 92 | cursor: pointer; 93 | opacity: 0; 94 | top: 0; 95 | bottom: 0; 96 | right: 0; 97 | } 98 | } 99 | 100 | // 选中状态 101 | .@{radio-prefix-cls}-checked { 102 | .@{radio-inner-prefix-cls} { 103 | border-color: @primary-color; 104 | &:after { 105 | transform: scale(1); 106 | opacity: 1; 107 | transition: all @radio-duration @ease-in-out-circ; 108 | } 109 | } 110 | } 111 | 112 | .@{radio-prefix-cls}-disabled { 113 | .@{radio-inner-prefix-cls} { 114 | border-color: @border-color-base !important; 115 | background-color: @input-disabled-bg; 116 | &:after { 117 | background-color: #ccc; 118 | } 119 | } 120 | 121 | .@{radio-prefix-cls}-input { 122 | cursor: not-allowed; 123 | } 124 | 125 | & + span { 126 | color: @disabled-color; 127 | cursor: not-allowed; 128 | } 129 | } 130 | 131 | span.@{radio-prefix-cls} + * { 132 | padding-left: 8px; 133 | padding-right: 8px; 134 | } 135 | 136 | .@{radio-prefix-cls}-button-wrapper { 137 | margin: 0; 138 | height: @input-height-base; 139 | line-height: @input-height-base - 2px; 140 | color: @radio-button-color; 141 | display: inline-block; 142 | transition: all 0.3s ease; 143 | cursor: pointer; 144 | border: @border-width-base @border-style-base @border-color-base; 145 | border-left: 0; 146 | background: @radio-button-bg; 147 | padding: 0 16px; 148 | position: relative; 149 | 150 | a { 151 | color: @radio-button-color; 152 | } 153 | 154 | > .@{radio-prefix-cls}-button { 155 | margin-left: 0; 156 | display: block; 157 | width: 0; 158 | height: 0; 159 | } 160 | 161 | .@{radio-group-prefix-cls}-large & { 162 | height: @input-height-lg; 163 | line-height: @input-height-lg - 2px; 164 | } 165 | 166 | .@{radio-group-prefix-cls}-small & { 167 | height: @input-height-sm; 168 | line-height: @input-height-sm - 2px; 169 | padding: 0 12px; 170 | &:first-child { 171 | border-radius: @border-radius-sm 0 0 @border-radius-sm; 172 | } 173 | &:last-child { 174 | border-radius: 0 @border-radius-sm @border-radius-sm 0; 175 | } 176 | } 177 | 178 | &:not(:first-child) { 179 | &::before { 180 | content: ""; 181 | display: block; 182 | top: 0; 183 | left: -1px; 184 | width: 1px; 185 | height: 100%; 186 | position: absolute; 187 | background-color: @border-color-base; 188 | } 189 | } 190 | &:first-child { 191 | border-radius: @border-radius-base 0 0 @border-radius-base; 192 | border-left: @border-width-base @border-style-base @border-color-base; 193 | } 194 | 195 | &:last-child { 196 | border-radius: 0 @border-radius-base @border-radius-base 0; 197 | } 198 | 199 | &:first-child:last-child { 200 | border-radius: @border-radius-base; 201 | } 202 | 203 | &:hover, 204 | &-focused { 205 | color: @primary-color; 206 | position: relative; 207 | } 208 | 209 | .@{radio-prefix-cls}-inner, 210 | input[type="checkbox"], 211 | input[type="radio"] { 212 | .opacity(0); 213 | width: 0; 214 | height: 0; 215 | } 216 | 217 | &-checked { 218 | background: @radio-button-bg; 219 | border-color: @primary-color; 220 | color: @primary-color; 221 | box-shadow: -1px 0 0 0 @primary-color; 222 | z-index: 1; 223 | &::before { 224 | background-color: @primary-color !important; 225 | opacity: 0.1; 226 | } 227 | &:first-child { 228 | border-color: @primary-color; 229 | box-shadow: none !important; 230 | } 231 | 232 | &:hover { 233 | border-color: @primary-5; 234 | box-shadow: -1px 0 0 0 @primary-5; 235 | color: @primary-5; 236 | } 237 | 238 | &:active { 239 | border-color: @primary-7; 240 | box-shadow: -1px 0 0 0 @primary-7; 241 | color: @primary-7; 242 | } 243 | } 244 | 245 | &-disabled { 246 | border-color: @border-color-base; 247 | background-color: @input-disabled-bg; 248 | cursor: not-allowed; 249 | color: @disabled-color; 250 | 251 | &:first-child, 252 | &:hover { 253 | border-color: @border-color-base; 254 | background-color: @input-disabled-bg; 255 | color: @disabled-color; 256 | } 257 | &:first-child { 258 | border-left-color: @border-color-base; 259 | } 260 | } 261 | 262 | &-disabled&-checked { 263 | color: #fff; 264 | background-color: #e6e6e6; 265 | border-color: @border-color-base; 266 | box-shadow: none; 267 | } 268 | } 269 | 270 | @keyframes antRadioEffect { 271 | 0% { 272 | transform: scale(1); 273 | opacity: 0.5; 274 | } 275 | 100% { 276 | transform: scale(1.6); 277 | opacity: 0; 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /src/spec/component.spec.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 3 | 4 | import { NzListModule } from 'ng-zorro-antd-extra'; 5 | 6 | const html = ``; 7 | 8 | describe('Component: ng-zorro-antd-extra', () => { 9 | let fixture: ComponentFixture; 10 | let context: TestNGComponent; 11 | 12 | beforeEach(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [TestNGComponent], 15 | imports: [NzListModule] 16 | }); 17 | TestBed.overrideComponent(TestNGComponent, {set: {template: html}}); 18 | fixture = TestBed.createComponent(TestNGComponent); 19 | context = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('fixture should not be null', () => { 24 | expect(fixture).not.toBeNull(); 25 | }); 26 | }); 27 | 28 | @Component({ 29 | selector: 'ng-zorro-antd-extra-test', 30 | template: '' 31 | }) 32 | class TestNGComponent { 33 | } 34 | -------------------------------------------------------------------------------- /src/style/color/bezierEasing.less: -------------------------------------------------------------------------------- 1 | /* stylelint-disable declaration-bang-space-before */ 2 | .bezierEasingMixin() { 3 | @functions: ~`(function() { 4 | var NEWTON_ITERATIONS = 4; 5 | var NEWTON_MIN_SLOPE = 0.001; 6 | var SUBDIVISION_PRECISION = 0.0000001; 7 | var SUBDIVISION_MAX_ITERATIONS = 10; 8 | 9 | var kSplineTableSize = 11; 10 | var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); 11 | 12 | var float32ArraySupported = typeof Float32Array === 'function'; 13 | 14 | function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } 15 | function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } 16 | function C (aA1) { return 3.0 * aA1; } 17 | 18 | // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. 19 | function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; } 20 | 21 | // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. 22 | function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); } 23 | 24 | function binarySubdivide (aX, aA, aB, mX1, mX2) { 25 | var currentX, currentT, i = 0; 26 | do { 27 | currentT = aA + (aB - aA) / 2.0; 28 | currentX = calcBezier(currentT, mX1, mX2) - aX; 29 | if (currentX > 0.0) { 30 | aB = currentT; 31 | } else { 32 | aA = currentT; 33 | } 34 | } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); 35 | return currentT; 36 | } 37 | 38 | function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { 39 | for (var i = 0; i < NEWTON_ITERATIONS; ++i) { 40 | var currentSlope = getSlope(aGuessT, mX1, mX2); 41 | if (currentSlope === 0.0) { 42 | return aGuessT; 43 | } 44 | var currentX = calcBezier(aGuessT, mX1, mX2) - aX; 45 | aGuessT -= currentX / currentSlope; 46 | } 47 | return aGuessT; 48 | } 49 | 50 | var BezierEasing = function (mX1, mY1, mX2, mY2) { 51 | if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { 52 | throw new Error('bezier x values must be in [0, 1] range'); 53 | } 54 | 55 | // Precompute samples table 56 | var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); 57 | if (mX1 !== mY1 || mX2 !== mY2) { 58 | for (var i = 0; i < kSplineTableSize; ++i) { 59 | sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); 60 | } 61 | } 62 | 63 | function getTForX (aX) { 64 | var intervalStart = 0.0; 65 | var currentSample = 1; 66 | var lastSample = kSplineTableSize - 1; 67 | 68 | for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) { 69 | intervalStart += kSampleStepSize; 70 | } 71 | --currentSample; 72 | 73 | // Interpolate to provide an initial guess for t 74 | var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]); 75 | var guessForT = intervalStart + dist * kSampleStepSize; 76 | 77 | var initialSlope = getSlope(guessForT, mX1, mX2); 78 | if (initialSlope >= NEWTON_MIN_SLOPE) { 79 | return newtonRaphsonIterate(aX, guessForT, mX1, mX2); 80 | } else if (initialSlope === 0.0) { 81 | return guessForT; 82 | } else { 83 | return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); 84 | } 85 | } 86 | 87 | return function BezierEasing (x) { 88 | if (mX1 === mY1 && mX2 === mY2) { 89 | return x; // linear 90 | } 91 | // Because JavaScript number are imprecise, we should guarantee the extremes are right. 92 | if (x === 0) { 93 | return 0; 94 | } 95 | if (x === 1) { 96 | return 1; 97 | } 98 | return calcBezier(getTForX(x), mY1, mY2); 99 | }; 100 | }; 101 | 102 | this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18); 103 | })()`; 104 | } 105 | // It is hacky way to make this function will be compiled preferentially by less 106 | // resolve error: `ReferenceError: colorPalette is not defined` 107 | // https://github.com/ant-design/ant-motion/issues/44 108 | .bezierEasingMixin(); 109 | -------------------------------------------------------------------------------- /src/style/color/colorPalette.less: -------------------------------------------------------------------------------- 1 | @import "bezierEasing"; 2 | @import "tinyColor"; 3 | 4 | // We create a very complex algorithm which take the place of original tint/shade color system 5 | // to make sure no one can understand it 👻 6 | // and create an entire color palette magicly by inputing just a single primary color. 7 | // We are using bezier-curve easing function and some color manipulations like tint/shade/darken/spin 8 | .colorPaletteMixin() { 9 | @functions: ~`(function() { 10 | var hueStep = 2; 11 | var saturationStep = 16; 12 | var saturationStep2 = 5; 13 | var brightnessStep1 = 5; 14 | var brightnessStep2 = 15; 15 | var lightColorCount = 5; 16 | var darkColorCount = 4; 17 | 18 | var getHue = function(hsv, i, isLight) { 19 | var hue; 20 | if (hsv.h >= 60 && hsv.h <= 240) { 21 | hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i; 22 | } else { 23 | hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i; 24 | } 25 | if (hue < 0) { 26 | hue += 360; 27 | } else if (hue >= 360) { 28 | hue -= 360; 29 | } 30 | return Math.round(hue); 31 | }; 32 | var getSaturation = function(hsv, i, isLight) { 33 | var saturation; 34 | if (isLight) { 35 | saturation = Math.round(hsv.s * 100) - saturationStep * i; 36 | } else if (i == darkColorCount) { 37 | saturation = Math.round(hsv.s * 100) + saturationStep; 38 | } else { 39 | saturation = Math.round(hsv.s * 100) + saturationStep2 * i; 40 | } 41 | if (saturation > 100) { 42 | saturation = 100; 43 | } 44 | if (isLight && i === lightColorCount && saturation > 10) { 45 | saturation = 10; 46 | } 47 | if (saturation < 6) { 48 | saturation = 6; 49 | } 50 | return Math.round(saturation); 51 | }; 52 | var getValue = function(hsv, i, isLight) { 53 | if (isLight) { 54 | return Math.round(hsv.v * 100) + brightnessStep1 * i; 55 | } 56 | return Math.round(hsv.v * 100) - brightnessStep2 * i; 57 | }; 58 | 59 | this.colorPalette = function(color, index) { 60 | var isLight = index <= 6; 61 | var hsv = tinycolor(color).toHsv(); 62 | var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1; 63 | return tinycolor({ 64 | h: getHue(hsv, i, isLight), 65 | s: getSaturation(hsv, i, isLight), 66 | v: getValue(hsv, i, isLight), 67 | }).toHexString(); 68 | }; 69 | })()`; 70 | } 71 | // It is hacky way to make this function will be compiled preferentially by less 72 | // resolve error: `ReferenceError: colorPalette is not defined` 73 | // https://github.com/ant-design/ant-motion/issues/44 74 | .colorPaletteMixin(); 75 | -------------------------------------------------------------------------------- /src/style/color/colors.less: -------------------------------------------------------------------------------- 1 | @import 'colorPalette'; 2 | 3 | // color palettes 4 | @blue-1: color(~`colorPalette("@{blue-6}", 1)`); 5 | @blue-2: color(~`colorPalette("@{blue-6}", 2)`); 6 | @blue-3: color(~`colorPalette("@{blue-6}", 3)`); 7 | @blue-4: color(~`colorPalette("@{blue-6}", 4)`); 8 | @blue-5: color(~`colorPalette("@{blue-6}", 5)`); 9 | @blue-6: #1890ff; 10 | @blue-7: color(~`colorPalette("@{blue-6}", 7)`); 11 | @blue-8: color(~`colorPalette("@{blue-6}", 8)`); 12 | @blue-9: color(~`colorPalette("@{blue-6}", 9)`); 13 | @blue-10: color(~`colorPalette("@{blue-6}", 10)`); 14 | 15 | @purple-1: color(~`colorPalette("@{purple-6}", 1)`); 16 | @purple-2: color(~`colorPalette("@{purple-6}", 2)`); 17 | @purple-3: color(~`colorPalette("@{purple-6}", 3)`); 18 | @purple-4: color(~`colorPalette("@{purple-6}", 4)`); 19 | @purple-5: color(~`colorPalette("@{purple-6}", 5)`); 20 | @purple-6: #722ed1; 21 | @purple-7: color(~`colorPalette("@{purple-6}", 7)`); 22 | @purple-8: color(~`colorPalette("@{purple-6}", 8)`); 23 | @purple-9: color(~`colorPalette("@{purple-6}", 9)`); 24 | @purple-10: color(~`colorPalette("@{purple-6}", 10)`); 25 | 26 | @cyan-1: color(~`colorPalette("@{cyan-6}", 1)`); 27 | @cyan-2: color(~`colorPalette("@{cyan-6}", 2)`); 28 | @cyan-3: color(~`colorPalette("@{cyan-6}", 3)`); 29 | @cyan-4: color(~`colorPalette("@{cyan-6}", 4)`); 30 | @cyan-5: color(~`colorPalette("@{cyan-6}", 5)`); 31 | @cyan-6: #13c2c2; 32 | @cyan-7: color(~`colorPalette("@{cyan-6}", 7)`); 33 | @cyan-8: color(~`colorPalette("@{cyan-6}", 8)`); 34 | @cyan-9: color(~`colorPalette("@{cyan-6}", 9)`); 35 | @cyan-10: color(~`colorPalette("@{cyan-6}", 10)`); 36 | 37 | @green-1: color(~`colorPalette("@{green-6}", 1)`); 38 | @green-2: color(~`colorPalette("@{green-6}", 2)`); 39 | @green-3: color(~`colorPalette("@{green-6}", 3)`); 40 | @green-4: color(~`colorPalette("@{green-6}", 4)`); 41 | @green-5: color(~`colorPalette("@{green-6}", 5)`); 42 | @green-6: #52c41a; 43 | @green-7: color(~`colorPalette("@{green-6}", 7)`); 44 | @green-8: color(~`colorPalette("@{green-6}", 8)`); 45 | @green-9: color(~`colorPalette("@{green-6}", 9)`); 46 | @green-10: color(~`colorPalette("@{green-6}", 10)`); 47 | 48 | @magenta-1: color(~`colorPalette("@{magenta-6}", 1)`); 49 | @magenta-2: color(~`colorPalette("@{magenta-6}", 2)`); 50 | @magenta-3: color(~`colorPalette("@{magenta-6}", 3)`); 51 | @magenta-4: color(~`colorPalette("@{magenta-6}", 4)`); 52 | @magenta-5: color(~`colorPalette("@{magenta-6}", 5)`); 53 | @magenta-6: #eb2f96; 54 | @magenta-7: color(~`colorPalette("@{magenta-6}", 7)`); 55 | @magenta-8: color(~`colorPalette("@{magenta-6}", 8)`); 56 | @magenta-9: color(~`colorPalette("@{magenta-6}", 9)`); 57 | @magenta-10: color(~`colorPalette("@{magenta-6}", 10)`); 58 | 59 | // alias of magenta 60 | @pink-1: color(~`colorPalette("@{pink-6}", 1)`); 61 | @pink-2: color(~`colorPalette("@{pink-6}", 2)`); 62 | @pink-3: color(~`colorPalette("@{pink-6}", 3)`); 63 | @pink-4: color(~`colorPalette("@{pink-6}", 4)`); 64 | @pink-5: color(~`colorPalette("@{pink-6}", 5)`); 65 | @pink-6: #eb2f96; 66 | @pink-7: color(~`colorPalette("@{pink-6}", 7)`); 67 | @pink-8: color(~`colorPalette("@{pink-6}", 8)`); 68 | @pink-9: color(~`colorPalette("@{pink-6}", 9)`); 69 | @pink-10: color(~`colorPalette("@{pink-6}", 10)`); 70 | 71 | @red-1: color(~`colorPalette("@{red-6}", 1)`); 72 | @red-2: color(~`colorPalette("@{red-6}", 2)`); 73 | @red-3: color(~`colorPalette("@{red-6}", 3)`); 74 | @red-4: color(~`colorPalette("@{red-6}", 4)`); 75 | @red-5: color(~`colorPalette("@{red-6}", 5)`); 76 | @red-6: #f5222d; 77 | @red-7: color(~`colorPalette("@{red-6}", 7)`); 78 | @red-8: color(~`colorPalette("@{red-6}", 8)`); 79 | @red-9: color(~`colorPalette("@{red-6}", 9)`); 80 | @red-10: color(~`colorPalette("@{red-6}", 10)`); 81 | 82 | @orange-1: color(~`colorPalette("@{orange-6}", 1)`); 83 | @orange-2: color(~`colorPalette("@{orange-6}", 2)`); 84 | @orange-3: color(~`colorPalette("@{orange-6}", 3)`); 85 | @orange-4: color(~`colorPalette("@{orange-6}", 4)`); 86 | @orange-5: color(~`colorPalette("@{orange-6}", 5)`); 87 | @orange-6: #fa8c16; 88 | @orange-7: color(~`colorPalette("@{orange-6}", 7)`); 89 | @orange-8: color(~`colorPalette("@{orange-6}", 8)`); 90 | @orange-9: color(~`colorPalette("@{orange-6}", 9)`); 91 | @orange-10: color(~`colorPalette("@{orange-6}", 10)`); 92 | 93 | @yellow-1: color(~`colorPalette("@{yellow-6}", 1)`); 94 | @yellow-2: color(~`colorPalette("@{yellow-6}", 2)`); 95 | @yellow-3: color(~`colorPalette("@{yellow-6}", 3)`); 96 | @yellow-4: color(~`colorPalette("@{yellow-6}", 4)`); 97 | @yellow-5: color(~`colorPalette("@{yellow-6}", 5)`); 98 | @yellow-6: #fadb14; 99 | @yellow-7: color(~`colorPalette("@{yellow-6}", 7)`); 100 | @yellow-8: color(~`colorPalette("@{yellow-6}", 8)`); 101 | @yellow-9: color(~`colorPalette("@{yellow-6}", 9)`); 102 | @yellow-10: color(~`colorPalette("@{yellow-6}", 10)`); 103 | 104 | @volcano-1: color(~`colorPalette("@{volcano-6}", 1)`); 105 | @volcano-2: color(~`colorPalette("@{volcano-6}", 2)`); 106 | @volcano-3: color(~`colorPalette("@{volcano-6}", 3)`); 107 | @volcano-4: color(~`colorPalette("@{volcano-6}", 4)`); 108 | @volcano-5: color(~`colorPalette("@{volcano-6}", 5)`); 109 | @volcano-6: #fa541c; 110 | @volcano-7: color(~`colorPalette("@{volcano-6}", 7)`); 111 | @volcano-8: color(~`colorPalette("@{volcano-6}", 8)`); 112 | @volcano-9: color(~`colorPalette("@{volcano-6}", 9)`); 113 | @volcano-10: color(~`colorPalette("@{volcano-6}", 10)`); 114 | 115 | @geekblue-1: color(~`colorPalette("@{geekblue-6}", 1)`); 116 | @geekblue-2: color(~`colorPalette("@{geekblue-6}", 2)`); 117 | @geekblue-3: color(~`colorPalette("@{geekblue-6}", 3)`); 118 | @geekblue-4: color(~`colorPalette("@{geekblue-6}", 4)`); 119 | @geekblue-5: color(~`colorPalette("@{geekblue-6}", 5)`); 120 | @geekblue-6: #2f54eb; 121 | @geekblue-7: color(~`colorPalette("@{geekblue-6}", 7)`); 122 | @geekblue-8: color(~`colorPalette("@{geekblue-6}", 8)`); 123 | @geekblue-9: color(~`colorPalette("@{geekblue-6}", 9)`); 124 | @geekblue-10: color(~`colorPalette("@{geekblue-6}", 10)`); 125 | 126 | @lime-1: color(~`colorPalette("@{lime-6}", 1)`); 127 | @lime-2: color(~`colorPalette("@{lime-6}", 2)`); 128 | @lime-3: color(~`colorPalette("@{lime-6}", 3)`); 129 | @lime-4: color(~`colorPalette("@{lime-6}", 4)`); 130 | @lime-5: color(~`colorPalette("@{lime-6}", 5)`); 131 | @lime-6: #a0d911; 132 | @lime-7: color(~`colorPalette("@{lime-6}", 7)`); 133 | @lime-8: color(~`colorPalette("@{lime-6}", 8)`); 134 | @lime-9: color(~`colorPalette("@{lime-6}", 9)`); 135 | @lime-10: color(~`colorPalette("@{lime-6}", 10)`); 136 | 137 | @gold-1: color(~`colorPalette("@{gold-6}", 1)`); 138 | @gold-2: color(~`colorPalette("@{gold-6}", 2)`); 139 | @gold-3: color(~`colorPalette("@{gold-6}", 3)`); 140 | @gold-4: color(~`colorPalette("@{gold-6}", 4)`); 141 | @gold-5: color(~`colorPalette("@{gold-6}", 5)`); 142 | @gold-6: #faad14; 143 | @gold-7: color(~`colorPalette("@{gold-6}", 7)`); 144 | @gold-8: color(~`colorPalette("@{gold-6}", 8)`); 145 | @gold-9: color(~`colorPalette("@{gold-6}", 9)`); 146 | @gold-10: color(~`colorPalette("@{gold-6}", 10)`); 147 | -------------------------------------------------------------------------------- /src/style/core/base.less: -------------------------------------------------------------------------------- 1 | /* stylelint-disable at-rule-no-unknown */ 2 | 3 | // Reboot 4 | // 5 | // Normalization of HTML elements, manually forked from Normalize.css to emove 6 | // styles targeting irrelevant browsers while applying new styles. 7 | // 8 | // Normalize is licensed MIT. https://github.com/necolas/normalize.css 9 | 10 | // http://stackoverflow.com/a/13611748/3040605 11 | @font-face { 12 | font-family: "Helvetica Neue For Number"; 13 | src: local("Helvetica Neue"); 14 | unicode-range: U+30-39; 15 | } 16 | 17 | // HTML & Body reset 18 | html, body { 19 | .square(100%); 20 | } 21 | 22 | // emove the clear button of a text input control in IE10+ 23 | input::-ms-clear, input::-ms-reveal { 24 | display: none; 25 | } 26 | 27 | // Document 28 | // 29 | // 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`. 30 | // 2. Change the default font family in all browsers. 31 | // 3. Correct the line height in all browsers. 32 | // 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS. 33 | // 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so 34 | // we force a non-overlapping, non-auto-hiding scrollbar to counteract. 35 | // 6. Change the default tap highlight to be completely transparent in iOS. 36 | 37 | *, 38 | *::before, 39 | *::after { 40 | box-sizing: border-box; // 1 41 | } 42 | 43 | html { 44 | font-family: sans-serif; // 2 45 | line-height: 1.15; // 3 46 | -webkit-text-size-adjust: 100%; // 4 47 | -ms-text-size-adjust: 100%; // 4 48 | -ms-overflow-style: scrollbar; // 5 49 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); // 6 50 | } 51 | 52 | // IE10+ doesn't honor `` in some cases. 53 | @at-root { 54 | @-ms-viewport { width: device-width; } 55 | } 56 | 57 | // Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers) 58 | article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { 59 | display: block; 60 | } 61 | 62 | // Body 63 | // 64 | // 1. emove the margin in all browsers. 65 | // 2. As a best practice, apply a default `body-background`. 66 | 67 | body { 68 | margin: 0; // 1 69 | font-family: @font-family; 70 | font-size: @font-size-base; 71 | line-height: @line-height-base; 72 | color: @text-color; 73 | background-color: @body-background; // 2 74 | } 75 | 76 | // Suppress the focus outline on elements that cannot be accessed via keyboard. 77 | // This prevents an unwanted focus outline from appearing around elements that 78 | // might still respond to pointer events. 79 | // 80 | // Credit: https://github.com/suitcss/base 81 | [tabindex="-1"]:focus { 82 | outline: none !important; 83 | } 84 | 85 | // Content grouping 86 | // 87 | // 1. Add the correct box sizing in Firefox. 88 | // 2. Show the overflow in Edge and IE. 89 | 90 | hr { 91 | box-sizing: content-box; // 1 92 | height: 0; // 1 93 | overflow: visible; // 2 94 | } 95 | 96 | // 97 | // Typography 98 | // 99 | 100 | // emove top margins from headings 101 | // 102 | // By default, `

`-`

` all receive top and bottom margins. We nuke the top 103 | // margin for easier control within type scales as it avoids margin collapsing. 104 | h1, h2, h3, h4, h5, h6 { 105 | margin-top: 0; 106 | margin-bottom: .5em; 107 | color: @heading-color; 108 | font-weight: 500; 109 | } 110 | 111 | // Reset margins on paragraphs 112 | // 113 | // Similarly, the top margin on `

`s get reset. However, we also reset the 114 | // bottom margin to use `em` units instead of `em`. 115 | p { 116 | margin-top: 0; 117 | margin-bottom: 1em; 118 | } 119 | 120 | // Abbreviations 121 | // 122 | // 1. emove the bottom border in Firefox 39-. 123 | // 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 124 | // 3. Add explicit cursor to indicate changed behavior. 125 | // 4. Duplicate behavior to the data-* attribute for our tooltip plugin 126 | 127 | abbr[title], 128 | abbr[data-original-title] { // 4 129 | text-decoration: underline; // 2 130 | text-decoration: underline dotted; // 2 131 | cursor: help; // 3 132 | border-bottom: 0; // 1 133 | } 134 | 135 | address { 136 | margin-bottom: 1em; 137 | font-style: normal; 138 | line-height: inherit; 139 | } 140 | 141 | input[type="text"], 142 | textarea { 143 | -webkit-appearance: none; 144 | } 145 | 146 | ol, 147 | ul, 148 | dl { 149 | margin-top: 0; 150 | margin-bottom: 1em; 151 | } 152 | 153 | ol ol, 154 | ul ul, 155 | ol ul, 156 | ul ol { 157 | margin-bottom: 0; 158 | } 159 | 160 | dt { 161 | font-weight: 500; 162 | } 163 | 164 | dd { 165 | margin-bottom: .5em; 166 | margin-left: 0; // Undo browser default 167 | } 168 | 169 | blockquote { 170 | margin: 0 0 1em; 171 | } 172 | 173 | dfn { 174 | font-style: italic; // Add the correct font style in Android 4.3- 175 | } 176 | 177 | b, 178 | strong { 179 | font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari 180 | } 181 | 182 | small { 183 | font-size: 80%; // Add the correct font size in all browsers 184 | } 185 | 186 | // 187 | // Prevent `sub` and `sup` elements from affecting the line height in 188 | // all browsers. 189 | // 190 | 191 | sub, 192 | sup { 193 | position: relative; 194 | font-size: 75%; 195 | line-height: 0; 196 | vertical-align: baseline; 197 | } 198 | 199 | sub { bottom: -.25em; } 200 | sup { top: -.5em; } 201 | 202 | // 203 | // Links 204 | // 205 | 206 | a { 207 | color: @link-color; 208 | background-color: transparent; // emove the gray background on active links in IE 10. 209 | text-decoration: @link-decoration; 210 | outline: none; 211 | cursor: pointer; 212 | transition: color .3s; 213 | -webkit-text-decoration-skip: objects; // emove gaps in links underline in iOS 8+ and Safari 8+. 214 | 215 | &:focus { 216 | text-decoration: underline; 217 | text-decoration-skip: ink; 218 | } 219 | 220 | &:hover { 221 | color: @link-hover-color; 222 | } 223 | 224 | &:active { 225 | color: @link-active-color; 226 | } 227 | 228 | &:active, 229 | &:hover { 230 | outline: 0; 231 | text-decoration: @link-hover-decoration; 232 | } 233 | 234 | &[disabled] { 235 | color: @disabled-color; 236 | cursor: not-allowed; 237 | pointer-events: none; 238 | } 239 | } 240 | 241 | // 242 | // Code 243 | // 244 | 245 | pre, 246 | code, 247 | kbd, 248 | samp { 249 | font-family: @code-family; 250 | font-size: 1em; // Correct the odd `em` font sizing in all browsers. 251 | } 252 | 253 | pre { 254 | // emove browser default top margin 255 | margin-top: 0; 256 | // Reset browser default of `1em` to use `em`s 257 | margin-bottom: 1em; 258 | // Don't allow content to break outside 259 | overflow: auto; 260 | } 261 | 262 | // 263 | // Figures 264 | // 265 | figure { 266 | // Apply a consistent margin strategy (matches our type styles). 267 | margin: 0 0 1em; 268 | } 269 | 270 | // 271 | // Images and content 272 | // 273 | 274 | img { 275 | vertical-align: middle; 276 | border-style: none; // emove the border on images inside links in IE 10-. 277 | } 278 | 279 | svg:not(:root) { 280 | overflow: hidden; // Hide the overflow in IE 281 | } 282 | 283 | // Avoid 300ms click delay on touch devices that support the `touch-action` CSS property. 284 | // 285 | // In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11 286 | // DON'T emove the click delay when `` is present. 287 | // However, they DO support emoving the click delay via `touch-action: manipulation`. 288 | // See: 289 | // * https://getbootstrap.com/docs/4.0/content/reboot/#click-delay-optimization-for-touch 290 | // * http://caniuse.com/#feat=css-touch-action 291 | // * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay 292 | 293 | a, 294 | area, 295 | button, 296 | [role="button"], 297 | input:not([type=range]), 298 | label, 299 | select, 300 | summary, 301 | textarea { 302 | touch-action: manipulation; 303 | } 304 | 305 | // 306 | // Tables 307 | // 308 | 309 | table { 310 | border-collapse: collapse; // Prevent double borders 311 | } 312 | 313 | caption { 314 | padding-top: .75em; 315 | padding-bottom: .3em; 316 | color: @text-color-secondary; 317 | text-align: left; 318 | caption-side: bottom; 319 | } 320 | 321 | th { 322 | // Matches default `` alignment by inheriting from the ``, or the 323 | // closest parent with a set `text-align`. 324 | text-align: inherit; 325 | } 326 | 327 | // 328 | // Forms 329 | // 330 | 331 | input, 332 | button, 333 | select, 334 | optgroup, 335 | textarea { 336 | margin: 0; // emove the margin in Firefox and Safari 337 | font-family: inherit; 338 | font-size: inherit; 339 | line-height: inherit; 340 | color: inherit; 341 | } 342 | 343 | input[type="text"], 344 | textarea { 345 | -webkit-appearance: none; 346 | } 347 | 348 | button, 349 | input { 350 | overflow: visible; // Show the overflow in Edge 351 | } 352 | 353 | button, 354 | select { 355 | text-transform: none; // emove the inheritance of text transform in Firefox 356 | } 357 | 358 | // 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 359 | // controls in Android 4. 360 | // 2. Correct the inability to style clickable types in iOS and Safari. 361 | button, 362 | html [type="button"], // 1 363 | [type="reset"], 364 | [type="submit"] { 365 | -webkit-appearance: button; // 2 366 | } 367 | 368 | // emove inner border and padding from Firefox, but don't restore the outline like Normalize. 369 | button::-moz-focus-inner, 370 | [type="button"]::-moz-focus-inner, 371 | [type="reset"]::-moz-focus-inner, 372 | [type="submit"]::-moz-focus-inner { 373 | padding: 0; 374 | border-style: none; 375 | } 376 | 377 | input[type="radio"], 378 | input[type="checkbox"] { 379 | box-sizing: border-box; // 1. Add the correct box sizing in IE 10- 380 | padding: 0; // 2. emove the padding in IE 10- 381 | } 382 | 383 | input[type="date"], 384 | input[type="time"], 385 | input[type="datetime-local"], 386 | input[type="month"] { 387 | // emove the default appearance of temporal inputs to avoid a Mobile Safari 388 | // bug where setting a custom line-height prevents text from being vertically 389 | // centered within the input. 390 | // See https://bugs.webkit.org/show_bug.cgi?id=139848 391 | // and https://github.com/twbs/bootstrap/issues/11266 392 | -webkit-appearance: listbox; 393 | } 394 | 395 | textarea { 396 | overflow: auto; // emove the default vertical scrollbar in IE. 397 | // Textareas should really only resize vertically so they don't break their (horizontal) containers. 398 | resize: vertical; 399 | } 400 | 401 | fieldset { 402 | // Browsers set a default `min-width: min-content;` on fieldsets, 403 | // unlike e.g. `

`s, which have `min-width: 0;` by default. 404 | // So we reset that to ensure fieldsets behave more like a standard block element. 405 | // See https://github.com/twbs/bootstrap/issues/12359 406 | // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements 407 | min-width: 0; 408 | // Reset the default outline behavior of fieldsets so they don't affect page layout. 409 | padding: 0; 410 | margin: 0; 411 | border: 0; 412 | } 413 | 414 | // 1. Correct the text wrapping in Edge and IE. 415 | // 2. Correct the color inheritance from `fieldset` elements in IE. 416 | legend { 417 | display: block; 418 | width: 100%; 419 | max-width: 100%; // 1 420 | padding: 0; 421 | margin-bottom: .5em; 422 | font-size: 1.5em; 423 | line-height: inherit; 424 | color: inherit; // 2 425 | white-space: normal; // 1 426 | } 427 | 428 | progress { 429 | vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera. 430 | } 431 | 432 | // Correct the cursor style of incement and decement buttons in Chrome. 433 | [type="number"]::-webkit-inner-spin-button, 434 | [type="number"]::-webkit-outer-spin-button { 435 | height: auto; 436 | } 437 | 438 | [type="search"] { 439 | // This overrides the extra rounded corners on search inputs in iOS so that our 440 | // `.form-control` class can properly style them. Note that this cannot simply 441 | // be added to `.form-control` as it's not specific enough. For details, see 442 | // https://github.com/twbs/bootstrap/issues/11586. 443 | outline-offset: -2px; // 2. Correct the outline style in Safari. 444 | -webkit-appearance: none; 445 | } 446 | 447 | // 448 | // emove the inner padding and cancel buttons in Chrome and Safari on macOS. 449 | // 450 | 451 | [type="search"]::-webkit-search-cancel-button, 452 | [type="search"]::-webkit-search-decoration { 453 | -webkit-appearance: none; 454 | } 455 | 456 | // 457 | // 1. Correct the inability to style clickable types in iOS and Safari. 458 | // 2. Change font properties to `inherit` in Safari. 459 | // 460 | 461 | ::-webkit-file-upload-button { 462 | font: inherit; // 2 463 | -webkit-appearance: button; // 1 464 | } 465 | 466 | // 467 | // Correct element displays 468 | // 469 | 470 | output { 471 | display: inline-block; 472 | } 473 | 474 | summary { 475 | display: list-item; // Add the correct display in all browsers 476 | } 477 | 478 | template { 479 | display: none; // Add the correct display in IE 480 | } 481 | 482 | // Always hide an element with the `hidden` HTML attribute (from PureCSS). 483 | // Needed for proper display in IE 10-. 484 | [hidden] { 485 | display: none !important; 486 | } 487 | 488 | mark { 489 | padding: .2em; 490 | background-color: @yellow-1; 491 | } 492 | 493 | ::selection { 494 | background: @primary-color; 495 | color: #fff; 496 | } 497 | 498 | // Utility classes 499 | .clearfix { 500 | .clearfix(); 501 | } 502 | -------------------------------------------------------------------------------- /src/style/core/index.less: -------------------------------------------------------------------------------- 1 | @import "../mixins/index"; 2 | @import "base"; 3 | @import "iconfont"; 4 | @import "motion"; 5 | -------------------------------------------------------------------------------- /src/style/core/motion.less: -------------------------------------------------------------------------------- 1 | @import "../mixins/motion"; 2 | @import "motion/fade"; 3 | @import "motion/move"; 4 | @import "motion/other"; 5 | @import "motion/slide"; 6 | @import "motion/swing"; 7 | @import "motion/zoom"; 8 | 9 | // For common/openAnimation 10 | .ant-motion-collapse { 11 | overflow: hidden; 12 | &-active { 13 | transition: height .15s @ease-in-out, opacity .15s @ease-in-out !important; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/style/core/motion/fade.less: -------------------------------------------------------------------------------- 1 | .fade-motion(@className, @keyframeName) { 2 | .make-motion(@className, @keyframeName); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | opacity: 0; 6 | animation-timing-function: linear; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: linear; 10 | } 11 | } 12 | 13 | .fade-motion(fade, antFade); 14 | 15 | @keyframes antFadeIn { 16 | 0% { 17 | opacity: 0; 18 | } 19 | 100% { 20 | opacity: 1; 21 | } 22 | } 23 | 24 | @keyframes antFadeOut { 25 | 0% { 26 | opacity: 1; 27 | } 28 | 100% { 29 | opacity: 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/style/core/motion/move.less: -------------------------------------------------------------------------------- 1 | .move-motion(@className, @keyframeName) { 2 | .make-motion(@className, @keyframeName); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | opacity: 0; 6 | animation-timing-function: @ease-out-circ; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: @ease-in-circ; 10 | } 11 | } 12 | 13 | .move-motion(move-up, antMoveUp); 14 | .move-motion(move-down, antMoveDown); 15 | .move-motion(move-left, antMoveLeft); 16 | .move-motion(move-right, antMoveRight); 17 | 18 | @keyframes antMoveDownIn { 19 | 0% { 20 | transform-origin: 0 0; 21 | transform: translateY(100%); 22 | opacity: 0; 23 | } 24 | 100% { 25 | transform-origin: 0 0; 26 | transform: translateY(0%); 27 | opacity: 1; 28 | } 29 | } 30 | 31 | @keyframes antMoveDownOut { 32 | 0% { 33 | transform-origin: 0 0; 34 | transform: translateY(0%); 35 | opacity: 1; 36 | } 37 | 100% { 38 | transform-origin: 0 0; 39 | transform: translateY(100%); 40 | opacity: 0; 41 | } 42 | } 43 | 44 | @keyframes antMoveLeftIn { 45 | 0% { 46 | transform-origin: 0 0; 47 | transform: translateX(-100%); 48 | opacity: 0; 49 | } 50 | 100% { 51 | transform-origin: 0 0; 52 | transform: translateX(0%); 53 | opacity: 1; 54 | } 55 | } 56 | 57 | @keyframes antMoveLeftOut { 58 | 0% { 59 | transform-origin: 0 0; 60 | transform: translateX(0%); 61 | opacity: 1; 62 | } 63 | 100% { 64 | transform-origin: 0 0; 65 | transform: translateX(-100%); 66 | opacity: 0; 67 | } 68 | } 69 | 70 | @keyframes antMoveRightIn { 71 | 0% { 72 | opacity: 0; 73 | transform-origin: 0 0; 74 | transform: translateX(100%); 75 | } 76 | 100% { 77 | opacity: 1; 78 | transform-origin: 0 0; 79 | transform: translateX(0%); 80 | } 81 | } 82 | 83 | @keyframes antMoveRightOut { 84 | 0% { 85 | transform-origin: 0 0; 86 | transform: translateX(0%); 87 | opacity: 1; 88 | } 89 | 100% { 90 | transform-origin: 0 0; 91 | transform: translateX(100%); 92 | opacity: 0; 93 | } 94 | } 95 | 96 | @keyframes antMoveUpIn { 97 | 0% { 98 | transform-origin: 0 0; 99 | transform: translateY(-100%); 100 | opacity: 0; 101 | } 102 | 100% { 103 | transform-origin: 0 0; 104 | transform: translateY(0%); 105 | opacity: 1; 106 | } 107 | } 108 | 109 | @keyframes antMoveUpOut { 110 | 0% { 111 | transform-origin: 0 0; 112 | transform: translateY(0%); 113 | opacity: 1; 114 | } 115 | 100% { 116 | transform-origin: 0 0; 117 | transform: translateY(-100%); 118 | opacity: 0; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/style/core/motion/other.less: -------------------------------------------------------------------------------- 1 | @keyframes loadingCircle { 2 | 0% { 3 | transform-origin: 50% 50%; 4 | transform: rotate(0deg); 5 | } 6 | 100% { 7 | transform-origin: 50% 50%; 8 | transform: rotate(360deg); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/style/core/motion/slide.less: -------------------------------------------------------------------------------- 1 | .slide-motion(@className, @keyframeName) { 2 | .make-motion(@className, @keyframeName); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | opacity: 0; 6 | animation-timing-function: @ease-out-quint; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: @ease-in-quint; 10 | } 11 | } 12 | 13 | .slide-motion(slide-up, antSlideUp); 14 | .slide-motion(slide-down, antSlideDown); 15 | .slide-motion(slide-left, antSlideLeft); 16 | .slide-motion(slide-right, antSlideRight); 17 | 18 | @keyframes antSlideUpIn { 19 | 0% { 20 | opacity: 0; 21 | transform-origin: 0% 0%; 22 | transform: scaleY(.8); 23 | } 24 | 100% { 25 | opacity: 1; 26 | transform-origin: 0% 0%; 27 | transform: scaleY(1); 28 | } 29 | } 30 | 31 | @keyframes antSlideUpOut { 32 | 0% { 33 | opacity: 1; 34 | transform-origin: 0% 0%; 35 | transform: scaleY(1); 36 | } 37 | 100% { 38 | opacity: 0; 39 | transform-origin: 0% 0%; 40 | transform: scaleY(.8); 41 | } 42 | } 43 | 44 | @keyframes antSlideDownIn { 45 | 0% { 46 | opacity: 0; 47 | transform-origin: 100% 100%; 48 | transform: scaleY(.8); 49 | } 50 | 100% { 51 | opacity: 1; 52 | transform-origin: 100% 100%; 53 | transform: scaleY(1); 54 | } 55 | } 56 | 57 | @keyframes antSlideDownOut { 58 | 0% { 59 | opacity: 1; 60 | transform-origin: 100% 100%; 61 | transform: scaleY(1); 62 | } 63 | 100% { 64 | opacity: 0; 65 | transform-origin: 100% 100%; 66 | transform: scaleY(.8); 67 | } 68 | } 69 | 70 | @keyframes antSlideLeftIn { 71 | 0% { 72 | opacity: 0; 73 | transform-origin: 0% 0%; 74 | transform: scaleX(.8); 75 | } 76 | 100% { 77 | opacity: 1; 78 | transform-origin: 0% 0%; 79 | transform: scaleX(1); 80 | } 81 | } 82 | 83 | @keyframes antSlideLeftOut { 84 | 0% { 85 | opacity: 1; 86 | transform-origin: 0% 0%; 87 | transform: scaleX(1); 88 | } 89 | 100% { 90 | opacity: 0; 91 | transform-origin: 0% 0%; 92 | transform: scaleX(.8); 93 | } 94 | } 95 | 96 | @keyframes antSlideRightIn { 97 | 0% { 98 | opacity: 0; 99 | transform-origin: 100% 0%; 100 | transform: scaleX(.8); 101 | } 102 | 100% { 103 | opacity: 1; 104 | transform-origin: 100% 0%; 105 | transform: scaleX(1); 106 | } 107 | } 108 | 109 | @keyframes antSlideRightOut { 110 | 0% { 111 | opacity: 1; 112 | transform-origin: 100% 0%; 113 | transform: scaleX(1); 114 | } 115 | 100% { 116 | opacity: 0; 117 | transform-origin: 100% 0%; 118 | transform: scaleX(.8); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/style/core/motion/swing.less: -------------------------------------------------------------------------------- 1 | .swing-motion(@className, @keyframeName) { 2 | .@{className}-enter, 3 | .@{className}-appear { 4 | .motion-common(); 5 | animation-play-state: paused; 6 | } 7 | .@{className}-enter.@{className}-enter-active, 8 | .@{className}-appear.@{className}-appear-active { 9 | animation-name: ~"@{keyframeName}In"; 10 | animation-play-state: running; 11 | } 12 | } 13 | 14 | .swing-motion(swing, antSwing); 15 | 16 | @keyframes antSwingIn { 17 | 0%, 18 | 100% { 19 | transform: translateX(0); 20 | } 21 | 20% { 22 | transform: translateX(-10px); 23 | } 24 | 40% { 25 | transform: translateX(10px); 26 | } 27 | 60% { 28 | transform: translateX(-5px); 29 | } 30 | 80% { 31 | transform: translateX(5px); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/style/core/motion/zoom.less: -------------------------------------------------------------------------------- 1 | .zoom-motion(@className, @keyframeName, @duration: @animation-duration-base) { 2 | .make-motion(@className, @keyframeName, @duration); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | transform: scale(0); // need this by yiminghe 6 | animation-timing-function: @ease-out-circ; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: @ease-in-out-circ; 10 | } 11 | } 12 | 13 | // For Modal, Select choosen item 14 | .zoom-motion(zoom, antZoom); 15 | // For Popover, Popconfirm, Dropdown 16 | .zoom-motion(zoom-big, antZoomBig); 17 | // For Tooltip 18 | .zoom-motion(zoom-big-fast, antZoomBig, @animation-duration-fast); 19 | 20 | .zoom-motion(zoom-up, antZoomUp); 21 | .zoom-motion(zoom-down, antZoomDown); 22 | .zoom-motion(zoom-left, antZoomLeft); 23 | .zoom-motion(zoom-right, antZoomRight); 24 | 25 | @keyframes antZoomIn { 26 | 0% { 27 | opacity: 0; 28 | transform: scale(0.2); 29 | } 30 | 100% { 31 | opacity: 1; 32 | transform: scale(1); 33 | } 34 | } 35 | 36 | @keyframes antZoomOut { 37 | 0% { 38 | transform: scale(1); 39 | } 40 | 100% { 41 | opacity: 0; 42 | transform: scale(0.2); 43 | } 44 | } 45 | 46 | @keyframes antZoomBigIn { 47 | 0% { 48 | opacity: 0; 49 | transform: scale(.8); 50 | } 51 | 100% { 52 | transform: scale(1); 53 | } 54 | } 55 | 56 | @keyframes antZoomBigOut { 57 | 0% { 58 | transform: scale(1); 59 | } 60 | 100% { 61 | opacity: 0; 62 | transform: scale(.8); 63 | } 64 | } 65 | 66 | @keyframes antZoomUpIn { 67 | 0% { 68 | opacity: 0; 69 | transform-origin: 50% 0%; 70 | transform: scale(.8); 71 | } 72 | 100% { 73 | transform-origin: 50% 0%; 74 | transform: scale(1); 75 | } 76 | } 77 | 78 | @keyframes antZoomUpOut { 79 | 0% { 80 | transform-origin: 50% 0%; 81 | transform: scale(1); 82 | } 83 | 100% { 84 | opacity: 0; 85 | transform-origin: 50% 0%; 86 | transform: scale(.8); 87 | } 88 | } 89 | 90 | @keyframes antZoomLeftIn { 91 | 0% { 92 | opacity: 0; 93 | transform-origin: 0% 50%; 94 | transform: scale(.8); 95 | } 96 | 100% { 97 | transform-origin: 0% 50%; 98 | transform: scale(1); 99 | } 100 | } 101 | 102 | @keyframes antZoomLeftOut { 103 | 0% { 104 | transform-origin: 0% 50%; 105 | transform: scale(1); 106 | } 107 | 100% { 108 | opacity: 0; 109 | transform-origin: 0% 50%; 110 | transform: scale(.8); 111 | } 112 | } 113 | 114 | @keyframes antZoomRightIn { 115 | 0% { 116 | opacity: 0; 117 | transform-origin: 100% 50%; 118 | transform: scale(.8); 119 | } 120 | 100% { 121 | transform-origin: 100% 50%; 122 | transform: scale(1); 123 | } 124 | } 125 | 126 | @keyframes antZoomRightOut { 127 | 0% { 128 | transform-origin: 100% 50%; 129 | transform: scale(1); 130 | } 131 | 100% { 132 | opacity: 0; 133 | transform-origin: 100% 50%; 134 | transform: scale(.8); 135 | } 136 | } 137 | 138 | @keyframes antZoomDownIn { 139 | 0% { 140 | opacity: 0; 141 | transform-origin: 50% 100%; 142 | transform: scale(.8); 143 | } 144 | 100% { 145 | transform-origin: 50% 100%; 146 | transform: scale(1); 147 | } 148 | } 149 | 150 | @keyframes antZoomDownOut { 151 | 0% { 152 | transform-origin: 50% 100%; 153 | transform: scale(1); 154 | } 155 | 100% { 156 | opacity: 0; 157 | transform-origin: 50% 100%; 158 | transform: scale(.8); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/style/index.less: -------------------------------------------------------------------------------- 1 | @import "./themes/default"; 2 | @import "./core/index"; 3 | -------------------------------------------------------------------------------- /src/style/index.tsx: -------------------------------------------------------------------------------- 1 | import './index.less'; 2 | -------------------------------------------------------------------------------- /src/style/mixins/clearfix.less: -------------------------------------------------------------------------------- 1 | // mixins for clearfix 2 | // ------------------------ 3 | .clearfix() { 4 | zoom: 1; 5 | &:before, 6 | &:after { 7 | content: " "; 8 | display: table; 9 | } 10 | &:after { 11 | clear: both; 12 | visibility: hidden; 13 | font-size: 0; 14 | height: 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/style/mixins/compatibility.less: -------------------------------------------------------------------------------- 1 | // Compatibility for browsers. 2 | 3 | // Placeholder text 4 | .placeholder(@color: @input-placeholder-color) { 5 | // Firefox 6 | &::-moz-placeholder { 7 | color: @color; 8 | opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526 9 | } 10 | // Internet Explorer 10+ 11 | &:-ms-input-placeholder { 12 | color: @color; 13 | } 14 | // Safari and Chrome 15 | &::-webkit-input-placeholder { 16 | color: @color; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/style/mixins/iconfont.less: -------------------------------------------------------------------------------- 1 | .iconfont-mixin() { 2 | display: inline-block; 3 | font-style: normal; 4 | vertical-align: baseline; 5 | text-align: center; 6 | text-transform: none; 7 | line-height: 1; 8 | text-rendering: optimizeLegibility; 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | &:before { 12 | display: block; 13 | font-family: "anticon" !important; 14 | } 15 | } 16 | 17 | .iconfont-font(@content) { 18 | font-family: 'anticon'; 19 | text-rendering: optimizeLegibility; 20 | -webkit-font-smoothing: antialiased; 21 | -moz-osx-font-smoothing: grayscale; 22 | content: @content; 23 | } 24 | 25 | // for iconfont font size 26 | // fix chrome 12px bug, support ie 27 | .iconfont-size-under-12px(@size, @rotate: 0deg) { 28 | display: inline-block; 29 | @font-scale: unit(@size / 12px); 30 | font-size: 12px; 31 | // IE9 32 | font-size: ~"@{size} \9"; // lesshint duplicateProperty: false 33 | transform: scale(@font-scale) rotate(@rotate); 34 | :root & { 35 | font-size: @font-size-sm; // reset IE9 and above 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/style/mixins/index.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------------------------------- 3 | @import "opacity"; 4 | @import "size"; 5 | @import "compatibility"; 6 | @import "clearfix"; 7 | @import "iconfont"; 8 | @import "motion"; 9 | @import "reset"; 10 | -------------------------------------------------------------------------------- /src/style/mixins/motion.less: -------------------------------------------------------------------------------- 1 | @import '../themes/default'; 2 | 3 | .motion-common(@duration: @animation-duration-base) { 4 | animation-duration: @duration; 5 | animation-fill-mode: both; 6 | } 7 | 8 | .motion-common-leave(@duration: @animation-duration-base) { 9 | animation-duration: @duration; 10 | animation-fill-mode: both; 11 | } 12 | 13 | .make-motion(@className, @keyframeName, @duration: @animation-duration-base) { 14 | .@{className}-enter, 15 | .@{className}-appear { 16 | .motion-common(@duration); 17 | animation-play-state: paused; 18 | } 19 | .@{className}-leave { 20 | .motion-common-leave(@duration); 21 | animation-play-state: paused; 22 | } 23 | .@{className}-enter.@{className}-enter-active, 24 | .@{className}-appear.@{className}-appear-active { 25 | animation-name: ~"@{keyframeName}In"; 26 | animation-play-state: running; 27 | } 28 | .@{className}-leave.@{className}-leave-active { 29 | animation-name: ~"@{keyframeName}Out"; 30 | animation-play-state: running; 31 | pointer-events: none; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/style/mixins/opacity.less: -------------------------------------------------------------------------------- 1 | // Opacity 2 | 3 | .opacity(@opacity) { 4 | opacity: @opacity; 5 | // IE8 filter 6 | @opacity-ie: (@opacity * 100); 7 | filter: ~"alpha(opacity=@{opacity-ie})"; 8 | } 9 | -------------------------------------------------------------------------------- /src/style/mixins/reset.less: -------------------------------------------------------------------------------- 1 | @import '../themes/default'; 2 | 3 | .reset-component() { 4 | font-family: @font-family; 5 | font-size: @font-size-base; 6 | line-height: @line-height-base; 7 | color: @text-color; 8 | box-sizing: border-box; 9 | margin: 0; 10 | padding: 0; 11 | list-style: none; 12 | } 13 | -------------------------------------------------------------------------------- /src/style/mixins/size.less: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | .size(@width; @height) { 4 | width: @width; 5 | height: @height; 6 | } 7 | 8 | .square(@size) { 9 | .size(@size; @size); 10 | } 11 | -------------------------------------------------------------------------------- /src/style/themes/default.less: -------------------------------------------------------------------------------- 1 | /* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ 2 | @import "../color/colors"; 3 | 4 | // The prefix to use on all css classes from ant. 5 | @ant-prefix : ant; 6 | 7 | // -------- Colors ----------- 8 | @primary-color : @blue-6; 9 | @info-color : @blue-6; 10 | @success-color : @green-6; 11 | @error-color : @red-6; 12 | @highlight-color : @red-6; 13 | @warning-color : @gold-6; 14 | @normal-color : #d9d9d9; 15 | 16 | // Color used by default to control hover and active backgrounds and for 17 | // alert info backgrounds. 18 | @primary-1: color(~`colorPalette("@{primary-color}", 1)`); // replace tint(@primary-color, 90%) 19 | @primary-2: color(~`colorPalette("@{primary-color}", 2)`); // replace tint(@primary-color, 80%) 20 | @primary-3: color(~`colorPalette("@{primary-color}", 3)`); // unused 21 | @primary-4: color(~`colorPalette("@{primary-color}", 4)`); // unused 22 | @primary-5: color(~`colorPalette("@{primary-color}", 5)`); // color used to control the text color in many active and hover states, replace tint(@primary-color, 20%) 23 | @primary-6: @primary-color; // color used to control the text color of active buttons, don't use, use @primary-color 24 | @primary-7: color(~`colorPalette("@{primary-color}", 7)`); // replace shade(@primary-color, 5%) 25 | @primary-8: color(~`colorPalette("@{primary-color}", 8)`); // unused 26 | @primary-9: color(~`colorPalette("@{primary-color}", 9)`); // unused 27 | @primary-10: color(~`colorPalette("@{primary-color}", 10)`); // unused 28 | 29 | // Base Scaffolding Variables 30 | // --- 31 | 32 | // Background color for `` 33 | @body-background : #fff; 34 | // Base background color for most components 35 | @component-background : #fff; 36 | @font-family-no-number : -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif; 37 | @font-family : "Helvetica Neue For Number", @font-family-no-number; 38 | @code-family : Consolas, Menlo, Courier, monospace; 39 | @heading-color : fade(#000, 85%); 40 | @text-color : fade(#000, 65%); 41 | @text-color-secondary : fade(#000, 45%); 42 | @heading-color-dark : fade(#fff, 100%); 43 | @text-color-dark : fade(#fff,85%); 44 | @text-color-secondary-dark: fade(#fff, 65%); 45 | @font-size-base : 14px; 46 | @font-size-lg : @font-size-base + 2px; 47 | @font-size-sm : 12px; 48 | @line-height-base : 1.5; 49 | @border-radius-base : 4px; 50 | @border-radius-sm : 2px; 51 | 52 | // vertical paddings 53 | @padding-lg : 24px; // containers 54 | @padding-md : 16px; // small containers and buttons 55 | @padding-sm : 12px; // Form controls and items 56 | @padding-xs : 8px; // small items 57 | 58 | // vertical padding for all form controls 59 | @control-padding-horizontal: @padding-sm; 60 | @control-padding-horizontal-sm: @padding-xs; 61 | 62 | // The background colors for active and hover states for things like 63 | // list items or table cells. 64 | @item-active-bg : @primary-1; 65 | @item-hover-bg : @primary-1; 66 | 67 | // ICONFONT 68 | @iconfont-css-prefix : anticon; 69 | @icon-url : "https://at.alicdn.com/t/font_148784_imrz4lshfwimgqfr"; 70 | 71 | // LINK 72 | @link-color : @primary-color; 73 | @link-hover-color : @primary-5; 74 | @link-active-color : @primary-7; 75 | @link-decoration : none; 76 | @link-hover-decoration : none; 77 | 78 | // Animation 79 | @ease-out : cubic-bezier(0.215, 0.61, 0.355, 1); 80 | @ease-in : cubic-bezier(0.55, 0.055, 0.675, 0.19); 81 | @ease-in-out : cubic-bezier(0.645, 0.045, 0.355, 1); 82 | @ease-out-back : cubic-bezier(0.12, 0.4, 0.29, 1.46); 83 | @ease-in-back : cubic-bezier(0.71, -0.46, 0.88, 0.6); 84 | @ease-in-out-back : cubic-bezier(0.71, -0.46, 0.29, 1.46); 85 | @ease-out-circ : cubic-bezier(0.08, 0.82, 0.17, 1); 86 | @ease-in-circ : cubic-bezier(0.6, 0.04, 0.98, 0.34); 87 | @ease-in-out-circ : cubic-bezier(0.78, 0.14, 0.15, 0.86); 88 | @ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1); 89 | @ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06); 90 | @ease-in-out-quint : cubic-bezier(0.86, 0, 0.07, 1); 91 | 92 | // Border color 93 | @border-color-base : hsv(0, 0, 85%); // base border outline a component 94 | @border-color-split : hsv(0, 0, 91%); // split border inside a component 95 | @border-width-base : 1px; // width of the border for a component 96 | @border-style-base : solid; // style of a components border 97 | 98 | // Outline 99 | @outline-blur-size : 0; 100 | @outline-width : 2px; 101 | @outline-color : @primary-color; 102 | 103 | @background-color-light : hsv(0, 0, 98%); // background of header and selected item 104 | @background-color-base : hsv(0, 0, 96%); // Default grey background color 105 | 106 | // Disabled states 107 | @disabled-color : fade(#000, 25%); 108 | @disabled-bg : @background-color-base; 109 | @disabled-color-dark : fade(#fff, 35%); 110 | 111 | // Shadow 112 | @shadow-color : rgba(0, 0, 0, .15); 113 | @box-shadow-base : @shadow-1-down; 114 | @shadow-1-up : 0 2px 8px @shadow-color; 115 | @shadow-1-down : 0 2px 8px @shadow-color; 116 | @shadow-1-left : -2px 0 8px @shadow-color; 117 | @shadow-1-right : 2px 0 8px @shadow-color; 118 | @shadow-2 : 0 4px 12px @shadow-color; 119 | 120 | // Buttons 121 | @btn-font-weight : 400; 122 | @btn-border-radius-base : @border-radius-base; 123 | @btn-border-radius-sm : @border-radius-base; 124 | 125 | @btn-primary-color : #fff; 126 | @btn-primary-bg : @primary-color; 127 | 128 | @btn-default-color : @text-color; 129 | @btn-default-bg : #fff; 130 | @btn-default-border : @border-color-base; 131 | 132 | @btn-danger-color : @error-color; 133 | @btn-danger-bg : @background-color-base; 134 | @btn-danger-border : @border-color-base; 135 | 136 | @btn-disable-color : @disabled-color; 137 | @btn-disable-bg : @disabled-bg; 138 | @btn-disable-border : @border-color-base; 139 | 140 | @btn-padding-base : 0 @padding-md - 1px; 141 | @btn-font-size-lg : @font-size-base; 142 | @btn-font-size-sm : @font-size-base; 143 | @btn-padding-lg : @btn-padding-base; 144 | @btn-padding-sm : 0 @padding-xs - 1px; 145 | 146 | @btn-height-base : 32px; 147 | @btn-height-lg : 40px; 148 | @btn-height-sm : 24px; 149 | 150 | @btn-circle-size : @btn-height-base; 151 | @btn-circle-size-lg : @btn-height-lg; 152 | @btn-circle-size-sm : @btn-height-sm; 153 | 154 | @btn-group-border : @primary-5; 155 | 156 | // Checkbox 157 | @checkbox-size : 16px; 158 | 159 | // Radio 160 | @radio-size : 16px; 161 | 162 | // Radio buttons 163 | @radio-button-bg : @btn-default-bg; 164 | @radio-button-color : @btn-default-color; 165 | 166 | // Media queries breakpoints 167 | // Extra small screen / phone 168 | @screen-xs : 480px; 169 | @screen-xs-min : @screen-xs; 170 | 171 | // Small screen / tablet 172 | @screen-sm : 576px; 173 | @screen-sm-min : @screen-sm; 174 | 175 | // Medium screen / desktop 176 | @screen-md : 768px; 177 | @screen-md-min : @screen-md; 178 | 179 | // Large screen / wide desktop 180 | @screen-lg : 992px; 181 | @screen-lg-min : @screen-lg; 182 | 183 | // Extra large screen / full hd 184 | @screen-xl : 1200px; 185 | @screen-xl-min : @screen-xl; 186 | 187 | // Extra extra large screen / large descktop 188 | @screen-xxl : 1600px; 189 | @screen-xxl-min : @screen-xxl; 190 | 191 | // provide a maximum 192 | @screen-xs-max : (@screen-sm-min - 1px); 193 | @screen-sm-max : (@screen-md-min - 1px); 194 | @screen-md-max : (@screen-lg-min - 1px); 195 | @screen-lg-max : (@screen-xl-min - 1px); 196 | @screen-xl-max : (@screen-xxl-min - 1px); 197 | 198 | // Grid system 199 | @grid-columns : 24; 200 | @grid-gutter-width : 0; 201 | 202 | // Layout 203 | @layout-body-background : #f0f2f5; 204 | @layout-header-background : #001529; 205 | @layout-footer-background : @layout-body-background; 206 | @layout-header-height : 64px; 207 | @layout-header-padding : 0 50px; 208 | @layout-footer-padding : 24px 50px; 209 | @layout-sider-background : @layout-header-background; 210 | @layout-trigger-height : 48px; 211 | @layout-trigger-background : #002140; 212 | @layout-trigger-color : #fff; 213 | @layout-zero-trigger-width : 36px; 214 | @layout-zero-trigger-height : 42px; 215 | 216 | // z-index list 217 | @zindex-affix : 10; 218 | @zindex-back-top : 10; 219 | @zindex-modal-mask : 1000; 220 | @zindex-modal : 1000; 221 | @zindex-notification : 1010; 222 | @zindex-message : 1010; 223 | @zindex-popover : 1030; 224 | @zindex-picker : 1050; 225 | @zindex-dropdown : 1050; 226 | @zindex-tooltip : 1060; 227 | 228 | // Animation 229 | @animation-duration-slow: .3s; // Modal 230 | @animation-duration-base: .2s; 231 | @animation-duration-fast: .1s; // Tooltip 232 | 233 | // Form 234 | // --- 235 | @label-required-color : @highlight-color; 236 | @label-color : @heading-color; 237 | @form-item-margin-bottom : 32px; 238 | @form-item-trailing-colon : true; 239 | @form-vertical-label-padding : 0 0 8px; 240 | @form-vertical-label-margin : 0; 241 | 242 | // Input 243 | // --- 244 | @input-height-base : 32px; 245 | @input-height-lg : 40px; 246 | @input-height-sm : 24px; 247 | @input-padding-horizontal : @control-padding-horizontal - 1px; 248 | @input-padding-horizontal-base: @input-padding-horizontal; 249 | @input-padding-horizontal-sm : @control-padding-horizontal-sm - 1px; 250 | @input-padding-horizontal-lg : @input-padding-horizontal; 251 | @input-padding-vertical-base : 4px; 252 | @input-padding-vertical-sm : 1px; 253 | @input-padding-vertical-lg : 6px; 254 | @input-placeholder-color : hsv(0, 0, 75%); 255 | @input-color : @text-color; 256 | @input-border-color : @border-color-base; 257 | @input-bg : #fff; 258 | @input-addon-bg : @background-color-light; 259 | @input-hover-border-color : @primary-color; 260 | @input-disabled-bg : @disabled-bg; 261 | 262 | // Tooltip 263 | // --- 264 | //* Tooltip max width 265 | @tooltip-max-width: 250px; 266 | //** Tooltip text color 267 | @tooltip-color: #fff; 268 | //** Tooltip background color 269 | @tooltip-bg: rgba(0, 0, 0, .75); 270 | //** Tooltip arrow width 271 | @tooltip-arrow-width: 5px; 272 | //** Tooltip distance with trigger 273 | @tooltip-distance: @tooltip-arrow-width - 1px + 4px; 274 | //** Tooltip arrow color 275 | @tooltip-arrow-color: @tooltip-bg; 276 | 277 | // Popover 278 | // --- 279 | //** Popover body background color 280 | @popover-bg: #fff; 281 | //** Popover text color 282 | @popover-color: @text-color; 283 | //** Popover maximum width 284 | @popover-min-width: 177px; 285 | //** Popover arrow width 286 | @popover-arrow-width: 5px; 287 | //** Popover arrow color 288 | @popover-arrow-color: @popover-bg; 289 | //** Popover outer arrow width 290 | //** Popover outer arrow color 291 | @popover-arrow-outer-color: @popover-bg; 292 | //** Popover distance with trigger 293 | @popover-distance: @popover-arrow-width + 4px; 294 | 295 | // Modal 296 | // -- 297 | @modal-mask-bg: rgba(0, 0, 0, 0.65); 298 | 299 | // Progress 300 | // -- 301 | @progress-default-color: @primary-color; 302 | @progress-remaining-color: @background-color-base; 303 | 304 | // Menu 305 | // --- 306 | @menu-dark-bg: @layout-header-background; 307 | @menu-dark-submenu-bg: #000c17; 308 | @menu-collapsed-width: 80px; 309 | 310 | // Spin 311 | // --- 312 | @spin-dot-size-sm: 14px; 313 | @spin-dot-size: 20px; 314 | @spin-dot-size-lg: 32px; 315 | 316 | // Table 317 | // -- 318 | @table-header-bg: @background-color-light; 319 | @table-header-sort-bg: @background-color-base; 320 | @table-row-hover-bg: @primary-1; 321 | @table-padding-vertical: 16px; 322 | @table-padding-horizontal: 16px; 323 | 324 | // Tag 325 | // -- 326 | @tag-default-bg: @background-color-light; 327 | @tag-default-color: @text-color; 328 | @tag-font-size: @font-size-sm; 329 | 330 | // TimePicker 331 | // --- 332 | @time-picker-panel-column-width: 56px; 333 | @time-picker-panel-width: @time-picker-panel-column-width * 3; 334 | @time-picker-selected-bg: @background-color-base; 335 | 336 | // Carousel 337 | // --- 338 | @carousel-dot-width: 16px; 339 | @carousel-dot-height: 3px; 340 | @carousel-dot-active-width: 24px; 341 | 342 | // Badge 343 | // --- 344 | @badge-height: 20px; 345 | @badge-dot-size: 6px; 346 | @badge-font-size: @font-size-sm; 347 | @badge-status-size: 6px; 348 | 349 | // Rate 350 | // --- 351 | @rate-star-color: @yellow-6; 352 | @rate-star-bg: @border-color-split; 353 | 354 | // Card 355 | // --- 356 | @card-head-color: @heading-color; 357 | @card-head-background: @component-background; 358 | @card-head-padding: 16px; 359 | @card-inner-head-padding: 12px; 360 | @card-padding-base: 24px; 361 | @card-padding-wider: 32px; 362 | @card-actions-background: @background-color-light; 363 | @card-shadow: 0 2px 8px rgba(0, 0, 0, .09); 364 | 365 | // Tabs 366 | // --- 367 | @tabs-card-head-background: @background-color-light; 368 | @tabs-card-height: 40px; 369 | @tabs-title-font-size: @font-size-base; 370 | 371 | // BackTop 372 | // --- 373 | @back-top-color: #fff; 374 | @back-top-bg: @text-color-secondary; 375 | @back-top-hover-bg: @text-color; 376 | 377 | // Avatar 378 | // --- 379 | @avatar-size-base: 32px; 380 | @avatar-size-lg: 40px; 381 | @avatar-size-sm: 24px; 382 | @avatar-font-size-base: 18px; 383 | @avatar-font-size-lg: 24px; 384 | @avatar-font-size-sm: 14px; 385 | @avatar-bg: #ccc; 386 | @avatar-color: #fff; 387 | @avatar-border-radius: @border-radius-base; 388 | 389 | // Switch 390 | // --- 391 | @switch-height: 22px; 392 | @switch-sm-height: 16px; 393 | 394 | // Pagination 395 | // --- 396 | @pagination-item-size: 32px; 397 | @pagination-item-size-sm: 24px; 398 | -------------------------------------------------------------------------------- /src/style/v2-compatible-reset.less: -------------------------------------------------------------------------------- 1 | // For 2.x reset compatibility 2 | // import 'antd/style/v2-compatible-reset'; 3 | // or 4 | // @import '~antd/style/v2-compatible-reset.css'; 5 | // unify the setting of elements's margin and padding for browsers 6 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { 7 | margin: 0; 8 | padding: 0; 9 | } 10 | 11 | ul, 12 | ol { 13 | list-style: none; 14 | } 15 | -------------------------------------------------------------------------------- /src/style/v2-compatible-reset.tsx: -------------------------------------------------------------------------------- 1 | import './v2-compatible-reset.less'; 2 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "../dist", 4 | "target": "es5", 5 | "module": "es2015", 6 | "moduleResolution": "node", 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "sourceMap": true, 10 | "inlineSources": true, 11 | "noImplicitAny": true, 12 | "declaration": true, 13 | "skipLibCheck": false, 14 | "stripInternal": true, 15 | "allowSyntheticDefaultImports": true, 16 | "noUnusedLocals": false, 17 | "noUnusedParameters": false, 18 | "lib": ["dom", "es2017"], 19 | "types": [ 20 | "jasmine" 21 | ], 22 | "typeRoots": [ 23 | "../node_modules/@types" 24 | ] 25 | }, 26 | "exclude": [ 27 | "node_modules" 28 | ], 29 | "files": [ 30 | "../scripts/typings.d.ts", 31 | "./index.ts" 32 | ], 33 | "angularCompilerOptions": { 34 | "genDir": "../temp/factories", 35 | "strictMetadataEmit": true, 36 | "skipTemplateCodegen": true 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "../dist/out-tsc", 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "sourceMap": true, 9 | "declaration": false, 10 | "moduleResolution": "node", 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "typeRoots": [ 14 | "../node_modules/@types" 15 | ], 16 | "types": [ 17 | "jasmine", 18 | "webpack" 19 | ], 20 | "lib": [ 21 | "es2016", 22 | "dom" 23 | ] 24 | }, 25 | "include": [ 26 | "../scripts/typings.d.ts", 27 | "../scripts/test.ts", 28 | "**/*.ts", 29 | "**/*.d.ts" 30 | ], 31 | "exclude": [ 32 | "../demo", 33 | "../node_modules" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /src/util/convert.ts: -------------------------------------------------------------------------------- 1 | export function toBoolean(value: boolean | string): boolean { 2 | return value === '' || (value && value !== 'false'); 3 | } 4 | 5 | const seenDeprecations: any = {}; 6 | export function deprecation(msg: string) { 7 | if (seenDeprecations[msg] !== true) { 8 | seenDeprecations[msg] = true; 9 | // tslint:disable-next-line:no-unused-expression 10 | console && console.warn('DEPRECATION: ' + msg); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.publish.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "emitDecoratorMetadata": true, 5 | "experimentalDecorators": true, 6 | "lib": [ 7 | "es7", 8 | "dom" 9 | ], 10 | "module": "es2015", 11 | "moduleResolution": "node", 12 | "noEmitOnError": true, 13 | "outDir": "./.lib", 14 | "rootDir": "./.ng_build", 15 | "sourceMap": true, 16 | "target": "es5", 17 | "inlineSources": true, 18 | "stripInternal": true, 19 | "baseUrl": ".", 20 | "paths": { 21 | }, 22 | "skipLibCheck": true, 23 | "typeRoots": [ 24 | "node_modules/@types" 25 | ] 26 | }, 27 | "include": [ 28 | "./.ng_build/**/*" 29 | ], 30 | "exclude": [ 31 | "./.ng_build/**/*.e2e.ts", 32 | "./.ng_build/**/*.spec.ts" 33 | ], 34 | "angularCompilerOptions": { 35 | "skipTemplateCodegen": true, 36 | "strictMetadataEmit": true, 37 | "genDir": "./.ng_compiled" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": ["node_modules/codelyzer"], 3 | "rules": { 4 | "arrow-return-shorthand": true, 5 | "callable-types": true, 6 | "class-name": true, 7 | "comment-format": [true, "check-space"], 8 | "curly": false, 9 | "eofline": true, 10 | "forin": false, 11 | "import-blacklist": [true, "rxjs"], 12 | "import-spacing": true, 13 | "indent": [true, "spaces"], 14 | "interface-over-type-literal": true, 15 | "label-position": true, 16 | "max-line-length": [false, 140], 17 | "member-access": false, 18 | "member-ordering": [ 19 | true, 20 | { 21 | "order": [ 22 | "static-field", 23 | "instance-field", 24 | "static-method", 25 | "instance-method" 26 | ] 27 | } 28 | ], 29 | "no-arg": true, 30 | "no-bitwise": true, 31 | "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], 32 | "no-construct": true, 33 | "no-debugger": true, 34 | "no-duplicate-super": true, 35 | "no-empty": false, 36 | "no-empty-interface": true, 37 | "no-eval": true, 38 | "no-inferrable-types": [true, "ignore-params"], 39 | "no-misused-new": true, 40 | "no-non-null-assertion": true, 41 | "no-shadowed-variable": true, 42 | "no-string-literal": false, 43 | "no-string-throw": true, 44 | "no-switch-case-fall-through": true, 45 | "no-trailing-whitespace": false, 46 | "no-unnecessary-initializer": true, 47 | "no-unused-expression": true, 48 | "no-use-before-declare": true, 49 | "no-var-keyword": true, 50 | "object-literal-sort-keys": false, 51 | "one-line": [ 52 | true, 53 | "check-open-brace", 54 | "check-catch", 55 | "check-else", 56 | "check-whitespace" 57 | ], 58 | "prefer-const": true, 59 | "quotemark": [true, "single"], 60 | "radix": true, 61 | "semicolon": [true, "always"], 62 | "triple-equals": [true, "allow-null-check"], 63 | "typedef-whitespace": [ 64 | true, 65 | { 66 | "call-signature": "nospace", 67 | "index-signature": "nospace", 68 | "parameter": "nospace", 69 | "property-declaration": "nospace", 70 | "variable-declaration": "nospace" 71 | } 72 | ], 73 | "typeof-compare": true, 74 | "unified-signatures": true, 75 | "variable-name": false, 76 | "whitespace": [ 77 | true, 78 | "check-branch", 79 | "check-decl", 80 | "check-operator", 81 | "check-separator", 82 | "check-type" 83 | ], 84 | "directive-selector": [false, "attribute", "app", "camelCase"], 85 | "component-selector": [false, "element", "app", "kebab-case"], 86 | "use-input-property-decorator": true, 87 | "use-output-property-decorator": true, 88 | "use-host-property-decorator": true, 89 | "no-input-rename": false, 90 | "no-output-rename": false, 91 | "use-life-cycle-interface": true, 92 | "use-pipe-transform-interface": true, 93 | "component-class-suffix": true, 94 | "directive-class-suffix": true, 95 | "no-access-missing-member": true, 96 | "templates-use-public": true, 97 | "invoke-injectable": true 98 | } 99 | } 100 | --------------------------------------------------------------------------------