Comments (22)
各个社区在开发时,可以先构建一次@ant-design/icons-svg
(未发包),该包位于packages/icons-svg
。之后可使用 lerna link
到对应社区的组件包进行开发。
开发思路可以分为两个阶段:
- 组件文件生成阶段:利用
@ant-design/icons-svg
中的抽象节点(asn, Abstract Node)。生成对应的ReactElement或者VNode。(Angular社区可以使用helpers中的renderIconDefinitionToSVGElement
渲染工具函数来渲染)。之后生成组件输出到src
目录。当然,也可以利用旧的构建好的组件重新编写一个函数组件即可。注意旧的组件就不再需要内部的图标集合(即可以删去) - 构建阶段:使用构建工具或编译工具 babel/tsc 或者社区打包解决方案 father/webpack/rollup等构建。
思路示例:
Angular (仅供参考)
// generate.ts
// $ node --require ts-node/register/transpile-only generate.ts
import * as allIconDefs from '@ant-design/icons-svg';
import { renderIconDefinitionToSVGElement } from '@ant-design/icons-svg/es/helpers';
import { IconDefinition } from '@ant-design/icons-svg/es/types';
import * as path from 'path';
import { writeFile, emptyDir } from 'fs-extra';
export interface IconDefinitionNg extends Omit<IconDefinition, 'icon'> {
identifier: string;
icon: string;
}
export function walk<T>(fn: (iconDef: IconDefinitionNg) => Promise<T>) {
return Promise.all(
Object.keys(allIconDefs).map((identifier) => {
const iconDef = (allIconDefs as { [id: string]: IconDefinition })[
identifier
];
const { name, theme } = iconDef;
const inlineSvg = renderIconDefinitionToSVGElement(iconDef, {
// the options only affect the two-tone icons.
placeholders: { primaryColor: '#333', secondaryColor: '#E6E6E6' }
});
return fn({ name, theme, icon: inlineSvg, identifier });
})
);
}
(async () => {
await emptyDir(path.resolve(__dirname, `../lib/icons/defs`));
const publicApiRows = await walk(async ({ identifier, ...iconDef }) => {
await writeFile(
path.resolve(__dirname, `../lib/icons/defs/${identifier}.ts`),
`export const ${identifier} = ${JSON.stringify(iconDef)};`,
'utf8'
);
return `export { ${identifier} } from './defs/${identifier}';`;
});
await writeFile(
path.resolve(__dirname, `../lib/icons/public_api.ts`),
publicApiRows.join('\n'),
'utf8'
);
})();
React (仅供参考)
// generate.ts
// $ node --require ts-node/register/transpile-only generate.ts
import * as allIconDefs from '@ant-design/icons-svg';
import { IconDefinition } from '@ant-design/icons-svg/es/types';
import * as path from 'path';
import { writeFile, emptyDir } from 'fs-extra';
import { template } from 'lodash';
export interface IconDefinitionWithIdentifier extends IconDefinition {
identifier: string;
}
export function walk<T>(
fn: (iconDef: IconDefinitionWithIdentifier) => Promise<T>
) {
return Promise.all(
Object.keys(allIconDefs).map((identifier) => {
const iconDef = (allIconDefs as { [id: string]: IconDefinition })[
identifier
];
return fn({ identifier, ...iconDef });
})
);
}
(async () => {
await emptyDir(path.resolve(__dirname, `../src/icons`));
const render = template(`
import React from 'react';
import <%= identifier %> from '@ant-design/icons-svg/es/<%= identifier %>';
import AntdIcon, { AntdIconProps } from '../components/AntdIcon';
const <%= _identifier %> = (props: AntdIconProps) => <AntdIcon {...props} icon={<%= identifier %>} />;
export default <%= _identifier %>;
`);
await walk(async ({ identifier }) => {
// It will be better if an react antd icon component has theme suffix.
// or use outline as default theme like this:
const _identifier = identifier
.replace(/Outline$/, '')
.replace(/Fill$/, 'Filled')
.replace(/TwoTone$/, 'TwoTone');
await writeFile(
path.resolve(__dirname, `../src/icons/${_identifier}.ts`),
render({
identifier,
_identifier
}),
'utf8'
);
});
})();
Vue (仅供参考)
// generate.ts
// $ node --require ts-node/register/transpile-only generate.ts
import * as allIconDefs from '@ant-design/icons-svg';
import { IconDefinition } from '@ant-design/icons-svg/es/types';
import * as path from 'path';
import { writeFile, emptyDir } from 'fs-extra';
import { template } from 'lodash';
export interface IconDefinitionWithIdentifier extends IconDefinition {
identifier: string;
}
export function walk<T>(
fn: (iconDef: IconDefinitionWithIdentifier) => Promise<T>
) {
return Promise.all(
Object.keys(allIconDefs).map((identifier) => {
const iconDef = (allIconDefs as { [id: string]: IconDefinition })[
identifier
];
return fn({ identifier, ...iconDef });
})
);
}
(async () => {
await emptyDir(path.resolve(__dirname, `../src/icons`));
const render = template(`
import Vue from 'vue';
import Icon from '../components/Icon';
import <%= identifier %> from '@ant-design/icons-svg/es/<%= identifier %>';
export default Vue.component('<%= kebabCaseIdentifier %>', {
functional: true,
render: (h, { data, children }) => h(Icon, { ...data, type: <%= identifier %> }, children)
});
`);
await walk(async ({ identifier, ...iconDef }) => {
const { name, theme } = iconDef;
await writeFile(
path.resolve(__dirname, `../src/icons/${identifier}.ts`),
render({
identifier,
kebabCaseIdentifier: `${name}-${theme}`
}),
'utf8'
);
});
})();
from ant-design-icons.
确认一下命名风格:
// 以 account-book 为例
// @ant-design/icons-svg/es/asn/AccountBookFilled
var AccountBookFilled = {
"name": "account-book",
"theme": "filled",
"icon": {
"tag": "svg",
"attrs": {
"viewBox": "64 64 896 896",
"focusable": "false"
},
"children": [{
"tag": "path",
"attrs": {
"d": "M880 184..."
}
}]
}
};
// @ant-design/icons-svg/es/asn/AccountBookOutlined
var AccountBookOutlined = {
"name": "account-book",
"theme": "outlined",
"icon": {
"tag": "svg",
"attrs": {
"viewBox": "64 64 896 896",
"focusable": "false"
},
"children": [{
"tag": "path",
"attrs": {
"d": "M880 184..."
}
}]
}
};
// @ant-design/icons-svg/es/asn/AccountBookTwoTone
var AccountBookTwoTone = {
"name": "account-book",
"theme": "twotone",
"icon": function icon(primaryColor, secondaryColor) {
return {
"tag": "svg",
"attrs": {
"viewBox": "64 64 896 896",
"focusable": "false"
},
"children": [{
"tag": "path",
"attrs": {
"d": "M712 304...",
"fill": secondaryColor
}
}, {
"tag": "path",
"attrs": {
"d": "M639.5 414...",
"fill": primaryColor
}
}, {
"tag": "path",
"attrs": {
"d": "M880 18...",
"fill": primaryColor
}
}]
};
}
};
短横线连字形式可以由name + '-' + theme
得到,通常用于Vue
组件名称形式中
account-book-filled
account-book-outlined
account-book-twotone
from ant-design-icons.
icons-react 库已完成对应 更新
from ant-design-icons.
观察了下, 目前使用icons-react
是需要逐个icon引入并且使用
我的做法是一次性把需要用到icon引入进来, 然后通过svg-sprite
形式使用, 使用时候只需要用过<icon name='xxxx'/>
, 不需要多次import icon
刚完成vue版, 不知道是否有其他坑
from ant-design-icons.
@zWingz Vue版本完成了?可以提pr上来
from ant-design-icons.
@HeskeyBaozi 我的修改太少了。 我直接push到v4了..
from ant-design-icons.
之前pr #100
包相关变动
packages/icons
中的包名由 @ant-design/icons-svg
修改为 @ant-design/icons-svg-legacy
。包名 @ant-design/icons-svg
由项目下的目录重写的 packages/icons-svg
继承。
新的 @ant-design/icons-svg
包和原来的版本 ( 4.0.0-alpha.0
和 @ant-design/icons <= 2.1.1
) 相比,有如下改动:
- 不再提供用于存放未处理的图标的
svg
目录 - 不再提供用于全量引入的
dist.js
文件和压缩过的umd.js
文件,全量引入直接用import * as allIcons from '@ant-design/icons-svg'
, 走index.js
即可 - 不再提供用于
tree-shaking
的lib/index.es.js
文件 - 不再提供用于字符串字面量引入用的短横线图标名称的清单
manifest.js
文件 - 提供
es
目录用于tree-shaking
最终用户得到的目录如下:
es
inline-svg # 此为处理后存放的svg图标
lib
package.json
ReadMe.md
这些改动的原则都是倾向于按需引入,保证主入口文件只有图标的导出,使得 import * as allIcons from '@ant-design/icons-svg'
只会导出图标信息。
此PR来源于
#90
@ant-design/icon-kit
这个脚手架已自我废弃
目前图标
为什么
-
不使用
rxjs
响应式编程这类范式强大之处在于对可观察数据的时序性控制和数学上持续性赋值:=
不同流的可组合性。图标生成就是文件系统IO和数据结构转换。显然gulp
及其生态能把这个任务做得更好,rxjs
也可以做但显然其长处并没有发挥出来,且编写无确切规范导致维护性差。 -
速度与维护选择
Before | icon-kit (rxjs) | gulp |
---|---|---|
15.42s | 6.88s | 9.55s |
from ant-design-icons.
赞赞赞
from ant-design-icons.
@HeskeyBaozi 我有个想法就是 icons-svg
这边 theme 也统一改成 Filled/Outlined/TwoTone 避免从 fill/outline/twoTone 转换,这里显得有点没有必要
from ant-design-icons.
@HeskeyBaozi 我有个想法就是
icons-svg
这边 theme 也统一改成 Filled/Outlined/TwoTone 避免从 fill/outline/twoTone 转换,这里显得有点没有必要
这个可以的。做好和其他开发者的沟通工作即可。我会尽快完成。
from ant-design-icons.
@zWingz 欢迎 pr
from ant-design-icons.
目前我开发方案是使用svg-symbol来实现, twotone方案是通过css variable
, 可能兼容性上跟ant-design所要求的有点出入
from ant-design-icons.
icons-vue done
from ant-design-icons.
目前各个社区的进度跟进方面 Vue
社区已经完成了。
关于合并有一些要注意的点:
Vue
之前是合并到master
分支上的,正常情况下合并应该是没有冲突 @tangjinzhou
Angular
和 React Native
方面:
- rn 代码是直接跨包使用
SVG
图标 @BANG88
需要修改路径到 icons-svg/svg
,同时注意主题风格名字的变化 fill
-> filled
,outline
-> outlined
- Angular 方面之前本身是全拷贝4.0之前的构建过程,总体来说这次有修改是构建本身的优化,对于用户来说,图标的变化是最直接的感知。所以应急方案为 路径修改到
icons-svg/svg
@wendellhu95
且注意主题风格名字的变化 fill
-> filled
,outline
-> outlined
from ant-design-icons.
好久没动 卡在 lerna bootstrap 😢
from ant-design-icons.
我这边统计了下图标的变化,主要是新增了图标,以及删除了 typo 错误的图标
https://github.com/vagusX/icons-v4-diff/pull/1/files
from ant-design-icons.
React/React-Native/Vue/Angular各自社区实现对应支持
tree shaking
的图标组件或指令,分支在仓库ant-design-icons下的next-v4
分支
- @ant-design/icons (React) @vagusX #112
- @ant-design/icons-vue (Vue) @tangjinzhou #153
- @ant-design/icons-angular (Angular) @wendzhue
- @ant-design/icons-react-native (React-Native) @BANG88
各自社区支持
tree shaking
的图标组件或指令实现后,即可去掉WIP:
前缀。
同时原来的icons-svg-legacy
可以考虑删除。
之后将next-v4
分支合并到master
分支上。
@wendellhu95 #196 这个 mr 合并了,我理解 ng 的也完成了哈
from ant-design-icons.
from ant-design-icons.
后续 actions:
- 从 master 中切出 legacy 分支
- 将 next-v4 合并到 master
- 发布 @ant-design/[email protected]
- 发布 @ant-design/icons 的对应版本 (react集成包)
后续原稳定分支的修复都在 legacy 上发布和修复
master 分支用来开发新的分支代码
from ant-design-icons.
分支不如叫 legacy
from ant-design-icons.
分支不如叫 legacy
有道理
from ant-design-icons.
@HeskeyBaozi 这个 issue 可以先 close 掉?
from ant-design-icons.
Related Issues (20)
- ant-design-icons在nextjs首页渲染时样式未能预先加载 HOT 1
- May I request INR icon?
- Cannot use import statement outside a module HOT 5
- Console error the icon StartDateOutlined-o does not exist or is not registered
- filled/twitch.svg is wrong size
- @ant-design/icons-vue 4 Months Behind on Latest Icons HOT 1
- Add icon for safari browser
- XFilled 显示异常
- @types/react 18.2.66版本删除了onPointerEnterCapture、onPointerLeaveCapture事件 HOT 6
- @ant-design/[email protected] tsc 失败 HOT 3
- Appstore 的图标命名 HOT 2
- latest tag 指向的是 4.x 版本 HOT 4
- latest tag 再次指向了 4.x 版本 HOT 1
- 无法在 vite 和 remix 中使用 HOT 6
- Regarding the React Natvie bug issue HOT 1
- airplane, hotel icons missing in nz icon
- Cascade Layers support HOT 3
- icons-react 的 createFromIconfontCN 加载远程字体图标文件缺少异步逻辑处理
- 排序图标反了?
- Use `prefixCls` for `updateCss` to allow multiple instances of `IconProvider`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ant-design-icons.