123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <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>
|