# Icon 图标

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/icon/freepass)
- 平台：PC
- 维护者：揭志胜
- 设计稿：http://pd.e-cology.com.cn/pd/E10/interface/e10xiaoguotu/PC/E10zjys/#s40
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[Icon]

## 代码演示

### Icon 组件使用须知

```jsx
import React, { PureComponent } from 'react';
import { PhotoView, PhotoViewData } from '@weapp/ui';
import image from '../image/14431680147154_.pic.jpg';

const images: PhotoViewData[] = [
  {
    id: '1',
    src: image,
  }
]

class Doc extends PureComponent<any, any> {
  state = {
    visible: false
  }
  preview = () => {
    this.setState({ visible: true })
  }
  onClose = () => {
    this.setState({ visible: false })
  }

  render() {
    const { visible } = this.state;
    return (
      <div>
        <span style={{ color: 'red', fontSize: '16px', lineHeight: '20px' }}>注意！！！组件内图标已迁移至图标库，demo 中图标已不再继续更新，查找图标请前往图标库（地址：<a href='https://weapp.eteams.cn/iconfont' target='_blank' rel="noreferrer">weapp.eteams.cn/iconfont</a>）
        </span>

        <h3>本地开发使用:</h3>
        本地开发使用的 <strong>Icon</strong> 组件，依赖 <strong> weapp-iconfont （0701基线发布）</strong>，如图标未显示，请执行 <strong> yarn upwedep </strong> 更新依赖，或将 iconfont 相关资源代理到 test 环境。

        <h3>图标更新:</h3>
        0701 基线更新后，设计当日上传的图标会在第二天更新到 test-mySql 和 release-mySql 环境，如果第二天其他环境没有找到相应图标，请手动构建下对应环境的
        weapp-iconfont 的 develop 或 releasew 分支。
        <br/>
        <br/>
        如需紧急使用当日上传的图标，请联系 <strong>揭志胜</strong> 手动同步。
        <br/>
        <br/>
        0701 基线更新后，beta 环境/自用系统/正式环境的图标随基线发布，如有图标需要紧急使用，请联系 <strong>揭志胜</strong> 发hotfix 包。
      </div>
    );
  }
}

export default Doc;
```

### 搜索图标

搜索图标

```jsx
import React from 'react';
import { Icon, Dialog, constants, Button, Input } from '@weapp/ui';
// import datas from '../app.json';
import * as allIcon from '../IconNames';
import IconCommonDemo from './common';

const { IconLoader } = Icon;

let icons: any = allIcon
let iconNames: any = []

for (const key in icons) {
  iconNames.push(...icons[key])
}

let datas: string[] = iconNames;

// console.log(iconNames.length)

//#region 图标名称
const { uiPcClsPrefix } = constants;

//#endregion
const { message } = Dialog;
const prefixCls = `${uiPcClsPrefix}-demo-icon`;

let wrapperStyle = {
  display: 'flex',
  justifyContent: 'start'
}
let buttonWidth = { minWidth: 100 }
export default class IconDemo extends React.Component {

  timer: any;

  libIcons: string[] = [];

  state = {
    icon: 'Icon-download02',
    isShowIconName: false,
    datas: [],
    iconName: '',
    inputValue: '',
    isSearch: false,
    color: 'red'
  }

  componentDidMount(): void {
    IconLoader.loadIconMap().then(res => {
      this.libIcons = Object.keys(res);
    }).catch((err) => {
      console.error(err);
      message({ type: 'error', content: '图标库加载失败！' })
    })
  }

  inputChange = (value: any) => {
    this.setState({ inputValue: value, isSearch: false })
  }

  handleSearch = () => {
    if (!this.state.inputValue) {
      this.setState({ datas: [], isSearch: true })
    } else {
      let newData = datas.concat(this.libIcons).filter((val: any) => (val as string).toLowerCase().indexOf(this.state.inputValue.toLowerCase()) !== -1)
      this.setState({ datas: Array.from(new Set(newData)), isSearch: true })
    }
  }

  onKeyDown = (e: any) => {
    //兼容浏览器的事件
    let theEvent = e || window.event;
    //兼容各浏览器的键盘事件
    let keyCode = theEvent.keyCode || theEvent.which || theEvent.charCode;
    if (keyCode === 13) {
      this.handleSearch();
    }
  }

  onclick = () => {
    if (this.state.color === 'red') {
      this.setState({ color: 'blue' })
    } else {
      this.setState({ color: 'red' })
    }
  }

  onChangeIconName = (value: any) => {
    this.setState({ iconName: value.toString() })
  }

  render() {
    const { datas, isSearch, inputValue, iconName } = this.state;
    return (
      <div className={prefixCls}>
        <div style={wrapperStyle}>
          <Input onChange={this.inputChange} onKeyDown={this.onKeyDown} placeholder={'输入图标名称，点击搜索按钮或回车进行搜索'} />
          <Button type='primary' onClick={this.handleSearch} style={buttonWidth}>搜索</Button>
        </div>
        <IconCommonDemo iconNames={datas} isSearch={isSearch} searchValue={inputValue} />

        <br />
        <h3>临时 demo：测试图标名称大小写不敏感功能</h3>
        <Input value={iconName} onChange={this.onChangeIconName} />
        <Icon name={iconName} />
      </div>
    );
  }
}
```

### 图片图标

通过 url 直接引入图片图标

```jsx
import React from 'react';
import { Icon } from '@weapp/ui';

const imgIcons = [
  { id: '1', url: '/build/ui/demo/assets/icon/img-icon-1.jpeg', },
  { id: '2', url: '/build/ui/demo/assets/icon/img-icon-2.jpg', },
  { id: '3', url: '/build/ui/demo/assets/icon/img-icon-3.jpeg', },
]

export default class Demo extends React.Component {
  render() {
    return (
      <div>
        {imgIcons.map(img => (
          <span key={img.id} style={{ marginRight: 8 }}>
            <Icon size='md' url={img.url} />
          </span>
        ))}
      </div>
    );
  }
}
```

### getSvgIconDom【测试版本】

通过 getSvgIconDom 方法获取 svg dom

```jsx
import React from 'react';
import { Icon, Input, Button, Dialog } from '@weapp/ui';
import { getHash } from '../../../../utils';

const defaultValue = 'Icon-My-Personnel-o';

export default class Demo extends React.Component {
  random = getHash();
  state = {
    value: defaultValue,
  }
  getIconSvgDom = () => {
    Icon.getSvgIconDom(this.state.value)
      .then(res => {
        const svgBox = document.getElementById(`render-svg-box_${this.random}`);
        const dom = res.svgDom;
        console.error(dom);
        // dom 即是一个 svg dom
        if (svgBox) svgBox.appendChild(dom);
      })
      .catch(err => {
        Dialog.message({
          type: 'error',
          content: err
        })
        console.error(err)
      })
  }

  handleChange = (value: React.ReactText) => {
    this.setState({ value })
  }

  rest = () => {
    this.setState({ value: defaultValue }, () => {
      const svgBox = document.getElementById(`render-svg-box_${this.random}`);
      if (svgBox) svgBox.innerHTML = '';
    })
  }

  render() {
    const { value } = this.state;
    return (
      <div>
        <div>
          <Input value={value} onChange={this.handleChange} />
        </div>
        <div>
          <Button onClick={this.getIconSvgDom}>获取 Icon: {value} 的 svg dom</Button>
          <Button onClick={this.rest}>重置</Button>
        </div>
        <div id={`render-svg-box_${this.random}`}></div>
      </div>
    );
  }
}
```

## API

### 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| size | 图标大小 | `xxs`(12) \| `xs`(14) \| `s`(16) \| `sm`(18) \| `md`(20) \| `lg`(22) |  |  |
| name | SVG 图标名称 | IconNames |  |  |
| component | 自定义 svg，支持 svg 和 use | React.ReactNode |  |  |
| url | image url | string |  |  |
| moduleColor | 模块图标取色范围 | `yellow`(#ff8400) \| `blue`(#0067ff) \| `indigo`(#218af8) \| `green`(#00a643) \| `red`(#ff666a) |  |  |
| fromIconfontCN | 通过这个参数可以设置使用 iconfont 的图标 |  |  |  |
