Skip to content

Commit

Permalink
feat(Icon): support TIcon (#681)
Browse files Browse the repository at this point in the history
  • Loading branch information
anlyyao committed May 22, 2023
1 parent 7eda788 commit 407ac0b
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 27 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"@vueuse/core": "^8.2.5",
"dayjs": "^1.10.7",
"lodash": "^4.17.21",
"tdesign-icons-vue-next": "^0.1.8",
"tdesign-icons-vue-next": "^0.1.11",
"validator": "^13.5.1"
},
"peerDependencies": {
Expand Down
1 change: 1 addition & 0 deletions src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ export { default as Footer } from './footer';
export { default as Empty } from './empty';
export { default as Link } from './link';
export { Form, FormItem } from './form';
export { default as Icon } from './icon';
20 changes: 9 additions & 11 deletions src/icon/demos/enhanced.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
<template>
<div class="t-demo-iconfont">
<div>
<icon name="cps-icon-home-sheep" :url="newSvgUrl" />
<icon name="cps-icon-home-sheep" :url="newSvgUrl" size="medium" />
<icon name="cps-icon-home-sheep" :url="newSvgUrl" size="large" />
<icon name="cps-icon-home-sheep" :url="newSvgUrl" size="25px" />
<icon name="cps-icon-home-sheep" :url="newSvgUrl" size="2em" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" size="medium" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" size="large" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" size="25px" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" size="2em" />
</div>
<br />
<div>
<icon name="cps-icon-home-sheep" :url="newSvgUrl" style="color: red" />
<icon name="cps-icon-home-sheep" :url="newSvgUrl" style="color: green" />
<icon name="cps-icon-home-sheep" :url="newSvgUrl" style="color: orange" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" style="color: red" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" style="color: green" />
<t-icon name="cps-icon-home-sheep" :url="newSvgUrl" style="color: orange" />
<!-- 引入新 Icon 之后,内置 Icon 依旧有效。name 传入图标名称全称。 -->
<icon name="t-icon-home" :url="newSvgUrl" />
<t-icon name="t-icon-home" :url="newSvgUrl" />
</div>
</div>
</template>

<script setup lang="ts">
import { Icon } from 'tdesign-icons-vue-next';
const newSvgUrl = 'https://tdesign.gtimg.com/icon/default-demo/index.js';
</script>
38 changes: 38 additions & 0 deletions src/icon/demos/mobile.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<div class="tdesign-mobile-demo">
<h1 class="title">Icon 图标</h1>
<p class="summary">Icon 作为UI构成中重要的元素,一定程度上影响UI界面整体呈现出的风格。</p>
<tdesign-demo-block title="SVG 全量引入" :padding="true">
<baseDemo />
</tdesign-demo-block>
<tdesign-demo-block title="SVG 按需引入" :padding="true">
<single />
</tdesign-demo-block>
<tdesign-demo-block title="SVG 高级用法" :padding="true">
<enhanced />
</tdesign-demo-block>
<tdesign-demo-block title="iconfont 图标" :padding="true">
<iconfont />
</tdesign-demo-block>
<tdesign-demo-block title="iconfont 高级用法" :padding="true">
<iconfontEnhanced />
</tdesign-demo-block>
</div>
</template>

<script lang="ts" setup>
import baseDemo from './base.vue';
import enhanced from './enhanced.vue';
import iconfontEnhanced from './iconfont-enhanced.vue';
import iconfont from './iconfont.vue';
import single from './single.vue';
</script>

<style lang="less">
.t-demo-iconfont {
.t-icon,
.cps-icon {
margin-right: 24px;
}
}
</style>
33 changes: 33 additions & 0 deletions src/icon/icon-svg-props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable */

/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */

import { TdIconSVGProps } from '../icon/type';
import { PropType } from 'vue';

export default {
/** 是否加载组件库内置图标 */
loadDefaultIcons: {
type: Boolean,
default: true,
},
/** 图标名称 */
name: {
type: String,
default: '',
required: true,
},
/** 图标尺寸,支持 'small', 'medium', 'large','35px', '3em' 等 */
size: {
type: String,
default: undefined,
},
/** 图标地址,地址内容参考[组件内部默认加载图标](https://tdesign.gtimg.com/icon/web/index.js) */
url: {
type: [String, Array] as PropType<TdIconSVGProps['url']>,
},
/** 点击时触发 */
onClick: Function as PropType<TdIconSVGProps['onClick']>,
};
37 changes: 37 additions & 0 deletions src/icon/icon.en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
:: BASE_DOC ::

## API
### IconSVG Props

name | type | default | description | required
-- | -- | -- | -- | --
loadDefaultIcons | Boolean | true | \- | N
name | String | - | required | Y
size | String | undefined | \- | N
style | String | - | html attribute | N
url | String / Array | - | Typescript:`string \| Array<string>` | N
onClick | Function | | Typescript:`(context: { e: MouseEvent }) => void`<br/> | N

### IconSVG Events

name | params | description
-- | -- | --
click | `(context: { e: MouseEvent })` | \-

### Iconfont Props

name | type | default | description | required
-- | -- | -- | -- | --
loadDefaultIcons | Boolean | true | \- | N
name | String | - | required | Y
size | String | undefined | \- | N
style | String | - | html attribute | N
tag | String | i | \- | N
url | String / Array | - | Typescript:`string \| Array<string>` | N
onClick | Function | | Typescript:`(context: { e: MouseEvent }) => void`<br/> | N

### Iconfont Events

name | params | description
-- | -- | --
click | `(context: { e: MouseEvent })` | \-
70 changes: 58 additions & 12 deletions src/icon/icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@

### 安装独立 Icon 包

图标相对其他基础组件较为独立,所以作为一个独立的 `npm` 包做发布管理。如果项目中直接使用,请安装 `tdesign-icons-vue-next`
图标相对其他基础组件较为独立,所以作为一个独立的 `npm` 包做发布管理。如果项目中直接使用,请安装 `tdesign-icons-vue-next` 同时 `tdesign-mobile-vue` 也内置了 `icon`, 支持直接通过 `t-icon` 来使用。

### SVG 全量引入

图标尺寸单位支持多种, 'small', 'medium', 'large', '35px', '3em' 等。
图标颜色使用 CSS 控制,如:style="color: red",或者 style="fill: red"。
点击右侧导航「全部图标」即可查看组件库全部图标。

::: demo demos/base
:::
{{ base }}

### SVG 按需引入

图标可以按需引入单个 SVG 图标。组件开发内部使用到 Icon 时,均按需引入 SVG 图标。

::: demo demos/single
:::
{{ single }}

### SVG 高级用法

Expand All @@ -28,15 +26,13 @@

组件会引入默认的 SVG 图标,如果希望禁止组件加载默认的 SVG 图标,将 `loadDefaultIcons` 置为 false 即可。

::: demo demos/enhanced
:::
{{ enhanced }}

### iconfont 图标

使用 Iconfont 图标需要单独引入 Iconfont 图标组件
使用 Iconfont 图标需要单独引入 Iconfont 图标组件

::: demo demos/iconfont
:::
{{ iconfont }}

### iconfont 高级用法

Expand All @@ -46,9 +42,59 @@

组件会引入默认的 iconfont 图标,如果希望禁止组件加载默认的 iconfont 图标,将 `loadDefaultIcons` 置为 false 即可。

::: demo demos/iconfont-enhanced
:::
{{ iconfont-enhanced }}


### FAQ

#### 如何获取全部图标的名称列表?

可以通过`import { manifest } from 'tdesign-icons-vue-next'` 获取全部图标的名称列表。

### t-icon、iconfont和icon使用时都会发起网络请求,我的项目是无网络场景,如何使用?

首先明确`t-icon``iconfont``icon`三者的关系。如上面的示例所示,`iconfont``icon`都是从icon独立包中引入,而`t-icon`只是为了方便用户习惯,对`icon`的一个简单封装。

`iconfont`需要加载图标的字体资源,而`icon`需要加载图标的svgsprite资源,这些资源都是相对来说比较大的,所以没有直接放在包里(当然不排除未来会做改动),所以会发起网络请求。

所以如果你的项目是无网络场景,请使用按需加载的图标,如`<t-icon name="add" />`请改为`<AddIcon />`

### 全部图标

<td-icons-view />

## API
### IconSVG Props

名称 | 类型 | 默认值 | 说明 | 必传
-- | -- | -- | -- | --
loadDefaultIcons | Boolean | true | 是否加载组件库内置图标 | N
name | String | - | 必需。图标名称 | Y
size | String | undefined | 图标尺寸,支持 'small', 'medium', 'large','35px', '3em' 等 | N
style | String | - | HTML 原生属性。可用于设置图标颜色,如:style=\"color: red\" | N
url | String / Array | - | 图标地址,地址内容参考[组件内部默认加载图标](https://tdesign.gtimg.com/icon/web/index.js)。TS 类型:`string \| Array<string>` | N
onClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>点击时触发 | N

### IconSVG Events

名称 | 参数 | 描述
-- | -- | --
click | `(context: { e: MouseEvent })` | 点击时触发

### Iconfont Props

名称 | 类型 | 默认值 | 说明 | 必传
-- | -- | -- | -- | --
loadDefaultIcons | Boolean | true | 是否加载组件库内置图标 | N
name | String | - | 必需。图标名称 | Y
size | String | undefined | 图标尺寸,支持 'small', 'medium', 'large','35px', '3em' 等 | N
style | String | - | HTML 原生属性。可用于设置图标颜色,如:style=\"color: red\" | N
tag | String | i | 图标 DOM 元素,可选值:i/span/div/... | N
url | String / Array | - | 图标地址,地址内容参考[组件内部默认加载图标](https://tdesign.gtimg.com/icon/web/index.css)。也可以在 index.html 中引入图标地址。TS 类型:`string \| Array<string>` | N
onClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>点击时触发 | N

### Iconfont Events

名称 | 参数 | 描述
-- | -- | --
click | `(context: { e: MouseEvent })` | 点击时触发
38 changes: 38 additions & 0 deletions src/icon/iconfont-props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable */

/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */

import { TdIconfontProps } from '../icon/type';
import { PropType } from 'vue';

export default {
/** 是否加载组件库内置图标 */
loadDefaultIcons: {
type: Boolean,
default: true,
},
/** 图标名称 */
name: {
type: String,
default: '',
required: true,
},
/** 图标尺寸,支持 'small', 'medium', 'large','35px', '3em' 等 */
size: {
type: String,
default: undefined,
},
/** 图标 DOM 元素,可选值:i/span/div/... */
tag: {
type: String,
default: 'i',
},
/** 图标地址,地址内容参考[组件内部默认加载图标](https://tdesign.gtimg.com/icon/web/index.css)。也可以在 index.html 中引入图标地址 */
url: {
type: [String, Array] as PropType<TdIconfontProps['url']>,
},
/** 点击时触发 */
onClick: Function as PropType<TdIconfontProps['onClick']>,
};
5 changes: 5 additions & 0 deletions src/icon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Icon as _Icon } from 'tdesign-icons-vue-next';
import { withInstall, WithInstallType } from '../shared';

export const Icon: WithInstallType<typeof _Icon> = withInstall(_Icon, 'TIcon');
export default Icon;
60 changes: 60 additions & 0 deletions src/icon/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* eslint-disable */

/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */

export interface TdIconfontProps {
/**
* 是否加载组件库内置图标
* @default true
*/
loadDefaultIcons?: boolean;
/**
* 图标名称
* @default ''
*/
name: string;
/**
* 图标尺寸,支持 'small', 'medium', 'large','35px', '3em' 等
*/
size?: string;
/**
* 图标 DOM 元素,可选值:i/span/div/...
* @default i
*/
tag?: string;
/**
* 图标地址,地址内容参考[组件内部默认加载图标](https://tdesign.gtimg.com/icon/web/index.css)。也可以在 index.html 中引入图标地址
*/
url?: string | Array<string>;
/**
* 点击时触发
*/
onClick?: (context: { e: MouseEvent }) => void;
}

export interface TdIconSVGProps {
/**
* 是否加载组件库内置图标
* @default true
*/
loadDefaultIcons?: boolean;
/**
* 图标名称
* @default ''
*/
name: string;
/**
* 图标尺寸,支持 'small', 'medium', 'large','35px', '3em' 等
*/
size?: string;
/**
* 图标地址,地址内容参考[组件内部默认加载图标](https://tdesign.gtimg.com/icon/web/index.js)
*/
url?: string | Array<string>;
/**
* 点击时触发
*/
onClick?: (context: { e: MouseEvent }) => void;
}
4 changes: 2 additions & 2 deletions src/shared/component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { App, Plugin, getCurrentInstance } from 'vue';

export type WithInstallType<T> = T & Plugin;
export const withInstall = <T>(comp: T): T & Plugin => {
export const withInstall = <T>(comp: T, alias?: string): T & Plugin => {
const c = comp as any;

c.install = (app: App, name?: string) => {
const defaultName = c.name;
app.component(name || defaultName, comp);
app.component(alias || name || defaultName, comp);
};

return c as T & Plugin;
Expand Down

0 comments on commit 407ac0b

Please sign in to comment.