Skip to content

Commit

Permalink
feat(Icon): get svg icon from iconfont, close #1209
Browse files Browse the repository at this point in the history
  • Loading branch information
youluna committed Oct 17, 2019
1 parent d90a739 commit eb23d0b
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 3 deletions.
70 changes: 70 additions & 0 deletions docs/icon/demo/iconfont.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# 使用其他源的图标

- order: 5

直接使用 iconfont 源扩展icon,且不使用定制主题包的方式,支持svg图标

:::lang=en-us
# Extend icon

- order: 5

Extend icon without theme package
:::
---

````jsx
import { Icon } from '@alifd/next';

const sizes = ['xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl'];

const CustomIcon = Icon.createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_1464085_egnk4s8yv2f.js',
});

ReactDOM.render(
<div>
<div className="icon-list">
<CustomIcon type="icon-store"/>
<CustomIcon type="icon-pic"/>
<CustomIcon type="icon-gift"/>
</div>
<br/>
<ul className="icon-sizes">
{sizes.map((size, index) => (
<li key={index}>
<CustomIcon type="icon-pic" size={size} />
<span>{size}</span>
</li>))}
</ul>
</div>, mountNode);
````
````css
.icon-list i {
margin: 0 10px;
}
.icon-sizes {
margin: 0;
padding: 0;
list-style: none;
}

.icon-sizes li {
display: inline-block;
width: 80px;
height: 80px;
}

.icon-sizes i {
display: block;
margin: 12px auto 0 auto;
text-align: center;
}

.icon-sizes span {
display: block;
margin-top: 10px;
text-align: center;
}
````

3 changes: 2 additions & 1 deletion src/core/util/_mixin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@
margin-right: $marginRight;
}

&:before {
&:before,
& .#{$css-prefix}icon-remote {
width: $size;
font-size: $size;
line-height: inherit;
Expand Down
65 changes: 65 additions & 0 deletions src/icon/icon-font.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react';
import cx from 'classnames';
import ConfigProvider from '../config-provider';
import Icon from './index';

const customCache = new Set();

export default function createFromIconfontCN(options = {}) {
const { scriptUrl, extraCommonProps = {} } = options;

/**
* DOM API required.
* Make sure in browser environment.
* The Custom Icon will create a <script/>
* that loads SVG symbols and insert the SVG Element into the document body.
*/
if (
typeof document !== 'undefined' &&
typeof window !== 'undefined' &&
typeof document.createElement === 'function' &&
typeof scriptUrl === 'string' &&
scriptUrl.length &&
!customCache.has(scriptUrl)
) {
const script = document.createElement('script');
script.setAttribute('src', scriptUrl);
script.setAttribute('data-namespace', scriptUrl);
customCache.add(scriptUrl);
document.body.appendChild(script);
}

const Iconfont = props => {
const { type, size, children, prefix = 'next-', ...others } = props;

// component > children > type
let content = null;
if (props.type) {
content = <use xlinkHref={`#${type}`} />;
}
if (children) {
content = children;
}

const classes = cx({
[`${prefix}icon-remote`]: true,
});

return (
<Icon size={size}>
<svg
className={classes}
focusable={false}
{...others}
{...extraCommonProps}
>
{content}
</svg>
</Icon>
);
};

Iconfont.displayName = 'Iconfont';

return ConfigProvider.config(Iconfont);
}
19 changes: 17 additions & 2 deletions src/icon/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import ConfigProvider from '../config-provider';
import createFromIconfontCN from './icon-font';

/**
* Icon
Expand All @@ -14,6 +15,7 @@ class Icon extends Component {
* 指定显示哪种图标
*/
type: PropTypes.string,
children: PropTypes.node,
/**
* 指定图标大小
*/
Expand All @@ -40,7 +42,15 @@ class Icon extends Component {

render() {
/* eslint-disable no-unused-vars*/
const { prefix, type, size, className, rtl, ...other } = this.props;
const {
prefix,
type,
size,
className,
rtl,
children,
...other
} = this.props;

const classes = cx({
[`${prefix}icon`]: true,
Expand All @@ -65,8 +75,13 @@ class Icon extends Component {
other.dir = 'rtl';
}

return <i {...other} className={classes} />;
return (
<i {...other} className={classes}>
{children}
</i>
);
}
}

Icon.createFromIconfontCN = createFromIconfontCN;
export default ConfigProvider.config(Icon);
10 changes: 10 additions & 0 deletions src/icon/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,13 @@
@include icon-size(inherit);
}
}

.#{$icon-prefix} {
&.#{$css-prefix}inherit .#{$css-prefix}icon-remote,
.#{$css-prefix}icon-remote {
width: 1em;
height: 1em;
vertical-align: -.15em;
fill: currentColor;
}
}

0 comments on commit eb23d0b

Please sign in to comment.