[improvement] rename packages dir to src (#3659)

This commit is contained in:
neverland
2019-06-27 11:25:57 +08:00
committed by GitHub
parent 8489918dca
commit 75c79b7044
619 changed files with 21 additions and 21 deletions
+71
View File
@@ -0,0 +1,71 @@
<template>
<demo-section>
<demo-block :title="$t('basicUsage')">
<van-search
v-model="value"
:placeholder="$t('placeholder')"
/>
</demo-block>
<demo-block :title="$t('title2')">
<form action="/">
<van-search
v-model="value"
:placeholder="$t('placeholder')"
show-action
@search="onSearch"
@cancel="onCancel"
/>
</form>
</demo-block>
<demo-block :title="$t('title3')">
<van-search
v-model="value"
:placeholder="$t('placeholder')"
show-action
shape="round"
:label="$t('label')"
@search="onSearch"
>
<template #action>
<div @click="onSearch">{{ $t('search') }}</div>
</template>
</van-search>
</demo-block>
</demo-section>
</template>
<script>
export default {
i18n: {
'zh-CN': {
title2: '监听对应事件',
title3: '高级用法',
placeholder: '请输入搜索关键词',
label: '地址'
},
'en-US': {
title2: 'Listen to Events',
title3: 'Advanced Usage',
placeholder: 'Placeholder',
label: 'Address'
}
},
data() {
return {
value: ''
};
},
methods: {
onSearch() {
this.$toast(this.value);
},
onCancel() {
this.$toast(this.$t('cancel'));
}
}
};
</script>
+99
View File
@@ -0,0 +1,99 @@
# Search
### Install
``` javascript
import { Search } from 'vant';
Vue.use(Search);
```
## Usage
### Basic Usage
```html
<van-search placeholder="Placeholder" v-model="value" />
```
```javascript
export default {
data() {
value: ''
}
}
```
### Listen to Events
`search` event will be triggered when click the search button on the keyboard.
`cancel` event will be triggered when click the cancel button.
Tips: There will be a search button on the keyboard when Search is inside a form in iOS.
```html
<form action="/">
<van-search
v-model="value"
placeholder="Placeholder"
show-action
@search="onSearch"
@cancel="onCancel"
/>
</form>
```
### Custom Button
Use `action` slot to custom right button, `cancel` event will no longer be triggered when use this slot
```html
<van-search
v-model="value"
show-action
shape="round"
@search="onSearch"
>
<div slot="action" @click="onSearch">Search</div>
</van-search>
```
## API
### Props
Search support all native properties of input tagsuch as `maxlength`、`placeholder`、`autofocus`
| Attribute | Description | Type | Default |
|------|------|------|------|
| label | Search label | `String` | - |
| shape | Can be set to `round` | `String` | `square` |
| background | Background color | `String` | `#f2f2f2` |
| clearable | Whether to be clearable | `Boolean` | `true` |
| show-action | Whether to show right button | `Boolean` | `false` |
| disabled | Whether to disable field | `Boolean` | `false` |
| readonly | Whether to be readonly | `Boolean` | `false` |
| error | Whether to show error info | `Boolean` | `false` |
| input-align | Input text align, can be set to `center` `right` | `String` | `left` |
| left-icon | Left icon name | `String` | `search` |
| right-icon | Right icon name | `String` | - |
### Events
Search support all native events of input tagsuch as `focus`、`blur`、`keypress`
| Event | Description | Arguments |
|------|------|------|
| cancel | Triggered when click cancel button | - |
| search | Triggered when confirm search | - |
| clear | Triggered when click clear icon | - |
### Slots
| Name | Description |
|------|------|
| label | Custom Search label |
| action | Custom right button, displayed when `showAction` is true |
| left-icon | Custom left icon |
| right-icon | Custom right icon |
+61
View File
@@ -0,0 +1,61 @@
@import '../style/var';
.van-search {
display: flex;
align-items: center;
box-sizing: border-box;
padding: @search-padding;
&__content {
display: flex;
flex: 1;
padding-left: 10px;
background-color: @search-background-color;
border-radius: 2px;
&--round {
border-radius: @search-input-height / 2;
}
}
&__label {
padding: @search-label-padding;
color: @search-label-color;
font-size: @search-label-font-size;
line-height: @search-input-height;
}
.van-cell {
flex: 1;
padding: 5px 10px 5px 0;
background-color: transparent;
&__left-icon {
color: @search-left-icon-color;
}
}
&--show-action {
padding-right: 0;
}
input {
&::-webkit-search-decoration,
&::-webkit-search-cancel-button,
&::-webkit-search-results-button,
&::-webkit-search-results-decoration {
display: none;
}
}
&__action {
padding: @search-action-padding;
color: @search-action-text-color;
font-size: @search-action-font-size;
line-height: @search-input-height;
&:active {
background-color: @active-color;
}
}
}
+137
View File
@@ -0,0 +1,137 @@
import { createNamespace } from '../utils';
import { inherit, emit } from '../utils/functional';
import { preventDefault } from '../utils/dom/event';
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: string;
value?: string;
label?: string;
leftIcon: string;
rightIcon?: string;
clearable: boolean;
background: string;
showAction?: boolean;
};
export type SearchSlots = DefaultSlots & {
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() {
emit(ctx, 'input', '');
emit(ctx, 'cancel');
}
return (
<div class={bem('action')}>
{slots.action ? slots.action() : <div onClick={onCancel}>{t('cancel')}</div>}
</div>
);
}
const fieldData = {
attrs: ctx.data.attrs,
on: {
...ctx.listeners,
input(value: string) {
emit(ctx, 'input', value);
},
keypress(event: KeyboardEvent) {
// press enter
if (event.keyCode === 13) {
preventDefault(event);
emit(ctx, 'search', props.value);
}
emit(ctx, 'keypress', event);
}
}
};
const inheritData = inherit(ctx);
delete inheritData.attrs;
return (
<div
class={bem({ 'show-action': props.showAction })}
style={{ background: props.background }}
{...inheritData}
>
<div class={bem('content', props.shape)}>
{Label()}
<Field
type="search"
border={false}
value={props.value}
leftIcon={props.leftIcon}
rightIcon={props.rightIcon}
clearable={props.clearable}
scopedSlots={{
'left-icon': slots['left-icon'],
'right-icon': slots['right-icon']
}}
{...fieldData}
/>
</div>
{Action()}
</div>
);
}
Search.props = {
value: String,
label: String,
rightIcon: String,
showAction: Boolean,
shape: {
type: String,
default: 'square'
},
clearable: {
type: Boolean,
default: true
},
background: {
type: String,
default: '#fff'
},
leftIcon: {
type: String,
default: 'search'
}
};
export default createComponent<SearchProps, SearchEvents, SearchSlots>(Search);
@@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-search" style="background: rgb(255, 255, 255);">
<div class="van-search__content van-search__content--square">
<div class="van-cell van-cell--borderless van-field">
<div class="van-field__left-icon"><i class="van-icon van-icon-search">
<!----></i></div>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" placeholder="请输入搜索关键词" class="van-field__control"></div>
</div>
</div>
</div>
</div>
</div>
<div>
<form action="/">
<div class="van-search van-search--show-action" style="background: rgb(255, 255, 255);">
<div class="van-search__content van-search__content--square">
<div class="van-cell van-cell--borderless van-field">
<div class="van-field__left-icon"><i class="van-icon van-icon-search">
<!----></i></div>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" placeholder="请输入搜索关键词" class="van-field__control"></div>
</div>
</div>
</div>
<div class="van-search__action">
<div>取消</div>
</div>
</div>
</form>
</div>
<div>
<div class="van-search van-search--show-action" style="background: rgb(255, 255, 255);">
<div class="van-search__content van-search__content--round">
<div class="van-search__label">地址</div>
<div class="van-cell van-cell--borderless van-field">
<div class="van-field__left-icon"><i class="van-icon van-icon-search">
<!----></i></div>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" placeholder="请输入搜索关键词" class="van-field__control"></div>
</div>
</div>
</div>
<div class="van-search__action">
<div>搜索</div>
</div>
</div>
</div>
</div>
`;
@@ -0,0 +1,63 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`left-icon prop 1`] = `
<div class="van-search" style="background: rgb(255, 255, 255);">
<div class="van-search__content van-search__content--square">
<div class="van-cell van-cell--borderless van-field">
<div class="van-field__left-icon"><i class="van-icon van-icon-setting-o">
<!----></i></div>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" class="van-field__control"></div>
</div>
</div>
</div>
</div>
`;
exports[`render label slot 1`] = `
<div class="van-search" style="background: rgb(255, 255, 255);">
<div class="van-search__content van-search__content--square">
<div class="van-search__label">Custom Label</div>
<div class="van-cell van-cell--borderless van-field">
<div class="van-field__left-icon"><i class="van-icon van-icon-search">
<!----></i></div>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" class="van-field__control"></div>
</div>
</div>
</div>
</div>
`;
exports[`right-icon prop 1`] = `
<div class="van-search" style="background: rgb(255, 255, 255);">
<div class="van-search__content van-search__content--square">
<div class="van-cell van-cell--borderless van-field">
<div class="van-field__left-icon"><i class="van-icon van-icon-search">
<!----></i></div>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" class="van-field__control">
<div class="van-field__right-icon"><i class="van-icon van-icon-setting-o">
<!----></i></div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`right-icon slot 1`] = `
<div class="van-search" style="background: rgb(255, 255, 255);">
<div class="van-search__content van-search__content--square">
<div class="van-cell van-cell--borderless van-field">
<div class="van-field__left-icon"><i class="van-icon van-icon-search">
<!----></i></div>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" class="van-field__control">
<div class="van-field__right-icon">Custom Right Icon</div>
</div>
</div>
</div>
</div>
</div>
`;
+4
View File
@@ -0,0 +1,4 @@
import Demo from '../demo';
import demoTest from '../../../test/demo-test';
demoTest(Demo);
+109
View File
@@ -0,0 +1,109 @@
/* eslint-disable object-shorthand */
import Search from '..';
import { mount } from '../../../test/utils';
test('listen input event', () => {
const onInput = jest.fn();
const wrapper = mount(Search, {
context: {
on: {
input: onInput
}
}
});
const input = wrapper.find('input');
input.element.value = '1';
input.trigger('input');
expect(onInput).toHaveBeenCalledWith('1');
});
test('cancel search', () => {
const onInput = jest.fn();
const onCancel = jest.fn();
const wrapper = mount(Search, {
propsData: {
value: 'test',
showAction: true
},
context: {
on: {
input: onInput,
cancel: onCancel
}
}
});
const cancel = wrapper.find('.van-search__action div');
cancel.trigger('click');
expect(onInput).toHaveBeenCalledWith('');
expect(onCancel).toHaveBeenCalled();
});
test('emit a search event', () => {
const onSearch = jest.fn();
const onKeypress = jest.fn();
const wrapper = mount(Search, {
context: {
on: {
search: onSearch,
keypress: onKeypress
}
}
});
const input = wrapper.find('input');
input.trigger('keypress.enter');
input.trigger('keypress.a');
expect(onSearch).toHaveBeenCalled();
expect(onKeypress).toHaveBeenCalled();
});
test('render label slot', () => {
const wrapper = mount(Search, {
scopedSlots: {
label() {
return 'Custom Label';
}
}
});
expect(wrapper).toMatchSnapshot();
});
test('left-icon prop', () => {
const wrapper = mount(Search, {
propsData: {
leftIcon: 'setting-o'
}
});
expect(wrapper).toMatchSnapshot();
});
test('right-icon prop', () => {
const wrapper = mount(Search, {
propsData: {
rightIcon: 'setting-o'
}
});
expect(wrapper).toMatchSnapshot();
});
test('right-icon slot', () => {
const wrapper = mount(Search, {
scopedSlots: {
'right-icon'() {
return 'Custom Right Icon';
}
}
});
expect(wrapper).toMatchSnapshot();
});
+92
View File
@@ -0,0 +1,92 @@
# Search 搜索
### 引入
``` javascript
import { Search } from 'vant';
Vue.use(Search);
```
## 代码演示
### 基础用法
`van-search` 中,v-model 用于控制搜索框中的文字。background 可以自定义搜索框外部背景色。
```html
<van-search placeholder="请输入搜索关键词" v-model="value" />
```
### 监听对应事件
`van-search` 提供了 search 和 cancel 事件。search 事件在用户点击键盘上的 搜索/回车 按钮触发。cancel 事件在用户点击搜索框右侧取消按钮时触发
Tips: 在 `van-search` 外层增加 form 标签,并且 action 不为空,即可在 IOS 弹出的输入法中显示搜索按钮
```html
<form action="/">
<van-search
v-model="value"
placeholder="请输入搜索关键词"
show-action
@search="onSearch"
@cancel="onCancel"
/>
</form>
```
### 自定义行动按钮
`van-search` 支持自定义右侧取消按钮,使用名字为 action 的插槽即可。使用此插槽以后,原有的 cancel 事件不再生效。
```html
<van-search
v-model="value"
placeholder="请输入搜索关键词"
show-action
shape="round"
@search="onSearch"
>
<div slot="action" @click="onSearch">搜索</div>
</van-search>
```
## API
### Props
Search 默认支持 Input 标签所有的原生属性,比如 `maxlength`、`placeholder`、`autofocus` 等
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| label | 搜索框左侧文本 | `String` | - | 1.6.6 |
| shape | 形状,可选值为 `round` | `String` | `square` | 1.6.6 |
| background | 搜索框背景色 | `String` | `#f2f2f2` | - |
| clearable | 是否启用清除控件 | `Boolean` | `true` | 2.0.0 |
| show-action | 是否在搜索框右侧显示取消按钮 | `Boolean` | `false` | - |
| disabled | 是否禁用输入框 | `Boolean` | `false` | - |
| readonly | 是否将输入框设为只读 | `Boolean` | `false` | - |
| error | 是否将输入内容标红 | `Boolean` | `false` | - |
| input-align | 输入框内容对齐方式,可选值为 `center` `right` | `String` | `left` | - |
| left-icon | 输入框左侧图标名称或图片链接,可选值见 Icon 组件 | `String` | `search` | 2.0.0 |
| right-icon | 输入框右侧图标名称或图片链接,可选值见 Icon 组件 | `String` | - | 2.0.0 |
### Events
Search 默认支持 Input 标签所有的原生事件,如 `focus`、`blur`、`keypress` 等
| 事件名 | 说明 | 回调参数 |
|------|------|------|
| cancel | 取消搜索 | - |
| search | 确定搜索 | - |
| clear | 点击清除按钮后触发 | - |
### Slots
| 名称 | 说明 |
|------|------|
| label | 自定义搜索框左侧文本 |
| action | 自定义搜索框右侧按钮,需要在`showAction`为 true 时才会显示 |
| left-icon | 自定义输入框左侧图标 |
| right-icon | 自定义输入框右侧图标 |