1<template> 2 <div class="search-global"> 3 <b-form-group 4 :label="$t('global.form.search')" 5 :label-for="`searchInput-${_uid}`" 6 label-class="invisible" 7 class="mb-2" 8 > 9 <b-input-group size="md" class="align-items-center"> 10 <b-input-group-prepend> 11 <icon-search class="search-icon" /> 12 </b-input-group-prepend> 13 <b-form-input 14 :id="`searchInput-${_uid}`" 15 ref="searchInput" 16 v-model="filter" 17 class="search-input" 18 type="text" 19 :aria-label="$t('global.form.search')" 20 :placeholder="placeholder" 21 @input="onChangeInput" 22 > 23 </b-form-input> 24 <b-button 25 v-if="filter" 26 variant="link" 27 class="btn-icon-only input-action-btn" 28 :title="$t('global.ariaLabel.clearSearch')" 29 @click="onClearSearch" 30 > 31 <icon-close /> 32 <span class="sr-only">{{ $t('global.ariaLabel.clearSearch') }}</span> 33 </b-button> 34 </b-input-group> 35 </b-form-group> 36 </div> 37</template> 38 39<script> 40import IconSearch from '@carbon/icons-vue/es/search/16'; 41import IconClose from '@carbon/icons-vue/es/close/20'; 42import { useI18n } from 'vue-i18n'; 43import i18n from '@/i18n'; 44 45export default { 46 name: 'Search', 47 components: { IconSearch, IconClose }, 48 props: { 49 placeholder: { 50 type: String, 51 default: function () { 52 return i18n.global.t('global.form.search'); 53 }, 54 }, 55 }, 56 emits: ['change-search', 'clear-search'], 57 data() { 58 return { 59 $t: useI18n().t, 60 filter: null, 61 }; 62 }, 63 methods: { 64 onChangeInput() { 65 this.$emit('change-search', this.filter); 66 }, 67 onClearSearch() { 68 this.filter = ''; 69 this.$emit('clear-search'); 70 this.$refs.searchInput.focus(); 71 }, 72 }, 73}; 74</script> 75 76<style lang="scss" scoped> 77.search-input { 78 padding-left: ($spacer * 2); 79} 80.search-icon { 81 position: absolute; 82 left: 10px; 83 top: 12px; 84 z-index: 4; 85 stroke: gray('400'); 86} 87</style> 88