feat(Button): add icon-position prop (#7174)

This commit is contained in:
neverland 2020-09-12 20:53:51 +08:00 committed by GitHub
parent 9750984d78
commit 2c38469591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 20 deletions

View File

@ -111,6 +111,7 @@ Vue.use(Button);
| color | Color, support linear-gradient | _string_ | - | | color | Color, support linear-gradient | _string_ | - |
| icon | Left Icon | _string_ | - | | icon | Left Icon | _string_ | - |
| icon-prefix `v2.6.0` | Icon className prefix | _string_ | `van-icon` | | icon-prefix `v2.6.0` | Icon className prefix | _string_ | `van-icon` |
| icon-position `v2.10.7` | Icon position, can be set to `right` | `left` |
| tag | HTML Tag | _string_ | `button` | | tag | HTML Tag | _string_ | `button` |
| native-type | Native Type Attribute | _string_ | `''` | | native-type | Native Type Attribute | _string_ | `''` |
| plain | Whether to be plain button | _boolean_ | `false` | | plain | Whether to be plain button | _boolean_ | `false` |

View File

@ -133,7 +133,8 @@ Vue.use(Button);
| color | 按钮颜色,支持传入`linear-gradient`渐变色 | _string_ | - | | color | 按钮颜色,支持传入`linear-gradient`渐变色 | _string_ | - |
| icon | 左侧[图标名称](#/zh-CN/icon)或图片链接 | _string_ | - | | icon | 左侧[图标名称](#/zh-CN/icon)或图片链接 | _string_ | - |
| icon-prefix `v2.6.0` | 图标类名前缀,同 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` | | icon-prefix `v2.6.0` | 图标类名前缀,同 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` |
| tag | 根节点的 HTML 标签 | _string_ | `button` | | icon-position `v2.10.7` | 图标展示位置,可选值为 `right` | `left` |
| tag | 按钮根节点的 HTML 标签 | _string_ | `button` |
| native-type | 原生 button 标签的 type 属性 | _string_ | - | | native-type | 原生 button 标签的 type 属性 | _string_ | - |
| block | 是否为块级元素 | _boolean_ | `false` | | block | 是否为块级元素 | _boolean_ | `false` |
| plain | 是否为朴素按钮 | _boolean_ | `false` | | plain | 是否为朴素按钮 | _boolean_ | `false` |

View File

@ -160,8 +160,10 @@
} }
&__icon + &__text, &__icon + &__text,
&__loading + &__text { &__loading + &__text,
margin-left: 5px; &__text + &__icon,
&__text + &__loading {
margin-left: @padding-base;
} }
&--hairline { &--hairline {

View File

@ -35,6 +35,7 @@ export type ButtonProps = RouteProps & {
loadingSize: string; loadingSize: string;
loadingType?: LoadingType; loadingType?: LoadingType;
loadingText?: string; loadingText?: string;
iconPosition: 'left' | 'right';
}; };
export type ButtonEvents = { export type ButtonEvents = {
@ -63,6 +64,7 @@ function Button(
loading, loading,
hairline, hairline,
loadingText, loadingText,
iconPosition,
} = props; } = props;
const style: Record<string, string | number> = {}; const style: Record<string, string | number> = {};
@ -111,12 +113,9 @@ function Button(
{ [BORDER_SURROUND]: hairline }, { [BORDER_SURROUND]: hairline },
]; ];
function Content() { function renderIcon() {
const content = [];
if (loading) { if (loading) {
content.push( return slots.loading ? (
slots.loading ? (
slots.loading() slots.loading()
) : ( ) : (
<Loading <Loading
@ -125,13 +124,22 @@ function Button(
type={props.loadingType} type={props.loadingType}
color="currentColor" color="currentColor"
/> />
)
); );
} else if (icon) { }
content.push(
if (icon) {
return (
<Icon name={icon} class={bem('icon')} classPrefix={props.iconPrefix} /> <Icon name={icon} class={bem('icon')} classPrefix={props.iconPrefix} />
); );
} }
}
function renderContent() {
const content = [];
if (iconPosition === 'left') {
content.push(renderIcon());
}
let text; let text;
if (loading) { if (loading) {
@ -144,6 +152,10 @@ function Button(
content.push(<span class={bem('text')}>{text}</span>); content.push(<span class={bem('text')}>{text}</span>);
} }
if (iconPosition === 'right') {
content.push(renderIcon());
}
return content; return content;
} }
@ -157,7 +169,7 @@ function Button(
onTouchstart={onTouchstart} onTouchstart={onTouchstart}
{...inherit(ctx)} {...inherit(ctx)}
> >
<div class={bem('content')}>{Content()}</div> <div class={bem('content')}>{renderContent()}</div>
</tag> </tag>
); );
} }
@ -194,6 +206,10 @@ Button.props = {
type: String, type: String,
default: '20px', default: '20px',
}, },
iconPosition: {
type: String,
default: 'left',
},
}; };
export default createComponent<ButtonProps, ButtonEvents, ButttonSlots>(Button); export default createComponent<ButtonProps, ButtonEvents, ButttonSlots>(Button);

View File

@ -1,5 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`icon-position prop 1`] = `
<button class="van-button van-button--default van-button--normal">
<div class="van-button__content"><i class="van-icon van-icon-plus van-button__icon">
<!----></i></div>
</button>
`;
exports[`icon-prefix prop 1`] = ` exports[`icon-prefix prop 1`] = `
<button class="van-button van-button--default van-button--normal"> <button class="van-button van-button--default van-button--normal">
<div class="van-button__content"><i class="my-icon my-icon-success van-button__icon"> <div class="van-button__content"><i class="my-icon my-icon-success van-button__icon">

View File

@ -11,6 +11,16 @@ test('loading-size prop', () => {
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
test('icon-position prop', () => {
const wrapper = mount(Button, {
propsData: {
icon: 'plus',
iconPosition: 'right',
},
});
expect(wrapper).toMatchSnapshot();
});
test('click event', () => { test('click event', () => {
const onClick = jest.fn(); const onClick = jest.fn();
const wrapper = mount(Button, { const wrapper = mount(Button, {