UNPKG

@coreui/vue

Version:

UI Components Library for Vue.js

130 lines (126 loc) 4.82 kB
'use strict'; 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