SelectInput.vue searching

This commit is contained in:
Peter Papp
2021-04-15 11:22:10 +02:00
parent 639f24fdfd
commit 6056e97463
@@ -7,8 +7,8 @@
<!--If is selected--> <!--If is selected-->
<div class="selected" v-if="selected"> <div class="selected" v-if="selected">
<div class="option-icon" v-if="selected.icon"> <div class="option-icon" v-if="selected.icon">
<user-icon v-if="selected.icon === 'user'" size="14"></user-icon> <user-icon v-if="selected.icon === 'user'" size="14" />
<edit2-icon v-if="selected.icon === 'user-edit'" size="14"></edit2-icon> <edit2-icon v-if="selected.icon === 'user-edit'" size="14" />
</div> </div>
<span class="option-value">{{ selected.label }}</span> <span class="option-value">{{ selected.label }}</span>
</div> </div>
@@ -23,34 +23,66 @@
<!--Options--> <!--Options-->
<transition name="slide-in"> <transition name="slide-in">
<ul class="input-options" v-if="isOpen"> <div class="input-options" v-if="isOpen">
<li class="option-item" @click="selectOption(option)" v-for="(option, i) in options" :key="i"> <div v-if="options.length > 5" class="select-search">
<div class="option-icon" v-if="option.icon"> <!--TODO: jazyk-->
<user-icon v-if="option.icon === 'user'" size="14"></user-icon> <input v-model="query" ref="search" type="text" placeholder="Search in list..." class="search-input focus-border-theme">
<edit2-icon v-if="option.icon === 'user-edit'" size="14"></edit2-icon> </div>
</div> <ul class="option-list">
<span class="option-value">{{ option.label }}</span> <li class="option-item" @click="selectOption(option)" v-for="(option, i) in optionList" :key="i">
</li> <div class="option-icon" v-if="option.icon">
</ul> <user-icon v-if="option.icon === 'user'" size="14" />
<edit2-icon v-if="option.icon === 'user-edit'" size="14" />
</div>
<span class="option-value">{{ option.label }}</span>
</li>
</ul>
</div>
</transition> </transition>
</div> </div>
</template> </template>
<script> <script>
import { ChevronDownIcon, Edit2Icon, UserIcon } from 'vue-feather-icons' import { ChevronDownIcon, Edit2Icon, UserIcon } from 'vue-feather-icons'
import {debounce, omitBy} from "lodash"
import {events} from '@/bus'
export default { export default {
name:'SelectInput', name:'SelectInput',
props: ['options', 'isError', 'default', 'placeholder'], props: [
'placeholder',
'options',
'isError',
'default',
],
components: { components: {
Edit2Icon, Edit2Icon,
UserIcon, UserIcon,
ChevronDownIcon ChevronDownIcon
}, },
watch: {
query: debounce(function (val) {
this.searchedResults = omitBy(this.options, string => {
return !string.label.toLowerCase().includes(val.toLowerCase())
})
}, 200),
},
computed: {
isSearching() {
return this.searchedResults && this.query !== ''
},
optionList() {
return this.isSearching
? this.searchedResults
: this.options
}
},
data() { data() {
return { return {
searchedResults: undefined,
selected: undefined, selected: undefined,
isOpen: false, isOpen: false,
query: '',
} }
}, },
methods: { methods: {
@@ -67,10 +99,13 @@
}, },
openMenu() { openMenu() {
this.isOpen = ! this.isOpen this.isOpen = ! this.isOpen
if (this.isOpen) {
this.$nextTick(() => this.$refs.search.focus());
}
}, },
}, },
created() { created() {
if (this.default) if (this.default)
this.selected = this.options.find(option => option.value === this.default) this.selected = this.options.find(option => option.value === this.default)
} }
@@ -87,6 +122,26 @@
width: 100%; width: 100%;
} }
.select-search {
background: white;
position: sticky;
top: 0;
padding: 13px;
.search-input {
border: 1px solid transparent;
background: $light_background;
@include transition(150ms);
@include font-size(14);
border-radius: 8px;
padding: 13px 20px;
appearance: none;
font-weight: 700;
outline: 0;
width: 100%;
}
}
.input-options { .input-options {
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.12); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.12);
background: white; background: white;