UNPKG

quasar

Version:

Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time

167 lines (138 loc) 4.16 kB
import Vue from 'vue' import QBtn from '../btn/QBtn.js' import QBtnGroup from '../btn-group/QBtnGroup.js' import ListenersMixin from '../../mixins/listeners.js' import FormMixin from '../../mixins/form.js' import RippleMixin from '../../mixins/ripple.js' import { slot, mergeSlot } from '../../utils/slot.js' export default Vue.extend({ name: 'QBtnToggle', mixins: [ ListenersMixin, RippleMixin, FormMixin ], props: { value: { required: true }, options: { type: Array, required: true, validator: v => v.every( opt => ('label' in opt || 'icon' in opt || 'slot' in opt) && 'value' in opt ) }, // To avoid seeing the active raise shadow through the transparent button, give it a color (even white). color: String, textColor: String, toggleColor: { type: String, default: 'primary' }, toggleTextColor: String, outline: Boolean, flat: Boolean, unelevated: Boolean, rounded: Boolean, push: Boolean, glossy: Boolean, size: String, padding: String, noCaps: Boolean, noWrap: Boolean, dense: Boolean, readonly: Boolean, disable: Boolean, stack: Boolean, stretch: Boolean, spread: Boolean, clearable: Boolean }, computed: { hasActiveValue () { return this.options.find(opt => opt.value === this.value) !== void 0 }, formAttrs () { return { type: 'hidden', name: this.name, value: this.value } }, btnOptions () { const mergeOption = (opt, key) => opt[key] === void 0 ? this[key] : opt[key] return this.options.map((opt, i) => ({ slot: opt.slot, options: { key: i, class: opt.class, style: opt.style, on: { ...this.qListeners, click: e => this.__set(opt.value, opt, e) }, attrs: opt.attrs, props: { ...opt, slot: void 0, class: void 0, style: void 0, value: void 0, attrs: void 0, outline: this.outline, flat: this.flat, rounded: this.rounded, push: this.push, unelevated: this.unelevated, dense: this.dense, disable: this.disable === true || opt.disable === true, // Options that come from the button specific options first, then from general props color: opt.value === this.value ? mergeOption(opt, 'toggleColor') : mergeOption(opt, 'color'), textColor: opt.value === this.value ? mergeOption(opt, 'toggleTextColor') : mergeOption(opt, 'textColor'), noCaps: mergeOption(opt, 'noCaps') === true, noWrap: mergeOption(opt, 'noWrap') === true, size: mergeOption(opt, 'size'), padding: mergeOption(opt, 'padding'), ripple: mergeOption(opt, 'ripple'), stack: mergeOption(opt, 'stack') === true, stretch: mergeOption(opt, 'stretch') === true } } })) } }, methods: { __set (value, opt, e) { if (this.readonly !== true) { if (this.value === value) { if (this.clearable === true) { this.$emit('input', null, null) this.$emit('clear') } } else { this.$emit('input', value, opt) } this.$emit('click', e) } } }, render (h) { const child = this.btnOptions.map(opt => { return h(QBtn, opt.options, opt.slot !== void 0 ? slot(this, opt.slot) : void 0) }) if (this.name !== void 0 && this.disable !== true && this.hasActiveValue === true) { this.__injectFormInput(child, 'push') } return h(QBtnGroup, { staticClass: 'q-btn-toggle', props: { outline: this.outline, flat: this.flat, rounded: this.rounded, push: this.push, stretch: this.stretch, unelevated: this.unelevated, glossy: this.glossy, spread: this.spread } }, mergeSlot(child, this, 'default')) } })