<script> import { onLeftClick, isPromise } from '../utils' import SingleValue from './SingleValue' import MultiValue from './MultiValue' import DeleteIcon from './icons/Delete' import ArrowIcon from './icons/Arrow' export default { name: 'vue-treeselect--control', inject: [ 'instance' ], computed: { /* eslint-disable valid-jsdoc */ /** * Should show the "脳" button that resets value? * @return {boolean} */ shouldShowX() { const { instance } = this return ( instance.clearable && !instance.disabled && instance.hasValue && (this.hasUndisabledValue || instance.allowClearingDisabled) ) }, /** * Should show the arrow button that toggles menu? * @return {boolean} */ shouldShowArrow() { const { instance } = this if (!instance.alwaysOpen) return true // Even with `alwaysOpen: true`, sometimes the menu is still closed, // e.g. when the control is disabled. return !instance.menu.isOpen }, /** * Has any undisabled option been selected? * @type {boolean} */ hasUndisabledValue() { const { instance } = this return ( instance.hasValue && instance.internalValue.some(id => !instance.getNode(id).isDisabled) ) }, /* eslint-enable valid-jsdoc */ }, methods: { renderX() { const { instance } = this const title = instance.multiple ? instance.clearAllText : instance.clearValueText if (!this.shouldShowX) return null return ( <div class="vue-treeselect__x-container" title={title} onMousedown={this.handleMouseDownOnX}> <DeleteIcon class="vue-treeselect__x" /> </div> ) }, renderArrow() { const { instance } = this const arrowClass = { 'vue-treeselect__control-arrow': true, 'vue-treeselect__control-arrow--rotated': instance.menu.isOpen, } if (!this.shouldShowArrow) return null return ( <div class="vue-treeselect__control-arrow-container" onMousedown={this.handleMouseDownOnArrow}> <ArrowIcon class={arrowClass} /> </div> ) }, handleMouseDownOnX: onLeftClick(function handleMouseDownOnX(evt) { /** * We don't use async/await here because we don't want * to rely on Babel polyfill or regenerator runtime. * See: https://babeljs.io/docs/plugins/transform-regenerator/ * We also don't want to assume there is a global `Promise` * class, since we are targeting to support IE9 without the * need of any polyfill. */ evt.stopPropagation() evt.preventDefault() const { instance } = this const result = instance.beforeClearAll() const handler = shouldClear => { if (shouldClear) instance.clear() } if (isPromise(result)) { // The handler will be called async. result.then(handler) } else { // Keep the same behavior here. setTimeout(() => handler(result), 0) // Also, note that IE9 requires: // setTimeout(() => fn(...args), delay) // Instead of: // setTimeout(fn, delay, ...args) } }), handleMouseDownOnArrow: onLeftClick(function handleMouseDownOnArrow(evt) { evt.preventDefault() evt.stopPropagation() const { instance } = this // Focus the input or prevent blurring. instance.focusInput() instance.toggleMenu() }), // This is meant to be called by child `<Value />` component. renderValueContainer(children) { return ( <div class="vue-treeselect__value-container"> {children} </div> ) }, }, render() { const { instance } = this const ValueContainer = instance.single ? SingleValue : MultiValue return ( <div class="vue-treeselect__control" onMousedown={instance.handleMouseDown}> <ValueContainer ref="value-container" /> {this.renderX()} {this.renderArrow()} </div> ) }, } </script>