// Styles import "../../../src/components/VItemGroup/VItemGroup.sass"; import Proxyable from '../../mixins/proxyable'; import Themeable from '../../mixins/themeable'; // Utilities import mixins from '../../util/mixins'; import { consoleWarn } from '../../util/console'; export const BaseItemGroup = mixins(Proxyable, Themeable).extend({ name: 'base-item-group', props: { activeClass: { type: String, default: 'v-item--active' }, mandatory: Boolean, max: { type: [Number, String], default: null }, multiple: Boolean }, data() { return { // As long as a value is defined, show it // Otherwise, check if multiple // to determine which default to provide internalLazyValue: this.value !== undefined ? this.value : this.multiple ? [] : undefined, items: [] }; }, computed: { classes() { return { 'v-item-group': true, ...this.themeClasses }; }, selectedItem() { if (this.multiple) return undefined; return this.items.find((item, index) => { return this.toggleMethod(this.getValue(item, index)); }); }, selectedItems() { return this.items.filter((item, index) => { return this.toggleMethod(this.getValue(item, index)); }); }, selectedValues() { if (this.internalValue == null) return []; return Array.isArray(this.internalValue) ? this.internalValue : [this.internalValue]; }, toggleMethod() { if (!this.multiple) { return v => this.internalValue === v; } const internalValue = this.internalValue; if (Array.isArray(internalValue)) { return v => internalValue.includes(v); } return () => false; } }, watch: { internalValue() { // https://github.com/vuetifyjs/vuetify/issues/5352 this.$nextTick(this.updateItemsState); } }, created() { if (this.multiple && !Array.isArray(this.internalValue)) { consoleWarn('Model must be bound to an array if the multiple property is true.', this); } }, methods: { genData() { return { class: this.classes }; }, getValue(item, i) { return item.value == null || item.value === '' ? i : item.value; }, onClick(item) { this.updateInternalValue(this.getValue(item, this.items.indexOf(item))); }, register(item) { const index = this.items.push(item) - 1; item.$on('change', () => this.onClick(item)); // If no value provided and mandatory, // assign first registered item if (this.mandatory && this.internalLazyValue == null) { this.updateMandatory(); } this.updateItem(item, index); }, unregister(item) { if (this._isDestroyed) return; const index = this.items.indexOf(item); const value = this.getValue(item, index); this.items.splice(index, 1); const valueIndex = this.selectedValues.indexOf(value); // Items is not selected, do nothing if (valueIndex < 0) return; // If not mandatory, use regular update process if (!this.mandatory) { return this.updateInternalValue(value); } // Remove the value if (this.multiple && Array.isArray(this.internalValue)) { this.internalValue = this.internalValue.filter(v => v !== value); } else { this.internalValue = undefined; } // If mandatory and we have no selection // add the last item as value /* istanbul ignore else */ if (!this.selectedItems.length) { this.updateMandatory(true); } }, updateItem(item, index) { const value = this.getValue(item, index); item.isActive = this.toggleMethod(value); }, updateItemsState() { if (this.mandatory && !this.selectedItems.length) { return this.updateMandatory(); } // TODO: Make this smarter so it // doesn't have to iterate every // child in an update this.items.forEach(this.updateItem); }, updateInternalValue(value) { this.multiple ? this.updateMultiple(value) : this.updateSingle(value); }, updateMandatory(last) { if (!this.items.length) return; const items = this.items.slice(); if (last) items.reverse(); const item = items.find(item => !item.disabled); // If no tabs are available // aborts mandatory value if (!item) return; const index = this.items.indexOf(item); this.updateInternalValue(this.getValue(item, index)); }, updateMultiple(value) { const defaultValue = Array.isArray(this.internalValue) ? this.internalValue : []; const internalValue = defaultValue.slice(); const index = internalValue.findIndex(val => val === value); if (this.mandatory && // Item already exists index > -1 && // value would be reduced below min internalValue.length - 1 < 1) return; if ( // Max is set this.max != null && // Item doesn't exist index < 0 && // value would be increased above max internalValue.length + 1 > this.max) return; index > -1 ? internalValue.splice(index, 1) : internalValue.push(value); this.internalValue = internalValue; }, updateSingle(value) { const isSame = value === this.internalValue; if (this.mandatory && isSame) return; this.internalValue = isSame ? undefined : value; } }, render(h) { return h('div', this.genData(), this.$slots.default); } }); export default BaseItemGroup.extend({ name: 'v-item-group', provide() { return { itemGroup: this }; } }); //# sourceMappingURL=VItemGroup.js.map