UNPKG

quasar-framework

Version:

Simultaneously build desktop/mobile SPA websites & phone/tablet apps with VueJS

165 lines (150 loc) 3.76 kB
import BtnMixin from './btn-mixin' import { QSpinner } from '../spinner' import { between } from '../../utils/format' export default { name: 'q-btn', mixins: [BtnMixin], props: { percentage: Number, darkPercentage: Boolean, waitForRipple: Boolean, repeatTimeout: [Number, Function] }, computed: { hasPercentage () { return this.percentage !== void 0 }, width () { return `${between(this.percentage, 0, 100)}%` }, events () { return this.isDisabled || !this.repeatTimeout ? { click: this.click } : { mousedown: this.__startRepeat, touchstart: this.__startRepeat, mouseup: this.__endRepeat, touchend: this.__endRepeat, mouseleave: this.__abortRepeat, touchmove: this.__abortRepeat } } }, data () { return { repeating: false } }, methods: { click (e) { this.__cleanup() const trigger = () => { if (this.isDisabled) { return } this.$emit('click', e) } if (this.waitForRipple && this.hasRipple) { this.timer = setTimeout(trigger, 300) } else { trigger() } }, __cleanup () { clearTimeout(this.timer) }, __startRepeat (e) { const setTimer = () => { this.timer = setTimeout( trigger, typeof this.repeatTimeout === 'function' ? this.repeatTimeout(this.repeatCount) : this.repeatTimeout ) } const trigger = () => { if (this.isDisabled) { return } this.repeatCount += 1 e.repeatCount = this.repeatCount this.$emit('click', e) setTimer() } this.repeatCount = 0 this.repeating = true setTimer() }, __abortRepeat () { this.repeating = false this.__cleanup() }, __endRepeat (e) { if (!this.repeating) { return } if (this.repeatCount) { this.repeatCount = 0 } else if (e.detail) { this.repeating = false e.repeatCount = 0 this.$emit('click', e) } this.__cleanup() } }, beforeDestroy () { this.__cleanup() }, render (h) { return h('button', { staticClass: 'q-btn inline relative-position q-btn-item non-selectable', 'class': this.classes, style: this.style, attrs: { tabindex: this.computedTabIndex }, on: this.events, directives: this.hasRipple ? [{ name: 'ripple', value: true }] : null }, [ __THEME__ === 'ios' || this.$q.platform.is.desktop ? h('div', { staticClass: 'q-focus-helper' }) : null, this.loading && this.hasPercentage ? h('div', { staticClass: 'q-btn-progress absolute-full', 'class': { 'q-btn-dark-progress': this.darkPercentage }, style: { width: this.width } }) : null, h('div', { staticClass: 'q-btn-inner row col items-center', 'class': this.innerClasses }, this.loading ? [ this.$slots.loading || h(QSpinner) ] : [ this.icon ? h('q-icon', { 'class': { 'on-left': this.label && this.isRectangle }, props: { name: this.icon } }) : null, this.label && this.isRectangle ? h('div', [ this.label ]) : null, this.$slots.default, this.iconRight && this.isRectangle ? h('q-icon', { staticClass: 'on-right', props: { name: this.iconRight } }) : null ] ) ]) } }