From 3bc6495b04dd80ae8ffedea89486acbf80da147f Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Sat, 4 Jul 2020 22:39:13 +0800 Subject: [PATCH] refactor: icon component --- src-next/icon/README.md | 99 ++++++++ src-next/icon/README.zh-CN.md | 106 ++++++++ src-next/icon/demo/index.vue | 229 ++++++++++++++++++ src-next/icon/index.js | 55 +++++ src-next/icon/index.less | 10 + src-next/icon/local.less | 1 + .../test/__snapshots__/index.spec.js.snap | 38 +++ src-next/icon/test/index.spec.js | 65 +++++ vant.config.js | 16 +- 9 files changed, 611 insertions(+), 8 deletions(-) create mode 100644 src-next/icon/README.md create mode 100644 src-next/icon/README.zh-CN.md create mode 100644 src-next/icon/demo/index.vue create mode 100644 src-next/icon/index.js create mode 100644 src-next/icon/index.less create mode 100644 src-next/icon/local.less create mode 100644 src-next/icon/test/__snapshots__/index.spec.js.snap create mode 100644 src-next/icon/test/index.spec.js diff --git a/src-next/icon/README.md b/src-next/icon/README.md new file mode 100644 index 000000000..fac716683 --- /dev/null +++ b/src-next/icon/README.md @@ -0,0 +1,99 @@ +# Icon + +### Install + +```js +import Vue from 'vue'; +import { Icon } from 'vant'; + +Vue.use(Icon); +``` + +## Usage + +### Basic Usage + +Use `name` prop to set icon name or icon URL + +```html + + +``` + +### Show Badge + +Use `dot` prop, a small red dot will be displayed in the upper right corner of the icon. + +Use `badge` prop, the badge will be displayed in the upper right corner of the icon. + +```html + + + +``` + +### Icon Color + +Use `color` prop to set icon color + +```html + + +``` + +### Icon Size + +Use `size` prop to set icon size + +```html + +``` + +### Use local font file + +Icon uses font file in `yzcdn.cn` by default,if you want to use the local font file,please import the following css file. + +```js +import 'vant/lib/icon/local.css'; +``` + +### Add custom iconfont + +```css +@font-face { + font-family: 'my-icon'; + src: url('./my-icon.ttf') format('truetype'); +} + +.my-icon { + font-family: 'my-icon'; +} + +.my-icon-extra::before { + content: '\e626'; +} +``` + +```html + +``` + +## API + +### Props + +| Attribute | Description | Type | Default | +| -------------- | ----------------------- | ------------------ | ---------- | +| name | Icon name or URL | _string_ | `''` | +| dot `v2.2.1` | Whether to show red dot | _boolean_ | `false` | +| badge `v2.5.6` | Content of the badge | _number \| string_ | `''` | +| color | Icon color | _string_ | `inherit` | +| size | Icon size | _number \| string_ | `inherit` | +| class-prefix | ClassName prefix | _string_ | `van-icon` | +| tag | HTML Tag | _string_ | `i` | + +### Events + +| Event | Description | Arguments | +| ----- | ------------------------- | -------------- | +| click | Triggered when click icon | _event: Event_ | diff --git a/src-next/icon/README.zh-CN.md b/src-next/icon/README.zh-CN.md new file mode 100644 index 000000000..794490b64 --- /dev/null +++ b/src-next/icon/README.zh-CN.md @@ -0,0 +1,106 @@ +# Icon 图标 + +### 介绍 + +基于字体的图标集,可以通过 Icon 组件使用,也可以在其他组件中通过`icon`属性引用 + +### 引入 + +```js +import Vue from 'vue'; +import { Icon } from 'vant'; + +Vue.use(Icon); +``` + +## 代码演示 + +### 基础用法 + +`Icon`的`name`属性支持传入图标名称或图片链接,所有可用的图标名称见右侧示例 + +```html + + +``` + +### 徽标提示 + +设置`dot`属性后,会在图标右上角展示一个小红点。设置`badge`属性后,会在图标右上角展示相应的徽标 + +```html + + + +``` + +### 图标颜色 + +`Icon`的`color`属性用来设置图标的颜色 + +```html + + +``` + +### 图标大小 + +`Icon`的`size`属性用来设置图标的尺寸大小,默认单位为`px` + +```html + +``` + +### 使用本地字体文件 + +Icon 组件默认引用有赞 CDN 提供的字体文件,并通过网络下载。如果需要在项目中使用本地字体文件,请引入下面的 CSS 文件,并在项目中配置`url-loader` + +```js +import 'vant/lib/icon/local.css'; +``` + +### 自定义图标 + +如果需要在现有 Icon 的基础上使用更多图标,可以引入第三方 iconfont 对应的字体文件和 CSS 文件,之后就可以在 Icon 组件中直接使用 + +```css +/* 引入第三方或自定义的字体图标样式 */ +@font-face { + font-family: 'my-icon'; + src: url('./my-icon.ttf') format('truetype'); +} + +.my-icon { + font-family: 'my-icon'; +} + +.my-icon-extra::before { + content: '\e626'; +} +``` + +```html + + +``` + +## API + +### Props + +| 参数 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| name | 图标名称或图片链接 | _string_ | - | +| dot `v2.2.1` | 是否显示图标右上角小红点 | _boolean_ | `false` | +| badge `v2.5.6` | 图标右上角徽标的内容 | _number \| string_ | - | +| info | 图标右上角徽标的内容(已废弃,请使用 badge 属性) | _number \| string_ | - | +| color | 图标颜色 | _string_ | `inherit` | +| size | 图标大小,如 `20px` `2em`,默认单位为`px` | _number \| string_ | `inherit` | +| class-prefix | 类名前缀,用于使用自定义图标 | _string_ | `van-icon` | +| tag | HTML 标签 | _string_ | `i` | + +### Events + +| 事件名 | 说明 | 回调参数 | +| ------ | -------------- | -------------- | +| click | 点击图标时触发 | _event: Event_ | diff --git a/src-next/icon/demo/index.vue b/src-next/icon/demo/index.vue new file mode 100644 index 000000000..65fde9596 --- /dev/null +++ b/src-next/icon/demo/index.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/src-next/icon/index.js b/src-next/icon/index.js new file mode 100644 index 000000000..0feda2433 --- /dev/null +++ b/src-next/icon/index.js @@ -0,0 +1,55 @@ +// Utils +import { addUnit, isDef } from '../../src/utils'; +import { createNamespace } from '../utils/create'; + +// Components +import Info from '../info'; + +const [createComponent, bem] = createNamespace('icon'); + +function isImage(name) { + return name ? name.indexOf('/') !== -1 : false; +} + +export default createComponent({ + props: { + dot: Boolean, + name: String, + size: [Number, String], + badge: [Number, String], + color: String, + tag: { + type: String, + default: 'i', + }, + classPrefix: { + type: String, + default: bem(), + }, + }, + + render() { + const { name } = this; + const imageIcon = isImage(name); + + return ( + + {/* {slots.default && slots.default()} */} + {imageIcon && } + + + ); + } +}); diff --git a/src-next/icon/index.less b/src-next/icon/index.less new file mode 100644 index 000000000..f1b78f967 --- /dev/null +++ b/src-next/icon/index.less @@ -0,0 +1,10 @@ +@import '../style/var'; +@import '~@vant/icons/src/index.less'; + +.van-icon { + &__image { + width: 1em; + height: 1em; + object-fit: contain; + } +} diff --git a/src-next/icon/local.less b/src-next/icon/local.less new file mode 100644 index 000000000..8232ecf08 --- /dev/null +++ b/src-next/icon/local.less @@ -0,0 +1 @@ +@import '~@vant/icons/src/encode.less'; diff --git a/src-next/icon/test/__snapshots__/index.spec.js.snap b/src-next/icon/test/__snapshots__/index.spec.js.snap new file mode 100644 index 000000000..54ddf2e50 --- /dev/null +++ b/src-next/icon/test/__snapshots__/index.spec.js.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`dot prop 1`] = ` + +
+
+`; + +exports[`render icon default slot 1`] = ` +Default slot + +`; + +exports[`render icon with builtin icon name 1`] = ` + + +`; + +exports[`render icon with local image 1`] = ` + + +`; + +exports[`render icon with url name 1`] = ` + + +`; + +exports[`size without unit 1`] = ` + + +`; + +exports[`tag prop 1`] = ` +
+ +
+`; diff --git a/src-next/icon/test/index.spec.js b/src-next/icon/test/index.spec.js new file mode 100644 index 000000000..60062101f --- /dev/null +++ b/src-next/icon/test/index.spec.js @@ -0,0 +1,65 @@ +import Icon from '..'; +import { mount } from '../../../test'; + +test('render icon with builtin icon name', () => { + const wrapper = mount(Icon, { + propsData: { + name: 'success', + }, + }); + expect(wrapper).toMatchSnapshot(); +}); + +test('render icon with url name', () => { + const wrapper = mount(Icon, { + propsData: { + name: 'https://img.yzcdn.com/icon.jpg', + }, + }); + expect(wrapper).toMatchSnapshot(); +}); + +test('render icon with local image', () => { + const wrapper = mount(Icon, { + propsData: { + name: '/assets/icon.jpg', + }, + }); + expect(wrapper).toMatchSnapshot(); +}); + +test('render icon default slot', () => { + const wrapper = mount({ + render(h) { + return h(Icon, { props: { name: 'success' } }, ['Default slot']); + }, + }); + expect(wrapper).toMatchSnapshot(); +}); + +test('tag prop', () => { + const wrapper = mount(Icon, { + propsData: { + tag: 'div', + }, + }); + expect(wrapper).toMatchSnapshot(); +}); + +test('dot prop', () => { + const wrapper = mount(Icon, { + propsData: { + dot: true, + }, + }); + expect(wrapper).toMatchSnapshot(); +}); + +test('size without unit', () => { + const wrapper = mount(Icon, { + propsData: { + size: 20, + }, + }); + expect(wrapper).toMatchSnapshot(); +}); diff --git a/vant.config.js b/vant.config.js index 3b8d1daf6..4dacc6028 100644 --- a/vant.config.js +++ b/vant.config.js @@ -86,10 +86,10 @@ module.exports = { // path: 'cell', // title: 'Cell 单元格', // }, - // { - // path: 'icon', - // title: 'Icon 图标', - // }, + { + path: 'icon', + title: 'Icon 图标', + }, // { // path: 'image', // title: 'Image 图片', @@ -433,10 +433,10 @@ module.exports = { // path: 'cell', // title: 'Cell', // }, - // { - // path: 'icon', - // title: 'Icon', - // }, + { + path: 'icon', + title: 'Icon', + }, // { // path: 'image', // title: 'Image',