xref: /openbmc/webui-vue/src/components/Global/Search.vue (revision d36ac8a8be8636ddd0e64ce005d507b21bcdeb00)
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        <template #prepend>
11          <b-input-group-text>
12            <icon-search class="search-icon" />
13          </b-input-group-text>
14        </template>
15        <b-form-input
16          :id="`searchInput-${uid}`"
17          ref="searchInput"
18          v-model="filter"
19          class="search-input"
20          type="text"
21          :aria-label="$t('global.form.search')"
22          :placeholder="placeholder"
23          @input="onChangeInput"
24        >
25        </b-form-input>
26        <b-button
27          v-if="filter"
28          variant="link"
29          class="btn-icon-only input-action-btn"
30          :title="$t('global.ariaLabel.clearSearch')"
31          @click="onClearSearch"
32        >
33          <icon-close />
34          <span class="visually-hidden">
35            {{ $t('global.ariaLabel.clearSearch') }}
36          </span>
37        </b-button>
38      </b-input-group>
39    </b-form-group>
40  </div>
41</template>
42
43<script>
44import IconSearch from '@carbon/icons-vue/es/search/16';
45import IconClose from '@carbon/icons-vue/es/close/20';
46import { useI18n } from 'vue-i18n';
47import i18n from '@/i18n';
48
49export default {
50  name: 'Search',
51  components: { IconSearch, IconClose },
52  props: {
53    placeholder: {
54      type: String,
55      default: function () {
56        return i18n.global.t('global.form.search');
57      },
58    },
59  },
60  emits: ['change-search', 'clear-search'],
61  data() {
62    return {
63      $t: useI18n().t,
64      filter: null,
65      uid: Math.random().toString(36).slice(2),
66    };
67  },
68  methods: {
69    onChangeInput() {
70      this.$emit('change-search', this.filter);
71    },
72    onClearSearch() {
73      this.filter = '';
74      this.$emit('clear-search');
75      const input = this.$refs.searchInput;
76      if (input && typeof input.focus === 'function') input.focus();
77    },
78  },
79};
80</script>
81
82<style lang="scss" scoped>
83.search-icon {
84  stroke: $gray-400;
85}
86</style>
87