63 lines
2.6 KiB
JavaScript
63 lines
2.6 KiB
JavaScript
Vue.component('tt-icon-select', {
|
|
props: ['options', 'label', 'value'],
|
|
data() {
|
|
return {
|
|
selectedOption: this.options.find(option => option.value.toString() === this.value) || null,
|
|
isOpen: false,
|
|
observer: null,
|
|
};
|
|
},
|
|
mounted() {
|
|
// Dynamically add CSS to disable default dropdown caret
|
|
const style = document.createElement('style');
|
|
style.innerHTML = `.tt-select .dropdown-toggle::after { display: none; }`;
|
|
document.body.appendChild(style);
|
|
|
|
document.addEventListener('click', this.handleClick);
|
|
|
|
this.observer = new ResizeObserver(this.calculateOffset.bind(this));
|
|
this.observer.observe(this.$refs.select);
|
|
this.calculateOffset();
|
|
},
|
|
beforeDestroy() {
|
|
document.removeEventListener('click', this.handleClick);
|
|
this.observer.disconnect();
|
|
},
|
|
watch: {
|
|
value(val) {
|
|
this.selectedOption = this.options.find(option => option.value.toString() === val) || null;
|
|
}
|
|
},
|
|
methods: {
|
|
selectOption(option) {
|
|
this.selectedOption = option;
|
|
this.$emit('input', option ? option.value.toString() : '');
|
|
this.isOpen = false;
|
|
},
|
|
calculateOffset() {
|
|
const offset = (this.$refs.select.offsetWidth - 64.41) / 2;
|
|
this.$refs.select.querySelector('.dropdown-menu').style.left = `${offset}px`;
|
|
},
|
|
handleClick() {
|
|
this.isOpen = this.$refs.selectedIcon.contains(event.target) ? !this.isOpen : false;
|
|
},
|
|
},
|
|
template: `
|
|
<div class="form-group tt-select" style="user-select: none;margin-bottom: 0; margin-top: 6px">
|
|
<div class="dropdown" :class="{'show': isOpen}">
|
|
<i v-if="selectedOption !== null" :class="selectedOption.icon" style="font-size: 18px; cursor: pointer" ref="selectedIcon"></i>
|
|
<span v-else style="cursor: pointer" ref="selectedIcon">Alle<i class="fas fa-caret-down"></i></span>
|
|
<div style="display: grid; justify-items: center;" ref="select">
|
|
<div class="dropdown-menu" :class="{'show': isOpen}" style="min-width: unset !important;">
|
|
<a class="dropdown-item text-center" href="#" @click.prevent="selectOption(null)">Alle</a>
|
|
<a v-for="option in options" class="dropdown-item text-center" href="#"
|
|
@click.prevent="selectOption(option)">
|
|
<i :class="option.icon" style="font-size: 18px" :title="option.text"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`
|
|
});
|