<template> <div id="custom-dropdown" :class="[ 'ui search selection dropdown', { 'active visible': isOpen }, { disabled }, ]" @click="toggleDropdown" > <input v-if="search" class="search" autocomplete="off" tabindex="0" @input="handelInput" v-on:keyup.enter="select(0)" v-model="input" :placeholder="placeholder" /> <!-- {{placeholder}} --> <div class="default text">{{ selected || placeholder }}</div> <i :class="['dropdown icon', { clear: search && selected }]" @click="clear" ></i> <div :class="['menu', { 'visible transition': isOpen }]"> <div v-for="(option, index) in processedOptions || ['No results found.']" @click="select(index)" :key="option + index" :class="[ processedOptions ? 'item' : 'message', { 'active selected': option === selected }, ]" >{{ option }}</div> </div> </div> </template> <script> export default { name: "Dropdown", props: ["options", "selected", "disabled", "search", "placeholder"], computed: { processedOptions: function () { //* si un objet {name, value} let options = this.options.map((el) => el.constructor == Object ? el.name : el ); if (this.search && this.input !== "") { options = this.searchOptions(options); } return options.length > 0 ? options : null; }, }, data() { return { isOpen: false, input: "", }; }, methods: { toggleDropdown() { this.isOpen = !this.isOpen; }, select(index) { setTimeout(() => { this.isOpen = false; // * quick & dirty, car toggle dropdown est rappelé plusieurs fois aileurs, à creuser... }, 500); this.$emit("update:selection", this.options[index]); this.input = ""; }, searchOptions(options) { return options.filter((el) => el.toLowerCase().includes(this.input.toLowerCase()) ); }, clear() { if (this.search) { this.input = ""; this.clearSelected(); } }, clearSelected() { this.$emit("update:selection", ""); }, handelInput() { this.isOpen = true; this.clearSelected(); }, clickOutsideDropdown(e) { if (!e.target.closest("#custom-dropdown")) this.isOpen = false; }, }, created() { window.addEventListener("mousedown", this.clickOutsideDropdown); }, beforeDestroy() { window.removeEventListener("mousedown", this.clickOutsideDropdown); }, }; </script> <style scoped> .ui.selection.dropdown .menu > .item { white-space: nowrap; } </style>