@coreui/vue
Version:
UI Components Library for Vue.js
130 lines (126 loc) • 4.82 kB
JavaScript
var vue = require('vue');
var transition = require('../../utils/transition.js');
const CNavGroup = vue.defineComponent({
name: 'CNavGroup',
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
*/
as: {
type: String,
default: 'li',
},
/**
* Make nav group more compact by cutting all `padding` in half.
*/
compact: Boolean,
/**
* Show nav group items.
*/
visible: Boolean,
},
emits: ['visible-change'],
setup(props, { slots, emit }) {
const visible = vue.ref();
const navGroupRef = vue.ref();
const visibleGroup = vue.ref();
const handleVisibleChange = (visible, index) => {
if (visible) {
visibleGroup.value = index;
}
else {
if (visibleGroup.value === index) {
visibleGroup.value = 0;
}
}
};
const isVisible = (index) => Boolean(visibleGroup.value === index);
vue.onMounted(() => {
visible.value = props.visible;
props.visible && navGroupRef.value.classList.add('show');
emit('visible-change', visible.value);
});
vue.watch(() => props.visible, () => {
visible.value = props.visible;
if (visible.value === false) {
visibleGroup.value = undefined;
}
});
vue.watch(visible, () => {
emit('visible-change', visible.value);
});
const handleTogglerClick = () => {
visible.value = !visible.value;
emit('visible-change', visible.value);
};
const handleBeforeEnter = (el) => {
el.style.height = '0px';
navGroupRef.value.classList.add('show');
};
// eslint-disable-next-line unicorn/consistent-function-scoping
const handleEnter = (el, done) => {
transition.executeAfterTransition(() => done(), el);
el.style.height = `${el.scrollHeight}px`;
};
// eslint-disable-next-line unicorn/consistent-function-scoping
const handleAfterEnter = (el) => {
el.style.height = 'auto';
};
// eslint-disable-next-line unicorn/consistent-function-scoping
const handleBeforeLeave = (el) => {
el.style.height = `${el.scrollHeight}px`;
};
// eslint-disable-next-line unicorn/consistent-function-scoping
const handleLeave = (el, done) => {
transition.executeAfterTransition(() => done(), el);
setTimeout(() => {
el.style.height = '0px';
}, 1);
};
const handleAfterLeave = () => {
navGroupRef.value.classList.remove('show');
};
return () => vue.h(props.as, {
class: 'nav-group',
ref: navGroupRef,
}, [
slots.togglerContent &&
vue.h('a', {
class: ['nav-link', 'nav-group-toggle'],
onClick: handleTogglerClick,
}, slots.togglerContent && slots.togglerContent()),
vue.h(vue.Transition, {
css: false,
onBeforeEnter: (el) => handleBeforeEnter(el),
onEnter: (el, done) => handleEnter(el, done),
onAfterEnter: (el) => handleAfterEnter(el),
onBeforeLeave: (el) => handleBeforeLeave(el),
onLeave: (el, done) => handleLeave(el, done),
onAfterLeave: () => handleAfterLeave(),
}, {
default: () => visible.value &&
vue.h(props.as === 'div' ? 'div' : 'ul', {
class: [
'nav-group-items',
{
compact: props.compact,
},
],
}, slots.default &&
slots.default().map((vnode, index) => {
// @ts-expect-error name is defined in component
if (vnode.type.name === 'CNavGroup') {
return vue.h(vnode, {
onVisibleChange: (visible) => handleVisibleChange(visible, index + 1),
...(visibleGroup.value && { visible: isVisible(index + 1) }),
});
}
return vnode;
})),
}),
]);
},
});
exports.CNavGroup = CNavGroup;
//# sourceMappingURL=CNavGroup.js.map
;