diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e89330a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.prettierrc b/.prettierrc index 014e002..f2be051 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,6 @@ { "tabWidth": 2, - "printWidth": 80, + "printWidth": 120, "semi": true, "singleQuote": true, "trailingComma": "none" diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cac0e10 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 7c37ec6..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 coderiver - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README-en.md b/README-en.md deleted file mode 100644 index 537a996..0000000 --- a/README-en.md +++ /dev/null @@ -1,99 +0,0 @@ -# coderiver-angular - -A fullstack JavaScript project, using technologies from the modern stack, such as: - -- [NestJS](https://github.com/nestjs/nest) - a JS backend framework providing architecture out of the box with a syntax similar to Angular -- [Angular](https://github.com/angular/angular) - a JS frontend framework created by Google -- [Angular Universal](https://github.com/angular/universal) - Angular Server Side Rendering - prerendered crawlable pages -- [RxJS](https://github.com/Reactive-Extensions/RxJS) - reactive extensions for JavaScript -- [Webpack](https://github.com/webpack/webpack) - the ultimate JS bundler - used for the server code since Angular has it under the hood -- [MongoDB](https://github.com/mongodb/mongo) - a NoSQL database -- [Mongoose](https://github.com/Automattic/mongoose) - MongoDB object modeling designed to work in an asynchronous environment -- [TypeScript](https://github.com/Microsoft/TypeScript) - superset of JS which compiles to JS, providing compile-time type checking -- [Passport](https://github.com/jaredhanson/passport) - a popular library used to implement JavaScript authentication -- [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) - a JavaScript json web tokens implementation by auth0 - -## Running the project - -These instructions should be sufficient for one to get the project going on their local machine - -### Cloning the github repository - -To clone the project, run - -``` -git clone https://github.com/bojidaryovchev/coderiver-angular.git -``` - -### Installing the dependencies - -To install the dependencies after you've cloned the project, go to its root folder and run - -``` -npm install -``` - -### Building the Angular application - -Before you start the server, you need to build the Angular application. To do so, run - -``` -npm run build:universal -``` - -### Starting the server - -Once you have the Angular app built, you can start the server by running - -``` -npm run watch:server -``` - -Notice that the server uses MongoDB so we need to have a MongoDB instance running so the server can connect to it - -### Alternative commands - -If you need to work on the frontend and backend parts at the same time, you can run - -``` -npm run watch -``` - -Then, you can go to the Angular dev server at port 4200 and test server requests (to port 1337), we got a proxy to the backend - -If you only need to work on the frontend, you can run - -``` -npm run watch:client -``` - -Alternatively, if you only need to work on the backend, you can run - -``` -npm run watch:server -``` - -Keeping in mind that you need to have the Angular app built and a mongodb connection established - -## Instructions - -### Getting GraphQL to work - -Currently there are issues with several packages so even though we have GraphQL implemented, it stays commented out because it doesn't work.. Here are the instructions to make it work: - -- Download https://www.dropbox.com/s/7bvht9thbmwt1e5/fixed-apollo-modules.rar?dl=0 - those are the apollo-angular and apollo-angular-link-http modules compiled in commonjs - then go in your node_modules folder and replace your apollo-angular and apollo-angular-link-http modules with these ones -- Download https://www.dropbox.com/s/n0vwfvdmn7wtkj8/fixed-nest-modules.rar?dl=0 - this is the fixed @nestjs/graphql module - there was an error when in combination with Angular Universal which is now fixed - then replace your @nestjs/graphql module with this one -- Open node_modules/@types/ws/index.d.ts and find net.AddressInfo - you will see a type definition of a function: - `address(): net.AddressInfo | string` - change it to `address(): string` - -Now, you can go ahead and uncomment the GraphqlModules on both client/server side and it works decently, I am using it in another project which is a clone of this one and everything works.. - -### Use Social login - -Modify with your application credentials: - -- src/server/modules/auth/config/facebook-config.ts -- src/server/modules/auth/config/google-config.ts -- src/server/modules/auth/config/twitter-config.ts - -To use it in mobile application with Facebook-token integration (Facebook App), use /api/auth/facebook/token endpoint. diff --git a/README.md b/README.md index 47581f8..d438aa7 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,27 @@ -

- - - -

+# CoderiverAngular -

-CodeRiver -

+This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.1. -
+## Development server -加入优秀的云端团队做一些有趣的事情。 +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. -
+## Code scaffolding -[English](README-en.md) | 简体中文 +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. -## 快速开始 +## Build -```bash -npm i -ng run start -``` -## 技术栈 +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. -### Angular +## Running unit tests -前端框架 +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). -### NG-ZORRO +## Running end-to-end tests -Ant Design 组件库的 Angular 实现,开发和服务于企业级后台产品。 +Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). -### Ng Alain +## Further help -基于 NG-ZORRO 的中后台前端解决方案,提供更多通用性业务模块,让开发者更加专注于业务。 - -### Jest + Protractor - -* 单端测试框架Jest -* e2e测试框架Protractor - -参考: -* [Angular + Jest + Wallabyjs why it is the ideal combination! And how to configure](https://blog.cloudboost.io/angular-jest-wallabyjs-why-it-is-the-ideal-combination-and-how-to-configure-b4cbe2eff4b3) -* [Angular 6: “ng test” with Jest in 3 minutes](https://codeburst.io/angular-6-ng-test-with-jest-in-3-minutes-b1fe5ed3417c) - -### Prettier - -代码格式化工具,结合 husky hook 和 lint-staged 会在每次 git 提交代码前自动格式化代码。 - -### tslint - -typescript 代码格式lint工具 - -### stylelint - -css或者css预处理器格式lint工具 - -### lint-staged - -lint-staged 结合 tslint 和 stlyelint 会在 git 提交代码前对代码进行 lint fix。 - -### codelyzer - -专门为 Angular TypeScript 提供的 lint 规则库。 - - -## 代码提交规范 - -代码提交规范试用Gitflow规范 - -commit内容形式 分为 fix、feat、doc 三种: - -* fix: 用于修复 bug ,例如: fix: remove unused dependcies. -* feat: 用于添加新的功能或特性等,例如: feat: add login page. -* doc: 用于更新文档,例如: doc: update description of project architecture. - -## npm 脚本说明 - -* 本地调试: npm run start -* 打包为静态文件: npm run build -* 单元测试: npm run test -* e2e测试: npm run e2e -* 静态检查: npm run lint -* 热更新方式调试: npm run hmr -* 测试覆盖率: npm run test:coverage - -## License - -The MIT License (see the [LICENSE](https://github.com/coderiver-org/coderiver-angular/blob/master/LICENSE) file for the full text) +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/angular.json b/angular.json index 81a0506..4bdbc99 100644 --- a/angular.json +++ b/angular.json @@ -17,28 +17,31 @@ "build": { "builder": "@angular-devkit/build-angular:browser", "options": { - "outputPath": "dist", + "outputPath": "dist/coderiver-angular", "index": "src/index.html", "main": "src/main.ts", - "tsConfig": "src/tsconfig.app.json", "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.app.json", "assets": [ + "src/favicon.ico", "src/assets", - "src/favicon.ico" + { + "glob": "**/*", + "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", + "output": "/assets/" + } ], - "styles": [ - "src/styles.less" - ], - "scripts": [ - "node_modules/ajv/dist/ajv.bundle.js" - ] + "styles": ["src/theme.less", "node_modules/normalize.css/normalize.css", "src/app/styles/styles.less"], + "scripts": [] }, "configurations": { "production": { - "fileReplacements": [{ - "replace": "./src/environments/environment.ts", - "with": "./src/environments/environment.prod.ts" - }], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], "optimization": true, "outputHashing": "all", "sourceMap": false, @@ -48,17 +51,13 @@ "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "budgets": [{ - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - }] - }, - "hmr": { - "fileReplacements": [{ - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.hmr.ts" - }] + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + } + ] } } }, @@ -70,10 +69,6 @@ "configurations": { "production": { "browserTarget": "coderiver-angular:build:production" - }, - "hmr": { - "browserTarget": "coderiver-angular:build:hmr", - "hmr": true } } }, @@ -84,21 +79,22 @@ } }, "test": { - "builder": "@angular-builders/jest:run", + "builder": "@angular-devkit/build-angular:karma", "options": { - "no-cache": true + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "karmaConfig": "src/karma.conf.js", + "styles": ["src/styles.scss"], + "scripts": [], + "assets": ["src/favicon.ico", "src/assets"] } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "src/tsconfig.app.json", - "src/tsconfig.spec.json" - ], - "exclude": [ - "**/node_modules/**" - ] + "tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"], + "exclude": ["**/node_modules/**"] } } } @@ -106,11 +102,12 @@ "coderiver-angular-e2e": { "root": "e2e/", "projectType": "application", + "prefix": "", "architect": { "e2e": { "builder": "@angular-devkit/build-angular:protractor", "options": { - "protractorConfig": "protractor.conf.js", + "protractorConfig": "e2e/protractor.conf.js", "devServerTarget": "coderiver-angular:serve" }, "configurations": { @@ -123,52 +120,11 @@ "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": "e2e/tsconfig.e2e.json", - "exclude": [ - "**/node_modules/**" - ] + "exclude": ["**/node_modules/**"] } } } } }, - "defaultProject": "coderiver-angular", - "schematics": { - "ng-alain:module": { - "routing": true, - "spec": false - }, - "ng-alain:list": { - "spec": false - }, - "ng-alain:edit": { - "spec": false, - "modal": true - }, - "ng-alain:view": { - "spec": false, - "modal": true - }, - "ng-alain:curd": { - "spec": false - }, - "@schematics/angular:module": { - "routing": true, - "spec": false - }, - "@schematics/angular:component": { - "prefix": "app", - "styleext": "less", - "spec": false, - "flat": false, - "inlineStyle": true, - "inlineTemplate": false - }, - "@schematics/angular:directive": { - "prefix": "app", - "spec": false - }, - "@schematics/angular:service": { - "spec": false - } - } + "defaultProject": "coderiver-angular" } diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts index 830a4bf..3b5613f 100644 --- a/e2e/src/app.e2e-spec.ts +++ b/e2e/src/app.e2e-spec.ts @@ -9,6 +9,6 @@ describe('workspace-project App', () => { it('should display welcome message', () => { page.navigateTo(); - expect(page.getParagraphText()).toEqual('Welcome to demo!'); + expect(page.getTitleText()).toEqual('Welcome to coderiver-angular!'); }); }); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts index 82ea75b..72e463a 100644 --- a/e2e/src/app.po.ts +++ b/e2e/src/app.po.ts @@ -5,7 +5,7 @@ export class AppPage { return browser.get('/'); } - getParagraphText() { + getTitleText() { return element(by.css('app-root h1')).getText(); } } diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 5f0046b..0000000 --- a/jest.config.js +++ /dev/null @@ -1,47 +0,0 @@ -module.exports = { - globals: { - 'ts-jest': { - tsConfigFile: './src/tsconfig.spec.json', - }, - __TRANSFORM_HTML__: true, - }, - testMatch: ['**/__tests__/**/*.+(ts|js)?(x)', '**/+(*.)+(spec|test).+(ts|js)?(x)'], - setupTestFrameworkScriptFile: '/node_modules/@angular-builders/jest/src/jest-config/setup.js', - transform: { - '^.+\\.(ts|html)$': '/node_modules/jest-preset-angular/preprocessor.js' - }, - transformIgnorePatterns: ['node_modules/(?!@ngrx)'], - moduleDirectories: [ - "node_modules", - "src/app", - ], - collectCoverageFrom: [ - 'src/app/module/**/*.{ts}', - '!src/app/*.{ts}', - '!src/app/**/*.{js}', - '!src/app/environment/*.{ts}', - '!src/app/language/*.{ts}', - '!src/app/**/*.module.{ts}', - '!src/app/**/*.interface.{ts}', - '!src/app/**/*.state.{ts}', - '!src/app/**/*.entity.{ts}' - ], - moduleFileExtensions: [ - 'ts', - 'tsx', - 'json', - 'js' - ], - testResultsProcessor: 'jest-sonar-reporter', - moduleNameMapper: { - "app/(.*)": "/src/app/$1", - "@common/(.*)": "/src/app/common/$1", - "@shared/(.*)": "/src/app/shared/$1", - "@core/(.*)": "/src/app/core/$1", - "@services/(.*)": "/src/app/services/$1", - "@components/(.*)": "/src/app/components/$1", - "@layout/(.*)": "/src/app/layout/$1", - "@testing/(.*)": "/src/testing/$1", - "@env/(.*)": "/src/environments/$1" - } -}; diff --git a/package.json b/package.json index 4e04af3..9cfadee 100644 --- a/package.json +++ b/package.json @@ -1,106 +1,51 @@ { - "name": "coderiver", - "version": "1.0.0", - "description": "", + "name": "coderiver-angular", + "version": "0.0.1", "scripts": { "ng": "ng", - "start": "npm run color-less && ng serve --proxy-config proxy.conf.json --host 0.0.0.0 -o", - "build": "npm run color-less && ng build --prod --build-optimizer", + "start": "ng serve", + "build": "ng build", "test": "ng test", - "lint": "npm run lint:ts && npm run lint:style", - "e2e": "ng e2e", - "color-less": "node scripts/color-less.js", - "lint:ts": "ng lint", - "lint:style": "stylelint \"{src}/**/*.less\" --syntax less", - "lint-staged": "lint-staged", - "hmr": "npm run color-less && ng serve -c=hmr", - "test:coverage": "jest --runInBand --coverage", - "test:snapshot": "jest --coverage -u", - "test:watch": "jest --clearCache && jest --watch" + "lint": "ng lint", + "e2e": "ng e2e" }, - "author": "coderiver", - "license": "MIT", + "private": true, "dependencies": { - "@angular/animations": "7.2.0", - "@angular/cdk": "7.2.1", - "@angular/common": "7.2.0", - "@angular/compiler": "7.2.0", - "@angular/core": "7.2.0", - "@angular/forms": "7.2.0", - "@angular/platform-browser": "7.2.0", - "@angular/platform-browser-dynamic": "7.2.0", - "@angular/router": "7.2.0", - "@delon/abc": "7.0.0-rc.3", - "@delon/acl": "7.0.0-rc.3", - "@delon/auth": "7.0.0-rc.3", - "@delon/cache": "7.0.0-rc.3", - "@delon/chart": "7.0.0-rc.3", - "@delon/form": "7.0.0-rc.3", - "@delon/mock": "7.0.0-rc.3", - "@delon/theme": "7.0.0-rc.3", - "@delon/util": "7.0.0-rc.3", - "ng-zorro-antd": "7.0.0-rc.3", - "rxjs": "6.3.3", - "screenfull": "4.0.0", - "tslib": "1.9.3", - "zone.js": "0.8.26" + "@angular/animations": "^7.2.1", + "@angular/cdk": "^7.2.1", + "@angular/common": "~7.2.0", + "@angular/compiler": "~7.2.0", + "@angular/core": "~7.2.0", + "@angular/forms": "~7.2.0", + "@angular/platform-browser": "~7.2.0", + "@angular/platform-browser-dynamic": "~7.2.0", + "@angular/router": "~7.2.0", + "core-js": "^2.5.4", + "ng-zorro-antd": "^7.0.0-rc.3", + "normalize.css": "^8.0.1", + "rxjs": "~6.3.3", + "tslib": "^1.9.0", + "zone.js": "~0.8.26" }, "devDependencies": { - "@angular-builders/jest": "7.2.0", - "@angular-devkit/build-angular": "0.12.1", - "@angular/cli": "7.2.1", - "@angular/compiler-cli": "7.2.0", - "@angularclass/hmr": "2.1.3", - "@types/jasmine": "3.3.5", - "@types/jasminewd2": "2.0.6", - "@types/node": "10.12.18", - "apply-loader": "2.0.0", - "codelyzer": "4.5.0", - "editorconfig-tools": "0.1.1", - "husky": "1.3.1", - "istanbul-reports": "2.0.1", - "jasmine": "3.3.1", - "jasmine-spec-reporter": "4.2.1", - "jasminewd2": "2.2.0", - "jest": "23.6.0", - "jest-sonar-reporter": "2.0.0", - "less-bundle-promise": "1.0.7", - "lint-staged": "8.1.0", - "ngx-wallaby-jest": "0.0.1", - "prettier": "1.15.3", - "prettier-stylelint": "0.4.2", - "protractor": "5.4.2", - "stylelint": "9.9.0", - "stylelint-config-prettier": "4.0.0", - "ts-node": "7.0.1", - "tslint": "5.12.1", - "typescript": "3.2.2", - "webpack": "4.28.4" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "linters": { - "*.{cmd,html,json,md,sh,txt,xml,yml}": [ - "editorconfig-tools fix", - "git add" - ], - "*.ts": [ - "tslint --fix", - "prettier --write", - "git add" - ], - "*.less": [ - "stylelint --fix --syntax less", - "prettier --write", - "git add" - ], - "ignore": [ - "src/assets/*" - ] - } + "@angular-devkit/build-angular": "~0.12.0", + "@angular/cli": "~7.2.1", + "@angular/compiler-cli": "~7.2.0", + "@angular/language-service": "~7.2.0", + "@types/jasmine": "~2.8.8", + "@types/jasminewd2": "~2.0.3", + "@types/node": "~8.9.4", + "codelyzer": "~4.5.0", + "jasmine-core": "~2.99.1", + "jasmine-spec-reporter": "~4.2.1", + "karma": "~3.1.1", + "karma-chrome-launcher": "~2.2.0", + "karma-coverage-istanbul-reporter": "~2.0.1", + "karma-jasmine": "~1.1.2", + "karma-jasmine-html-reporter": "^0.2.2", + "protractor": "~5.4.0", + "ts-node": "~7.0.0", + "tslint": "~5.11.0", + "typescript": "~3.2.2" } } diff --git a/protractor.conf.js b/protractor.conf.js deleted file mode 100644 index 7ee3b5e..0000000 --- a/protractor.conf.js +++ /dev/null @@ -1,28 +0,0 @@ -// Protractor configuration file, see link for more information -// https://github.com/angular/protractor/blob/master/lib/config.ts - -const { SpecReporter } = require('jasmine-spec-reporter'); - -exports.config = { - allScriptsTimeout: 11000, - specs: [ - './e2e/**/*.e2e-spec.ts' - ], - capabilities: { - 'browserName': 'chrome' - }, - directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 30000, - print: function() {} - }, - onPrepare() { - require('ts-node').register({ - project: 'e2e/tsconfig.e2e.json' - }); - jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); - } -}; diff --git a/proxy.conf.json b/proxy.conf.json deleted file mode 100644 index 991ee75..0000000 --- a/proxy.conf.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "/api": { - "target": "http://localhost:1337", - "secure": false - } -} \ No newline at end of file diff --git a/scripts/color-less.js b/scripts/color-less.js deleted file mode 100644 index b9b1b1b..0000000 --- a/scripts/color-less.js +++ /dev/null @@ -1,27 +0,0 @@ -const path = require('path'); -const fs = require('fs'); -const bundle = require('less-bundle-promise'); - -const root = path.resolve(__dirname, '../'); -const allLessPath = path.join(root, '_all.less'); -const target = path.join(root, 'src/assets/alain-default.less'); - -const content = ` -@import 'node_modules/@delon/theme/styles/index'; -@import 'node_modules/@delon/theme/styles/layout/default/index'; -@import 'node_modules/@delon/theme/styles/layout/fullscreen/index'; -@import 'node_modules/@delon/abc/index'; -@import 'node_modules/@delon/chart/index'; - -@import 'src/styles/index'; -@import 'src/styles/theme'; -`; - -fs.writeFileSync(allLessPath, content); - -bundle({ - src: allLessPath, -}).then(colorsLess => { - fs.writeFileSync(target, colorsLess); - fs.unlinkSync(allLessPath); -}); diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts new file mode 100644 index 0000000..34ac924 --- /dev/null +++ b/src/app/app-routing.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +const routes: Routes = [ + { path: '', redirectTo: '/home', pathMatch: 'full' }, + { + path: 'home', + loadChildren: './layout/home/home.module#HomeModule' + }, + { + path: 'passport', + loadChildren: './layout/passport/passport.module#PassportModule' + } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/src/app/app.component.less b/src/app/app.component.less deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index f4c7f92..dc240f2 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,18 +1,35 @@ -import { TestBed, TestModuleMetadata } from '@angular/core/testing'; -import { APP_BASE_HREF } from '@angular/common'; -import { setUpTestBed } from '@testing/common.spec'; - -import { AppComponent } from './app.component'; - -describe('Component: App', () => { - setUpTestBed({ - declarations: [AppComponent], - providers: [{ provide: APP_BASE_HREF, useValue: '/' }], - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const comp = fixture.debugElement.componentInstance; - expect(comp).toBeTruthy(); - }); -}); +import { TestBed, async } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + RouterTestingModule + ], + declarations: [ + AppComponent + ], + }).compileComponents(); + })); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'coderiver-angular'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('coderiver-angular'); + }); + + it('should render title in a h1 tag', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to coderiver-angular!'); + }); +}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f247985..01e14f9 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,40 +1,9 @@ -import { Component, OnInit, Renderer2, ElementRef } from '@angular/core'; -import { Router, NavigationEnd } from '@angular/router'; -import { filter } from 'rxjs/operators'; -import { TitleService } from '@delon/theme'; -import { VERSION as VERSION_ALAIN } from '@delon/theme'; -import { VERSION as VERSION_ZORRO, NzModalService } from 'ng-zorro-antd'; +import { Component } from '@angular/core'; @Component({ selector: 'app-root', - template: ``, + template: ` + + ` }) -export class AppComponent implements OnInit { - constructor( - el: ElementRef, - renderer: Renderer2, - private router: Router, - private titleSrv: TitleService, - private modalSrv: NzModalService, - ) { - renderer.setAttribute( - el.nativeElement, - 'ng-alain-version', - VERSION_ALAIN.full, - ); - renderer.setAttribute( - el.nativeElement, - 'ng-zorro-version', - VERSION_ZORRO.full, - ); - } - - ngOnInit() { - this.router.events - .pipe(filter(evt => evt instanceof NavigationEnd)) - .subscribe(() => { - this.titleSrv.setTitle(); - this.modalSrv.closeAll(); - }); - } -} +export class AppComponent {} diff --git a/src/app/app.graphql.module.ts b/src/app/app.graphql.module.ts deleted file mode 100644 index 752971e..0000000 --- a/src/app/app.graphql.module.ts +++ /dev/null @@ -1,59 +0,0 @@ -// import { NgModule, Inject, PLATFORM_ID } from '@angular/core'; -// import { isPlatformBrowser } from '@angular/common'; -// import { ApolloModule, Apollo } from 'apollo-angular'; -// import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http'; -// import { InMemoryCache } from 'apollo-cache-inmemory'; -// import { WebSocketLink } from 'apollo-link-ws'; -// import { split, ApolloLink } from 'apollo-link'; -// import { getMainDefinition } from 'apollo-utilities'; - -// @NgModule({ -// imports: [ -// ApolloModule, -// HttpLinkModule -// ] -// }) -// export class GraphqlModule { -// constructor( -// private readonly apollo: Apollo, -// private readonly httpLink: HttpLink, -// @Inject(PLATFORM_ID) private platformId: Object -// ) { -// if (isPlatformBrowser(platformId)) { -// // Create an http link: -// const http = httpLink.create({ -// uri: 'http://localhost:1337/graphql' -// }); - -// const authToken: string = localStorage.getItem('token') || null; -// // Create a WebSocket link: -// const ws = new WebSocketLink({ -// uri: -// 'ws://localhost:1338/subscriptions', -// options: { -// reconnect: true, -// connectionParams: { -// authToken -// } -// } -// }); - -// // using the ability to split links, you can send data to each link -// // depending on what kind of operation is being sent -// const link = split( -// // split based on operation type -// ({ query }) => { -// const { kind, operation } = getMainDefinition(query as any) as any; -// return kind === 'OperationDefinition' && operation === 'subscription'; -// }, -// ws, -// http, -// ); - -// apollo.create({ -// link, -// cache: new InMemoryCache() -// }); -// } -// } -// } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 978d889..f8571fa 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,96 +1,22 @@ -import { NgModule, LOCALE_ID, APP_INITIALIZER, Injector } from '@angular/core'; -import { HttpClient, HttpClientModule } from '@angular/common/http'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; -// #region default language -// 参考:https://ng-alain.com/docs/i18n -import { default as ngLang } from '@angular/common/locales/zh'; -import { NZ_I18N, zh_CN as zorroLang } from 'ng-zorro-antd'; -import { DELON_LOCALE, zh_CN as delonLang } from '@delon/theme'; +import { AppComponent } from './app.component'; -const LANG = { - abbr: 'zh', - ng: ngLang, - zorro: zorroLang, - delon: delonLang -}; -// register angular +import { AppRoutingModule } from './app-routing.module'; +import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd'; +import { HttpClientModule } from '@angular/common/http'; import { registerLocaleData } from '@angular/common'; +import zh from '@angular/common/locales/zh'; -registerLocaleData(LANG.ng, LANG.abbr); -const LANG_PROVIDES = [ - { provide: LOCALE_ID, useValue: LANG.abbr }, - { provide: NZ_I18N, useValue: LANG.zorro }, - { provide: DELON_LOCALE, useValue: LANG.delon } -]; -// #endregion - -// #region JSON Schema form (using @delon/form) -import { JsonSchemaModule } from '@shared/json-schema/json-schema.module'; - -const FORM_MODULES = [JsonSchemaModule]; -// #endregion - -// #region Http Interceptors -import { HTTP_INTERCEPTORS } from '@angular/common/http'; -import { SimpleInterceptor } from '@delon/auth'; -import { DefaultInterceptor } from '@core/net/default.interceptor'; - -const INTERCEPTOR_PROVIDES = [ - { provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true }, - { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true } -]; -// #endregion - -// #region global third module -const GLOBAL_THIRD_MODULES: any[] = []; -// #endregion - -// #region Startup Service -import { StartupService } from '@core/startup/startup.service'; - -export function StartupServiceFactory( - startupService: StartupService -): Function { - return () => startupService.load(); -} - -const APPINIT_PROVIDES = [ - StartupService, - { - provide: APP_INITIALIZER, - useFactory: StartupServiceFactory, - deps: [StartupService], - multi: true - } -]; -// #endregion - -import { DelonModule } from './delon.module'; -import { CoreModule } from './core/core.module'; -import { SharedModule } from './shared/shared.module'; -import { AppComponent } from './app.component'; -import { RoutesModule } from './app.routes.module'; -import { LayoutModule } from './layout/layout.module'; -import { ComponentsModule } from './components/components.module'; +registerLocaleData(zh); @NgModule({ declarations: [AppComponent], - imports: [ - BrowserModule, - BrowserAnimationsModule, - HttpClientModule, - DelonModule.forRoot(), - CoreModule, - SharedModule, - LayoutModule, - ComponentsModule, - RoutesModule, - ...FORM_MODULES, - ...GLOBAL_THIRD_MODULES - ], - providers: [...LANG_PROVIDES, ...INTERCEPTOR_PROVIDES, ...APPINIT_PROVIDES], + imports: [BrowserModule, BrowserAnimationsModule, FormsModule, AppRoutingModule, NgZorroAntdModule, HttpClientModule], + providers: [{ provide: NZ_I18N, useValue: zh_CN }], bootstrap: [AppComponent] }) export class AppModule {} diff --git a/src/app/app.routes.module.ts b/src/app/app.routes.module.ts deleted file mode 100644 index 30a84bb..0000000 --- a/src/app/app.routes.module.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { SimpleGuard } from '@delon/auth'; -import { environment } from '@env/environment'; -// layout -import { LayoutDefaultComponent } from '@layout/default/default.component'; -import { LayoutFullScreenComponent } from '@layout/fullscreen/fullscreen.component'; -import { LayoutPassportComponent } from '@layout/passport/passport.component'; -// dashboard pages -import { DashboardComponent } from '@components/dashboard/dashboard.component'; -// passport pages -import { UserLoginComponent } from '@components/passport/login/login.component'; -import { UserRegisterComponent } from '@components/passport/register/register.component'; -import { UserRegisterResultComponent } from '@components/passport/register-result/register-result.component'; -// single pages -import { CallbackComponent } from '@components/callback/callback.component'; -import { UserLockComponent } from '@components/passport/lock/lock.component'; -import { Exception403Component } from '@components/exception/403.component'; -import { Exception404Component } from '@components/exception/404.component'; -import { Exception500Component } from '@components/exception/500.component'; -import { HomeComponent } from '@layout/home/home.component'; -import { HomePageComponent } from '@components/homepage/home-page.component'; - -const routes: Routes = [ - // 以后应该能用到 - // { - // path: '', - // component: LayoutDefaultComponent, - // // canActivate: [SimpleGuard], - // children: [ - // { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, - // { path: 'dashboard', component: DashboardComponent, data: { title: '仪表盘', titleI18n: 'dashboard' } }, - // // 业务子模块 - // // { path: 'widgets', loadChildren: './widgets/widgets.module#WidgetsModule' } - // ] - // }, - { - path: '', - component: HomeComponent, - children: [ - { path: '', redirectTo: 'home', pathMatch: 'full' }, - { - path: 'home', - component: HomePageComponent, - data: { title: '仪表盘', titleI18n: 'dashboard' } - } - // 业务子模块 - // { path: 'widgets', loadChildren: './widgets/widgets.module#WidgetsModule' } - ] - }, - // 全屏布局 - { - path: 'fullscreen', - component: LayoutFullScreenComponent, - children: [] - }, - // passport - { - path: 'passport', - component: LayoutPassportComponent, - children: [ - { - path: 'login', - component: UserLoginComponent, - data: { title: '登录', titleI18n: 'pro-login' } - }, - { - path: 'register', - component: UserRegisterComponent, - data: { title: '注册', titleI18n: 'pro-register' } - }, - { - path: 'register-result', - component: UserRegisterResultComponent, - data: { title: '注册结果', titleI18n: 'pro-register-result' } - } - ] - }, - // 单页不包裹Layout - { path: 'callback/:type', component: CallbackComponent }, - { - path: 'lock', - component: UserLockComponent, - data: { title: '锁屏', titleI18n: 'lock' } - }, - { path: '403', component: Exception403Component }, - { path: '404', component: Exception404Component }, - { path: '500', component: Exception500Component }, - { path: '**', redirectTo: 'dashboard' } -]; - -@NgModule({ - imports: [RouterModule.forRoot(routes, { useHash: environment.useHash })], - exports: [RouterModule] -}) -export class RoutesModule {} diff --git a/src/app/components/callback/callback.component.ts b/src/app/components/callback/callback.component.ts deleted file mode 100644 index b5eec9f..0000000 --- a/src/app/components/callback/callback.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { SocialService } from '@delon/auth'; -import { Subscription } from 'rxjs'; - -@Component({ - selector: 'app-callback', - template: ``, - providers: [SocialService], -}) -export class CallbackComponent implements OnInit, OnDestroy { - private router$: Subscription; - type: string; - - constructor( - private socialService: SocialService, - private route: ActivatedRoute, - ) {} - - ngOnInit(): void { - this.router$ = this.route.params.subscribe(params => { - this.type = params['type']; - this.mockModel(); - }); - } - - private mockModel() { - this.socialService.callback({ - token: '123456789', - name: 'cipchk', - email: `${this.type}@${this.type}.com`, - id: 10000, - time: +new Date(), - }); - } - - ngOnDestroy() { - this.router$.unsubscribe(); - } -} diff --git a/src/app/components/components.module.ts b/src/app/components/components.module.ts deleted file mode 100644 index aab95b4..0000000 --- a/src/app/components/components.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { SharedModule } from '@shared/shared.module'; -// dashboard pages -import { DashboardComponent } from './dashboard/dashboard.component'; -// passport pages -import { UserLoginComponent } from './passport/login/login.component'; -import { UserRegisterComponent } from './passport/register/register.component'; -import { UserRegisterResultComponent } from './passport/register-result/register-result.component'; -// single pages -import { CallbackComponent } from './callback/callback.component'; -import { UserLockComponent } from './passport/lock/lock.component'; -import { Exception403Component } from './exception/403.component'; -import { Exception404Component } from './exception/404.component'; -import { Exception500Component } from './exception/500.component'; -import { HomePageComponent } from '@components/homepage/home-page.component'; -import { ExcellentProjectComponent } from '@components/homepage/excellent-project/excellent-project.component'; -import { HomeCarouselComponent } from '@components/homepage/home-carousel/home-carousel.component'; -import { TitleLineComponent } from '@components/homepage/title-line/title-line.component'; -import { GoodItemComponent } from '@components/homepage/goot-item/good-item.component'; -import { FastJoinComponent } from '@components/homepage/fast-join/fast-join.component'; -import { DownloadAppComponent } from './homepage/download/download-app.component'; - -const COMPONENTS = [ - DashboardComponent, - HomePageComponent, - ExcellentProjectComponent, - HomeCarouselComponent, - GoodItemComponent, - FastJoinComponent, - TitleLineComponent, - DownloadAppComponent, - // passport pages - UserLoginComponent, - UserRegisterComponent, - UserRegisterResultComponent, - // single pages - CallbackComponent, - UserLockComponent, - Exception403Component, - Exception404Component, - Exception500Component -]; -const COMPONENTS_NOROUNT: any[] = []; - -@NgModule({ - imports: [SharedModule], - declarations: [...COMPONENTS, ...COMPONENTS_NOROUNT], - entryComponents: COMPONENTS_NOROUNT -}) -export class ComponentsModule {} diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html deleted file mode 100644 index be2ea81..0000000 --- a/src/app/components/dashboard/dashboard.component.html +++ /dev/null @@ -1,4 +0,0 @@ - -
-

Page NameWelcome !

-
\ No newline at end of file diff --git a/src/app/components/dashboard/dashboard.component.ts b/src/app/components/dashboard/dashboard.component.ts deleted file mode 100644 index 2d190a3..0000000 --- a/src/app/components/dashboard/dashboard.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { _HttpClient } from '@delon/theme'; - -@Component({ - selector: 'app-dashboard', - templateUrl: './dashboard.component.html' -}) -export class DashboardComponent implements OnInit { - constructor(private http: _HttpClient) {} - - ngOnInit() {} -} diff --git a/src/app/components/exception/403.component.ts b/src/app/components/exception/403.component.ts deleted file mode 100644 index 8355d3b..0000000 --- a/src/app/components/exception/403.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { NzModalService } from 'ng-zorro-antd'; - -@Component({ - selector: 'exception-403', - template: ``, -}) -export class Exception403Component { - constructor(modalSrv: NzModalService) { - modalSrv.closeAll(); - } -} diff --git a/src/app/components/exception/404.component.ts b/src/app/components/exception/404.component.ts deleted file mode 100644 index 50f8baf..0000000 --- a/src/app/components/exception/404.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { NzModalService } from 'ng-zorro-antd'; - -@Component({ - selector: 'exception-404', - template: ``, -}) -export class Exception404Component { - constructor(modalSrv: NzModalService) { - modalSrv.closeAll(); - } -} diff --git a/src/app/components/exception/500.component.ts b/src/app/components/exception/500.component.ts deleted file mode 100644 index 4614dbb..0000000 --- a/src/app/components/exception/500.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { NzModalService } from 'ng-zorro-antd'; - -@Component({ - selector: 'exception-500', - template: ``, -}) -export class Exception500Component { - constructor(modalSrv: NzModalService) { - modalSrv.closeAll(); - } -} diff --git a/src/app/components/homepage/download/download-app.component.html b/src/app/components/homepage/download/download-app.component.html deleted file mode 100644 index bb60e86..0000000 --- a/src/app/components/homepage/download/download-app.component.html +++ /dev/null @@ -1,11 +0,0 @@ - -
-
- - -
- - -
-
-
diff --git a/src/app/components/homepage/download/download-app.component.less b/src/app/components/homepage/download/download-app.component.less deleted file mode 100644 index 3d16dab..0000000 --- a/src/app/components/homepage/download/download-app.component.less +++ /dev/null @@ -1,48 +0,0 @@ -.download { - background-image: url('../../../../assets/icon/home/back.png'); - background-repeat: no-repeat; - background-size: contain; - background-position: right; - width: 100%; - padding-top: 50%; - position: relative; - - &-app { - position: absolute; - top: 20%; - width: 100%; - - &-android, - &-ios, - &-code-android, - &-code-ios { - max-width: 25%; - cursor: pointer; - } - - &-ios, - &-code-ios { - margin-left: 5%; - } - - &-code-ios, - &-code-android { - visibility: hidden; - padding: 10px; - border: 1px solid; - border-top: none; - } - - &-android:hover ~ .download-app-code { - .download-app-code-android { - visibility: unset; - } - } - - &-ios:hover ~ .download-app-code { - .download-app-code-ios { - visibility: unset; - } - } - } -} diff --git a/src/app/components/homepage/download/download-app.component.ts b/src/app/components/homepage/download/download-app.component.ts deleted file mode 100644 index f684347..0000000 --- a/src/app/components/homepage/download/download-app.component.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'page-download-app', - templateUrl: './download-app.component.html', - styleUrls: ['./download-app.component.less'] -}) -export class DownloadAppComponent {} diff --git a/src/app/components/homepage/excellent-project/excellent-project.component.html b/src/app/components/homepage/excellent-project/excellent-project.component.html deleted file mode 100644 index bec8009..0000000 --- a/src/app/components/homepage/excellent-project/excellent-project.component.html +++ /dev/null @@ -1,17 +0,0 @@ -
- -
-
- - {{item.name}} - {{item.introduce}} -
- - {{item.pageView}} - - {{item.likeNum}} -
-
-
-
diff --git a/src/app/components/homepage/excellent-project/excellent-project.component.less b/src/app/components/homepage/excellent-project/excellent-project.component.less deleted file mode 100644 index 56cff58..0000000 --- a/src/app/components/homepage/excellent-project/excellent-project.component.less +++ /dev/null @@ -1,69 +0,0 @@ -.project { - &-content { - display: flex; - flex-direction: row; - flex-wrap: wrap; - - &__item { - width: 50%; - padding: 2.5%; - display: flex; - flex-direction: column; - - &-img { - max-width: 100%; - } - - .text-one { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } - - &-name { - .text-one; - margin-top: 13px; - font-size: 15px; - color: #18262a; - } - - &-intro { - .text-one; - margin-top: 7px; - font-size: 10px; - color: #999999; - } - - &-operate { - display: flex; - flex-direction: row; - align-items: center; - - .icon-common { - display: inline-block; - background-repeat: no-repeat; - background-size: contain; - width: 18px; - height: 12px; - cursor: pointer; - } - - .icon-watch { - .icon-common; - background-image: url('../../../../assets/icon/home/浏览icon.png'); - } - - .icon-praise { - .icon-common; - height: 15px; - background-image: url('../../../../assets/icon/home/点赞icon.png'); - margin-left: 20px; - } - } - } - - &__item:hover { - box-shadow: 1px 3px 5px 1px rgba(0, 0, 0, 0.3); - } - } -} diff --git a/src/app/components/homepage/excellent-project/excellent-project.component.ts b/src/app/components/homepage/excellent-project/excellent-project.component.ts deleted file mode 100644 index 84ff807..0000000 --- a/src/app/components/homepage/excellent-project/excellent-project.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { Router } from '@angular/router'; - -@Component({ - selector: 'page-excellent-project', - templateUrl: './excellent-project.component.html', - styleUrls: ['./excellent-project.component.less'] -}) -export class ExcellentProjectComponent { - constructor(private router: Router) {} - - @Input() projects: Array = [ - { - name: - '项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1', - introduce: - '第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目第一个项目', - avatar: '', - pageView: 10000, - heatNum: '', - likeNum: 200 - }, - { - name: '项目2', - introduce: '第一个项目', - avatar: '', - pageView: 10000, - heatNum: '', - likeNum: 200 - }, - { - name: '项目3', - introduce: '第一个项目', - avatar: '', - pageView: 10000, - heatNum: '', - likeNum: 200 - }, - { - name: '项目4', - introduce: '第一个项目', - avatar: '', - pageView: 10000, - heatNum: '', - likeNum: 200 - } - ]; - - toProjectCenter = () => { - this.router.navigate(['/project-center']); - }; -} diff --git a/src/app/components/homepage/fast-join/fast-join.component.html b/src/app/components/homepage/fast-join/fast-join.component.html deleted file mode 100644 index 171c422..0000000 --- a/src/app/components/homepage/fast-join/fast-join.component.html +++ /dev/null @@ -1,24 +0,0 @@ - -
-
-
- - {{item.teamName}} -
{{item.recruitInfo}}
-
-
-
{{item.introduce}}
-
- -
-
{{item.founderName}}
-
{{item.founderPosition}}
-
-
-
-
-
-
- - -
diff --git a/src/app/components/homepage/fast-join/fast-join.component.less b/src/app/components/homepage/fast-join/fast-join.component.less deleted file mode 100644 index fcbb461..0000000 --- a/src/app/components/homepage/fast-join/fast-join.component.less +++ /dev/null @@ -1,103 +0,0 @@ -.fast-join { - display: flex !important; - flex-direction: row; - - &-item { - padding: 2%; - color: #18262a; - cursor: pointer; - flex: 1; - overflow: hidden; - &__list { - display: flex; - flex-direction: column; - - &-img { - max-width: 100%; - } - - &-teamName { - margin: 10px 0; - font-size: 15px; - } - - &-recruit { - font-size: 10px; - } - } - - &__detail { - display: none; - flex-direction: column; - justify-content: space-between; - - &-intro { - font-size: 15px; - } - - &-info { - display: flex; - flex-direction: row; - align-items: center; - - &-header { - width: 30px; - height: 30px; - border-radius: 50%; - - &__name, - &__position { - font-size: 10px; - margin-left: 10px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } - } - } - } - - &-item:hover { - box-shadow: 0px 4px 5px 1px rgba(0, 0, 0, 0.3); - - .fast-join-item__list { - display: none; - } - - .fast-join-item__detail { - display: flex; - height: 100%; - } - } - - &-button { - display: flex; - flex-direction: row; - justify-content: space-between; - margin-top: 25px; - - .icon-common { - display: inline-block; - background-size: cover; - background-repeat: no-repeat; - height: 28px; - width: 28px; - cursor: pointer; - } - - &__left { - .icon-common; - background-image: url('../../../../assets/icon/home/icon-left.png'); - } - - &__right { - .icon-common; - background-image: url('../../../../assets/icon/home/icon-right.png'); - } - - .show { - visibility: hidden; - } - } -} diff --git a/src/app/components/homepage/fast-join/fast-join.component.ts b/src/app/components/homepage/fast-join/fast-join.component.ts deleted file mode 100644 index 727ed06..0000000 --- a/src/app/components/homepage/fast-join/fast-join.component.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Component, - Input, - OnInit -} from '@angular/core'; - -@Component({ - selector: 'page-fast-join', - templateUrl: './fast-join.component.html', - styleUrls: ['./fast-join.component.less'] -}) -export class FastJoinComponent implements AfterViewInit { - @Input() groups: Array = [ - { - teamName: '河马1', - recruitInfo: '正在招募:UX设计师,UI设计师,前端工程师,全栈工程师...', - teamAvatar: 'string', - introduce: - '加入河马团队,实现更高效的工作合作模式,我们正在招募全栈程序员,UX设计师,前端工程师。', - founderName: 'Alex Wang', - founderPosition: '河马团队发起人/创始人', - founderAvatar: '' - }, - { - teamName: '河马2', - recruitInfo: '正在招募:UX设计师,UI设计师,前端工程师,全栈工程师...', - teamAvatar: 'string', - introduce: - '加入河马团队,实现更高效的工作合作模式,我们正在招募全栈程序员,UX设计师,前端工程师。', - founderName: 'Alex Wang', - founderPosition: '河马团队发起人/创始人', - founderAvatar: '' - }, - { - teamName: '河马3', - recruitInfo: '正在招募:UX设计师,UI设计师,前端工程师,全栈工程师...', - teamAvatar: 'string', - introduce: - '加入河马团队,实现更高效的工作合作模式,我们正在招募全栈程序员,UX设计师,前端工程师。', - founderName: 'Alex Wang', - founderPosition: '河马团队发起人/创始人', - founderAvatar: '' - }, - { - teamName: '河马4', - recruitInfo: '正在招募:UX设计师,UI设计师,前端工程师,全栈工程师...', - teamAvatar: 'string', - introduce: - '加入河马团队,实现更高效的工作合作模式,我们正在招募全栈程序员,UX设计师,前端工程师。', - founderName: 'Alex Wang', - founderPosition: '河马团队发起人/创始人', - founderAvatar: '' - }, - { - teamName: '河马5', - recruitInfo: '正在招募:UX设计师,UI设计师,前端工程师,全栈工程师...', - teamAvatar: 'string', - introduce: - '加入河马团队,实现更高效的工作合作模式,我们正在招募全栈程序员,UX设计师,前端工程师。', - founderName: 'Alex Wang', - founderPosition: '河马团队发起人/创始人', - founderAvatar: '' - }, - { - teamName: '河马6', - recruitInfo: '正在招募:UX设计师,UI设计师,前端工程师,全栈工程师...', - teamAvatar: 'string', - introduce: - '加入河马团队,实现更高效的工作合作模式,我们正在招募全栈程序员,UX设计师,前端工程师。', - founderName: 'Alex Wang', - founderPosition: '河马团队发起人/创始人', - founderAvatar: '' - } - ]; - currentIndex = 0; - maxIndex = 0; - showList: Array = []; - - constructor(private cdr: ChangeDetectorRef) {} - - getMoreGroup = () => {}; - - ngAfterViewInit(): void { - this.afterChange(); - } - - afterChange = () => { - this.showList = this.groups.slice( - this.currentIndex * 3, - this.currentIndex * 3 + 3 - ); - this.maxIndex = Math.ceil(this.groups.length / 3) - 1; - this.cdr.detectChanges(); - }; - - changeIndex = (isAdd: boolean = false) => { - isAdd ? this.currentIndex++ : this.currentIndex--; - this.afterChange(); - }; -} diff --git a/src/app/components/homepage/goot-item/good-item.component.html b/src/app/components/homepage/goot-item/good-item.component.html deleted file mode 100644 index 23e7d63..0000000 --- a/src/app/components/homepage/goot-item/good-item.component.html +++ /dev/null @@ -1,10 +0,0 @@ -
-
-
- -
- {{item.name}} - {{item.roleName}} -
{{item.introduce}}
-
-
diff --git a/src/app/components/homepage/goot-item/good-item.component.less b/src/app/components/homepage/goot-item/good-item.component.less deleted file mode 100644 index 305d0f8..0000000 --- a/src/app/components/homepage/goot-item/good-item.component.less +++ /dev/null @@ -1,60 +0,0 @@ -.container { - display: flex; - flex-direction: row; - flex-wrap: wrap; - - &-item { - display: flex; - flex-direction: column; - align-items: center; - width: 25%; - padding: 2%; - color: #18262a; - cursor: pointer; - - &__header { - background-repeat: no-repeat; - background-size: cover; - background-image: url('../../../../assets/icon/home/头像-圈圈.png'); - width: 100%; - padding-top: 100%; - position: relative; - - &-img { - top: 6%; - left: 6%; - position: absolute; - max-width: 88%; - max-height: 88%; - } - } - - &-first { - font-size: 17px; - } - - &-second { - font-size: 9px; - } - - &-intro { - font-size: 9px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; - } - } - - &-item:hover { - box-shadow: 0px 4px 5px 1px rgba(0, 0, 0, 0.3); - .container-item-intro { - white-space: unset; - display: -webkit-box; //必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。 - //-webkit-box-orient; //必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。 - text-overflow: ellipsis; //可以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本 。 - overflow: hidden; - -webkit-line-clamp: 5; - } - } -} diff --git a/src/app/components/homepage/goot-item/good-item.component.ts b/src/app/components/homepage/goot-item/good-item.component.ts deleted file mode 100644 index fc261ab..0000000 --- a/src/app/components/homepage/goot-item/good-item.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'page-good-item', - templateUrl: './good-item.component.html', - styleUrls: ['./good-item.component.less'] -}) -export class GoodItemComponent { - @Input() dataSource: Array = []; -} diff --git a/src/app/components/homepage/home-carousel/home-carousel.component.html b/src/app/components/homepage/home-carousel/home-carousel.component.html deleted file mode 100644 index ee4e8f9..0000000 --- a/src/app/components/homepage/home-carousel/home-carousel.component.html +++ /dev/null @@ -1,13 +0,0 @@ - -
- -
- 近23万优秀开发者 - 您的专属云端开发团队 -
- 新建项目 - 快速组队 -
-
-
-
` diff --git a/src/app/components/homepage/home-carousel/home-carousel.component.less b/src/app/components/homepage/home-carousel/home-carousel.component.less deleted file mode 100644 index f0f6373..0000000 --- a/src/app/components/homepage/home-carousel/home-carousel.component.less +++ /dev/null @@ -1,54 +0,0 @@ -/deep/ .carousel { - display: block; - margin-bottom: 50px; -} - -.home-item { - position: relative; - - &-img { - max-width: 100%; - } - - &-show { - position: absolute; - left: 5px; - right: 0; - top: 0; - bottom: 0; - display: flex; - flex-direction: column; - justify-content: center; - - &__first { - color: #4688f1; - font-size: 35px; - } - - &__second { - font-size: 35px; - color: #18262a; - margin: 16px 0 30px 0; - } - - .button-common { - padding: 10px 20px; - cursor: pointer; - } - - .button-create { - .button-common; - color: black; - border: 1px solid black; - } - - .button-group { - .button-common; - color: #40aea8; - border: 1px solid #40aea8; - margin-left: 20px; - } - } - - //max-height: 459px; -} diff --git a/src/app/components/homepage/home-carousel/home-carousel.component.ts b/src/app/components/homepage/home-carousel/home-carousel.component.ts deleted file mode 100644 index 2eabb91..0000000 --- a/src/app/components/homepage/home-carousel/home-carousel.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, HostBinding, Input } from '@angular/core'; -import { Router } from '@angular/router'; - -@Component({ - selector: 'page-home-carousel', - templateUrl: './home-carousel.component.html', - styleUrls: ['./home-carousel.component.less'] -}) -export class HomeCarouselComponent { - @HostBinding('class.carousel') car = true; - - constructor(private router: Router) {} - - @Input() carousels: Array = [ - { - path: '', - url: - 'http://img17.3lian.com/d/file/201702/20/d5d692b492df805ad8a4cb61fd1c73d3.jpg' - }, - { - path: '', - url: - 'http://img17.3lian.com/d/file/201702/20/7d3079c4ca0d11a0126116100d1ca3dd.jpg' - }, - { - path: '', - url: - 'http://img17.3lian.com/d/file/201702/20/ec4acb80b76b3e84fe58f48b558908d3.jpg' - }, - { - path: '', - url: - 'http://img17.3lian.com/d/file/201702/20/a7c84a0702d14a073f76dda56f71dec0.jpg' - } - ]; - - create = () => {}; - - joinGroup = () => {}; -} diff --git a/src/app/components/homepage/home-page.component.html b/src/app/components/homepage/home-page.component.html deleted file mode 100644 index c38167c..0000000 --- a/src/app/components/homepage/home-page.component.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/app/components/homepage/home-page.component.ts b/src/app/components/homepage/home-page.component.ts deleted file mode 100644 index ba3f654..0000000 --- a/src/app/components/homepage/home-page.component.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Component, HostBinding } from '@angular/core'; - -@Component({ - selector: 'page-home-page', - templateUrl: './home-page.component.html' -}) -export class HomePageComponent { - @HostBinding('style.display') dis = 'block'; - goodProgrammers: Array = [ - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: 'string' - }, - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: - '前端工程师前端工程师前端工程师前端工程师前端工程师前端工程师' + - '前端工程师前端工程师前端工程师前端工程师前端工程师前端工程师前端工程师' + - '前端工程师前端工程师前端工程师前端工程师前端工程师前端工程师' - }, - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: 'string' - }, - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: 'string' - } - ]; - goodDesigners: Array = [ - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: 'string' - }, - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: 'string' - }, - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: 'string' - }, - { - name: '张三', - roleId: 2, - roleName: '前端工程师', - avatar: 'string', - introduce: 'string' - } - ]; - - toMoreProgrammer = () => {}; - - toMoreDesigner = () => {}; -} diff --git a/src/app/components/homepage/title-line/title-line.component.html b/src/app/components/homepage/title-line/title-line.component.html deleted file mode 100644 index 687dba8..0000000 --- a/src/app/components/homepage/title-line/title-line.component.html +++ /dev/null @@ -1,7 +0,0 @@ -
-
-
- {{title}} - {{action}} -
-
diff --git a/src/app/components/homepage/title-line/title-line.component.less b/src/app/components/homepage/title-line/title-line.component.less deleted file mode 100644 index fb1139d..0000000 --- a/src/app/components/homepage/title-line/title-line.component.less +++ /dev/null @@ -1,26 +0,0 @@ -.contain { - &-line { - margin-top: 30px; - width: 100%; - height: 2px; - } - - &-title { - color: #18262a; - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - height: 110px; - - &__left { - font-size: 20px; - } - - &__right { - font-size: 15px; - color: #40aea8; - cursor: pointer; - } - } -} diff --git a/src/app/components/homepage/title-line/title-line.component.ts b/src/app/components/homepage/title-line/title-line.component.ts deleted file mode 100644 index c40d1c0..0000000 --- a/src/app/components/homepage/title-line/title-line.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'page-title-line', - templateUrl: './title-line.component.html', - styleUrls: ['./title-line.component.less'] -}) -export class TitleLineComponent { - @Input() title = ''; - @Input() color = '#40aea8'; - @Input() action = '查看更多'; - @Input() clickFunc: Function = () => {}; -} diff --git a/src/app/components/passport/lock/lock.component.html b/src/app/components/passport/lock/lock.component.html deleted file mode 100644 index 98e7b1c..0000000 --- a/src/app/components/passport/lock/lock.component.html +++ /dev/null @@ -1,23 +0,0 @@ - -
-
-
- -
-
- - - - - - 请输入密码! - - - - - - - -
-
-
\ No newline at end of file diff --git a/src/app/components/passport/lock/lock.component.less b/src/app/components/passport/lock/lock.component.less deleted file mode 100644 index 80251d7..0000000 --- a/src/app/components/passport/lock/lock.component.less +++ /dev/null @@ -1,12 +0,0 @@ -:host ::ng-deep { - .ant-card-body { - position: relative; - margin-top: 80px; - } - .avatar { - position: absolute; - top: -20px; - left: 50%; - margin-left: -20px; - } -} diff --git a/src/app/components/passport/lock/lock.component.spec.ts b/src/app/components/passport/lock/lock.component.spec.ts deleted file mode 100644 index a4daab7..0000000 --- a/src/app/components/passport/lock/lock.component.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed, TestModuleMetadata } from '@angular/core/testing'; -import { setUpTestBed } from '@testing/common.spec'; - -import { UserLockComponent } from './lock.component'; - -describe('Pages: lock', () => { - setUpTestBed({ - declarations: [UserLockComponent], - }); - - it('should create an instance', () => { - const fixture = TestBed.createComponent(UserLockComponent); - const comp = fixture.debugElement.componentInstance; - expect(comp).toBeTruthy(); - }); -}); diff --git a/src/app/components/passport/lock/lock.component.ts b/src/app/components/passport/lock/lock.component.ts deleted file mode 100644 index cb168ed..0000000 --- a/src/app/components/passport/lock/lock.component.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Router } from '@angular/router'; -import { Component } from '@angular/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { SettingsService } from '@delon/theme'; - -@Component({ - selector: 'passport-lock', - templateUrl: './lock.component.html', - styleUrls: ['./lock.component.less'] -}) -export class UserLockComponent { - f: FormGroup; - - constructor( - fb: FormBuilder, - public settings: SettingsService, - private router: Router - ) { - this.f = fb.group({ - password: [null, Validators.required] - }); - } - - submit() { - // tslint:disable-next-line:forin - for (const i in this.f.controls) { - this.f.controls[i].markAsDirty(); - this.f.controls[i].updateValueAndValidity(); - } - if (this.f.valid) { - console.log('Valid!'); - console.log(this.f.value); - this.router.navigate(['dashboard']); - } - } -} diff --git a/src/app/components/passport/login/login.component.html b/src/app/components/passport/login/login.component.html deleted file mode 100644 index e006c9f..0000000 --- a/src/app/components/passport/login/login.component.html +++ /dev/null @@ -1,62 +0,0 @@ - -
- - - - - - - - - Please enter mobile number! - - - - - - - - Please enter password! - - - - - - - - - - - 请输入手机号 - 手机号格式错误 - - - - - - - - - - - 请输入验证码! - - - - - - - - - - - - - - 忘记密码 - - - - -
-
其他登录方式注册账户
\ No newline at end of file diff --git a/src/app/components/passport/login/login.component.less b/src/app/components/passport/login/login.component.less deleted file mode 100644 index ff9656f..0000000 --- a/src/app/components/passport/login/login.component.less +++ /dev/null @@ -1,42 +0,0 @@ -@import '~@delon/theme/styles/default'; -:host { - display: block; - width: 368px; - margin: 0 auto; - ::ng-deep { - .ant-tabs .ant-tabs-bar { - border-bottom: 0; - margin-bottom: 24px; - text-align: center; - } - .ant-tabs-tab { - font-size: 16px; - line-height: 24px; - } - .ant-input-affix-wrapper .ant-input:not(:first-child) { - padding-left: 34px; - } - .icon { - font-size: 24px; - color: rgba(0, 0, 0, 0.2); - margin-left: 16px; - vertical-align: middle; - cursor: pointer; - transition: color 0.3s; - &:hover { - color: @primary-color; - } - } - .other { - text-align: left; - margin-top: 24px; - line-height: 22px; - nz-tooltip { - vertical-align: middle; - } - .register { - float: right; - } - } - } -} diff --git a/src/app/components/passport/login/login.component.ts b/src/app/components/passport/login/login.component.ts deleted file mode 100644 index 47abb9b..0000000 --- a/src/app/components/passport/login/login.component.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { SettingsService, _HttpClient } from '@delon/theme'; -import { Component, OnDestroy, Inject, Optional } from '@angular/core'; -import { Router } from '@angular/router'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { NzMessageService, NzModalService } from 'ng-zorro-antd'; -import { - SocialService, - SocialOpenType, - TokenService, - DA_SERVICE_TOKEN -} from '@delon/auth'; -import { ReuseTabService } from '@delon/abc'; -import { environment } from '@env/environment'; -import { StartupService } from '@core/startup/startup.service'; - -@Component({ - selector: 'passport-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.less'], - providers: [SocialService] -}) -export class UserLoginComponent implements OnDestroy { - constructor( - fb: FormBuilder, - modalSrv: NzModalService, - public msg: NzMessageService, - private router: Router, - private settingsService: SettingsService, - private socialService: SocialService, - @Optional() - @Inject(ReuseTabService) - private reuseTabService: ReuseTabService, - @Inject(DA_SERVICE_TOKEN) private tokenService: TokenService, - private startupSrv: StartupService, - public http: _HttpClient - ) { - this.form = fb.group({ - userName: [null, [Validators.required, Validators.minLength(5)]], - password: [null, Validators.required], - mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], - captcha: [null, [Validators.required]], - remember: [true] - }); - modalSrv.closeAll(); - } - - // #region fields - - get userName() { - return this.form.controls.userName; - } - get password() { - return this.form.controls.password; - } - get mobile() { - return this.form.controls.mobile; - } - get captcha() { - return this.form.controls.captcha; - } - form: FormGroup; - error = ''; - type = 0; - - // #region get captcha - - count = 0; - interval$: any; - - // #endregion - - switch(ret: any) { - this.type = ret.index; - } - - getCaptcha() { - if (this.mobile.invalid) { - this.mobile.markAsDirty({ onlySelf: true }); - this.mobile.updateValueAndValidity({ onlySelf: true }); - return; - } - this.count = 59; - this.interval$ = setInterval(() => { - this.count -= 1; - if (this.count <= 0) { - clearInterval(this.interval$); - } - }, 1000); - } - - // #endregion - - submit() { - this.error = ''; - if (this.type === 0) { - this.userName.markAsDirty(); - this.userName.updateValueAndValidity(); - this.password.markAsDirty(); - this.password.updateValueAndValidity(); - if (this.userName.invalid || this.password.invalid) { - return; - } - } else { - this.mobile.markAsDirty(); - this.mobile.updateValueAndValidity(); - this.captcha.markAsDirty(); - this.captcha.updateValueAndValidity(); - if (this.mobile.invalid || this.captcha.invalid) { - return; - } - } - - // 默认配置中对所有HTTP请求都会强制 [校验](https://ng-alain.com/auth/getting-started) 用户 Token - // 然一般来说登录请求不需要校验,因此可以在请求URL加上:`/login?_allow_anonymous=true` 表示不触发用户 Token 校验 - this.http - .post('/login/account?_allow_anonymous=true', { - type: this.type, - userName: this.userName.value, - password: this.password.value - }) - .subscribe((res: any) => { - if (res.msg !== 'ok') { - this.error = res.msg; - return; - } - // 清空路由复用信息 - this.reuseTabService.clear(); - // 设置用户Token信息 - this.tokenService.set(res.user); - // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 - this.startupSrv.load().then(() => this.router.navigate(['/'])); - }); - } - - // #region social - - open(type: string, openType: SocialOpenType = 'href') { - let url = ``; - let callback = ``; - if (environment.production) { - callback = 'https://ng-alain.github.io/ng-alain/callback/' + type; - } else { - callback = 'http://localhost:4200/callback/' + type; - } - switch (type) { - case 'auth0': - url = `//cipchk.auth0.com/login?client=8gcNydIDzGBYxzqV0Vm1CX_RXH-wsWo5&redirect_uri=${decodeURIComponent( - callback - )}`; - break; - case 'github': - url = `//github.com/login/oauth/authorize?client_id=9d6baae4b04a23fcafa2&response_type=code&redirect_uri=${decodeURIComponent( - callback - )}`; - break; - case 'weibo': - url = `https://api.weibo.com/oauth2/authorize?client_id=1239507802&response_type=code&redirect_uri=${decodeURIComponent( - callback - )}`; - break; - } - if (openType === 'window') { - this.socialService - .login(url, '/', { - type: 'window' - }) - .subscribe(res => { - if (res) { - this.settingsService.setUser(res); - this.router.navigateByUrl('/'); - } - }); - } else { - this.socialService.login(url, '/', { - type: 'href' - }); - } - } - - // #endregion - - ngOnDestroy(): void { - if (this.interval$) { - clearInterval(this.interval$); - } - } -} diff --git a/src/app/components/passport/register-result/register-result.component.html b/src/app/components/passport/register-result/register-result.component.html deleted file mode 100644 index 1a2a2f1..0000000 --- a/src/app/components/passport/register-result/register-result.component.html +++ /dev/null @@ -1,20 +0,0 @@ - - -
- 你的账户:{{ email }} 注册成功 -
-
- - -
diff --git a/src/app/components/passport/register-result/register-result.component.ts b/src/app/components/passport/register-result/register-result.component.ts deleted file mode 100644 index 742c038..0000000 --- a/src/app/components/passport/register-result/register-result.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from '@angular/core'; -import { NzMessageService } from 'ng-zorro-antd'; -import { ActivatedRoute } from '@angular/router'; - -@Component({ - selector: 'passport-register-result', - templateUrl: './register-result.component.html' -}) -export class UserRegisterResultComponent { - params = { email: '' }; - email = ''; - constructor(route: ActivatedRoute, public msg: NzMessageService) { - this.params.email = this.email = - route.snapshot.queryParams.email || 'ng-alain@example.com'; - } -} diff --git a/src/app/components/passport/register/register.component.html b/src/app/components/passport/register/register.component.html deleted file mode 100644 index d43af4e..0000000 --- a/src/app/components/passport/register/register.component.html +++ /dev/null @@ -1,163 +0,0 @@ -

注册

-
- - - - - - - - 请输入邮箱地址! - 邮箱地址格式错误! - - - - - - - - - - 请输入密码! - -
- -
强度:强
-
强度:中
-
强度:太短
-
-
- -
-

- 请至少输入 6 个字符。请不要使用容易被猜到的密码。 -

-
-
-
-
-
- - - - - - - 请确认密码! - 两次输入的密码不匹配! - - - - - - - - - - - - - - - - 请输入手机号! - 手机号格式错误! - - - - - - - - - - - 请输入验证码! - - - - - - - - - - -
diff --git a/src/app/components/passport/register/register.component.less b/src/app/components/passport/register/register.component.less deleted file mode 100644 index a9ed25f..0000000 --- a/src/app/components/passport/register/register.component.less +++ /dev/null @@ -1,42 +0,0 @@ -@import '~@delon/theme/styles/default'; -:host { - display: block; - width: 368px; - margin: 0 auto; - ::ng-deep { - h3 { - font-size: 16px; - margin-bottom: 20px; - } - .submit { - width: 50%; - } - .login { - float: right; - line-height: @btn-height-lg; - } - } -} -::ng-deep { - .register-password-cdk { - .success, - .warning, - .error { - transition: color 0.3s; - } - .success { - color: @success-color; - } - .warning { - color: @warning-color; - } - .error { - color: @error-color; - } - .progress-pass > .progress { - .ant-progress-bg { - background-color: @warning-color; - } - } - } -} diff --git a/src/app/components/passport/register/register.component.ts b/src/app/components/passport/register/register.component.ts deleted file mode 100644 index d1f35d4..0000000 --- a/src/app/components/passport/register/register.component.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { Component, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; -import { - FormGroup, - FormBuilder, - Validators, - FormControl -} from '@angular/forms'; -import { NzMessageService } from 'ng-zorro-antd'; -import { _HttpClient } from '@delon/theme'; - -@Component({ - selector: 'passport-register', - templateUrl: './register.component.html', - styleUrls: ['./register.component.less'] -}) -export class UserRegisterComponent implements OnDestroy { - constructor( - fb: FormBuilder, - private router: Router, - public http: _HttpClient, - public msg: NzMessageService - ) { - this.form = fb.group({ - mail: [null, [Validators.required, Validators.email]], - password: [ - null, - [ - Validators.required, - Validators.minLength(6), - UserRegisterComponent.checkPassword.bind(this) - ] - ], - confirm: [ - null, - [ - Validators.required, - Validators.minLength(6), - UserRegisterComponent.passwordEquar - ] - ], - mobilePrefix: ['+86'], - mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], - captcha: [null, [Validators.required]] - }); - } - - // #region fields - - get mail() { - return this.form.controls.mail; - } - get password() { - return this.form.controls.password; - } - get confirm() { - return this.form.controls.confirm; - } - get mobile() { - return this.form.controls.mobile; - } - get captcha() { - return this.form.controls.captcha; - } - form: FormGroup; - error = ''; - type = 0; - visible = false; - status = 'pool'; - progress = 0; - passwordProgressMap = { - ok: 'success', - pass: 'normal', - pool: 'exception' - }; - - // #endregion - - // #region get captcha - - count = 0; - interval$: any; - - static checkPassword(control: FormControl): any { - if (!control) { - return null; - } - const self: any = this; - self.visible = !!control.value; - if (control.value && control.value.length > 9) { - self.status = 'ok'; - } else if (control.value && control.value.length > 5) { - self.status = 'pass'; - } else { - self.status = 'pool'; - } - - if (self.visible) { - self.progress = - control.value.length * 10 > 100 ? 100 : control.value.length * 10; - } - } - - static passwordEquar(control: FormControl) { - if (!control || !control.parent) { - return null; - } - if (control.value !== control.parent.get('password').value) { - return { equar: true }; - } - return null; - } - - getCaptcha() { - if (this.mobile.invalid) { - this.mobile.markAsDirty({ onlySelf: true }); - this.mobile.updateValueAndValidity({ onlySelf: true }); - return; - } - this.count = 59; - this.interval$ = setInterval(() => { - this.count -= 1; - if (this.count <= 0) { - clearInterval(this.interval$); - } - }, 1000); - } - - // #endregion - - submit() { - this.error = ''; - for (const i in this.form.controls) { - if (this.form.controls.hasOwnProperty(i)) { - this.form.controls[i].markAsDirty(); - this.form.controls[i].updateValueAndValidity(); - } - } - if (this.form.invalid) { - return; - } - - const data = this.form.value; - this.http.post('/register', data).subscribe(() => { - this.router.navigateByUrl('/passport/register-result', { - queryParams: { email: data.mail } - }); - }); - } - - ngOnDestroy(): void { - if (this.interval$) { - clearInterval(this.interval$); - } - } -} diff --git a/src/app/core/README.md b/src/app/core/README.md deleted file mode 100644 index 2d98e12..0000000 --- a/src/app/core/README.md +++ /dev/null @@ -1,5 +0,0 @@ -### CoreModule - -**应** 仅只留 `providers` 属性。 - -**作用:** 一些通用服务,例如:用户消息、HTTP数据访问。 diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts deleted file mode 100644 index 856faaa..0000000 --- a/src/app/core/core.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { NgModule, Optional, SkipSelf } from '@angular/core'; -import { throwIfAlreadyLoaded } from './module-import-guard'; - - -@NgModule({ - providers: [ - ] -}) -export class CoreModule { - constructor( @Optional() @SkipSelf() parentModule: CoreModule) { - throwIfAlreadyLoaded(parentModule, 'CoreModule'); - } -} diff --git a/src/app/core/module-import-guard.ts b/src/app/core/module-import-guard.ts deleted file mode 100644 index 927601d..0000000 --- a/src/app/core/module-import-guard.ts +++ /dev/null @@ -1,6 +0,0 @@ -// https://angular.io/guide/styleguide#style-04-12 -export function throwIfAlreadyLoaded(parentModule: any, moduleName: string) { - if (parentModule) { - throw new Error(`${moduleName} has already been loaded. Import Core modules in the AppModule only.`); - } -} diff --git a/src/app/core/net/default.interceptor.ts b/src/app/core/net/default.interceptor.ts deleted file mode 100644 index f27991d..0000000 --- a/src/app/core/net/default.interceptor.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Injectable, Injector } from '@angular/core'; -import { Router } from '@angular/router'; -import { - HttpInterceptor, - HttpRequest, - HttpHandler, - HttpErrorResponse, - HttpSentEvent, - HttpHeaderResponse, - HttpProgressEvent, - HttpResponse, - HttpUserEvent, -} from '@angular/common/http'; -import { Observable, of, throwError } from 'rxjs'; -import { mergeMap, catchError } from 'rxjs/operators'; -import { NzMessageService } from 'ng-zorro-antd'; -import { _HttpClient } from '@delon/theme'; -import { environment } from '@env/environment'; - -/** - * 默认HTTP拦截器,其注册细节见 `app.module.ts` - */ -@Injectable() -export class DefaultInterceptor implements HttpInterceptor { - constructor(private injector: Injector) {} - - get msg(): NzMessageService { - return this.injector.get(NzMessageService); - } - - private goTo(url: string) { - setTimeout(() => this.injector.get(Router).navigateByUrl(url)); - } - - private handleData( - event: HttpResponse | HttpErrorResponse, - ): Observable { - // 可能会因为 `throw` 导出无法执行 `_HttpClient` 的 `end()` 操作 - this.injector.get(_HttpClient).end(); - // 业务处理:一些通用操作 - switch (event.status) { - case 200: - // 业务层级错误处理,以下是假定restful有一套统一输出格式(指不管成功与否都有相应的数据格式)情况下进行处理 - // 例如响应内容: - // 错误内容:{ status: 1, msg: '非法参数' } - // 正确内容:{ status: 0, response: { } } - // 则以下代码片断可直接适用 - // if (event instanceof HttpResponse) { - // const body: any = event.body; - // if (body && body.status !== 0) { - // this.msg.error(body.msg); - // // 继续抛出错误中断后续所有 Pipe、subscribe 操作,因此: - // // this.http.get('/').subscribe() 并不会触发 - // return throwError({}); - // } else { - // // 重新修改 `body` 内容为 `response` 内容,对于绝大多数场景已经无须再关心业务状态码 - // return of(new HttpResponse(Object.assign(event, { body: body.response }))); - // // 或者依然保持完整的格式 - // return of(event); - // } - // } - break; - case 401: // 未登录状态码 - this.goTo('/passport/login'); - break; - case 403: - case 404: - case 500: - this.goTo(`/${event.status}`); - break; - default: - if (event instanceof HttpErrorResponse) { - console.warn( - '未可知错误,大部分是由于后端不支持CORS或无效配置引起', - event, - ); - this.msg.error(event.message); - } - break; - } - return of(event); - } - - intercept( - req: HttpRequest, - next: HttpHandler, - ): Observable< - | HttpSentEvent - | HttpHeaderResponse - | HttpProgressEvent - | HttpResponse - | HttpUserEvent - > { - // 统一加上服务端前缀 - let url = req.url; - if (!url.startsWith('https://') && !url.startsWith('http://')) { - url = environment.SERVER_URL + url; - } - - const newReq = req.clone({ - url: url, - }); - return next.handle(newReq).pipe( - mergeMap((event: any) => { - // 允许统一对请求错误处理,这是因为一个请求若是业务上错误的情况下其HTTP请求的状态是200的情况下需要 - if (event instanceof HttpResponse && event.status === 200) { - return this.handleData(event); - } - // 若一切都正常,则后续操作 - return of(event); - }), - catchError((err: HttpErrorResponse) => this.handleData(err)), - ); - } -} diff --git a/src/app/core/startup/startup.service.ts b/src/app/core/startup/startup.service.ts deleted file mode 100644 index cdf12c2..0000000 --- a/src/app/core/startup/startup.service.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Injectable, Injector, Inject } from '@angular/core'; -import { Router } from '@angular/router'; -import { HttpClient } from '@angular/common/http'; -import { zip } from 'rxjs'; -import { catchError } from 'rxjs/operators'; -import { MenuService, SettingsService, TitleService, ALAIN_I18N_TOKEN } from '@delon/theme'; -import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; -import { ACLService } from '@delon/acl'; - -import { NzIconService } from 'ng-zorro-antd'; -import { ICONS_AUTO } from '../../../style-icons-auto'; -import { ICONS } from '../../../style-icons'; - -/** - * 用于应用启动时 - * 一般用来获取应用所需要的基础数据等 - */ -@Injectable() -export class StartupService { - constructor( - iconSrv: NzIconService, - private menuService: MenuService, - private settingService: SettingsService, - private aclService: ACLService, - private titleService: TitleService, - @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, - private httpClient: HttpClient, - private injector: Injector - ) { - iconSrv.addIcon(...ICONS_AUTO, ...ICONS); - } - - private viaHttp(resolve: any, reject: any) { - zip( - this.httpClient.get('assets/tmp/app-data.json') - ).pipe( - // 接收其他拦截器后产生的异常消息 - catchError(([appData]) => { - resolve(null); - return [appData]; - }) - ).subscribe(([appData]) => { - - // application data - const res: any = appData; - // 应用信息:包括站点名、描述、年份 - this.settingService.setApp(res.app); - // 用户信息:包括姓名、头像、邮箱地址 - this.settingService.setUser(res.user); - // ACL:设置权限为全量 - this.aclService.setFull(true); - // 初始化菜单 - this.menuService.add(res.menu); - // 设置页面标题的后缀 - this.titleService.suffix = res.app.name; - }, - () => { }, - () => { - resolve(null); - }); - } - - private viaMock(resolve: any, reject: any) { - // const tokenData = this.tokenService.get(); - // if (!tokenData.token) { - // this.injector.get(Router).navigateByUrl('/passport/login'); - // resolve({}); - // return; - // } - // mock - const app: any = { - name: `ng-alain`, - description: `Ng-zorro admin panel front-end framework` - }; - const user: any = { - name: 'Admin', - avatar: './assets/tmp/img/avatar.jpg', - email: 'cipchk@qq.com', - token: '123456789' - }; - // 应用信息:包括站点名、描述、年份 - this.settingService.setApp(app); - // 用户信息:包括姓名、头像、邮箱地址 - this.settingService.setUser(user); - // ACL:设置权限为全量 - this.aclService.setFull(true); - // 初始化菜单 - this.menuService.add([ - { - text: '主导航', - group: true, - children: [ - { - text: '仪表盘', - link: '/dashboard', - icon: { type: 'icon', value: 'appstore' } - }, - { - text: '快捷菜单', - icon: { type: 'icon', value: 'rocket' }, - shortcutRoot: true - } - ] - } - ]); - // 设置页面标题的后缀 - this.titleService.suffix = app.name; - - resolve({}); - } - - load(): Promise { - // only works with promises - // https://github.com/angular/angular/issues/15088 - return new Promise((resolve, reject) => { - // http - // this.viaHttp(resolve, reject); - // mock:请勿在生产环境中这么使用,viaMock 单纯只是为了模拟一些数据使脚手架一开始能正常运行 - this.viaMock(resolve, reject); - - }); - } -} diff --git a/src/app/delon.module.ts b/src/app/delon.module.ts deleted file mode 100644 index 7e03aa9..0000000 --- a/src/app/delon.module.ts +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 进一步对基础模块的导入提炼 - * 有关模块注册指导原则请参考:https://github.com/ng-alain/ng-alain/issues/180 - */ -import { - NgModule, - Optional, - SkipSelf, - ModuleWithProviders -} from '@angular/core'; -import { throwIfAlreadyLoaded } from '@core/module-import-guard'; - -import { AlainThemeModule } from '@delon/theme'; -import { DelonABCModule, STConfig } from '@delon/abc'; -import { DelonChartModule } from '@delon/chart'; -import { DelonAuthModule } from '@delon/auth'; -import { DelonACLModule } from '@delon/acl'; -import { DelonCacheModule } from '@delon/cache'; -import { DelonUtilModule } from '@delon/util'; - -// #region mock -import { DelonMockModule } from '@delon/mock'; -import { environment } from '@env/environment'; -const MOCK_MODULES: any[] = !environment.production ? [] : []; -// #endregion - -// #region reuse-tab -/** - * 若需要[路由复用](https://ng-alain.com/components/reuse-tab)需要: - * 1、增加 `REUSETAB_PROVIDES` - * 2、在 `src/app/layout/default/default.component.html` 修改: - * ```html - *
- * - * - *
- * ``` - */ -import { RouteReuseStrategy } from '@angular/router'; -import { ReuseTabService, ReuseTabStrategy } from '@delon/abc/reuse-tab'; -const REUSETAB_PROVIDES: any[] = [ - // { - // provide: RouteReuseStrategy, - // useClass: ReuseTabStrategy, - // deps: [ReuseTabService], - // }, -]; -// #endregion - -// #region global config functions - -import { PageHeaderConfig } from '@delon/abc'; -export function fnPageHeaderConfig(): PageHeaderConfig { - return Object.assign(new PageHeaderConfig(), { homeI18n: 'home' }); -} - -import { DelonAuthConfig } from '@delon/auth'; -export function fnDelonAuthConfig(): DelonAuthConfig { - return Object.assign(new DelonAuthConfig(), { - login_url: '/passport/login' - }); -} - -export function fnSTConfig(): STConfig { - return Object.assign(new STConfig(), { - modal: { size: 'lg' } - }); -} - -const GLOBAL_CONFIG_PROVIDES = [ - // TIPS:@delon/abc 有大量的全局配置信息,例如设置所有 `st` 的页码默认为 `20` 行 - { provide: STConfig, useFactory: fnSTConfig }, - { provide: PageHeaderConfig, useFactory: fnPageHeaderConfig }, - { provide: DelonAuthConfig, useFactory: fnDelonAuthConfig } -]; - -// #endregion - -@NgModule({ - imports: [ - AlainThemeModule.forRoot(), - DelonABCModule, - DelonChartModule, - DelonAuthModule, - DelonACLModule, - DelonCacheModule, - DelonUtilModule, - // mock - ...MOCK_MODULES - ] -}) -export class DelonModule { - constructor( - @Optional() - @SkipSelf() - parentModule: DelonModule - ) { - throwIfAlreadyLoaded(parentModule, 'DelonModule'); - } - - static forRoot(): ModuleWithProviders { - return { - ngModule: DelonModule, - providers: [...REUSETAB_PROVIDES, ...GLOBAL_CONFIG_PROVIDES] - }; - } -} diff --git a/src/app/guards/auth-guard.service.ts b/src/app/guards/auth-guard.service.ts deleted file mode 100644 index 631d390..0000000 --- a/src/app/guards/auth-guard.service.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - CanActivate, - CanActivateChild, - ActivatedRouteSnapshot, - RouterStateSnapshot, - Router -} from '@angular/router'; -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { AuthService } from '../services/auth.service'; - -@Injectable() -export class AuthGuardService implements CanActivate, CanActivateChild { - constructor( - private readonly authService: AuthService, - private readonly router: Router - ) { } - - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable | Promise { - if (!this.authService.isAuthenticated()) { - this.router.navigate(['recipes']); - return false; - } - - return true; - } - - canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable | Promise { - return this.canActivate(route, state); - } -} diff --git a/src/app/guards/can-deactivate-guard.service.ts b/src/app/guards/can-deactivate-guard.service.ts deleted file mode 100644 index bff63e9..0000000 --- a/src/app/guards/can-deactivate-guard.service.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - CanDeactivate, - ActivatedRouteSnapshot, - RouterStateSnapshot -} from '@angular/router'; -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; - -export interface CanComponentDeactivate { - canDeactivate: () => Observable | Promise | boolean; -} - -@Injectable() -export class CanDeactivateGuardService implements CanDeactivate { - - constructor() { } - - canDeactivate( - component: CanComponentDeactivate, - route: ActivatedRouteSnapshot, - state: RouterStateSnapshot, - nextState?: RouterStateSnapshot): Observable | Promise | boolean { - return component.canDeactivate(); - } -} diff --git a/src/app/guards/guards.module.ts b/src/app/guards/guards.module.ts deleted file mode 100644 index 422b76b..0000000 --- a/src/app/guards/guards.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CanDeactivateGuardService } from './can-deactivate-guard.service'; -import { AuthGuardService } from './auth-guard.service'; - -@NgModule({ - providers: [AuthGuardService, CanDeactivateGuardService] -}) -export class GuardsModule {} diff --git a/src/app/interceptors/interceptors.module.ts b/src/app/interceptors/interceptors.module.ts deleted file mode 100644 index b63c8fd..0000000 --- a/src/app/interceptors/interceptors.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { HTTP_INTERCEPTORS } from '@angular/common/http'; -import { TokenInterceptor } from './token.interceptor'; - -@NgModule({ - providers: [ - { - provide: HTTP_INTERCEPTORS, - useClass: TokenInterceptor, - multi: true - } - ], - exports: [] -}) -export class InterceptorsModule {} diff --git a/src/app/interceptors/token.interceptor.ts b/src/app/interceptors/token.interceptor.ts deleted file mode 100644 index 16982aa..0000000 --- a/src/app/interceptors/token.interceptor.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Injectable, Injector } from '@angular/core'; -import { HttpInterceptor, HttpRequest, HttpHandler, HttpHeaders } from '@angular/common/http'; -import { AuthService } from '../services/auth.service'; - -@Injectable() -export class TokenInterceptor implements HttpInterceptor { - authService: AuthService; - - constructor( - private readonly injector: Injector - ) {} - - intercept(request: HttpRequest, next: HttpHandler) { - this.authService = this.injector.get(AuthService); - - const bearer = `Bearer ${this.authService.getToken()}`; - - request = request.clone({ - headers: new HttpHeaders().set('Authorization', bearer) - }); - - return next.handle(request); - } -} diff --git a/src/app/layout/default/default.component.html b/src/app/layout/default/default.component.html deleted file mode 100644 index 0cacfeb..0000000 --- a/src/app/layout/default/default.component.html +++ /dev/null @@ -1,8 +0,0 @@ - -
- - -
- -
- \ No newline at end of file diff --git a/src/app/layout/default/default.component.spec.ts b/src/app/layout/default/default.component.spec.ts deleted file mode 100644 index 429a4e3..0000000 --- a/src/app/layout/default/default.component.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TestBed, TestModuleMetadata } from '@angular/core/testing'; - -import { setUpTestBed } from '@testing/common.spec'; - -import { LayoutDefaultComponent } from './default.component'; - -describe('Layout', () => { - setUpTestBed({ - declarations: [LayoutDefaultComponent], - }); - - it('should create an instance', () => { - const fixture = TestBed.createComponent(LayoutDefaultComponent); - const comp = fixture.debugElement.componentInstance; - expect(comp).toBeTruthy(); - }); -}); diff --git a/src/app/layout/default/default.component.ts b/src/app/layout/default/default.component.ts deleted file mode 100644 index 97b1e5d..0000000 --- a/src/app/layout/default/default.component.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { - Component, - ViewChild, - HostBinding, - ComponentFactoryResolver, - ViewContainerRef, - AfterViewInit, - OnInit, - OnDestroy, - ElementRef, - Renderer2, - Inject -} from '@angular/core'; -import { DOCUMENT } from '@angular/common'; -import { - Router, - NavigationEnd, - RouteConfigLoadStart, - NavigationError, - NavigationCancel -} from '@angular/router'; -import { NzMessageService, NzIconService } from 'ng-zorro-antd'; -import { Subscription } from 'rxjs'; -import { updateHostClass } from '@delon/util'; -import { ScrollService, MenuService, SettingsService } from '@delon/theme'; - -// #region icons - -import { - MenuFoldOutline, - MenuUnfoldOutline, - SearchOutline, - SettingOutline, - FullscreenOutline, - FullscreenExitOutline, - BellOutline, - LockOutline, - PlusOutline, - UserOutline, - LogoutOutline, - EllipsisOutline, - GlobalOutline, - ArrowDownOutline, - // Optional - GithubOutline, - AppstoreOutline -} from '@ant-design/icons-angular/icons'; - -const ICONS = [ - MenuFoldOutline, - MenuUnfoldOutline, - SearchOutline, - SettingOutline, - FullscreenOutline, - FullscreenExitOutline, - BellOutline, - LockOutline, - PlusOutline, - UserOutline, - LogoutOutline, - EllipsisOutline, - GlobalOutline, - ArrowDownOutline, - // Optional - GithubOutline, - AppstoreOutline -]; - -// #endregion - -import { environment } from '@env/environment'; -import { SettingDrawerComponent } from './setting-drawer/setting-drawer.component'; - -@Component({ - selector: 'layout-default', - templateUrl: './default.component.html', - preserveWhitespaces: false -}) -export class LayoutDefaultComponent - implements OnInit, AfterViewInit, OnDestroy { - private notify$: Subscription; - isFetching = false; - @ViewChild('settingHost', { read: ViewContainerRef }) - settingHost: ViewContainerRef; - @HostBinding('class') - defaultClass = 'alain-default'; - - constructor( - iconSrv: NzIconService, - router: Router, - scroll: ScrollService, - _message: NzMessageService, - private resolver: ComponentFactoryResolver, - public menuSrv: MenuService, - public settings: SettingsService, - private el: ElementRef, - private renderer: Renderer2, - @Inject(DOCUMENT) private doc: any - ) { - iconSrv.addIcon(...ICONS); - // scroll to top in change page - router.events.subscribe(evt => { - if (!this.isFetching && evt instanceof RouteConfigLoadStart) { - this.isFetching = true; - } - if (evt instanceof NavigationError || evt instanceof NavigationCancel) { - this.isFetching = false; - if (evt instanceof NavigationError) { - _message.error(`无法加载${evt.url}路由`, { nzDuration: 1000 * 3 }); - } - return; - } - if (!(evt instanceof NavigationEnd)) { - return; - } - setTimeout(() => { - scroll.scrollToTop(); - this.isFetching = false; - }, 100); - }); - } - - private setClass() { - const { el, renderer, settings } = this; - const layout = settings.layout; - updateHostClass( - el.nativeElement, - renderer, - { - ['alain-default']: true, - [`alain-default__fixed`]: layout.fixed, - [`alain-default__boxed`]: layout.boxed, - [`alain-default__collapsed`]: layout.collapsed - }, - true - ); - - this.doc.body.classList[layout.colorWeak ? 'add' : 'remove']('color-weak'); - } - - ngAfterViewInit(): void { - // Setting componet for only developer - if (!environment.production) { - setTimeout(() => { - const settingFactory = this.resolver.resolveComponentFactory( - SettingDrawerComponent - ); - this.settingHost.createComponent(settingFactory); - }, 22); - } - } - - ngOnInit() { - this.notify$ = this.settings.notify.subscribe(() => this.setClass()); - this.setClass(); - } - - ngOnDestroy() { - this.notify$.unsubscribe(); - } -} diff --git a/src/app/layout/default/header/components/fullscreen.component.ts b/src/app/layout/default/header/components/fullscreen.component.ts deleted file mode 100644 index efe3df0..0000000 --- a/src/app/layout/default/header/components/fullscreen.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Component, HostListener, HostBinding } from '@angular/core'; -// import * as screenfull from 'screenfull'; -const screenfull = require('screenfull'); - -@Component({ - selector: 'header-fullscreen', - template: ` - - {{ status ? '退出全屏' : '全屏' }} - `, -}) -export class HeaderFullScreenComponent { - status = false; - - @HostBinding('class') - defaultClass = 'd-block'; - - @HostListener('window:resize') - _resize() { - this.status = screenfull.isFullscreen; - } - - @HostListener('click') - _click() { - if (screenfull.enabled) { - screenfull.toggle(); - } - } -} diff --git a/src/app/layout/default/header/components/icon.component.ts b/src/app/layout/default/header/components/icon.component.ts deleted file mode 100644 index 236101d..0000000 --- a/src/app/layout/default/header/components/icon.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'header-icon', - template: ` - -
- -
-
- -
-
- - Calendar -
-
- - Files -
-
- - Cloud -
-
- - Star -
-
- - Team -
-
- - QR -
-
- - Pay -
-
- - Print -
-
-
-
-
- `, -}) -export class HeaderIconComponent { - loading = true; - - change() { - setTimeout(() => (this.loading = false), 500); - } -} diff --git a/src/app/layout/default/header/components/notify.component.ts b/src/app/layout/default/header/components/notify.component.ts deleted file mode 100644 index ebdda74..0000000 --- a/src/app/layout/default/header/components/notify.component.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { Component } from '@angular/core'; -import * as distanceInWordsToNow from 'date-fns/distance_in_words_to_now'; -import { NzMessageService } from 'ng-zorro-antd'; -import { NoticeItem, NoticeIconList } from '@delon/abc'; - -/** - * 菜单通知 - */ -@Component({ - selector: 'header-notify', - template: ` - - `, -}) -export class HeaderNotifyComponent { - data: NoticeItem[] = [ - { - title: '通知', - list: [], - emptyText: '你已查看所有通知', - emptyImage: - 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg', - clearText: '清空通知', - }, - { - title: '消息', - list: [], - emptyText: '您已读完所有消息', - emptyImage: - 'https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg', - clearText: '清空消息', - }, - { - title: '待办', - list: [], - emptyText: '你已完成所有待办', - emptyImage: - 'https://gw.alipayobjects.com/zos/rmsportal/HsIsxMZiWKrNUavQUXqx.svg', - clearText: '清空待办', - }, - ]; - count = 5; - loading = false; - - constructor(private msg: NzMessageService) {} - - updateNoticeData(notices: NoticeIconList[]): NoticeItem[] { - const data = this.data.slice(); - data.forEach(i => (i.list = [])); - - notices.forEach(item => { - const newItem = { ...item }; - if (newItem.datetime) { - newItem.datetime = distanceInWordsToNow(item.datetime, { - locale: (window as any).__locale__, - }); - } - if (newItem.extra && newItem.status) { - const colorGroup: {[key: string]: any} = { - todo: undefined, - processing: 'blue', - urgent: 'red', - doing: 'gold', - }; - newItem.color = colorGroup[newItem.status]; - } - data.find(w => w.title === newItem.type).list.push(newItem); - }); - return data; - } - - loadData() { - if (this.loading) { return; } - this.loading = true; - setTimeout(() => { - this.data = this.updateNoticeData([ - { - id: '000000001', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '你收到了 14 份新周报', - datetime: '2017-08-09', - type: '通知', - }, - { - id: '000000002', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', - title: '你推荐的 曲妮妮 已通过第三轮面试', - datetime: '2017-08-08', - type: '通知', - }, - { - id: '000000003', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', - title: '这种模板可以区分多种通知类型', - datetime: '2017-08-07', - read: true, - type: '通知', - }, - { - id: '000000004', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', - title: '左侧图标用于区分不同的类型', - datetime: '2017-08-07', - type: '通知', - }, - { - id: '000000005', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '内容不要超过两行字,超出时自动截断', - datetime: '2017-08-07', - type: '通知', - }, - { - id: '000000006', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '曲丽丽 评论了你', - description: '描述信息描述信息描述信息', - datetime: '2017-08-07', - type: '消息', - }, - { - id: '000000007', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '朱偏右 回复了你', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: '消息', - }, - { - id: '000000008', - avatar: - 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '标题', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: '消息', - }, - { - id: '000000009', - title: '任务名称', - description: '任务需要在 2017-01-12 20:00 前启动', - extra: '未开始', - status: 'todo', - type: '待办', - }, - { - id: '000000010', - title: '第三方紧急代码变更', - description: - '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '马上到期', - status: 'urgent', - type: '待办', - }, - { - id: '000000011', - title: '信息安全考试', - description: '指派竹尔于 2017-01-09 前完成更新并发布', - extra: '已耗时 8 天', - status: 'doing', - type: '待办', - }, - { - id: '000000012', - title: 'ABCD 版本发布', - description: - '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '进行中', - status: 'processing', - type: '待办', - }, - ]); - - this.loading = false; - }, 1000); - } - - clear(type: string) { - this.msg.success(`清空了 ${type}`); - } - - select(res: any) { - this.msg.success(`点击了 ${res.title} 的 ${res.item.title}`); - } -} diff --git a/src/app/layout/default/header/components/search.component.ts b/src/app/layout/default/header/components/search.component.ts deleted file mode 100644 index d606c8c..0000000 --- a/src/app/layout/default/header/components/search.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - Component, - HostBinding, - Input, - ElementRef, - AfterViewInit, -} from '@angular/core'; - -@Component({ - selector: 'header-search', - template: ` - - - - `, -}) -export class HeaderSearchComponent implements AfterViewInit { - q: string; - - qIpt: HTMLInputElement; - - @HostBinding('class.alain-default__search-focus') - focus = false; - - @HostBinding('class.alain-default__search-toggled') - searchToggled = false; - - @Input() - set toggleChange(value: boolean) { - if (typeof value === 'undefined') { return; } - this.searchToggled = true; - this.focus = true; - setTimeout(() => this.qIpt.focus(), 300); - } - - constructor(private el: ElementRef) {} - - ngAfterViewInit() { - this.qIpt = (this.el.nativeElement as HTMLElement).querySelector( - '.ant-input', - ) as HTMLInputElement; - } - - qFocus() { - this.focus = true; - } - - qBlur() { - this.focus = false; - this.searchToggled = false; - } -} diff --git a/src/app/layout/default/header/components/storage.component.ts b/src/app/layout/default/header/components/storage.component.ts deleted file mode 100644 index 2b608a4..0000000 --- a/src/app/layout/default/header/components/storage.component.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Component, HostListener, HostBinding } from '@angular/core'; -import { NzModalService, NzMessageService } from 'ng-zorro-antd'; - -@Component({ - selector: 'header-storage', - template: ` - - 清理本地缓存 - ` -}) -export class HeaderStorageComponent { - constructor( - private confirmServ: NzModalService, - private messageServ: NzMessageService, - ) {} - - @HostBinding('class') - defaultClass = 'd-block'; - - @HostListener('click') - _click() { - this.confirmServ.confirm({ - nzTitle: 'Make sure clear all local storage?', - nzOnOk: () => { - localStorage.clear(); - this.messageServ.success('Clear Finished!'); - }, - }); - } -} diff --git a/src/app/layout/default/header/components/task.component.ts b/src/app/layout/default/header/components/task.component.ts deleted file mode 100644 index 97131b5..0000000 --- a/src/app/layout/default/header/components/task.component.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'header-task', - template: ` - -
- - - -
-
- - -
-
- -
-
- cipchk -

Please tell me what happened in a few words, don't go into details.

-
-
-
-
- -
-
- はなさき -

ハルカソラトキヘダツヒカリ

-
-
-
-
- -
-
- 苏先生 -

请告诉我,我应该说点什么好?

-
-
-
-
- -
-
- Kent -

Please tell me what happened in a few words, don't go into details.

-
-
-
-
- -
-
- Jefferson -

Please tell me what happened in a few words, don't go into details.

-
-
-
-
- See All -
-
-
-
-
- `, -}) -export class HeaderTaskComponent { - loading = true; - - change() { - setTimeout(() => (this.loading = false), 500); - } -} diff --git a/src/app/layout/default/header/components/user.component.ts b/src/app/layout/default/header/components/user.component.ts deleted file mode 100644 index bbef00d..0000000 --- a/src/app/layout/default/header/components/user.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, Inject } from '@angular/core'; -import { Router } from '@angular/router'; -import { SettingsService } from '@delon/theme'; -import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; - -@Component({ - selector: 'header-user', - template: ` - -
- - {{settings.user.name}} -
-
-
- 个人中心 -
-
- 个人设置 -
-
  • -
    - 退出登录 -
    -
    -
    - `, -}) -export class HeaderUserComponent { - constructor( - public settings: SettingsService, - private router: Router, - @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, - ) {} - - logout() { - this.tokenService.clear(); - this.router.navigateByUrl(this.tokenService.login_url); - } -} diff --git a/src/app/layout/default/header/header.component.html b/src/app/layout/default/header/header.component.html deleted file mode 100644 index ed78fae..0000000 --- a/src/app/layout/default/header/header.component.html +++ /dev/null @@ -1,52 +0,0 @@ - - -
    -
      - -
    • -
      -
    • - -
    • - -
    • -
      -
    • - -
    • -
      -
    • -
    - -
      - -
    • - -
    • - -
    • - -
    • - -
    • - -
    • - -
    • - -
      -
      -
      - -
      -
      - -
      -
      -
      -
    • -
    • - -
    • -
    -
    \ No newline at end of file diff --git a/src/app/layout/default/header/header.component.spec.ts b/src/app/layout/default/header/header.component.spec.ts deleted file mode 100644 index 25a611e..0000000 --- a/src/app/layout/default/header/header.component.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed, TestModuleMetadata } from '@angular/core/testing'; -import { setUpTestBed } from '@testing/common.spec'; - -import { HeaderComponent } from './header.component'; - -describe('Layout: Header', () => { - setUpTestBed({ - declarations: [HeaderComponent], - }); - - it('should create an instance', () => { - const fixture = TestBed.createComponent(HeaderComponent); - const comp = fixture.debugElement.componentInstance; - expect(comp).toBeTruthy(); - }); -}); diff --git a/src/app/layout/default/header/header.component.ts b/src/app/layout/default/header/header.component.ts deleted file mode 100644 index 6ae591a..0000000 --- a/src/app/layout/default/header/header.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Component, ViewChild } from '@angular/core'; -import { SettingsService } from '@delon/theme'; - -@Component({ - selector: 'layout-header', - templateUrl: './header.component.html' -}) -export class HeaderComponent { - searchToggleStatus: boolean; - - constructor(public settings: SettingsService) {} - - toggleCollapsedSidebar() { - this.settings.setLayout('collapsed', !this.settings.layout.collapsed); - } - - searchToggleChange() { - this.searchToggleStatus = !this.searchToggleStatus; - } -} diff --git a/src/app/layout/default/header/index.md b/src/app/layout/default/header/index.md deleted file mode 100644 index aead1c5..0000000 --- a/src/app/layout/default/header/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -component: app-header -title: 顶部菜单 ---- - -顶部菜单组件允许通过 `components` 目录下的组件进行按需组装。 - -## 组件列表 - -组件名 | 说明 -----|------ -`header-fullscreen` | 全屏切换 -`header-icon` | 应用图标 -`header-langs` | 语言切换 -`header-notify` | 菜单通知 -`header-search` | 搜索框 -`header-storage` | 清除 LocalStorage 缓存 -`header-task` | 任务通知 -`header-theme` | 主题切换 -`header-user` | 用户菜单 diff --git a/src/app/layout/default/setting-drawer/setting-drawer-item.component.html b/src/app/layout/default/setting-drawer/setting-drawer-item.component.html deleted file mode 100644 index 8eca288..0000000 --- a/src/app/layout/default/setting-drawer/setting-drawer-item.component.html +++ /dev/null @@ -1,40 +0,0 @@ -{{ i.label }}{{ i.tip }} -
    - - - - - - - - - - - - - -
    diff --git a/src/app/layout/default/setting-drawer/setting-drawer-item.component.ts b/src/app/layout/default/setting-drawer/setting-drawer-item.component.ts deleted file mode 100644 index be5cd73..0000000 --- a/src/app/layout/default/setting-drawer/setting-drawer-item.component.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Component, Input, HostBinding } from '@angular/core'; - -@Component({ - // tslint:disable-next-line:component-selector - selector: 'setting-drawer-item', - templateUrl: './setting-drawer-item.component.html', - preserveWhitespaces: false -}) -export class SettingDrawerItemComponent { - i: any = {}; - - @HostBinding('class') - defaultClass = 'setting-drawer__body-item'; - - @Input() - set data(val: any) { - this.i = val; - if (val.type === 'px') { - this.pxVal = +val.value.replace('px', ''); - } - } - - pxVal: number; - pxChange(val: number) { - this.i.value = `${val}px`; - } - format = (value: any) => `${value} px`; -} diff --git a/src/app/layout/default/setting-drawer/setting-drawer.component.html b/src/app/layout/default/setting-drawer/setting-drawer.component.html deleted file mode 100644 index 59e5538..0000000 --- a/src/app/layout/default/setting-drawer/setting-drawer.component.html +++ /dev/null @@ -1,56 +0,0 @@ - - -
    -
    -

    主题色

    -
    - -
    -

    设置

    - - -
    - - - -
    -
    - - - - - - - - - - - - - - - - - - - - -
    -
    - -
    -
    固定头和侧边栏 - -
    -
    色弱模式 - -
    -
    - - - - - -
    -
    -
    \ No newline at end of file diff --git a/src/app/layout/default/setting-drawer/setting-drawer.component.ts b/src/app/layout/default/setting-drawer/setting-drawer.component.ts deleted file mode 100644 index d3ca41c..0000000 --- a/src/app/layout/default/setting-drawer/setting-drawer.component.ts +++ /dev/null @@ -1,353 +0,0 @@ -import { - Component, - ChangeDetectionStrategy, - NgZone, - Inject, - ChangeDetectorRef, - HostBinding -} from '@angular/core'; -import { DOCUMENT } from '@angular/common'; -import { NzMessageService } from 'ng-zorro-antd'; -import { LazyService, copy, deepCopy } from '@delon/util'; -import { SettingsService } from '@delon/theme'; - -const ALAINDEFAULTVAR = 'alain-default-vars'; -const DEFAULT_COLORS = [ - { - key: 'dust', - color: '#F5222D' - }, - { - key: 'volcano', - color: '#FA541C' - }, - { - key: 'sunset', - color: '#FAAD14' - }, - { - key: 'cyan', - color: '#13C2C2' - }, - { - key: 'green', - color: '#52C41A' - }, - { - key: 'daybreak', - color: '#1890ff' - }, - { - key: 'geekblue', - color: '#2F54EB' - }, - { - key: 'purple', - color: '#722ED1' - } -]; -const DEFAULT_VARS: any = { - 'primary-color': { label: '主颜色', type: 'color', default: '#1890ff' }, - 'alain-default-header-hg': { - label: '高', - type: 'px', - default: '64px', - max: 300, - min: 24 - }, - 'alain-default-header-bg': { - label: '背景色', - type: 'color', - default: '@primary-color', - tip: '默认同主色系' - }, - 'alain-default-header-padding': { - label: '顶部左右内边距', - type: 'px', - default: '16px' - }, - // 侧边栏 - 'alain-default-aside-wd': { label: '宽度', type: 'px', default: '200px' }, - 'alain-default-aside-bg': { - label: '背景', - type: 'color', - default: '#ffffff' - }, - 'alain-default-aside-collapsed-wd': { - label: '收缩宽度', - type: 'px', - default: '64px' - }, - 'alain-default-aside-nav-padding-top-bottom': { - label: '项上下内边距', - type: 'px', - default: '8px', - step: 8 - }, - // 主菜单 - 'alain-default-aside-nav-fs': { - label: '菜单字号', - type: 'px', - default: '14px', - min: 14, - max: 30 - }, - 'alain-default-aside-collapsed-nav-fs': { - label: '收缩菜单字号', - type: 'px', - default: '24px', - min: 24, - max: 32 - }, - 'alain-default-aside-nav-item-height': { - label: '菜单项高度', - type: 'px', - default: '38px', - min: 24, - max: 64 - }, - 'alain-default-aside-nav-text-color': { - label: '菜单文本颜色', - type: 'color', - default: 'rgba(0, 0, 0, 0.65)', - rgba: true - }, - 'alain-default-aside-nav-text-hover-color': { - label: '菜单文本悬停颜色', - type: 'color', - default: '@primary-color', - tip: '默认同主色系' - }, - 'alain-default-aside-nav-group-text-color': { - label: '菜单分组文本颜色', - type: 'color', - default: 'rgba(0, 0, 0, 0.43)', - rgba: true - }, - 'alain-default-aside-nav-selected-text-color': { - label: '菜单激活时文本颜色', - type: 'color', - default: '@primary-color', - tip: '默认同主色系' - }, - 'alain-default-aside-nav-selected-bg': { - label: '菜单激活时背景颜色', - type: 'color', - default: '#fcfcfc' - }, - // 内容 - 'alain-default-content-bg': { - label: '背景色', - type: 'color', - default: '#f5f7fa' - }, - 'alain-default-content-heading-bg': { - label: '标题背景色', - type: 'color', - default: '#fafbfc' - }, - 'alain-default-content-heading-border': { - label: '标题底部边框色', - type: 'color', - default: '#efe3e5' - }, - 'alain-default-content-padding': { - label: '内边距', - type: 'px', - default: '24px', - min: 0, - max: 128, - step: 8 - }, - // zorro组件修正 - 'form-state-visual-feedback-enabled': { - label: '开启表单元素的视觉反馈', - type: 'switch', - default: true - }, - 'preserve-white-spaces-enabled': { - label: '开启 preserveWhitespaces', - type: 'switch', - default: true - }, - 'nz-table-img-radius': { - label: '表格中:图片圆角', - type: 'px', - default: '4px', - min: 0, - max: 128 - }, - 'nz-table-img-margin-right': { - label: '表格中:图片右外边距', - type: 'px', - default: '4px', - min: 0, - max: 128 - }, - 'nz-table-img-max-width': { - label: '表格中:图片最大宽度', - type: 'px', - default: '32px', - min: 8, - max: 128 - }, - 'nz-table-img-max-height': { - label: '表格中:图片最大高度', - type: 'px', - default: '32px', - min: 8, - max: 128 - } -}; - -@Component({ - // tslint:disable-next-line:component-selector - selector: 'setting-drawer', - templateUrl: './setting-drawer.component.html', - preserveWhitespaces: false, - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class SettingDrawerComponent { - private loadedLess = false; - - @HostBinding('class') - defaultClass = 'setting-drawer'; - - collapse = false; - get layout() { - return this.settingSrv.layout; - } - data: any = {}; - color: string; - colors = DEFAULT_COLORS; - - constructor( - private cd: ChangeDetectorRef, - private msg: NzMessageService, - private settingSrv: SettingsService, - private lazy: LazyService, - private zone: NgZone, - @Inject(DOCUMENT) private doc: any - ) { - this.color = this.cachedData['@primary-color'] || this.DEFAULT_PRIMARY; - this.resetData(this.cachedData, false); - } - - private get cachedData() { - return this.settingSrv.layout[ALAINDEFAULTVAR] || {}; - } - - private get DEFAULT_PRIMARY() { - return DEFAULT_VARS['primary-color'].default; - } - - private loadLess(): Promise { - if (this.loadedLess) { - return Promise.resolve(); - } - return this.lazy - .loadStyle('./assets/alain-default.less', 'stylesheet/less') - .then(() => { - const lessConfigNode = this.doc.createElement('script'); - lessConfigNode.innerHTML = ` - window.less = { - async: true, - env: 'production', - javascriptEnabled: true - }; - `; - this.doc.body.appendChild(lessConfigNode); - }) - .then(() => - this.lazy.loadScript( - 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js' - ) - ) - .then(() => { - this.loadedLess = true; - }); - } - - private genVars() { - const { data, color, validKeys } = this; - const vars: any = { - [`@primary-color`]: color - }; - validKeys - .filter(key => key !== 'primary-color') - .forEach(key => (vars[`@${key}`] = data[key].value)); - this.setLayout(ALAINDEFAULTVAR, vars); - return vars; - } - - private runLess() { - const { zone, msg, cd } = this; - const msgId = msg.loading(`正在编译主题!`, { nzDuration: 0 }).messageId; - setTimeout(() => { - zone.runOutsideAngular(() => { - this.loadLess().then(() => { - (window as any).less.modifyVars(this.genVars()).then(() => { - msg.success('成功'); - msg.remove(msgId); - zone.run(() => cd.detectChanges()); - }); - }); - }); - }, 200); - } - - toggle() { - this.collapse = !this.collapse; - } - - changeColor(color: string) { - this.color = color; - Object.keys(DEFAULT_VARS) - .filter(key => DEFAULT_VARS[key].default === '@primary-color') - .forEach(key => delete this.cachedData[`@${key}`]); - this.resetData(this.cachedData, false); - } - - setLayout(name: string, value: any) { - this.settingSrv.setLayout(name, value); - } - - private resetData(nowData?: any, run = true) { - nowData = nowData || {}; - const data = deepCopy(DEFAULT_VARS); - Object.keys(data).forEach(key => { - const value = nowData[`@${key}`] || data[key].default || ''; - data[key].value = value === `@primary-color` ? this.color : value; - }); - this.data = data; - if (run) { - this.cd.detectChanges(); - this.runLess(); - } - } - - private get validKeys(): string[] { - return Object.keys(this.data).filter( - key => this.data[key].value !== this.data[key].default - ); - } - - apply() { - this.runLess(); - } - - reset() { - this.color = this.DEFAULT_PRIMARY; - this.settingSrv.setLayout(ALAINDEFAULTVAR, {}); - this.resetData({}); - } - - copyVar() { - const vars = this.genVars(); - const copyContent = Object.keys(vars) - .map(key => `${key}: ${vars[key]};`) - .join('\n'); - copy(copyContent); - this.msg.success('Copy success'); - } -} diff --git a/src/app/layout/default/sidebar/sidebar.component.html b/src/app/layout/default/sidebar/sidebar.component.html deleted file mode 100644 index ea9cfa6..0000000 --- a/src/app/layout/default/sidebar/sidebar.component.html +++ /dev/null @@ -1,16 +0,0 @@ - -
    - -
    - - -
    -
      -
    • 个人中心
    • -
    • 个人设置
    • -
    -
    - -
    \ No newline at end of file diff --git a/src/app/layout/default/sidebar/sidebar.component.spec.ts b/src/app/layout/default/sidebar/sidebar.component.spec.ts deleted file mode 100644 index fabcd26..0000000 --- a/src/app/layout/default/sidebar/sidebar.component.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed, TestModuleMetadata } from '@angular/core/testing'; -import { setUpTestBed } from '@testing/common.spec'; - -import { SidebarComponent } from './sidebar.component'; - -describe('Layout: Sidebar', () => { - setUpTestBed({ - declarations: [SidebarComponent], - }); - - it('should create an instance', () => { - const fixture = TestBed.createComponent(SidebarComponent); - const comp = fixture.debugElement.componentInstance; - expect(comp).toBeTruthy(); - }); -}); diff --git a/src/app/layout/default/sidebar/sidebar.component.ts b/src/app/layout/default/sidebar/sidebar.component.ts deleted file mode 100644 index 2ae54b8..0000000 --- a/src/app/layout/default/sidebar/sidebar.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from '@angular/core'; -import { NzMessageService } from 'ng-zorro-antd'; -import { SettingsService } from '@delon/theme'; - -@Component({ - selector: 'layout-sidebar', - templateUrl: './sidebar.component.html' -}) -export class SidebarComponent { - constructor( - public settings: SettingsService, - public msgSrv: NzMessageService - ) {} -} diff --git a/src/app/layout/fullscreen/fullscreen.component.html b/src/app/layout/fullscreen/fullscreen.component.html deleted file mode 100644 index a693b2b..0000000 --- a/src/app/layout/fullscreen/fullscreen.component.html +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/src/app/layout/fullscreen/fullscreen.component.ts b/src/app/layout/fullscreen/fullscreen.component.ts deleted file mode 100644 index 9cdeb5a..0000000 --- a/src/app/layout/fullscreen/fullscreen.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component, HostBinding } from '@angular/core'; - -@Component({ - selector: 'layout-fullscreen', - templateUrl: './fullscreen.component.html' -}) -export class LayoutFullScreenComponent { - @HostBinding('class') - defaultClass = 'alain-fullscreen'; -} diff --git a/src/app/layout/home/footer/home-footer.component.html b/src/app/layout/home/footer/home-footer.component.html deleted file mode 100644 index 086c914..0000000 --- a/src/app/layout/home/footer/home-footer.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
    - footer -
    diff --git a/src/app/layout/home/footer/home-footer.component.ts b/src/app/layout/home/footer/home-footer.component.ts deleted file mode 100644 index f7dbfa9..0000000 --- a/src/app/layout/home/footer/home-footer.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component, HostBinding } from '@angular/core'; - -@Component({ - selector: 'layout-home-footer', - templateUrl: './home-footer.component.html' -}) -export class HomeFooterComponent {} diff --git a/src/app/layout/home/header/home-header.component.html b/src/app/layout/home/header/home-header.component.html deleted file mode 100644 index 1bb988d..0000000 --- a/src/app/layout/home/header/home-header.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
    - header -
    diff --git a/src/app/layout/home/header/home-header.component.ts b/src/app/layout/home/header/home-header.component.ts deleted file mode 100644 index 05bfb5a..0000000 --- a/src/app/layout/home/header/home-header.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component, HostBinding } from '@angular/core'; - -@Component({ - selector: 'layout-home-header', - templateUrl: './home-header.component.html' -}) -export class HomeHeaderComponent {} diff --git a/src/app/layout/home/home-routing.module.ts b/src/app/layout/home/home-routing.module.ts new file mode 100644 index 0000000..d24bffd --- /dev/null +++ b/src/app/layout/home/home-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { HomeComponent } from './home.component'; + +const routes: Routes = [ + { + path: '', + component: HomeComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class HomeRoutingModule {} + +export const routedComponents = [HomeComponent]; diff --git a/src/app/layout/home/home.component.html b/src/app/layout/home/home.component.html deleted file mode 100644 index ba070eb..0000000 --- a/src/app/layout/home/home.component.html +++ /dev/null @@ -1,9 +0,0 @@ -
    -
    - -
    -
    - - -
    -
    diff --git a/src/app/layout/home/home.component.less b/src/app/layout/home/home.component.less deleted file mode 100644 index b1f9c70..0000000 --- a/src/app/layout/home/home.component.less +++ /dev/null @@ -1,27 +0,0 @@ -.home-container { - display: block; - height: 100%; - background: white; - padding: 0 16.7%; - - &-header { - position: fixed; - top: 0; - left: 0; - right: 0; - height: 80px; - background: white; - z-index: 10; - padding: 0 16.7%; - } - - &-main { - position: fixed; - top: 80px; - left: 0; - right: 0; - bottom: 0; - padding: 0 16.7%; - overflow: auto; - } -} diff --git a/src/app/layout/home/home.component.ts b/src/app/layout/home/home.component.ts index 7cee521..cb7ed3f 100644 --- a/src/app/layout/home/home.component.ts +++ b/src/app/layout/home/home.component.ts @@ -1,8 +1,10 @@ -import { Component, HostBinding } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ - selector: 'layout-home', - templateUrl: './home.component.html', - styleUrls: ['./home.component.less'] + selector: 'ng-home', + template: ` + + + ` }) export class HomeComponent {} diff --git a/src/app/layout/home/home.module.ts b/src/app/layout/home/home.module.ts new file mode 100644 index 0000000..64925a6 --- /dev/null +++ b/src/app/layout/home/home.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core'; +import { HomeRoutingModule, routedComponents } from './home-routing.module'; +import { NgZorroAntdModule } from 'ng-zorro-antd'; + +@NgModule({ + imports: [HomeRoutingModule, NgZorroAntdModule], + declarations: [...routedComponents] +}) +export class HomeModule {} diff --git a/src/app/layout/layout.module.ts b/src/app/layout/layout.module.ts deleted file mode 100644 index 4a24d20..0000000 --- a/src/app/layout/layout.module.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { NgModule } from '@angular/core'; -import { SharedModule } from '@shared/shared.module'; - -import { LayoutDefaultComponent } from './default/default.component'; -import { LayoutFullScreenComponent } from './fullscreen/fullscreen.component'; -import { HeaderComponent } from './default/header/header.component'; -import { SidebarComponent } from './default/sidebar/sidebar.component'; -import { HeaderSearchComponent } from './default/header/components/search.component'; -import { HeaderNotifyComponent } from './default/header/components/notify.component'; -import { HeaderTaskComponent } from './default/header/components/task.component'; -import { HeaderIconComponent } from './default/header/components/icon.component'; -import { HeaderFullScreenComponent } from './default/header/components/fullscreen.component'; -import { HeaderStorageComponent } from './default/header/components/storage.component'; -import { HeaderUserComponent } from './default/header/components/user.component'; - -import { SettingDrawerComponent } from './default/setting-drawer/setting-drawer.component'; -import { SettingDrawerItemComponent } from './default/setting-drawer/setting-drawer-item.component'; - -const SETTINGDRAWER = [SettingDrawerComponent, SettingDrawerItemComponent]; - -const COMPONENTS = [ - LayoutDefaultComponent, - LayoutFullScreenComponent, - HeaderComponent, - SidebarComponent, - ...SETTINGDRAWER -]; -const HOME_COMPONENTS = [ - HomeComponent, - HomeHeaderComponent, - HomeFooterComponent -]; -const HEADERCOMPONENTS = [ - HeaderSearchComponent, - HeaderNotifyComponent, - HeaderTaskComponent, - HeaderIconComponent, - HeaderFullScreenComponent, - HeaderStorageComponent, - HeaderUserComponent -]; - -// passport -import { LayoutPassportComponent } from './passport/passport.component'; -import { HomeHeaderComponent } from '@layout/home/header/home-header.component'; -import { HomeFooterComponent } from '@layout/home/footer/home-footer.component'; -import { HomeComponent } from '@layout/home/home.component'; - -const PASSPORT = [LayoutPassportComponent]; - -@NgModule({ - imports: [SharedModule], - entryComponents: SETTINGDRAWER, - declarations: [ - ...COMPONENTS, - ...HEADERCOMPONENTS, - ...PASSPORT, - ...HOME_COMPONENTS - ], - exports: [...COMPONENTS, ...PASSPORT] -}) -export class LayoutModule {} diff --git a/src/app/layout/passport/passport-routing.module.ts b/src/app/layout/passport/passport-routing.module.ts new file mode 100644 index 0000000..afd0312 --- /dev/null +++ b/src/app/layout/passport/passport-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { PassportComponent } from './passport.component'; + +const routes: Routes = [ + { + path: '', + component: PassportComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class PassportRoutingModule {} + +export const routedComponents = [PassportComponent]; diff --git a/src/app/layout/passport/passport.component.html b/src/app/layout/passport/passport.component.html index 6d665bf..1157609 100644 --- a/src/app/layout/passport/passport.component.html +++ b/src/app/layout/passport/passport.component.html @@ -1,11 +1,34 @@ - -
    -
    -
    -
    ng-alain
    -
    武林中最有影响力的《葵花宝典》;欲练神功,挥刀自宫
    +
    +
    +
    + +
    欢迎登录CodeRiver
    - - Copyright2017卡色出品 +
    +
    + + + + + + + + + + + + + + +
    +
    +
    -
    \ No newline at end of file +
    + + diff --git a/src/app/layout/passport/passport.component.less b/src/app/layout/passport/passport.component.less index 4340f88..f7a7c3f 100644 --- a/src/app/layout/passport/passport.component.less +++ b/src/app/layout/passport/passport.component.less @@ -1,71 +1,48 @@ -@import '~@delon/theme/styles/default'; -:host { - ::ng-deep { - .container { - display: flex; - flex-direction: column; - min-height: 100%; - background: #f0f2f5; - } - .langs { - text-align: right; - width: 100%; - height: 40px; - line-height: 44px; - .anticon { - margin-top: 24px; - margin-right: 24px; - font-size: 14px; - vertical-align: top; - cursor: pointer; +.cr-passport-container { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100vh; + background: url('~/assets/imgs/bg_passport.png') no-repeat center; + background-size: cover; + + .sign-card { + width: 430px; + background: #ffffff; + + &-header { + padding-top: 30px; + text-align: center; + + .logo img { + width: 200px; + } + .title { + margin-top: 10px; + font-size: 20px; } } - .wrap { - padding: 32px 0; - flex: 1; - } - .ant-form-item { - margin-bottom: 24px; - } + &-content { + margin-top: 30px; + padding: 0 50px; + + .login-form-operation { + margin-top: 20px; + margin-bottom: 10px; - @media (min-width: @screen-md-min) { - .container { - background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg'); - background-repeat: no-repeat; - background-position: center 110px; - background-size: 100%; + .login-form-forgot { + float: right; + } } - .wrap { - padding: 32px 0 24px; + .login-form-button { + width: 100%; } } - .top { + &-footer { + line-height: 60px; text-align: center; - } - .header { - height: 44px; - line-height: 44px; - a { - text-decoration: none; - } - } - .logo { - height: 44px; - margin-right: 16px; - } - .title { - font-size: 33px; - color: @heading-color; - font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif; - font-weight: 600; - position: relative; - vertical-align: middle; - } - .desc { - font-size: @font-size-base; - color: @text-color-secondary; - margin-top: 12px; - margin-bottom: 40px; + background: #F6F6F6; } } } diff --git a/src/app/layout/passport/passport.component.ts b/src/app/layout/passport/passport.component.ts index 6d198c7..6d301c5 100644 --- a/src/app/layout/passport/passport.component.ts +++ b/src/app/layout/passport/passport.component.ts @@ -1,23 +1,8 @@ import { Component } from '@angular/core'; @Component({ - selector: 'layout-passport', + selector: 'cr-passport', templateUrl: './passport.component.html', styleUrls: ['./passport.component.less'] }) -export class LayoutPassportComponent { - links = [ - { - title: '帮助', - href: '' - }, - { - title: '隐私', - href: '' - }, - { - title: '条款', - href: '' - } - ]; -} +export class PassportComponent {} diff --git a/src/app/layout/passport/passport.module.ts b/src/app/layout/passport/passport.module.ts new file mode 100644 index 0000000..59fa9c3 --- /dev/null +++ b/src/app/layout/passport/passport.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core'; +import { PassportRoutingModule, routedComponents } from './passport-routing.module'; +import { NgZorroAntdModule } from 'ng-zorro-antd'; + +@NgModule({ + imports: [PassportRoutingModule, NgZorroAntdModule], + declarations: [...routedComponents] +}) +export class PassportModule {} diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts deleted file mode 100644 index 6cf2353..0000000 --- a/src/app/services/auth.service.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import {Observable, of} from 'rxjs'; -import { IToken } from '@shared/interfaces/token.interface'; -import 'rxjs/add/operator/mergeMap'; -import { mergeMap} from 'rxjs/operators'; - -@Injectable() -export class AuthService { - constructor( - private readonly httpClient: HttpClient - ) {} - - signUp(email: string, password: string): void { - this.httpClient.post(`api/auth/local/signup`, { - email, - password - }).subscribe((token: IToken) => { - localStorage.setItem('token', token.token); - }); - } - - signIn(email: string, password: string): void { - this.httpClient.post(`api/auth/local/signin`, { - email, - password - }).subscribe((token: IToken) => { - localStorage.setItem('token', token.token); - }); - } - - requestFacebookRedirectUri(): Observable { - return this.httpClient.get('api/auth/facebook/uri'); - } - - facebookSignIn(code: string): Observable { - return this.httpClient.post('api/auth/facebook/signin', { code }).pipe( - mergeMap((token: IToken) => { - localStorage.setItem('token', token.token); - return of(token); - }) - ); - } - - requestTwitterRedirectUri(): Observable { - return this.httpClient.get('api/auth/twitter/uri'); - } - - twitterSignIn(oauth_token: string, oauth_verifier: string): Observable { - return this.httpClient.post('api/auth/twitter/signin', { oauth_token, oauth_verifier }); - } - - requestGoogleRedirectUri(): Observable { - return this.httpClient.get('api/auth/google/uri'); - } - - googleSignIn(code: string): Observable { - return this.httpClient.post('api/auth/google/signin', { code }); - } - - getProtected(): Observable { - return this.httpClient.get(`api/auth/authorized`); - } - - getToken(): string { - try { - return localStorage.getItem('token'); - } catch (e) { - return null; - } - } - - isAuthenticated(): boolean { - return !!this.getToken(); - } -} diff --git a/src/app/services/shopping-list.service.ts b/src/app/services/shopping-list.service.ts deleted file mode 100644 index e72c86c..0000000 --- a/src/app/services/shopping-list.service.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { EventEmitter, Injectable } from '@angular/core'; -import { Ingredient } from '../shared/components/ingredient/ingredient.component'; - -@Injectable() -export class ShoppingListService { - public ingredientCreated: EventEmitter = new EventEmitter(); - // public ingredientsChanged: EventEmitter = new EventEmitter(); - - private ingredients: Ingredient[] = [ - new Ingredient('tomatoes', 3), - new Ingredient('cheese', 1), - new Ingredient('potatoes', 2) - ]; - - constructor() {} - - public getIngredients(): Promise { - return new Promise((resolve, reject) => { - resolve(this.ingredients); - }); - } - - public addIngredient(ingredient: Ingredient) { - this.ingredients.push(ingredient); - // this.ingredientsChanged.emit(this.ingredients.slice()); - } - - public removeIngredient(index: number) { - this.ingredients.splice(index, 1); - // this.ingredientsChanged.emit(this.ingredients.slice()); - } - - public addIngredients(ingredients: Ingredient[]): void { - this.ingredients.push(...ingredients); - // this.ingredientsChanged.emit(this.ingredients.slice()); - } - -} diff --git a/src/app/shared/components/ingredient/ingredient.component.html b/src/app/shared/components/ingredient/ingredient.component.html deleted file mode 100644 index 869f449..0000000 --- a/src/app/shared/components/ingredient/ingredient.component.html +++ /dev/null @@ -1,2 +0,0 @@ -{{ ingredient.name }} ({{ ingredient.amount }}) - \ No newline at end of file diff --git a/src/app/shared/components/ingredient/ingredient.component.less b/src/app/shared/components/ingredient/ingredient.component.less deleted file mode 100644 index 93c77ed..0000000 --- a/src/app/shared/components/ingredient/ingredient.component.less +++ /dev/null @@ -1,3 +0,0 @@ -.btn-small { - padding: 2px 10px 2px 10px; -} \ No newline at end of file diff --git a/src/app/shared/components/ingredient/ingredient.component.spec.ts b/src/app/shared/components/ingredient/ingredient.component.spec.ts deleted file mode 100644 index cbfbab6..0000000 --- a/src/app/shared/components/ingredient/ingredient.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { IngredientComponent } from './ingredient.component'; - -describe('IngredientComponent', () => { - let component: IngredientComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ IngredientComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(IngredientComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/shared/components/ingredient/ingredient.component.ts b/src/app/shared/components/ingredient/ingredient.component.ts deleted file mode 100644 index 7e6c450..0000000 --- a/src/app/shared/components/ingredient/ingredient.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; - -export class Ingredient { - constructor(public name: string, public amount: number) {} -} - -@Component({ - selector: 'app-ingredient', - templateUrl: './ingredient.component.html', - styleUrls: ['./ingredient.component.less'] -}) -export class IngredientComponent implements OnInit { - @Input() ingredient: Ingredient; - @Output() ingredientRemoved: EventEmitter = new EventEmitter(); - - constructor() {} - - ngOnInit() {} - - onRemoveIngredient() { - this.ingredientRemoved.emit(this.ingredient); - } -} diff --git a/src/app/shared/directives/dropdown.directive.spec.ts b/src/app/shared/directives/dropdown.directive.spec.ts deleted file mode 100644 index f726f90..0000000 --- a/src/app/shared/directives/dropdown.directive.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DropdownDirective } from './dropdown.directive'; - -describe('DropdownDirective', () => { - it('should create an instance', () => { - const directive = new DropdownDirective(); - expect(directive).toBeTruthy(); - }); -}); diff --git a/src/app/shared/directives/dropdown.directive.ts b/src/app/shared/directives/dropdown.directive.ts deleted file mode 100644 index a7cb157..0000000 --- a/src/app/shared/directives/dropdown.directive.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Directive, HostBinding, HostListener } from '@angular/core'; - -@Directive({ - selector: '[appDropdown]' -}) -export class DropdownDirective { - @HostBinding('class.open') isOpen = false; - - constructor( - ) { } - - @HostListener('click') handleClick(e: Event): void { - this.isOpen = !this.isOpen; - } -} diff --git a/src/app/shared/interfaces/token.interface.ts b/src/app/shared/interfaces/token.interface.ts deleted file mode 100644 index 2410552..0000000 --- a/src/app/shared/interfaces/token.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IToken { - readonly token: string; -} diff --git a/src/app/shared/json-schema/json-schema.module.ts b/src/app/shared/json-schema/json-schema.module.ts deleted file mode 100644 index 5d036e5..0000000 --- a/src/app/shared/json-schema/json-schema.module.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { NgModule } from '@angular/core'; -import { SharedModule } from '@shared/shared.module'; -import { DelonFormModule, WidgetRegistry } from '@delon/form'; - -// import { TinymceWidget } from './widgets/tinymce/tinymce.widget'; -// import { UEditorWidget } from './widgets/ueditor/ueditor.widget'; - -export const SCHEMA_THIRDS_COMPONENTS: any[] = [ - // TinymceWidget, - // UEditorWidget -]; - -@NgModule({ - declarations: SCHEMA_THIRDS_COMPONENTS, - entryComponents: SCHEMA_THIRDS_COMPONENTS, - imports: [ - SharedModule, - DelonFormModule.forRoot() - ], - exports: [ - ...SCHEMA_THIRDS_COMPONENTS - ] -}) -export class JsonSchemaModule { - constructor(widgetRegistry: WidgetRegistry) { - // widgetRegistry.register(TinymceWidget.KEY, TinymceWidget); - // widgetRegistry.register(UEditorWidget.KEY, UEditorWidget); - } -} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts deleted file mode 100644 index bc8d8bd..0000000 --- a/src/app/shared/shared.module.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { ReactiveFormsModule, FormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; -// delon -import { AlainThemeModule } from '@delon/theme'; -import { DelonABCModule } from '@delon/abc'; -import { DelonACLModule } from '@delon/acl'; -import { DelonFormModule } from '@delon/form'; - -// #region third libs -import { NgZorroAntdModule } from 'ng-zorro-antd'; -import { CountdownModule } from 'ngx-countdown'; -const THIRDMODULES = [ - NgZorroAntdModule, - CountdownModule -]; -// #endregion - -// #region your componets & directives -import { IngredientComponent } from './components/ingredient/ingredient.component'; -import { DropdownDirective } from './directives/dropdown.directive'; -const COMPONENTS = [ IngredientComponent ]; -const DIRECTIVES = [ DropdownDirective ]; -// #endregion - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - RouterModule, - ReactiveFormsModule, - AlainThemeModule.forChild(), - DelonABCModule, - DelonACLModule, - DelonFormModule, - // third libs - ...THIRDMODULES - ], - declarations: [ - // your components - ...COMPONENTS, - ...DIRECTIVES - ], - exports: [ - CommonModule, - FormsModule, - ReactiveFormsModule, - RouterModule, - AlainThemeModule, - DelonABCModule, - DelonACLModule, - DelonFormModule, - // third libs - ...THIRDMODULES, - // your components - ...COMPONENTS, - ...DIRECTIVES - ] -}) -export class SharedModule { } diff --git a/src/styles/index.less b/src/app/styles/styles.less similarity index 50% rename from src/styles/index.less rename to src/app/styles/styles.less index 90d4ee0..c32b395 100644 --- a/src/styles/index.less +++ b/src/app/styles/styles.less @@ -1 +1,10 @@ /* You can add global styles to this file, and also import other style files */ + +body { + width: 100vw; + min-height: 100vh; +} + +a { + text-decoration: none; +} diff --git a/src/assets/alain-default.less b/src/assets/alain-default.less deleted file mode 100644 index 896f793..0000000 --- a/src/assets/alain-default.less +++ /dev/null @@ -1,22520 +0,0 @@ -// default -/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ -/* stylelint-disable no-duplicate-selectors */ -/* stylelint-disable */ -.bezierEasingMixin() { -@functions: ~`(function() { - var NEWTON_ITERATIONS = 4; - var NEWTON_MIN_SLOPE = 0.001; - var SUBDIVISION_PRECISION = 0.0000001; - var SUBDIVISION_MAX_ITERATIONS = 10; - - var kSplineTableSize = 11; - var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); - - var float32ArraySupported = typeof Float32Array === 'function'; - - function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } - function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } - function C (aA1) { return 3.0 * aA1; } - - // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. - function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; } - - // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. - function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); } - - function binarySubdivide (aX, aA, aB, mX1, mX2) { - var currentX, currentT, i = 0; - do { - currentT = aA + (aB - aA) / 2.0; - currentX = calcBezier(currentT, mX1, mX2) - aX; - if (currentX > 0.0) { - aB = currentT; - } else { - aA = currentT; - } - } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); - return currentT; - } - - function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { - for (var i = 0; i < NEWTON_ITERATIONS; ++i) { - var currentSlope = getSlope(aGuessT, mX1, mX2); - if (currentSlope === 0.0) { - return aGuessT; - } - var currentX = calcBezier(aGuessT, mX1, mX2) - aX; - aGuessT -= currentX / currentSlope; - } - return aGuessT; - } - - var BezierEasing = function (mX1, mY1, mX2, mY2) { - if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { - throw new Error('bezier x values must be in [0, 1] range'); - } - - // Precompute samples table - var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); - if (mX1 !== mY1 || mX2 !== mY2) { - for (var i = 0; i < kSplineTableSize; ++i) { - sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); - } - } - - function getTForX (aX) { - var intervalStart = 0.0; - var currentSample = 1; - var lastSample = kSplineTableSize - 1; - - for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) { - intervalStart += kSampleStepSize; - } - --currentSample; - - // Interpolate to provide an initial guess for t - var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]); - var guessForT = intervalStart + dist * kSampleStepSize; - - var initialSlope = getSlope(guessForT, mX1, mX2); - if (initialSlope >= NEWTON_MIN_SLOPE) { - return newtonRaphsonIterate(aX, guessForT, mX1, mX2); - } else if (initialSlope === 0.0) { - return guessForT; - } else { - return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); - } - } - - return function BezierEasing (x) { - if (mX1 === mY1 && mX2 === mY2) { - return x; // linear - } - // Because JavaScript number are imprecise, we should guarantee the extremes are right. - if (x === 0) { - return 0; - } - if (x === 1) { - return 1; - } - return calcBezier(getTForX(x), mY1, mY2); - }; - }; - - this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18); - // less 3 requires a return - return ''; -})()`; -} -// It is hacky way to make this function will be compiled preferentially by less -// resolve error: `ReferenceError: colorPalette is not defined` -// https://github.com/ant-design/ant-motion/issues/44 -.bezierEasingMixin(); - -/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */ -.tinyColorMixin() { -@functions: ~`(function() { -// TinyColor v1.4.1 -// https://github.com/bgrins/TinyColor -// 2016-07-07, Brian Grinstead, MIT License -var trimLeft = /^\s+/, - trimRight = /\s+$/, - tinyCounter = 0, - mathRound = Math.round, - mathMin = Math.min, - mathMax = Math.max, - mathRandom = Math.random; - -function tinycolor (color, opts) { - - color = (color) ? color : ''; - opts = opts || { }; - - // If input is already a tinycolor, return itself - if (color instanceof tinycolor) { - return color; - } - // If we are called as a function, call using new instead - if (!(this instanceof tinycolor)) { - return new tinycolor(color, opts); - } - - var rgb = inputToRGB(color); - this._originalInput = color, - this._r = rgb.r, - this._g = rgb.g, - this._b = rgb.b, - this._a = rgb.a, - this._roundA = mathRound(100*this._a) / 100, - this._format = opts.format || rgb.format; - this._gradientType = opts.gradientType; - - // Don't let the range of [0,255] come back in [0,1]. - // Potentially lose a little bit of precision here, but will fix issues where - // .5 gets interpreted as half of the total, instead of half of 1 - // If it was supposed to be 128, this was already taken care of by inputToRgb - if (this._r < 1) { this._r = mathRound(this._r); } - if (this._g < 1) { this._g = mathRound(this._g); } - if (this._b < 1) { this._b = mathRound(this._b); } - - this._ok = rgb.ok; - this._tc_id = tinyCounter++; -} - -tinycolor.prototype = { - isDark: function() { - return this.getBrightness() < 128; - }, - isLight: function() { - return !this.isDark(); - }, - isValid: function() { - return this._ok; - }, - getOriginalInput: function() { - return this._originalInput; - }, - getFormat: function() { - return this._format; - }, - getAlpha: function() { - return this._a; - }, - getBrightness: function() { - //http://www.w3.org/TR/AERT#color-contrast - var rgb = this.toRgb(); - return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; - }, - getLuminance: function() { - //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef - var rgb = this.toRgb(); - var RsRGB, GsRGB, BsRGB, R, G, B; - RsRGB = rgb.r/255; - GsRGB = rgb.g/255; - BsRGB = rgb.b/255; - - if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);} - if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);} - if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);} - return (0.2126 * R) + (0.7152 * G) + (0.0722 * B); - }, - setAlpha: function(value) { - this._a = boundAlpha(value); - this._roundA = mathRound(100*this._a) / 100; - return this; - }, - toHsv: function() { - var hsv = rgbToHsv(this._r, this._g, this._b); - return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a }; - }, - toHsvString: function() { - var hsv = rgbToHsv(this._r, this._g, this._b); - var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100); - return (this._a == 1) ? - "hsv(" + h + ", " + s + "%, " + v + "%)" : - "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")"; - }, - toHsl: function() { - var hsl = rgbToHsl(this._r, this._g, this._b); - return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a }; - }, - toHslString: function() { - var hsl = rgbToHsl(this._r, this._g, this._b); - var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100); - return (this._a == 1) ? - "hsl(" + h + ", " + s + "%, " + l + "%)" : - "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")"; - }, - toHex: function(allow3Char) { - return rgbToHex(this._r, this._g, this._b, allow3Char); - }, - toHexString: function(allow3Char) { - return '#' + this.toHex(allow3Char); - }, - toHex8: function(allow4Char) { - return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char); - }, - toHex8String: function(allow4Char) { - return '#' + this.toHex8(allow4Char); - }, - toRgb: function() { - return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a }; - }, - toRgbString: function() { - return (this._a == 1) ? - "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" : - "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")"; - }, - toPercentageRgb: function() { - return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a }; - }, - toPercentageRgbString: function() { - return (this._a == 1) ? - "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" : - "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; - }, - toName: function() { - if (this._a === 0) { - return "transparent"; - } - - if (this._a < 1) { - return false; - } - - return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; - }, - toFilter: function(secondColor) { - var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a); - var secondHex8String = hex8String; - var gradientType = this._gradientType ? "GradientType = 1, " : ""; - - if (secondColor) { - var s = tinycolor(secondColor); - secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a); - } - - return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")"; - }, - toString: function(format) { - var formatSet = !!format; - format = format || this._format; - - var formattedString = false; - var hasAlpha = this._a < 1 && this._a >= 0; - var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name"); - - if (needsAlphaFormat) { - // Special case for "transparent", all other non-alpha formats - // will return rgba when there is transparency. - if (format === "name" && this._a === 0) { - return this.toName(); - } - return this.toRgbString(); - } - if (format === "rgb") { - formattedString = this.toRgbString(); - } - if (format === "prgb") { - formattedString = this.toPercentageRgbString(); - } - if (format === "hex" || format === "hex6") { - formattedString = this.toHexString(); - } - if (format === "hex3") { - formattedString = this.toHexString(true); - } - if (format === "hex4") { - formattedString = this.toHex8String(true); - } - if (format === "hex8") { - formattedString = this.toHex8String(); - } - if (format === "name") { - formattedString = this.toName(); - } - if (format === "hsl") { - formattedString = this.toHslString(); - } - if (format === "hsv") { - formattedString = this.toHsvString(); - } - - return formattedString || this.toHexString(); - }, - clone: function() { - return tinycolor(this.toString()); - }, - - _applyModification: function(fn, args) { - var color = fn.apply(null, [this].concat([].slice.call(args))); - this._r = color._r; - this._g = color._g; - this._b = color._b; - this.setAlpha(color._a); - return this; - }, - lighten: function() { - return this._applyModification(lighten, arguments); - }, - brighten: function() { - return this._applyModification(brighten, arguments); - }, - darken: function() { - return this._applyModification(darken, arguments); - }, - desaturate: function() { - return this._applyModification(desaturate, arguments); - }, - saturate: function() { - return this._applyModification(saturate, arguments); - }, - greyscale: function() { - return this._applyModification(greyscale, arguments); - }, - spin: function() { - return this._applyModification(spin, arguments); - }, - - _applyCombination: function(fn, args) { - return fn.apply(null, [this].concat([].slice.call(args))); - }, - analogous: function() { - return this._applyCombination(analogous, arguments); - }, - complement: function() { - return this._applyCombination(complement, arguments); - }, - monochromatic: function() { - return this._applyCombination(monochromatic, arguments); - }, - splitcomplement: function() { - return this._applyCombination(splitcomplement, arguments); - }, - triad: function() { - return this._applyCombination(triad, arguments); - }, - tetrad: function() { - return this._applyCombination(tetrad, arguments); - } -}; - -// If input is an object, force 1 into "1.0" to handle ratios properly -// String input requires "1.0" as input, so 1 will be treated as 1 -tinycolor.fromRatio = function(color, opts) { - if (typeof color == "object") { - var newColor = {}; - for (var i in color) { - if (color.hasOwnProperty(i)) { - if (i === "a") { - newColor[i] = color[i]; - } - else { - newColor[i] = convertToPercentage(color[i]); - } - } - } - color = newColor; - } - - return tinycolor(color, opts); -}; - -// Given a string or object, convert that input to RGB -// Possible string inputs: -// -// "red" -// "#f00" or "f00" -// "#ff0000" or "ff0000" -// "#ff000000" or "ff000000" -// "rgb 255 0 0" or "rgb (255, 0, 0)" -// "rgb 1.0 0 0" or "rgb (1, 0, 0)" -// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" -// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" -// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" -// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" -// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" -// -function inputToRGB(color) { - - var rgb = { r: 0, g: 0, b: 0 }; - var a = 1; - var s = null; - var v = null; - var l = null; - var ok = false; - var format = false; - - if (typeof color == "string") { - color = stringInputToObject(color); - } - - if (typeof color == "object") { - if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { - rgb = rgbToRgb(color.r, color.g, color.b); - ok = true; - format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; - } - else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { - s = convertToPercentage(color.s); - v = convertToPercentage(color.v); - rgb = hsvToRgb(color.h, s, v); - ok = true; - format = "hsv"; - } - else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { - s = convertToPercentage(color.s); - l = convertToPercentage(color.l); - rgb = hslToRgb(color.h, s, l); - ok = true; - format = "hsl"; - } - - if (color.hasOwnProperty("a")) { - a = color.a; - } - } - - a = boundAlpha(a); - - return { - ok: ok, - format: color.format || format, - r: mathMin(255, mathMax(rgb.r, 0)), - g: mathMin(255, mathMax(rgb.g, 0)), - b: mathMin(255, mathMax(rgb.b, 0)), - a: a - }; -} - -// Conversion Functions -// -------------------- - -// rgbToHsl, rgbToHsv, hslToRgb, hsvToRgb modified from: -// - -// rgbToRgb -// Handle bounds / percentage checking to conform to CSS color spec -// -// *Assumes:* r, g, b in [0, 255] or [0, 1] -// *Returns:* { r, g, b } in [0, 255] -function rgbToRgb(r, g, b){ - return { - r: bound01(r, 255) * 255, - g: bound01(g, 255) * 255, - b: bound01(b, 255) * 255 - }; -} - -// rgbToHsl -// Converts an RGB color value to HSL. -// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] -// *Returns:* { h, s, l } in [0,1] -function rgbToHsl(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(r, g, b); - var h, s, l = (max + min) / 2; - - if(max == min) { - h = s = 0; // achromatic - } - else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch(max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - - h /= 6; - } - - return { h: h, s: s, l: l }; -} - -// hslToRgb -// Converts an HSL color value to RGB. -// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] -// *Returns:* { r, g, b } in the set [0, 255] -function hslToRgb(h, s, l) { - var r, g, b; - - h = bound01(h, 360); - s = bound01(s, 100); - l = bound01(l, 100); - - function hue2rgb(p, q, t) { - if(t < 0) t += 1; - if(t > 1) t -= 1; - if(t < 1/6) return p + (q - p) * 6 * t; - if(t < 1/2) return q; - if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; - return p; - } - - if(s === 0) { - r = g = b = l; // achromatic - } - else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1/3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1/3); - } - - return { r: r * 255, g: g * 255, b: b * 255 }; -} - -// rgbToHsv -// Converts an RGB color value to HSV -// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] -// *Returns:* { h, s, v } in [0,1] -function rgbToHsv(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(r, g, b); - var h, s, v = max; - - var d = max - min; - s = max === 0 ? 0 : d / max; - - if(max == min) { - h = 0; // achromatic - } - else { - switch(max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h, s: s, v: v }; -} - -// hsvToRgb -// Converts an HSV color value to RGB. -// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] -// *Returns:* { r, g, b } in the set [0, 255] - function hsvToRgb(h, s, v) { - - h = bound01(h, 360) * 6; - s = bound01(s, 100); - v = bound01(v, 100); - - var i = Math.floor(h), - f = h - i, - p = v * (1 - s), - q = v * (1 - f * s), - t = v * (1 - (1 - f) * s), - mod = i % 6, - r = [v, q, p, p, t, v][mod], - g = [t, v, v, q, p, p][mod], - b = [p, p, t, v, v, q][mod]; - - return { r: r * 255, g: g * 255, b: b * 255 }; -} - -// rgbToHex -// Converts an RGB color to hex -// Assumes r, g, and b are contained in the set [0, 255] -// Returns a 3 or 6 character hex -function rgbToHex(r, g, b, allow3Char) { - - var hex = [ - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)) - ]; - - // Return a 3 character hex if possible - if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); - } - - return hex.join(""); -} - -// rgbaToHex -// Converts an RGBA color plus alpha transparency to hex -// Assumes r, g, b are contained in the set [0, 255] and -// a in [0, 1]. Returns a 4 or 8 character rgba hex -function rgbaToHex(r, g, b, a, allow4Char) { - - var hex = [ - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)), - pad2(convertDecimalToHex(a)) - ]; - - // Return a 4 character hex if possible - if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0); - } - - return hex.join(""); -} - -// rgbaToArgbHex -// Converts an RGBA color to an ARGB Hex8 string -// Rarely used, but required for "toFilter()" -function rgbaToArgbHex(r, g, b, a) { - - var hex = [ - pad2(convertDecimalToHex(a)), - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)) - ]; - - return hex.join(""); -} - -// equals -// Can be called with any tinycolor input -tinycolor.equals = function (color1, color2) { - if (!color1 || !color2) { return false; } - return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); -}; - -tinycolor.random = function() { - return tinycolor.fromRatio({ - r: mathRandom(), - g: mathRandom(), - b: mathRandom() - }); -}; - -// Modification Functions -// ---------------------- -// Thanks to less.js for some of the basics here -// - -function desaturate(color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.s -= amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); -} - -function saturate(color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.s += amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); -} - -function greyscale(color) { - return tinycolor(color).desaturate(100); -} - -function lighten (color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.l += amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); -} - -function brighten(color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var rgb = tinycolor(color).toRgb(); - rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100)))); - rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100)))); - rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100)))); - return tinycolor(rgb); -} - -function darken (color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.l -= amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); -} - -// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue. -// Values outside of this range will be wrapped into this range. -function spin(color, amount) { - var hsl = tinycolor(color).toHsl(); - var hue = (hsl.h + amount) % 360; - hsl.h = hue < 0 ? 360 + hue : hue; - return tinycolor(hsl); -} - -// Combination Functions -// --------------------- -// Thanks to jQuery xColor for some of the ideas behind these -// - -function complement(color) { - var hsl = tinycolor(color).toHsl(); - hsl.h = (hsl.h + 180) % 360; - return tinycolor(hsl); -} - -function triad(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }) - ]; -} - -function tetrad(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }) - ]; -} - -function splitcomplement(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}), - tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l}) - ]; -} - -function analogous(color, results, slices) { - results = results || 6; - slices = slices || 30; - - var hsl = tinycolor(color).toHsl(); - var part = 360 / slices; - var ret = [tinycolor(color)]; - - for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) { - hsl.h = (hsl.h + part) % 360; - ret.push(tinycolor(hsl)); - } - return ret; -} - -function monochromatic(color, results) { - results = results || 6; - var hsv = tinycolor(color).toHsv(); - var h = hsv.h, s = hsv.s, v = hsv.v; - var ret = []; - var modification = 1 / results; - - while (results--) { - ret.push(tinycolor({ h: h, s: s, v: v})); - v = (v + modification) % 1; - } - - return ret; -} - -// Utility Functions -// --------------------- - -tinycolor.mix = function(color1, color2, amount) { - amount = (amount === 0) ? 0 : (amount || 50); - - var rgb1 = tinycolor(color1).toRgb(); - var rgb2 = tinycolor(color2).toRgb(); - - var p = amount / 100; - - var rgba = { - r: ((rgb2.r - rgb1.r) * p) + rgb1.r, - g: ((rgb2.g - rgb1.g) * p) + rgb1.g, - b: ((rgb2.b - rgb1.b) * p) + rgb1.b, - a: ((rgb2.a - rgb1.a) * p) + rgb1.a - }; - - return tinycolor(rgba); -}; - -// Readability Functions -// --------------------- -// false -// tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false -tinycolor.isReadable = function(color1, color2, wcag2) { - var readability = tinycolor.readability(color1, color2); - var wcag2Parms, out; - - out = false; - - wcag2Parms = validateWCAG2Parms(wcag2); - switch (wcag2Parms.level + wcag2Parms.size) { - case "AAsmall": - case "AAAlarge": - out = readability >= 4.5; - break; - case "AAlarge": - out = readability >= 3; - break; - case "AAAsmall": - out = readability >= 7; - break; - } - return out; - -}; - -// mostReadable -// Given a base color and a list of possible foreground or background -// colors for that base, returns the most readable color. -// Optionally returns Black or White if the most readable color is unreadable. -// *Example* -// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255" -// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff" -// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3" -// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff" -tinycolor.mostReadable = function(baseColor, colorList, args) { - var bestColor = null; - var bestScore = 0; - var readability; - var includeFallbackColors, level, size ; - args = args || {}; - includeFallbackColors = args.includeFallbackColors ; - level = args.level; - size = args.size; - - for (var i= 0; i < colorList.length ; i++) { - readability = tinycolor.readability(baseColor, colorList[i]); - if (readability > bestScore) { - bestScore = readability; - bestColor = tinycolor(colorList[i]); - } - } - - if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) { - return bestColor; - } - else { - args.includeFallbackColors=false; - return tinycolor.mostReadable(baseColor,["#fff", "#000"],args); - } -}; - -// Big List of Colors -// ------------------ -// -var names = tinycolor.names = { - aliceblue: "f0f8ff", - antiquewhite: "faebd7", - aqua: "0ff", - aquamarine: "7fffd4", - azure: "f0ffff", - beige: "f5f5dc", - bisque: "ffe4c4", - black: "000", - blanchedalmond: "ffebcd", - blue: "00f", - blueviolet: "8a2be2", - brown: "a52a2a", - burlywood: "deb887", - burntsienna: "ea7e5d", - cadetblue: "5f9ea0", - chartreuse: "7fff00", - chocolate: "d2691e", - coral: "ff7f50", - cornflowerblue: "6495ed", - cornsilk: "fff8dc", - crimson: "dc143c", - cyan: "0ff", - darkblue: "00008b", - darkcyan: "008b8b", - darkgoldenrod: "b8860b", - darkgray: "a9a9a9", - darkgreen: "006400", - darkgrey: "a9a9a9", - darkkhaki: "bdb76b", - darkmagenta: "8b008b", - darkolivegreen: "556b2f", - darkorange: "ff8c00", - darkorchid: "9932cc", - darkred: "8b0000", - darksalmon: "e9967a", - darkseagreen: "8fbc8f", - darkslateblue: "483d8b", - darkslategray: "2f4f4f", - darkslategrey: "2f4f4f", - darkturquoise: "00ced1", - darkviolet: "9400d3", - deeppink: "ff1493", - deepskyblue: "00bfff", - dimgray: "696969", - dimgrey: "696969", - dodgerblue: "1e90ff", - firebrick: "b22222", - floralwhite: "fffaf0", - forestgreen: "228b22", - fuchsia: "f0f", - gainsboro: "dcdcdc", - ghostwhite: "f8f8ff", - gold: "ffd700", - goldenrod: "daa520", - gray: "808080", - green: "008000", - greenyellow: "adff2f", - grey: "808080", - honeydew: "f0fff0", - hotpink: "ff69b4", - indianred: "cd5c5c", - indigo: "4b0082", - ivory: "fffff0", - khaki: "f0e68c", - lavender: "e6e6fa", - lavenderblush: "fff0f5", - lawngreen: "7cfc00", - lemonchiffon: "fffacd", - lightblue: "add8e6", - lightcoral: "f08080", - lightcyan: "e0ffff", - lightgoldenrodyellow: "fafad2", - lightgray: "d3d3d3", - lightgreen: "90ee90", - lightgrey: "d3d3d3", - lightpink: "ffb6c1", - lightsalmon: "ffa07a", - lightseagreen: "20b2aa", - lightskyblue: "87cefa", - lightslategray: "789", - lightslategrey: "789", - lightsteelblue: "b0c4de", - lightyellow: "ffffe0", - lime: "0f0", - limegreen: "32cd32", - linen: "faf0e6", - magenta: "f0f", - maroon: "800000", - mediumaquamarine: "66cdaa", - mediumblue: "0000cd", - mediumorchid: "ba55d3", - mediumpurple: "9370db", - mediumseagreen: "3cb371", - mediumslateblue: "7b68ee", - mediumspringgreen: "00fa9a", - mediumturquoise: "48d1cc", - mediumvioletred: "c71585", - midnightblue: "191970", - mintcream: "f5fffa", - mistyrose: "ffe4e1", - moccasin: "ffe4b5", - navajowhite: "ffdead", - navy: "000080", - oldlace: "fdf5e6", - olive: "808000", - olivedrab: "6b8e23", - orange: "ffa500", - orangered: "ff4500", - orchid: "da70d6", - palegoldenrod: "eee8aa", - palegreen: "98fb98", - paleturquoise: "afeeee", - palevioletred: "db7093", - papayawhip: "ffefd5", - peachpuff: "ffdab9", - peru: "cd853f", - pink: "ffc0cb", - plum: "dda0dd", - powderblue: "b0e0e6", - purple: "800080", - rebeccapurple: "663399", - red: "f00", - rosybrown: "bc8f8f", - royalblue: "4169e1", - saddlebrown: "8b4513", - salmon: "fa8072", - sandybrown: "f4a460", - seagreen: "2e8b57", - seashell: "fff5ee", - sienna: "a0522d", - silver: "c0c0c0", - skyblue: "87ceeb", - slateblue: "6a5acd", - slategray: "708090", - slategrey: "708090", - snow: "fffafa", - springgreen: "00ff7f", - steelblue: "4682b4", - tan: "d2b48c", - teal: "008080", - thistle: "d8bfd8", - tomato: "ff6347", - turquoise: "40e0d0", - violet: "ee82ee", - wheat: "f5deb3", - white: "fff", - whitesmoke: "f5f5f5", - yellow: "ff0", - yellowgreen: "9acd32" -}; - -// Make it easy to access colors via hexNames[hex] -var hexNames = tinycolor.hexNames = flip(names); - -// Utilities -// --------- - -// { 'name1': 'val1' } becomes { 'val1': 'name1' } -function flip(o) { - var flipped = { }; - for (var i in o) { - if (o.hasOwnProperty(i)) { - flipped[o[i]] = i; - } - } - return flipped; -} - -// Return a valid alpha value [0,1] with all invalid values being set to 1 -function boundAlpha(a) { - a = parseFloat(a); - - if (isNaN(a) || a < 0 || a > 1) { - a = 1; - } - - return a; -} - -// Take input from [0, n] and return it as [0, 1] -function bound01(n, max) { - if (isOnePointZero(n)) { n = "100%"; } - - var processPercent = isPercentage(n); - n = mathMin(max, mathMax(0, parseFloat(n))); - - // Automatically convert percentage into number - if (processPercent) { - n = parseInt(n * max, 10) / 100; - } - - // Handle floating point rounding errors - if ((Math.abs(n - max) < 0.000001)) { - return 1; - } - - // Convert into [0, 1] range if it isn't already - return (n % max) / parseFloat(max); -} - -// Force a number between 0 and 1 -function clamp01(val) { - return mathMin(1, mathMax(0, val)); -} - -// Parse a base-16 hex value into a base-10 integer -function parseIntFromHex(val) { - return parseInt(val, 16); -} - -// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 -// -function isOnePointZero(n) { - return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1; -} - -// Check to see if string passed in is a percentage -function isPercentage(n) { - return typeof n === "string" && n.indexOf('%') != -1; -} - -// Force a hex value to have 2 characters -function pad2(c) { - return c.length == 1 ? '0' + c : '' + c; -} - -// Replace a decimal with it's percentage value -function convertToPercentage(n) { - if (n <= 1) { - n = (n * 100) + "%"; - } - - return n; -} - -// Converts a decimal to a hex value -function convertDecimalToHex(d) { - return Math.round(parseFloat(d) * 255).toString(16); -} -// Converts a hex value to a decimal -function convertHexToDecimal(h) { - return (parseIntFromHex(h) / 255); -} - -var matchers = (function() { - - // - var CSS_INTEGER = "[-\\+]?\\d+%?"; - - // - var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; - - // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. - var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; - - // Actual matching. - // Parentheses and commas are optional, but not required. - // Whitespace can take the place of commas or opening paren - var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - - return { - CSS_UNIT: new RegExp(CSS_UNIT), - rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), - rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), - hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), - hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), - hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), - hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), - hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, - hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ - }; -})(); - -// isValidCSSUnit -// Take in a single string / number and check to see if it looks like a CSS unit -// (see matchers above for definition). -function isValidCSSUnit(color) { - return !!matchers.CSS_UNIT.exec(color); -} - -// stringInputToObject -// Permissive string parsing. Take in a number of formats, and output an object -// based on detected format. Returns { r, g, b } or { h, s, l } or { h, s, v} -function stringInputToObject(color) { - - color = color.replace(trimLeft, '').replace(trimRight, '').toLowerCase(); - var named = false; - if (names[color]) { - color = names[color]; - named = true; - } - else if (color == 'transparent') { - return { r: 0, g: 0, b: 0, a: 0, format: "name" }; - } - - // Try to match string input using regular expressions. - // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] - // Just return an object and let the conversion functions handle that. - // This way the result will be the same whether the tinycolor is initialized with string or object. - var match; - if ((match = matchers.rgb.exec(color))) { - return { r: match[1], g: match[2], b: match[3] }; - } - if ((match = matchers.rgba.exec(color))) { - return { r: match[1], g: match[2], b: match[3], a: match[4] }; - } - if ((match = matchers.hsl.exec(color))) { - return { h: match[1], s: match[2], l: match[3] }; - } - if ((match = matchers.hsla.exec(color))) { - return { h: match[1], s: match[2], l: match[3], a: match[4] }; - } - if ((match = matchers.hsv.exec(color))) { - return { h: match[1], s: match[2], v: match[3] }; - } - if ((match = matchers.hsva.exec(color))) { - return { h: match[1], s: match[2], v: match[3], a: match[4] }; - } - if ((match = matchers.hex8.exec(color))) { - return { - r: parseIntFromHex(match[1]), - g: parseIntFromHex(match[2]), - b: parseIntFromHex(match[3]), - a: convertHexToDecimal(match[4]), - format: named ? "name" : "hex8" - }; - } - if ((match = matchers.hex6.exec(color))) { - return { - r: parseIntFromHex(match[1]), - g: parseIntFromHex(match[2]), - b: parseIntFromHex(match[3]), - format: named ? "name" : "hex" - }; - } - if ((match = matchers.hex4.exec(color))) { - return { - r: parseIntFromHex(match[1] + '' + match[1]), - g: parseIntFromHex(match[2] + '' + match[2]), - b: parseIntFromHex(match[3] + '' + match[3]), - a: convertHexToDecimal(match[4] + '' + match[4]), - format: named ? "name" : "hex8" - }; - } - if ((match = matchers.hex3.exec(color))) { - return { - r: parseIntFromHex(match[1] + '' + match[1]), - g: parseIntFromHex(match[2] + '' + match[2]), - b: parseIntFromHex(match[3] + '' + match[3]), - format: named ? "name" : "hex" - }; - } - - return false; -} - -function validateWCAG2Parms(parms) { - // return valid WCAG2 parms for isReadable. - // If input parms are invalid, return {"level":"AA", "size":"small"} - var level, size; - parms = parms || {"level":"AA", "size":"small"}; - level = (parms.level || "AA").toUpperCase(); - size = (parms.size || "small").toLowerCase(); - if (level !== "AA" && level !== "AAA") { - level = "AA"; - } - if (size !== "small" && size !== "large") { - size = "small"; - } - return {"level":level, "size":size}; -} - -this.tinycolor = tinycolor; - -})()`; -} -// It is hacky way to make this function will be compiled preferentially by less -// resolve error: `ReferenceError: colorPalette is not defined` -// https://github.com/ant-design/ant-motion/issues/44 -.tinyColorMixin(); - -// We create a very complex algorithm which take the place of original tint/shade color system -// to make sure no one can understand it 👻 -// and create an entire color palette magicly by inputing just a single primary color. -// We are using bezier-curve easing function and some color manipulations like tint/shade/darken/spin -.colorPaletteMixin() { -@functions: ~`(function() { - var hueStep = 2; - var saturationStep = 16; - var saturationStep2 = 5; - var brightnessStep1 = 5; - var brightnessStep2 = 15; - var lightColorCount = 5; - var darkColorCount = 4; - - var getHue = function(hsv, i, isLight) { - var hue; - if (hsv.h >= 60 && hsv.h <= 240) { - hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i; - } else { - hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i; - } - if (hue < 0) { - hue += 360; - } else if (hue >= 360) { - hue -= 360; - } - return Math.round(hue); - }; - var getSaturation = function(hsv, i, isLight) { - var saturation; - if (isLight) { - saturation = Math.round(hsv.s * 100) - saturationStep * i; - } else if (i == darkColorCount) { - saturation = Math.round(hsv.s * 100) + saturationStep; - } else { - saturation = Math.round(hsv.s * 100) + saturationStep2 * i; - } - if (saturation > 100) { - saturation = 100; - } - if (isLight && i === lightColorCount && saturation > 10) { - saturation = 10; - } - if (saturation < 6) { - saturation = 6; - } - return Math.round(saturation); - }; - var getValue = function(hsv, i, isLight) { - if (isLight) { - return Math.round(hsv.v * 100) + brightnessStep1 * i; - } - return Math.round(hsv.v * 100) - brightnessStep2 * i; - }; - - this.colorPalette = function(color, index) { - var isLight = index <= 6; - var hsv = tinycolor(color).toHsv(); - var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1; - return tinycolor({ - h: getHue(hsv, i, isLight), - s: getSaturation(hsv, i, isLight), - v: getValue(hsv, i, isLight), - }).toHexString(); - }; -})()`; -} -// It is hacky way to make this function will be compiled preferentially by less -// resolve error: `ReferenceError: colorPalette is not defined` -// https://github.com/ant-design/ant-motion/issues/44 -.colorPaletteMixin(); - -// color palettes -@blue-1: color(~`colorPalette('@{blue-6}', 1) `); -@blue-2: color(~`colorPalette('@{blue-6}', 2) `); -@blue-3: color(~`colorPalette('@{blue-6}', 3) `); -@blue-4: color(~`colorPalette('@{blue-6}', 4) `); -@blue-5: color(~`colorPalette('@{blue-6}', 5) `); -@blue-6: #1890ff; -@blue-7: color(~`colorPalette('@{blue-6}', 7) `); -@blue-8: color(~`colorPalette('@{blue-6}', 8) `); -@blue-9: color(~`colorPalette('@{blue-6}', 9) `); -@blue-10: color(~`colorPalette('@{blue-6}', 10) `); - -@purple-1: color(~`colorPalette('@{purple-6}', 1) `); -@purple-2: color(~`colorPalette('@{purple-6}', 2) `); -@purple-3: color(~`colorPalette('@{purple-6}', 3) `); -@purple-4: color(~`colorPalette('@{purple-6}', 4) `); -@purple-5: color(~`colorPalette('@{purple-6}', 5) `); -@purple-6: #722ed1; -@purple-7: color(~`colorPalette('@{purple-6}', 7) `); -@purple-8: color(~`colorPalette('@{purple-6}', 8) `); -@purple-9: color(~`colorPalette('@{purple-6}', 9) `); -@purple-10: color(~`colorPalette('@{purple-6}', 10) `); - -@cyan-1: color(~`colorPalette('@{cyan-6}', 1) `); -@cyan-2: color(~`colorPalette('@{cyan-6}', 2) `); -@cyan-3: color(~`colorPalette('@{cyan-6}', 3) `); -@cyan-4: color(~`colorPalette('@{cyan-6}', 4) `); -@cyan-5: color(~`colorPalette('@{cyan-6}', 5) `); -@cyan-6: #13c2c2; -@cyan-7: color(~`colorPalette('@{cyan-6}', 7) `); -@cyan-8: color(~`colorPalette('@{cyan-6}', 8) `); -@cyan-9: color(~`colorPalette('@{cyan-6}', 9) `); -@cyan-10: color(~`colorPalette('@{cyan-6}', 10) `); - -@green-1: color(~`colorPalette('@{green-6}', 1) `); -@green-2: color(~`colorPalette('@{green-6}', 2) `); -@green-3: color(~`colorPalette('@{green-6}', 3) `); -@green-4: color(~`colorPalette('@{green-6}', 4) `); -@green-5: color(~`colorPalette('@{green-6}', 5) `); -@green-6: #52c41a; -@green-7: color(~`colorPalette('@{green-6}', 7) `); -@green-8: color(~`colorPalette('@{green-6}', 8) `); -@green-9: color(~`colorPalette('@{green-6}', 9) `); -@green-10: color(~`colorPalette('@{green-6}', 10) `); - -@magenta-1: color(~`colorPalette('@{magenta-6}', 1) `); -@magenta-2: color(~`colorPalette('@{magenta-6}', 2) `); -@magenta-3: color(~`colorPalette('@{magenta-6}', 3) `); -@magenta-4: color(~`colorPalette('@{magenta-6}', 4) `); -@magenta-5: color(~`colorPalette('@{magenta-6}', 5) `); -@magenta-6: #eb2f96; -@magenta-7: color(~`colorPalette('@{magenta-6}', 7) `); -@magenta-8: color(~`colorPalette('@{magenta-6}', 8) `); -@magenta-9: color(~`colorPalette('@{magenta-6}', 9) `); -@magenta-10: color(~`colorPalette('@{magenta-6}', 10) `); - -// alias of magenta -@pink-1: color(~`colorPalette('@{pink-6}', 1) `); -@pink-2: color(~`colorPalette('@{pink-6}', 2) `); -@pink-3: color(~`colorPalette('@{pink-6}', 3) `); -@pink-4: color(~`colorPalette('@{pink-6}', 4) `); -@pink-5: color(~`colorPalette('@{pink-6}', 5) `); -@pink-6: #eb2f96; -@pink-7: color(~`colorPalette('@{pink-6}', 7) `); -@pink-8: color(~`colorPalette('@{pink-6}', 8) `); -@pink-9: color(~`colorPalette('@{pink-6}', 9) `); -@pink-10: color(~`colorPalette('@{pink-6}', 10) `); - -@red-1: color(~`colorPalette('@{red-6}', 1) `); -@red-2: color(~`colorPalette('@{red-6}', 2) `); -@red-3: color(~`colorPalette('@{red-6}', 3) `); -@red-4: color(~`colorPalette('@{red-6}', 4) `); -@red-5: color(~`colorPalette('@{red-6}', 5) `); -@red-6: #f5222d; -@red-7: color(~`colorPalette('@{red-6}', 7) `); -@red-8: color(~`colorPalette('@{red-6}', 8) `); -@red-9: color(~`colorPalette('@{red-6}', 9) `); -@red-10: color(~`colorPalette('@{red-6}', 10) `); - -@orange-1: color(~`colorPalette('@{orange-6}', 1) `); -@orange-2: color(~`colorPalette('@{orange-6}', 2) `); -@orange-3: color(~`colorPalette('@{orange-6}', 3) `); -@orange-4: color(~`colorPalette('@{orange-6}', 4) `); -@orange-5: color(~`colorPalette('@{orange-6}', 5) `); -@orange-6: #fa8c16; -@orange-7: color(~`colorPalette('@{orange-6}', 7) `); -@orange-8: color(~`colorPalette('@{orange-6}', 8) `); -@orange-9: color(~`colorPalette('@{orange-6}', 9) `); -@orange-10: color(~`colorPalette('@{orange-6}', 10) `); - -@yellow-1: color(~`colorPalette('@{yellow-6}', 1) `); -@yellow-2: color(~`colorPalette('@{yellow-6}', 2) `); -@yellow-3: color(~`colorPalette('@{yellow-6}', 3) `); -@yellow-4: color(~`colorPalette('@{yellow-6}', 4) `); -@yellow-5: color(~`colorPalette('@{yellow-6}', 5) `); -@yellow-6: #fadb14; -@yellow-7: color(~`colorPalette('@{yellow-6}', 7) `); -@yellow-8: color(~`colorPalette('@{yellow-6}', 8) `); -@yellow-9: color(~`colorPalette('@{yellow-6}', 9) `); -@yellow-10: color(~`colorPalette('@{yellow-6}', 10) `); - -@volcano-1: color(~`colorPalette('@{volcano-6}', 1) `); -@volcano-2: color(~`colorPalette('@{volcano-6}', 2) `); -@volcano-3: color(~`colorPalette('@{volcano-6}', 3) `); -@volcano-4: color(~`colorPalette('@{volcano-6}', 4) `); -@volcano-5: color(~`colorPalette('@{volcano-6}', 5) `); -@volcano-6: #fa541c; -@volcano-7: color(~`colorPalette('@{volcano-6}', 7) `); -@volcano-8: color(~`colorPalette('@{volcano-6}', 8) `); -@volcano-9: color(~`colorPalette('@{volcano-6}', 9) `); -@volcano-10: color(~`colorPalette('@{volcano-6}', 10) `); - -@geekblue-1: color(~`colorPalette('@{geekblue-6}', 1) `); -@geekblue-2: color(~`colorPalette('@{geekblue-6}', 2) `); -@geekblue-3: color(~`colorPalette('@{geekblue-6}', 3) `); -@geekblue-4: color(~`colorPalette('@{geekblue-6}', 4) `); -@geekblue-5: color(~`colorPalette('@{geekblue-6}', 5) `); -@geekblue-6: #2f54eb; -@geekblue-7: color(~`colorPalette('@{geekblue-6}', 7) `); -@geekblue-8: color(~`colorPalette('@{geekblue-6}', 8) `); -@geekblue-9: color(~`colorPalette('@{geekblue-6}', 9) `); -@geekblue-10: color(~`colorPalette('@{geekblue-6}', 10) `); - -@lime-1: color(~`colorPalette('@{lime-6}', 1) `); -@lime-2: color(~`colorPalette('@{lime-6}', 2) `); -@lime-3: color(~`colorPalette('@{lime-6}', 3) `); -@lime-4: color(~`colorPalette('@{lime-6}', 4) `); -@lime-5: color(~`colorPalette('@{lime-6}', 5) `); -@lime-6: #a0d911; -@lime-7: color(~`colorPalette('@{lime-6}', 7) `); -@lime-8: color(~`colorPalette('@{lime-6}', 8) `); -@lime-9: color(~`colorPalette('@{lime-6}', 9) `); -@lime-10: color(~`colorPalette('@{lime-6}', 10) `); - -@gold-1: color(~`colorPalette('@{gold-6}', 1) `); -@gold-2: color(~`colorPalette('@{gold-6}', 2) `); -@gold-3: color(~`colorPalette('@{gold-6}', 3) `); -@gold-4: color(~`colorPalette('@{gold-6}', 4) `); -@gold-5: color(~`colorPalette('@{gold-6}', 5) `); -@gold-6: #faad14; -@gold-7: color(~`colorPalette('@{gold-6}', 7) `); -@gold-8: color(~`colorPalette('@{gold-6}', 8) `); -@gold-9: color(~`colorPalette('@{gold-6}', 9) `); -@gold-10: color(~`colorPalette('@{gold-6}', 10) `); - -// The prefix to use on all css classes from ant. -@ant-prefix : ant; - -// -------- Colors ----------- -@primary-color : @blue-6; -@info-color : @blue-6; -@success-color : @green-6; -@processing-color : @blue-6; -@error-color : @red-6; -@highlight-color : @red-6; -@warning-color : @gold-6; -@normal-color : #d9d9d9; - -// Color used by default to control hover and active backgrounds and for -// alert info backgrounds. -@primary-1: color(~`colorPalette('@{primary-color}', 1) `); // replace tint(@primary-color, 90%) -@primary-2: color(~`colorPalette('@{primary-color}', 2) `); // replace tint(@primary-color, 80%) -@primary-3: color(~`colorPalette('@{primary-color}', 3) `); // unused -@primary-4: color(~`colorPalette('@{primary-color}', 4) `); // unused -@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%) -@primary-6: @primary-color; // color used to control the text color of active buttons, don't use, use @primary-color -@primary-7: color(~`colorPalette('@{primary-color}', 7) `); // replace shade(@primary-color, 5%) -@primary-8: color(~`colorPalette('@{primary-color}', 8) `); // unused -@primary-9: color(~`colorPalette('@{primary-color}', 9) `); // unused -@primary-10: color(~`colorPalette('@{primary-color}', 10) `); // unused - -// Base Scaffolding Variables -// --- - -// Background color for `` -@body-background : #fff; -// Base background color for most components -@component-background : #fff; -@font-family : "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, -"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; -@code-family : "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; -@heading-color : fade(#000, 85%); -@text-color : fade(#000, 65%); -@text-color-secondary : fade(#000, 45%); -@heading-color-dark : fade(#fff, 100%); -@text-color-dark : fade(#fff, 85%); -@text-color-secondary-dark: fade(#fff, 65%); -@font-variant-base : tabular-nums; -@font-size-base : 14px; -@font-size-lg : @font-size-base + 2px; -@font-size-sm : 12px; -@line-height-base : 1.5; -@border-radius-base : 4px; -@border-radius-sm : 2px; - -// vertical paddings -@padding-lg : 24px; // containers -@padding-md : 16px; // small containers and buttons -@padding-sm : 12px; // Form controls and items -@padding-xs : 8px; // small items - -// vertical padding for all form controls -@control-padding-horizontal: @padding-sm; -@control-padding-horizontal-sm: @padding-xs; - -// The background colors for active and hover states for things like -// list items or table cells. -@item-active-bg : @primary-1; -@item-hover-bg : @primary-1; - -// ICONFONT -@iconfont-css-prefix : anticon; - -// LINK -@link-color : @primary-color; -@link-hover-color : color(~`colorPalette("@{link-color}", 5)`); -@link-active-color : color(~`colorPalette("@{link-color}", 7)`); -@link-decoration : none; -@link-hover-decoration : none; - -// Animation -@ease-base-out : cubic-bezier(0.7, 0.3, 0.1, 1); -@ease-base-in : cubic-bezier(0.9, 0, 0.3, 0.7); -@ease-out : cubic-bezier(0.215, 0.61, 0.355, 1); -@ease-in : cubic-bezier(0.55, 0.055, 0.675, 0.19); -@ease-in-out : cubic-bezier(0.645, 0.045, 0.355, 1); -@ease-out-back : cubic-bezier(0.12, 0.4, 0.29, 1.46); -@ease-in-back : cubic-bezier(0.71, -0.46, 0.88, 0.6); -@ease-in-out-back : cubic-bezier(0.71, -0.46, 0.29, 1.46); -@ease-out-circ : cubic-bezier(0.08, 0.82, 0.17, 1); -@ease-in-circ : cubic-bezier(0.6, 0.04, 0.98, 0.34); -@ease-in-out-circ : cubic-bezier(0.78, 0.14, 0.15, 0.86); -@ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1); -@ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06); -@ease-in-out-quint : cubic-bezier(0.86, 0, 0.07, 1); - -// Border color -@border-color-base : hsv(0, 0, 85%); // base border outline a component -@border-color-split : hsv(0, 0, 91%); // split border inside a component -@border-width-base : 1px; // width of the border for a component -@border-style-base : solid; // style of a components border - -// Outline -@outline-blur-size : 0; -@outline-width : 2px; -@outline-color : @primary-color; - -@background-color-light : hsv(0, 0, 98%); // background of header and selected item -@background-color-base : hsv(0, 0, 96%); // Default grey background color - -// Disabled states -@disabled-color : fade(#000, 25%); -@disabled-bg : @background-color-base; -@disabled-color-dark : fade(#fff, 35%); - -// Shadow -@shadow-color : rgba(0, 0, 0, .15); -@box-shadow-base : @shadow-1-down; -@shadow-1-up : 0 -2px 8px @shadow-color; -@shadow-1-down : 0 2px 8px @shadow-color; -@shadow-1-left : -2px 0 8px @shadow-color; -@shadow-1-right : 2px 0 8px @shadow-color; -@shadow-2 : 0 4px 12px @shadow-color; - -// Buttons -@btn-font-weight : 400; -@btn-border-radius-base : @border-radius-base; -@btn-border-radius-sm : @border-radius-base; - -@btn-primary-color : #fff; -@btn-primary-bg : @primary-color; - -@btn-default-color : @text-color; -@btn-default-bg : #fff; -@btn-default-border : @border-color-base; - -@btn-danger-color : @error-color; -@btn-danger-bg : @background-color-base; -@btn-danger-border : @border-color-base; - -@btn-disable-color : @disabled-color; -@btn-disable-bg : @disabled-bg; -@btn-disable-border : @border-color-base; - -@btn-padding-base : 0 @padding-md - 1px; -@btn-font-size-lg : @font-size-lg; -@btn-font-size-sm : @font-size-base; -@btn-padding-lg : @btn-padding-base; -@btn-padding-sm : 0 @padding-xs - 1px; - -@btn-height-base : 32px; -@btn-height-lg : 40px; -@btn-height-sm : 24px; - -@btn-circle-size : @btn-height-base; -@btn-circle-size-lg : @btn-height-lg; -@btn-circle-size-sm : @btn-height-sm; - -@btn-group-border : @primary-5; - -// Checkbox -@checkbox-size : 16px; -@checkbox-color : @primary-color; -@checkbox-check-color : #fff; -@checkbox-border-width : @border-width-base; - -// Radio -@radio-size : 16px; -@radio-dot-color : @primary-color; - -// Radio buttons -@radio-button-bg : @btn-default-bg; -@radio-button-color : @btn-default-color; -@radio-button-hover-color : @primary-5; -@radio-button-active-color : @primary-7; - -// Media queries breakpoints -// Extra small screen / phone -@screen-xs : 480px; -@screen-xs-min : @screen-xs; - -// Small screen / tablet -@screen-sm : 576px; -@screen-sm-min : @screen-sm; - -// Medium screen / desktop -@screen-md : 768px; -@screen-md-min : @screen-md; - -// Large screen / wide desktop -@screen-lg : 992px; -@screen-lg-min : @screen-lg; - -// Extra large screen / full hd -@screen-xl : 1200px; -@screen-xl-min : @screen-xl; - -// Extra extra large screen / large descktop -@screen-xxl : 1600px; -@screen-xxl-min : @screen-xxl; - -// provide a maximum -@screen-xs-max : (@screen-sm-min - 1px); -@screen-sm-max : (@screen-md-min - 1px); -@screen-md-max : (@screen-lg-min - 1px); -@screen-lg-max : (@screen-xl-min - 1px); -@screen-xl-max : (@screen-xxl-min - 1px); - -// Grid system -@grid-columns : 24; -@grid-gutter-width : 0; - -// Layout -@layout-body-background : #f0f2f5; -@layout-header-background : #001529; -@layout-footer-background : @layout-body-background; -@layout-header-height : 64px; -@layout-header-padding : 0 50px; -@layout-footer-padding : 24px 50px; -@layout-sider-background : @layout-header-background; -@layout-trigger-height : 48px; -@layout-trigger-background : #002140; -@layout-trigger-color : #fff; -@layout-zero-trigger-width : 36px; -@layout-zero-trigger-height : 42px; -// Layout light theme -@layout-sider-background-light : #fff; -@layout-trigger-background-light: #fff; -@layout-trigger-color-light : @text-color; - -// z-index list -@zindex-affix : 10; -@zindex-back-top : 10; -@zindex-modal-mask : 1000; -@zindex-modal : 1000; -@zindex-notification : 1010; -@zindex-message : 1010; -@zindex-popover : 1030; -@zindex-picker : 1050; -@zindex-dropdown : 1050; -@zindex-tooltip : 1060; - -// Animation -@animation-duration-slow: 0.3s; // Modal -@animation-duration-base: 0.2s; -@animation-duration-fast: 0.1s; // Tooltip - -// Form -// --- -@label-required-color : @highlight-color; -@label-color : @heading-color; -@form-item-margin-bottom : 24px; -@form-item-trailing-colon : true; -@form-vertical-label-padding : 0 0 8px; -@form-vertical-label-margin : 0; - -// Input -// --- -@input-height-base : 32px; -@input-height-lg : 40px; -@input-height-sm : 24px; -@input-padding-horizontal : @control-padding-horizontal - 1px; -@input-padding-horizontal-base: @input-padding-horizontal; -@input-padding-horizontal-sm : @control-padding-horizontal-sm - 1px; -@input-padding-horizontal-lg : @input-padding-horizontal; -@input-padding-vertical-base : 4px; -@input-padding-vertical-sm : 1px; -@input-padding-vertical-lg : 6px; -@input-placeholder-color : hsv(0, 0, 75%); -@input-color : @text-color; -@input-border-color : @border-color-base; -@input-bg : #fff; -@input-addon-bg : @background-color-light; -@input-hover-border-color : @primary-color; -@input-disabled-bg : @disabled-bg; -@input-outline-offset : 0 0; - -// Tooltip -// --- -//* Tooltip max width -@tooltip-max-width: 250px; -//** Tooltip text color -@tooltip-color: #fff; -//** Tooltip background color -@tooltip-bg: rgba(0, 0, 0, 0.75); -//** Tooltip arrow width -@tooltip-arrow-width: 5px; -//** Tooltip distance with trigger -@tooltip-distance: @tooltip-arrow-width - 1px + 4px; -//** Tooltip arrow color -@tooltip-arrow-color: @tooltip-bg; - -// Popover -// --- -//** Popover body background color -@popover-bg: #fff; -//** Popover text color -@popover-color: @text-color; -//** Popover maximum width -@popover-min-width: 177px; -//** Popover arrow width -@popover-arrow-width: 6px; -//** Popover arrow color -@popover-arrow-color: @popover-bg; -//** Popover outer arrow width -//** Popover outer arrow color -@popover-arrow-outer-color: @popover-bg; -//** Popover distance with trigger -@popover-distance: @popover-arrow-width + 4px; - -// Modal -// -- -@modal-header-bg: @component-background; -@modal-mask-bg: rgba(0, 0, 0, 0.65); - -// Progress -// -- -@progress-default-color: @processing-color; -@progress-remaining-color: @background-color-base; -@progress-text-color: @text-color; - -// Menu -// --- -@menu-inline-toplevel-item-height: 40px; -@menu-item-height: 40px; -@menu-collapsed-width: 80px; -@menu-bg: @component-background; -@menu-popup-bg: @component-background; -@menu-item-color: @text-color; -@menu-highlight-color: @primary-color; -@menu-item-active-bg: @item-active-bg; -@menu-item-active-border-width: 3px; -@menu-item-group-title-color: @text-color-secondary; -// dark theme -@menu-dark-color: @text-color-secondary-dark; -@menu-dark-bg: @layout-header-background; -@menu-dark-arrow-color: #fff; -@menu-dark-submenu-bg: #000c17; -@menu-dark-highlight-color: #fff; -@menu-dark-item-active-bg: @primary-color; - -// Spin -// --- -@spin-dot-size-sm: 14px; -@spin-dot-size: 20px; -@spin-dot-size-lg: 32px; - -// Table -// -- -@table-header-bg: @background-color-light; -@table-header-color: @heading-color; -@table-header-sort-bg: @background-color-base; -@table-body-sort-bg: rgba(0, 0, 0, 0.01); -@table-row-hover-bg: @primary-1; -@table-selected-row-bg: #fafafa; -@table-expanded-row-bg: #fbfbfb; -@table-padding-vertical: 16px; -@table-padding-horizontal: 16px; -@table-border-radius-base : @border-radius-base; - -// Tag -// -- -@tag-default-bg: @background-color-light; -@tag-default-color: @text-color; -@tag-font-size: @font-size-sm; - -// TimePicker -// --- -@time-picker-panel-column-width: 56px; -@time-picker-panel-width: @time-picker-panel-column-width * 3; -@time-picker-selected-bg: @background-color-base; - -// Carousel -// --- -@carousel-dot-width: 16px; -@carousel-dot-height: 3px; -@carousel-dot-active-width: 24px; - -// Badge -// --- -@badge-height: 20px; -@badge-dot-size: 6px; -@badge-font-size: @font-size-sm; -@badge-font-weight: normal; -@badge-status-size: 6px; - -// Rate -// --- -@rate-star-color: @yellow-6; -@rate-star-bg: @border-color-split; - -// Card -// --- -@card-head-color: @heading-color; -@card-head-background: transparent; -@card-head-padding: 16px; -@card-inner-head-padding: 12px; -@card-padding-base: 24px; -@card-padding-wider: 32px; -@card-actions-background: @background-color-light; -@card-shadow: 0 2px 8px rgba(0, 0, 0, 0.09); - -// Comment -// --- -@comment-padding-base: 16px 0; -@comment-nest-indent: 44px; -@comment-author-name-color: @text-color-secondary; -@comment-author-time-color: #ccc; -@comment-action-color: @text-color-secondary; -@comment-action-hover-color: #595959; - -// Tabs -// --- -@tabs-card-head-background: @background-color-light; -@tabs-card-height: 40px; -@tabs-card-active-color: @primary-color; -@tabs-title-font-size: @font-size-base; -@tabs-title-font-size-lg: @font-size-lg; -@tabs-title-font-size-sm: @font-size-base; -@tabs-ink-bar-color: @primary-color; -@tabs-bar-margin: 0 0 16px 0; -@tabs-horizontal-margin: 0 32px 0 0; -@tabs-horizontal-padding: 12px 16px; -@tabs-horizontal-padding-lg: 16px; -@tabs-horizontal-padding-sm: 8px 16px; -@tabs-vertical-padding: 8px 24px; -@tabs-vertical-margin: 0 0 16px 0; -@tabs-scrolling-size: 32px; -@tabs-highlight-color: @primary-color; -@tabs-hover-color: @primary-5; -@tabs-active-color: @primary-7; - -// BackTop -// --- -@back-top-color: #fff; -@back-top-bg: @text-color-secondary; -@back-top-hover-bg: @text-color; - -// Avatar -// --- -@avatar-size-base: 32px; -@avatar-size-lg: 40px; -@avatar-size-sm: 24px; -@avatar-font-size-base: 18px; -@avatar-font-size-lg: 24px; -@avatar-font-size-sm: 14px; -@avatar-bg: #ccc; -@avatar-color: #fff; -@avatar-border-radius: @border-radius-base; - -// Switch -// --- -@switch-height: 22px; -@switch-sm-height: 16px; -@switch-sm-checked-margin-left: -(@switch-sm-height - 3px); -@switch-disabled-opacity: 0.4; -@switch-color: @primary-color; - -// Pagination -// --- -@pagination-item-size: 32px; -@pagination-item-size-sm: 24px; -@pagination-font-family: Arial; -@pagination-font-weight-active: 500; - -// Breadcrumb -// --- -@breadcrumb-base-color: @text-color-secondary; -@breadcrumb-last-item-color: @text-color; -@breadcrumb-font-size: @font-size-base; -@breadcrumb-icon-font-size: @font-size-base; -@breadcrumb-link-color: @text-color-secondary; -@breadcrumb-link-color-hover: @primary-5; -@breadcrumb-separator-color: @text-color-secondary; -@breadcrumb-separator-margin: 0 @padding-xs; - -// Slider -// --- -@slider-margin: 14px 6px 10px; -@slider-rail-background-color: @background-color-base; -@slider-rail-background-color-hover: #e1e1e1; -@slider-track-background-color: @primary-5; -@slider-track-background-color-hover: @primary-6; -@slider-handle-color: @primary-5; -@slider-handle-color-hover: @primary-6; -@slider-handle-color-focus: tint(@primary-color, 20%); -@slider-handle-color-focus-shadow: fade(@primary-color, 20%); -@slider-handle-color-tooltip-open: @primary-color; -@slider-dot-border-color: @border-color-split; -@slider-dot-border-color-active: @primary-5; -@slider-disabled-color: @disabled-color; -@slider-disabled-background-color: @component-background; - -// Tree -// --- -@tree-title-height: 24px; -@tree-child-padding: 18px; -@tree-directory-selected-color: #fff; -@tree-directory-selected-bg: @primary-color; - -// Collapse -// --- -@collapse-header-padding: 12px 0 12px 40px; -@collapse-header-bg: @background-color-light; -@collapse-content-padding: @padding-md; -@collapse-content-bg: @component-background; - -// Skeleton -// --- -@skeleton-color: #f2f2f2; - -// Transfer -// --- -@transfer-disabled-bg: @disabled-bg; - -// Message -// --- -@message-notice-content-padding: 10px 16px; - -// Motion -// --- -@wave-animation-width: 6px; - -// Alert -// --- -@alert-success-border-color: ~`colorPalette('@{success-color}', 3) `; -@alert-success-bg-color: ~`colorPalette('@{success-color}', 1) `; -@alert-success-icon-color: @success-color; -@alert-info-border-color: ~`colorPalette('@{info-color}', 3) `; -@alert-info-bg-color: ~`colorPalette('@{info-color}', 1) `; -@alert-info-icon-color: @info-color; -@alert-warning-border-color: ~`colorPalette('@{warning-color}', 3) `; -@alert-warning-bg-color: ~`colorPalette('@{warning-color}', 1) `; -@alert-warning-icon-color: @warning-color; -@alert-error-border-color: ~`colorPalette('@{error-color}', 3) `; -@alert-error-bg-color: ~`colorPalette('@{error-color}', 1) `; -@alert-error-icon-color: @error-color; - -// List -// --- -@list-empty-text-padding: @padding-md; -@list-item-padding: @padding-sm 0; -@list-item-content-margin: 0 0 @padding-md 0; -@list-item-meta-margin-bottom: @padding-md; -@list-item-meta-avatar-margin-right: @padding-md; -@list-item-meta-title-margin-bottom: @padding-sm; - -// Mixins -// -------------------------------------------------- -// Sizing shortcuts - -.size(@width; @height) { - width: @width; - height: @height; -} - -.square(@size) { - .size(@size; @size); -} - -// Compatibility for browsers. - -// Placeholder text -.placeholder(@color: @input-placeholder-color) { - // Firefox - &::-moz-placeholder { - color: @color; - opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526 - } - // Internet Explorer 10+ - &:-ms-input-placeholder { - color: @color; - } - // Safari and Chrome - &::-webkit-input-placeholder { - color: @color; - } -} - -// mixins for clearfix -// ------------------------ -.clearfix() { - zoom: 1; - &:before, - &:after { - content: ''; - display: table; - } - &:after { - clear: both; - } -} - -.iconfont-mixin() { - display: inline-block; - font-style: normal; - vertical-align: -0.125em; // for SVG icon, see https://blog.prototypr.io/align-svg-icons-to-text-and-say-goodbye-to-font-icons-d44b3d7b26b4 - text-align: center; - text-transform: none; - line-height: 0; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - > * { - line-height: 1; - } - - svg { - display: inline-block; - } - - &:before { - display: none; // dont display old icon. - } - - & &-icon { - display: block; - } -} - -// for iconfont font size -// fix chrome 12px bug, support ie -.iconfont-size-under-12px(@size, @rotate: 0deg) { - display: inline-block; - @font-scale: unit(@size / 12px); - font-size: 12px; - // IE9 - font-size: ~'@{size} \9'; - transform: scale(@font-scale) rotate(@rotate); - :root & { - font-size: @font-size-sm; // reset IE9 and above - } -} - -.motion-common(@duration: @animation-duration-base) { - animation-duration: @duration; - animation-fill-mode: both; -} - -.motion-common-leave(@duration: @animation-duration-base) { - animation-duration: @duration; - animation-fill-mode: both; -} - -.make-motion(@className, @keyframeName, @duration: @animation-duration-base) { - .@{className}-enter, - .@{className}-appear { - .motion-common(@duration); - animation-play-state: paused; - } - .@{className}-leave { - .motion-common-leave(@duration); - animation-play-state: paused; - } - .@{className}-enter.@{className}-enter-active, - .@{className}-appear.@{className}-appear-active { - animation-name: ~'@{keyframeName}In'; - animation-play-state: running; - } - .@{className}-leave.@{className}-leave-active { - animation-name: ~'@{keyframeName}Out'; - animation-play-state: running; - pointer-events: none; - } -} - -.reset-component() { - font-family: @font-family; - font-size: @font-size-base; - font-variant: @font-variant-base; - line-height: @line-height-base; - color: @text-color; - box-sizing: border-box; - margin: 0; - padding: 0; - list-style: none; -} - -.text-truncate() { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.textOverflow() { - overflow: hidden; - text-overflow: ellipsis; - word-break: break-all; - white-space: nowrap; -} - -.textOverflowMulti(@line: 3, @bg: #fff) { - overflow: hidden; - position: relative; - line-height: 1.5em; - max-height: @line * 1.5em; - text-align: justify; - margin-right: -1em; - padding-right: 1em; - &:before { - background: @bg; - content: '...'; - padding: 0 1px; - position: absolute; - right: 14px; - bottom: 0; - } - &:after { - background: white; - content: ''; - margin-top: 0.2em; - position: absolute; - right: 14px; - width: 1em; - height: 1em; - } -} - -@white: #fff; -@black: #000; - -// grey -@grey-1: #ffffff; -@grey-2: #fafafa; -@grey-3: #f5f5f5; -@grey-4: #e8e8e8; -@grey-5: #d9d9d9; -@grey-6: #bfbfbf; -@grey-7: #8c8c8c; -@grey-8: #595959; -@grey-9: #262626; -@grey-10: #000000; - -@color-light-position: 2; -@color-basic-position: 3; -@color-dark-position: 4; -@color-no-list: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; - -@colors: - red @red-5 @red-6 @red-7, - volcano @volcano-5 @volcano-6 @volcano-7, - orange @orange-5 @orange-6 @orange-7, - gold @gold-5 @gold-6 @gold-7, - yellow @yellow-5 @yellow-6 @yellow-7, - lime @lime-5 @lime-6 @lime-7, - green @green-5 @green-6 @green-7, - cyan @cyan-5 @cyan-6 @cyan-7, - blue @blue-5 @blue-6 @blue-7, - geekblue @geekblue-5 @geekblue-6 @geekblue-7, - purple @purple-5 @purple-6 @purple-7, - magenta @magenta-5 @magenta-6 @magenta-7, - grey @grey-5 @grey-6 @grey-7; - -// Alias -@aliasColors: - primary blue, - success green, - error red, - warning yellow; - -// Grey patch -@greyColorer: -lighter @grey-3, -darker @grey-9; - -// Layout Gutter -@layout-gutter: 8px; - -@xs: @layout-gutter / 2; -@sm: @layout-gutter; -@md: @layout-gutter * 2; -@lg: @layout-gutter * 3; - -@grid-breakpoints: - xs @screen-xs, - sm @screen-sm, - md @screen-md, - lg @screen-lg, - xl @screen-xl; - -@mobile-min: @screen-md-min; -@mobile-max: @screen-md-min - 1px; - -// spaceing -@spacings: - 0 0, - xs @xs, - sm @sm, - md @md, - lg @lg; - -// type -@ul-ol-margin: 18px; - -// position -@zindex-base: @zindex-back-top - 1; -@zindex-fixed: @zindex-base; -@zindex: @zindex-base; - -@overflows: auto, hidden; -@positions: static, relative, absolute, fixed, sticky; - -// 文本 -@text-xs: @font-size-base - 2; // 12px -@text-sm: @font-size-base + 0; // 14px -@text-md: @font-size-base + 2; // 16px -@text-lg: @font-size-base + 4; // 18px -@text-xl: @font-size-base + 8; // 22px - -// icon -@icon-sm: @font-size-base * 2; // 24px -@icon-md: @font-size-base * 4; // 48px -@icon-lg: @font-size-base * 6; // 72px - -// 宽度 -@widths: - sm @layout-gutter * 20, // 160px - md @layout-gutter * 30, // 240px - lg @layout-gutter * 40, // 320px - 10 10%, - 20 20%, - 30 30%, - 40 40%, - 50 50%, - 60 60%, - 70 70%, - 80 80%, - 90 90%, - 100 100%; - -// 圆角 -@border-radius-md: @border-radius-base; // 4px -@border-radius-lg: @border-radius-base + 2px; // 6px - -@muted-color: @grey-7; - -// Colors -@white: #fff; -@black: #000; - -// scrollbar -@scrollbar-enabled: true; -@scrollbar-width: 6px; -@scrollbar-height: 6px; -@scrollbar-track-color: rgba(0, 0, 0, 0.3); -@scrollbar-thumb-color: #6e6e6e; -@scrollbar-table-enabled: false; - -// type -// ========== - -// font-size -// https://ant.design/docs/spec/font-cn#字号 -@font-size-large: @font-size-base + 8; // 20px -@font-size-small: @font-size-base; // 12px - -@h1-font-size: @font-size-base + 20; // 32px -@h2-font-size: @font-size-base + 12; // 24px -@h3-font-size: @font-size-base + 8; // 20px -@h4-font-size: @font-size-base + 4; // 16px -@h5-font-size: @font-size-base + 2; // 14px -@h6-font-size: @font-size-base; // 12px - -@enable-all-colors: true; - -// Code -@code-border-color: #eee; -@code-bg: #f7f7f7; - -@drawer-xl: 1200px; -@drawer-lg: 900px; -@drawer-md: 600px; -@drawer-sm: 300px; - -@modal-xl: 1200px; -@modal-lg: 900px; -@modal-md: 600px; -@modal-sm: 300px; - -@preserve-white-spaces-enabled: true; -// 搜索框与表格 -@preserve-sf-and-st-spaces: @layout-gutter * 2; -// 按钮间 -@preserve-buttons-spaces: @layout-gutter; - -// table -@nz-table-img-radius: 4px; -@nz-table-img-margin-right: 4px; -@nz-table-img-max-height: 32px; -@nz-table-img-max-width: 32px; -@nz-table-rep-max-width: @mobile-max; -@nz-table-rep-header-background: @border-color-split; -@nz-table-rep-even-background: #f9f9f9; -@nz-table-rep-padding-vertical: @table-padding-vertical / 2; -@nz-table-rep-padding-horizontal: @table-padding-horizontal / 2; -@nz-table-rep-column-name-width: 100px; -@nz-table-rep-column-name-text-align: right; -@nz-table-rep-column-name-padding-right: 8px; -@nz-table-rep-column-name-color: rgba(0, 0, 0, 0.5); - -// Forced to turn off Modal animation -@forced-turn-off-nz-modal-animation-enabled: false; - -// antd -// antd -/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ -/* stylelint-disable no-duplicate-selectors */ -/* stylelint-disable */ -.bezierEasingMixin() { -@functions: ~`(function() { - var NEWTON_ITERATIONS = 4; - var NEWTON_MIN_SLOPE = 0.001; - var SUBDIVISION_PRECISION = 0.0000001; - var SUBDIVISION_MAX_ITERATIONS = 10; - - var kSplineTableSize = 11; - var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); - - var float32ArraySupported = typeof Float32Array === 'function'; - - function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } - function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } - function C (aA1) { return 3.0 * aA1; } - - // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. - function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; } - - // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. - function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); } - - function binarySubdivide (aX, aA, aB, mX1, mX2) { - var currentX, currentT, i = 0; - do { - currentT = aA + (aB - aA) / 2.0; - currentX = calcBezier(currentT, mX1, mX2) - aX; - if (currentX > 0.0) { - aB = currentT; - } else { - aA = currentT; - } - } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); - return currentT; - } - - function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { - for (var i = 0; i < NEWTON_ITERATIONS; ++i) { - var currentSlope = getSlope(aGuessT, mX1, mX2); - if (currentSlope === 0.0) { - return aGuessT; - } - var currentX = calcBezier(aGuessT, mX1, mX2) - aX; - aGuessT -= currentX / currentSlope; - } - return aGuessT; - } - - var BezierEasing = function (mX1, mY1, mX2, mY2) { - if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { - throw new Error('bezier x values must be in [0, 1] range'); - } - - // Precompute samples table - var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); - if (mX1 !== mY1 || mX2 !== mY2) { - for (var i = 0; i < kSplineTableSize; ++i) { - sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); - } - } - - function getTForX (aX) { - var intervalStart = 0.0; - var currentSample = 1; - var lastSample = kSplineTableSize - 1; - - for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) { - intervalStart += kSampleStepSize; - } - --currentSample; - - // Interpolate to provide an initial guess for t - var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]); - var guessForT = intervalStart + dist * kSampleStepSize; - - var initialSlope = getSlope(guessForT, mX1, mX2); - if (initialSlope >= NEWTON_MIN_SLOPE) { - return newtonRaphsonIterate(aX, guessForT, mX1, mX2); - } else if (initialSlope === 0.0) { - return guessForT; - } else { - return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); - } - } - - return function BezierEasing (x) { - if (mX1 === mY1 && mX2 === mY2) { - return x; // linear - } - // Because JavaScript number are imprecise, we should guarantee the extremes are right. - if (x === 0) { - return 0; - } - if (x === 1) { - return 1; - } - return calcBezier(getTForX(x), mY1, mY2); - }; - }; - - this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18); - // less 3 requires a return - return ''; -})()`; -} -// It is hacky way to make this function will be compiled preferentially by less -// resolve error: `ReferenceError: colorPalette is not defined` -// https://github.com/ant-design/ant-motion/issues/44 -.bezierEasingMixin(); - -/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */ -.tinyColorMixin() { -@functions: ~`(function() { -// TinyColor v1.4.1 -// https://github.com/bgrins/TinyColor -// 2016-07-07, Brian Grinstead, MIT License -var trimLeft = /^\s+/, - trimRight = /\s+$/, - tinyCounter = 0, - mathRound = Math.round, - mathMin = Math.min, - mathMax = Math.max, - mathRandom = Math.random; - -function tinycolor (color, opts) { - - color = (color) ? color : ''; - opts = opts || { }; - - // If input is already a tinycolor, return itself - if (color instanceof tinycolor) { - return color; - } - // If we are called as a function, call using new instead - if (!(this instanceof tinycolor)) { - return new tinycolor(color, opts); - } - - var rgb = inputToRGB(color); - this._originalInput = color, - this._r = rgb.r, - this._g = rgb.g, - this._b = rgb.b, - this._a = rgb.a, - this._roundA = mathRound(100*this._a) / 100, - this._format = opts.format || rgb.format; - this._gradientType = opts.gradientType; - - // Don't let the range of [0,255] come back in [0,1]. - // Potentially lose a little bit of precision here, but will fix issues where - // .5 gets interpreted as half of the total, instead of half of 1 - // If it was supposed to be 128, this was already taken care of by inputToRgb - if (this._r < 1) { this._r = mathRound(this._r); } - if (this._g < 1) { this._g = mathRound(this._g); } - if (this._b < 1) { this._b = mathRound(this._b); } - - this._ok = rgb.ok; - this._tc_id = tinyCounter++; -} - -tinycolor.prototype = { - isDark: function() { - return this.getBrightness() < 128; - }, - isLight: function() { - return !this.isDark(); - }, - isValid: function() { - return this._ok; - }, - getOriginalInput: function() { - return this._originalInput; - }, - getFormat: function() { - return this._format; - }, - getAlpha: function() { - return this._a; - }, - getBrightness: function() { - //http://www.w3.org/TR/AERT#color-contrast - var rgb = this.toRgb(); - return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; - }, - getLuminance: function() { - //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef - var rgb = this.toRgb(); - var RsRGB, GsRGB, BsRGB, R, G, B; - RsRGB = rgb.r/255; - GsRGB = rgb.g/255; - BsRGB = rgb.b/255; - - if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);} - if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);} - if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);} - return (0.2126 * R) + (0.7152 * G) + (0.0722 * B); - }, - setAlpha: function(value) { - this._a = boundAlpha(value); - this._roundA = mathRound(100*this._a) / 100; - return this; - }, - toHsv: function() { - var hsv = rgbToHsv(this._r, this._g, this._b); - return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a }; - }, - toHsvString: function() { - var hsv = rgbToHsv(this._r, this._g, this._b); - var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100); - return (this._a == 1) ? - "hsv(" + h + ", " + s + "%, " + v + "%)" : - "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")"; - }, - toHsl: function() { - var hsl = rgbToHsl(this._r, this._g, this._b); - return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a }; - }, - toHslString: function() { - var hsl = rgbToHsl(this._r, this._g, this._b); - var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100); - return (this._a == 1) ? - "hsl(" + h + ", " + s + "%, " + l + "%)" : - "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")"; - }, - toHex: function(allow3Char) { - return rgbToHex(this._r, this._g, this._b, allow3Char); - }, - toHexString: function(allow3Char) { - return '#' + this.toHex(allow3Char); - }, - toHex8: function(allow4Char) { - return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char); - }, - toHex8String: function(allow4Char) { - return '#' + this.toHex8(allow4Char); - }, - toRgb: function() { - return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a }; - }, - toRgbString: function() { - return (this._a == 1) ? - "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" : - "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")"; - }, - toPercentageRgb: function() { - return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a }; - }, - toPercentageRgbString: function() { - return (this._a == 1) ? - "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" : - "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; - }, - toName: function() { - if (this._a === 0) { - return "transparent"; - } - - if (this._a < 1) { - return false; - } - - return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; - }, - toFilter: function(secondColor) { - var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a); - var secondHex8String = hex8String; - var gradientType = this._gradientType ? "GradientType = 1, " : ""; - - if (secondColor) { - var s = tinycolor(secondColor); - secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a); - } - - return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")"; - }, - toString: function(format) { - var formatSet = !!format; - format = format || this._format; - - var formattedString = false; - var hasAlpha = this._a < 1 && this._a >= 0; - var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name"); - - if (needsAlphaFormat) { - // Special case for "transparent", all other non-alpha formats - // will return rgba when there is transparency. - if (format === "name" && this._a === 0) { - return this.toName(); - } - return this.toRgbString(); - } - if (format === "rgb") { - formattedString = this.toRgbString(); - } - if (format === "prgb") { - formattedString = this.toPercentageRgbString(); - } - if (format === "hex" || format === "hex6") { - formattedString = this.toHexString(); - } - if (format === "hex3") { - formattedString = this.toHexString(true); - } - if (format === "hex4") { - formattedString = this.toHex8String(true); - } - if (format === "hex8") { - formattedString = this.toHex8String(); - } - if (format === "name") { - formattedString = this.toName(); - } - if (format === "hsl") { - formattedString = this.toHslString(); - } - if (format === "hsv") { - formattedString = this.toHsvString(); - } - - return formattedString || this.toHexString(); - }, - clone: function() { - return tinycolor(this.toString()); - }, - - _applyModification: function(fn, args) { - var color = fn.apply(null, [this].concat([].slice.call(args))); - this._r = color._r; - this._g = color._g; - this._b = color._b; - this.setAlpha(color._a); - return this; - }, - lighten: function() { - return this._applyModification(lighten, arguments); - }, - brighten: function() { - return this._applyModification(brighten, arguments); - }, - darken: function() { - return this._applyModification(darken, arguments); - }, - desaturate: function() { - return this._applyModification(desaturate, arguments); - }, - saturate: function() { - return this._applyModification(saturate, arguments); - }, - greyscale: function() { - return this._applyModification(greyscale, arguments); - }, - spin: function() { - return this._applyModification(spin, arguments); - }, - - _applyCombination: function(fn, args) { - return fn.apply(null, [this].concat([].slice.call(args))); - }, - analogous: function() { - return this._applyCombination(analogous, arguments); - }, - complement: function() { - return this._applyCombination(complement, arguments); - }, - monochromatic: function() { - return this._applyCombination(monochromatic, arguments); - }, - splitcomplement: function() { - return this._applyCombination(splitcomplement, arguments); - }, - triad: function() { - return this._applyCombination(triad, arguments); - }, - tetrad: function() { - return this._applyCombination(tetrad, arguments); - } -}; - -// If input is an object, force 1 into "1.0" to handle ratios properly -// String input requires "1.0" as input, so 1 will be treated as 1 -tinycolor.fromRatio = function(color, opts) { - if (typeof color == "object") { - var newColor = {}; - for (var i in color) { - if (color.hasOwnProperty(i)) { - if (i === "a") { - newColor[i] = color[i]; - } - else { - newColor[i] = convertToPercentage(color[i]); - } - } - } - color = newColor; - } - - return tinycolor(color, opts); -}; - -// Given a string or object, convert that input to RGB -// Possible string inputs: -// -// "red" -// "#f00" or "f00" -// "#ff0000" or "ff0000" -// "#ff000000" or "ff000000" -// "rgb 255 0 0" or "rgb (255, 0, 0)" -// "rgb 1.0 0 0" or "rgb (1, 0, 0)" -// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" -// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" -// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" -// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" -// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" -// -function inputToRGB(color) { - - var rgb = { r: 0, g: 0, b: 0 }; - var a = 1; - var s = null; - var v = null; - var l = null; - var ok = false; - var format = false; - - if (typeof color == "string") { - color = stringInputToObject(color); - } - - if (typeof color == "object") { - if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { - rgb = rgbToRgb(color.r, color.g, color.b); - ok = true; - format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; - } - else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { - s = convertToPercentage(color.s); - v = convertToPercentage(color.v); - rgb = hsvToRgb(color.h, s, v); - ok = true; - format = "hsv"; - } - else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { - s = convertToPercentage(color.s); - l = convertToPercentage(color.l); - rgb = hslToRgb(color.h, s, l); - ok = true; - format = "hsl"; - } - - if (color.hasOwnProperty("a")) { - a = color.a; - } - } - - a = boundAlpha(a); - - return { - ok: ok, - format: color.format || format, - r: mathMin(255, mathMax(rgb.r, 0)), - g: mathMin(255, mathMax(rgb.g, 0)), - b: mathMin(255, mathMax(rgb.b, 0)), - a: a - }; -} - -// Conversion Functions -// -------------------- - -// rgbToHsl, rgbToHsv, hslToRgb, hsvToRgb modified from: -// - -// rgbToRgb -// Handle bounds / percentage checking to conform to CSS color spec -// -// *Assumes:* r, g, b in [0, 255] or [0, 1] -// *Returns:* { r, g, b } in [0, 255] -function rgbToRgb(r, g, b){ - return { - r: bound01(r, 255) * 255, - g: bound01(g, 255) * 255, - b: bound01(b, 255) * 255 - }; -} - -// rgbToHsl -// Converts an RGB color value to HSL. -// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] -// *Returns:* { h, s, l } in [0,1] -function rgbToHsl(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(r, g, b); - var h, s, l = (max + min) / 2; - - if(max == min) { - h = s = 0; // achromatic - } - else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch(max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - - h /= 6; - } - - return { h: h, s: s, l: l }; -} - -// hslToRgb -// Converts an HSL color value to RGB. -// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] -// *Returns:* { r, g, b } in the set [0, 255] -function hslToRgb(h, s, l) { - var r, g, b; - - h = bound01(h, 360); - s = bound01(s, 100); - l = bound01(l, 100); - - function hue2rgb(p, q, t) { - if(t < 0) t += 1; - if(t > 1) t -= 1; - if(t < 1/6) return p + (q - p) * 6 * t; - if(t < 1/2) return q; - if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; - return p; - } - - if(s === 0) { - r = g = b = l; // achromatic - } - else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1/3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1/3); - } - - return { r: r * 255, g: g * 255, b: b * 255 }; -} - -// rgbToHsv -// Converts an RGB color value to HSV -// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] -// *Returns:* { h, s, v } in [0,1] -function rgbToHsv(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(r, g, b); - var h, s, v = max; - - var d = max - min; - s = max === 0 ? 0 : d / max; - - if(max == min) { - h = 0; // achromatic - } - else { - switch(max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h, s: s, v: v }; -} - -// hsvToRgb -// Converts an HSV color value to RGB. -// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] -// *Returns:* { r, g, b } in the set [0, 255] - function hsvToRgb(h, s, v) { - - h = bound01(h, 360) * 6; - s = bound01(s, 100); - v = bound01(v, 100); - - var i = Math.floor(h), - f = h - i, - p = v * (1 - s), - q = v * (1 - f * s), - t = v * (1 - (1 - f) * s), - mod = i % 6, - r = [v, q, p, p, t, v][mod], - g = [t, v, v, q, p, p][mod], - b = [p, p, t, v, v, q][mod]; - - return { r: r * 255, g: g * 255, b: b * 255 }; -} - -// rgbToHex -// Converts an RGB color to hex -// Assumes r, g, and b are contained in the set [0, 255] -// Returns a 3 or 6 character hex -function rgbToHex(r, g, b, allow3Char) { - - var hex = [ - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)) - ]; - - // Return a 3 character hex if possible - if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); - } - - return hex.join(""); -} - -// rgbaToHex -// Converts an RGBA color plus alpha transparency to hex -// Assumes r, g, b are contained in the set [0, 255] and -// a in [0, 1]. Returns a 4 or 8 character rgba hex -function rgbaToHex(r, g, b, a, allow4Char) { - - var hex = [ - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)), - pad2(convertDecimalToHex(a)) - ]; - - // Return a 4 character hex if possible - if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0); - } - - return hex.join(""); -} - -// rgbaToArgbHex -// Converts an RGBA color to an ARGB Hex8 string -// Rarely used, but required for "toFilter()" -function rgbaToArgbHex(r, g, b, a) { - - var hex = [ - pad2(convertDecimalToHex(a)), - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)) - ]; - - return hex.join(""); -} - -// equals -// Can be called with any tinycolor input -tinycolor.equals = function (color1, color2) { - if (!color1 || !color2) { return false; } - return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); -}; - -tinycolor.random = function() { - return tinycolor.fromRatio({ - r: mathRandom(), - g: mathRandom(), - b: mathRandom() - }); -}; - -// Modification Functions -// ---------------------- -// Thanks to less.js for some of the basics here -// - -function desaturate(color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.s -= amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); -} - -function saturate(color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.s += amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); -} - -function greyscale(color) { - return tinycolor(color).desaturate(100); -} - -function lighten (color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.l += amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); -} - -function brighten(color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var rgb = tinycolor(color).toRgb(); - rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100)))); - rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100)))); - rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100)))); - return tinycolor(rgb); -} - -function darken (color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.l -= amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); -} - -// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue. -// Values outside of this range will be wrapped into this range. -function spin(color, amount) { - var hsl = tinycolor(color).toHsl(); - var hue = (hsl.h + amount) % 360; - hsl.h = hue < 0 ? 360 + hue : hue; - return tinycolor(hsl); -} - -// Combination Functions -// --------------------- -// Thanks to jQuery xColor for some of the ideas behind these -// - -function complement(color) { - var hsl = tinycolor(color).toHsl(); - hsl.h = (hsl.h + 180) % 360; - return tinycolor(hsl); -} - -function triad(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }) - ]; -} - -function tetrad(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }) - ]; -} - -function splitcomplement(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}), - tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l}) - ]; -} - -function analogous(color, results, slices) { - results = results || 6; - slices = slices || 30; - - var hsl = tinycolor(color).toHsl(); - var part = 360 / slices; - var ret = [tinycolor(color)]; - - for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) { - hsl.h = (hsl.h + part) % 360; - ret.push(tinycolor(hsl)); - } - return ret; -} - -function monochromatic(color, results) { - results = results || 6; - var hsv = tinycolor(color).toHsv(); - var h = hsv.h, s = hsv.s, v = hsv.v; - var ret = []; - var modification = 1 / results; - - while (results--) { - ret.push(tinycolor({ h: h, s: s, v: v})); - v = (v + modification) % 1; - } - - return ret; -} - -// Utility Functions -// --------------------- - -tinycolor.mix = function(color1, color2, amount) { - amount = (amount === 0) ? 0 : (amount || 50); - - var rgb1 = tinycolor(color1).toRgb(); - var rgb2 = tinycolor(color2).toRgb(); - - var p = amount / 100; - - var rgba = { - r: ((rgb2.r - rgb1.r) * p) + rgb1.r, - g: ((rgb2.g - rgb1.g) * p) + rgb1.g, - b: ((rgb2.b - rgb1.b) * p) + rgb1.b, - a: ((rgb2.a - rgb1.a) * p) + rgb1.a - }; - - return tinycolor(rgba); -}; - -// Readability Functions -// --------------------- -// false -// tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false -tinycolor.isReadable = function(color1, color2, wcag2) { - var readability = tinycolor.readability(color1, color2); - var wcag2Parms, out; - - out = false; - - wcag2Parms = validateWCAG2Parms(wcag2); - switch (wcag2Parms.level + wcag2Parms.size) { - case "AAsmall": - case "AAAlarge": - out = readability >= 4.5; - break; - case "AAlarge": - out = readability >= 3; - break; - case "AAAsmall": - out = readability >= 7; - break; - } - return out; - -}; - -// mostReadable -// Given a base color and a list of possible foreground or background -// colors for that base, returns the most readable color. -// Optionally returns Black or White if the most readable color is unreadable. -// *Example* -// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255" -// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff" -// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3" -// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff" -tinycolor.mostReadable = function(baseColor, colorList, args) { - var bestColor = null; - var bestScore = 0; - var readability; - var includeFallbackColors, level, size ; - args = args || {}; - includeFallbackColors = args.includeFallbackColors ; - level = args.level; - size = args.size; - - for (var i= 0; i < colorList.length ; i++) { - readability = tinycolor.readability(baseColor, colorList[i]); - if (readability > bestScore) { - bestScore = readability; - bestColor = tinycolor(colorList[i]); - } - } - - if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) { - return bestColor; - } - else { - args.includeFallbackColors=false; - return tinycolor.mostReadable(baseColor,["#fff", "#000"],args); - } -}; - -// Big List of Colors -// ------------------ -// -var names = tinycolor.names = { - aliceblue: "f0f8ff", - antiquewhite: "faebd7", - aqua: "0ff", - aquamarine: "7fffd4", - azure: "f0ffff", - beige: "f5f5dc", - bisque: "ffe4c4", - black: "000", - blanchedalmond: "ffebcd", - blue: "00f", - blueviolet: "8a2be2", - brown: "a52a2a", - burlywood: "deb887", - burntsienna: "ea7e5d", - cadetblue: "5f9ea0", - chartreuse: "7fff00", - chocolate: "d2691e", - coral: "ff7f50", - cornflowerblue: "6495ed", - cornsilk: "fff8dc", - crimson: "dc143c", - cyan: "0ff", - darkblue: "00008b", - darkcyan: "008b8b", - darkgoldenrod: "b8860b", - darkgray: "a9a9a9", - darkgreen: "006400", - darkgrey: "a9a9a9", - darkkhaki: "bdb76b", - darkmagenta: "8b008b", - darkolivegreen: "556b2f", - darkorange: "ff8c00", - darkorchid: "9932cc", - darkred: "8b0000", - darksalmon: "e9967a", - darkseagreen: "8fbc8f", - darkslateblue: "483d8b", - darkslategray: "2f4f4f", - darkslategrey: "2f4f4f", - darkturquoise: "00ced1", - darkviolet: "9400d3", - deeppink: "ff1493", - deepskyblue: "00bfff", - dimgray: "696969", - dimgrey: "696969", - dodgerblue: "1e90ff", - firebrick: "b22222", - floralwhite: "fffaf0", - forestgreen: "228b22", - fuchsia: "f0f", - gainsboro: "dcdcdc", - ghostwhite: "f8f8ff", - gold: "ffd700", - goldenrod: "daa520", - gray: "808080", - green: "008000", - greenyellow: "adff2f", - grey: "808080", - honeydew: "f0fff0", - hotpink: "ff69b4", - indianred: "cd5c5c", - indigo: "4b0082", - ivory: "fffff0", - khaki: "f0e68c", - lavender: "e6e6fa", - lavenderblush: "fff0f5", - lawngreen: "7cfc00", - lemonchiffon: "fffacd", - lightblue: "add8e6", - lightcoral: "f08080", - lightcyan: "e0ffff", - lightgoldenrodyellow: "fafad2", - lightgray: "d3d3d3", - lightgreen: "90ee90", - lightgrey: "d3d3d3", - lightpink: "ffb6c1", - lightsalmon: "ffa07a", - lightseagreen: "20b2aa", - lightskyblue: "87cefa", - lightslategray: "789", - lightslategrey: "789", - lightsteelblue: "b0c4de", - lightyellow: "ffffe0", - lime: "0f0", - limegreen: "32cd32", - linen: "faf0e6", - magenta: "f0f", - maroon: "800000", - mediumaquamarine: "66cdaa", - mediumblue: "0000cd", - mediumorchid: "ba55d3", - mediumpurple: "9370db", - mediumseagreen: "3cb371", - mediumslateblue: "7b68ee", - mediumspringgreen: "00fa9a", - mediumturquoise: "48d1cc", - mediumvioletred: "c71585", - midnightblue: "191970", - mintcream: "f5fffa", - mistyrose: "ffe4e1", - moccasin: "ffe4b5", - navajowhite: "ffdead", - navy: "000080", - oldlace: "fdf5e6", - olive: "808000", - olivedrab: "6b8e23", - orange: "ffa500", - orangered: "ff4500", - orchid: "da70d6", - palegoldenrod: "eee8aa", - palegreen: "98fb98", - paleturquoise: "afeeee", - palevioletred: "db7093", - papayawhip: "ffefd5", - peachpuff: "ffdab9", - peru: "cd853f", - pink: "ffc0cb", - plum: "dda0dd", - powderblue: "b0e0e6", - purple: "800080", - rebeccapurple: "663399", - red: "f00", - rosybrown: "bc8f8f", - royalblue: "4169e1", - saddlebrown: "8b4513", - salmon: "fa8072", - sandybrown: "f4a460", - seagreen: "2e8b57", - seashell: "fff5ee", - sienna: "a0522d", - silver: "c0c0c0", - skyblue: "87ceeb", - slateblue: "6a5acd", - slategray: "708090", - slategrey: "708090", - snow: "fffafa", - springgreen: "00ff7f", - steelblue: "4682b4", - tan: "d2b48c", - teal: "008080", - thistle: "d8bfd8", - tomato: "ff6347", - turquoise: "40e0d0", - violet: "ee82ee", - wheat: "f5deb3", - white: "fff", - whitesmoke: "f5f5f5", - yellow: "ff0", - yellowgreen: "9acd32" -}; - -// Make it easy to access colors via hexNames[hex] -var hexNames = tinycolor.hexNames = flip(names); - -// Utilities -// --------- - -// { 'name1': 'val1' } becomes { 'val1': 'name1' } -function flip(o) { - var flipped = { }; - for (var i in o) { - if (o.hasOwnProperty(i)) { - flipped[o[i]] = i; - } - } - return flipped; -} - -// Return a valid alpha value [0,1] with all invalid values being set to 1 -function boundAlpha(a) { - a = parseFloat(a); - - if (isNaN(a) || a < 0 || a > 1) { - a = 1; - } - - return a; -} - -// Take input from [0, n] and return it as [0, 1] -function bound01(n, max) { - if (isOnePointZero(n)) { n = "100%"; } - - var processPercent = isPercentage(n); - n = mathMin(max, mathMax(0, parseFloat(n))); - - // Automatically convert percentage into number - if (processPercent) { - n = parseInt(n * max, 10) / 100; - } - - // Handle floating point rounding errors - if ((Math.abs(n - max) < 0.000001)) { - return 1; - } - - // Convert into [0, 1] range if it isn't already - return (n % max) / parseFloat(max); -} - -// Force a number between 0 and 1 -function clamp01(val) { - return mathMin(1, mathMax(0, val)); -} - -// Parse a base-16 hex value into a base-10 integer -function parseIntFromHex(val) { - return parseInt(val, 16); -} - -// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 -// -function isOnePointZero(n) { - return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1; -} - -// Check to see if string passed in is a percentage -function isPercentage(n) { - return typeof n === "string" && n.indexOf('%') != -1; -} - -// Force a hex value to have 2 characters -function pad2(c) { - return c.length == 1 ? '0' + c : '' + c; -} - -// Replace a decimal with it's percentage value -function convertToPercentage(n) { - if (n <= 1) { - n = (n * 100) + "%"; - } - - return n; -} - -// Converts a decimal to a hex value -function convertDecimalToHex(d) { - return Math.round(parseFloat(d) * 255).toString(16); -} -// Converts a hex value to a decimal -function convertHexToDecimal(h) { - return (parseIntFromHex(h) / 255); -} - -var matchers = (function() { - - // - var CSS_INTEGER = "[-\\+]?\\d+%?"; - - // - var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; - - // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. - var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; - - // Actual matching. - // Parentheses and commas are optional, but not required. - // Whitespace can take the place of commas or opening paren - var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - - return { - CSS_UNIT: new RegExp(CSS_UNIT), - rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), - rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), - hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), - hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), - hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), - hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), - hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, - hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ - }; -})(); - -// isValidCSSUnit -// Take in a single string / number and check to see if it looks like a CSS unit -// (see matchers above for definition). -function isValidCSSUnit(color) { - return !!matchers.CSS_UNIT.exec(color); -} - -// stringInputToObject -// Permissive string parsing. Take in a number of formats, and output an object -// based on detected format. Returns { r, g, b } or { h, s, l } or { h, s, v} -function stringInputToObject(color) { - - color = color.replace(trimLeft, '').replace(trimRight, '').toLowerCase(); - var named = false; - if (names[color]) { - color = names[color]; - named = true; - } - else if (color == 'transparent') { - return { r: 0, g: 0, b: 0, a: 0, format: "name" }; - } - - // Try to match string input using regular expressions. - // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] - // Just return an object and let the conversion functions handle that. - // This way the result will be the same whether the tinycolor is initialized with string or object. - var match; - if ((match = matchers.rgb.exec(color))) { - return { r: match[1], g: match[2], b: match[3] }; - } - if ((match = matchers.rgba.exec(color))) { - return { r: match[1], g: match[2], b: match[3], a: match[4] }; - } - if ((match = matchers.hsl.exec(color))) { - return { h: match[1], s: match[2], l: match[3] }; - } - if ((match = matchers.hsla.exec(color))) { - return { h: match[1], s: match[2], l: match[3], a: match[4] }; - } - if ((match = matchers.hsv.exec(color))) { - return { h: match[1], s: match[2], v: match[3] }; - } - if ((match = matchers.hsva.exec(color))) { - return { h: match[1], s: match[2], v: match[3], a: match[4] }; - } - if ((match = matchers.hex8.exec(color))) { - return { - r: parseIntFromHex(match[1]), - g: parseIntFromHex(match[2]), - b: parseIntFromHex(match[3]), - a: convertHexToDecimal(match[4]), - format: named ? "name" : "hex8" - }; - } - if ((match = matchers.hex6.exec(color))) { - return { - r: parseIntFromHex(match[1]), - g: parseIntFromHex(match[2]), - b: parseIntFromHex(match[3]), - format: named ? "name" : "hex" - }; - } - if ((match = matchers.hex4.exec(color))) { - return { - r: parseIntFromHex(match[1] + '' + match[1]), - g: parseIntFromHex(match[2] + '' + match[2]), - b: parseIntFromHex(match[3] + '' + match[3]), - a: convertHexToDecimal(match[4] + '' + match[4]), - format: named ? "name" : "hex8" - }; - } - if ((match = matchers.hex3.exec(color))) { - return { - r: parseIntFromHex(match[1] + '' + match[1]), - g: parseIntFromHex(match[2] + '' + match[2]), - b: parseIntFromHex(match[3] + '' + match[3]), - format: named ? "name" : "hex" - }; - } - - return false; -} - -function validateWCAG2Parms(parms) { - // return valid WCAG2 parms for isReadable. - // If input parms are invalid, return {"level":"AA", "size":"small"} - var level, size; - parms = parms || {"level":"AA", "size":"small"}; - level = (parms.level || "AA").toUpperCase(); - size = (parms.size || "small").toLowerCase(); - if (level !== "AA" && level !== "AAA") { - level = "AA"; - } - if (size !== "small" && size !== "large") { - size = "small"; - } - return {"level":level, "size":size}; -} - -this.tinycolor = tinycolor; - -})()`; -} -// It is hacky way to make this function will be compiled preferentially by less -// resolve error: `ReferenceError: colorPalette is not defined` -// https://github.com/ant-design/ant-motion/issues/44 -.tinyColorMixin(); - -// We create a very complex algorithm which take the place of original tint/shade color system -// to make sure no one can understand it 👻 -// and create an entire color palette magicly by inputing just a single primary color. -// We are using bezier-curve easing function and some color manipulations like tint/shade/darken/spin -.colorPaletteMixin() { -@functions: ~`(function() { - var hueStep = 2; - var saturationStep = 16; - var saturationStep2 = 5; - var brightnessStep1 = 5; - var brightnessStep2 = 15; - var lightColorCount = 5; - var darkColorCount = 4; - - var getHue = function(hsv, i, isLight) { - var hue; - if (hsv.h >= 60 && hsv.h <= 240) { - hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i; - } else { - hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i; - } - if (hue < 0) { - hue += 360; - } else if (hue >= 360) { - hue -= 360; - } - return Math.round(hue); - }; - var getSaturation = function(hsv, i, isLight) { - var saturation; - if (isLight) { - saturation = Math.round(hsv.s * 100) - saturationStep * i; - } else if (i == darkColorCount) { - saturation = Math.round(hsv.s * 100) + saturationStep; - } else { - saturation = Math.round(hsv.s * 100) + saturationStep2 * i; - } - if (saturation > 100) { - saturation = 100; - } - if (isLight && i === lightColorCount && saturation > 10) { - saturation = 10; - } - if (saturation < 6) { - saturation = 6; - } - return Math.round(saturation); - }; - var getValue = function(hsv, i, isLight) { - if (isLight) { - return Math.round(hsv.v * 100) + brightnessStep1 * i; - } - return Math.round(hsv.v * 100) - brightnessStep2 * i; - }; - - this.colorPalette = function(color, index) { - var isLight = index <= 6; - var hsv = tinycolor(color).toHsv(); - var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1; - return tinycolor({ - h: getHue(hsv, i, isLight), - s: getSaturation(hsv, i, isLight), - v: getValue(hsv, i, isLight), - }).toHexString(); - }; -})()`; -} -// It is hacky way to make this function will be compiled preferentially by less -// resolve error: `ReferenceError: colorPalette is not defined` -// https://github.com/ant-design/ant-motion/issues/44 -.colorPaletteMixin(); - -// color palettes -@blue-1: color(~`colorPalette('@{blue-6}', 1) `); -@blue-2: color(~`colorPalette('@{blue-6}', 2) `); -@blue-3: color(~`colorPalette('@{blue-6}', 3) `); -@blue-4: color(~`colorPalette('@{blue-6}', 4) `); -@blue-5: color(~`colorPalette('@{blue-6}', 5) `); -@blue-6: #1890ff; -@blue-7: color(~`colorPalette('@{blue-6}', 7) `); -@blue-8: color(~`colorPalette('@{blue-6}', 8) `); -@blue-9: color(~`colorPalette('@{blue-6}', 9) `); -@blue-10: color(~`colorPalette('@{blue-6}', 10) `); - -@purple-1: color(~`colorPalette('@{purple-6}', 1) `); -@purple-2: color(~`colorPalette('@{purple-6}', 2) `); -@purple-3: color(~`colorPalette('@{purple-6}', 3) `); -@purple-4: color(~`colorPalette('@{purple-6}', 4) `); -@purple-5: color(~`colorPalette('@{purple-6}', 5) `); -@purple-6: #722ed1; -@purple-7: color(~`colorPalette('@{purple-6}', 7) `); -@purple-8: color(~`colorPalette('@{purple-6}', 8) `); -@purple-9: color(~`colorPalette('@{purple-6}', 9) `); -@purple-10: color(~`colorPalette('@{purple-6}', 10) `); - -@cyan-1: color(~`colorPalette('@{cyan-6}', 1) `); -@cyan-2: color(~`colorPalette('@{cyan-6}', 2) `); -@cyan-3: color(~`colorPalette('@{cyan-6}', 3) `); -@cyan-4: color(~`colorPalette('@{cyan-6}', 4) `); -@cyan-5: color(~`colorPalette('@{cyan-6}', 5) `); -@cyan-6: #13c2c2; -@cyan-7: color(~`colorPalette('@{cyan-6}', 7) `); -@cyan-8: color(~`colorPalette('@{cyan-6}', 8) `); -@cyan-9: color(~`colorPalette('@{cyan-6}', 9) `); -@cyan-10: color(~`colorPalette('@{cyan-6}', 10) `); - -@green-1: color(~`colorPalette('@{green-6}', 1) `); -@green-2: color(~`colorPalette('@{green-6}', 2) `); -@green-3: color(~`colorPalette('@{green-6}', 3) `); -@green-4: color(~`colorPalette('@{green-6}', 4) `); -@green-5: color(~`colorPalette('@{green-6}', 5) `); -@green-6: #52c41a; -@green-7: color(~`colorPalette('@{green-6}', 7) `); -@green-8: color(~`colorPalette('@{green-6}', 8) `); -@green-9: color(~`colorPalette('@{green-6}', 9) `); -@green-10: color(~`colorPalette('@{green-6}', 10) `); - -@magenta-1: color(~`colorPalette('@{magenta-6}', 1) `); -@magenta-2: color(~`colorPalette('@{magenta-6}', 2) `); -@magenta-3: color(~`colorPalette('@{magenta-6}', 3) `); -@magenta-4: color(~`colorPalette('@{magenta-6}', 4) `); -@magenta-5: color(~`colorPalette('@{magenta-6}', 5) `); -@magenta-6: #eb2f96; -@magenta-7: color(~`colorPalette('@{magenta-6}', 7) `); -@magenta-8: color(~`colorPalette('@{magenta-6}', 8) `); -@magenta-9: color(~`colorPalette('@{magenta-6}', 9) `); -@magenta-10: color(~`colorPalette('@{magenta-6}', 10) `); - -// alias of magenta -@pink-1: color(~`colorPalette('@{pink-6}', 1) `); -@pink-2: color(~`colorPalette('@{pink-6}', 2) `); -@pink-3: color(~`colorPalette('@{pink-6}', 3) `); -@pink-4: color(~`colorPalette('@{pink-6}', 4) `); -@pink-5: color(~`colorPalette('@{pink-6}', 5) `); -@pink-6: #eb2f96; -@pink-7: color(~`colorPalette('@{pink-6}', 7) `); -@pink-8: color(~`colorPalette('@{pink-6}', 8) `); -@pink-9: color(~`colorPalette('@{pink-6}', 9) `); -@pink-10: color(~`colorPalette('@{pink-6}', 10) `); - -@red-1: color(~`colorPalette('@{red-6}', 1) `); -@red-2: color(~`colorPalette('@{red-6}', 2) `); -@red-3: color(~`colorPalette('@{red-6}', 3) `); -@red-4: color(~`colorPalette('@{red-6}', 4) `); -@red-5: color(~`colorPalette('@{red-6}', 5) `); -@red-6: #f5222d; -@red-7: color(~`colorPalette('@{red-6}', 7) `); -@red-8: color(~`colorPalette('@{red-6}', 8) `); -@red-9: color(~`colorPalette('@{red-6}', 9) `); -@red-10: color(~`colorPalette('@{red-6}', 10) `); - -@orange-1: color(~`colorPalette('@{orange-6}', 1) `); -@orange-2: color(~`colorPalette('@{orange-6}', 2) `); -@orange-3: color(~`colorPalette('@{orange-6}', 3) `); -@orange-4: color(~`colorPalette('@{orange-6}', 4) `); -@orange-5: color(~`colorPalette('@{orange-6}', 5) `); -@orange-6: #fa8c16; -@orange-7: color(~`colorPalette('@{orange-6}', 7) `); -@orange-8: color(~`colorPalette('@{orange-6}', 8) `); -@orange-9: color(~`colorPalette('@{orange-6}', 9) `); -@orange-10: color(~`colorPalette('@{orange-6}', 10) `); - -@yellow-1: color(~`colorPalette('@{yellow-6}', 1) `); -@yellow-2: color(~`colorPalette('@{yellow-6}', 2) `); -@yellow-3: color(~`colorPalette('@{yellow-6}', 3) `); -@yellow-4: color(~`colorPalette('@{yellow-6}', 4) `); -@yellow-5: color(~`colorPalette('@{yellow-6}', 5) `); -@yellow-6: #fadb14; -@yellow-7: color(~`colorPalette('@{yellow-6}', 7) `); -@yellow-8: color(~`colorPalette('@{yellow-6}', 8) `); -@yellow-9: color(~`colorPalette('@{yellow-6}', 9) `); -@yellow-10: color(~`colorPalette('@{yellow-6}', 10) `); - -@volcano-1: color(~`colorPalette('@{volcano-6}', 1) `); -@volcano-2: color(~`colorPalette('@{volcano-6}', 2) `); -@volcano-3: color(~`colorPalette('@{volcano-6}', 3) `); -@volcano-4: color(~`colorPalette('@{volcano-6}', 4) `); -@volcano-5: color(~`colorPalette('@{volcano-6}', 5) `); -@volcano-6: #fa541c; -@volcano-7: color(~`colorPalette('@{volcano-6}', 7) `); -@volcano-8: color(~`colorPalette('@{volcano-6}', 8) `); -@volcano-9: color(~`colorPalette('@{volcano-6}', 9) `); -@volcano-10: color(~`colorPalette('@{volcano-6}', 10) `); - -@geekblue-1: color(~`colorPalette('@{geekblue-6}', 1) `); -@geekblue-2: color(~`colorPalette('@{geekblue-6}', 2) `); -@geekblue-3: color(~`colorPalette('@{geekblue-6}', 3) `); -@geekblue-4: color(~`colorPalette('@{geekblue-6}', 4) `); -@geekblue-5: color(~`colorPalette('@{geekblue-6}', 5) `); -@geekblue-6: #2f54eb; -@geekblue-7: color(~`colorPalette('@{geekblue-6}', 7) `); -@geekblue-8: color(~`colorPalette('@{geekblue-6}', 8) `); -@geekblue-9: color(~`colorPalette('@{geekblue-6}', 9) `); -@geekblue-10: color(~`colorPalette('@{geekblue-6}', 10) `); - -@lime-1: color(~`colorPalette('@{lime-6}', 1) `); -@lime-2: color(~`colorPalette('@{lime-6}', 2) `); -@lime-3: color(~`colorPalette('@{lime-6}', 3) `); -@lime-4: color(~`colorPalette('@{lime-6}', 4) `); -@lime-5: color(~`colorPalette('@{lime-6}', 5) `); -@lime-6: #a0d911; -@lime-7: color(~`colorPalette('@{lime-6}', 7) `); -@lime-8: color(~`colorPalette('@{lime-6}', 8) `); -@lime-9: color(~`colorPalette('@{lime-6}', 9) `); -@lime-10: color(~`colorPalette('@{lime-6}', 10) `); - -@gold-1: color(~`colorPalette('@{gold-6}', 1) `); -@gold-2: color(~`colorPalette('@{gold-6}', 2) `); -@gold-3: color(~`colorPalette('@{gold-6}', 3) `); -@gold-4: color(~`colorPalette('@{gold-6}', 4) `); -@gold-5: color(~`colorPalette('@{gold-6}', 5) `); -@gold-6: #faad14; -@gold-7: color(~`colorPalette('@{gold-6}', 7) `); -@gold-8: color(~`colorPalette('@{gold-6}', 8) `); -@gold-9: color(~`colorPalette('@{gold-6}', 9) `); -@gold-10: color(~`colorPalette('@{gold-6}', 10) `); - -// The prefix to use on all css classes from ant. -@ant-prefix : ant; - -// -------- Colors ----------- -@primary-color : @blue-6; -@info-color : @blue-6; -@success-color : @green-6; -@processing-color : @blue-6; -@error-color : @red-6; -@highlight-color : @red-6; -@warning-color : @gold-6; -@normal-color : #d9d9d9; - -// Color used by default to control hover and active backgrounds and for -// alert info backgrounds. -@primary-1: color(~`colorPalette('@{primary-color}', 1) `); // replace tint(@primary-color, 90%) -@primary-2: color(~`colorPalette('@{primary-color}', 2) `); // replace tint(@primary-color, 80%) -@primary-3: color(~`colorPalette('@{primary-color}', 3) `); // unused -@primary-4: color(~`colorPalette('@{primary-color}', 4) `); // unused -@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%) -@primary-6: @primary-color; // color used to control the text color of active buttons, don't use, use @primary-color -@primary-7: color(~`colorPalette('@{primary-color}', 7) `); // replace shade(@primary-color, 5%) -@primary-8: color(~`colorPalette('@{primary-color}', 8) `); // unused -@primary-9: color(~`colorPalette('@{primary-color}', 9) `); // unused -@primary-10: color(~`colorPalette('@{primary-color}', 10) `); // unused - -// Base Scaffolding Variables -// --- - -// Background color for `` -@body-background : #fff; -// Base background color for most components -@component-background : #fff; -@font-family : "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, -"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; -@code-family : "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; -@heading-color : fade(#000, 85%); -@text-color : fade(#000, 65%); -@text-color-secondary : fade(#000, 45%); -@heading-color-dark : fade(#fff, 100%); -@text-color-dark : fade(#fff, 85%); -@text-color-secondary-dark: fade(#fff, 65%); -@font-variant-base : tabular-nums; -@font-size-base : 14px; -@font-size-lg : @font-size-base + 2px; -@font-size-sm : 12px; -@line-height-base : 1.5; -@border-radius-base : 4px; -@border-radius-sm : 2px; - -// vertical paddings -@padding-lg : 24px; // containers -@padding-md : 16px; // small containers and buttons -@padding-sm : 12px; // Form controls and items -@padding-xs : 8px; // small items - -// vertical padding for all form controls -@control-padding-horizontal: @padding-sm; -@control-padding-horizontal-sm: @padding-xs; - -// The background colors for active and hover states for things like -// list items or table cells. -@item-active-bg : @primary-1; -@item-hover-bg : @primary-1; - -// ICONFONT -@iconfont-css-prefix : anticon; - -// LINK -@link-color : @primary-color; -@link-hover-color : color(~`colorPalette("@{link-color}", 5)`); -@link-active-color : color(~`colorPalette("@{link-color}", 7)`); -@link-decoration : none; -@link-hover-decoration : none; - -// Animation -@ease-base-out : cubic-bezier(0.7, 0.3, 0.1, 1); -@ease-base-in : cubic-bezier(0.9, 0, 0.3, 0.7); -@ease-out : cubic-bezier(0.215, 0.61, 0.355, 1); -@ease-in : cubic-bezier(0.55, 0.055, 0.675, 0.19); -@ease-in-out : cubic-bezier(0.645, 0.045, 0.355, 1); -@ease-out-back : cubic-bezier(0.12, 0.4, 0.29, 1.46); -@ease-in-back : cubic-bezier(0.71, -0.46, 0.88, 0.6); -@ease-in-out-back : cubic-bezier(0.71, -0.46, 0.29, 1.46); -@ease-out-circ : cubic-bezier(0.08, 0.82, 0.17, 1); -@ease-in-circ : cubic-bezier(0.6, 0.04, 0.98, 0.34); -@ease-in-out-circ : cubic-bezier(0.78, 0.14, 0.15, 0.86); -@ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1); -@ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06); -@ease-in-out-quint : cubic-bezier(0.86, 0, 0.07, 1); - -// Border color -@border-color-base : hsv(0, 0, 85%); // base border outline a component -@border-color-split : hsv(0, 0, 91%); // split border inside a component -@border-width-base : 1px; // width of the border for a component -@border-style-base : solid; // style of a components border - -// Outline -@outline-blur-size : 0; -@outline-width : 2px; -@outline-color : @primary-color; - -@background-color-light : hsv(0, 0, 98%); // background of header and selected item -@background-color-base : hsv(0, 0, 96%); // Default grey background color - -// Disabled states -@disabled-color : fade(#000, 25%); -@disabled-bg : @background-color-base; -@disabled-color-dark : fade(#fff, 35%); - -// Shadow -@shadow-color : rgba(0, 0, 0, .15); -@box-shadow-base : @shadow-1-down; -@shadow-1-up : 0 -2px 8px @shadow-color; -@shadow-1-down : 0 2px 8px @shadow-color; -@shadow-1-left : -2px 0 8px @shadow-color; -@shadow-1-right : 2px 0 8px @shadow-color; -@shadow-2 : 0 4px 12px @shadow-color; - -// Buttons -@btn-font-weight : 400; -@btn-border-radius-base : @border-radius-base; -@btn-border-radius-sm : @border-radius-base; - -@btn-primary-color : #fff; -@btn-primary-bg : @primary-color; - -@btn-default-color : @text-color; -@btn-default-bg : #fff; -@btn-default-border : @border-color-base; - -@btn-danger-color : @error-color; -@btn-danger-bg : @background-color-base; -@btn-danger-border : @border-color-base; - -@btn-disable-color : @disabled-color; -@btn-disable-bg : @disabled-bg; -@btn-disable-border : @border-color-base; - -@btn-padding-base : 0 @padding-md - 1px; -@btn-font-size-lg : @font-size-lg; -@btn-font-size-sm : @font-size-base; -@btn-padding-lg : @btn-padding-base; -@btn-padding-sm : 0 @padding-xs - 1px; - -@btn-height-base : 32px; -@btn-height-lg : 40px; -@btn-height-sm : 24px; - -@btn-circle-size : @btn-height-base; -@btn-circle-size-lg : @btn-height-lg; -@btn-circle-size-sm : @btn-height-sm; - -@btn-group-border : @primary-5; - -// Checkbox -@checkbox-size : 16px; -@checkbox-color : @primary-color; -@checkbox-check-color : #fff; -@checkbox-border-width : @border-width-base; - -// Radio -@radio-size : 16px; -@radio-dot-color : @primary-color; - -// Radio buttons -@radio-button-bg : @btn-default-bg; -@radio-button-color : @btn-default-color; -@radio-button-hover-color : @primary-5; -@radio-button-active-color : @primary-7; - -// Media queries breakpoints -// Extra small screen / phone -@screen-xs : 480px; -@screen-xs-min : @screen-xs; - -// Small screen / tablet -@screen-sm : 576px; -@screen-sm-min : @screen-sm; - -// Medium screen / desktop -@screen-md : 768px; -@screen-md-min : @screen-md; - -// Large screen / wide desktop -@screen-lg : 992px; -@screen-lg-min : @screen-lg; - -// Extra large screen / full hd -@screen-xl : 1200px; -@screen-xl-min : @screen-xl; - -// Extra extra large screen / large descktop -@screen-xxl : 1600px; -@screen-xxl-min : @screen-xxl; - -// provide a maximum -@screen-xs-max : (@screen-sm-min - 1px); -@screen-sm-max : (@screen-md-min - 1px); -@screen-md-max : (@screen-lg-min - 1px); -@screen-lg-max : (@screen-xl-min - 1px); -@screen-xl-max : (@screen-xxl-min - 1px); - -// Grid system -@grid-columns : 24; -@grid-gutter-width : 0; - -// Layout -@layout-body-background : #f0f2f5; -@layout-header-background : #001529; -@layout-footer-background : @layout-body-background; -@layout-header-height : 64px; -@layout-header-padding : 0 50px; -@layout-footer-padding : 24px 50px; -@layout-sider-background : @layout-header-background; -@layout-trigger-height : 48px; -@layout-trigger-background : #002140; -@layout-trigger-color : #fff; -@layout-zero-trigger-width : 36px; -@layout-zero-trigger-height : 42px; -// Layout light theme -@layout-sider-background-light : #fff; -@layout-trigger-background-light: #fff; -@layout-trigger-color-light : @text-color; - -// z-index list -@zindex-affix : 10; -@zindex-back-top : 10; -@zindex-modal-mask : 1000; -@zindex-modal : 1000; -@zindex-notification : 1010; -@zindex-message : 1010; -@zindex-popover : 1030; -@zindex-picker : 1050; -@zindex-dropdown : 1050; -@zindex-tooltip : 1060; - -// Animation -@animation-duration-slow: 0.3s; // Modal -@animation-duration-base: 0.2s; -@animation-duration-fast: 0.1s; // Tooltip - -// Form -// --- -@label-required-color : @highlight-color; -@label-color : @heading-color; -@form-item-margin-bottom : 24px; -@form-item-trailing-colon : true; -@form-vertical-label-padding : 0 0 8px; -@form-vertical-label-margin : 0; - -// Input -// --- -@input-height-base : 32px; -@input-height-lg : 40px; -@input-height-sm : 24px; -@input-padding-horizontal : @control-padding-horizontal - 1px; -@input-padding-horizontal-base: @input-padding-horizontal; -@input-padding-horizontal-sm : @control-padding-horizontal-sm - 1px; -@input-padding-horizontal-lg : @input-padding-horizontal; -@input-padding-vertical-base : 4px; -@input-padding-vertical-sm : 1px; -@input-padding-vertical-lg : 6px; -@input-placeholder-color : hsv(0, 0, 75%); -@input-color : @text-color; -@input-border-color : @border-color-base; -@input-bg : #fff; -@input-addon-bg : @background-color-light; -@input-hover-border-color : @primary-color; -@input-disabled-bg : @disabled-bg; -@input-outline-offset : 0 0; - -// Tooltip -// --- -//* Tooltip max width -@tooltip-max-width: 250px; -//** Tooltip text color -@tooltip-color: #fff; -//** Tooltip background color -@tooltip-bg: rgba(0, 0, 0, 0.75); -//** Tooltip arrow width -@tooltip-arrow-width: 5px; -//** Tooltip distance with trigger -@tooltip-distance: @tooltip-arrow-width - 1px + 4px; -//** Tooltip arrow color -@tooltip-arrow-color: @tooltip-bg; - -// Popover -// --- -//** Popover body background color -@popover-bg: #fff; -//** Popover text color -@popover-color: @text-color; -//** Popover maximum width -@popover-min-width: 177px; -//** Popover arrow width -@popover-arrow-width: 6px; -//** Popover arrow color -@popover-arrow-color: @popover-bg; -//** Popover outer arrow width -//** Popover outer arrow color -@popover-arrow-outer-color: @popover-bg; -//** Popover distance with trigger -@popover-distance: @popover-arrow-width + 4px; - -// Modal -// -- -@modal-header-bg: @component-background; -@modal-mask-bg: rgba(0, 0, 0, 0.65); - -// Progress -// -- -@progress-default-color: @processing-color; -@progress-remaining-color: @background-color-base; -@progress-text-color: @text-color; - -// Menu -// --- -@menu-inline-toplevel-item-height: 40px; -@menu-item-height: 40px; -@menu-collapsed-width: 80px; -@menu-bg: @component-background; -@menu-popup-bg: @component-background; -@menu-item-color: @text-color; -@menu-highlight-color: @primary-color; -@menu-item-active-bg: @item-active-bg; -@menu-item-active-border-width: 3px; -@menu-item-group-title-color: @text-color-secondary; -// dark theme -@menu-dark-color: @text-color-secondary-dark; -@menu-dark-bg: @layout-header-background; -@menu-dark-arrow-color: #fff; -@menu-dark-submenu-bg: #000c17; -@menu-dark-highlight-color: #fff; -@menu-dark-item-active-bg: @primary-color; - -// Spin -// --- -@spin-dot-size-sm: 14px; -@spin-dot-size: 20px; -@spin-dot-size-lg: 32px; - -// Table -// -- -@table-header-bg: @background-color-light; -@table-header-color: @heading-color; -@table-header-sort-bg: @background-color-base; -@table-body-sort-bg: rgba(0, 0, 0, 0.01); -@table-row-hover-bg: @primary-1; -@table-selected-row-bg: #fafafa; -@table-expanded-row-bg: #fbfbfb; -@table-padding-vertical: 16px; -@table-padding-horizontal: 16px; -@table-border-radius-base : @border-radius-base; - -// Tag -// -- -@tag-default-bg: @background-color-light; -@tag-default-color: @text-color; -@tag-font-size: @font-size-sm; - -// TimePicker -// --- -@time-picker-panel-column-width: 56px; -@time-picker-panel-width: @time-picker-panel-column-width * 3; -@time-picker-selected-bg: @background-color-base; - -// Carousel -// --- -@carousel-dot-width: 16px; -@carousel-dot-height: 3px; -@carousel-dot-active-width: 24px; - -// Badge -// --- -@badge-height: 20px; -@badge-dot-size: 6px; -@badge-font-size: @font-size-sm; -@badge-font-weight: normal; -@badge-status-size: 6px; - -// Rate -// --- -@rate-star-color: @yellow-6; -@rate-star-bg: @border-color-split; - -// Card -// --- -@card-head-color: @heading-color; -@card-head-background: transparent; -@card-head-padding: 16px; -@card-inner-head-padding: 12px; -@card-padding-base: 24px; -@card-padding-wider: 32px; -@card-actions-background: @background-color-light; -@card-shadow: 0 2px 8px rgba(0, 0, 0, 0.09); - -// Comment -// --- -@comment-padding-base: 16px 0; -@comment-nest-indent: 44px; -@comment-author-name-color: @text-color-secondary; -@comment-author-time-color: #ccc; -@comment-action-color: @text-color-secondary; -@comment-action-hover-color: #595959; - -// Tabs -// --- -@tabs-card-head-background: @background-color-light; -@tabs-card-height: 40px; -@tabs-card-active-color: @primary-color; -@tabs-title-font-size: @font-size-base; -@tabs-title-font-size-lg: @font-size-lg; -@tabs-title-font-size-sm: @font-size-base; -@tabs-ink-bar-color: @primary-color; -@tabs-bar-margin: 0 0 16px 0; -@tabs-horizontal-margin: 0 32px 0 0; -@tabs-horizontal-padding: 12px 16px; -@tabs-horizontal-padding-lg: 16px; -@tabs-horizontal-padding-sm: 8px 16px; -@tabs-vertical-padding: 8px 24px; -@tabs-vertical-margin: 0 0 16px 0; -@tabs-scrolling-size: 32px; -@tabs-highlight-color: @primary-color; -@tabs-hover-color: @primary-5; -@tabs-active-color: @primary-7; - -// BackTop -// --- -@back-top-color: #fff; -@back-top-bg: @text-color-secondary; -@back-top-hover-bg: @text-color; - -// Avatar -// --- -@avatar-size-base: 32px; -@avatar-size-lg: 40px; -@avatar-size-sm: 24px; -@avatar-font-size-base: 18px; -@avatar-font-size-lg: 24px; -@avatar-font-size-sm: 14px; -@avatar-bg: #ccc; -@avatar-color: #fff; -@avatar-border-radius: @border-radius-base; - -// Switch -// --- -@switch-height: 22px; -@switch-sm-height: 16px; -@switch-sm-checked-margin-left: -(@switch-sm-height - 3px); -@switch-disabled-opacity: 0.4; -@switch-color: @primary-color; - -// Pagination -// --- -@pagination-item-size: 32px; -@pagination-item-size-sm: 24px; -@pagination-font-family: Arial; -@pagination-font-weight-active: 500; - -// Breadcrumb -// --- -@breadcrumb-base-color: @text-color-secondary; -@breadcrumb-last-item-color: @text-color; -@breadcrumb-font-size: @font-size-base; -@breadcrumb-icon-font-size: @font-size-base; -@breadcrumb-link-color: @text-color-secondary; -@breadcrumb-link-color-hover: @primary-5; -@breadcrumb-separator-color: @text-color-secondary; -@breadcrumb-separator-margin: 0 @padding-xs; - -// Slider -// --- -@slider-margin: 14px 6px 10px; -@slider-rail-background-color: @background-color-base; -@slider-rail-background-color-hover: #e1e1e1; -@slider-track-background-color: @primary-5; -@slider-track-background-color-hover: @primary-6; -@slider-handle-color: @primary-5; -@slider-handle-color-hover: @primary-6; -@slider-handle-color-focus: tint(@primary-color, 20%); -@slider-handle-color-focus-shadow: fade(@primary-color, 20%); -@slider-handle-color-tooltip-open: @primary-color; -@slider-dot-border-color: @border-color-split; -@slider-dot-border-color-active: @primary-5; -@slider-disabled-color: @disabled-color; -@slider-disabled-background-color: @component-background; - -// Tree -// --- -@tree-title-height: 24px; -@tree-child-padding: 18px; -@tree-directory-selected-color: #fff; -@tree-directory-selected-bg: @primary-color; - -// Collapse -// --- -@collapse-header-padding: 12px 0 12px 40px; -@collapse-header-bg: @background-color-light; -@collapse-content-padding: @padding-md; -@collapse-content-bg: @component-background; - -// Skeleton -// --- -@skeleton-color: #f2f2f2; - -// Transfer -// --- -@transfer-disabled-bg: @disabled-bg; - -// Message -// --- -@message-notice-content-padding: 10px 16px; - -// Motion -// --- -@wave-animation-width: 6px; - -// Alert -// --- -@alert-success-border-color: ~`colorPalette('@{success-color}', 3) `; -@alert-success-bg-color: ~`colorPalette('@{success-color}', 1) `; -@alert-success-icon-color: @success-color; -@alert-info-border-color: ~`colorPalette('@{info-color}', 3) `; -@alert-info-bg-color: ~`colorPalette('@{info-color}', 1) `; -@alert-info-icon-color: @info-color; -@alert-warning-border-color: ~`colorPalette('@{warning-color}', 3) `; -@alert-warning-bg-color: ~`colorPalette('@{warning-color}', 1) `; -@alert-warning-icon-color: @warning-color; -@alert-error-border-color: ~`colorPalette('@{error-color}', 3) `; -@alert-error-bg-color: ~`colorPalette('@{error-color}', 1) `; -@alert-error-icon-color: @error-color; - -// List -// --- -@list-empty-text-padding: @padding-md; -@list-item-padding: @padding-sm 0; -@list-item-content-margin: 0 0 @padding-md 0; -@list-item-meta-margin-bottom: @padding-md; -@list-item-meta-avatar-margin-right: @padding-md; -@list-item-meta-title-margin-bottom: @padding-sm; - -// Mixins -// -------------------------------------------------- -// Sizing shortcuts - -.size(@width; @height) { - width: @width; - height: @height; -} - -.square(@size) { - .size(@size; @size); -} - -// Compatibility for browsers. - -// Placeholder text -.placeholder(@color: @input-placeholder-color) { - // Firefox - &::-moz-placeholder { - color: @color; - opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526 - } - // Internet Explorer 10+ - &:-ms-input-placeholder { - color: @color; - } - // Safari and Chrome - &::-webkit-input-placeholder { - color: @color; - } -} - -// mixins for clearfix -// ------------------------ -.clearfix() { - zoom: 1; - &:before, - &:after { - content: ''; - display: table; - } - &:after { - clear: both; - } -} - -.iconfont-mixin() { - display: inline-block; - font-style: normal; - vertical-align: -0.125em; // for SVG icon, see https://blog.prototypr.io/align-svg-icons-to-text-and-say-goodbye-to-font-icons-d44b3d7b26b4 - text-align: center; - text-transform: none; - line-height: 0; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - > * { - line-height: 1; - } - - svg { - display: inline-block; - } - - &:before { - display: none; // dont display old icon. - } - - & &-icon { - display: block; - } -} - -// for iconfont font size -// fix chrome 12px bug, support ie -.iconfont-size-under-12px(@size, @rotate: 0deg) { - display: inline-block; - @font-scale: unit(@size / 12px); - font-size: 12px; - // IE9 - font-size: ~'@{size} \9'; - transform: scale(@font-scale) rotate(@rotate); - :root & { - font-size: @font-size-sm; // reset IE9 and above - } -} - -.motion-common(@duration: @animation-duration-base) { - animation-duration: @duration; - animation-fill-mode: both; -} - -.motion-common-leave(@duration: @animation-duration-base) { - animation-duration: @duration; - animation-fill-mode: both; -} - -.make-motion(@className, @keyframeName, @duration: @animation-duration-base) { - .@{className}-enter, - .@{className}-appear { - .motion-common(@duration); - animation-play-state: paused; - } - .@{className}-leave { - .motion-common-leave(@duration); - animation-play-state: paused; - } - .@{className}-enter.@{className}-enter-active, - .@{className}-appear.@{className}-appear-active { - animation-name: ~'@{keyframeName}In'; - animation-play-state: running; - } - .@{className}-leave.@{className}-leave-active { - animation-name: ~'@{keyframeName}Out'; - animation-play-state: running; - pointer-events: none; - } -} - -.reset-component() { - font-family: @font-family; - font-size: @font-size-base; - font-variant: @font-variant-base; - line-height: @line-height-base; - color: @text-color; - box-sizing: border-box; - margin: 0; - padding: 0; - list-style: none; -} - -/* stylelint-disable at-rule-no-unknown */ - -// Reboot -// -// Normalization of HTML elements, manually forked from Normalize.css to remove -// styles targeting irrelevant browsers while applying new styles. -// -// Normalize is licensed MIT. https://github.com/necolas/normalize.css - -@font-face { - font-family: 'Chinese Quote'; - src: local('PingFang SC'), local('SimSun'); - unicode-range: U+2018, U+2019, U+201c, U+201d; -} - -// HTML & Body reset -html, -body { - .square(100%); -} - -// remove the clear button of a text input control in IE10+ -input::-ms-clear, -input::-ms-reveal { - display: none; -} - -// Document -// -// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`. -// 2. Change the default font family in all browsers. -// 3. Correct the line height in all browsers. -// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS. -// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so -// we force a non-overlapping, non-auto-hiding scrollbar to counteract. -// 6. Change the default tap highlight to be completely transparent in iOS. - -*, -*::before, -*::after { - box-sizing: border-box; // 1 -} - -html { - font-family: sans-serif; // 2 - line-height: 1.15; // 3 - -webkit-text-size-adjust: 100%; // 4 - -ms-text-size-adjust: 100%; // 4 - -ms-overflow-style: scrollbar; // 5 - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); // 6 -} - -// IE10+ doesn't honor `` in some cases. -@-ms-viewport { - width: device-width; -} - -// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers) -article, -aside, -dialog, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section { - display: block; -} - -// Body -// -// 1. remove the margin in all browsers. -// 2. As a best practice, apply a default `body-background`. - -body { - margin: 0; // 1 - font-family: @font-family; - font-size: @font-size-base; - font-variant: @font-variant-base; - line-height: @line-height-base; - color: @text-color; - background-color: @body-background; // 2 -} - -// Suppress the focus outline on elements that cannot be accessed via keyboard. -// This prevents an unwanted focus outline from appearing around elements that -// might still respond to pointer events. -// -// Credit: https://github.com/suitcss/base -[tabindex='-1']:focus { - outline: none !important; -} - -// Content grouping -// -// 1. Add the correct box sizing in Firefox. -// 2. Show the overflow in Edge and IE. - -hr { - box-sizing: content-box; // 1 - height: 0; // 1 - overflow: visible; // 2 -} - -// -// Typography -// - -// remove top margins from headings -// -// By default, `

    `-`

    ` all receive top and bottom margins. We nuke the top -// margin for easier control within type scales as it avoids margin collapsing. -h1, -h2, -h3, -h4, -h5, -h6 { - margin-top: 0; - margin-bottom: 0.5em; - color: @heading-color; - font-weight: 500; -} - -// Reset margins on paragraphs -// -// Similarly, the top margin on `

    `s get reset. However, we also reset the -// bottom margin to use `em` units instead of `em`. -p { - margin-top: 0; - margin-bottom: 1em; -} - -// Abbreviations -// -// 1. remove the bottom border in Firefox 39-. -// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. -// 3. Add explicit cursor to indicate changed behavior. -// 4. Duplicate behavior to the data-* attribute for our tooltip plugin - -abbr[title], -abbr[data-original-title] { - // 4 - text-decoration: underline; // 2 - text-decoration: underline dotted; // 2 - cursor: help; // 3 - border-bottom: 0; // 1 -} - -address { - margin-bottom: 1em; - font-style: normal; - line-height: inherit; -} - -input[type='text'], -input[type='password'], -input[type='number'], -textarea { - -webkit-appearance: none; -} - -ol, -ul, -dl { - margin-top: 0; - margin-bottom: 1em; -} - -ol ol, -ul ul, -ol ul, -ul ol { - margin-bottom: 0; -} - -dt { - font-weight: 500; -} - -dd { - margin-bottom: 0.5em; - margin-left: 0; // Undo browser default -} - -blockquote { - margin: 0 0 1em; -} - -dfn { - font-style: italic; // Add the correct font style in Android 4.3- -} - -b, -strong { - font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari -} - -small { - font-size: 80%; // Add the correct font size in all browsers -} - -// -// Prevent `sub` and `sup` elements from affecting the line height in -// all browsers. -// - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} -sup { - top: -0.5em; -} - -// -// Links -// - -a { - color: @link-color; - background-color: transparent; // remove the gray background on active links in IE 10. - text-decoration: @link-decoration; - outline: none; - cursor: pointer; - transition: color 0.3s; - -webkit-text-decoration-skip: objects; // remove gaps in links underline in iOS 8+ and Safari 8+. - - &:focus { - text-decoration: underline; - text-decoration-skip: ink; - } - - &:hover { - color: @link-hover-color; - } - - &:active { - color: @link-active-color; - } - - &:active, - &:hover { - outline: 0; - text-decoration: @link-hover-decoration; - } - - &[disabled] { - color: @disabled-color; - cursor: not-allowed; - pointer-events: none; - } -} - -// -// Code -// - -pre, -code, -kbd, -samp { - font-family: @code-family; - font-size: 1em; // Correct the odd `em` font sizing in all browsers. -} - -pre { - // remove browser default top margin - margin-top: 0; - // Reset browser default of `1em` to use `em`s - margin-bottom: 1em; - // Don't allow content to break outside - overflow: auto; -} - -// -// Figures -// -figure { - // Apply a consistent margin strategy (matches our type styles). - margin: 0 0 1em; -} - -// -// Images and content -// - -img { - vertical-align: middle; - border-style: none; // remove the border on images inside links in IE 10-. -} - -svg:not(:root) { - overflow: hidden; // Hide the overflow in IE -} - -// Avoid 300ms click delay on touch devices that support the `touch-action` CSS property. -// -// In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11 -// DON'T remove the click delay when `` is present. -// However, they DO support emoving the click delay via `touch-action: manipulation`. -// See: -// * https://getbootstrap.com/docs/4.0/content/reboot/#click-delay-optimization-for-touch -// * http://caniuse.com/#feat=css-touch-action -// * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay - -a, -area, -button, -[role='button'], -input:not([type='range']), -label, -select, -summary, -textarea { - touch-action: manipulation; -} - -// -// Tables -// - -table { - border-collapse: collapse; // Prevent double borders -} - -caption { - padding-top: 0.75em; - padding-bottom: 0.3em; - color: @text-color-secondary; - text-align: left; - caption-side: bottom; -} - -th { - // Matches default `` alignment by inheriting from the ``, or the - // closest parent with a set `text-align`. - text-align: inherit; -} - -// -// Forms -// - -input, -button, -select, -optgroup, -textarea { - margin: 0; // remove the margin in Firefox and Safari - font-family: inherit; - font-size: inherit; - line-height: inherit; - color: inherit; -} - -button, -input { - overflow: visible; // Show the overflow in Edge -} - -button, -select { - text-transform: none; // remove the inheritance of text transform in Firefox -} - -// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` -// controls in Android 4. -// 2. Correct the inability to style clickable types in iOS and Safari. -button, -html [type="button"], // 1 -[type="reset"], -[type="submit"] { - -webkit-appearance: button; // 2 -} - -// remove inner border and padding from Firefox, but don't restore the outline like Normalize. -button::-moz-focus-inner, -[type='button']::-moz-focus-inner, -[type='reset']::-moz-focus-inner, -[type='submit']::-moz-focus-inner { - padding: 0; - border-style: none; -} - -input[type='radio'], -input[type='checkbox'] { - box-sizing: border-box; // 1. Add the correct box sizing in IE 10- - padding: 0; // 2. remove the padding in IE 10- -} - -input[type='date'], -input[type='time'], -input[type='datetime-local'], -input[type='month'] { - // remove the default appearance of temporal inputs to avoid a Mobile Safari - // bug where setting a custom line-height prevents text from being vertically - // centered within the input. - // See https://bugs.webkit.org/show_bug.cgi?id=139848 - // and https://github.com/twbs/bootstrap/issues/11266 - -webkit-appearance: listbox; -} - -textarea { - overflow: auto; // remove the default vertical scrollbar in IE. - // Textareas should really only resize vertically so they don't break their (horizontal) containers. - resize: vertical; -} - -fieldset { - // Browsers set a default `min-width: min-content;` on fieldsets, - // unlike e.g. `

    `s, which have `min-width: 0;` by default. - // So we reset that to ensure fieldsets behave more like a standard block element. - // See https://github.com/twbs/bootstrap/issues/12359 - // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements - min-width: 0; - // Reset the default outline behavior of fieldsets so they don't affect page layout. - padding: 0; - margin: 0; - border: 0; -} - -// 1. Correct the text wrapping in Edge and IE. -// 2. Correct the color inheritance from `fieldset` elements in IE. -legend { - display: block; - width: 100%; - max-width: 100%; // 1 - padding: 0; - margin-bottom: 0.5em; - font-size: 1.5em; - line-height: inherit; - color: inherit; // 2 - white-space: normal; // 1 -} - -progress { - vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera. -} - -// Correct the cursor style of incement and decement buttons in Chrome. -[type='number']::-webkit-inner-spin-button, -[type='number']::-webkit-outer-spin-button { - height: auto; -} - -[type='search'] { - // This overrides the extra rounded corners on search inputs in iOS so that our - // `.form-control` class can properly style them. Note that this cannot simply - // be added to `.form-control` as it's not specific enough. For details, see - // https://github.com/twbs/bootstrap/issues/11586. - outline-offset: -2px; // 2. Correct the outline style in Safari. - -webkit-appearance: none; -} - -// -// remove the inner padding and cancel buttons in Chrome and Safari on macOS. -// - -[type='search']::-webkit-search-cancel-button, -[type='search']::-webkit-search-decoration { - -webkit-appearance: none; -} - -// -// 1. Correct the inability to style clickable types in iOS and Safari. -// 2. Change font properties to `inherit` in Safari. -// - -::-webkit-file-upload-button { - font: inherit; // 2 - -webkit-appearance: button; // 1 -} - -// -// Correct element displays -// - -output { - display: inline-block; -} - -summary { - display: list-item; // Add the correct display in all browsers -} - -template { - display: none; // Add the correct display in IE -} - -// Always hide an element with the `hidden` HTML attribute (from PureCSS). -// Needed for proper display in IE 10-. -[hidden] { - display: none !important; -} - -mark { - padding: 0.2em; - background-color: @yellow-1; -} - -::selection { - background: @primary-color; - color: #fff; -} - -// Utility classes -.clearfix { - .clearfix(); -} - -.@{iconfont-css-prefix} { - .iconfont-mixin(); -} - -.@{iconfont-css-prefix}-spin:before { - display: inline-block; - animation: loadingCircle 1s infinite linear; -} -.@{iconfont-css-prefix}-spin { - display: inline-block; - animation: loadingCircle 1s infinite linear; -} - -.fade-motion(@className, @keyframeName) { - .make-motion(@className, @keyframeName); - .@{className}-enter, - .@{className}-appear { - opacity: 0; - animation-timing-function: linear; - } - .@{className}-leave { - animation-timing-function: linear; - } -} - -.fade-motion(fade, antFade); - -@keyframes antFadeIn { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -@keyframes antFadeOut { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } -} - -.move-motion(@className, @keyframeName) { - .make-motion(@className, @keyframeName); - .@{className}-enter, - .@{className}-appear { - opacity: 0; - animation-timing-function: @ease-out-circ; - } - .@{className}-leave { - animation-timing-function: @ease-in-circ; - } -} - -.move-motion(move-up, antMoveUp); -.move-motion(move-down, antMoveDown); -.move-motion(move-left, antMoveLeft); -.move-motion(move-right, antMoveRight); - -@keyframes antMoveDownIn { - 0% { - transform-origin: 0 0; - transform: translateY(100%); - opacity: 0; - } - 100% { - transform-origin: 0 0; - transform: translateY(0%); - opacity: 1; - } -} - -@keyframes antMoveDownOut { - 0% { - transform-origin: 0 0; - transform: translateY(0%); - opacity: 1; - } - 100% { - transform-origin: 0 0; - transform: translateY(100%); - opacity: 0; - } -} - -@keyframes antMoveLeftIn { - 0% { - transform-origin: 0 0; - transform: translateX(-100%); - opacity: 0; - } - 100% { - transform-origin: 0 0; - transform: translateX(0%); - opacity: 1; - } -} - -@keyframes antMoveLeftOut { - 0% { - transform-origin: 0 0; - transform: translateX(0%); - opacity: 1; - } - 100% { - transform-origin: 0 0; - transform: translateX(-100%); - opacity: 0; - } -} - -@keyframes antMoveRightIn { - 0% { - opacity: 0; - transform-origin: 0 0; - transform: translateX(100%); - } - 100% { - opacity: 1; - transform-origin: 0 0; - transform: translateX(0%); - } -} - -@keyframes antMoveRightOut { - 0% { - transform-origin: 0 0; - transform: translateX(0%); - opacity: 1; - } - 100% { - transform-origin: 0 0; - transform: translateX(100%); - opacity: 0; - } -} - -@keyframes antMoveUpIn { - 0% { - transform-origin: 0 0; - transform: translateY(-100%); - opacity: 0; - } - 100% { - transform-origin: 0 0; - transform: translateY(0%); - opacity: 1; - } -} - -@keyframes antMoveUpOut { - 0% { - transform-origin: 0 0; - transform: translateY(0%); - opacity: 1; - } - 100% { - transform-origin: 0 0; - transform: translateY(-100%); - opacity: 0; - } -} - -@keyframes loadingCircle { - 100% { - transform: rotate(360deg); - } -} - -[ant-click-animating], -[ant-click-animating-without-extra-node] { - position: relative; -} - -[ant-click-animating-without-extra-node]:after, -.ant-click-animating-node { - content: ''; - position: absolute; - top: -1px; - left: -1px; - bottom: -1px; - right: -1px; - border-radius: inherit; - border: 0 solid @primary-color; - opacity: 0.2; - animation: fadeEffect 2s @ease-out-circ, waveEffect 0.4s @ease-out-circ; - animation-fill-mode: forwards; - display: block; - pointer-events: none; -} - -@keyframes waveEffect { - 100% { - top: -@wave-animation-width; - left: -@wave-animation-width; - bottom: -@wave-animation-width; - right: -@wave-animation-width; - border-width: @wave-animation-width; - } -} - -@keyframes fadeEffect { - 100% { - opacity: 0; - } -} - -.slide-motion(@className, @keyframeName) { - .make-motion(@className, @keyframeName); - .@{className}-enter, - .@{className}-appear { - opacity: 0; - animation-timing-function: @ease-out-quint; - } - .@{className}-leave { - animation-timing-function: @ease-in-quint; - } -} - -.slide-motion(slide-up, antSlideUp); -.slide-motion(slide-down, antSlideDown); -.slide-motion(slide-left, antSlideLeft); -.slide-motion(slide-right, antSlideRight); - -@keyframes antSlideUpIn { - 0% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0.8); - } - 100% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } -} - -@keyframes antSlideUpOut { - 0% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } - 100% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0.8); - } -} - -@keyframes antSlideDownIn { - 0% { - opacity: 0; - transform-origin: 100% 100%; - transform: scaleY(0.8); - } - 100% { - opacity: 1; - transform-origin: 100% 100%; - transform: scaleY(1); - } -} - -@keyframes antSlideDownOut { - 0% { - opacity: 1; - transform-origin: 100% 100%; - transform: scaleY(1); - } - 100% { - opacity: 0; - transform-origin: 100% 100%; - transform: scaleY(0.8); - } -} - -@keyframes antSlideLeftIn { - 0% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleX(0.8); - } - 100% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleX(1); - } -} - -@keyframes antSlideLeftOut { - 0% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleX(1); - } - 100% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleX(0.8); - } -} - -@keyframes antSlideRightIn { - 0% { - opacity: 0; - transform-origin: 100% 0%; - transform: scaleX(0.8); - } - 100% { - opacity: 1; - transform-origin: 100% 0%; - transform: scaleX(1); - } -} - -@keyframes antSlideRightOut { - 0% { - opacity: 1; - transform-origin: 100% 0%; - transform: scaleX(1); - } - 100% { - opacity: 0; - transform-origin: 100% 0%; - transform: scaleX(0.8); - } -} - -.swing-motion(@className, @keyframeName) { - .@{className}-enter, - .@{className}-appear { - .motion-common(); - animation-play-state: paused; - } - .@{className}-enter.@{className}-enter-active, - .@{className}-appear.@{className}-appear-active { - animation-name: ~'@{keyframeName}In'; - animation-play-state: running; - } -} - -.swing-motion(swing, antSwing); - -@keyframes antSwingIn { - 0%, - 100% { - transform: translateX(0); - } - 20% { - transform: translateX(-10px); - } - 40% { - transform: translateX(10px); - } - 60% { - transform: translateX(-5px); - } - 80% { - transform: translateX(5px); - } -} - -.zoom-motion(@className, @keyframeName, @duration: @animation-duration-base) { - .make-motion(@className, @keyframeName, @duration); - .@{className}-enter, - .@{className}-appear { - transform: scale(0); // need this by yiminghe - animation-timing-function: @ease-out-circ; - } - .@{className}-leave { - animation-timing-function: @ease-in-out-circ; - } -} - -// For Modal, Select choosen item -.zoom-motion(zoom, antZoom); -// For Popover, Popconfirm, Dropdown -.zoom-motion(zoom-big, antZoomBig); -// For Tooltip -.zoom-motion(zoom-big-fast, antZoomBig, @animation-duration-fast); - -.zoom-motion(zoom-up, antZoomUp); -.zoom-motion(zoom-down, antZoomDown); -.zoom-motion(zoom-left, antZoomLeft); -.zoom-motion(zoom-right, antZoomRight); - -@keyframes antZoomIn { - 0% { - opacity: 0; - transform: scale(0.2); - } - 100% { - opacity: 1; - transform: scale(1); - } -} - -@keyframes antZoomOut { - 0% { - transform: scale(1); - } - 100% { - opacity: 0; - transform: scale(0.2); - } -} - -@keyframes antZoomBigIn { - 0% { - opacity: 0; - transform: scale(0.8); - } - 100% { - transform: scale(1); - } -} - -@keyframes antZoomBigOut { - 0% { - transform: scale(1); - } - 100% { - opacity: 0; - transform: scale(0.8); - } -} - -@keyframes antZoomUpIn { - 0% { - opacity: 0; - transform-origin: 50% 0%; - transform: scale(0.8); - } - 100% { - transform-origin: 50% 0%; - transform: scale(1); - } -} - -@keyframes antZoomUpOut { - 0% { - transform-origin: 50% 0%; - transform: scale(1); - } - 100% { - opacity: 0; - transform-origin: 50% 0%; - transform: scale(0.8); - } -} - -@keyframes antZoomLeftIn { - 0% { - opacity: 0; - transform-origin: 0% 50%; - transform: scale(0.8); - } - 100% { - transform-origin: 0% 50%; - transform: scale(1); - } -} - -@keyframes antZoomLeftOut { - 0% { - transform-origin: 0% 50%; - transform: scale(1); - } - 100% { - opacity: 0; - transform-origin: 0% 50%; - transform: scale(0.8); - } -} - -@keyframes antZoomRightIn { - 0% { - opacity: 0; - transform-origin: 100% 50%; - transform: scale(0.8); - } - 100% { - transform-origin: 100% 50%; - transform: scale(1); - } -} - -@keyframes antZoomRightOut { - 0% { - transform-origin: 100% 50%; - transform: scale(1); - } - 100% { - opacity: 0; - transform-origin: 100% 50%; - transform: scale(0.8); - } -} - -@keyframes antZoomDownIn { - 0% { - opacity: 0; - transform-origin: 50% 100%; - transform: scale(0.8); - } - 100% { - transform-origin: 50% 100%; - transform: scale(1); - } -} - -@keyframes antZoomDownOut { - 0% { - transform-origin: 50% 100%; - transform: scale(1); - } - 100% { - opacity: 0; - transform-origin: 50% 100%; - transform: scale(0.8); - } -} - -// For common/openAnimation -.ant-motion-collapse { - overflow: hidden; - &-active { - transition: height 0.15s @ease-in-out, opacity 0.15s @ease-in-out !important; - } -} - -// grid muse be first - -// mixins for grid system -// ------------------------ -.make-row(@gutter: @grid-gutter-width) { - position: relative; - margin-left: (@gutter / -2); - margin-right: (@gutter / -2); - height: auto; - .clearfix; -} - -.make-grid-columns() { - .col(@index) { - @item: ~'.@{ant-prefix}-col-@{index}, .@{ant-prefix}-col-xs-@{index}, .@{ant-prefix}-col-sm-@{index}, .@{ant-prefix}-col-md-@{index}, .@{ant-prefix}-col-lg-@{index}'; - .col((@index + 1), @item); - } - .col(@index, @list) when (@index =< @grid-columns) { - @item: ~'.@{ant-prefix}-col-@{index}, .@{ant-prefix}-col-xs-@{index}, .@{ant-prefix}-col-sm-@{index}, .@{ant-prefix}-col-md-@{index}, .@{ant-prefix}-col-lg-@{index}'; - .col((@index + 1), ~'@{list}, @{item}'); - } - .col(@index, @list) when (@index > @grid-columns) { - @{list} { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - padding-left: (@grid-gutter-width / 2); - padding-right: (@grid-gutter-width / 2); - } - } - .col(1); -} - -.float-grid-columns(@class) { - .col(@index) { - // initial - @item: ~'.@{ant-prefix}-col@{class}-@{index}'; - .col((@index + 1), @item); - } - .col(@index, @list) when (@index =< @grid-columns) { - // general - @item: ~'.@{ant-prefix}-col@{class}-@{index}'; - .col((@index + 1), ~'@{list}, @{item}'); - } - .col(@index, @list) when (@index > @grid-columns) { - // terminal - @{list} { - float: left; - flex: 0 0 auto; - } - } - .col(1); // kickstart it -} - -.loop-grid-columns(@index, @class) when (@index > 0) { - .@{ant-prefix}-col@{class}-@{index} { - display: block; - box-sizing: border-box; - width: percentage((@index / @grid-columns)); - } - .@{ant-prefix}-col@{class}-push-@{index} { - left: percentage((@index / @grid-columns)); - } - .@{ant-prefix}-col@{class}-pull-@{index} { - right: percentage((@index / @grid-columns)); - } - .@{ant-prefix}-col@{class}-offset-@{index} { - margin-left: percentage((@index / @grid-columns)); - } - .@{ant-prefix}-col@{class}-order-@{index} { - order: @index; - } - .loop-grid-columns((@index - 1), @class); -} - -.loop-grid-columns(@index, @class) when (@index = 0) { - .@{ant-prefix}-col@{class}-@{index} { - display: none; - } - .@{ant-prefix}-col-push-@{index} { - left: auto; - } - .@{ant-prefix}-col-pull-@{index} { - right: auto; - } - .@{ant-prefix}-col@{class}-push-@{index} { - left: auto; - } - .@{ant-prefix}-col@{class}-pull-@{index} { - right: auto; - } - .@{ant-prefix}-col@{class}-offset-@{index} { - margin-left: 0; - } - .@{ant-prefix}-col@{class}-order-@{index} { - order: 0; - } -} - -.make-grid(@class: ~'') { - .float-grid-columns(@class); - .loop-grid-columns(@grid-columns, @class); -} - -// Grid system -.@{ant-prefix}-row { - .make-row(); - display: block; - box-sizing: border-box; -} - -.@{ant-prefix}-row-flex { - display: flex; - flex-flow: row wrap; - - &:before, - &:after { - display: flex; - } -} - -// x轴原点 -.@{ant-prefix}-row-flex-start { - justify-content: flex-start; -} - -// x轴居中 -.@{ant-prefix}-row-flex-center { - justify-content: center; -} - -// x轴反方向 -.@{ant-prefix}-row-flex-end { - justify-content: flex-end; -} - -// x轴平分 -.@{ant-prefix}-row-flex-space-between { - justify-content: space-between; -} - -// x轴有间隔地平分 -.@{ant-prefix}-row-flex-space-around { - justify-content: space-around; -} - -// 顶部对齐 -.@{ant-prefix}-row-flex-top { - align-items: flex-start; -} - -// 居中对齐 -.@{ant-prefix}-row-flex-middle { - align-items: center; -} - -// 底部对齐 -.@{ant-prefix}-row-flex-bottom { - align-items: flex-end; -} - -.@{ant-prefix}-col { - position: relative; - display: block; -} - -.make-grid-columns(); -.make-grid(); - -// Extra small grid -// -// Columns, offsets, pushes, and pulls for extra small devices like -// smartphones. - -.make-grid(-xs); - -// Small grid -// -// Columns, offsets, pushes, and pulls for the small device range, from phones -// to tablets. - -@media (min-width: @screen-sm-min) { - .make-grid(-sm); -} - -// Medium grid -// -// Columns, offsets, pushes, and pulls for the desktop device range. - -@media (min-width: @screen-md-min) { - .make-grid(-md); -} - -// Large grid -// -// Columns, offsets, pushes, and pulls for the large desktop device range. - -@media (min-width: @screen-lg-min) { - .make-grid(-lg); -} - -// Extra Large grid -// -// Columns, offsets, pushes, and pulls for the full hd device range. - -@media (min-width: @screen-xl-min) { - .make-grid(-xl); -} - -// Extra Extra Large grid -// -// Columns, offsets, pushes, and pulls for the full hd device range. - -@media (min-width: @screen-xxl-min) { - .make-grid(-xxl); -} - -.@{ant-prefix}-affix { - position: fixed; - z-index: @zindex-affix; -} - -@alert-prefix-cls: ~'@{ant-prefix}-alert'; - -@alert-message-color: @heading-color; -@alert-text-color: @text-color; -@alert-close-color: @text-color-secondary; -@alert-close-hover-color: #404040; - -.@{alert-prefix-cls} { - .reset-component; - position: relative; - padding: 8px 15px 8px 37px; - border-radius: @border-radius-base; - - &&-no-icon { - padding: 8px 15px; - } - - &&-closable { - padding-right: 30px; - } - - &-icon { - top: 8px + @font-size-base * @line-height-base / 2 - @font-size-base / 2; - left: 16px; - position: absolute; - } - - &-description { - font-size: @font-size-base; - line-height: 22px; - display: none; - } - - &-success { - border: @border-width-base @border-style-base @alert-success-border-color; - background-color: @alert-success-bg-color; - .@{alert-prefix-cls}-icon { - color: @alert-success-icon-color; - } - } - - &-info { - border: @border-width-base @border-style-base @alert-info-border-color; - background-color: @alert-info-bg-color; - .@{alert-prefix-cls}-icon { - color: @alert-info-icon-color; - } - } - - &-warning { - border: @border-width-base @border-style-base @alert-warning-border-color; - background-color: @alert-warning-bg-color; - .@{alert-prefix-cls}-icon { - color: @alert-warning-icon-color; - } - } - - &-error { - border: @border-width-base @border-style-base @alert-error-border-color; - background-color: @alert-error-bg-color; - .@{alert-prefix-cls}-icon { - color: @alert-error-icon-color; - } - } - - &-close-icon { - font-size: @font-size-sm; - position: absolute; - right: 16px; - top: 8px; - line-height: 22px; - overflow: hidden; - cursor: pointer; - - .@{iconfont-css-prefix}-close { - color: @alert-close-color; - transition: color 0.3s; - &:hover { - color: @alert-close-hover-color; - } - } - } - - &-close-text { - position: absolute; - right: 16px; - } - - &-with-description { - padding: 15px 15px 15px 64px; - position: relative; - border-radius: @border-radius-base; - color: @alert-text-color; - line-height: @line-height-base; - } - - &-with-description&-no-icon { - padding: 15px; - } - - &-with-description &-icon { - position: absolute; - top: 16px; - left: 24px; - font-size: 24px; - } - - &-with-description &-close-icon { - position: absolute; - top: 16px; - right: 16px; - cursor: pointer; - font-size: @font-size-base; - } - - &-with-description &-message { - font-size: @font-size-lg; - color: @alert-message-color; - display: block; - margin-bottom: 4px; - } - - &-with-description &-description { - display: block; - } - - &&-close { - height: 0 !important; - margin: 0; - padding-top: 0; - padding-bottom: 0; - transition: all 0.3s @ease-in-out-circ; - transform-origin: 50% 0; - } - - &-slide-up-leave { - animation: antAlertSlideUpOut 0.3s @ease-in-out-circ; - animation-fill-mode: both; - } - - &-banner { - border-radius: 0; - border: 0; - margin-bottom: 0; - } -} - -@keyframes antAlertSlideUpIn { - 0% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0); - } - 100% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } -} - -@keyframes antAlertSlideUpOut { - 0% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } - 100% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0); - } -} - -@anchor-border-width: 2px; - -.@{ant-prefix}-anchor { - .reset-component; - position: relative; - padding-left: @anchor-border-width; - - &-wrapper { - background-color: @component-background; - overflow: auto; - padding-left: 4px; - margin-left: -4px; - } - - &-ink { - position: absolute; - height: 100%; - left: 0; - top: 0; - &:before { - content: ' '; - position: relative; - width: @anchor-border-width; - height: 100%; - display: block; - background-color: @border-color-split; - margin: 0 auto; - } - &-ball { - display: none; - position: absolute; - width: 8px; - height: 8px; - border-radius: 8px; - border: 2px solid @primary-color; - background-color: @component-background; - left: 50%; - transition: top 0.3s ease-in-out; - transform: translateX(-50%); - &.visible { - display: inline-block; - } - } - } - - &.fixed &-ink &-ink-ball { - display: none; - } - - &-link { - padding: 7px 0 7px 16px; - line-height: 1.143; - - &-title { - display: block; - position: relative; - transition: all 0.3s; - color: @text-color; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-bottom: 6px; - - &:only-child { - margin-bottom: 0; - } - } - - &-active > &-title { - color: @primary-color; - } - } - - &-link &-link { - padding-top: 5px; - padding-bottom: 5px; - } -} - -@avatar-prefix-cls: ~'@{ant-prefix}-avatar'; - -.@{avatar-prefix-cls} { - .reset-component; - display: inline-block; - text-align: center; - background: @avatar-bg; - color: @avatar-color; - white-space: nowrap; - position: relative; - overflow: hidden; - vertical-align: middle; - - &-image { - background: transparent; - } - - .avatar-size(@avatar-size-base, @avatar-font-size-base); - - &-lg { - .avatar-size(@avatar-size-lg, @avatar-font-size-lg); - } - - &-sm { - .avatar-size(@avatar-size-sm, @avatar-font-size-sm); - } - - &-square { - border-radius: @avatar-border-radius; - } - - & > img { - width: 100%; - height: 100%; - display: block; - } -} - -.avatar-size(@size, @font-size) { - width: @size; - height: @size; - line-height: @size; - border-radius: 50%; - - &-string { - position: absolute; - left: 50%; - transform-origin: 0 center; - } - - &.@{avatar-prefix-cls}-icon { - font-size: @font-size; - } -} - -@backtop-prefix-cls: ~'@{ant-prefix}-back-top'; - -.@{backtop-prefix-cls} { - .reset-component; - z-index: @zindex-back-top; - position: fixed; - right: 100px; - bottom: 50px; - height: 40px; - width: 40px; - cursor: pointer; - - &-content { - height: 40px; - width: 40px; - border-radius: 20px; - background-color: @back-top-bg; - color: @back-top-color; - text-align: center; - transition: all 0.3s @ease-in-out; - overflow: hidden; - - &:hover { - background-color: @back-top-hover-bg; - transition: all 0.3s @ease-in-out; - } - } - - &-icon { - margin: 12px auto; - width: 14px; - height: 16px; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAoCAYAAACWwljjAAAABGdBTUEAALGPC/xhBQAAAbtJREFUWAntmMtKw0AUhhMvS5cuxILgQlRUpIggIoKIIoigG1eC+AA+jo+i6FIXBfeuXIgoeKVeitVWJX5HWhhDksnUpp3FDPyZk3Nm5nycmZKkXhAEOXSA3lG7muTeRzmfy6HneUvIhnYkQK+Q9NhAA0Opg0vBEhjBKHiyb8iGMyQMOYuK41BcBSypAL+MYXSKjtFAW7EAGEO3qN4uMQbbAkXiSfRQJ1H6a+yhlkKRcAoVFYiweYNjtCVQJJpBz2GCiPt7fBOZQpFgDpUikse5HgnkM4Fi4QX0Fpc5wf9EbLqpUCy4jMoJSXWhFwbMNgWKhVbRhy5jirhs9fy/oFhgHVVTJEs7RLZ8sSEoJm6iz7SZDMbJ+/OKERQTttCXQRLToRUmrKWCYuA2+jbN0MB4OQobYShfdTCgn/sL1K36M7TLrN3n+758aPy2rrpR6+/od5E8tf/A1uLS9aId5T7J3CNYihkQ4D9PiMdMC7mp4rjB9kjFjZp8BlnVHJBuO1yFXIV0FdDF3RlyFdJVQBdv5AxVdIsq8apiZ2PyYO1EVykesGfZEESsCkweyR8MUW+V8uJ1gkYipmpdP1pm2aJVPEGzAAAAAElFTkSuQmCC) - ~'100%/100%' no-repeat; - } -} - -@media screen and (max-width: @screen-md) { - .@{backtop-prefix-cls} { - right: 60px; - } -} - -@media screen and (max-width: @screen-xs) { - .@{backtop-prefix-cls} { - right: 20px; - } -} - -@badge-prefix-cls: ~'@{ant-prefix}-badge'; -@number-prefix-cls: ~'@{ant-prefix}-scroll-number'; - -.@{badge-prefix-cls} { - .reset-component; - position: relative; - display: inline-block; - line-height: 1; - color: unset; - - &-count { - top: -@badge-height / 2; - height: @badge-height; - border-radius: @badge-height / 2; - min-width: @badge-height; - background: @highlight-color; - color: #fff; - line-height: @badge-height; - text-align: center; - padding: 0 6px; - font-size: @badge-font-size; - font-weight: @badge-font-weight; - white-space: nowrap; - box-shadow: 0 0 0 1px #fff; - z-index: 10; - a, - a:hover { - color: #fff; - } - } - - &-multiple-words { - padding: 0 8px; - } - - &-dot { - top: -@badge-dot-size / 2; - height: @badge-dot-size; - width: @badge-dot-size; - border-radius: 100%; - background: @highlight-color; - z-index: 10; - box-shadow: 0 0 0 1px #fff; - } - - &-count, - &-dot, - .@{number-prefix-cls}-custom-component { - position: absolute; - right: 0; - transform: translateX(50%); - transform-origin: 100%; - } - - .@{number-prefix-cls}-custom-component { - transform: translate(50%, -50%); - } - - &-status { - line-height: inherit; - vertical-align: baseline; - - &-dot { - width: @badge-status-size; - height: @badge-status-size; - display: inline-block; - border-radius: 50%; - vertical-align: middle; - position: relative; - top: -1px; - } - &-success { - background-color: @success-color; - } - &-processing { - background-color: @processing-color; - position: relative; - &:after { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - border-radius: 50%; - border: 1px solid @processing-color; - content: ''; - animation: antStatusProcessing 1.2s infinite ease-in-out; - } - } - &-default { - background-color: @normal-color; - } - &-error { - background-color: @error-color; - } - &-warning { - background-color: @warning-color; - } - &-text { - color: @text-color; - font-size: @font-size-base; - margin-left: 8px; - } - } - - &-zoom-appear, - &-zoom-enter { - animation: antZoomBadgeIn 0.3s @ease-out-back; - animation-fill-mode: both; - } - - &-zoom-leave { - animation: antZoomBadgeOut 0.3s @ease-in-back; - animation-fill-mode: both; - } - - &-not-a-wrapper { - vertical-align: middle; - - .@{ant-prefix}-scroll-number { - top: auto; - display: block; - position: relative; - } - - .@{badge-prefix-cls}-count { - transform: none; - } - } -} - -@keyframes antStatusProcessing { - 0% { - transform: scale(0.8); - opacity: 0.5; - } - 100% { - transform: scale(2.4); - opacity: 0; - } -} - -.@{number-prefix-cls} { - overflow: hidden; - &-only { - display: inline-block; - transition: all 0.3s @ease-in-out; - height: @badge-height; - > p { - height: @badge-height; - margin: 0; - } - } -} - -@keyframes antZoomBadgeIn { - 0% { - opacity: 0; - transform: scale(0) translateX(50%); - } - 100% { - transform: scale(1) translateX(50%); - } -} - -@keyframes antZoomBadgeOut { - 0% { - transform: scale(1) translateX(50%); - } - 100% { - opacity: 0; - transform: scale(0) translateX(50%); - } -} - -@breadcrumb-prefix-cls: ~'@{ant-prefix}-breadcrumb'; - -.@{breadcrumb-prefix-cls} { - .reset-component; - color: @breadcrumb-base-color; - font-size: @breadcrumb-font-size; - - .@{iconfont-css-prefix} { - font-size: @breadcrumb-icon-font-size; - } - - a { - color: @breadcrumb-link-color; - transition: color 0.3s; - &:hover { - color: @breadcrumb-link-color-hover; - } - } - - & > span:last-child { - color: @breadcrumb-last-item-color; - } - - & > span:last-child &-separator { - display: none; - } - - &-separator { - margin: @breadcrumb-separator-margin; - color: @breadcrumb-separator-color; - } - - &-link { - > .@{iconfont-css-prefix} + span { - margin-left: 4px; - } - } -} - -// mixins for button -// ------------------------ -.button-size(@height; @padding; @font-size; @border-radius) { - padding: @padding; - font-size: @font-size; - border-radius: @border-radius; - height: @height; -} - -.button-disabled() { - &.disabled, - &[disabled] { - &, - &:hover, - &:focus, - &:active, - &.active { - .button-color(@btn-disable-color; @btn-disable-bg; @btn-disable-border); - text-shadow: none; - box-shadow: none; - } - } -} - -.button-variant-primary(@color; @background) { - .button-color(@color; @background; @background); - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12); - box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045); - - &:hover, - &:focus { - .button-color( - @color; ~`colorPalette('@{background}', 5) `; ~`colorPalette('@{background}', 5) ` - ); - } - - &:active, - &.active { - .button-color( - @color; ~`colorPalette('@{background}', 7) `; ~`colorPalette('@{background}', 7) ` - ); - } - - .button-disabled(); -} - -.button-variant-other(@color; @background; @border) { - .button-color(@color; @background; @border); - - &:hover, - &:focus { - .button-color(@primary-5; @background; @primary-5); - } - - &:active, - &.active { - .button-color(@primary-7; @background; @primary-7); - } - - .button-disabled(); -} - -.button-variant-danger(@color; @background; @border) { - .button-color(@color; @background; @border); - - &:hover { - .button-color( - @btn-primary-color; ~`colorPalette('@{color}', 5) `; ~`colorPalette('@{color}', 5) ` - ); - } - - &:focus { - .button-color(~`colorPalette('@{color}', 5) `; #fff; ~`colorPalette('@{color}', 5) `); - } - - &:active, - &.active { - .button-color( - @btn-primary-color; ~`colorPalette('@{color}', 7) `; ~`colorPalette('@{color}', 7) ` - ); - } - - .button-disabled(); -} - -.button-variant-ghost(@color) { - .button-color(@color; transparent; @color); - text-shadow: none; - - &:hover, - &:focus { - .button-color(~`colorPalette('@{color}', 5) `; transparent; ~`colorPalette('@{color}', 5) `); - } - - &:active, - &.active { - .button-color(~`colorPalette('@{color}', 7) `; transparent; ~`colorPalette('@{color}', 7) `); - } - - .button-disabled(); -} - -.button-color(@color; @background; @border) { - color: @color; - background-color: @background; - border-color: @border; - // a inside Button which only work in Chrome - // http://stackoverflow.com/a/17253457 - > a:only-child { - color: currentColor; - &:after { - content: ''; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - background: transparent; - } - } -} - -.button-group-base(@btnClassName) { - position: relative; - display: inline-block; - > .@{btnClassName}, - > span > .@{btnClassName} { - position: relative; - - &:hover, - &:focus, - &:active, - &.active { - z-index: 2; - } - - &:disabled { - z-index: 0; - } - } - - // size - &-lg > .@{btnClassName}, - &-lg > span > .@{btnClassName} { - .button-size(@btn-height-lg; @btn-padding-lg; @btn-font-size-lg; 0); - line-height: @btn-height-lg - 2px; - } - - &-sm > .@{btnClassName}, - &-sm > span > .@{btnClassName} { - .button-size(@btn-height-sm; @btn-padding-sm; @font-size-base; 0); - line-height: @btn-height-sm - 2px; - > .@{iconfont-css-prefix} { - font-size: @font-size-base; - } - } -} - -// Base styles of buttons -// -------------------------------------------------- -.btn() { - display: inline-block; - font-weight: @btn-font-weight; - text-align: center; - touch-action: manipulation; - cursor: pointer; - background-image: none; - border: @border-width-base @border-style-base transparent; - white-space: nowrap; - .button-size(@btn-height-base; @btn-padding-base; @font-size-base; @btn-border-radius-base); - user-select: none; - transition: all 0.3s @ease-in-out; - position: relative; - box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015); - - > .@{iconfont-css-prefix} { - line-height: 1; - } - - &, - &:active, - &:focus { - outline: 0; - } - - &:not([disabled]):hover { - text-decoration: none; - } - - &:not([disabled]):active { - outline: 0; - box-shadow: none; - } - - &.disabled, - &[disabled] { - cursor: not-allowed; - > * { - pointer-events: none; - } - } - - &-lg { - .button-size(@btn-height-lg; @btn-padding-lg; @btn-font-size-lg; @btn-border-radius-base); - } - - &-sm { - .button-size(@btn-height-sm; @btn-padding-sm; @btn-font-size-sm; @btn-border-radius-sm); - } -} - -// primary button style -.btn-primary() { - .button-variant-primary(@btn-primary-color; @btn-primary-bg); -} - -// default button style -.btn-default() { - .button-variant-other(@btn-default-color; @btn-default-bg; @btn-default-border); - &:hover, - &:focus, - &:active, - &.active { - background: @btn-default-bg; - text-decoration: none; - } -} - -// ghost button style -.btn-ghost() { - .button-variant-other(@btn-ghost-color, @btn-ghost-bg, @btn-ghost-border); -} - -// dashed button style -.btn-dashed() { - .button-variant-other(@btn-default-color, @btn-default-bg, @btn-default-border); - border-style: dashed; -} - -// danger button style -.btn-danger() { - .button-variant-danger(@btn-danger-color, @btn-danger-bg, @btn-danger-border); -} - -// circle button: the content only contains icon -.btn-circle(@btnClassName: btn) { - .square(@btn-circle-size); - .button-size(@btn-circle-size; 0; @font-size-base + 2px; 50%); - - &.@{btnClassName}-lg { - .square(@btn-circle-size-lg); - .button-size(@btn-circle-size-lg; 0; @btn-font-size-lg + 2px; 50%); - } - - &.@{btnClassName}-sm { - .square(@btn-circle-size-sm); - .button-size(@btn-circle-size-sm; 0; @font-size-base; 50%); - } -} - -// Horizontal button groups styl -// -------------------------------------------------- -.btn-group(@btnClassName: btn) { - .button-group-base(@btnClassName); - - .@{btnClassName} + .@{btnClassName}, - .@{btnClassName} + &, - span + .@{btnClassName}, - .@{btnClassName} + span, - > span + span, - & + .@{btnClassName}, - & + & { - margin-left: -1px; - } - - .@{btnClassName}-primary + .@{btnClassName}:not(.@{btnClassName}-primary):not([disabled]) { - border-left-color: transparent; - } - - .@{btnClassName} { - border-radius: 0; - } - - > .@{btnClassName}:first-child, - > span:first-child > .@{btnClassName} { - margin-left: 0; - } - > .@{btnClassName}:only-child { - border-radius: @btn-border-radius-base; - } - > span:only-child > .@{btnClassName} { - border-radius: @btn-border-radius-base; - } - - > .@{btnClassName}:first-child:not(:last-child), - > span:first-child:not(:last-child) > .@{btnClassName} { - border-bottom-left-radius: @btn-border-radius-base; - border-top-left-radius: @btn-border-radius-base; - } - - > .@{btnClassName}:last-child:not(:first-child), - > span:last-child:not(:first-child) > .@{btnClassName} { - border-bottom-right-radius: @btn-border-radius-base; - border-top-right-radius: @btn-border-radius-base; - } - - &-sm { - > .@{btnClassName}:only-child { - border-radius: @btn-border-radius-sm; - } - > span:only-child > .@{btnClassName} { - border-radius: @btn-border-radius-sm; - } - > .@{btnClassName}:first-child:not(:last-child), - > span:first-child:not(:last-child) > .@{btnClassName} { - border-bottom-left-radius: @btn-border-radius-sm; - border-top-left-radius: @btn-border-radius-sm; - } - > .@{btnClassName}:last-child:not(:first-child), - > span:last-child:not(:first-child) > .@{btnClassName} { - border-bottom-right-radius: @btn-border-radius-sm; - border-top-right-radius: @btn-border-radius-sm; - } - } - - & > & { - float: left; - } - - & > &:not(:first-child):not(:last-child) > .@{btnClassName} { - border-radius: 0; - } - - & > &:first-child:not(:last-child) { - > .@{btnClassName}:last-child { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - padding-right: 8px; - } - } - - & > &:last-child:not(:first-child) > .@{btnClassName}:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - padding-left: 8px; - } -} - -@btn-prefix-cls: ~'@{ant-prefix}-btn'; - -// for compatible -@btn-ghost-color: @text-color; -@btn-ghost-bg: transparent; -@btn-ghost-border: @border-color-base; - -// Button styles -// ----------------------------- -.@{btn-prefix-cls} { - // Fixing https://github.com/ant-design/ant-design/issues/12978 - // It is a render problem of chrome, which is only happened in the codesandbox demo - // 0.001px solution works and I don't why - line-height: @line-height-base - 0.001; - .btn; - .btn-default; - - // Make sure that the target of Button's click event always be `button` - // Ref: https://github.com/ant-design/ant-design/issues/7034 - > i, - > span { - pointer-events: none; - display: inline-block; - } - - &-primary { - .btn-primary; - - .@{btn-prefix-cls}-group &:not(:first-child):not(:last-child) { - border-right-color: @btn-group-border; - border-left-color: @btn-group-border; - - &:disabled { - border-color: @btn-default-border; - } - } - - .@{btn-prefix-cls}-group &:first-child { - &:not(:last-child) { - border-right-color: @btn-group-border; - &[disabled] { - border-right-color: @btn-default-border; - } - } - } - - .@{btn-prefix-cls}-group &:last-child:not(:first-child), - .@{btn-prefix-cls}-group & + & { - border-left-color: @btn-group-border; - &[disabled] { - border-left-color: @btn-default-border; - } - } - } - - &-ghost { - .btn-ghost; - } - - &-dashed { - .btn-dashed; - } - - &-danger { - .btn-danger; - } - - &-circle, - &-circle-outline { - .btn-circle(@btn-prefix-cls); - } - - &:before { - position: absolute; - top: -1px; - left: -1px; - bottom: -1px; - right: -1px; - background: #fff; - opacity: 0.35; - content: ''; - border-radius: inherit; - z-index: 1; - transition: opacity 0.2s; - pointer-events: none; - display: none; - } - - .@{iconfont-css-prefix} { - transition: margin-left 0.3s @ease-in-out; - } - - &&-loading:before { - display: block; - } - - &&-loading:not(&-circle):not(&-circle-outline):not(&-icon-only) { - padding-left: 29px; - pointer-events: none; - position: relative; - .@{iconfont-css-prefix}:not(:last-child) { - margin-left: -14px; - } - } - - &-sm&-loading:not(&-circle):not(&-circle-outline):not(&-icon-only) { - padding-left: 24px; - .@{iconfont-css-prefix} { - margin-left: -17px; - } - } - - &-group { - .btn-group(@btn-prefix-cls); - } - - &:not(&-circle):not(&-circle-outline)&-icon-only { - padding-left: 8px; - padding-right: 8px; - } - - // http://stackoverflow.com/a/21281554/3040605 - &:focus > span, - &:active > span { - position: relative; - } - - // To ensure that a space will be placed between character and `Icon`. - > .@{iconfont-css-prefix} + span, - > span + .@{iconfont-css-prefix} { - margin-left: 8px; - } - - &-background-ghost { - background: transparent !important; - border-color: #fff; - color: #fff; - } - - &-background-ghost&-primary { - .button-variant-ghost(@btn-primary-bg); - } - - &-background-ghost&-danger { - .button-variant-ghost(@btn-danger-color); - } - - &-two-chinese-chars:first-letter { - letter-spacing: 0.34em; - } - - &-two-chinese-chars > *:not(.@{iconfont-css-prefix}) { - letter-spacing: 0.34em; - margin-right: -0.34em; - } - - &-block { - width: 100%; - } - - .christmas&-primary:before { - content: ''; - display: block; - position: absolute; - top: -6px; - left: 0; - right: 0; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE0AAAAXCAYAAABOHMIhAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABiZJREFUeNrsWMtPlFcUvzPMwIDysLyRR4uATDHWCiVgSmRlios2DeiiXUFs0nRBd6arxqQhJDapkYXhP4BqDKTQhZaFNQSCaBEVJjwdHsNr5DUMDDPDzPT3u7nTDEgRKrKgc5KT+z3uufec33de99P4fD4RpL2RNgjB3kn35MkTeRERESFiYmLkGBoaKnQ6nWSNRvPPZFxr+vv7k6KioiIdDsfa8vLyQkFBgcP3Bnel3MDAQArWI0eFhISE87nb7bZ7PJ4VvLYuLi5O5+fnu9+kMNfq6+tLjIyMzMY6KeBEbK/XarXReI3lPDZMWcc4v7GxYV1dXR3Jy8ub2E5HPvJ6vRSSDH0ku1wuAfsEZOV1IEFHoeNFdHS0yMrK2knR0Lm5uR+hxLdQMjbwHTZbB41h8RGwCdc9MzMzneHh4bGJiYlf4SN8ijkfwqiIncCAAR7Iz2GPSShudjqdfeCeqampvwBQfFxc3JdYqwTv8gB8/F48A8BgKecE14V+L7ju2tpae05OzkuCCZvkPOj8mizmC6vVKtmPu+bx48cC3qI1mUyFUOyywWD4SHlELBaLJmCHNcwAghuAOujtuF4FqHO4nsX4EsAS3I4TJ04ME1h8PDE9PS09TYZoY2Pj1729vd6lpSVfkDYTPG0UkfNDRUWFgQ5Gb2Mh0N29e9eG/GQfHh4W8/PzwUy/ObQ/gMfVVlZW1iAiZdQxp3nv3LljRoL/5erVq1UIxzSiiVD9X4EDYATynCwAzGO858hCQRoaGmJFZNJz8YIcBc4BF966dau6sLAwBxVSJCUlCSThQwuU3W6XkYUok1Vzm5znQx5bbm9v77p+/frPeNSNRzZ/ISBwrG4ZR48eLamtrf2+uLjYSEG9Xi/wTISFhQlWGXohyzO/CJlVl23KQRLbABoaHx+/Z1lUZ/Hq1SsJFj3JT3hmHx8fnydPTEzMj46OziHPW2w22wxeD4Kfgadh/4YEzU8Az4DhffAn5eXlX1y6dKkEoCTspAQ9Mjs7+0BBo8Fms1lkZGTsOo0QLLRNkvnR+fEJzIMHD0xtbW39CL8JTFtSbAOvBIyLHIGVm9VzE2gKuDAMSSpcT6KXyT137lx2cnLyMXhcGDb3wq3XuWF3d/fCzZs3P0c4v5eSknJQbYLo7Ox0gC2lpaVZ3Be67Th/dnZWoAJKsJC3XA8fPhxoamp6hMb+BaaMgWcUMGtszZjiFDNmvcDI91pzG0iY4ARwkwrxkcHBwUdgNrRMbnrqoRbkVzDcvn3bl5qaWsmcgFH4G8XdEGUWFhak51AuISFBnkoCTyFbyWKxCJwIxlC0fq2rq7tcVFRkRKskjh8/Lr0+kBjCCDV/knfdv3//WX19/R8IRRNemxlu4AXwKqM+EJwdj1HbPYSwh3sCPAJDABm2LLchCjS+5/kirKGhwWk0GrMuXrxYQuX9hm/XXTMXMY+srKwI5ApZrbYmZh7deEJhAUKjLe/pLTzSsCuHrK+1tbUJVe3P6upq87Vr174rKysrYHVj/uW+OH3IfEuw4F3ee/fuPQfAvwOs5yyE4CnlFOu7BWrTCWlreO6FACpBZGwUw4BvkANLobReHb3kGZYGsGzTq/zlO8AT1ru6uoZbWlqeA6gINJAfnz59OlVLoX8Jtebm5raampqfcMvQYgTknz9//sKVK1c+y83NTdIEuCnaKMuNGzd+6+np6cCtSTkAw9D9X8Dyh+dbgaaAC1XAnUlPTy+qqqq6cPbs2UzkmWjNljiDJzpwHFnCkW2yo6NjCKW8H54wjlezKvRT09LSTsJrz5w6dSoN+Yp51ADAPUj8VoDbDq9pxrwuJcNIYQllJTIi/xopBw/VA7DJp0+f9hA78CgL5F5C8J2CpoCj8sfA6WCe/FPRhsRlZmbGIs8Y4FFO5CJgtrSsvrRVGW1V93b1myoGnKAKEcHgnwsWpg1lNI0fphwrmdqbckeU18WrnlOjqp5/j7W3BWvfQVPKa5SBkcrYCNVB65TRTlWZ1lXiXVU5xbtlDb2SPaLWYwrgHIcqPg6Vc7fbX69Yoyqfa7/AeiegbWOEVhmsVcWDwPn224iDJgla8Hd38Hd3ELQgaIeI/hZgAIPEp0vmQJdoAAAAAElFTkSuQmCC) - no-repeat 50% 0; - background-size: 64px; - opacity: 1; - } - - .christmas&-primary&-lg:before { - background-size: 72px; - } - - .christmas&-primary&-sm:before { - background-size: 56px; - } - - // https://github.com/ant-design/ant-design/issues/12681 - &:empty { - vertical-align: top; - } -} - -a.@{btn-prefix-cls} { - line-height: @btn-height-base - 2px; - &-lg { - line-height: @btn-height-lg - 2px; - } - &-sm { - line-height: @btn-height-sm - 2px; - } -} - -@full-calendar-prefix-cls: ~'@{ant-prefix}-fullcalendar'; - -.@{full-calendar-prefix-cls} { - .reset-component; - outline: none; - border-top: @border-width-base @border-style-base @border-color-base; - - &-month-select { - margin-left: 5px; - } - - &-header { - padding: 11px 16px 11px 0; - text-align: right; - - .@{ant-prefix}-select-dropdown { - text-align: left; - } - - .@{ant-prefix}-radio-group { - margin-left: 8px; - text-align: left; - } - - label.@{ant-prefix}-radio-button { - height: 22px; - line-height: 20px; - padding: 0 10px; - } - } - - &-date-panel { - position: relative; - outline: none; - } - - &-calendar-body { - padding: 8px 12px; - } - - table { - border-collapse: collapse; - max-width: 100%; - background-color: transparent; - width: 100%; - height: 256px; - } - - table, - th, - td { - border: 0; - } - - td { - position: relative; - } - - &-calendar-table { - border-spacing: 0; - margin-bottom: 0; - } - - &-column-header { - line-height: 18px; - padding: 0; - width: 33px; - text-align: center; - .@{full-calendar-prefix-cls}-column-header-inner { - display: block; - font-weight: normal; - } - } - - &-week-number-header { - .@{full-calendar-prefix-cls}-column-header-inner { - display: none; - } - } - - &-month, - &-date { - text-align: center; - transition: all 0.3s; - } - - &-value { - display: block; - margin: 0 auto; - color: @text-color; - border-radius: @border-radius-sm; - width: 24px; - height: 24px; - padding: 0; - background: transparent; - line-height: 24px; - transition: all 0.3s; - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } - - &:active { - background: @primary-color; - color: #fff; - } - } - - &-month-panel-cell &-value { - width: 48px; - } - - &-today &-value, - &-month-panel-current-cell &-value { - box-shadow: 0 0 0 1px @primary-color inset; - } - - &-selected-day &-value, - &-month-panel-selected-cell &-value { - background: @primary-color; - color: #fff; - } - - &-disabled-cell-first-of-row &-value { - border-top-left-radius: @border-radius-base; - border-bottom-left-radius: @border-radius-base; - } - - &-disabled-cell-last-of-row &-value { - border-top-right-radius: @border-radius-base; - border-bottom-right-radius: @border-radius-base; - } - - &-last-month-cell &-value, - &-next-month-btn-day &-value { - color: @disabled-color; - } - - &-month-panel-table { - table-layout: fixed; - width: 100%; - border-collapse: separate; - } - - &-content { - position: absolute; - width: 100%; - left: 0; - bottom: -9px; - } - - &-fullscreen { - border-top: 0; - } - - &-fullscreen &-table { - table-layout: fixed; - } - - &-fullscreen &-header { - .@{ant-prefix}-radio-group { - margin-left: 16px; - } - label.@{ant-prefix}-radio-button { - height: @input-height-base; - line-height: @input-height-base - 2px; - } - } - - &-fullscreen &-month, - &-fullscreen &-date { - text-align: left; - margin: 0 4px; - display: block; - color: @text-color; - height: 116px; - padding: 4px 8px; - border-top: 2px solid @border-color-split; - transition: background 0.3s; - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } - - &:active { - background: @primary-2; - } - } - - &-fullscreen &-column-header { - text-align: right; - padding-right: 12px; - padding-bottom: 5px; - } - - &-fullscreen &-value { - text-align: right; - background: transparent; - width: auto; - } - - &-fullscreen &-today &-value { - color: @text-color; - } - - &-fullscreen &-month-panel-current-cell &-month, - &-fullscreen &-today &-date { - border-top-color: @primary-color; - background: transparent; - } - - &-fullscreen &-month-panel-current-cell &-value, - &-fullscreen &-today &-value { - box-shadow: none; - } - - &-fullscreen &-month-panel-selected-cell &-month, - &-fullscreen &-selected-day &-date { - background: @primary-1; - } - - &-fullscreen &-month-panel-selected-cell &-value, - &-fullscreen &-selected-day &-value { - color: @primary-color; - } - - &-fullscreen &-last-month-cell &-date, - &-fullscreen &-next-month-btn-day &-date { - color: @disabled-color; - } - - &-fullscreen &-content { - height: 88px; - overflow-y: auto; - position: static; - width: auto; - left: auto; - bottom: auto; - } - - &-disabled-cell &-date { - &, - &:hover { - cursor: not-allowed; - } - } - - &-disabled-cell:not(&-today) &-date { - &, - &:hover { - background: transparent; - } - } - - &-disabled-cell &-value { - color: @disabled-color; - border-radius: 0; - width: auto; - cursor: not-allowed; - } -} - -@card-prefix-cls: ~'@{ant-prefix}-card'; -@card-head-height: 48px; -@card-hover-border: rgba(0, 0, 0, 0.09); -@card-radius: @border-radius-sm; - -.@{card-prefix-cls} { - .reset-component; - background: @component-background; - border-radius: @card-radius; - position: relative; - transition: all 0.3s; - - &-hoverable { - cursor: pointer; - &:hover { - box-shadow: @card-shadow; - border-color: @card-hover-border; - } - } - - &-bordered { - border: @border-width-base @border-style-base @border-color-split; - } - - &-head { - background: @card-head-background; - border-bottom: @border-width-base @border-style-base @border-color-split; - padding: 0 @card-padding-base; - border-radius: @card-radius @card-radius 0 0; - .clearfix; - margin-bottom: -1px; // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png - min-height: @card-head-height; - font-size: @font-size-lg; - color: @card-head-color; - font-weight: 500; - - &-wrapper { - display: flex; - align-items: center; - } - - &-title { - padding: @card-head-padding 0; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - flex: 1; - display: inline-block; - } - - .@{ant-prefix}-tabs { - margin-bottom: -17px; - clear: both; - font-size: @font-size-base; - color: @text-color; - font-weight: normal; - - &-bar { - border-bottom: @border-width-base @border-style-base @border-color-split; - } - } - } - - &-extra { - float: right; - padding: @card-head-padding 0; - font-size: @font-size-base; - color: @text-color; - font-weight: normal; - // https://stackoverflow.com/a/22429853/3040605 - margin-left: auto; - } - - &-body { - padding: @card-padding-base; - .clearfix; - } - - &-contain-grid:not(&-loading) &-body { - margin: -1px 0 0 -1px; - padding: 0; - } - - &-grid { - border-radius: 0; - border: 0; - 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; - width: 33.33%; - float: left; - padding: @card-padding-base; - transition: all 0.3s; - &:hover { - position: relative; - z-index: 1; - box-shadow: @box-shadow-base; - } - } - - &-contain-tabs > &-head &-head-title { - padding-bottom: 0; - min-height: @card-head-height - @card-head-padding; - } - - &-contain-tabs &-extra { - padding-bottom: 0; - } - - &-cover { - > * { - width: 100%; - display: block; - } - img { - border-radius: @card-radius @card-radius 0 0; - } - } - - &-actions { - border-top: @border-width-base @border-style-base @border-color-split; - background: @card-actions-background; - .clearfix; - list-style: none; - margin: 0; - padding: 0; - - & > li { - float: left; - text-align: center; - margin: 12px 0; - color: @text-color-secondary; - - & > span { - display: inline-block; - font-size: 14px; - cursor: pointer; - line-height: 22px; - min-width: 32px; - position: relative; - - &:hover { - color: @primary-color; - transition: color 0.3s; - } - - & > .anticon { - font-size: 16px; - line-height: 22px; - } - - a { - color: @text-color-secondary; - line-height: 22px; - display: inline-block; - width: 100%; - - &:hover { - color: @primary-color; - } - } - } - - &:not(:last-child) { - border-right: @border-width-base @border-style-base @border-color-split; - } - } - } - - &-wider-padding &-head { - padding: 0 @card-padding-wider; - } - - &-wider-padding &-body { - padding: @card-padding-base @card-padding-wider; - } - - &-padding-transition &-head, - &-padding-transition &-body { - transition: padding 0.3s; - } - - &-type-inner &-head { - padding: 0 @card-padding-base; - background: @background-color-light; - - &-title { - padding: @card-inner-head-padding 0; - font-size: @font-size-base; - } - } - - &-type-inner &-body { - padding: 16px @card-padding-base; - } - - &-type-inner &-extra { - padding: @card-inner-head-padding + 1.5px 0; - } - - &-meta { - margin: -4px 0; - .clearfix; - - &-avatar { - padding-right: 16px; - float: left; - } - - &-detail { - overflow: hidden; - > div:not(:last-child) { - margin-bottom: 8px; - } - } - - &-title { - font-size: @font-size-lg; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - color: @card-head-color; - font-weight: 500; - } - - &-description { - color: @text-color-secondary; - } - } - - &-loading { - overflow: hidden; - position: relative; - - &:after { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: @card-padding-base; - background: @component-background; - content: ''; - } - } - - &-loading &-body { - user-select: none; - } - - &-loading-content { - p { - margin: 0; - } - } - - &-loading-block { - height: 14px; - margin: 4px 0; - border-radius: @card-radius; - background: linear-gradient( - 90deg, - rgba(207, 216, 220, 0.2), - rgba(207, 216, 220, 0.4), - rgba(207, 216, 220, 0.2) - ); - animation: card-loading 1.4s ease infinite; - background-size: 600% 600%; - } -} - -@keyframes card-loading { - 0%, - 100% { - background-position: 0 50%; - } - 50% { - background-position: 100% 50%; - } -} - -.@{ant-prefix}-carousel { - .reset-component; - - .slick-slider { - position: relative; - display: block; - box-sizing: border-box; - -webkit-touch-callout: none; - -ms-touch-action: pan-y; - touch-action: pan-y; - -webkit-tap-highlight-color: transparent; - } - .slick-list { - position: relative; - overflow: hidden; - display: block; - margin: 0; - padding: 0; - - &:focus { - outline: none; - } - - &.dragging { - cursor: pointer; - } - - .slick-slide { - pointer-events: none; - - &.slick-active { - pointer-events: auto; - } - } - } - .slick-slider .slick-track, - .slick-slider .slick-list { - transform: translate3d(0, 0, 0); - } - - .slick-track { - position: relative; - left: 0; - top: 0; - display: block; - - &:before, - &:after { - content: ''; - display: table; - } - - &:after { - clear: both; - } - - .slick-loading & { - visibility: hidden; - } - } - .slick-slide { - float: left; - height: 100%; - min-height: 1px; - [dir='rtl'] & { - float: right; - } - img { - display: block; - } - &.slick-loading img { - display: none; - } - - display: none; - - &.dragging img { - pointer-events: none; - } - } - - .slick-initialized .slick-slide { - display: block; - } - - .slick-loading .slick-slide { - visibility: hidden; - } - - .slick-vertical .slick-slide { - display: block; - height: auto; - border: @border-width-base @border-style-base transparent; - } - .slick-arrow.slick-hidden { - display: none; - } - - // Arrows - .slick-prev, - .slick-next { - position: absolute; - display: block; - height: 20px; - width: 20px; - line-height: 0; - font-size: 0; - cursor: pointer; - background: transparent; - color: transparent; - top: 50%; - margin-top: -10px; - padding: 0; - border: 0; - outline: none; - &:hover, - &:focus { - outline: none; - background: transparent; - color: transparent; - &:before { - opacity: 1; - } - } - &.slick-disabled:before { - opacity: 0.25; - } - } - - .slick-prev { - left: -25px; - &:before { - content: '←'; - } - } - - .slick-next { - right: -25px; - &:before { - content: '→'; - } - } - - // Dots - .slick-dots { - position: absolute; - bottom: 12px; - list-style: none; - display: block; - text-align: center; - margin: 0; - padding: 0; - width: 100%; - height: @carousel-dot-height; - li { - position: relative; - display: inline-block; - vertical-align: top; - text-align: center; - margin: 0 2px; - padding: 0; - button { - border: 0; - cursor: pointer; - background: #fff; - opacity: 0.3; - display: block; - width: @carousel-dot-width; - height: @carousel-dot-height; - border-radius: 1px; - outline: none; - font-size: 0; - color: transparent; - transition: all 0.5s; - padding: 0; - &:hover, - &:focus { - opacity: 0.75; - } - } - &.slick-active button { - background: #fff; - opacity: 1; - width: @carousel-dot-active-width; - &:hover, - &:focus { - opacity: 1; - } - } - } - } -} - -.@{ant-prefix}-carousel-vertical { - .slick-dots { - width: @carousel-dot-height; - bottom: auto; - right: 12px; - top: 50%; - transform: translateY(-50%); - height: auto; - li { - margin: 0 2px; - vertical-align: baseline; - button { - width: @carousel-dot-height; - height: @carousel-dot-width; - } - &.slick-active button { - width: @carousel-dot-height; - height: @carousel-dot-active-width; - } - } - } -} - -@input-affix-width: 19px; - -// size mixins for input -.input-lg() { - padding: @input-padding-vertical-lg @input-padding-horizontal-lg; - height: @input-height-lg; - font-size: @font-size-lg; -} - -.input-sm() { - padding: @input-padding-vertical-sm @input-padding-horizontal-sm; - height: @input-height-sm; -} - -// input status -// == when focus or actived -.active(@color: @outline-color) { - border-color: ~`colorPalette('@{color}', 5) `; - outline: 0; - box-shadow: @input-outline-offset @outline-blur-size @outline-width fade(@color, 20%); - border-right-width: @border-width-base !important; -} - -// == when hoverd -.hover(@color: @input-hover-border-color) { - border-color: ~`colorPalette('@{color}', 5) `; - border-right-width: @border-width-base !important; -} - -.disabled() { - background-color: @input-disabled-bg; - opacity: 1; - cursor: not-allowed; - color: @disabled-color; - &:hover { - .hover(@input-border-color); - } -} - -// Basic style for input -.input() { - position: relative; - display: inline-block; - padding: @input-padding-vertical-base @input-padding-horizontal-base; - width: 100%; - height: @input-height-base; - font-size: @font-size-base; - line-height: @line-height-base; - color: @input-color; - background-color: @input-bg; - background-image: none; - border: @border-width-base @border-style-base @input-border-color; - border-radius: @border-radius-base; - .placeholder(); // Reset placeholder - transition: all 0.3s; - - &:hover { - .hover(); - } - - &:focus { - .active(); - } - - &-disabled { - .disabled(); - } - - // Reset height for `textarea`s - textarea& { - max-width: 100%; // prevent textearea resize from coming out of its container - height: auto; - vertical-align: bottom; - transition: all 0.3s, height 0s; - min-height: @input-height-base; - } - - // Size - &-lg { - .input-lg(); - } - - &-sm { - .input-sm(); - } -} - -// label input -.input-group(@inputClass) { - position: relative; - display: table; - border-collapse: separate; - border-spacing: 0; - width: 100%; - - // Undo padding and float of grid classes - &[class*='col-'] { - float: none; - padding-left: 0; - padding-right: 0; - } - - > [class*='col-'] { - padding-right: 8px; - &:last-child { - padding-right: 0; - } - } - - &-addon, - &-wrap, - > .@{inputClass} { - display: table-cell; - - &:not(:first-child):not(:last-child) { - border-radius: 0; - } - } - - &-addon, - &-wrap { - width: 1px; // To make addon/wrap as small as possible - white-space: nowrap; - vertical-align: middle; - } - - &-wrap > * { - display: block !important; - } - - .@{inputClass} { - float: left; - width: 100%; - margin-bottom: 0; - &:focus { - z-index: 1; // Fix https://gw.alipayobjects.com/zos/rmsportal/DHNpoqfMXSfrSnlZvhsJ.png - border-right-width: 1px; - } - &:hover { - z-index: 1; - border-right-width: 1px; - } - } - - &-addon { - padding: 0 @input-padding-horizontal-base; - font-size: @font-size-base; - font-weight: normal; - line-height: 1; - color: @input-color; - text-align: center; - background-color: @input-addon-bg; - border: @border-width-base @border-style-base @input-border-color; - border-radius: @border-radius-base; - position: relative; - transition: all 0.3s; - - // Reset Select's style in addon - .@{ant-prefix}-select { - margin: -(@input-padding-vertical-base + 1px) (-@input-padding-horizontal-base); - - .@{ant-prefix}-select-selection { - background-color: inherit; - margin: -1px; - border: @border-width-base @border-style-base transparent; - box-shadow: none; - } - - &-open, - &-focused { - .@{ant-prefix}-select-selection { - color: @primary-color; - } - } - } - - // Expand addon icon click area - // https://github.com/ant-design/ant-design/issues/3714 - > i:only-child:after { - position: absolute; - content: ''; - top: 0; - left: 0; - right: 0; - bottom: 0; - } - } - - // Reset rounded corners - > .@{inputClass}:first-child, - &-addon:first-child { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - - // Reset Select's style in addon - .@{ant-prefix}-select .@{ant-prefix}-select-selection { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - } - } - - > .@{inputClass}-affix-wrapper { - &:not(:first-child) .@{inputClass} { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - } - - &:not(:last-child) .@{inputClass} { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - } - } - - &-addon:first-child { - border-right: 0; - } - &-addon:last-child { - border-left: 0; - } - - > .@{inputClass}:last-child, - &-addon:last-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - - // Reset Select's style in addon - .@{ant-prefix}-select .@{ant-prefix}-select-selection { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - } - } - - // Sizing options - &-lg .@{inputClass}, - &-lg > &-addon { - .input-lg(); - } - - &-sm .@{inputClass}, - &-sm > &-addon { - .input-sm(); - } - - // Fix https://github.com/ant-design/ant-design/issues/5754 - &-lg .@{ant-prefix}-select-selection--single { - height: @input-height-lg; - } - - &-sm .@{ant-prefix}-select-selection--single { - height: @input-height-sm; - } - - .@{inputClass}-affix-wrapper { - display: table-cell; - width: 100%; - float: left; - } - - &&-compact { - display: block; - .clearfix; - - &-addon, - &-wrap, - > .@{inputClass} { - &:not(:first-child):not(:last-child) { - border-right-width: @border-width-base; - &:hover { - z-index: 1; - } - &:focus { - z-index: 1; - } - } - } - - & > * { - border-radius: 0; - vertical-align: top; // https://github.com/ant-design/ant-design-pro/issues/139 - float: none; - display: inline-block; - } - - & > *:not(:last-child) { - border-right-width: @border-width-base; - margin-right: -@border-width-base; - } - - // Undo float for .ant-input-group .ant-input - .@{inputClass} { - float: none; - } - - // reset border for Select, DatePicker, AutoComplete, Cascader, Mention, TimePicker - & > .@{ant-prefix}-select > .@{ant-prefix}-select-selection, - & > .@{ant-prefix}-calendar-picker .@{ant-prefix}-input, - & > .@{ant-prefix}-select-auto-complete .@{ant-prefix}-input, - & > .@{ant-prefix}-cascader-picker .@{ant-prefix}-input, - & > .@{ant-prefix}-mention-wrapper .@{ant-prefix}-mention-editor, - & > .@{ant-prefix}-time-picker .@{ant-prefix}-time-picker-input { - border-radius: 0; - border-right-width: @border-width-base; - &:hover { - z-index: 1; - } - &:focus { - z-index: 1; - } - } - - & > *:first-child, - & > .@{ant-prefix}-select:first-child > .@{ant-prefix}-select-selection, - & > .@{ant-prefix}-calendar-picker:first-child .@{ant-prefix}-input, - & > .@{ant-prefix}-select-auto-complete:first-child .@{ant-prefix}-input, - & > .@{ant-prefix}-cascader-picker:first-child .@{ant-prefix}-input, - & > .@{ant-prefix}-mention-wrapper:first-child .@{ant-prefix}-mention-editor, - & > .@{ant-prefix}-time-picker:first-child .@{ant-prefix}-time-picker-input { - border-top-left-radius: @border-radius-base; - border-bottom-left-radius: @border-radius-base; - } - - & > *:last-child, - & > .@{ant-prefix}-select:last-child > .@{ant-prefix}-select-selection, - & > .@{ant-prefix}-calendar-picker:last-child .@{ant-prefix}-input, - & > .@{ant-prefix}-select-auto-complete:last-child .@{ant-prefix}-input, - & > .@{ant-prefix}-cascader-picker:last-child .@{ant-prefix}-input, - & > .@{ant-prefix}-cascader-picker-focused:last-child .@{ant-prefix}-input, - & > .@{ant-prefix}-mention-wrapper:last-child .@{ant-prefix}-mention-editor, - & > .@{ant-prefix}-time-picker:last-child .@{ant-prefix}-time-picker-input { - border-top-right-radius: @border-radius-base; - border-bottom-right-radius: @border-radius-base; - border-right-width: @border-width-base; - } - - // https://github.com/ant-design/ant-design/issues/12493 - & > .@{ant-prefix}-select-auto-complete .@{ant-prefix}-input { - vertical-align: top; - } - } -} - -.input-affix-wrapper(@inputClass) { - position: relative; - display: inline-block; - width: 100%; - - &:hover .@{inputClass}:not(.@{inputClass}-disabled) { - .hover(); - } - - .@{inputClass} { - position: relative; - } - - .@{inputClass}-prefix, - .@{inputClass}-suffix { - position: absolute; - top: 50%; - z-index: 2; - transform: translateY(-50%); - line-height: 0; - color: @input-color; - :not(.anticon) { - line-height: @line-height-base; - } - } - - .@{inputClass}-prefix { - left: @input-padding-horizontal-base + 1px; - } - - .@{inputClass}-suffix { - right: @input-padding-horizontal-base + 1px; - } - - .@{inputClass}:not(:first-child) { - padding-left: @input-padding-horizontal-base + @input-affix-width; - } - - .@{inputClass}:not(:last-child) { - padding-right: @input-padding-horizontal-base + @input-affix-width; - } -} - -@cascader-prefix-cls: ~'@{ant-prefix}-cascader'; - -.@{cascader-prefix-cls} { - .reset-component; - - &-input.@{ant-prefix}-input { - // Add important to fix https://github.com/ant-design/ant-design/issues/5078 - // because input.less will compile after cascader.less - background-color: transparent !important; - cursor: pointer; - width: 100%; - position: relative; - } - - &-picker-show-search &-input.@{ant-prefix}-input { - position: relative; - } - - &-picker { - .reset-component; - position: relative; - display: inline-block; - cursor: pointer; - background-color: @component-background; - border-radius: @border-radius-base; - outline: 0; - transition: color 0.3s; - - &-with-value &-label { - color: transparent; - } - - &-disabled { - cursor: not-allowed; - background: @input-disabled-bg; - color: @disabled-color; - .@{cascader-prefix-cls}-input { - cursor: not-allowed; - } - } - - &:focus .@{cascader-prefix-cls}-input { - .active; - } - - &-show-search&-focused { - color: @disabled-color; - } - - &-label { - position: absolute; - left: 0; - height: 20px; - line-height: 20px; - top: 50%; - margin-top: -10px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - width: 100%; - padding: 0 @control-padding-horizontal; - } - - &-clear { - opacity: 0; - position: absolute; - right: @control-padding-horizontal; - z-index: 2; - background: @component-background; - top: 50%; - font-size: @font-size-sm; - color: @disabled-color; - width: 12px; - height: 12px; - margin-top: -6px; - line-height: 12px; - cursor: pointer; - transition: color 0.3s ease, opacity 0.15s ease; - &:hover { - color: @text-color-secondary; - } - } - - &:hover &-clear { - opacity: 1; - } - - // arrow - &-arrow { - position: absolute; - z-index: 1; - top: 50%; - right: @control-padding-horizontal; - width: 12px; - height: 12px; - font-size: 12px; - margin-top: -6px; - line-height: 12px; - color: @disabled-color; - transition: transform 0.2s; - &&-expand { - transform: rotate(180deg); - } - } - } - - &-picker-small &-picker-clear, - &-picker-small &-picker-arrow { - right: @control-padding-horizontal-sm; - } - - &-menus { - font-size: @font-size-base; - background: @component-background; - position: absolute; - z-index: @zindex-dropdown; - border-radius: @border-radius-base; - box-shadow: @box-shadow-base; - white-space: nowrap; - - ul, - ol { - list-style: none; - margin: 0; - padding: 0; - } - - &-empty, - &-hidden { - display: none; - } - &.slide-up-enter.slide-up-enter-active&-placement-bottomLeft, - &.slide-up-appear.slide-up-appear-active&-placement-bottomLeft { - animation-name: antSlideUpIn; - } - - &.slide-up-enter.slide-up-enter-active&-placement-topLeft, - &.slide-up-appear.slide-up-appear-active&-placement-topLeft { - animation-name: antSlideDownIn; - } - - &.slide-up-leave.slide-up-leave-active&-placement-bottomLeft { - animation-name: antSlideUpOut; - } - - &.slide-up-leave.slide-up-leave-active&-placement-topLeft { - animation-name: antSlideDownOut; - } - } - &-menu { - display: inline-block; - vertical-align: top; - min-width: 111px; - height: 180px; - list-style: none; - margin: 0; - padding: 0; - border-right: @border-width-base @border-style-base @border-color-split; - overflow: auto; - -ms-overflow-style: -ms-autohiding-scrollbar; // https://github.com/ant-design/ant-design/issues/11857 - - &:first-child { - border-radius: @border-radius-base 0 0 @border-radius-base; - } - &:last-child { - border-right-color: transparent; - margin-right: -1px; - border-radius: 0 @border-radius-base @border-radius-base 0; - } - &:only-child { - border-radius: @border-radius-base; - } - } - &-menu-item { - padding: 5px @control-padding-horizontal; - line-height: 22px; - cursor: pointer; - white-space: nowrap; - transition: all 0.3s; - &:hover { - background: @item-hover-bg; - } - &-disabled { - cursor: not-allowed; - color: @disabled-color; - &:hover { - background: transparent; - } - } - &-active:not(&-disabled) { - &, - &:hover { - background: @background-color-base; - font-weight: 600; - } - } - &-expand { - position: relative; - padding-right: 24px; - } - - &-expand &-expand-icon, - &-expand &-loading-icon { - .iconfont-size-under-12px(10px); - color: @text-color-secondary; - position: absolute; - right: @control-padding-horizontal; - } - - & &-keyword { - color: @highlight-color; - } - } -} - -.antCheckboxFn(@checkbox-prefix-cls: ~'@{ant-prefix}-checkbox') { - @checkbox-inner-prefix-cls: ~'@{checkbox-prefix-cls}-inner'; - // 一般状态 - .@{checkbox-prefix-cls} { - .reset-component; - white-space: nowrap; - cursor: pointer; - outline: none; - display: inline-block; - line-height: 1; - position: relative; - vertical-align: middle; - top: -0.09em; - - .@{checkbox-prefix-cls}-wrapper:hover &-inner, - &:hover &-inner, - &-input:focus + &-inner { - border-color: @checkbox-color; - } - - &-checked:after { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - border-radius: @border-radius-sm; - border: 1px solid @checkbox-color; - content: ''; - animation: antCheckboxEffect 0.36s ease-in-out; - animation-fill-mode: both; - visibility: hidden; - } - - &:hover:after, - .@{checkbox-prefix-cls}-wrapper:hover &:after { - visibility: visible; - } - - &-inner { - position: relative; - top: 0; - left: 0; - display: block; - width: @checkbox-size; - height: @checkbox-size; - border: @checkbox-border-width @border-style-base @border-color-base; - border-radius: @border-radius-sm; - background-color: @checkbox-check-color; - transition: all 0.3s; - // Fix IE checked style - // https://github.com/ant-design/ant-design/issues/12597 - border-collapse: separate; - - &:after { - @check-width: (@checkbox-size / 14) * 5px; - @check-height: (@checkbox-size / 14) * 8px; - transform: rotate(45deg) scale(0); - position: absolute; - left: (@checkbox-size - @check-width) / 2 - 0.5px * (@checkbox-size / 14); - top: (@checkbox-size - @check-height) / 2 - 2px * (@checkbox-size / 14); - display: table; - width: @check-width; - height: @check-height; - border: 2px solid @checkbox-check-color; - border-top: 0; - border-left: 0; - content: ' '; - transition: all 0.1s @ease-in-back, opacity 0.1s; - opacity: 0; - } - } - - &-input { - position: absolute; - left: 0; - z-index: 1; - cursor: pointer; - opacity: 0; - top: 0; - bottom: 0; - right: 0; - width: 100%; - height: 100%; - } - } - - // 选中状态 - .@{checkbox-prefix-cls}-checked .@{checkbox-inner-prefix-cls}:after { - transform: rotate(45deg) scale(1); - position: absolute; - display: table; - border: 2px solid @checkbox-check-color; - border-top: 0; - border-left: 0; - content: ' '; - transition: all 0.2s @ease-out-back 0.1s; - opacity: 1; - } - - .@{checkbox-prefix-cls}-checked { - .@{checkbox-inner-prefix-cls} { - background-color: @checkbox-color; - border-color: @checkbox-color; - } - } - - .@{checkbox-prefix-cls}-disabled { - cursor: not-allowed; - - &.@{checkbox-prefix-cls}-checked { - .@{checkbox-inner-prefix-cls}:after { - animation-name: none; - border-color: @disabled-color; - } - } - - .@{checkbox-prefix-cls}-input { - cursor: not-allowed; - } - - .@{checkbox-inner-prefix-cls} { - border-color: @border-color-base !important; - background-color: @input-disabled-bg; - &:after { - animation-name: none; - border-color: @input-disabled-bg; - border-collapse: separate; - } - } - - & + span { - color: @disabled-color; - cursor: not-allowed; - } - } - - .@{checkbox-prefix-cls}-wrapper { - .reset-component; - line-height: unset; - cursor: pointer; - display: inline-block; - & + & { - margin-left: 8px; - } - } - - .@{checkbox-prefix-cls}-wrapper + span, - .@{checkbox-prefix-cls} + span { - padding-left: 8px; - padding-right: 8px; - } - - .@{checkbox-prefix-cls}-group { - .reset-component; - display: inline-block; - &-item { - display: inline-block; - margin-right: 8px; - &:last-child { - margin-right: 0; - } - } - &-item + &-item { - margin-left: 0; - } - } - - // 半选状态 - .@{checkbox-prefix-cls}-indeterminate { - .@{checkbox-inner-prefix-cls} { - background-color: #fff; - border-color: @border-color-base; - } - .@{checkbox-inner-prefix-cls}:after { - @indeterminate-width: @checkbox-size - 8px; - @indeterminate-height: @checkbox-size - 8px; - content: ' '; - transform: translate(-50%, -50%) scale(1); - border: 0; - left: 50%; - top: 50%; - width: @indeterminate-width; - height: @indeterminate-height; - background-color: @checkbox-color; - opacity: 1; - } - - &.@{checkbox-prefix-cls}-disabled .@{checkbox-inner-prefix-cls}:after { - border-color: @disabled-color; - background-color: @disabled-color; - } - } -} - -@keyframes antCheckboxEffect { - 0% { - transform: scale(1); - opacity: 0.5; - } - 100% { - transform: scale(1.6); - opacity: 0; - } -} - -.antCheckboxFn(); - -@collapse-prefix-cls: ~'@{ant-prefix}-collapse'; - -.collapse-close() { - transform: rotate(0); -} -.collapse-open() { - transform: rotate(90deg); -} - -.@{collapse-prefix-cls} { - .reset-component; - background-color: @collapse-header-bg; - border-radius: @border-radius-base; - border: @border-width-base @border-style-base @border-color-base; - border-bottom: 0; - - & > &-item { - border-bottom: @border-width-base @border-style-base @border-color-base; - - &:last-child { - &, - & > .@{collapse-prefix-cls}-header { - border-radius: 0 0 @border-radius-base @border-radius-base; - } - } - - > .@{collapse-prefix-cls}-header { - line-height: 22px; - padding: @collapse-header-padding; - color: @heading-color; - cursor: pointer; - position: relative; - transition: all 0.3s; - - .arrow { - .iconfont-mixin(); - font-size: @font-size-sm; - position: absolute; - display: inline-block; - line-height: 46px; - vertical-align: top; - top: 50%; - transform: translateY(-50%); - left: @padding-md; - & svg { - .collapse-close(); - transition: transform 0.24s; - } - } - - &:focus { - outline: none; - } - } - - &.@{collapse-prefix-cls}-no-arrow { - > .@{collapse-prefix-cls}-header { - padding-left: 12px; - } - } - } - - &-anim-active { - transition: height 0.2s @ease-out; - } - - &-content { - overflow: hidden; - color: @text-color; - background-color: @collapse-content-bg; - border-top: @border-width-base @border-style-base @border-color-base; - - & > &-box { - padding: @collapse-content-padding; - } - - &-inactive { - display: none; - } - } - - &-item:last-child { - > .@{collapse-prefix-cls}-content { - border-radius: 0 0 @border-radius-base @border-radius-base; - } - } - - & > &-item > &-header[aria-expanded='true'] { - .anticon-right svg { - .collapse-open(); - } - } - - &-borderless { - background-color: @component-background; - border: 0; - } - - &-borderless > &-item { - border-bottom: 1px solid @border-color-base; - } - - &-borderless > &-item:last-child, - &-borderless > &-item:last-child &-header { - border-radius: 0; - } - - &-borderless > &-item > &-content { - background-color: transparent; - border-top: 0; - } - - &-borderless > &-item > &-content > &-content-box { - padding-top: 4px; - } - - & &-item-disabled > &-header { - &, - & > .arrow { - cursor: not-allowed; - color: @disabled-color; - } - } -} - -.cdk-overlay-container { - pointer-events: none; - top: 0; - left: 0; - height: 100%; - width: 100%; - position: fixed; - z-index: 1000; -} - -.cdk-overlay-backdrop { - top: 0; - bottom: 0; - left: 0; - right: 0; - -webkit-tap-highlight-color: transparent; - transition: opacity .4s cubic-bezier(.25, .8, .25, 1); - opacity: 0; - position: absolute; - pointer-events: auto; - z-index: 1000; -} - -.cdk-overlay-pane { - position: absolute; - pointer-events: auto; - z-index: 1000; // Give an opportunity to the content own to manage their z-index such as Modal -} - -.cdk-overlay-connected-position-bounding-box { - position: absolute; - z-index: 1000; - display: flex; - flex-direction: column; - min-width: 1px; - min-height: 1px; -} - -.box-shadow-left() { - .ant-table-th-right-sticky, .ant-table-td-right-sticky { - box-shadow: -6px 0 6px 0px rgba(0, 0, 0, .05); - } -} - -.box-shadow-right() { - .ant-table-th-left-sticky, .ant-table-td-left-sticky { - box-shadow: 6px 0 6px 0px rgba(0, 0, 0, .05); - } -} - -.border-left() { - .ant-table-th-right-sticky, .ant-table-td-right-sticky { - border-right: @border-width-base @border-style-base @border-color-split; - } -} - -.border-right() { - .ant-table-th-left-sticky, .ant-table-td-left-sticky { - border-left: @border-width-base @border-style-base @border-color-split; - } -} - -.ant-table-td-right-sticky + .ant-table-td-right-sticky { - box-shadow: none; -} - -.ant-table-th-right-sticky + .ant-table-th-right-sticky { - box-shadow: none; -} - -.ant-table-th-left-sticky, .ant-table-th-right-sticky, .ant-table-td-right-sticky, .ant-table-td-left-sticky { - position: sticky !important; - z-index: 1; -} - -.ant-table-td-left-sticky, .ant-table-td-right-sticky { - background: @component-background; -} - -.ant-table-tbody { - & > tr { - &:hover { - & > td { - &.ant-table-td-left-sticky { - background: @table-row-hover-bg; - } - - &.ant-table-td-right-sticky { - background: @table-row-hover-bg; - } - } - } - } -} - -.ant-table-scroll-position-middle { - .box-shadow-right; - .box-shadow-left; -} - -.ant-table-scroll-position-left { - .box-shadow-left; -} - -.ant-table-scroll-position-right { - .box-shadow-right; -} - -.ant-table-bordered { - &.ant-table-scroll-position-middle { - .border-right; - .border-left; - } - - &.ant-table-scroll-position-left { - .border-left; - } - - &.ant-table-scroll-position-right { - .border-right; - } -} - -// hack tree css -.ant-tree { - &.ant-tree-show-line { - > nz-tree-node:not(:last-child), .ant-tree-child-tree > nz-tree-node:not(:last-child) { - > li:before { - content: ' '; - width: 1px; - border-left: 1px solid @border-color-base; - height: 100%; - position: absolute; - left: 12px; - margin: 22px 0; - } - } - .ant-tree-child-tree > nz-tree-node:last-child { - > li:before { - content: ' '; - width: 1px; - border-left: 0px solid @border-color-base; - height: 100%; - position: absolute; - left: 12px; - margin: 22px 0; - } - } - } - .font-highlight { - color: @highlight-color; - } -} - -textarea.cdk-textarea-autosize-measuring { - height: auto !important; - overflow: hidden !important; - // Having 2px top and bottom padding seems to fix a bug where Chrome gets an incorrect - // measurement. We just have to account for it later and subtract it off the final result. - padding: 2px 0 !important; - box-sizing: content-box !important; -} - -@divider-prefix-cls: ~'@{ant-prefix}-divider'; - -.@{divider-prefix-cls} { - .reset-component; - background: @border-color-split; - - &, // for compatiable - &-vertical { - margin: 0 8px; - display: inline-block; - height: 0.9em; - width: 1px; - vertical-align: middle; - position: relative; - top: -0.06em; - } - &-horizontal { - display: block; - height: 1px; - width: 100%; - min-width: 100%; // Fix https://github.com/ant-design/ant-design/issues/10914 - margin: 24px 0; - clear: both; - } - - &-horizontal&-with-text, - &-horizontal&-with-text-left, - &-horizontal&-with-text-right { - display: table; - white-space: nowrap; - text-align: center; - background: transparent; - font-weight: 500; - color: @heading-color; - font-size: @font-size-lg; - margin: 16px 0; - &:before, - &:after { - content: ''; - display: table-cell; - position: relative; - top: 50%; - width: 50%; - border-top: 1px solid @border-color-split; - transform: translateY(50%); - } - } - - &-horizontal&-with-text-left, - &-horizontal&-with-text-right { - .@{divider-prefix-cls}-inner-text { - display: inline-block; - padding: 0 10px; - } - } - - &-horizontal&-with-text-left { - &:before { - top: 50%; - width: 5%; - } - &:after { - top: 50%; - width: 95%; - } - } - - &-horizontal&-with-text-right { - &:before { - top: 50%; - width: 95%; - } - &:after { - top: 50%; - width: 5%; - } - } - - &-inner-text { - display: inline-block; - padding: 0 24px; - } - - &-dashed { - background: none; - border-top: 1px dashed @border-color-split; - } - &-horizontal&-with-text&-dashed, - &-horizontal&-with-text-left&-dashed, - &-horizontal&-with-text-right&-dashed { - border-top: 0; - &:before, - &:after { - border-style: dashed none none; - } - } -} - -@dropdown-prefix-cls: ~'@{ant-prefix}-dropdown'; - -.@{dropdown-prefix-cls} { - .reset-component; - position: absolute; - left: -9999px; - top: -9999px; - z-index: @zindex-dropdown; - display: block; - - &:before { - position: absolute; - top: -7px; - left: -7px; - right: 0; - bottom: -7px; - content: ' '; - opacity: 0.0001; - } - - &-wrap { - position: relative; - - .@{ant-prefix}-btn > .@{iconfont-css-prefix}-down { - .iconfont-size-under-12px(10px); - } - - .@{iconfont-css-prefix}-down:before { - transition: transform 0.2s; - } - } - - &-wrap-open { - .@{iconfont-css-prefix}-down:before { - transform: rotate(180deg); - } - } - - &-hidden, - &-menu-hidden { - display: none; - } - - &-menu { - outline: none; - position: relative; - list-style-type: none; - padding: 4px 0; - margin: 0; - text-align: left; - background-color: @component-background; - border-radius: @border-radius-base; - box-shadow: @box-shadow-base; - background-clip: padding-box; - -webkit-transform: translate3d(0, 0, 0); - - &-item-group-title { - color: @text-color-secondary; - padding: 5px @control-padding-horizontal; - transition: all 0.3s; - } - - &-submenu-popup { - position: absolute; - z-index: @zindex-dropdown; - - > .@{dropdown-prefix-cls}-menu { - transform-origin: 0 0; - } - } - - &-item, - &-submenu-title { - padding: 5px @control-padding-horizontal; - margin: 0; - clear: both; - font-size: @font-size-base; - font-weight: normal; - color: @text-color; - white-space: nowrap; - cursor: pointer; - transition: all 0.3s; - line-height: 22px; - - > .anticon:first-child { - min-width: 12px; - margin-right: 8px; - } - - > a { - color: @text-color; - display: block; - padding: 5px @control-padding-horizontal; - margin: -5px -@control-padding-horizontal; - transition: all 0.3s; - &:focus { - text-decoration: none; - } - } - - &-selected, - &-selected > a { - color: @primary-color; - background-color: @item-active-bg; - } - - &:hover { - background-color: @item-hover-bg; - } - - &-disabled { - color: @disabled-color; - cursor: not-allowed; - - &:hover { - color: @disabled-color; - background-color: @component-background; - cursor: not-allowed; - } - } - - &-divider { - height: 1px; - overflow: hidden; - background-color: @border-color-split; - line-height: 0; - margin: 4px 0; - } - .@{dropdown-prefix-cls}-menu-submenu-arrow { - position: absolute; - right: @padding-xs; - &-icon { - font-style: normal; - color: @text-color-secondary; - .iconfont-size-under-12px(10px); - } - } - } - - &-submenu-title { - padding-right: 26px; - } - - &-submenu-vertical { - position: relative; - } - - &-submenu-vertical > & { - top: 0; - left: 100%; - position: absolute; - min-width: 100%; - margin-left: 4px; - transform-origin: 0 0; - } - - &-submenu&-submenu-disabled .@{dropdown-prefix-cls}-menu-submenu-title { - &, - .@{dropdown-prefix-cls}-menu-submenu-arrow-icon { - color: @disabled-color; - } - } - } - - &.slide-down-enter.slide-down-enter-active&-placement-bottomLeft, - &.slide-down-appear.slide-down-appear-active&-placement-bottomLeft, - &.slide-down-enter.slide-down-enter-active&-placement-bottomCenter, - &.slide-down-appear.slide-down-appear-active&-placement-bottomCenter, - &.slide-down-enter.slide-down-enter-active&-placement-bottomRight, - &.slide-down-appear.slide-down-appear-active&-placement-bottomRight { - animation-name: antSlideUpIn; - } - - &.slide-up-enter.slide-up-enter-active&-placement-topLeft, - &.slide-up-appear.slide-up-appear-active&-placement-topLeft, - &.slide-up-enter.slide-up-enter-active&-placement-topCenter, - &.slide-up-appear.slide-up-appear-active&-placement-topCenter, - &.slide-up-enter.slide-up-enter-active&-placement-topRight, - &.slide-up-appear.slide-up-appear-active&-placement-topRight { - animation-name: antSlideDownIn; - } - - &.slide-down-leave.slide-down-leave-active&-placement-bottomLeft, - &.slide-down-leave.slide-down-leave-active&-placement-bottomCenter, - &.slide-down-leave.slide-down-leave-active&-placement-bottomRight { - animation-name: antSlideUpOut; - } - - &.slide-up-leave.slide-up-leave-active&-placement-topLeft, - &.slide-up-leave.slide-up-leave-active&-placement-topCenter, - &.slide-up-leave.slide-up-leave-active&-placement-topRight { - animation-name: antSlideDownOut; - } -} - -.@{dropdown-prefix-cls}-trigger, -.@{dropdown-prefix-cls}-link { - > .@{iconfont-css-prefix}.@{iconfont-css-prefix}-down { - .iconfont-size-under-12px(10px); - } -} - -.@{dropdown-prefix-cls}-button { - white-space: nowrap; - - &.@{ant-prefix}-btn-group > .@{ant-prefix}-btn:last-child:not(:first-child) { - padding-left: @padding-xs; - padding-right: @padding-xs; - } - .@{iconfont-css-prefix}.@{iconfont-css-prefix}-down { - .iconfont-size-under-12px(10px); - } -} - -// https://github.com/ant-design/ant-design/issues/4903 -.@{dropdown-prefix-cls}-menu-dark { - &, - .@{dropdown-prefix-cls}-menu { - background: @menu-dark-bg; - } - .@{dropdown-prefix-cls}-menu-item, - .@{dropdown-prefix-cls}-menu-submenu-title, - .@{dropdown-prefix-cls}-menu-item > a { - color: @text-color-secondary-dark; - .@{dropdown-prefix-cls}-menu-submenu-arrow:after { - color: @text-color-secondary-dark; - } - &:hover { - color: #fff; - background: transparent; - } - } - .@{dropdown-prefix-cls}-menu-item-selected { - &, - &:hover, - > a { - background: @primary-color; - color: #fff; - } - } -} - -.form-control-validation(@text-color: @input-color; @border-color: @input-border-color; @background-color: @input-bg) { - .@{ant-prefix}-form-explain, - .@{ant-prefix}-form-split { - color: @text-color; - } - // 输入框的不同校验状态 - .@{ant-prefix}-input { - &, - &:hover { - border-color: @border-color; - } - - &:focus { - .active(@border-color); - } - - &:not([disabled]):hover { - border-color: @border-color; - } - } - - .@{ant-prefix}-calendar-picker-open .@{ant-prefix}-calendar-picker-input { - .active(@border-color); - } - - // Input prefix - .@{ant-prefix}-input-affix-wrapper { - .@{ant-prefix}-input { - &, - &:hover { - border-color: @border-color; - } - - &:focus { - .active(@border-color); - } - } - - &:hover .@{ant-prefix}-input:not(.@{ant-prefix}-input-disabled) { - border-color: @border-color; - } - } - - .@{ant-prefix}-input-prefix { - color: @text-color; - } - - .@{ant-prefix}-input-group-addon { - color: @text-color; - border-color: @border-color; - background-color: @background-color; - } - - .has-feedback { - color: @text-color; - } -} - -// Reset form styles -// ----------------------------- -// Based on Bootstrap framework -.reset-form() { - legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: @font-size-lg; - line-height: inherit; - color: @text-color-secondary; - border: 0; - border-bottom: @border-width-base @border-style-base @border-color-base; - } - - label { - font-size: @font-size-base; - } - - input[type='search'] { - box-sizing: border-box; - } - - // Position radios and checkboxes better - input[type='radio'], - input[type='checkbox'] { - line-height: normal; - } - - input[type='file'] { - display: block; - } - - // Make range inputs behave like textual form controls - input[type='range'] { - display: block; - width: 100%; - } - - // Make multiple select elements height not fixed - select[multiple], - select[size] { - height: auto; - } - - // Focus for file, radio, and checkbox - input[type='file']:focus, - input[type='radio']:focus, - input[type='checkbox']:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } - - // Adjust output element - output { - display: block; - padding-top: 15px; - font-size: @font-size-base; - line-height: @line-height-base; - color: @input-color; - } -} - -@form-prefix-cls: ~'@{ant-prefix}-form'; -@form-component-height: @input-height-base; -@form-component-max-height: @input-height-lg; -@form-feedback-icon-size: @font-size-base; -@form-help-margin-top: (@form-component-height - @form-component-max-height) / 2 + 2px; - -.@{form-prefix-cls} { - .reset-component; - .reset-form; -} - -.@{form-prefix-cls}-item-required:before { - display: inline-block; - margin-right: 4px; - content: '*'; - font-family: SimSun; - line-height: 1; - font-size: @font-size-base; - color: @label-required-color; - .@{form-prefix-cls}-hide-required-mark & { - display: none; - } -} - -// Radio && Checkbox -input[type='radio'], -input[type='checkbox'] { - &[disabled], - &.disabled { - cursor: not-allowed; - } -} - -// These classes are used directly on