mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-13 16:45:18 +08:00
Refactor select.vue to use the outside click directive [SCI-9496]
This commit is contained in:
parent
957f539e32
commit
45e45d1543
2 changed files with 15 additions and 37 deletions
|
@ -16,7 +16,9 @@ export default {
|
||||||
exclude.forEach(refName => {
|
exclude.forEach(refName => {
|
||||||
if (!clickedOnExcludedEl) {
|
if (!clickedOnExcludedEl) {
|
||||||
const excludedEl = vnode.context.$refs[refName];
|
const excludedEl = vnode.context.$refs[refName];
|
||||||
clickedOnExcludedEl = excludedEl?.contains(e.target);
|
if (!excludedEl) return;
|
||||||
|
|
||||||
|
clickedOnExcludedEl = (excludedEl._isVue ? excludedEl.$el : excludedEl).contains(e.target);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div @click="toggle" ref="container" class="sn-select" :class="{ 'sn-select--open': isOpen, 'sn-select--blank': !valueLabel, 'disabled': disabled }">
|
<div v-click-outside="{ handler: 'close', exclude: ['optionsContainer'] }" @click="toggle" ref="container" class="sn-select" :class="{ 'sn-select--open': isOpen, 'sn-select--blank': !valueLabel, 'disabled': disabled }">
|
||||||
<slot>
|
<slot>
|
||||||
<button ref="focusElement" class="sn-select__value">
|
<button ref="focusElement" class="sn-select__value">
|
||||||
<span>{{ valueLabel || (placeholder || i18n.t('general.select')) }}</span>
|
<span>{{ valueLabel || (placeholder || i18n.t('general.select')) }}</span>
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||||
|
import outsideClick from '../../packs/vue/directives/outside_click';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Select',
|
name: 'Select',
|
||||||
|
@ -48,12 +49,13 @@
|
||||||
noOptionsPlaceholder: { type: String },
|
noOptionsPlaceholder: { type: String },
|
||||||
disabled: { type: Boolean, default: false }
|
disabled: { type: Boolean, default: false }
|
||||||
},
|
},
|
||||||
comments: { PerfectScrollbar },
|
directives: {
|
||||||
|
'click-outside': outsideClick
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
optionPositionStyle: '',
|
optionPositionStyle: ''
|
||||||
blurPrevented: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -66,34 +68,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.focusElement.onblur = this.blur;
|
|
||||||
document.addEventListener('scroll', this.updateOptionPosition);
|
document.addEventListener('scroll', this.updateOptionPosition);
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
document.removeEventListener('scroll', this.updateOptionPosition);
|
document.removeEventListener('scroll', this.updateOptionPosition);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
preventBlur() {
|
|
||||||
this.blurPrevented = true;
|
|
||||||
},
|
|
||||||
allowBlur() {
|
|
||||||
setTimeout(() => { this.blurPrevented = false }, 200);
|
|
||||||
},
|
|
||||||
blur() {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (this.blurPrevented) {
|
|
||||||
this.focusElement.focus();
|
|
||||||
} else {
|
|
||||||
this.isOpen = false;
|
|
||||||
this.$emit('blur');
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
},
|
|
||||||
toggle() {
|
toggle() {
|
||||||
if (this.isOpen && this.blurPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isOpen = !this.isOpen;
|
this.isOpen = !this.isOpen;
|
||||||
|
|
||||||
if (this.isOpen) {
|
if (this.isOpen) {
|
||||||
|
@ -103,14 +84,16 @@
|
||||||
});
|
});
|
||||||
this.$refs.optionsContainer.scrollTop = 0;
|
this.$refs.optionsContainer.scrollTop = 0;
|
||||||
this.updateOptionPosition();
|
this.updateOptionPosition();
|
||||||
this.setUpBlurHandlers();
|
|
||||||
} else {
|
} else {
|
||||||
this.optionPositionStyle = '';
|
this.close()
|
||||||
this.$emit('close');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
close() {
|
||||||
|
this.isOpen = false;
|
||||||
|
this.optionPositionStyle = '';
|
||||||
|
this.$emit('close');
|
||||||
|
},
|
||||||
setValue(value) {
|
setValue(value) {
|
||||||
this.focusElement.blur();
|
|
||||||
this.$emit('change', value);
|
this.$emit('change', value);
|
||||||
},
|
},
|
||||||
updateOptionPosition() {
|
updateOptionPosition() {
|
||||||
|
@ -129,13 +112,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.optionPositionStyle = `position: fixed; top: ${top}px; left: ${left}px; width: ${width}px`
|
this.optionPositionStyle = `position: fixed; top: ${top}px; left: ${left}px; width: ${width}px`
|
||||||
},
|
|
||||||
setUpBlurHandlers() {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$refs.optionsContainer.$el.querySelector('.ps__thumb-y').addEventListener('mousedown', this.preventBlur);
|
|
||||||
this.$refs.optionsContainer.$el.querySelector('.ps__thumb-y').addEventListener('mouseup', this.allowBlur);
|
|
||||||
document.addEventListener('mouseup', this.allowBlur);
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue