Skip to content

Commit a99fb38

Browse files
committed
feat: Add color props
1 parent af57c3f commit a99fb38

11 files changed

Lines changed: 106 additions & 34 deletions

README.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,13 @@ cd ios && pod install
6464
### use_typescript
6565
如果您的项目使用Typescript编写,请设置为true。这个选项将决定生成的图标组件是`.tsx`还是`.jsx`后缀。
6666

67+
当该值为false时,我们会为您的图标生成`.jsx``.d.ts`两个文件,以便您能享受到最好的开发体验。
68+
6769
### generate_mode
6870
生成组件的方式:
69-
##### all-in-one
71+
##### 1、all-in-one
7072
只生成一个`<Icon name="xxx" />` 组件,里面包含了所有图标信息。所以这个组件会比较大。
71-
##### depends-on
73+
##### 2、depends-on
7274
每个图标都会生成一个组件`<IconXXX />`。这种模式也会生成一个`Icon`组件,但和all-in-one不同的是,这个Icon组件总是import其他的图标组件,它相当于一个门面。
7375

7476
### safe_dir
@@ -91,7 +93,9 @@ cd ios && pod install
9193
生成后查看您设置的保存目录中是否含有所有的图标
9294

9395
# Step 5
94-
使用这些图标。现在我们提供了两种引入方式供您选择:
96+
使用这些图标。
97+
<br />
98+
现在我们提供了两种引入方式供您选择:
9599

96100
1、使用汇总`Icon`组件:
97101
```typescript jsx
@@ -123,6 +127,28 @@ export const App = () => {
123127
};
124128
```
125129

130+
# 使用
131+
### 图标尺寸
132+
根据配置`default_icon_size`,每个图标都会有一个默认的尺寸,你可以随时覆盖。
133+
```typescript jsx
134+
<Icon name="user" size={20} />
135+
```
136+
### 图标单色
137+
单色图标,如果不指定颜色值,图标将渲染原本的颜色。如果你想设置为其他的颜色,那么设置一个你想要的颜色即可
138+
```typescript jsx
139+
<Icon name="user" color="#ff0000" />
140+
141+
<Icon name="user" color="#red" />
142+
```
143+
### 图标多色彩
144+
多色彩的图标,如果不指定颜色值,图标将渲染原本的多色彩。如果你想设置为其他的颜色,那么设置一组你想要的颜色即可
145+
```typescript jsx
146+
<Icon name="user" color={['#ff0000', 'green']} />
147+
```
148+
颜色组的数量以及排序,需要根据当前图标的信息来确定。您需要进入图标组件中查看并得出结论。
149+
150+
**注意:如果color是字符串而不是数组,那么即使是多色彩图标,也会变成单色图标。**
151+
126152
# 更新图标
127153
当您在iconfont.cn中的图标有变更时,只需更改配置`symbol_url`,然后再次执行`Step 4`即可生成最新的图标组件
128154
```bash

package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
{
22
"name": "react-native-iconfont-cli",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"main": "index.js",
5-
"keywords": ["iconfont", "react-native", "react-native-iconfont", "icon", "icons", "iconfont.cn"],
5+
"keywords": [
6+
"iconfont",
7+
"react-native",
8+
"react-native-iconfont",
9+
"icon",
10+
"icons",
11+
"iconfont.cn"
12+
],
613
"repository": "git@github.com:fwh1990/react-native-iconfont-cli.git",
714
"author": "范文华 <531362022@qq.com>",
815
"license": "MIT",
@@ -21,7 +28,6 @@
2128
"lodash": "^4.17.15",
2229
"minimist": "^1.2.0",
2330
"mkdirp": "^0.5.1",
24-
"prop-types": "^15.7.2",
2531
"tslib": "^1.10.0",
2632
"xml2js": "^0.4.19"
2733
},
@@ -31,7 +37,6 @@
3137
"@types/minimist": "^1.2.0",
3238
"@types/mkdirp": "^0.5.2",
3339
"@types/node": "^12.7.2",
34-
"@types/prop-types": "^15.7.1",
3540
"@types/react": "^16.9.2",
3641
"@types/xml2js": "^0.4.4",
3742
"react": "^16.9.0",

src/libs/generateComponent.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export const generateComponent = (data: XmlData) => {
4646
: iconId;
4747
const componentName = upperFirst(camelCase(iconId));
4848

49-
5049
names.push(iconIdAfterTrim);
5150

5251
for (const domName of Object.keys(item)) {
@@ -71,7 +70,7 @@ export const generateComponent = (data: XmlData) => {
7170
}
7271

7372
imports.push(componentName);
74-
cases += `${whitespace(6)}return <${componentName} size={size} />;\n`;
73+
cases += `${whitespace(6)}return <${componentName} size={size} color={color} />;\n`;
7574

7675
singleFile = getTemplate('SingleIcon' + extension);
7776
singleFile = replaceSize(singleFile, config.default_font_size);
@@ -87,6 +86,13 @@ export const generateComponent = (data: XmlData) => {
8786

8887
fs.writeFileSync(path.join(saveDir, componentName + extension), singleFile);
8988

89+
if (!config.use_typescript) {
90+
let typeDefinitionFile = getTemplate('SingleIcon.d.ts');
91+
92+
typeDefinitionFile = replaceComponentName(typeDefinitionFile, componentName);
93+
fs.writeFileSync(path.join(saveDir, componentName + '.d.ts'), typeDefinitionFile);
94+
}
95+
9096
console.log(`${colors.green('√')} Generated icon "${colors.yellow(iconId)}"`);
9197
});
9298

@@ -101,6 +107,11 @@ export const generateComponent = (data: XmlData) => {
101107
iconFile = replaceNames(iconFile, names);
102108
} else {
103109
iconFile = replaceNamesArray(iconFile, names);
110+
111+
let typeDefinitionFile = getTemplate('Icon.d.ts');
112+
113+
typeDefinitionFile = replaceNames(typeDefinitionFile, names);
114+
fs.writeFileSync(path.join(saveDir, 'Icon.d.ts'), typeDefinitionFile);
104115
}
105116

106117
if (config.generate_mode === GENERATE_MODE.allInOne) {
@@ -120,15 +131,24 @@ const generateCase = (data: XmlData['svg']['symbol'][number], baseIdent: number)
120131
for (const domName of Object.keys(data)) {
121132
let realDomName = DOM_MAP[domName];
122133

123-
if (!realDomName) {
134+
if (domName === '$') {
124135
continue;
125136
}
126137

138+
if (!realDomName) {
139+
console.error(colors.red(`Unable to transform dom "${domName}"`));
140+
process.exit(1);
141+
}
142+
143+
const counter = {
144+
colorIndex: 0,
145+
};
146+
127147
if (data[domName].$) {
128-
template += `${whitespace(baseIdent + 2)}<${realDomName} ${addAttribute(data[domName])} />\n`;
148+
template += `${whitespace(baseIdent + 2)}<${realDomName}${addAttribute(data[domName], counter)} />\n`;
129149
} else if (Array.isArray(data[domName])) {
130150
data[domName].forEach((sub) => {
131-
template += `${whitespace(baseIdent + 2)}<${realDomName} ${addAttribute(sub)} />\n`;
151+
template += `${whitespace(baseIdent + 2)}<${realDomName}${addAttribute(sub, counter)} />\n`;
132152
});
133153
}
134154
}
@@ -138,12 +158,17 @@ const generateCase = (data: XmlData['svg']['symbol'][number], baseIdent: number)
138158
return template;
139159
};
140160

141-
const addAttribute = (sub: XmlData['svg']['symbol'][number]['path'][number]) => {
161+
const addAttribute = (sub: XmlData['svg']['symbol'][number]['path'][number], counter: { colorIndex: number }) => {
142162
let template = '';
143163

144164
if (sub && sub.$) {
145165
for (const attributeName of Object.keys(sub.$)) {
146-
template += ` ${attributeName}="${sub.$[attributeName]}"`;
166+
if (attributeName === 'fill') {
167+
template += ` ${attributeName}={color ? typeof color === 'string' && color || color[${counter.colorIndex}] || '${sub.$[attributeName]}' : '${sub.$[attributeName]}'}`;
168+
counter.colorIndex += 1;
169+
} else {
170+
template += ` ${attributeName}="${sub.$[attributeName]}"`;
171+
}
147172
}
148173
}
149174

src/libs/replace.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { GENERATE_MODE } from './generateMode';
2+
13
export const replaceSize = (content: string, size: number) => {
24
return content.replace(/#size#/g, String(size));
35
};
@@ -45,13 +47,15 @@ export const replaceImports = (content: string, imports: string[]) => {
4547
export const replaceToOneComments = (content: string) => {
4648
return content.replace(/#comments#/g,
4749
'// If you don\'t like lots of icon files in your project,\n' +
48-
'// try to set generate_mode to `all-in-one` in root file `iconfont.json`.\n' +
49-
'// And then regenerate icons by using cli command.');
50+
`// try to set generate_mode to "${GENERATE_MODE.allInOne}" in root file "iconfont.json".\n` +
51+
'// And then regenerate icons by using cli command.'
52+
);
5053
};
5154

5255
export const replaceToDependsComments = (content: string) => {
5356
return content.replace(/#comments#/g,
5457
'// If you don\'t want to make all icons in one file,\n' +
55-
'// try to set generate_mode to `depends-on` in root file `iconfont.json`.\n' +
56-
'// And then regenerate icons by using cli command.');
58+
`// try to set generate_mode to "${GENERATE_MODE.dependsOn}" in root file "iconfont.json".\n` +
59+
'// And then regenerate icons by using cli command.'
60+
);
5761
};

src/templates/Icon.d.ts.template

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { FunctionComponent } from 'react';
2+
3+
interface Props {
4+
size?: number;
5+
color?: string | string[];
6+
name: '#names#';
7+
}
8+
9+
declare const Icon: FunctionComponent<Props>;
10+
11+
export = Icon;

src/templates/Icon.jsx.template

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,18 @@
22
/* eslint-disable */
33

44
import React from 'react';
5-
import { number, oneOf } from 'prop-types';
65
#svgComponents#
76
#imports#
87

98
#comments#
10-
const Icon = ({ size, name }) => {
9+
const Icon = ({ color, name, size }) => {
1110
switch (name) {
1211
#cases#
1312
}
1413

1514
return null;
1615
};
1716

18-
Icon.propTypes = {
19-
size: number,
20-
name: oneOf(#namesArray#),
21-
};
22-
2317
Icon.defaultProps = {
2418
size: #size#,
2519
};

src/templates/Icon.tsx.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import React, { FunctionComponent } from 'react';
77

88
interface Props {
99
size?: number;
10+
color?: string | string[];
1011
name: '#names#';
1112
}
1213

1314
#comments#
14-
const Icon: FunctionComponent<Props> = ({ size, name }) => {
15+
const Icon: FunctionComponent<Props> = ({ color, name, size }) => {
1516
switch (name) {
1617
#cases#
1718
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { FunctionComponent } from 'react';
2+
3+
interface Props {
4+
size?: number;
5+
color?: string | string[];
6+
}
7+
8+
declare const #componentName#: FunctionComponent<Props>;
9+
10+
export = #componentName#;

src/templates/SingleIcon.jsx.template

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,13 @@
22
/* eslint-disable */
33

44
import React from 'react';
5-
import { number } from 'prop-types';
65
#svgComponents#
76

87
#comments#
9-
const #componentName# = ({ size }) => {
8+
const #componentName# = ({ size, color }) => {
109
return (#iconContent# );
1110
};
1211

13-
#componentName#.propTypes = {
14-
size: number,
15-
};
16-
1712
#componentName#.defaultProps = {
1813
size: #size#,
1914
};

src/templates/SingleIcon.tsx.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import React, { FunctionComponent } from 'react';
66

77
interface Props {
88
size?: number;
9+
color?: string | string[];
910
}
1011

1112
#comments#
12-
const #componentName#: FunctionComponent<Props> = ({ size }) => {
13+
const #componentName#: FunctionComponent<Props> = ({ size, color }) => {
1314
return (#iconContent# );
1415
};
1516

0 commit comments

Comments
 (0)