├── renovate.json ├── .travis.yml ├── jest.config.js ├── .eslintrc.js ├── .prettierrc.js ├── src ├── index.ts ├── types.ts └── generate.ts ├── tests ├── presets.test.ts ├── index.test.ts ├── export.test.ts └── __snapshots__ │ └── presets.test.ts.snap ├── .fatherrc.ts ├── .github └── workflows │ ├── ci.yml │ ├── dependency-review.yml │ └── codeql.yml ├── tsconfig.json ├── .gitignore ├── bench ├── generate.bench.ts ├── generate-old.ts └── presets.bench.ts ├── LICENSE ├── package.json ├── generate-presets.ts └── README.md /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base"] 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - 12 5 | 6 | script: 7 | - npm run coverage -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | collectCoverage: true, 4 | }; 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [require.resolve('@umijs/fabric/dist/eslint')], 3 | }; 4 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | const fabric = require('@umijs/fabric'); 2 | 3 | module.exports = { 4 | ...fabric.prettier, 5 | }; 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as generate } from './generate'; 2 | export * from './presets' 3 | export type * from './types' 4 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export type Palette = string[] & { primary?: string }; 2 | 3 | export type PalettesProps = Record; 4 | -------------------------------------------------------------------------------- /tests/presets.test.ts: -------------------------------------------------------------------------------- 1 | import * as presets from '../src/presets' 2 | 3 | test('presets', () => { 4 | expect(presets).toMatchSnapshot() 5 | }) -------------------------------------------------------------------------------- /.fatherrc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'father'; 2 | 3 | export default defineConfig({ 4 | plugins: ['@rc-component/father-plugin'], 5 | }); 6 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ✅ test 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | uses: react-component/rc-test/.github/workflows/test.yml@main 6 | secrets: inherit 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationMap": true, 5 | "esModuleInterop": true, 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "noUnusedLocals": true, 9 | "noUnusedParameters": true, 10 | "strict": true, 11 | "skipLibCheck": true, 12 | "target": "es2015", 13 | "baseUrl": ".", 14 | "paths": { 15 | "@/*": ["./src/*"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .project 13 | .*proj 14 | .svn/ 15 | *.swp 16 | *.swo 17 | *.log 18 | *.log.* 19 | *.json.gzip 20 | node_modules/ 21 | .buildpath 22 | .settings 23 | npm-debug.log 24 | nohup.out 25 | src/**/*.js 26 | src/presets.ts 27 | tests/**/*.js 28 | /.vscode/ 29 | /coverage 30 | yarn.lock 31 | package-lock.json 32 | pnpm-lock.yaml 33 | /.history 34 | lib 35 | es 36 | dist 37 | -------------------------------------------------------------------------------- /bench/generate.bench.ts: -------------------------------------------------------------------------------- 1 | import { bench, describe } from 'vitest'; 2 | import generate from '../src/generate'; 3 | import generateOld from './generate-old'; 4 | 5 | describe('generate from hex string', () => { 6 | bench('@ctrl/tinycolor', () => { 7 | generateOld('#66ccff'); 8 | }); 9 | 10 | bench('@ant-design/fast-color', () => { 11 | generate('#66ccff'); 12 | }); 13 | }); 14 | 15 | describe('generate from rgb object', () => { 16 | bench('@ctrl/tinycolor', () => { 17 | generateOld({ r: 102, g: 204, b: 255 }); 18 | }); 19 | 20 | bench('@ant-design/fast-color', () => { 21 | generate({ r: 102, g: 204, b: 255 }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Dependency Review Action 2 | # 3 | # This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. 4 | # 5 | # Source repository: https://github.com/actions/dependency-review-action 6 | # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement 7 | name: 'Dependency Review' 8 | on: [pull_request] 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | dependency-review: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: 'Checkout Repository' 18 | uses: actions/checkout@v3 19 | - name: 'Dependency Review' 20 | uses: actions/dependency-review-action@v3 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2018-present Ant UED, https://xtech.antfin.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ant-design/colors", 3 | "version": "8.0.0", 4 | "description": "Color palettes calculator of Ant Design", 5 | "homepage": "https://github.com/ant-design/ant-design-colors#readme", 6 | "bugs": { 7 | "url": "https://github.com/ant-design/ant-design-colors/issues" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/ant-design/ant-design-colors.git" 12 | }, 13 | "license": "MIT", 14 | "author": "afc163 ", 15 | "main": "./lib/index", 16 | "module": "./es/index", 17 | "typings": "es/index.d.ts", 18 | "files": [ 19 | "lib", 20 | "es" 21 | ], 22 | "scripts": { 23 | "bench": "vitest bench", 24 | "coverage": "npm test -- --coverage", 25 | "compile": "father build", 26 | "lint": "eslint src --ext .ts", 27 | "prepare": "tsx generate-presets", 28 | "prepublishOnly": "npm run compile && rc-np", 29 | "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", 30 | "test": "jest" 31 | }, 32 | "dependencies": { 33 | "@ant-design/fast-color": "^3.0.0" 34 | }, 35 | "devDependencies": { 36 | "@ctrl/tinycolor": "^3.6.1", 37 | "@rc-component/father-plugin": "^2.0.4", 38 | "@rc-component/np": "^1.0.0", 39 | "@types/jest": "^26.0.24", 40 | "@types/node": "^20.14.9", 41 | "@umijs/fabric": "^3.0.0", 42 | "eslint": "^7.32.0", 43 | "father": "^4.4.4", 44 | "jest": "^26.6.3", 45 | "prettier": "^2.8.8", 46 | "ts-jest": "^26.5.6", 47 | "tsx": "^4.16.1", 48 | "typescript": "~5.8.2", 49 | "vitest": "^1.6.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /generate-presets.ts: -------------------------------------------------------------------------------- 1 | import type { PalettesProps } from './src/types'; 2 | import generate from './src/generate'; 3 | import { writeFileSync } from 'fs' 4 | 5 | const presetPrimaryColors: Record = { 6 | red: '#F5222D', 7 | volcano: '#FA541C', 8 | orange: '#FA8C16', 9 | gold: '#FAAD14', 10 | yellow: '#FADB14', 11 | lime: '#A0D911', 12 | green: '#52C41A', 13 | cyan: '#13C2C2', 14 | blue: '#1677FF', 15 | geekblue: '#2F54EB', 16 | purple: '#722ED1', 17 | magenta: '#EB2F96', 18 | grey: '#666666', 19 | }; 20 | 21 | const presetPalettes: PalettesProps = {}; 22 | const presetDarkPalettes: PalettesProps = {}; 23 | 24 | Object.keys(presetPrimaryColors).forEach((key): void => { 25 | presetPalettes[key] = generate(presetPrimaryColors[key]); 26 | presetPalettes[key].primary = presetPalettes[key][5]; 27 | 28 | // dark presetPalettes 29 | presetDarkPalettes[key] = generate(presetPrimaryColors[key], { 30 | theme: 'dark', 31 | backgroundColor: '#141414', 32 | }); 33 | presetDarkPalettes[key].primary = presetDarkPalettes[key][5]; 34 | }); 35 | 36 | writeFileSync('./src/presets.ts', `// Generated by script. Do NOT modify! 37 | import type { Palette, PalettesProps } from './types'; 38 | 39 | export const presetPrimaryColors: Record = ${JSON.stringify(presetPrimaryColors, null, 2)}; 40 | 41 | ${Object.keys(presetPrimaryColors).map(key => `export const ${key}: Palette = ${JSON.stringify(presetPalettes[key], null, 2)};\n${key}.primary = ${key}[5];`).join('\n\n')} 42 | 43 | export const gray = grey; 44 | 45 | export const presetPalettes: PalettesProps = { 46 | ${Object.keys(presetPrimaryColors).join(',\n ')}, 47 | }; 48 | 49 | ${Object.keys(presetPrimaryColors).map(key => `export const ${key}Dark: Palette = ${JSON.stringify(presetDarkPalettes[key], null, 2)};\n${key}Dark.primary = ${key}Dark[5];`).join('\n\n')} 50 | 51 | export const presetDarkPalettes: PalettesProps = { 52 | ${Object.keys(presetPrimaryColors).map(key => `${key}: ${key}Dark`).join(',\n ')}, 53 | }; 54 | `); -------------------------------------------------------------------------------- /tests/index.test.ts: -------------------------------------------------------------------------------- 1 | import { generate, presetPalettes } from '../src'; 2 | 3 | export const presetBlueColors = [ 4 | '#e6f4ff', 5 | '#bae0ff', 6 | '#91caff', 7 | '#69b1ff', 8 | '#4096ff', 9 | '#1677ff', 10 | '#0958d9', 11 | '#003eb3', 12 | '#002c8c', 13 | '#001d66', 14 | ].map((color) => color.toLowerCase()); 15 | 16 | export const presetBlueDarkColors = [ 17 | '#111a2c', 18 | '#112545', 19 | '#15325b', 20 | '#15417e', 21 | '#1554ad', 22 | '#1668dc', 23 | '#3c89e8', 24 | '#65a9f3', 25 | '#8dc5f8', 26 | '#b7dcfa', 27 | ]; 28 | 29 | test('Generate palettes from a given color', () => { 30 | expect(generate('#1890ff')).toEqual([ 31 | '#e6f7ff', 32 | '#bae7ff', 33 | '#91d5ff', 34 | '#69c0ff', 35 | '#40a9ff', 36 | '#1890ff', 37 | '#096dd9', 38 | '#0050b3', 39 | '#003a8c', 40 | '#002766', 41 | ]); 42 | }); 43 | 44 | test('Generate dark palettes from a given color', () => { 45 | expect( 46 | generate('#1890ff', { 47 | theme: 'dark', 48 | backgroundColor: '#141414', 49 | }), 50 | ).toEqual([ 51 | '#111d2c', 52 | '#112a45', 53 | '#15395b', 54 | '#164c7e', 55 | '#1765ad', 56 | '#177ddc', 57 | '#3c9ae8', 58 | '#65b7f3', 59 | '#8dcff8', 60 | '#b7e3fa', 61 | ]); 62 | }); 63 | 64 | test('Generate primary color', () => { 65 | expect(presetPalettes.blue.primary).toEqual('#1677ff'); 66 | }); 67 | 68 | test('should contain preseted palettes', () => { 69 | expect(Object.keys(presetPalettes)).toEqual([ 70 | 'red', 71 | 'volcano', 72 | 'orange', 73 | 'gold', 74 | 'yellow', 75 | 'lime', 76 | 'green', 77 | 'cyan', 78 | 'blue', 79 | 'geekblue', 80 | 'purple', 81 | 'magenta', 82 | 'grey', 83 | ]); 84 | expect([...presetPalettes.blue]).toEqual(presetBlueColors); 85 | }); 86 | 87 | test('Generate grey colors', () => { 88 | // 测试灰色(h=0, s=0 的特殊情况) 89 | expect(generate('#666666')).toBeTruthy(); 90 | expect(generate('#666666', { theme: 'dark' })).toBeTruthy(); 91 | }); 92 | -------------------------------------------------------------------------------- /tests/export.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | blue, 3 | cyan, 4 | geekblue, 5 | gold, 6 | gray, 7 | green, 8 | grey, 9 | lime, 10 | magenta, 11 | orange, 12 | presetDarkPalettes, 13 | purple, 14 | red, 15 | volcano, 16 | yellow, 17 | } from '../src'; 18 | import { presetBlueColors, presetBlueDarkColors } from './index.test'; 19 | 20 | test(`import { blue } from '@ant-design/colors'`, () => { 21 | expect(blue.primary).toEqual(presetBlueColors[5]); 22 | expect([...blue]).toEqual(presetBlueColors); 23 | }); 24 | 25 | test(`import { presetDarkPalettes } from '@ant-design/colors'`, () => { 26 | const darkBlue = presetDarkPalettes.blue; 27 | expect([...darkBlue]).toEqual(presetBlueDarkColors); 28 | }); 29 | 30 | test(`other colors'`, () => { 31 | expect(red.length).toEqual(10); 32 | expect(volcano.length).toEqual(10); 33 | expect(orange.length).toEqual(10); 34 | expect(gold.length).toEqual(10); 35 | expect(yellow.length).toEqual(10); 36 | expect(lime.length).toEqual(10); 37 | expect(green.length).toEqual(10); 38 | expect(cyan.length).toEqual(10); 39 | expect(blue.length).toEqual(10); 40 | expect(geekblue.length).toEqual(10); 41 | expect(purple.length).toEqual(10); 42 | expect(magenta.length).toEqual(10); 43 | expect(grey.length).toEqual(10); 44 | expect(gray.length).toEqual(10); 45 | 46 | expect(presetDarkPalettes.red.length).toEqual(10); 47 | expect(presetDarkPalettes.volcano.length).toEqual(10); 48 | expect(presetDarkPalettes.orange.length).toEqual(10); 49 | expect(presetDarkPalettes.gold.length).toEqual(10); 50 | expect(presetDarkPalettes.yellow.length).toEqual(10); 51 | expect(presetDarkPalettes.lime.length).toEqual(10); 52 | expect(presetDarkPalettes.green.length).toEqual(10); 53 | expect(presetDarkPalettes.cyan.length).toEqual(10); 54 | expect(presetDarkPalettes.blue.length).toEqual(10); 55 | expect(presetDarkPalettes.geekblue.length).toEqual(10); 56 | expect(presetDarkPalettes.purple.length).toEqual(10); 57 | expect(presetDarkPalettes.magenta.length).toEqual(10); 58 | expect(presetDarkPalettes.grey.length).toEqual(10); 59 | }); 60 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "master" ] 17 | pull_request: 18 | branches: [ "master" ] 19 | schedule: 20 | - cron: '17 7 * * 5' 21 | 22 | jobs: 23 | analyze: 24 | name: Analyze 25 | # Runner size impacts CodeQL analysis time. To learn more, please see: 26 | # - https://gh.io/recommended-hardware-resources-for-running-codeql 27 | # - https://gh.io/supported-runners-and-hardware-resources 28 | # - https://gh.io/using-larger-runners 29 | # Consider using larger runners for possible analysis time improvements. 30 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} 31 | timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} 32 | permissions: 33 | actions: read 34 | contents: read 35 | security-events: write 36 | 37 | strategy: 38 | fail-fast: false 39 | matrix: 40 | language: [ 'javascript-typescript' ] 41 | # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] 42 | # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both 43 | # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both 44 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 45 | 46 | steps: 47 | - name: Checkout repository 48 | uses: actions/checkout@v4 49 | 50 | # Initializes the CodeQL tools for scanning. 51 | - name: Initialize CodeQL 52 | uses: github/codeql-action/init@v3 53 | with: 54 | languages: ${{ matrix.language }} 55 | # If you wish to specify custom queries, you can do so here or in a config file. 56 | # By default, queries listed here will override any specified in a config file. 57 | # Prefix the list here with "+" to use these queries and those in the config file. 58 | 59 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 60 | # queries: security-extended,security-and-quality 61 | 62 | 63 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). 64 | # If this step fails, then you should remove it and run the build manually (see below) 65 | - name: Autobuild 66 | uses: github/codeql-action/autobuild@v3 67 | 68 | # ℹ️ Command-line programs to run using the OS shell. 69 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 70 | 71 | # If the Autobuild fails above, remove it and uncomment the following three lines. 72 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 73 | 74 | # - run: | 75 | # echo "Run, Build Application using script" 76 | # ./location_of_script_within_repo/buildscript.sh 77 | 78 | - name: Perform CodeQL Analysis 79 | uses: github/codeql-action/analyze@v3 80 | with: 81 | category: "/language:${{matrix.language}}" 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Ant Design Colors

2 | 3 |
4 | 5 | :art: Color palettes calculator of [Ant Design](https://ant.design/docs/spec/colors). 6 | 7 | [![CI status][github-action-image]][github-action-url] 8 | [![codecov][codecov-image]][codecov-url] 9 | [![NPM version][npm-image]][npm-url] 10 | [![NPM downloads][download-image]][download-url] 11 | [![][bundlephobia-image]][bundlephobia-url] 12 | 13 | ![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png) 14 | 15 | [npm-image]: http://img.shields.io/npm/v/@ant-design/colors.svg?style=flat-square 16 | [npm-url]: http://npmjs.org/package/@ant-design/colors 17 | [github-action-image]: https://github.com/ant-design/ant-design-colors/actions/workflows/ci.yml/badge.svg 18 | [github-action-url]: https://github.com/ant-design/ant-design-colors/actions/workflows/ci.yml 19 | [codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design-colors/main.svg?style=flat-square 20 | [codecov-url]: https://codecov.io/gh/ant-design/ant-design-colors/tree/main 21 | [download-image]: https://img.shields.io/npm/dm/@ant-design/colors.svg?style=flat-square 22 | [download-url]: https://npmjs.org/package/@ant-design/colors 23 | [bundlephobia-image]: https://badgen.net/bundlephobia/minzip/@ant-design/colors?style=flat-square 24 | [bundlephobia-url]: https://bundlephobia.com/package/@ant-design/colors 25 |
26 | 27 | ![](https://user-images.githubusercontent.com/507615/55726820-43e68400-5a43-11e9-8541-b0fc28b78f37.png) 28 | 29 | ## Install 30 | 31 | ```bash 32 | $ npm install @ant-design/colors 33 | // or 34 | $ yarn add @ant-design/colors 35 | ``` 36 | 37 | ## Usage 38 | 39 | ```bash 40 | $ npm install @ant-design/colors --save 41 | ``` 42 | 43 | ```js 44 | import { 45 | red, 46 | volcano, 47 | gold, 48 | yellow, 49 | lime, 50 | green, 51 | cyan, 52 | blue, 53 | geekblue, 54 | purple, 55 | magenta, 56 | grey, 57 | } from '@ant-design/colors'; 58 | 59 | console.log(blue); // ['#E6F4FF', '#BAE0FF', '#91CAFF', '#69B1FF', '#4096FF', '#1677FF', '#0958D9', '#003EB3', '#002C8C', '#001D66'] 60 | console.log(blue.primary); // '#1677FF' 61 | ``` 62 | 63 | ```js 64 | import { generate, presetPalettes } from '@ant-design/colors'; 65 | 66 | // Generate color palettes by a given color 67 | const colors = generate('#1890ff'); 68 | console.log(colors); // ['#E6F7FF', '#BAE7FF', '#91D5FF', ''#69C0FF', '#40A9FF', '#1890FF', '#096DD9', '#0050B3', '#003A8C', '#002766'] 69 | console.log(presetPalettes); 70 | /* 71 | { 72 | red: [...], 73 | volcano: [...], 74 | orange: [...], 75 | gold: [...], 76 | yellow: [...], 77 | lime: [...], 78 | green: [...], 79 | cyan: [...], 80 | blue: [...], 81 | geekblue: [...], 82 | purple: [...], 83 | magenta: [...], 84 | } 85 | */ 86 | ``` 87 | 88 | ```js 89 | import { generate, presetDarkPalettes } from '@ant-design/colors'; 90 | 91 | // Generate dark color palettes by a given color 92 | const colors = generate('#1890ff', { 93 | theme: 'dark', 94 | backgroundColor: '#141414', 95 | }); 96 | console.log(colors); // ['#111d2c', '#112a45', '#15395b', '#164c7e', '#1765ad', '#177ddc', '#3c9ae8', '#65b7f3', '#8dcff8', '#b7e3fa'] 97 | console.log(presetDarkPalettes); 98 | /* 99 | { 100 | red: [...], 101 | volcano: [...], 102 | orange: [...], 103 | gold: [...], 104 | yellow: [...], 105 | lime: [...], 106 | green: [...], 107 | cyan: [...], 108 | blue: [...], 109 | geekblue: [...], 110 | purple: [...], 111 | magenta: [...], 112 | } 113 | */ 114 | ``` 115 | 116 | ## Articles 117 | 118 | - [Ant Design Colors](https://ant.design/docs/spec/colors) 119 | - [Ant Design 色板生成算法演进之路](https://zhuanlan.zhihu.com/p/32422584) 120 | -------------------------------------------------------------------------------- /src/generate.ts: -------------------------------------------------------------------------------- 1 | import type { ColorInput } from '@ant-design/fast-color'; 2 | import { FastColor } from '@ant-design/fast-color'; 3 | 4 | const hueStep = 2; // 色相阶梯 5 | const saturationStep = 0.16; // 饱和度阶梯,浅色部分 6 | const saturationStep2 = 0.05; // 饱和度阶梯,深色部分 7 | const brightnessStep1 = 0.05; // 亮度阶梯,浅色部分 8 | const brightnessStep2 = 0.15; // 亮度阶梯,深色部分 9 | const lightColorCount = 5; // 浅色数量,主色上 10 | const darkColorCount = 4; // 深色数量,主色下 11 | 12 | // 暗色主题颜色映射关系表 13 | const darkColorMap = [ 14 | { index: 7, amount: 15 }, 15 | { index: 6, amount: 25 }, 16 | { index: 5, amount: 30 }, 17 | { index: 5, amount: 45 }, 18 | { index: 5, amount: 65 }, 19 | { index: 5, amount: 85 }, 20 | { index: 4, amount: 90 }, 21 | { index: 3, amount: 95 }, 22 | { index: 2, amount: 97 }, 23 | { index: 1, amount: 98 }, 24 | ]; 25 | 26 | interface HsvObject { 27 | h: number; 28 | s: number; 29 | v: number; 30 | } 31 | 32 | function getHue(hsv: HsvObject, i: number, light?: boolean): number { 33 | let hue: number; 34 | // 根据色相不同,色相转向不同 35 | if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) { 36 | hue = light ? Math.round(hsv.h) - hueStep * i : Math.round(hsv.h) + hueStep * i; 37 | } else { 38 | hue = light ? Math.round(hsv.h) + hueStep * i : Math.round(hsv.h) - hueStep * i; 39 | } 40 | if (hue < 0) { 41 | hue += 360; 42 | } else if (hue >= 360) { 43 | hue -= 360; 44 | } 45 | return hue; 46 | } 47 | 48 | function getSaturation(hsv: HsvObject, i: number, light?: boolean): number { 49 | // grey color don't change saturation 50 | if (hsv.h === 0 && hsv.s === 0) { 51 | return hsv.s; 52 | } 53 | let saturation: number; 54 | if (light) { 55 | saturation = hsv.s - saturationStep * i; 56 | } else if (i === darkColorCount) { 57 | saturation = hsv.s + saturationStep; 58 | } else { 59 | saturation = hsv.s + saturationStep2 * i; 60 | } 61 | // 边界值修正 62 | if (saturation > 1) { 63 | saturation = 1; 64 | } 65 | // 第一格的 s 限制在 0.06-0.1 之间 66 | if (light && i === lightColorCount && saturation > 0.1) { 67 | saturation = 0.1; 68 | } 69 | if (saturation < 0.06) { 70 | saturation = 0.06; 71 | } 72 | return Math.round(saturation * 100) / 100; 73 | } 74 | 75 | function getValue(hsv: HsvObject, i: number, light?: boolean): number { 76 | let value: number; 77 | if (light) { 78 | value = hsv.v + brightnessStep1 * i; 79 | } else { 80 | value = hsv.v - brightnessStep2 * i; 81 | } 82 | // Clamp value between 0 and 1 83 | value = Math.max(0, Math.min(1, value)); 84 | return Math.round(value * 100) / 100; 85 | } 86 | 87 | interface Opts { 88 | theme?: 'dark' | 'default'; 89 | backgroundColor?: string; 90 | } 91 | 92 | export default function generate(color: ColorInput, opts: Opts = {}): string[] { 93 | const patterns: FastColor[] = []; 94 | const pColor = new FastColor(color); 95 | const hsv = pColor.toHsv(); 96 | for (let i = lightColorCount; i > 0; i -= 1) { 97 | const c = new FastColor({ 98 | h: getHue(hsv, i, true), 99 | s: getSaturation(hsv, i, true), 100 | v: getValue(hsv, i, true), 101 | }); 102 | patterns.push(c); 103 | } 104 | patterns.push(pColor); 105 | for (let i = 1; i <= darkColorCount; i += 1) { 106 | const c = new FastColor({ 107 | h: getHue(hsv, i), 108 | s: getSaturation(hsv, i), 109 | v: getValue(hsv, i), 110 | }); 111 | patterns.push(c); 112 | } 113 | 114 | // dark theme patterns 115 | if (opts.theme === 'dark') { 116 | return darkColorMap.map(({ index, amount }) => 117 | new FastColor(opts.backgroundColor || '#141414').mix(patterns[index], amount).toHexString(), 118 | ); 119 | } 120 | 121 | return patterns.map((c) => c.toHexString()); 122 | } 123 | -------------------------------------------------------------------------------- /bench/generate-old.ts: -------------------------------------------------------------------------------- 1 | import { inputToRGB, rgbToHex, rgbToHsv } from '@ctrl/tinycolor'; 2 | 3 | const hueStep = 2; // 色相阶梯 4 | const saturationStep = 0.16; // 饱和度阶梯,浅色部分 5 | const saturationStep2 = 0.05; // 饱和度阶梯,深色部分 6 | const brightnessStep1 = 0.05; // 亮度阶梯,浅色部分 7 | const brightnessStep2 = 0.15; // 亮度阶梯,深色部分 8 | const lightColorCount = 5; // 浅色数量,主色上 9 | const darkColorCount = 4; // 深色数量,主色下 10 | // 暗色主题颜色映射关系表 11 | const darkColorMap = [ 12 | { index: 7, opacity: 0.15 }, 13 | { index: 6, opacity: 0.25 }, 14 | { index: 5, opacity: 0.3 }, 15 | { index: 5, opacity: 0.45 }, 16 | { index: 5, opacity: 0.65 }, 17 | { index: 5, opacity: 0.85 }, 18 | { index: 4, opacity: 0.9 }, 19 | { index: 3, opacity: 0.95 }, 20 | { index: 2, opacity: 0.97 }, 21 | { index: 1, opacity: 0.98 }, 22 | ]; 23 | 24 | interface HsvObject { 25 | h: number; 26 | s: number; 27 | v: number; 28 | } 29 | 30 | interface RgbObject { 31 | r: number; 32 | g: number; 33 | b: number; 34 | } 35 | 36 | // Wrapper function ported from TinyColor.prototype.toHsv 37 | // Keep it here because of `hsv.h * 360` 38 | function toHsv({ r, g, b }: RgbObject): HsvObject { 39 | const hsv = rgbToHsv(r, g, b); 40 | return { h: hsv.h * 360, s: hsv.s, v: hsv.v }; 41 | } 42 | 43 | // Wrapper function ported from TinyColor.prototype.toHexString 44 | // Keep it here because of the prefix `#` 45 | function toHex({ r, g, b }: RgbObject): string { 46 | return `#${rgbToHex(r, g, b, false)}`; 47 | } 48 | 49 | // Wrapper function ported from TinyColor.prototype.mix, not treeshakable. 50 | // Amount in range [0, 1] 51 | // Assume color1 & color2 has no alpha, since the following src code did so. 52 | function mix(rgb1: RgbObject, rgb2: RgbObject, amount: number): RgbObject { 53 | const p = amount / 100; 54 | const rgb = { 55 | r: (rgb2.r - rgb1.r) * p + rgb1.r, 56 | g: (rgb2.g - rgb1.g) * p + rgb1.g, 57 | b: (rgb2.b - rgb1.b) * p + rgb1.b, 58 | }; 59 | return rgb; 60 | } 61 | 62 | function getHue(hsv: HsvObject, i: number, light?: boolean): number { 63 | let hue: number; 64 | // 根据色相不同,色相转向不同 65 | if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) { 66 | hue = light ? Math.round(hsv.h) - hueStep * i : Math.round(hsv.h) + hueStep * i; 67 | } else { 68 | hue = light ? Math.round(hsv.h) + hueStep * i : Math.round(hsv.h) - hueStep * i; 69 | } 70 | if (hue < 0) { 71 | hue += 360; 72 | } else if (hue >= 360) { 73 | hue -= 360; 74 | } 75 | return hue; 76 | } 77 | 78 | function getSaturation(hsv: HsvObject, i: number, light?: boolean): number { 79 | // grey color don't change saturation 80 | if (hsv.h === 0 && hsv.s === 0) { 81 | return hsv.s; 82 | } 83 | let saturation: number; 84 | if (light) { 85 | saturation = hsv.s - saturationStep * i; 86 | } else if (i === darkColorCount) { 87 | saturation = hsv.s + saturationStep; 88 | } else { 89 | saturation = hsv.s + saturationStep2 * i; 90 | } 91 | // 边界值修正 92 | if (saturation > 1) { 93 | saturation = 1; 94 | } 95 | // 第一格的 s 限制在 0.06-0.1 之间 96 | if (light && i === lightColorCount && saturation > 0.1) { 97 | saturation = 0.1; 98 | } 99 | if (saturation < 0.06) { 100 | saturation = 0.06; 101 | } 102 | return Number(saturation.toFixed(2)); 103 | } 104 | 105 | function getValue(hsv: HsvObject, i: number, light?: boolean): number { 106 | let value: number; 107 | if (light) { 108 | value = hsv.v + brightnessStep1 * i; 109 | } else { 110 | value = hsv.v - brightnessStep2 * i; 111 | } 112 | if (value > 1) { 113 | value = 1; 114 | } 115 | return Number(value.toFixed(2)); 116 | } 117 | 118 | interface Opts { 119 | theme?: 'dark' | 'default'; 120 | backgroundColor?: string; 121 | } 122 | 123 | export default function generate(color: any, opts: Opts = {}): string[] { 124 | const patterns: string[] = []; 125 | const pColor = inputToRGB(color); 126 | for (let i = lightColorCount; i > 0; i -= 1) { 127 | const hsv = toHsv(pColor); 128 | const colorString: string = toHex( 129 | inputToRGB({ 130 | h: getHue(hsv, i, true), 131 | s: getSaturation(hsv, i, true), 132 | v: getValue(hsv, i, true), 133 | }), 134 | ); 135 | patterns.push(colorString); 136 | } 137 | patterns.push(toHex(pColor)); 138 | for (let i = 1; i <= darkColorCount; i += 1) { 139 | const hsv = toHsv(pColor); 140 | const colorString: string = toHex( 141 | inputToRGB({ 142 | h: getHue(hsv, i), 143 | s: getSaturation(hsv, i), 144 | v: getValue(hsv, i), 145 | }), 146 | ); 147 | patterns.push(colorString); 148 | } 149 | 150 | // dark theme patterns 151 | if (opts.theme === 'dark') { 152 | return darkColorMap.map(({ index, opacity }) => { 153 | const darkColorString: string = toHex( 154 | mix( 155 | inputToRGB(opts.backgroundColor || '#141414'), 156 | inputToRGB(patterns[index]), 157 | opacity * 100, 158 | ), 159 | ); 160 | return darkColorString; 161 | }); 162 | } 163 | return patterns; 164 | } -------------------------------------------------------------------------------- /bench/presets.bench.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unused-vars */ 2 | import { describe, bench } from 'vitest'; 3 | import type { Palette, PalettesProps } from '../src/types'; 4 | import generate from '../src/generate'; 5 | 6 | describe('presets', () => { 7 | bench('runtime calculate', () => { 8 | const presetPrimaryColors: Record = { 9 | red: '#F5222D', 10 | volcano: '#FA541C', 11 | orange: '#FA8C16', 12 | gold: '#FAAD14', 13 | yellow: '#FADB14', 14 | lime: '#A0D911', 15 | green: '#52C41A', 16 | cyan: '#13C2C2', 17 | blue: '#1677FF', 18 | geekblue: '#2F54EB', 19 | purple: '#722ED1', 20 | magenta: '#EB2F96', 21 | grey: '#666666', 22 | }; 23 | 24 | const presetPalettes: PalettesProps = {}; 25 | const presetDarkPalettes: PalettesProps = {}; 26 | 27 | Object.keys(presetPrimaryColors).forEach((key): void => { 28 | presetPalettes[key] = generate(presetPrimaryColors[key]); 29 | presetPalettes[key].primary = presetPalettes[key][5]; 30 | 31 | // dark presetPalettes 32 | presetDarkPalettes[key] = generate(presetPrimaryColors[key], { 33 | theme: 'dark', 34 | backgroundColor: '#141414', 35 | }); 36 | presetDarkPalettes[key].primary = presetDarkPalettes[key][5]; 37 | }); 38 | 39 | const red = presetPalettes.red; 40 | const volcano = presetPalettes.volcano; 41 | const gold = presetPalettes.gold; 42 | const orange = presetPalettes.orange; 43 | const yellow = presetPalettes.yellow; 44 | const lime = presetPalettes.lime; 45 | const green = presetPalettes.green; 46 | const cyan = presetPalettes.cyan; 47 | const blue = presetPalettes.blue; 48 | const geekblue = presetPalettes.geekblue; 49 | const purple = presetPalettes.purple; 50 | const magenta = presetPalettes.magenta; 51 | const grey = presetPalettes.grey; 52 | const gray = presetPalettes.grey; 53 | 54 | expect(red).toBeTruthy(); 55 | expect(volcano).toBeTruthy(); 56 | expect(gold).toBeTruthy(); 57 | expect(orange).toBeTruthy(); 58 | expect(yellow).toBeTruthy(); 59 | expect(lime).toBeTruthy(); 60 | expect(green).toBeTruthy(); 61 | expect(cyan).toBeTruthy(); 62 | expect(blue).toBeTruthy(); 63 | expect(geekblue).toBeTruthy(); 64 | expect(purple).toBeTruthy(); 65 | expect(magenta).toBeTruthy(); 66 | expect(grey).toBeTruthy(); 67 | expect(gray).toBeTruthy(); 68 | }); 69 | 70 | bench('pre-compile', () => { 71 | const presetPrimaryColors: Record = { 72 | red: '#F5222D', 73 | volcano: '#FA541C', 74 | orange: '#FA8C16', 75 | gold: '#FAAD14', 76 | yellow: '#FADB14', 77 | lime: '#A0D911', 78 | green: '#52C41A', 79 | cyan: '#13C2C2', 80 | blue: '#1677FF', 81 | geekblue: '#2F54EB', 82 | purple: '#722ED1', 83 | magenta: '#EB2F96', 84 | grey: '#666666', 85 | }; 86 | 87 | const red: Palette = [ 88 | '#fff1f0', 89 | '#ffccc7', 90 | '#ffa39e', 91 | '#ff7875', 92 | '#ff4d4f', 93 | '#f5222d', 94 | '#cf1322', 95 | '#a8071a', 96 | '#820014', 97 | '#5c0011', 98 | ]; 99 | red.primary = red[5]; 100 | 101 | const volcano: Palette = [ 102 | '#fff2e8', 103 | '#ffd8bf', 104 | '#ffbb96', 105 | '#ff9c6e', 106 | '#ff7a45', 107 | '#fa541c', 108 | '#d4380d', 109 | '#ad2102', 110 | '#871400', 111 | '#610b00', 112 | ]; 113 | volcano.primary = volcano[5]; 114 | 115 | const orange: Palette = [ 116 | '#fff7e6', 117 | '#ffe7ba', 118 | '#ffd591', 119 | '#ffc069', 120 | '#ffa940', 121 | '#fa8c16', 122 | '#d46b08', 123 | '#ad4e00', 124 | '#873800', 125 | '#612500', 126 | ]; 127 | orange.primary = orange[5]; 128 | 129 | const gold: Palette = [ 130 | '#fffbe6', 131 | '#fff1b8', 132 | '#ffe58f', 133 | '#ffd666', 134 | '#ffc53d', 135 | '#faad14', 136 | '#d48806', 137 | '#ad6800', 138 | '#874d00', 139 | '#613400', 140 | ]; 141 | gold.primary = gold[5]; 142 | 143 | const yellow: Palette = [ 144 | '#feffe6', 145 | '#ffffb8', 146 | '#fffb8f', 147 | '#fff566', 148 | '#ffec3d', 149 | '#fadb14', 150 | '#d4b106', 151 | '#ad8b00', 152 | '#876800', 153 | '#614700', 154 | ]; 155 | yellow.primary = yellow[5]; 156 | 157 | const lime: Palette = [ 158 | '#fcffe6', 159 | '#f4ffb8', 160 | '#eaff8f', 161 | '#d3f261', 162 | '#bae637', 163 | '#a0d911', 164 | '#7cb305', 165 | '#5b8c00', 166 | '#3f6600', 167 | '#254000', 168 | ]; 169 | lime.primary = lime[5]; 170 | 171 | const green: Palette = [ 172 | '#f6ffed', 173 | '#d9f7be', 174 | '#b7eb8f', 175 | '#95de64', 176 | '#73d13d', 177 | '#52c41a', 178 | '#389e0d', 179 | '#237804', 180 | '#135200', 181 | '#092b00', 182 | ]; 183 | green.primary = green[5]; 184 | 185 | const cyan: Palette = [ 186 | '#e6fffb', 187 | '#b5f5ec', 188 | '#87e8de', 189 | '#5cdbd3', 190 | '#36cfc9', 191 | '#13c2c2', 192 | '#08979c', 193 | '#006d75', 194 | '#00474f', 195 | '#002329', 196 | ]; 197 | cyan.primary = cyan[5]; 198 | 199 | const blue: Palette = [ 200 | '#e6f4ff', 201 | '#bae0ff', 202 | '#91caff', 203 | '#69b1ff', 204 | '#4096ff', 205 | '#1677ff', 206 | '#0958d9', 207 | '#003eb3', 208 | '#002c8c', 209 | '#001d66', 210 | ]; 211 | blue.primary = blue[5]; 212 | 213 | const geekblue: Palette = [ 214 | '#f0f5ff', 215 | '#d6e4ff', 216 | '#adc6ff', 217 | '#85a5ff', 218 | '#597ef7', 219 | '#2f54eb', 220 | '#1d39c4', 221 | '#10239e', 222 | '#061178', 223 | '#030852', 224 | ]; 225 | geekblue.primary = geekblue[5]; 226 | 227 | const purple: Palette = [ 228 | '#f9f0ff', 229 | '#efdbff', 230 | '#d3adf7', 231 | '#b37feb', 232 | '#9254de', 233 | '#722ed1', 234 | '#531dab', 235 | '#391085', 236 | '#22075e', 237 | '#120338', 238 | ]; 239 | purple.primary = purple[5]; 240 | 241 | const magenta: Palette = [ 242 | '#fff0f6', 243 | '#ffd6e7', 244 | '#ffadd2', 245 | '#ff85c0', 246 | '#f759ab', 247 | '#eb2f96', 248 | '#c41d7f', 249 | '#9e1068', 250 | '#780650', 251 | '#520339', 252 | ]; 253 | magenta.primary = magenta[5]; 254 | 255 | const grey: Palette = [ 256 | '#a6a6a6', 257 | '#999999', 258 | '#8c8c8c', 259 | '#808080', 260 | '#737373', 261 | '#666666', 262 | '#404040', 263 | '#1a1a1a', 264 | '#000000', 265 | '#000000', 266 | ]; 267 | grey.primary = grey[5]; 268 | 269 | const gray = grey; 270 | 271 | const presetPalettes: PalettesProps = { 272 | red, 273 | volcano, 274 | orange, 275 | gold, 276 | yellow, 277 | lime, 278 | green, 279 | cyan, 280 | blue, 281 | geekblue, 282 | purple, 283 | magenta, 284 | grey, 285 | gray: grey, 286 | }; 287 | 288 | const redDark: Palette = [ 289 | '#2a1215', 290 | '#431418', 291 | '#58181c', 292 | '#791a1f', 293 | '#a61d24', 294 | '#d32029', 295 | '#e84749', 296 | '#f37370', 297 | '#f89f9a', 298 | '#fac8c3', 299 | ]; 300 | redDark.primary = redDark[5]; 301 | 302 | const volcanoDark: Palette = [ 303 | '#2b1611', 304 | '#441d12', 305 | '#592716', 306 | '#7c3118', 307 | '#aa3e19', 308 | '#d84a1b', 309 | '#e87040', 310 | '#f3956a', 311 | '#f8b692', 312 | '#fad4bc', 313 | ]; 314 | volcanoDark.primary = volcanoDark[5]; 315 | 316 | const orangeDark: Palette = [ 317 | '#2b1d11', 318 | '#442a11', 319 | '#593815', 320 | '#7c4a15', 321 | '#aa6215', 322 | '#d87a16', 323 | '#e89a3c', 324 | '#f3b765', 325 | '#f8cf8d', 326 | '#fae3b7', 327 | ]; 328 | orangeDark.primary = orangeDark[5]; 329 | 330 | const goldDark: Palette = [ 331 | '#2b2111', 332 | '#443111', 333 | '#594214', 334 | '#7c5914', 335 | '#aa7714', 336 | '#d89614', 337 | '#e8b339', 338 | '#f3cc62', 339 | '#f8df8b', 340 | '#faedb5', 341 | ]; 342 | goldDark.primary = goldDark[5]; 343 | 344 | const yellowDark: Palette = [ 345 | '#2b2611', 346 | '#443b11', 347 | '#595014', 348 | '#7c6e14', 349 | '#aa9514', 350 | '#d8bd14', 351 | '#e8d639', 352 | '#f3ea62', 353 | '#f8f48b', 354 | '#fafab5', 355 | ]; 356 | yellowDark.primary = yellowDark[5]; 357 | 358 | const limeDark: Palette = [ 359 | '#1f2611', 360 | '#2e3c10', 361 | '#3e4f13', 362 | '#536d13', 363 | '#6f9412', 364 | '#8bbb11', 365 | '#a9d134', 366 | '#c9e75d', 367 | '#e4f88b', 368 | '#f0fab5', 369 | ]; 370 | limeDark.primary = limeDark[5]; 371 | 372 | const greenDark: Palette = [ 373 | '#162312', 374 | '#1d3712', 375 | '#274916', 376 | '#306317', 377 | '#3c8618', 378 | '#49aa19', 379 | '#6abe39', 380 | '#8fd460', 381 | '#b2e58b', 382 | '#d5f2bb', 383 | ]; 384 | greenDark.primary = greenDark[5]; 385 | 386 | const cyanDark: Palette = [ 387 | '#112123', 388 | '#113536', 389 | '#144848', 390 | '#146262', 391 | '#138585', 392 | '#13a8a8', 393 | '#33bcb7', 394 | '#58d1c9', 395 | '#84e2d8', 396 | '#b2f1e8', 397 | ]; 398 | cyanDark.primary = cyanDark[5]; 399 | 400 | const blueDark: Palette = [ 401 | '#111a2c', 402 | '#112545', 403 | '#15325b', 404 | '#15417e', 405 | '#1554ad', 406 | '#1668dc', 407 | '#3c89e8', 408 | '#65a9f3', 409 | '#8dc5f8', 410 | '#b7dcfa', 411 | ]; 412 | blueDark.primary = blueDark[5]; 413 | 414 | const geekblueDark: Palette = [ 415 | '#131629', 416 | '#161d40', 417 | '#1c2755', 418 | '#203175', 419 | '#263ea0', 420 | '#2b4acb', 421 | '#5273e0', 422 | '#7f9ef3', 423 | '#a8c1f8', 424 | '#d2e0fa', 425 | ]; 426 | geekblueDark.primary = geekblueDark[5]; 427 | 428 | const purpleDark: Palette = [ 429 | '#1a1325', 430 | '#24163a', 431 | '#301c4d', 432 | '#3e2069', 433 | '#51258f', 434 | '#642ab5', 435 | '#854eca', 436 | '#ab7ae0', 437 | '#cda8f0', 438 | '#ebd7fa', 439 | ]; 440 | purpleDark.primary = purpleDark[5]; 441 | 442 | const magentaDark: Palette = [ 443 | '#291321', 444 | '#40162f', 445 | '#551c3b', 446 | '#75204f', 447 | '#a02669', 448 | '#cb2b83', 449 | '#e0529c', 450 | '#f37fb7', 451 | '#f8a8cc', 452 | '#fad2e3', 453 | ]; 454 | magentaDark.primary = magentaDark[5]; 455 | 456 | const greyDark: Palette = [ 457 | '#151515', 458 | '#1f1f1f', 459 | '#2d2d2d', 460 | '#393939', 461 | '#494949', 462 | '#5a5a5a', 463 | '#6a6a6a', 464 | '#7b7b7b', 465 | '#888888', 466 | '#969696', 467 | ]; 468 | greyDark.primary = greyDark[5]; 469 | 470 | const grayDark = greyDark; 471 | 472 | const presetDarkPalettes: PalettesProps = { 473 | red: redDark, 474 | volcano: volcanoDark, 475 | orange: orangeDark, 476 | gold: goldDark, 477 | yellow: yellowDark, 478 | lime: limeDark, 479 | green: greenDark, 480 | cyan: cyanDark, 481 | blue: blueDark, 482 | geekblue: geekblueDark, 483 | purple: purpleDark, 484 | magenta: magentaDark, 485 | grey: greyDark, 486 | gray: greyDark, 487 | }; 488 | 489 | expect(red).toBeTruthy(); 490 | expect(volcano).toBeTruthy(); 491 | expect(gold).toBeTruthy(); 492 | expect(orange).toBeTruthy(); 493 | expect(yellow).toBeTruthy(); 494 | expect(lime).toBeTruthy(); 495 | expect(green).toBeTruthy(); 496 | expect(cyan).toBeTruthy(); 497 | expect(blue).toBeTruthy(); 498 | expect(geekblue).toBeTruthy(); 499 | expect(purple).toBeTruthy(); 500 | expect(magenta).toBeTruthy(); 501 | expect(grey).toBeTruthy(); 502 | expect(gray).toBeTruthy(); 503 | expect(presetPrimaryColors).toBeTruthy(); 504 | expect(presetPalettes).toBeTruthy(); 505 | expect(grayDark).toBeTruthy(); 506 | expect(presetDarkPalettes).toBeTruthy(); 507 | }); 508 | }); 509 | -------------------------------------------------------------------------------- /tests/__snapshots__/presets.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`presets 1`] = ` 4 | Object { 5 | "blue": Array [ 6 | "#e6f4ff", 7 | "#bae0ff", 8 | "#91caff", 9 | "#69b1ff", 10 | "#4096ff", 11 | "#1677ff", 12 | "#0958d9", 13 | "#003eb3", 14 | "#002c8c", 15 | "#001d66", 16 | ], 17 | "blueDark": Array [ 18 | "#111a2c", 19 | "#112545", 20 | "#15325b", 21 | "#15417e", 22 | "#1554ad", 23 | "#1668dc", 24 | "#3c89e8", 25 | "#65a9f3", 26 | "#8dc5f8", 27 | "#b7dcfa", 28 | ], 29 | "cyan": Array [ 30 | "#e6fffb", 31 | "#b5f5ec", 32 | "#87e8de", 33 | "#5cdbd3", 34 | "#36cfc9", 35 | "#13c2c2", 36 | "#08979c", 37 | "#006d75", 38 | "#00474f", 39 | "#002329", 40 | ], 41 | "cyanDark": Array [ 42 | "#112123", 43 | "#113536", 44 | "#144848", 45 | "#146262", 46 | "#138585", 47 | "#13a8a8", 48 | "#33bcb7", 49 | "#58d1c9", 50 | "#84e2d8", 51 | "#b2f1e8", 52 | ], 53 | "geekblue": Array [ 54 | "#f0f5ff", 55 | "#d6e4ff", 56 | "#adc6ff", 57 | "#85a5ff", 58 | "#597ef7", 59 | "#2f54eb", 60 | "#1d39c4", 61 | "#10239e", 62 | "#061178", 63 | "#030852", 64 | ], 65 | "geekblueDark": Array [ 66 | "#131629", 67 | "#161d40", 68 | "#1c2755", 69 | "#203175", 70 | "#263ea0", 71 | "#2b4acb", 72 | "#5273e0", 73 | "#7f9ef3", 74 | "#a8c1f8", 75 | "#d2e0fa", 76 | ], 77 | "gold": Array [ 78 | "#fffbe6", 79 | "#fff1b8", 80 | "#ffe58f", 81 | "#ffd666", 82 | "#ffc53d", 83 | "#faad14", 84 | "#d48806", 85 | "#ad6800", 86 | "#874d00", 87 | "#613400", 88 | ], 89 | "goldDark": Array [ 90 | "#2b2111", 91 | "#443111", 92 | "#594214", 93 | "#7c5914", 94 | "#aa7714", 95 | "#d89614", 96 | "#e8b339", 97 | "#f3cc62", 98 | "#f8df8b", 99 | "#faedb5", 100 | ], 101 | "gray": Array [ 102 | "#a6a6a6", 103 | "#999999", 104 | "#8c8c8c", 105 | "#808080", 106 | "#737373", 107 | "#666666", 108 | "#404040", 109 | "#1a1a1a", 110 | "#000000", 111 | "#000000", 112 | ], 113 | "green": Array [ 114 | "#f6ffed", 115 | "#d9f7be", 116 | "#b7eb8f", 117 | "#95de64", 118 | "#73d13d", 119 | "#52c41a", 120 | "#389e0d", 121 | "#237804", 122 | "#135200", 123 | "#092b00", 124 | ], 125 | "greenDark": Array [ 126 | "#162312", 127 | "#1d3712", 128 | "#274916", 129 | "#306317", 130 | "#3c8618", 131 | "#49aa19", 132 | "#6abe39", 133 | "#8fd460", 134 | "#b2e58b", 135 | "#d5f2bb", 136 | ], 137 | "grey": Array [ 138 | "#a6a6a6", 139 | "#999999", 140 | "#8c8c8c", 141 | "#808080", 142 | "#737373", 143 | "#666666", 144 | "#404040", 145 | "#1a1a1a", 146 | "#000000", 147 | "#000000", 148 | ], 149 | "greyDark": Array [ 150 | "#151515", 151 | "#1f1f1f", 152 | "#2d2d2d", 153 | "#393939", 154 | "#494949", 155 | "#5a5a5a", 156 | "#6a6a6a", 157 | "#7b7b7b", 158 | "#888888", 159 | "#969696", 160 | ], 161 | "lime": Array [ 162 | "#fcffe6", 163 | "#f4ffb8", 164 | "#eaff8f", 165 | "#d3f261", 166 | "#bae637", 167 | "#a0d911", 168 | "#7cb305", 169 | "#5b8c00", 170 | "#3f6600", 171 | "#254000", 172 | ], 173 | "limeDark": Array [ 174 | "#1f2611", 175 | "#2e3c10", 176 | "#3e4f13", 177 | "#536d13", 178 | "#6f9412", 179 | "#8bbb11", 180 | "#a9d134", 181 | "#c9e75d", 182 | "#e4f88b", 183 | "#f0fab5", 184 | ], 185 | "magenta": Array [ 186 | "#fff0f6", 187 | "#ffd6e7", 188 | "#ffadd2", 189 | "#ff85c0", 190 | "#f759ab", 191 | "#eb2f96", 192 | "#c41d7f", 193 | "#9e1068", 194 | "#780650", 195 | "#520339", 196 | ], 197 | "magentaDark": Array [ 198 | "#291321", 199 | "#40162f", 200 | "#551c3b", 201 | "#75204f", 202 | "#a02669", 203 | "#cb2b83", 204 | "#e0529c", 205 | "#f37fb7", 206 | "#f8a8cc", 207 | "#fad2e3", 208 | ], 209 | "orange": Array [ 210 | "#fff7e6", 211 | "#ffe7ba", 212 | "#ffd591", 213 | "#ffc069", 214 | "#ffa940", 215 | "#fa8c16", 216 | "#d46b08", 217 | "#ad4e00", 218 | "#873800", 219 | "#612500", 220 | ], 221 | "orangeDark": Array [ 222 | "#2b1d11", 223 | "#442a11", 224 | "#593815", 225 | "#7c4a15", 226 | "#aa6215", 227 | "#d87a16", 228 | "#e89a3c", 229 | "#f3b765", 230 | "#f8cf8d", 231 | "#fae3b7", 232 | ], 233 | "presetDarkPalettes": Object { 234 | "blue": Array [ 235 | "#111a2c", 236 | "#112545", 237 | "#15325b", 238 | "#15417e", 239 | "#1554ad", 240 | "#1668dc", 241 | "#3c89e8", 242 | "#65a9f3", 243 | "#8dc5f8", 244 | "#b7dcfa", 245 | ], 246 | "cyan": Array [ 247 | "#112123", 248 | "#113536", 249 | "#144848", 250 | "#146262", 251 | "#138585", 252 | "#13a8a8", 253 | "#33bcb7", 254 | "#58d1c9", 255 | "#84e2d8", 256 | "#b2f1e8", 257 | ], 258 | "geekblue": Array [ 259 | "#131629", 260 | "#161d40", 261 | "#1c2755", 262 | "#203175", 263 | "#263ea0", 264 | "#2b4acb", 265 | "#5273e0", 266 | "#7f9ef3", 267 | "#a8c1f8", 268 | "#d2e0fa", 269 | ], 270 | "gold": Array [ 271 | "#2b2111", 272 | "#443111", 273 | "#594214", 274 | "#7c5914", 275 | "#aa7714", 276 | "#d89614", 277 | "#e8b339", 278 | "#f3cc62", 279 | "#f8df8b", 280 | "#faedb5", 281 | ], 282 | "green": Array [ 283 | "#162312", 284 | "#1d3712", 285 | "#274916", 286 | "#306317", 287 | "#3c8618", 288 | "#49aa19", 289 | "#6abe39", 290 | "#8fd460", 291 | "#b2e58b", 292 | "#d5f2bb", 293 | ], 294 | "grey": Array [ 295 | "#151515", 296 | "#1f1f1f", 297 | "#2d2d2d", 298 | "#393939", 299 | "#494949", 300 | "#5a5a5a", 301 | "#6a6a6a", 302 | "#7b7b7b", 303 | "#888888", 304 | "#969696", 305 | ], 306 | "lime": Array [ 307 | "#1f2611", 308 | "#2e3c10", 309 | "#3e4f13", 310 | "#536d13", 311 | "#6f9412", 312 | "#8bbb11", 313 | "#a9d134", 314 | "#c9e75d", 315 | "#e4f88b", 316 | "#f0fab5", 317 | ], 318 | "magenta": Array [ 319 | "#291321", 320 | "#40162f", 321 | "#551c3b", 322 | "#75204f", 323 | "#a02669", 324 | "#cb2b83", 325 | "#e0529c", 326 | "#f37fb7", 327 | "#f8a8cc", 328 | "#fad2e3", 329 | ], 330 | "orange": Array [ 331 | "#2b1d11", 332 | "#442a11", 333 | "#593815", 334 | "#7c4a15", 335 | "#aa6215", 336 | "#d87a16", 337 | "#e89a3c", 338 | "#f3b765", 339 | "#f8cf8d", 340 | "#fae3b7", 341 | ], 342 | "purple": Array [ 343 | "#1a1325", 344 | "#24163a", 345 | "#301c4d", 346 | "#3e2069", 347 | "#51258f", 348 | "#642ab5", 349 | "#854eca", 350 | "#ab7ae0", 351 | "#cda8f0", 352 | "#ebd7fa", 353 | ], 354 | "red": Array [ 355 | "#2a1215", 356 | "#431418", 357 | "#58181c", 358 | "#791a1f", 359 | "#a61d24", 360 | "#d32029", 361 | "#e84749", 362 | "#f37370", 363 | "#f89f9a", 364 | "#fac8c3", 365 | ], 366 | "volcano": Array [ 367 | "#2b1611", 368 | "#441d12", 369 | "#592716", 370 | "#7c3118", 371 | "#aa3e19", 372 | "#d84a1b", 373 | "#e87040", 374 | "#f3956a", 375 | "#f8b692", 376 | "#fad4bc", 377 | ], 378 | "yellow": Array [ 379 | "#2b2611", 380 | "#443b11", 381 | "#595014", 382 | "#7c6e14", 383 | "#aa9514", 384 | "#d8bd14", 385 | "#e8d639", 386 | "#f3ea62", 387 | "#f8f48b", 388 | "#fafab5", 389 | ], 390 | }, 391 | "presetPalettes": Object { 392 | "blue": Array [ 393 | "#e6f4ff", 394 | "#bae0ff", 395 | "#91caff", 396 | "#69b1ff", 397 | "#4096ff", 398 | "#1677ff", 399 | "#0958d9", 400 | "#003eb3", 401 | "#002c8c", 402 | "#001d66", 403 | ], 404 | "cyan": Array [ 405 | "#e6fffb", 406 | "#b5f5ec", 407 | "#87e8de", 408 | "#5cdbd3", 409 | "#36cfc9", 410 | "#13c2c2", 411 | "#08979c", 412 | "#006d75", 413 | "#00474f", 414 | "#002329", 415 | ], 416 | "geekblue": Array [ 417 | "#f0f5ff", 418 | "#d6e4ff", 419 | "#adc6ff", 420 | "#85a5ff", 421 | "#597ef7", 422 | "#2f54eb", 423 | "#1d39c4", 424 | "#10239e", 425 | "#061178", 426 | "#030852", 427 | ], 428 | "gold": Array [ 429 | "#fffbe6", 430 | "#fff1b8", 431 | "#ffe58f", 432 | "#ffd666", 433 | "#ffc53d", 434 | "#faad14", 435 | "#d48806", 436 | "#ad6800", 437 | "#874d00", 438 | "#613400", 439 | ], 440 | "green": Array [ 441 | "#f6ffed", 442 | "#d9f7be", 443 | "#b7eb8f", 444 | "#95de64", 445 | "#73d13d", 446 | "#52c41a", 447 | "#389e0d", 448 | "#237804", 449 | "#135200", 450 | "#092b00", 451 | ], 452 | "grey": Array [ 453 | "#a6a6a6", 454 | "#999999", 455 | "#8c8c8c", 456 | "#808080", 457 | "#737373", 458 | "#666666", 459 | "#404040", 460 | "#1a1a1a", 461 | "#000000", 462 | "#000000", 463 | ], 464 | "lime": Array [ 465 | "#fcffe6", 466 | "#f4ffb8", 467 | "#eaff8f", 468 | "#d3f261", 469 | "#bae637", 470 | "#a0d911", 471 | "#7cb305", 472 | "#5b8c00", 473 | "#3f6600", 474 | "#254000", 475 | ], 476 | "magenta": Array [ 477 | "#fff0f6", 478 | "#ffd6e7", 479 | "#ffadd2", 480 | "#ff85c0", 481 | "#f759ab", 482 | "#eb2f96", 483 | "#c41d7f", 484 | "#9e1068", 485 | "#780650", 486 | "#520339", 487 | ], 488 | "orange": Array [ 489 | "#fff7e6", 490 | "#ffe7ba", 491 | "#ffd591", 492 | "#ffc069", 493 | "#ffa940", 494 | "#fa8c16", 495 | "#d46b08", 496 | "#ad4e00", 497 | "#873800", 498 | "#612500", 499 | ], 500 | "purple": Array [ 501 | "#f9f0ff", 502 | "#efdbff", 503 | "#d3adf7", 504 | "#b37feb", 505 | "#9254de", 506 | "#722ed1", 507 | "#531dab", 508 | "#391085", 509 | "#22075e", 510 | "#120338", 511 | ], 512 | "red": Array [ 513 | "#fff1f0", 514 | "#ffccc7", 515 | "#ffa39e", 516 | "#ff7875", 517 | "#ff4d4f", 518 | "#f5222d", 519 | "#cf1322", 520 | "#a8071a", 521 | "#820014", 522 | "#5c0011", 523 | ], 524 | "volcano": Array [ 525 | "#fff2e8", 526 | "#ffd8bf", 527 | "#ffbb96", 528 | "#ff9c6e", 529 | "#ff7a45", 530 | "#fa541c", 531 | "#d4380d", 532 | "#ad2102", 533 | "#871400", 534 | "#610b00", 535 | ], 536 | "yellow": Array [ 537 | "#feffe6", 538 | "#ffffb8", 539 | "#fffb8f", 540 | "#fff566", 541 | "#ffec3d", 542 | "#fadb14", 543 | "#d4b106", 544 | "#ad8b00", 545 | "#876800", 546 | "#614700", 547 | ], 548 | }, 549 | "presetPrimaryColors": Object { 550 | "blue": "#1677FF", 551 | "cyan": "#13C2C2", 552 | "geekblue": "#2F54EB", 553 | "gold": "#FAAD14", 554 | "green": "#52C41A", 555 | "grey": "#666666", 556 | "lime": "#A0D911", 557 | "magenta": "#EB2F96", 558 | "orange": "#FA8C16", 559 | "purple": "#722ED1", 560 | "red": "#F5222D", 561 | "volcano": "#FA541C", 562 | "yellow": "#FADB14", 563 | }, 564 | "purple": Array [ 565 | "#f9f0ff", 566 | "#efdbff", 567 | "#d3adf7", 568 | "#b37feb", 569 | "#9254de", 570 | "#722ed1", 571 | "#531dab", 572 | "#391085", 573 | "#22075e", 574 | "#120338", 575 | ], 576 | "purpleDark": Array [ 577 | "#1a1325", 578 | "#24163a", 579 | "#301c4d", 580 | "#3e2069", 581 | "#51258f", 582 | "#642ab5", 583 | "#854eca", 584 | "#ab7ae0", 585 | "#cda8f0", 586 | "#ebd7fa", 587 | ], 588 | "red": Array [ 589 | "#fff1f0", 590 | "#ffccc7", 591 | "#ffa39e", 592 | "#ff7875", 593 | "#ff4d4f", 594 | "#f5222d", 595 | "#cf1322", 596 | "#a8071a", 597 | "#820014", 598 | "#5c0011", 599 | ], 600 | "redDark": Array [ 601 | "#2a1215", 602 | "#431418", 603 | "#58181c", 604 | "#791a1f", 605 | "#a61d24", 606 | "#d32029", 607 | "#e84749", 608 | "#f37370", 609 | "#f89f9a", 610 | "#fac8c3", 611 | ], 612 | "volcano": Array [ 613 | "#fff2e8", 614 | "#ffd8bf", 615 | "#ffbb96", 616 | "#ff9c6e", 617 | "#ff7a45", 618 | "#fa541c", 619 | "#d4380d", 620 | "#ad2102", 621 | "#871400", 622 | "#610b00", 623 | ], 624 | "volcanoDark": Array [ 625 | "#2b1611", 626 | "#441d12", 627 | "#592716", 628 | "#7c3118", 629 | "#aa3e19", 630 | "#d84a1b", 631 | "#e87040", 632 | "#f3956a", 633 | "#f8b692", 634 | "#fad4bc", 635 | ], 636 | "yellow": Array [ 637 | "#feffe6", 638 | "#ffffb8", 639 | "#fffb8f", 640 | "#fff566", 641 | "#ffec3d", 642 | "#fadb14", 643 | "#d4b106", 644 | "#ad8b00", 645 | "#876800", 646 | "#614700", 647 | ], 648 | "yellowDark": Array [ 649 | "#2b2611", 650 | "#443b11", 651 | "#595014", 652 | "#7c6e14", 653 | "#aa9514", 654 | "#d8bd14", 655 | "#e8d639", 656 | "#f3ea62", 657 | "#f8f48b", 658 | "#fafab5", 659 | ], 660 | } 661 | `; 662 | --------------------------------------------------------------------------------