feat: migrate Search component

This commit is contained in:
chenjiahan 2020-08-16 15:08:28 +08:00
parent 322db54c77
commit 735acabcec
4 changed files with 124 additions and 157 deletions

View File

@ -54,4 +54,5 @@ module.exports = [
'datetime-picker', 'datetime-picker',
'number-keyboard', 'number-keyboard',
'password-input', 'password-input',
'search',
]; ];

115
src/search/index.js Normal file
View File

@ -0,0 +1,115 @@
// Utils
import { createNamespace } from '../utils';
import { preventDefault } from '../utils/dom/event';
// Components
import Field from '../field';
const [createComponent, bem, t] = createNamespace('search');
export default createComponent({
inheritAttrs: false,
props: {
label: String,
rightIcon: String,
modelValue: String,
actionText: String,
background: String,
showAction: Boolean,
clearTrigger: String,
shape: {
type: String,
default: 'square',
},
clearable: {
type: Boolean,
default: true,
},
leftIcon: {
type: String,
default: 'search',
},
},
emits: ['search', 'cancel', 'keypress'],
setup(props, { emit, slots }) {
return function () {
function Label() {
if (slots.label || props.label) {
return (
<div class={bem('label')}>
{slots.label ? slots.label() : props.label}
</div>
);
}
}
function Action() {
if (!props.showAction) {
return;
}
function onCancel() {
if (slots.action) {
return;
}
emit('update:modelValue', '');
emit('cancel');
}
return (
<div
class={bem('action')}
role="button"
tabindex="0"
onClick={onCancel}
>
{slots.action ? slots.action() : props.actionText || t('cancel')}
</div>
);
}
const fieldData = {
...this.$attrs,
onKeypress(event) {
// press enter
if (event.keyCode === 13) {
preventDefault(event);
emit('search', props.modelValue);
}
emit('keypress', event);
},
};
return (
<div
class={bem({ 'show-action': props.showAction })}
style={{ background: props.background }}
>
{slots.left?.()}
<div class={bem('content', props.shape)}>
{Label()}
<Field
type="search"
border={false}
leftIcon={props.leftIcon}
rightIcon={props.rightIcon}
clearable={props.clearable}
modelValue={props.modelValue}
clearTrigger={props.clearTrigger}
scopedSlots={{
'left-icon': slots['left-icon'],
'right-icon': slots['right-icon'],
}}
{...fieldData}
/>
</div>
{Action()}
</div>
);
};
},
});

View File

@ -1,149 +0,0 @@
// Utils
import { createNamespace } from '../utils';
import { inherit, emit } from '../utils/functional';
import { preventDefault } from '../utils/dom/event';
// Components
import Field from '../field';
// Types
import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots, ScopedSlot } from '../utils/types';
const [createComponent, bem, t] = createNamespace('search');
export type SearchProps = {
shape: 'sqaure' | 'round';
value?: string;
label?: string;
leftIcon: string;
rightIcon?: string;
clearable: boolean;
background: string;
actionText?: string;
showAction?: boolean;
clearTrigger?: string;
};
export type SearchSlots = DefaultSlots & {
left?: ScopedSlot;
label?: ScopedSlot;
action?: ScopedSlot;
'left-icon'?: ScopedSlot;
'right-icon'?: ScopedSlot;
};
export type SearchEvents = {
onCancel?(): void;
onInput?(value: string): void;
onSearch?(value: string): void;
onKeypress?(event: KeyboardEvent): void;
};
function Search(
h: CreateElement,
props: SearchProps,
slots: SearchSlots,
ctx: RenderContext<SearchProps>
) {
function Label() {
if (slots.label || props.label) {
return (
<div class={bem('label')}>
{slots.label ? slots.label() : props.label}
</div>
);
}
}
function Action() {
if (!props.showAction) {
return;
}
function onCancel() {
if (slots.action) {
return;
}
emit(ctx, 'input', '');
emit(ctx, 'cancel');
}
return (
<div class={bem('action')} role="button" tabindex="0" onClick={onCancel}>
{slots.action ? slots.action() : props.actionText || t('cancel')}
</div>
);
}
const fieldData = {
attrs: ctx.data.attrs,
on: {
...ctx.listeners,
keypress(event: KeyboardEvent) {
// press enter
if (event.keyCode === 13) {
preventDefault(event);
emit(ctx, 'search', props.value);
}
emit(ctx, 'keypress', event);
},
},
};
const inheritData = inherit(ctx);
inheritData.attrs = undefined;
return (
<div
class={bem({ 'show-action': props.showAction })}
style={{ background: props.background }}
{...inheritData}
>
{slots.left?.()}
<div class={bem('content', props.shape)}>
{Label()}
<Field
type="search"
border={false}
value={props.value}
leftIcon={props.leftIcon}
rightIcon={props.rightIcon}
clearable={props.clearable}
clearTrigger={props.clearTrigger}
scopedSlots={{
'left-icon': slots['left-icon'],
'right-icon': slots['right-icon'],
}}
{...fieldData}
/>
</div>
{Action()}
</div>
);
}
Search.props = {
value: String,
label: String,
rightIcon: String,
actionText: String,
background: String,
showAction: Boolean,
clearTrigger: String,
shape: {
type: String,
default: 'square',
},
clearable: {
type: Boolean,
default: true,
},
leftIcon: {
type: String,
default: 'search',
},
};
export default createComponent<SearchProps, SearchEvents, SearchSlots>(Search);

View File

@ -155,10 +155,10 @@ module.exports = {
path: 'rate', path: 'rate',
title: 'Rate 评分', title: 'Rate 评分',
}, },
// { {
// path: 'search', path: 'search',
// title: 'Search 搜索', title: 'Search 搜索',
// }, },
{ {
path: 'slider', path: 'slider',
title: 'Slider 滑块', title: 'Slider 滑块',
@ -489,10 +489,10 @@ module.exports = {
path: 'rate', path: 'rate',
title: 'Rate', title: 'Rate',
}, },
// { {
// path: 'search', path: 'search',
// title: 'Search', title: 'Search',
// }, },
{ {
path: 'slider', path: 'slider',
title: 'Slider', title: 'Slider',