Skip to content

Commit

Permalink
feat: new component SearchBox
Browse files Browse the repository at this point in the history
  • Loading branch information
YanxinTang committed Aug 25, 2020
1 parent 88f3e8f commit 011ea2d
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 3 deletions.
3 changes: 2 additions & 1 deletion components.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"Radio": "@components/Radio",
"Row": "@components/Row",
"Col": "@components/Col",
"Toggle": "@components/Toggle"
"Toggle": "@components/Toggle",
"SearchBox": "@components/SearchBox"
}
3 changes: 2 additions & 1 deletion docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ module.exports = {
'/components/button',
'/components/checkbox',
'/components/radio',
'/components/toggle'
'/components/toggle',
'/components/searchBox'
],
},
],
Expand Down
110 changes: 110 additions & 0 deletions docs/components/searchBox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# SearchBox 搜索框

## 基础用法

::: demo
```html
<template>
<Row gutter=".5rem 0">
<Col>
<SearchBox placeholder="Search" v-model="input" @escape="input = ''"/>
</Col>
</Row>
<Row gutter=".5rem 0">
<Col>
<SearchBox placeholder="Search" v-model="input" disableAnimation @escape="input = ''"/>
</Col>
</Row>
<Row gutter=".5rem 0">
<Col>
<SearchBox placeholder="Search" v-model="input" underlined @escape="input = ''"/>
</Col>
</Row>
</template>


<script>
export default {
data() {
return {
input: ''
}
}
}
</script>
```
:::

## 带下划线的搜索框

::: demo
```html
<Row gutter=".5rem 0">
<Col>
<SearchBox placeholder="Search" underlined/>
</Col>
</Row>
```
:::

## 禁用的搜索框

::: demo
```html
<Row gutter=".5rem 0">
<Col>
<SearchBox placeholder="Search" disabled/>
</Col>
</Row>
<Row gutter=".5rem 0">
<Col>
<SearchBox placeholder="Search" underlined disabled/>
</Col>
</Row>
```
:::

## 自定义图标的搜索框

::: demo
```html
<Row gutter=".5rem 0">
<Col>
<SearchBox placeholder="Filter" icon="icon-Filter"/>
</Col>
</Row>
```
:::

## 自定义宽度的搜索框

::: demo
```html
<Row gutter=".5rem 0">
<Col>
<SearchBox style="width: 200px;"/>
</Col>
</Row>
```
:::

## 属性

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-------|------ |------|------|------|
| value | 搜索框的值 | String, Number |||
| disableAnimation | 禁用动画 | Boolean || true |
| underlined | 下划线边框 | Boolean || false |
| placeholder | 搜索框的 placeholder | String || false |
| icon | 搜索框的 图标 | String || `icon-Search` |
| disabled | 禁用搜索框 | Boolean || false |


## 事件

| 参数 | 说明 | 回调参数 |
|-------|------ |------|
| input | 搜索框的值发生变化后触发 | (value: 搜索框的值) |
| change | 搜索框失焦或用户按下回车触发 | (value: 搜索框的值) |
| escape | 用户按下 esp 触发 | (value: 搜索框的值) |
| search | 用户按下 enter 触发 | (value: 搜索框的值) |
70 changes: 70 additions & 0 deletions src/components/SearchBox/SearchBox.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<template>
<div
class="searchbox"
:class="{
'searchbox--disabled': disabled,
'searchbox--focus': focus,
'searchbox--animation': !disableAnimation,
'searchbox--underlined': underlined,
'searchbox--has-input': hasInput,
}"
role="search"
>
<div class="searchbox__icon-container">
<i :class="['icon', icon]"></i>
</div>
<input
type="text"
class="searchbox__field"
ref="field"
:placeholder="placeholder"
:value="value"
:disabled="disabled"
@input="$emit('input', $event.target.value)"
@change="$emit('change', $event.target.value)"
@focus="focus = true"
@blur="focus = false"
@keydown.esc="$emit('escape')"
@keydown.enter="$emit('search', value)"
/>
<div class="searchbox__clear-button" v-if="hasInput">
<Button icon="Clear" plain @click="clearButtonClickHandler"></Button>
</div>
</div>
</template>

<script>
import Button from '@components/Button';
export default {
name: 'SearchBox',
components: { Button },
props: {
value: [String, Number],
disableAnimation: Boolean,
underlined: Boolean,
placeholder: String,
icon: {
type: String,
default: 'icon-Search',
},
disabled: Boolean,
},
data() {
return {
focus: false,
};
},
computed: {
hasInput() {
return this.value !== undefined && String(this.value).length > 0;
},
},
methods: {
clearButtonClickHandler() {
this.$emit('escape');
this.$refs.field.focus();
},
},
};
</script>
7 changes: 7 additions & 0 deletions src/components/SearchBox/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import SearchBox from './SearchBox.vue';

SearchBox.install = Vue => {
Vue.component(SearchBox.name, SearchBox);
};

export default SearchBox;
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Col from '@components/Col';
import Checkbox from '@components/Checkbox';
import Radio from '@components/Radio';
import Toggle from '@components/Toggle';
import SearchBox from '@components/SearchBox';

const components = {
Button,
Expand All @@ -12,6 +13,7 @@ const components = {
Checkbox,
Radio,
Toggle,
SearchBox,
};

const install = function (Vue) {
Expand Down
133 changes: 133 additions & 0 deletions src/themes/fluent-ui/SearchBox.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
@import 'variable';

$color: $neutralPrimary;
$iconColor: $themePrimary;
$clearButtonColor: $neutralSecondary;
$background: $white;
$borderRadius: $roundedCorner2;
$borderColor: $neutralSecondary;
$transition: width 0.167s ease 0s;
$hoverBorderColor: $neutralPrimary;
$disabledColor: $neutralTertiary;
$disabledBorderColor: $neutralLighter;
$disabledBackgroundColor: $neutralLighter;

.searchbox {
position: relative;
color: $color;
background-color: $background;
display: flex;
flex-flow: row nowrap;
align-items: stretch;
padding: 1px 0 1px 4px;
border-radius: $borderRadius;
border: 1px solid $borderColor;
height: 32px;
box-sizing: border-box;
font-size: $font-size-medium;
padding: 0 1px;
-webkit-font-smoothing: antialiased;

.searchbox__icon-container {
display: flex;
flex-flow: column;
justify-content: center;
flex-shrink: 1;
font-size: $font-size-medium;
width: 32px;
text-align: center;
color: $iconColor;
cursor: text;

icon {
opacity: 1;
}
}

.searchbox__field {
background: transparent;
border: none;
outline: none;
font-weight: inherit;
font-family: inherit;
font-size: inherit;
color: $color;
flex: 1 1 0;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
&::-ms-clear {
display: none;
}
}

.searchbox__clear-button {
display: flex;
flex-flow: column nowrap;
.button {
flex-basis: 28px;
padding: 0 4px;
height: 100%;
color: $clearButtonColor;
font-size: 12px;
}
}

&:hover {
border-color: $hoverBorderColor;
}

&.searchbox--focus {
border-color: $themePrimary;
border-width: 2px;

.searchbox__icon-container {
width: 4px;

.icon {
opacity: 0;
}
}
}

&.searchbox--disabled {
border-color: $disabledBorderColor;
background-color: $disabledBackgroundColor;
pointer-events: none;
cursor: default;

.searchbox__icon-container {
color: $disabledColor;
}
}
}

.searchbox.searchbox--animation {
.searchbox__icon-container {
transition: $transition;
}
}

.searchbox.searchbox--underlined {
border-width: 0 0 1px 0;
border-radius: 0;
padding: 1px 0 1px 8px;

&.searchbox--focus {
border-bottom-width: 2px;
}

&.searchbox--disabled {
background-color: $white;
}
}

.searchbox.searchbox--has-input:hover {
.searchbox__icon-container {
width: 4px;

.icon {
opacity: 0;
}
}
}
3 changes: 2 additions & 1 deletion src/themes/fluent-ui/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
@import 'Button.scss';
@import 'Checkbox.scss';
@import 'Radio.scss';
@import 'Toggle.scss';
@import 'Toggle.scss';
@import 'SearchBox.scss';

0 comments on commit 011ea2d

Please sign in to comment.