175 lines
4.5 KiB
JavaScript
175 lines
4.5 KiB
JavaScript
|
// Styles
|
||
|
import "../../../src/components/VList/VListGroup.sass"; // Components
|
||
|
|
||
|
import VIcon from '../VIcon';
|
||
|
import VListItem from './VListItem';
|
||
|
import VListItemIcon from './VListItemIcon'; // Mixins
|
||
|
|
||
|
import Bootable from '../../mixins/bootable';
|
||
|
import Colorable from '../../mixins/colorable';
|
||
|
import Toggleable from '../../mixins/toggleable';
|
||
|
import { inject as RegistrableInject } from '../../mixins/registrable'; // Directives
|
||
|
|
||
|
import ripple from '../../directives/ripple'; // Transitions
|
||
|
|
||
|
import { VExpandTransition } from '../transitions'; // Utils
|
||
|
|
||
|
import mixins from '../../util/mixins';
|
||
|
const baseMixins = mixins(Bootable, Colorable, RegistrableInject('list'), Toggleable);
|
||
|
export default baseMixins.extend().extend({
|
||
|
name: 'v-list-group',
|
||
|
directives: {
|
||
|
ripple
|
||
|
},
|
||
|
props: {
|
||
|
activeClass: {
|
||
|
type: String,
|
||
|
default: ''
|
||
|
},
|
||
|
appendIcon: {
|
||
|
type: String,
|
||
|
default: '$vuetify.icons.expand'
|
||
|
},
|
||
|
color: {
|
||
|
type: String,
|
||
|
default: 'primary'
|
||
|
},
|
||
|
disabled: Boolean,
|
||
|
group: String,
|
||
|
noAction: Boolean,
|
||
|
prependIcon: String,
|
||
|
ripple: {
|
||
|
type: [Boolean, Object],
|
||
|
default: true
|
||
|
},
|
||
|
subGroup: Boolean
|
||
|
},
|
||
|
computed: {
|
||
|
classes() {
|
||
|
return {
|
||
|
'v-list-group--active': this.isActive,
|
||
|
'v-list-group--disabled': this.disabled,
|
||
|
'v-list-group--no-action': this.noAction,
|
||
|
'v-list-group--sub-group': this.subGroup
|
||
|
};
|
||
|
}
|
||
|
|
||
|
},
|
||
|
watch: {
|
||
|
isActive(val) {
|
||
|
/* istanbul ignore else */
|
||
|
if (!this.subGroup && val) {
|
||
|
this.list && this.list.listClick(this._uid);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
$route: 'onRouteChange'
|
||
|
},
|
||
|
|
||
|
created() {
|
||
|
this.list && this.list.register(this);
|
||
|
|
||
|
if (this.group && this.$route && this.value == null) {
|
||
|
this.isActive = this.matchRoute(this.$route.path);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
beforeDestroy() {
|
||
|
this.list && this.list.unregister(this);
|
||
|
},
|
||
|
|
||
|
methods: {
|
||
|
click(e) {
|
||
|
if (this.disabled) return;
|
||
|
this.isBooted = true;
|
||
|
this.$emit('click', e);
|
||
|
this.$nextTick(() => this.isActive = !this.isActive);
|
||
|
},
|
||
|
|
||
|
genIcon(icon) {
|
||
|
return this.$createElement(VIcon, icon);
|
||
|
},
|
||
|
|
||
|
genAppendIcon() {
|
||
|
const icon = !this.subGroup ? this.appendIcon : false;
|
||
|
if (!icon && !this.$slots.appendIcon) return null;
|
||
|
return this.$createElement(VListItemIcon, {
|
||
|
staticClass: 'v-list-group__header__append-icon'
|
||
|
}, [this.$slots.appendIcon || this.genIcon(icon)]);
|
||
|
},
|
||
|
|
||
|
genHeader() {
|
||
|
return this.$createElement(VListItem, {
|
||
|
staticClass: 'v-list-group__header',
|
||
|
attrs: {
|
||
|
'aria-expanded': String(this.isActive),
|
||
|
role: 'button'
|
||
|
},
|
||
|
class: {
|
||
|
[this.activeClass]: this.isActive
|
||
|
},
|
||
|
props: {
|
||
|
inputValue: this.isActive
|
||
|
},
|
||
|
directives: [{
|
||
|
name: 'ripple',
|
||
|
value: this.ripple
|
||
|
}],
|
||
|
on: { ...this.$listeners,
|
||
|
click: this.click
|
||
|
}
|
||
|
}, [this.genPrependIcon(), this.$slots.activator, this.genAppendIcon()]);
|
||
|
},
|
||
|
|
||
|
genItems() {
|
||
|
return this.$createElement('div', {
|
||
|
staticClass: 'v-list-group__items',
|
||
|
directives: [{
|
||
|
name: 'show',
|
||
|
value: this.isActive
|
||
|
}]
|
||
|
}, this.showLazyContent([this.$createElement('div', this.$slots.default)]));
|
||
|
},
|
||
|
|
||
|
genPrependIcon() {
|
||
|
const icon = this.prependIcon ? this.prependIcon : this.subGroup ? '$vuetify.icons.subgroup' : false;
|
||
|
if (!icon && !this.$slots.prependIcon) return null;
|
||
|
return this.$createElement(VListItemIcon, {
|
||
|
staticClass: 'v-list-group__header__prepend-icon'
|
||
|
}, [this.$slots.prependIcon || this.genIcon(icon)]);
|
||
|
},
|
||
|
|
||
|
onRouteChange(to) {
|
||
|
/* istanbul ignore if */
|
||
|
if (!this.group) return;
|
||
|
const isActive = this.matchRoute(to.path);
|
||
|
/* istanbul ignore else */
|
||
|
|
||
|
if (isActive && this.isActive !== isActive) {
|
||
|
this.list && this.list.listClick(this._uid);
|
||
|
}
|
||
|
|
||
|
this.isActive = isActive;
|
||
|
},
|
||
|
|
||
|
toggle(uid) {
|
||
|
const isActive = this._uid === uid;
|
||
|
if (isActive) this.isBooted = true;
|
||
|
this.$nextTick(() => this.isActive = isActive);
|
||
|
},
|
||
|
|
||
|
matchRoute(to) {
|
||
|
return to.match(this.group) !== null;
|
||
|
}
|
||
|
|
||
|
},
|
||
|
|
||
|
render(h) {
|
||
|
return h('div', this.setTextColor(this.isActive && this.color, {
|
||
|
staticClass: 'v-list-group',
|
||
|
class: this.classes
|
||
|
}), [this.genHeader(), h(VExpandTransition, [this.genItems()])]);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
//# sourceMappingURL=VListGroup.js.map
|