From a99fb382da9959f7f03b938c982a8a7810e24540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E6=96=87=E5=8D=8E?= <531362022@qq.com> Date: Tue, 27 Aug 2019 23:21:42 +0800 Subject: [PATCH] feat: Add color props --- README.md | 32 +++++++++++++++++++-- package.json | 13 ++++++--- src/libs/generateComponent.ts | 39 +++++++++++++++++++++----- src/libs/replace.ts | 12 +++++--- src/templates/Icon.d.ts.template | 11 ++++++++ src/templates/Icon.jsx.template | 8 +----- src/templates/Icon.tsx.template | 3 +- src/templates/SingleIcon.d.ts.template | 10 +++++++ src/templates/SingleIcon.jsx.template | 7 +---- src/templates/SingleIcon.tsx.template | 3 +- yarn.lock | 2 +- 11 files changed, 106 insertions(+), 34 deletions(-) create mode 100644 src/templates/Icon.d.ts.template create mode 100644 src/templates/SingleIcon.d.ts.template diff --git a/README.md b/README.md index 1e441dc..b79c90b 100644 --- a/README.md +++ b/README.md @@ -64,11 +64,13 @@ cd ios && pod install ### use_typescript 如果您的项目使用Typescript编写,请设置为true。这个选项将决定生成的图标组件是`.tsx`还是`.jsx`后缀。 +当该值为false时,我们会为您的图标生成`.jsx`和`.d.ts`两个文件,以便您能享受到最好的开发体验。 + ### generate_mode 生成组件的方式: -##### all-in-one +##### 1、all-in-one 只生成一个`` 组件,里面包含了所有图标信息。所以这个组件会比较大。 -##### depends-on +##### 2、depends-on 每个图标都会生成一个组件``。这种模式也会生成一个`Icon`组件,但和all-in-one不同的是,这个Icon组件总是import其他的图标组件,它相当于一个门面。 ### safe_dir @@ -91,7 +93,9 @@ cd ios && pod install 生成后查看您设置的保存目录中是否含有所有的图标 # Step 5 -使用这些图标。现在我们提供了两种引入方式供您选择: +使用这些图标。 +
+现在我们提供了两种引入方式供您选择: 1、使用汇总`Icon`组件: ```typescript jsx @@ -123,6 +127,28 @@ export const App = () => { }; ``` +# 使用 +### 图标尺寸 +根据配置`default_icon_size`,每个图标都会有一个默认的尺寸,你可以随时覆盖。 +```typescript jsx + +``` +### 图标单色 +单色图标,如果不指定颜色值,图标将渲染原本的颜色。如果你想设置为其他的颜色,那么设置一个你想要的颜色即可 +```typescript jsx + + + +``` +### 图标多色彩 +多色彩的图标,如果不指定颜色值,图标将渲染原本的多色彩。如果你想设置为其他的颜色,那么设置一组你想要的颜色即可 +```typescript jsx + +``` +颜色组的数量以及排序,需要根据当前图标的信息来确定。您需要进入图标组件中查看并得出结论。 + +**注意:如果color是字符串而不是数组,那么即使是多色彩图标,也会变成单色图标。** + # 更新图标 当您在iconfont.cn中的图标有变更时,只需更改配置`symbol_url`,然后再次执行`Step 4`即可生成最新的图标组件 ```bash diff --git a/package.json b/package.json index 1ab1187..e1ee7bf 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,15 @@ { "name": "react-native-iconfont-cli", - "version": "1.0.0", + "version": "1.1.0", "main": "index.js", - "keywords": ["iconfont", "react-native", "react-native-iconfont", "icon", "icons", "iconfont.cn"], + "keywords": [ + "iconfont", + "react-native", + "react-native-iconfont", + "icon", + "icons", + "iconfont.cn" + ], "repository": "git@github.com:fwh1990/react-native-iconfont-cli.git", "author": "范文华 <531362022@qq.com>", "license": "MIT", @@ -21,7 +28,6 @@ "lodash": "^4.17.15", "minimist": "^1.2.0", "mkdirp": "^0.5.1", - "prop-types": "^15.7.2", "tslib": "^1.10.0", "xml2js": "^0.4.19" }, @@ -31,7 +37,6 @@ "@types/minimist": "^1.2.0", "@types/mkdirp": "^0.5.2", "@types/node": "^12.7.2", - "@types/prop-types": "^15.7.1", "@types/react": "^16.9.2", "@types/xml2js": "^0.4.4", "react": "^16.9.0", diff --git a/src/libs/generateComponent.ts b/src/libs/generateComponent.ts index c698bb0..a6b4df6 100644 --- a/src/libs/generateComponent.ts +++ b/src/libs/generateComponent.ts @@ -46,7 +46,6 @@ export const generateComponent = (data: XmlData) => { : iconId; const componentName = upperFirst(camelCase(iconId)); - names.push(iconIdAfterTrim); for (const domName of Object.keys(item)) { @@ -71,7 +70,7 @@ export const generateComponent = (data: XmlData) => { } imports.push(componentName); - cases += `${whitespace(6)}return <${componentName} size={size} />;\n`; + cases += `${whitespace(6)}return <${componentName} size={size} color={color} />;\n`; singleFile = getTemplate('SingleIcon' + extension); singleFile = replaceSize(singleFile, config.default_font_size); @@ -87,6 +86,13 @@ export const generateComponent = (data: XmlData) => { fs.writeFileSync(path.join(saveDir, componentName + extension), singleFile); + if (!config.use_typescript) { + let typeDefinitionFile = getTemplate('SingleIcon.d.ts'); + + typeDefinitionFile = replaceComponentName(typeDefinitionFile, componentName); + fs.writeFileSync(path.join(saveDir, componentName + '.d.ts'), typeDefinitionFile); + } + console.log(`${colors.green('√')} Generated icon "${colors.yellow(iconId)}"`); }); @@ -101,6 +107,11 @@ export const generateComponent = (data: XmlData) => { iconFile = replaceNames(iconFile, names); } else { iconFile = replaceNamesArray(iconFile, names); + + let typeDefinitionFile = getTemplate('Icon.d.ts'); + + typeDefinitionFile = replaceNames(typeDefinitionFile, names); + fs.writeFileSync(path.join(saveDir, 'Icon.d.ts'), typeDefinitionFile); } if (config.generate_mode === GENERATE_MODE.allInOne) { @@ -120,15 +131,24 @@ const generateCase = (data: XmlData['svg']['symbol'][number], baseIdent: number) for (const domName of Object.keys(data)) { let realDomName = DOM_MAP[domName]; - if (!realDomName) { + if (domName === '$') { continue; } + if (!realDomName) { + console.error(colors.red(`Unable to transform dom "${domName}"`)); + process.exit(1); + } + + const counter = { + colorIndex: 0, + }; + if (data[domName].$) { - template += `${whitespace(baseIdent + 2)}<${realDomName} ${addAttribute(data[domName])} />\n`; + template += `${whitespace(baseIdent + 2)}<${realDomName}${addAttribute(data[domName], counter)} />\n`; } else if (Array.isArray(data[domName])) { data[domName].forEach((sub) => { - template += `${whitespace(baseIdent + 2)}<${realDomName} ${addAttribute(sub)} />\n`; + template += `${whitespace(baseIdent + 2)}<${realDomName}${addAttribute(sub, counter)} />\n`; }); } } @@ -138,12 +158,17 @@ const generateCase = (data: XmlData['svg']['symbol'][number], baseIdent: number) return template; }; -const addAttribute = (sub: XmlData['svg']['symbol'][number]['path'][number]) => { +const addAttribute = (sub: XmlData['svg']['symbol'][number]['path'][number], counter: { colorIndex: number }) => { let template = ''; if (sub && sub.$) { for (const attributeName of Object.keys(sub.$)) { - template += ` ${attributeName}="${sub.$[attributeName]}"`; + if (attributeName === 'fill') { + template += ` ${attributeName}={color ? typeof color === 'string' && color || color[${counter.colorIndex}] || '${sub.$[attributeName]}' : '${sub.$[attributeName]}'}`; + counter.colorIndex += 1; + } else { + template += ` ${attributeName}="${sub.$[attributeName]}"`; + } } } diff --git a/src/libs/replace.ts b/src/libs/replace.ts index 8d8501f..7c8d3db 100644 --- a/src/libs/replace.ts +++ b/src/libs/replace.ts @@ -1,3 +1,5 @@ +import { GENERATE_MODE } from './generateMode'; + export const replaceSize = (content: string, size: number) => { return content.replace(/#size#/g, String(size)); }; @@ -45,13 +47,15 @@ export const replaceImports = (content: string, imports: string[]) => { export const replaceToOneComments = (content: string) => { return content.replace(/#comments#/g, '// If you don\'t like lots of icon files in your project,\n' + - '// try to set generate_mode to `all-in-one` in root file `iconfont.json`.\n' + - '// And then regenerate icons by using cli command.'); + `// try to set generate_mode to "${GENERATE_MODE.allInOne}" in root file "iconfont.json".\n` + + '// And then regenerate icons by using cli command.' + ); }; export const replaceToDependsComments = (content: string) => { return content.replace(/#comments#/g, '// If you don\'t want to make all icons in one file,\n' + - '// try to set generate_mode to `depends-on` in root file `iconfont.json`.\n' + - '// And then regenerate icons by using cli command.'); + `// try to set generate_mode to "${GENERATE_MODE.dependsOn}" in root file "iconfont.json".\n` + + '// And then regenerate icons by using cli command.' + ); }; diff --git a/src/templates/Icon.d.ts.template b/src/templates/Icon.d.ts.template new file mode 100644 index 0000000..38af089 --- /dev/null +++ b/src/templates/Icon.d.ts.template @@ -0,0 +1,11 @@ +import { FunctionComponent } from 'react'; + +interface Props { + size?: number; + color?: string | string[]; + name: '#names#'; +} + +declare const Icon: FunctionComponent; + +export = Icon; diff --git a/src/templates/Icon.jsx.template b/src/templates/Icon.jsx.template index 2782ea9..5184e80 100644 --- a/src/templates/Icon.jsx.template +++ b/src/templates/Icon.jsx.template @@ -2,12 +2,11 @@ /* eslint-disable */ import React from 'react'; -import { number, oneOf } from 'prop-types'; #svgComponents# #imports# #comments# -const Icon = ({ size, name }) => { +const Icon = ({ color, name, size }) => { switch (name) { #cases# } @@ -15,11 +14,6 @@ const Icon = ({ size, name }) => { return null; }; -Icon.propTypes = { - size: number, - name: oneOf(#namesArray#), -}; - Icon.defaultProps = { size: #size#, }; diff --git a/src/templates/Icon.tsx.template b/src/templates/Icon.tsx.template index ceb59fe..e4a0659 100644 --- a/src/templates/Icon.tsx.template +++ b/src/templates/Icon.tsx.template @@ -7,11 +7,12 @@ import React, { FunctionComponent } from 'react'; interface Props { size?: number; + color?: string | string[]; name: '#names#'; } #comments# -const Icon: FunctionComponent = ({ size, name }) => { +const Icon: FunctionComponent = ({ color, name, size }) => { switch (name) { #cases# } diff --git a/src/templates/SingleIcon.d.ts.template b/src/templates/SingleIcon.d.ts.template new file mode 100644 index 0000000..b3d2be6 --- /dev/null +++ b/src/templates/SingleIcon.d.ts.template @@ -0,0 +1,10 @@ +import { FunctionComponent } from 'react'; + +interface Props { + size?: number; + color?: string | string[]; +} + +declare const #componentName#: FunctionComponent; + +export = #componentName#; diff --git a/src/templates/SingleIcon.jsx.template b/src/templates/SingleIcon.jsx.template index 43766ae..b8aba3b 100644 --- a/src/templates/SingleIcon.jsx.template +++ b/src/templates/SingleIcon.jsx.template @@ -2,18 +2,13 @@ /* eslint-disable */ import React from 'react'; -import { number } from 'prop-types'; #svgComponents# #comments# -const #componentName# = ({ size }) => { +const #componentName# = ({ size, color }) => { return (#iconContent# ); }; -#componentName#.propTypes = { - size: number, -}; - #componentName#.defaultProps = { size: #size#, }; diff --git a/src/templates/SingleIcon.tsx.template b/src/templates/SingleIcon.tsx.template index 5023b17..af6b2b7 100644 --- a/src/templates/SingleIcon.tsx.template +++ b/src/templates/SingleIcon.tsx.template @@ -6,10 +6,11 @@ import React, { FunctionComponent } from 'react'; interface Props { size?: number; + color?: string | string[]; } #comments# -const #componentName#: FunctionComponent = ({ size }) => { +const #componentName#: FunctionComponent = ({ size, color }) => { return (#iconContent# ); }; diff --git a/yarn.lock b/yarn.lock index 642cd09..5ccc8cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -866,7 +866,7 @@ resolved "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44" integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== -"@types/prop-types@*", "@types/prop-types@^15.7.1": +"@types/prop-types@*": version "15.7.1" resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6" integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==