From 4da67b91806f0f04c4d82a073082c730fbda325f Mon Sep 17 00:00:00 2001 From: zhangyu Date: Mon, 29 Jun 2020 16:33:17 +0800 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=20svg=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locals/README.md | 3 ++ locals/word.svg | 33 +++++++++++++++++++ package.json | 2 +- scripts/config/demo-js.json | 3 +- scripts/config/demo-ts.json | 3 +- snapshots/demo-js/IconWord.d.ts | 15 +++++++++ snapshots/demo-js/IconWord.js | 49 +++++++++++++++++++++++++++++ snapshots/demo-js/index.d.ts | 2 +- snapshots/demo-js/index.js | 3 ++ snapshots/demo-ts/IconWord.tsx | 56 +++++++++++++++++++++++++++++++++ snapshots/demo-ts/index.tsx | 5 ++- src/commands/createIcon.ts | 21 +++++++------ src/libs/generateComponent.ts | 40 +++++++++++++++++++++-- src/libs/getConfig.ts | 1 + src/libs/parseLocalSvg.tsx | 33 +++++++++++++++++++ src/libs/replace.ts | 7 +++++ 16 files changed, 259 insertions(+), 17 deletions(-) create mode 100644 locals/README.md create mode 100644 locals/word.svg create mode 100644 snapshots/demo-js/IconWord.d.ts create mode 100644 snapshots/demo-js/IconWord.js create mode 100644 snapshots/demo-ts/IconWord.tsx create mode 100644 src/libs/parseLocalSvg.tsx diff --git a/locals/README.md b/locals/README.md new file mode 100644 index 0000000..58f53f8 --- /dev/null +++ b/locals/README.md @@ -0,0 +1,3 @@ +## 验证获取正则是否正常 + +word.svg 文件是从 ui 图中直接获取的,且他是渐变色的 diff --git a/locals/word.svg b/locals/word.svg new file mode 100644 index 0000000..d27c2a5 --- /dev/null +++ b/locals/word.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package.json b/package.json index b049bf9..6a6bd7a 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-svg": "*" + "react-native-svg": ">=9.7.0" }, "dependencies": { "colors": "^1.3.3", diff --git a/scripts/config/demo-js.json b/scripts/config/demo-js.json index 9f7158f..970651a 100644 --- a/scripts/config/demo-js.json +++ b/scripts/config/demo-js.json @@ -3,5 +3,6 @@ "use_typescript": false, "save_dir": "./snapshots/demo-js", "trim_icon_prefix": "icon", - "default_icon_size": 18 + "default_icon_size": 18, + "local_dir": "./locals" } diff --git a/scripts/config/demo-ts.json b/scripts/config/demo-ts.json index f01fd1c..8571b6f 100644 --- a/scripts/config/demo-ts.json +++ b/scripts/config/demo-ts.json @@ -3,5 +3,6 @@ "use_typescript": true, "save_dir": "./snapshots/demo-ts", "trim_icon_prefix": "icon", - "default_icon_size": 20 + "default_icon_size": 20, + "local_dir": "./locals" } diff --git a/snapshots/demo-js/IconWord.d.ts b/snapshots/demo-js/IconWord.d.ts new file mode 100644 index 0000000..c1a43a7 --- /dev/null +++ b/snapshots/demo-js/IconWord.d.ts @@ -0,0 +1,15 @@ +/* eslint-disable */ + +import { FunctionComponent } from 'react'; +// Don't forget to install package: @types/react-native +import { ViewProps } from 'react-native'; +import { GProps } from 'react-native-svg'; + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +declare const IconWord: FunctionComponent; + +export default IconWord; diff --git a/snapshots/demo-js/IconWord.js b/snapshots/demo-js/IconWord.js new file mode 100644 index 0000000..62d3c0c --- /dev/null +++ b/snapshots/demo-js/IconWord.js @@ -0,0 +1,49 @@ +/* eslint-disable */ + +import React from 'react'; +import { GProps, SvgXml } from 'react-native-svg'; + + +const IconWord = ({ size, color, ...rest }) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconWord.defaultProps = { + size: 18, +}; + +export default React.memo ? React.memo(IconWord) : IconWord; diff --git a/snapshots/demo-js/index.d.ts b/snapshots/demo-js/index.d.ts index 7c143a3..02e5194 100644 --- a/snapshots/demo-js/index.d.ts +++ b/snapshots/demo-js/index.d.ts @@ -6,7 +6,7 @@ import { ViewProps } from 'react-native'; import { GProps } from 'react-native-svg'; interface Props extends GProps, ViewProps { - name: 'alipay' | 'user' | 'setup'; + name: 'alipay' | 'user' | 'setup' | 'word'; size?: number; color?: string | string[]; } diff --git a/snapshots/demo-js/index.js b/snapshots/demo-js/index.js index 0ba6b01..0c0b491 100644 --- a/snapshots/demo-js/index.js +++ b/snapshots/demo-js/index.js @@ -5,6 +5,7 @@ import React from 'react'; import IconAlipay from './IconAlipay'; import IconUser from './IconUser'; import IconSetup from './IconSetup'; +import IconWord from './IconWord'; const IconFont = ({ name, ...rest }) => { switch (name) { @@ -14,6 +15,8 @@ const IconFont = ({ name, ...rest }) => { return ; case 'setup': return ; + case 'word': + return ; } return null; diff --git a/snapshots/demo-ts/IconWord.tsx b/snapshots/demo-ts/IconWord.tsx new file mode 100644 index 0000000..13d85b8 --- /dev/null +++ b/snapshots/demo-ts/IconWord.tsx @@ -0,0 +1,56 @@ +/* tslint:disable */ +/* eslint-disable */ + +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; +import { GProps, SvgXml } from 'react-native-svg'; + + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +const IconWord: FunctionComponent = ({ size, color, ...rest }) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconWord.defaultProps = { + size: 20, +}; + +export default React.memo ? React.memo(IconWord) : IconWord; diff --git a/snapshots/demo-ts/index.tsx b/snapshots/demo-ts/index.tsx index 7e42fa9..c84da79 100644 --- a/snapshots/demo-ts/index.tsx +++ b/snapshots/demo-ts/index.tsx @@ -7,8 +7,9 @@ import { GProps } from 'react-native-svg'; import IconAlipay from './IconAlipay'; import IconUser from './IconUser'; import IconSetup from './IconSetup'; +import IconWord from './IconWord'; -export type IconNames = 'alipay' | 'user' | 'setup'; +export type IconNames = 'alipay' | 'user' | 'setup' | 'word'; interface Props extends GProps, ViewProps { name: IconNames; @@ -24,6 +25,8 @@ const IconFont: FunctionComponent = ({ name, ...rest }) => { return ; case 'setup': return ; + case 'word': + return ; } return null; diff --git a/src/commands/createIcon.ts b/src/commands/createIcon.ts index c77db2d..ad74d54 100644 --- a/src/commands/createIcon.ts +++ b/src/commands/createIcon.ts @@ -1,15 +1,18 @@ #!/usr/bin/env node -import colors from 'colors'; -import { getConfig } from '../libs/getConfig'; -import { fetchXml } from 'iconfont-parser'; -import { generateComponent } from '../libs/generateComponent'; +import colors from 'colors' +import { getConfig } from '../libs/getConfig' +import { fetchXml } from 'iconfont-parser' +import { generateComponent } from '../libs/generateComponent' +import parseLocalSvg from '../libs/parseLocalSvg' -const config = getConfig(); +const config = getConfig() + +const localSvg = parseLocalSvg(config) fetchXml(config.symbol_url).then((result) => { - generateComponent(result, config); + generateComponent(result, localSvg, config) }).catch((e) => { - console.error(colors.red(e.message || 'Unknown Error')); - process.exit(1); -}); + console.error(colors.red(e.message || 'Unknown Error')) + process.exit(1) +}) diff --git a/src/libs/generateComponent.ts b/src/libs/generateComponent.ts index 565719c..2f06cfb 100644 --- a/src/libs/generateComponent.ts +++ b/src/libs/generateComponent.ts @@ -16,10 +16,11 @@ import { replaceSingleIconContent, replaceSize, replaceSvgComponents, - replaceHelper, -} from './replace'; + replaceHelper, replaceNoHelper, +} from './replace' import { whitespace } from './whitespace'; import { copyTemplate } from './copyTemplate'; +import { ILocalSvg } from '../libs/parseLocalSvg'; const SVG_MAP = { path: 'Path', @@ -27,7 +28,7 @@ const SVG_MAP = { const ATTRIBUTE_FILL_MAP = ['path']; -export const generateComponent = (data: XmlData, config: Config) => { +export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: Config) => { const svgComponents: Set = new Set(); const names: string[] = []; const imports: string[] = []; @@ -100,6 +101,39 @@ export const generateComponent = (data: XmlData, config: Config) => { console.log(`${colors.green('√')} Generated icon "${colors.yellow(iconId)}"`); }); + + localSvg.forEach(({ name, svgStr }, index) => { + let singleFile: string; + + const componentName = upperFirst(config.trim_icon_prefix) + upperFirst(camelCase(name)); + const currentSvgComponents = new Set(['GProps', 'SvgXml']); + + names.push(name); + + cases += `${whitespace(4)}case '${name}':\n`; + + imports.push(componentName); + cases += `${whitespace(6)}return <${componentName} key="L${index + 1}" {...rest} />;\n`; + + singleFile = getTemplate('SingleIcon' + jsxExtension); + singleFile = replaceSize(singleFile, config.default_icon_size); + singleFile = replaceSvgComponents(singleFile, currentSvgComponents); + singleFile = replaceComponentName(singleFile, componentName); + singleFile = replaceSingleIconContent(singleFile, `\n${whitespace(4)}\n`); + singleFile = replaceNoHelper(singleFile); + + fs.writeFileSync(path.join(saveDir, componentName + jsxExtension), 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 local icon "${colors.yellow(name)}"`); + }) + let iconFile = getTemplate('Icon' + jsxExtension); iconFile = replaceSize(iconFile, config.default_icon_size); diff --git a/src/libs/getConfig.ts b/src/libs/getConfig.ts index bb8c3a7..391353d 100644 --- a/src/libs/getConfig.ts +++ b/src/libs/getConfig.ts @@ -9,6 +9,7 @@ export interface Config { save_dir: string; trim_icon_prefix: string; default_icon_size: number; + local_dir?: string } let cacheConfig: Config; diff --git a/src/libs/parseLocalSvg.tsx b/src/libs/parseLocalSvg.tsx new file mode 100644 index 0000000..1d2a606 --- /dev/null +++ b/src/libs/parseLocalSvg.tsx @@ -0,0 +1,33 @@ +import glob from 'glob' +import path from 'path' +import { Config } from '../libs/getConfig' +import * as fs from 'fs' + +export interface ILocalSvg { + svgStr: string + name: string +} + +const parseLocalSvg = ({ local_dir }: Config) => { + if (!local_dir) { + return [] + } + + const localDir = path.resolve(local_dir) + + const localSvg = glob.sync(path.join(localDir, '**/*.svg')) + + return localSvg.reduce((previousValue, currentValue) => { + + let svgStr = fs.readFileSync(currentValue, 'utf-8') + + svgStr = svgStr.substring(svgStr.indexOf('') + 6) + .replace(//g, '') + + previousValue.push({ svgStr, name: path.basename(currentValue, '.svg') }) + + return previousValue + }, []) +} + +export default parseLocalSvg diff --git a/src/libs/replace.ts b/src/libs/replace.ts index bfe03bd..abbbc5d 100644 --- a/src/libs/replace.ts +++ b/src/libs/replace.ts @@ -49,6 +49,13 @@ export const replaceHelper = (content: string) => { ); }; +export const replaceNoHelper = (content: string) => { + return content.replace( + /#helper#/g, + '' + ); +}; + export const replaceNoColor = (content: string) => { return content.replace(/#colorFunc#/g, ''); }; From 574140c4e2b4a1ece7ef429b6ab6b5f916958508 Mon Sep 17 00:00:00 2001 From: zhangyu Date: Mon, 29 Jun 2020 17:04:02 +0800 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=BA=93,?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E4=BE=9B=E8=87=AA=E5=B7=B1=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 166 ++------------------------------------------------- package.json | 12 ++-- yarn.lock | 84 ++++++++++++++++++++++++-- 3 files changed, 92 insertions(+), 170 deletions(-) diff --git a/README.md b/README.md index a55ba4b..47e8f9e 100644 --- a/README.md +++ b/README.md @@ -1,174 +1,18 @@ ## react-native-iconfont-cli -用纯JS把iconfont.cn的图标转换成RN组件,不依赖字体,支持多色彩,支持热更新 -![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/icons.png?raw=true) +fork react-native-iconfont-cli 并且添加了 本地 svg 的支持 -## 痛点 +原库的使用: https://github.com/iconfont-cli/react-native-iconfont-cli -通常地,当我们想在RN里使用iconfont,我们可能会借助`react-native-vector-icons`导入ttf字体文件,或者直接手动下载各个svg文件到本地,然后单个使用。 +添加了本地 svg 支持之后的配置文件: -使用ttf字体有一个弊端,就是每次更新图标,都要相应的更新ttf文件,然后再次打包发布APP。而且ttf不支持多种色彩的图标,导致所有图标都是单色。如果你是借助`react-native-vector-icons`,该库内置了10多套ttf文件,合起来有`2M`左右;你可能用不到它们,但是它们仍然会被打包进你的APP里。 - -下载svg到本地也不方便,因为你需要额外维护一份图标字体,有可能造成线上和本地的图标不一致问题。而且如果你想动态地改变svg的渲染色彩,基本上是不可能的,只能渲染原图的颜色。 - --------- - -为了解决这些问题,我用纯Javascript实现iconfont到React组件的转换操作,**不需要依赖ttf字体文件**,不需要手动下载图标到本地。 - -## 特性 - -1、纯组件,不依赖字体,体积小 -
-2、支持渲染多色彩图标,支持自定义颜色 -
-3、支持热更新 -
-4、自动化生成图标组件,支持es6和typescript两种文件格式 - -## Step 1 -安装插件 -```bash -# Yarn -yarn add react-native-svg -yarn add react-native-iconfont-cli --dev - -# Npm -npm install react-native-svg -npm install react-native-iconfont-cli --save-dev -``` - -# Step 2 -静态链接。请注意您使用的React-Native版本号 -```bash -# RN < 0.60 -react-native link react-native-svg - -# RN >= 0.60 -cd ios && pod install -``` - -# Step 3 -生成配置文件 -```bash -npx iconfont-init ``` -此时项目根目录会生成一个`iconfont.json`的文件,内容如下: -```json { "symbol_url": "请参考README.md,复制官网提供的JS链接", "use_typescript": false, "save_dir": "./src/iconfont", "trim_icon_prefix": "icon", - "default_icon_size": 18 + "default_icon_size": 18, + "local_dir": "./locals" // 唯一不同点 } ``` -### 配置参数说明: -### symbol_url -请直接复制[iconfont](http://iconfont.cn)官网提供的项目链接。请务必看清是`.js`后缀而不是.css后缀。如果你现在还没有创建iconfont的仓库,那么可以填入这个链接去测试:`http://at.alicdn.com/t/font_1373348_ghk94ooopqr.js` - -
- -![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/symbol-url.png?raw=true) - -### use_typescript -如果您的项目使用Typescript编写,请设置为true。这个选项将决定生成的图标组件是`.tsx`还是`.js`后缀。 - -当该值为false时,我们会为您的图标生成`.js`和`.d.ts`两种文件,以便您能享受到最好的开发体验。 - -### save_dir -根据iconfont图标生成的组件存放的位置。每次生成组件之前,该文件夹都会被清空。 - -### trim_icon_prefix -如果你的图标有通用的前缀,而你在使用的时候又不想重复去写,那么可以通过这种配置这个选项把前缀统一去掉。 - -### default_icon_size -我们将为每个生成的图标组件加入默认的字体大小,当然,你也可以通过传入props的方式改变这个size值。 - -# Step 4 -开始生成React-Native标准组件 -```bash -npx iconfont-rn -``` - -生成后查看您设置的保存目录中是否含有所有的图标,你可以参考[snapshots目录](https://github.com/iconfont-cli/react-native-iconfont-cli/tree/master/snapshots)的快照文件,以区分不同模式下的图标结构。 - -# 使用 -
-现在我们提供了两种引入方式供您选择: - -1、使用汇总`Icon`组件: -```typescript jsx -import IconFont from '../src/iconfont'; - -export const App = () => { - return ( - - - - - ); -}; -``` - -2、使用单个图标。这样可以避免没用到的图标也打包进App: - -```typescript jsx -import IconAlipay from '../src/iconfont/IconAlipay'; -import IconWechat from '../src/iconfont/IconWechat'; - -export const App = () => { - return ( - - - - - ); -}; -``` - -### 图标尺寸 -根据配置`default_icon_size`,每个图标都会有一个默认的尺寸,你可以随时覆盖。 -```typescript jsx - -``` -![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/default-color-icon.png?raw=true) -### 图标单色 -单色图标,如果不指定颜色值,图标将渲染原本的颜色。如果你想设置为其他的颜色,那么设置一个你想要的颜色即可。 - -**注意:如果你在props传入的color是字符串而不是数组,那么即使原本是多色彩的图标,也会变成单色图标。** - -```typescript jsx - -``` -![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/one-color-icon.png?raw=true) - -### 图标多色彩 -多色彩的图标,如果不指定颜色值,图标将渲染原本的多色彩。如果你想设置为其他的颜色,那么设置一组你想要的颜色即可 -```typescript jsx - -``` -颜色组的数量以及排序,需要根据当前图标的信息来确定。您需要进入图标组件中查看并得出结论。 - - -![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/multi-color-icon.png?raw=true) - -# 更新图标 -当您在iconfont.cn中的图标有变更时,只需更改配置`symbol_url`,然后再次执行`Step 4`即可生成最新的图标组件 -```bash -# 修改 symbol_url 配置后执行: -npx iconfont-rn -``` - - -# 扩展 -|平台|库| -|----|---| -|小程序|[mini-program-iconfont-cli](https://github.com/iconfont-cli/mini-program-iconfont-cli)| -|Taro|[taro-iconfont-cli](https://github.com/iconfont-cli/taro-iconfont-cli)| -|React H5|[react-iconfont-cli](https://github.com/iconfont-cli/react-iconfont-cli)| -|Flutter|[flutter-iconfont-cli](https://github.com/iconfont-cli/flutter-iconfont-cli)| -|Remax|[remax-iconfont-cli](https://github.com/iconfont-cli/remax-iconfont-cli)| - --------- - -欢迎使用,并给我一些反馈和建议,让这个库做的更好 diff --git a/package.json b/package.json index 6a6bd7a..5b53bf2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "react-native-iconfont-cli", - "version": "2.1.0", + "name": "@grewer/react-native-iconfont-cli", + "version": "2.2.0", "main": "index.js", "keywords": [ "iconfont", @@ -10,8 +10,12 @@ "icons", "iconfont.cn" ], - "repository": "git@github.com:iconfont-cli/react-native-iconfont-cli.git", + "repository": "https://github.com/Grewer/react-native-iconfont-cli", "author": "范文华 <531362022@qq.com>", + "contributors": [{ + "name": "grewer", + "email": "grewer@grewer.cn" + }], "license": "MIT", "bin": { "iconfont": "./commands/help.js", @@ -41,7 +45,7 @@ "@types/react": "^16.9.2", "react": "^16.9.0", "react-native": "^0.60.5", - "react-native-svg": "^9.7.0", + "react-native-svg": "^9.7.1", "ts-node": "^8.3.0", "typescript": "^3.5.3" } diff --git a/yarn.lock b/yarn.lock index 8ef5311..113dcaf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1201,6 +1201,11 @@ big-integer@^1.6.7: resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.44.tgz#4ee9ae5f5839fc11ade338fea216b4513454a539" integrity sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ== +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + bplist-creator@0.0.7: version "0.0.7" resolved "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz#37df1536092824b87c42f957b01344117372ae45" @@ -1577,6 +1582,29 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" +css-select@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@^1.0.0-alpha.37: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + +css-what@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" + integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg== + csstype@^2.2.0: version "2.6.6" resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41" @@ -1701,11 +1729,37 @@ diff@^4.0.1: resolved "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -1730,6 +1784,11 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +entities@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + envinfo@^7.1.0: version "7.3.1" resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" @@ -2836,6 +2895,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + mem@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" @@ -3395,6 +3459,13 @@ npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + nullthrows@^1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" @@ -3798,10 +3869,13 @@ react-is@^16.8.1, react-is@^16.8.4: resolved "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw== -react-native-svg@^9.7.0: - version "9.7.0" - resolved "https://registry.npmjs.org/react-native-svg/-/react-native-svg-9.7.0.tgz#2d0bf1d31d5f1dd061587215b50deb29e626df18" - integrity sha512-8E1snfe2YYbfu6SP5DOoQgRhCdv7D0F4VewUAV+IgAn+IScrA/uuLB8LCodRdO+9U4Rm5dJ4yIwsVhPHRtuBkw== +react-native-svg@^9.7.1: + version "9.13.6" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.6.tgz#5365fba2bc460054b90851e71f2a71006a5d373f" + integrity sha512-vjjuJhEhQCwWjqsgWyGy6/C/LIBM2REDxB40FU1PMhi8T3zQUwUHnA6M15pJKlQG8vaZyA+QnLyIVhjtujRgig== + dependencies: + css-select "^2.0.2" + css-tree "^1.0.0-alpha.37" react-native@^0.60.5: version "0.60.5" @@ -4289,7 +4363,7 @@ source-map@^0.5.0, source-map@^0.5.6: resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== From 2d184232b9cebf0605bffeb85366d8da6f37967c Mon Sep 17 00:00:00 2001 From: zhangyu Date: Mon, 29 Jun 2020 17:31:11 +0800 Subject: [PATCH 03/11] =?UTF-8?q?Revert=20"feat:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BA=93,=E5=8F=AF=E4=BB=A5=E4=BE=9B=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E4=BD=BF=E7=94=A8"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 574140c4 --- README.md | 166 +++++++++++++++++++++++++++++++++++++++++++++++++-- package.json | 12 ++-- yarn.lock | 84 ++------------------------ 3 files changed, 170 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index 47e8f9e..a55ba4b 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,174 @@ ## react-native-iconfont-cli +用纯JS把iconfont.cn的图标转换成RN组件,不依赖字体,支持多色彩,支持热更新 -fork react-native-iconfont-cli 并且添加了 本地 svg 的支持 +![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/icons.png?raw=true) -原库的使用: https://github.com/iconfont-cli/react-native-iconfont-cli +## 痛点 -添加了本地 svg 支持之后的配置文件: +通常地,当我们想在RN里使用iconfont,我们可能会借助`react-native-vector-icons`导入ttf字体文件,或者直接手动下载各个svg文件到本地,然后单个使用。 +使用ttf字体有一个弊端,就是每次更新图标,都要相应的更新ttf文件,然后再次打包发布APP。而且ttf不支持多种色彩的图标,导致所有图标都是单色。如果你是借助`react-native-vector-icons`,该库内置了10多套ttf文件,合起来有`2M`左右;你可能用不到它们,但是它们仍然会被打包进你的APP里。 + +下载svg到本地也不方便,因为你需要额外维护一份图标字体,有可能造成线上和本地的图标不一致问题。而且如果你想动态地改变svg的渲染色彩,基本上是不可能的,只能渲染原图的颜色。 + +-------- + +为了解决这些问题,我用纯Javascript实现iconfont到React组件的转换操作,**不需要依赖ttf字体文件**,不需要手动下载图标到本地。 + +## 特性 + +1、纯组件,不依赖字体,体积小 +
+2、支持渲染多色彩图标,支持自定义颜色 +
+3、支持热更新 +
+4、自动化生成图标组件,支持es6和typescript两种文件格式 + +## Step 1 +安装插件 +```bash +# Yarn +yarn add react-native-svg +yarn add react-native-iconfont-cli --dev + +# Npm +npm install react-native-svg +npm install react-native-iconfont-cli --save-dev +``` + +# Step 2 +静态链接。请注意您使用的React-Native版本号 +```bash +# RN < 0.60 +react-native link react-native-svg + +# RN >= 0.60 +cd ios && pod install +``` + +# Step 3 +生成配置文件 +```bash +npx iconfont-init ``` +此时项目根目录会生成一个`iconfont.json`的文件,内容如下: +```json { "symbol_url": "请参考README.md,复制官网提供的JS链接", "use_typescript": false, "save_dir": "./src/iconfont", "trim_icon_prefix": "icon", - "default_icon_size": 18, - "local_dir": "./locals" // 唯一不同点 + "default_icon_size": 18 } ``` +### 配置参数说明: +### symbol_url +请直接复制[iconfont](http://iconfont.cn)官网提供的项目链接。请务必看清是`.js`后缀而不是.css后缀。如果你现在还没有创建iconfont的仓库,那么可以填入这个链接去测试:`http://at.alicdn.com/t/font_1373348_ghk94ooopqr.js` + +
+ +![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/symbol-url.png?raw=true) + +### use_typescript +如果您的项目使用Typescript编写,请设置为true。这个选项将决定生成的图标组件是`.tsx`还是`.js`后缀。 + +当该值为false时,我们会为您的图标生成`.js`和`.d.ts`两种文件,以便您能享受到最好的开发体验。 + +### save_dir +根据iconfont图标生成的组件存放的位置。每次生成组件之前,该文件夹都会被清空。 + +### trim_icon_prefix +如果你的图标有通用的前缀,而你在使用的时候又不想重复去写,那么可以通过这种配置这个选项把前缀统一去掉。 + +### default_icon_size +我们将为每个生成的图标组件加入默认的字体大小,当然,你也可以通过传入props的方式改变这个size值。 + +# Step 4 +开始生成React-Native标准组件 +```bash +npx iconfont-rn +``` + +生成后查看您设置的保存目录中是否含有所有的图标,你可以参考[snapshots目录](https://github.com/iconfont-cli/react-native-iconfont-cli/tree/master/snapshots)的快照文件,以区分不同模式下的图标结构。 + +# 使用 +
+现在我们提供了两种引入方式供您选择: + +1、使用汇总`Icon`组件: +```typescript jsx +import IconFont from '../src/iconfont'; + +export const App = () => { + return ( + + + + + ); +}; +``` + +2、使用单个图标。这样可以避免没用到的图标也打包进App: + +```typescript jsx +import IconAlipay from '../src/iconfont/IconAlipay'; +import IconWechat from '../src/iconfont/IconWechat'; + +export const App = () => { + return ( + + + + + ); +}; +``` + +### 图标尺寸 +根据配置`default_icon_size`,每个图标都会有一个默认的尺寸,你可以随时覆盖。 +```typescript jsx + +``` +![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/default-color-icon.png?raw=true) +### 图标单色 +单色图标,如果不指定颜色值,图标将渲染原本的颜色。如果你想设置为其他的颜色,那么设置一个你想要的颜色即可。 + +**注意:如果你在props传入的color是字符串而不是数组,那么即使原本是多色彩的图标,也会变成单色图标。** + +```typescript jsx + +``` +![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/one-color-icon.png?raw=true) + +### 图标多色彩 +多色彩的图标,如果不指定颜色值,图标将渲染原本的多色彩。如果你想设置为其他的颜色,那么设置一组你想要的颜色即可 +```typescript jsx + +``` +颜色组的数量以及排序,需要根据当前图标的信息来确定。您需要进入图标组件中查看并得出结论。 + + +![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/multi-color-icon.png?raw=true) + +# 更新图标 +当您在iconfont.cn中的图标有变更时,只需更改配置`symbol_url`,然后再次执行`Step 4`即可生成最新的图标组件 +```bash +# 修改 symbol_url 配置后执行: +npx iconfont-rn +``` + + +# 扩展 +|平台|库| +|----|---| +|小程序|[mini-program-iconfont-cli](https://github.com/iconfont-cli/mini-program-iconfont-cli)| +|Taro|[taro-iconfont-cli](https://github.com/iconfont-cli/taro-iconfont-cli)| +|React H5|[react-iconfont-cli](https://github.com/iconfont-cli/react-iconfont-cli)| +|Flutter|[flutter-iconfont-cli](https://github.com/iconfont-cli/flutter-iconfont-cli)| +|Remax|[remax-iconfont-cli](https://github.com/iconfont-cli/remax-iconfont-cli)| + +-------- + +欢迎使用,并给我一些反馈和建议,让这个库做的更好 diff --git a/package.json b/package.json index 5b53bf2..6a6bd7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@grewer/react-native-iconfont-cli", - "version": "2.2.0", + "name": "react-native-iconfont-cli", + "version": "2.1.0", "main": "index.js", "keywords": [ "iconfont", @@ -10,12 +10,8 @@ "icons", "iconfont.cn" ], - "repository": "https://github.com/Grewer/react-native-iconfont-cli", + "repository": "git@github.com:iconfont-cli/react-native-iconfont-cli.git", "author": "范文华 <531362022@qq.com>", - "contributors": [{ - "name": "grewer", - "email": "grewer@grewer.cn" - }], "license": "MIT", "bin": { "iconfont": "./commands/help.js", @@ -45,7 +41,7 @@ "@types/react": "^16.9.2", "react": "^16.9.0", "react-native": "^0.60.5", - "react-native-svg": "^9.7.1", + "react-native-svg": "^9.7.0", "ts-node": "^8.3.0", "typescript": "^3.5.3" } diff --git a/yarn.lock b/yarn.lock index 113dcaf..8ef5311 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1201,11 +1201,6 @@ big-integer@^1.6.7: resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.44.tgz#4ee9ae5f5839fc11ade338fea216b4513454a539" integrity sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ== -boolbase@^1.0.0, boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - bplist-creator@0.0.7: version "0.0.7" resolved "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz#37df1536092824b87c42f957b01344117372ae45" @@ -1582,29 +1577,6 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" -css-select@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" - integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== - dependencies: - boolbase "^1.0.0" - css-what "^3.2.1" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-tree@^1.0.0-alpha.37: - version "1.0.0-alpha.39" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" - integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== - dependencies: - mdn-data "2.0.6" - source-map "^0.6.1" - -css-what@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" - integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg== - csstype@^2.2.0: version "2.6.6" resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41" @@ -1729,37 +1701,11 @@ diff@^4.0.1: resolved "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= -domelementtype@1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== - -domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -1784,11 +1730,6 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -entities@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" - integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== - envinfo@^7.1.0: version "7.3.1" resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" @@ -2895,11 +2836,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -mdn-data@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" - integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== - mem@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" @@ -3459,13 +3395,6 @@ npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - nullthrows@^1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" @@ -3869,13 +3798,10 @@ react-is@^16.8.1, react-is@^16.8.4: resolved "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw== -react-native-svg@^9.7.1: - version "9.13.6" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.6.tgz#5365fba2bc460054b90851e71f2a71006a5d373f" - integrity sha512-vjjuJhEhQCwWjqsgWyGy6/C/LIBM2REDxB40FU1PMhi8T3zQUwUHnA6M15pJKlQG8vaZyA+QnLyIVhjtujRgig== - dependencies: - css-select "^2.0.2" - css-tree "^1.0.0-alpha.37" +react-native-svg@^9.7.0: + version "9.7.0" + resolved "https://registry.npmjs.org/react-native-svg/-/react-native-svg-9.7.0.tgz#2d0bf1d31d5f1dd061587215b50deb29e626df18" + integrity sha512-8E1snfe2YYbfu6SP5DOoQgRhCdv7D0F4VewUAV+IgAn+IScrA/uuLB8LCodRdO+9U4Rm5dJ4yIwsVhPHRtuBkw== react-native@^0.60.5: version "0.60.5" @@ -4363,7 +4289,7 @@ source-map@^0.5.0, source-map@^0.5.6: resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== From f3e9656eb4a40fcf9614c927dd78906ad29e3daf Mon Sep 17 00:00:00 2001 From: zhangyu Date: Mon, 29 Jun 2020 17:47:08 +0800 Subject: [PATCH 04/11] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20tsx=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=BA=20ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/commands/createIcon.ts | 2 +- src/libs/{parseLocalSvg.tsx => parseLocalSvg.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/libs/{parseLocalSvg.tsx => parseLocalSvg.ts} (100%) diff --git a/src/commands/createIcon.ts b/src/commands/createIcon.ts index ad74d54..e311424 100644 --- a/src/commands/createIcon.ts +++ b/src/commands/createIcon.ts @@ -4,7 +4,7 @@ import colors from 'colors' import { getConfig } from '../libs/getConfig' import { fetchXml } from 'iconfont-parser' import { generateComponent } from '../libs/generateComponent' -import parseLocalSvg from '../libs/parseLocalSvg' +import parseLocalSvg from 'src/libs/parseLocalSvg' const config = getConfig() diff --git a/src/libs/parseLocalSvg.tsx b/src/libs/parseLocalSvg.ts similarity index 100% rename from src/libs/parseLocalSvg.tsx rename to src/libs/parseLocalSvg.ts From b78a94b1d6ac6f16d6b2243d81ef850dd8d8b8d8 Mon Sep 17 00:00:00 2001 From: zhangyu Date: Mon, 29 Jun 2020 17:48:03 +0800 Subject: [PATCH 05/11] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E5=BC=95?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/commands/createIcon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/createIcon.ts b/src/commands/createIcon.ts index e311424..ad74d54 100644 --- a/src/commands/createIcon.ts +++ b/src/commands/createIcon.ts @@ -4,7 +4,7 @@ import colors from 'colors' import { getConfig } from '../libs/getConfig' import { fetchXml } from 'iconfont-parser' import { generateComponent } from '../libs/generateComponent' -import parseLocalSvg from 'src/libs/parseLocalSvg' +import parseLocalSvg from '../libs/parseLocalSvg' const config = getConfig() From 35b16f5583b7899b2e85e8246004764cd42af586 Mon Sep 17 00:00:00 2001 From: zhangyu Date: Wed, 1 Jul 2020 22:48:23 +0800 Subject: [PATCH 06/11] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=90=84?= =?UTF-8?q?=E7=A7=8D=20css=20=E7=9A=84=20svg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locals/README.md | 2 - locals/classSvg.svg | 19 +++++++ locals/inlineStyle.svg | 13 +++++ locals/normal.svg | 3 + locals/style.svg | 3 + locals/word.svg | 33 ----------- snapshots/demo-js/IconClassSvg.d.ts | 15 +++++ snapshots/demo-js/IconClassSvg.js | 35 ++++++++++++ snapshots/demo-js/IconInlineStyle.d.ts | 15 +++++ snapshots/demo-js/IconInlineStyle.js | 29 ++++++++++ snapshots/demo-js/IconNormal.d.ts | 15 +++++ snapshots/demo-js/IconNormal.js | 19 +++++++ .../demo-js/{IconWord.d.ts => IconStyle.d.ts} | 4 +- snapshots/demo-js/IconStyle.js | 19 +++++++ snapshots/demo-js/IconWord.js | 49 ---------------- snapshots/demo-js/index.d.ts | 2 +- snapshots/demo-js/index.js | 15 ++++- snapshots/demo-ts/IconClassSvg.tsx | 42 ++++++++++++++ snapshots/demo-ts/IconInlineStyle.tsx | 37 ++++++++++++ snapshots/demo-ts/IconNormal.tsx | 28 ++++++++++ snapshots/demo-ts/IconStyle.tsx | 26 +++++++++ snapshots/demo-ts/IconWord.tsx | 56 ------------------- snapshots/demo-ts/index.tsx | 17 ++++-- src/libs/generateComponent.ts | 14 +++-- src/libs/parseLocalSvg.ts | 10 +++- 25 files changed, 363 insertions(+), 157 deletions(-) create mode 100644 locals/classSvg.svg create mode 100644 locals/inlineStyle.svg create mode 100644 locals/normal.svg create mode 100644 locals/style.svg delete mode 100644 locals/word.svg create mode 100644 snapshots/demo-js/IconClassSvg.d.ts create mode 100644 snapshots/demo-js/IconClassSvg.js create mode 100644 snapshots/demo-js/IconInlineStyle.d.ts create mode 100644 snapshots/demo-js/IconInlineStyle.js create mode 100644 snapshots/demo-js/IconNormal.d.ts create mode 100644 snapshots/demo-js/IconNormal.js rename snapshots/demo-js/{IconWord.d.ts => IconStyle.d.ts} (79%) create mode 100644 snapshots/demo-js/IconStyle.js delete mode 100644 snapshots/demo-js/IconWord.js create mode 100644 snapshots/demo-ts/IconClassSvg.tsx create mode 100644 snapshots/demo-ts/IconInlineStyle.tsx create mode 100644 snapshots/demo-ts/IconNormal.tsx create mode 100644 snapshots/demo-ts/IconStyle.tsx delete mode 100644 snapshots/demo-ts/IconWord.tsx diff --git a/locals/README.md b/locals/README.md index 58f53f8..99f62e0 100644 --- a/locals/README.md +++ b/locals/README.md @@ -1,3 +1 @@ ## 验证获取正则是否正常 - -word.svg 文件是从 ui 图中直接获取的,且他是渐变色的 diff --git a/locals/classSvg.svg b/locals/classSvg.svg new file mode 100644 index 0000000..24ff12a --- /dev/null +++ b/locals/classSvg.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/locals/inlineStyle.svg b/locals/inlineStyle.svg new file mode 100644 index 0000000..03c5087 --- /dev/null +++ b/locals/inlineStyle.svg @@ -0,0 +1,13 @@ + + + + diff --git a/locals/normal.svg b/locals/normal.svg new file mode 100644 index 0000000..3ae922c --- /dev/null +++ b/locals/normal.svg @@ -0,0 +1,3 @@ + + + diff --git a/locals/style.svg b/locals/style.svg new file mode 100644 index 0000000..48eca44 --- /dev/null +++ b/locals/style.svg @@ -0,0 +1,3 @@ + + + diff --git a/locals/word.svg b/locals/word.svg deleted file mode 100644 index d27c2a5..0000000 --- a/locals/word.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/snapshots/demo-js/IconClassSvg.d.ts b/snapshots/demo-js/IconClassSvg.d.ts new file mode 100644 index 0000000..e9149b5 --- /dev/null +++ b/snapshots/demo-js/IconClassSvg.d.ts @@ -0,0 +1,15 @@ +/* eslint-disable */ + +import { FunctionComponent } from 'react'; +// Don't forget to install package: @types/react-native +import { ViewProps } from 'react-native'; +import { GProps } from 'react-native-svg'; + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +declare const IconClassSvg: FunctionComponent; + +export default IconClassSvg; diff --git a/snapshots/demo-js/IconClassSvg.js b/snapshots/demo-js/IconClassSvg.js new file mode 100644 index 0000000..f07f449 --- /dev/null +++ b/snapshots/demo-js/IconClassSvg.js @@ -0,0 +1,35 @@ +/* eslint-disable */ + +import React from 'react'; +import { GProps, SvgCss } from 'react-native-svg'; + + +const IconClassSvg = ({ size, color, ...rest }) => { + return ( + + + + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconClassSvg.defaultProps = { + size: 18, +}; + +export default React.memo ? React.memo(IconClassSvg) : IconClassSvg; diff --git a/snapshots/demo-js/IconInlineStyle.d.ts b/snapshots/demo-js/IconInlineStyle.d.ts new file mode 100644 index 0000000..95651e7 --- /dev/null +++ b/snapshots/demo-js/IconInlineStyle.d.ts @@ -0,0 +1,15 @@ +/* eslint-disable */ + +import { FunctionComponent } from 'react'; +// Don't forget to install package: @types/react-native +import { ViewProps } from 'react-native'; +import { GProps } from 'react-native-svg'; + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +declare const IconInlineStyle: FunctionComponent; + +export default IconInlineStyle; diff --git a/snapshots/demo-js/IconInlineStyle.js b/snapshots/demo-js/IconInlineStyle.js new file mode 100644 index 0000000..8a420ca --- /dev/null +++ b/snapshots/demo-js/IconInlineStyle.js @@ -0,0 +1,29 @@ +/* eslint-disable */ + +import React from 'react'; +import { GProps, SvgCss } from 'react-native-svg'; + + +const IconInlineStyle = ({ size, color, ...rest }) => { + return ( + + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconInlineStyle.defaultProps = { + size: 18, +}; + +export default React.memo ? React.memo(IconInlineStyle) : IconInlineStyle; diff --git a/snapshots/demo-js/IconNormal.d.ts b/snapshots/demo-js/IconNormal.d.ts new file mode 100644 index 0000000..cfe8b88 --- /dev/null +++ b/snapshots/demo-js/IconNormal.d.ts @@ -0,0 +1,15 @@ +/* eslint-disable */ + +import { FunctionComponent } from 'react'; +// Don't forget to install package: @types/react-native +import { ViewProps } from 'react-native'; +import { GProps } from 'react-native-svg'; + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +declare const IconNormal: FunctionComponent; + +export default IconNormal; diff --git a/snapshots/demo-js/IconNormal.js b/snapshots/demo-js/IconNormal.js new file mode 100644 index 0000000..176501c --- /dev/null +++ b/snapshots/demo-js/IconNormal.js @@ -0,0 +1,19 @@ +/* eslint-disable */ + +import React from 'react'; +import { GProps, SvgXml } from 'react-native-svg'; + + +const IconNormal = ({ size, color, ...rest }) => { + return ( + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconNormal.defaultProps = { + size: 18, +}; + +export default React.memo ? React.memo(IconNormal) : IconNormal; diff --git a/snapshots/demo-js/IconWord.d.ts b/snapshots/demo-js/IconStyle.d.ts similarity index 79% rename from snapshots/demo-js/IconWord.d.ts rename to snapshots/demo-js/IconStyle.d.ts index c1a43a7..06def0f 100644 --- a/snapshots/demo-js/IconWord.d.ts +++ b/snapshots/demo-js/IconStyle.d.ts @@ -10,6 +10,6 @@ interface Props extends GProps, ViewProps { color?: string | string[]; } -declare const IconWord: FunctionComponent; +declare const IconStyle: FunctionComponent; -export default IconWord; +export default IconStyle; diff --git a/snapshots/demo-js/IconStyle.js b/snapshots/demo-js/IconStyle.js new file mode 100644 index 0000000..12ec494 --- /dev/null +++ b/snapshots/demo-js/IconStyle.js @@ -0,0 +1,19 @@ +/* eslint-disable */ + +import React from 'react'; +import { GProps, SvgXml } from 'react-native-svg'; + + +const IconStyle = ({ size, color, ...rest }) => { + return ( + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconStyle.defaultProps = { + size: 18, +}; + +export default React.memo ? React.memo(IconStyle) : IconStyle; diff --git a/snapshots/demo-js/IconWord.js b/snapshots/demo-js/IconWord.js deleted file mode 100644 index 62d3c0c..0000000 --- a/snapshots/demo-js/IconWord.js +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable */ - -import React from 'react'; -import { GProps, SvgXml } from 'react-native-svg'; - - -const IconWord = ({ size, color, ...rest }) => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`} width={size} height={size} {...rest} /> - ); -}; - -IconWord.defaultProps = { - size: 18, -}; - -export default React.memo ? React.memo(IconWord) : IconWord; diff --git a/snapshots/demo-js/index.d.ts b/snapshots/demo-js/index.d.ts index 02e5194..09863ef 100644 --- a/snapshots/demo-js/index.d.ts +++ b/snapshots/demo-js/index.d.ts @@ -6,7 +6,7 @@ import { ViewProps } from 'react-native'; import { GProps } from 'react-native-svg'; interface Props extends GProps, ViewProps { - name: 'alipay' | 'user' | 'setup' | 'word'; + name: 'alipay' | 'user' | 'setup' | 'classSvg' | 'inlineStyle' | 'normal' | 'style'; size?: number; color?: string | string[]; } diff --git a/snapshots/demo-js/index.js b/snapshots/demo-js/index.js index 0c0b491..c13e02d 100644 --- a/snapshots/demo-js/index.js +++ b/snapshots/demo-js/index.js @@ -5,7 +5,10 @@ import React from 'react'; import IconAlipay from './IconAlipay'; import IconUser from './IconUser'; import IconSetup from './IconSetup'; -import IconWord from './IconWord'; +import IconClassSvg from './IconClassSvg'; +import IconInlineStyle from './IconInlineStyle'; +import IconNormal from './IconNormal'; +import IconStyle from './IconStyle'; const IconFont = ({ name, ...rest }) => { switch (name) { @@ -15,8 +18,14 @@ const IconFont = ({ name, ...rest }) => { return ; case 'setup': return ; - case 'word': - return ; + case 'classSvg': + return ; + case 'inlineStyle': + return ; + case 'normal': + return ; + case 'style': + return ; } return null; diff --git a/snapshots/demo-ts/IconClassSvg.tsx b/snapshots/demo-ts/IconClassSvg.tsx new file mode 100644 index 0000000..1f9a129 --- /dev/null +++ b/snapshots/demo-ts/IconClassSvg.tsx @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ + +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; +import { GProps, SvgCss } from 'react-native-svg'; + + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +const IconClassSvg: FunctionComponent = ({ size, color, ...rest }) => { + return ( + + + + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconClassSvg.defaultProps = { + size: 20, +}; + +export default React.memo ? React.memo(IconClassSvg) : IconClassSvg; diff --git a/snapshots/demo-ts/IconInlineStyle.tsx b/snapshots/demo-ts/IconInlineStyle.tsx new file mode 100644 index 0000000..3146133 --- /dev/null +++ b/snapshots/demo-ts/IconInlineStyle.tsx @@ -0,0 +1,37 @@ +/* tslint:disable */ +/* eslint-disable */ + +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; +import { GProps, SvgCss } from 'react-native-svg'; + + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + + +const IconInlineStyle: FunctionComponent = ({ size, color, ...rest }) => { + return ( + + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconInlineStyle.defaultProps = { + size: 20, +}; + +export default React.memo ? React.memo(IconInlineStyle) : IconInlineStyle; diff --git a/snapshots/demo-ts/IconNormal.tsx b/snapshots/demo-ts/IconNormal.tsx new file mode 100644 index 0000000..2fb8318 --- /dev/null +++ b/snapshots/demo-ts/IconNormal.tsx @@ -0,0 +1,28 @@ +/* tslint:disable */ +/* eslint-disable */ + +import React, { FunctionComponent } from 'react' +import { ViewProps } from 'react-native' +import { GProps, SvgXml } from 'react-native-svg' + + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +const svg = ` + +` + +const IconNormal: FunctionComponent = ({ size, color, ...rest }) => { + return ( + + ) +} + +IconNormal.defaultProps = { + size: 20, +} + +export default React.memo ? React.memo(IconNormal) : IconNormal diff --git a/snapshots/demo-ts/IconStyle.tsx b/snapshots/demo-ts/IconStyle.tsx new file mode 100644 index 0000000..2f8116e --- /dev/null +++ b/snapshots/demo-ts/IconStyle.tsx @@ -0,0 +1,26 @@ +/* tslint:disable */ +/* eslint-disable */ + +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; +import { GProps, SvgXml } from 'react-native-svg'; + + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +const IconStyle: FunctionComponent = ({ size, color, ...rest }) => { + return ( + + +`} width={size} height={size} {...rest} /> + ); +}; + +IconStyle.defaultProps = { + size: 20, +}; + +export default React.memo ? React.memo(IconStyle) : IconStyle; diff --git a/snapshots/demo-ts/IconWord.tsx b/snapshots/demo-ts/IconWord.tsx deleted file mode 100644 index 13d85b8..0000000 --- a/snapshots/demo-ts/IconWord.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ - -import React, { FunctionComponent } from 'react'; -import { ViewProps } from 'react-native'; -import { GProps, SvgXml } from 'react-native-svg'; - - -interface Props extends GProps, ViewProps { - size?: number; - color?: string | string[]; -} - -const IconWord: FunctionComponent = ({ size, color, ...rest }) => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`} width={size} height={size} {...rest} /> - ); -}; - -IconWord.defaultProps = { - size: 20, -}; - -export default React.memo ? React.memo(IconWord) : IconWord; diff --git a/snapshots/demo-ts/index.tsx b/snapshots/demo-ts/index.tsx index c84da79..3767e3f 100644 --- a/snapshots/demo-ts/index.tsx +++ b/snapshots/demo-ts/index.tsx @@ -7,9 +7,12 @@ import { GProps } from 'react-native-svg'; import IconAlipay from './IconAlipay'; import IconUser from './IconUser'; import IconSetup from './IconSetup'; -import IconWord from './IconWord'; +import IconClassSvg from './IconClassSvg'; +import IconInlineStyle from './IconInlineStyle'; +import IconNormal from './IconNormal'; +import IconStyle from './IconStyle'; -export type IconNames = 'alipay' | 'user' | 'setup' | 'word'; +export type IconNames = 'alipay' | 'user' | 'setup' | 'classSvg' | 'inlineStyle' | 'normal' | 'style'; interface Props extends GProps, ViewProps { name: IconNames; @@ -25,8 +28,14 @@ const IconFont: FunctionComponent = ({ name, ...rest }) => { return ; case 'setup': return ; - case 'word': - return ; + case 'classSvg': + return ; + case 'inlineStyle': + return ; + case 'normal': + return ; + case 'style': + return ; } return null; diff --git a/src/libs/generateComponent.ts b/src/libs/generateComponent.ts index 2f06cfb..fdd84ab 100644 --- a/src/libs/generateComponent.ts +++ b/src/libs/generateComponent.ts @@ -101,12 +101,16 @@ export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: console.log(`${colors.green('√')} Generated icon "${colors.yellow(iconId)}"`); }); - - localSvg.forEach(({ name, svgStr }, index) => { + /** + * 本地文件添加 + */ + localSvg.forEach(({ name, svgStr,styleType }, index) => { let singleFile: string; const componentName = upperFirst(config.trim_icon_prefix) + upperFirst(camelCase(name)); - const currentSvgComponents = new Set(['GProps', 'SvgXml']); + const currentSvgComponents = new Set(['GProps']); + + currentSvgComponents.add(styleType ? 'SvgCss' : 'SvgXml'); names.push(name); @@ -119,7 +123,7 @@ export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: singleFile = replaceSize(singleFile, config.default_icon_size); singleFile = replaceSvgComponents(singleFile, currentSvgComponents); singleFile = replaceComponentName(singleFile, componentName); - singleFile = replaceSingleIconContent(singleFile, `\n${whitespace(4)}\n`); + singleFile = replaceSingleIconContent(singleFile, `\n${whitespace(4)}<${styleType ? 'SvgCss' : 'SvgXml'} xml={\`${svgStr}\`} width={size} height={size} {...rest} />\n`); singleFile = replaceNoHelper(singleFile); fs.writeFileSync(path.join(saveDir, componentName + jsxExtension), singleFile); @@ -155,7 +159,7 @@ export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: fs.writeFileSync(path.join(saveDir, 'index' + jsxExtension), iconFile); console.log(`\n${colors.green('√')} All icons have putted into dir: ${colors.green(config.save_dir)}\n`); -}; +} const generateCase = (data: XmlData['svg']['symbol'][number], baseIdent: number) => { let template = `\n${whitespace(baseIdent)}\n`; diff --git a/src/libs/parseLocalSvg.ts b/src/libs/parseLocalSvg.ts index 1d2a606..4ebe719 100644 --- a/src/libs/parseLocalSvg.ts +++ b/src/libs/parseLocalSvg.ts @@ -6,6 +6,7 @@ import * as fs from 'fs' export interface ILocalSvg { svgStr: string name: string + styleType: boolean } const parseLocalSvg = ({ local_dir }: Config) => { @@ -21,10 +22,15 @@ const parseLocalSvg = ({ local_dir }: Config) => { let svgStr = fs.readFileSync(currentValue, 'utf-8') + /** + * 去除注释,title,desc等不需要的标签 + */ svgStr = svgStr.substring(svgStr.indexOf('') + 6) - .replace(//g, '') + .replace(//g, '').replace(/(.*?)<\/title>/g, '').replace(/(.*?)<\/desc>/g, '') - previousValue.push({ svgStr, name: path.basename(currentValue, '.svg') }) + const styleType = !!~svgStr.indexOf('') + + previousValue.push({ svgStr, name: path.basename(currentValue, '.svg'), styleType }) return previousValue }, []) From b3cf8a3787e72f9282034947446dfdf19c855b7d Mon Sep 17 00:00:00 2001 From: zhangyu Date: Wed, 1 Jul 2020 22:53:42 +0800 Subject: [PATCH 07/11] style: format --- src/libs/generateComponent.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/generateComponent.ts b/src/libs/generateComponent.ts index fdd84ab..00c2883 100644 --- a/src/libs/generateComponent.ts +++ b/src/libs/generateComponent.ts @@ -104,7 +104,7 @@ export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: /** * 本地文件添加 */ - localSvg.forEach(({ name, svgStr,styleType }, index) => { + localSvg.forEach(({ name, svgStr, styleType }, index) => { let singleFile: string; const componentName = upperFirst(config.trim_icon_prefix) + upperFirst(camelCase(name)); @@ -117,6 +117,7 @@ export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: cases += `${whitespace(4)}case '${name}':\n`; imports.push(componentName); + cases += `${whitespace(6)}return <${componentName} key="L${index + 1}" {...rest} />;\n`; singleFile = getTemplate('SingleIcon' + jsxExtension); From a1af08802ce9ad4ec70422aaadb1cb1c50e38e5b Mon Sep 17 00:00:00 2001 From: zhangyu Date: Wed, 1 Jul 2020 23:20:08 +0800 Subject: [PATCH 08/11] =?UTF-8?q?style:=20=E4=BC=98=E5=8C=96=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E6=96=87=E4=BB=B6=E7=9A=84=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- snapshots/demo-js/IconClassSvg.js | 15 ++++++++------ snapshots/demo-js/IconInlineStyle.js | 15 ++++++++------ snapshots/demo-js/IconNormal.js | 11 +++++++---- snapshots/demo-js/IconStyle.js | 11 +++++++---- snapshots/demo-ts/IconClassSvg.tsx | 13 +++++++----- snapshots/demo-ts/IconInlineStyle.tsx | 14 +++++++------ snapshots/demo-ts/IconNormal.tsx | 23 +++++++++++----------- snapshots/demo-ts/IconStyle.tsx | 11 +++++++---- src/libs/generateComponent.ts | 15 +++++++++----- src/libs/replace.ts | 11 ++++------- src/templates/LocalSingleIcon.js.template | 16 +++++++++++++++ src/templates/LocalSingleIcon.tsx.template | 23 ++++++++++++++++++++++ 12 files changed, 120 insertions(+), 58 deletions(-) create mode 100644 src/templates/LocalSingleIcon.js.template create mode 100644 src/templates/LocalSingleIcon.tsx.template diff --git a/snapshots/demo-js/IconClassSvg.js b/snapshots/demo-js/IconClassSvg.js index f07f449..334b99c 100644 --- a/snapshots/demo-js/IconClassSvg.js +++ b/snapshots/demo-js/IconClassSvg.js @@ -1,12 +1,10 @@ /* eslint-disable */ import React from 'react'; -import { GProps, SvgCss } from 'react-native-svg'; +import { SvgCss } from 'react-native-svg'; - -const IconClassSvg = ({ size, color, ...rest }) => { - return ( - +const xml = ` + -`} width={size} height={size} {...rest} /> + +` + +const IconInlineStyle = ({ size, color, ...rest }) => { + return ( + ); }; diff --git a/snapshots/demo-js/IconNormal.js b/snapshots/demo-js/IconNormal.js index 176501c..035351d 100644 --- a/snapshots/demo-js/IconNormal.js +++ b/snapshots/demo-js/IconNormal.js @@ -1,14 +1,17 @@ /* eslint-disable */ import React from 'react'; -import { GProps, SvgXml } from 'react-native-svg'; +import { SvgXml } from 'react-native-svg'; +const xml = ` + + + +` const IconNormal = ({ size, color, ...rest }) => { return ( - - -`} width={size} height={size} {...rest} /> + ); }; diff --git a/snapshots/demo-js/IconStyle.js b/snapshots/demo-js/IconStyle.js index 12ec494..544ff59 100644 --- a/snapshots/demo-js/IconStyle.js +++ b/snapshots/demo-js/IconStyle.js @@ -1,14 +1,17 @@ /* eslint-disable */ import React from 'react'; -import { GProps, SvgXml } from 'react-native-svg'; +import { SvgXml } from 'react-native-svg'; +const xml = ` + + + +` const IconStyle = ({ size, color, ...rest }) => { return ( - - -`} width={size} height={size} {...rest} /> + ); }; diff --git a/snapshots/demo-ts/IconClassSvg.tsx b/snapshots/demo-ts/IconClassSvg.tsx index 1f9a129..da2a240 100644 --- a/snapshots/demo-ts/IconClassSvg.tsx +++ b/snapshots/demo-ts/IconClassSvg.tsx @@ -5,15 +5,13 @@ import React, { FunctionComponent } from 'react'; import { ViewProps } from 'react-native'; import { GProps, SvgCss } from 'react-native-svg'; - interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconClassSvg: FunctionComponent = ({ size, color, ...rest }) => { - return ( - +const xml = ` + -`} width={size} height={size} {...rest} /> + +` + +const IconInlineStyle: FunctionComponent = ({ size, color, ...rest }) => { + return ( + ); }; diff --git a/snapshots/demo-ts/IconNormal.tsx b/snapshots/demo-ts/IconNormal.tsx index 2fb8318..847dc87 100644 --- a/snapshots/demo-ts/IconNormal.tsx +++ b/snapshots/demo-ts/IconNormal.tsx @@ -1,28 +1,29 @@ /* tslint:disable */ /* eslint-disable */ -import React, { FunctionComponent } from 'react' -import { ViewProps } from 'react-native' -import { GProps, SvgXml } from 'react-native-svg' - +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; +import { GProps, SvgXml } from 'react-native-svg'; interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const svg = ` +const xml = ` + -` + +` const IconNormal: FunctionComponent = ({ size, color, ...rest }) => { return ( - - ) -} + + ); +}; IconNormal.defaultProps = { size: 20, -} +}; -export default React.memo ? React.memo(IconNormal) : IconNormal +export default React.memo ? React.memo(IconNormal) : IconNormal; diff --git a/snapshots/demo-ts/IconStyle.tsx b/snapshots/demo-ts/IconStyle.tsx index 2f8116e..0a1ab66 100644 --- a/snapshots/demo-ts/IconStyle.tsx +++ b/snapshots/demo-ts/IconStyle.tsx @@ -5,17 +5,20 @@ import React, { FunctionComponent } from 'react'; import { ViewProps } from 'react-native'; import { GProps, SvgXml } from 'react-native-svg'; - interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } +const xml = ` + + + +` + const IconStyle: FunctionComponent = ({ size, color, ...rest }) => { return ( - - -`} width={size} height={size} {...rest} /> + ); }; diff --git a/src/libs/generateComponent.ts b/src/libs/generateComponent.ts index 00c2883..03e73a2 100644 --- a/src/libs/generateComponent.ts +++ b/src/libs/generateComponent.ts @@ -16,7 +16,8 @@ import { replaceSingleIconContent, replaceSize, replaceSvgComponents, - replaceHelper, replaceNoHelper, + replaceHelper, + replaceComponentXml, } from './replace' import { whitespace } from './whitespace'; import { copyTemplate } from './copyTemplate'; @@ -108,7 +109,11 @@ export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: let singleFile: string; const componentName = upperFirst(config.trim_icon_prefix) + upperFirst(camelCase(name)); - const currentSvgComponents = new Set(['GProps']); + const currentSvgComponents = new Set(); + + if (config.use_typescript) { + currentSvgComponents.add('GProps'); + } currentSvgComponents.add(styleType ? 'SvgCss' : 'SvgXml'); @@ -120,12 +125,12 @@ export const generateComponent = (data: XmlData, localSvg: ILocalSvg[], config: cases += `${whitespace(6)}return <${componentName} key="L${index + 1}" {...rest} />;\n`; - singleFile = getTemplate('SingleIcon' + jsxExtension); + singleFile = getTemplate('LocalSingleIcon' + jsxExtension); singleFile = replaceSize(singleFile, config.default_icon_size); singleFile = replaceSvgComponents(singleFile, currentSvgComponents); singleFile = replaceComponentName(singleFile, componentName); - singleFile = replaceSingleIconContent(singleFile, `\n${whitespace(4)}<${styleType ? 'SvgCss' : 'SvgXml'} xml={\`${svgStr}\`} width={size} height={size} {...rest} />\n`); - singleFile = replaceNoHelper(singleFile); + singleFile = replaceComponentXml(singleFile, `const xml = \`\n${svgStr}\n\``); + singleFile = replaceSingleIconContent(singleFile, `\n${whitespace(4)}<${styleType ? 'SvgCss' : 'SvgXml'} xml={xml} width={size} height={size} {...rest} />\n`); fs.writeFileSync(path.join(saveDir, componentName + jsxExtension), singleFile); diff --git a/src/libs/replace.ts b/src/libs/replace.ts index abbbc5d..bec9e78 100644 --- a/src/libs/replace.ts +++ b/src/libs/replace.ts @@ -49,13 +49,6 @@ export const replaceHelper = (content: string) => { ); }; -export const replaceNoHelper = (content: string) => { - return content.replace( - /#helper#/g, - '' - ); -}; - export const replaceNoColor = (content: string) => { return content.replace(/#colorFunc#/g, ''); }; @@ -63,3 +56,7 @@ export const replaceNoColor = (content: string) => { export const replaceSummaryIcon = (content: string, iconName: string) => { return content.replace(/#SummaryIcon#/g, iconName); }; + +export const replaceComponentXml = (content: string, svgStr: string) => { + return content.replace(/#xml#/g, svgStr); +} diff --git a/src/templates/LocalSingleIcon.js.template b/src/templates/LocalSingleIcon.js.template new file mode 100644 index 0000000..74c374d --- /dev/null +++ b/src/templates/LocalSingleIcon.js.template @@ -0,0 +1,16 @@ +/* eslint-disable */ + +import React from 'react'; +#svgComponents# + +#xml# + +const #componentName# = ({ size, color, ...rest }) => { + return (#iconContent# ); +}; + +#componentName#.defaultProps = { + size: #size#, +}; + +export default React.memo ? React.memo(#componentName#) : #componentName#; diff --git a/src/templates/LocalSingleIcon.tsx.template b/src/templates/LocalSingleIcon.tsx.template new file mode 100644 index 0000000..e9f75c9 --- /dev/null +++ b/src/templates/LocalSingleIcon.tsx.template @@ -0,0 +1,23 @@ +/* tslint:disable */ +/* eslint-disable */ + +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; +#svgComponents# + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +#xml# + +const #componentName#: FunctionComponent = ({ size, color, ...rest }) => { + return (#iconContent# ); +}; + +#componentName#.defaultProps = { + size: #size#, +}; + +export default React.memo ? React.memo(#componentName#) : #componentName#; From 9a03338e08ebd161da2a9867538a5c77c45e214f Mon Sep 17 00:00:00 2001 From: zhangyu Date: Thu, 2 Jul 2020 22:46:23 +0800 Subject: [PATCH 09/11] =?UTF-8?q?refactor:=20locals=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E4=BF=AE=E6=94=B9,=20=E6=94=B9=E4=B8=BA=20lo?= =?UTF-8?q?cal=5Fsvgs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {locals => localSvgs}/classSvg.svg | 0 {locals => localSvgs}/inlineStyle.svg | 0 {locals => localSvgs}/normal.svg | 0 {locals => localSvgs}/style.svg | 0 locals/README.md | 1 - scripts/config/demo-js.json | 2 +- scripts/config/demo-ts.json | 2 +- src/libs/getConfig.ts | 2 +- src/libs/iconfont.json | 3 ++- src/libs/parseLocalSvg.ts | 6 +++--- 10 files changed, 8 insertions(+), 8 deletions(-) rename {locals => localSvgs}/classSvg.svg (100%) rename {locals => localSvgs}/inlineStyle.svg (100%) rename {locals => localSvgs}/normal.svg (100%) rename {locals => localSvgs}/style.svg (100%) delete mode 100644 locals/README.md diff --git a/locals/classSvg.svg b/localSvgs/classSvg.svg similarity index 100% rename from locals/classSvg.svg rename to localSvgs/classSvg.svg diff --git a/locals/inlineStyle.svg b/localSvgs/inlineStyle.svg similarity index 100% rename from locals/inlineStyle.svg rename to localSvgs/inlineStyle.svg diff --git a/locals/normal.svg b/localSvgs/normal.svg similarity index 100% rename from locals/normal.svg rename to localSvgs/normal.svg diff --git a/locals/style.svg b/localSvgs/style.svg similarity index 100% rename from locals/style.svg rename to localSvgs/style.svg diff --git a/locals/README.md b/locals/README.md deleted file mode 100644 index 99f62e0..0000000 --- a/locals/README.md +++ /dev/null @@ -1 +0,0 @@ -## 验证获取正则是否正常 diff --git a/scripts/config/demo-js.json b/scripts/config/demo-js.json index 970651a..8566101 100644 --- a/scripts/config/demo-js.json +++ b/scripts/config/demo-js.json @@ -4,5 +4,5 @@ "save_dir": "./snapshots/demo-js", "trim_icon_prefix": "icon", "default_icon_size": 18, - "local_dir": "./locals" + "local_svgs": "./localSvgs" } diff --git a/scripts/config/demo-ts.json b/scripts/config/demo-ts.json index 8571b6f..d7155b9 100644 --- a/scripts/config/demo-ts.json +++ b/scripts/config/demo-ts.json @@ -4,5 +4,5 @@ "save_dir": "./snapshots/demo-ts", "trim_icon_prefix": "icon", "default_icon_size": 20, - "local_dir": "./locals" + "local_svgs": "./localSvgs" } diff --git a/src/libs/getConfig.ts b/src/libs/getConfig.ts index 391353d..116c828 100644 --- a/src/libs/getConfig.ts +++ b/src/libs/getConfig.ts @@ -9,7 +9,7 @@ export interface Config { save_dir: string; trim_icon_prefix: string; default_icon_size: number; - local_dir?: string + local_svgs?: string } let cacheConfig: Config; diff --git a/src/libs/iconfont.json b/src/libs/iconfont.json index 53b3928..2114e4a 100644 --- a/src/libs/iconfont.json +++ b/src/libs/iconfont.json @@ -3,5 +3,6 @@ "use_typescript": false, "save_dir": "./src/iconfont", "trim_icon_prefix": "icon", - "default_icon_size": 18 + "default_icon_size": 18, + "local_svgs": "./localSvgs" } diff --git a/src/libs/parseLocalSvg.ts b/src/libs/parseLocalSvg.ts index 4ebe719..c276ed3 100644 --- a/src/libs/parseLocalSvg.ts +++ b/src/libs/parseLocalSvg.ts @@ -9,12 +9,12 @@ export interface ILocalSvg { styleType: boolean } -const parseLocalSvg = ({ local_dir }: Config) => { - if (!local_dir) { +const parseLocalSvg = ({ local_svgs }: Config) => { + if (!local_svgs) { return [] } - const localDir = path.resolve(local_dir) + const localDir = path.resolve(local_svgs) const localSvg = glob.sync(path.join(localDir, '**/*.svg')) From 0926b6aa4ecdce9c3a10b79cff232ecce2998e39 Mon Sep 17 00:00:00 2001 From: zhangyu Date: Thu, 2 Jul 2020 22:46:52 +0800 Subject: [PATCH 10/11] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E5=AF=B9=E4=BA=8E=E6=9C=AC=E5=9C=B0=20svg=20=E7=9A=84?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a55ba4b..4f3950e 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ npx iconfont-init "use_typescript": false, "save_dir": "./src/iconfont", "trim_icon_prefix": "icon", - "default_icon_size": 18 + "default_icon_size": 18, + "local_svgs": "./localSvgs" } ``` ### 配置参数说明: @@ -84,6 +85,9 @@ npx iconfont-init ### default_icon_size 我们将为每个生成的图标组件加入默认的字体大小,当然,你也可以通过传入props的方式改变这个size值。 +### local_svgs +本地 svg 的路径, 配置此项后在路径中添加 svg 文件即可。 + # Step 4 开始生成React-Native标准组件 ```bash @@ -152,6 +156,13 @@ export const App = () => { ![](https://github.com/fwh1990/react-native-iconfont-cli/blob/master/images/multi-color-icon.png?raw=true) + +### 图标渐变色 +渐变色的图标 iconfont 并不支持上传, 所以需要在本地 svg 的支持, 在本地文件中添加 svg 和 `local_svgs` 配置项, 生成组件即可使用, 使用方式和 iconfont 组件相同 + +**注 1: 当前版本暂不支持本地文件的 `color` 参数** +**注 2: svg 的兼容受 `react-native-svg` 影响, 如果在某些机型上不显示 svg, 可检查 `react-native-svg` 是否支持** + # 更新图标 当您在iconfont.cn中的图标有变更时,只需更改配置`symbol_url`,然后再次执行`Step 4`即可生成最新的图标组件 ```bash From 3f6e5f60ab7640bb51ee528475cf6d674a23d446 Mon Sep 17 00:00:00 2001 From: zhangyu Date: Thu, 2 Jul 2020 22:48:32 +0800 Subject: [PATCH 11/11] =?UTF-8?q?doc:=20=E4=BF=AE=E6=AD=A3=E8=AF=AD?= =?UTF-8?q?=E6=B3=95=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4f3950e..ea8c67f 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ npx iconfont-init 我们将为每个生成的图标组件加入默认的字体大小,当然,你也可以通过传入props的方式改变这个size值。 ### local_svgs -本地 svg 的路径, 配置此项后在路径中添加 svg 文件即可。 +本地 svg 的路径, 配置此项后在路径中添加 svg 文件即可。支持渐变图标。 # Step 4 开始生成React-Native标准组件 @@ -158,10 +158,10 @@ export const App = () => { ### 图标渐变色 -渐变色的图标 iconfont 并不支持上传, 所以需要在本地 svg 的支持, 在本地文件中添加 svg 和 `local_svgs` 配置项, 生成组件即可使用, 使用方式和 iconfont 组件相同 +渐变色的图标 iconfont 并不支持上传, 所以需要本地 svg 的支持, 在本地文件中添加 svg 和 `local_svgs` 配置项, 生成组件即可使用, 使用方式和 iconfont 组件相同 **注 1: 当前版本暂不支持本地文件的 `color` 参数** -**注 2: svg 的兼容受 `react-native-svg` 影响, 如果在某些机型上不显示 svg, 可检查 `react-native-svg` 是否支持** +**注 2: svg 的兼容受 `react-native-svg` 影响, 如果某些机型上不显示 svg, 可检查 `react-native-svg` 是否支持** # 更新图标 当您在iconfont.cn中的图标有变更时,只需更改配置`symbol_url`,然后再次执行`Step 4`即可生成最新的图标组件