vue-sidebar-menu
Version:
A Vue.js Sidebar Menu Component
3 lines (2 loc) • 17.9 kB
JavaScript
(function(I,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(I=typeof globalThis<"u"?globalThis:I||self,e(I.VueSidebarMenu={},I.Vue))})(this,(function(I,e){"use strict";const he=["href","onClick"],ge={compatConfig:{MODE:3,inheritAttrs:!1}},be=e.defineComponent({...ge,__name:"SidebarMenuLink",props:{item:{}},setup(t){const l=t,r=e.getCurrentInstance()?.appContext.config.globalProperties.$router,n=e.computed(()=>!!(!l.item.href||l.item.external||!r));return(a,i)=>{const d=e.resolveComponent("router-link");return n.value?(e.openBlock(),e.createElementBlock("a",e.normalizeProps(e.mergeProps({key:0},a.$attrs)),[e.renderSlot(a.$slots,"default")],16)):(e.openBlock(),e.createBlock(d,{key:1,custom:"",to:a.$attrs.href},{default:e.withCtx(({href:p,navigate:s})=>[e.createElementVNode("a",e.mergeProps(a.$attrs,{href:p,onClick:s}),[e.renderSlot(a.$slots,"default")],16,he)]),_:3},8,["to"]))}}}),ke={compatConfig:{MODE:3}},we=e.defineComponent({...ke,__name:"SidebarMenuIcon",props:{icon:{}},setup(t){const l=t,r=e.computed(()=>({class:["vsm--icon",typeof l.icon=="object"?l.icon.class:l.icon],"aria-hidden":!0,...typeof l.icon=="object"?l.icon.attributes:{}}));return(n,a)=>typeof t.icon=="object"&&t.icon.text?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.icon.element?t.icon.element:"i"),e.normalizeProps(e.mergeProps({key:0},r.value)),{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.icon.text),1)]),_:1},16)):typeof t.icon=="object"?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.icon.element?t.icon.element:"i"),e.normalizeProps(e.mergeProps({key:1},r.value)),null,16)):(e.openBlock(),e.createElementBlock("i",e.normalizeProps(e.mergeProps({key:2},r.value)),null,16))}}),Ce={compatConfig:{MODE:3}},ve=e.defineComponent({...Ce,__name:"SidebarMenuBadge",props:{badge:{}},setup(t){const l=t,r=e.computed(()=>({class:["vsm--badge",l.badge.class],...l.badge.attributes}));return(n,a)=>t.badge.text?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.badge.element?t.badge.element:"span"),e.normalizeProps(e.mergeProps({key:0},r.value)),{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.badge.text),1)]),_:1},16)):(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.badge.element?t.badge.element:"span"),e.normalizeProps(e.mergeProps({key:1},r.value)),null,16))}});function ye(t){const l=Symbol(t.name||"SidebarInjectionState");return[(...a)=>{const i=t(...a);return e.provide(l,i),i},()=>e.inject(l)]}const[_e,Z]=ye((t,l,r,n,a,i,d,p,s,h,x,E)=>({getSidebarProps:t,getSidebarRef:l,getIsCollapsed:r,getMobileItem:n,getMobileItemRect:a,getCurrentRoute:i,updateIsCollapsed:d,setMobileItem:p,unsetMobileItem:s,clearMobileItemTimeout:h,onRouteChange:x,emitItemClick:E}));function Be(t,l){const{matched:r}=t,{length:n}=r,a=r[n-1],i=l.matched;if(!a||!i.length)return-1;const d=i.findIndex(se.bind(null,a));if(d>-1)return d;const p=ie(r[n-2]);return n>1&&ie(a)===p&&i[i.length-1].path!==p?i.findIndex(se.bind(null,r[n-2])):d}function Se(t,l){if(Object.keys(t).length!==Object.keys(l).length)return!1;for(const r in t)if(!Me(t[r],l[r]))return!1;return!0}function xe(t,l){for(const r in l){const n=l[r],a=t[r];if(typeof n=="string"){if(n!==a)return!1}else if(!Array.isArray(a)||a.length!==n.length||n.some((i,d)=>i!==a[d]))return!1}return!0}function ie(t){return t?t.aliasOf?t.aliasOf.path:t.path:""}function se(t,l){return(t.aliasOf||t)===(l.aliasOf||l)}function Me(t,l){return Array.isArray(t)?ce(t,l):Array.isArray(l)?ce(l,t):t===l}function ce(t,l){return Array.isArray(l)?t.length===l.length&&t.every((r,n)=>r===l[n]):t.length===1&&t[0]===l}const Ee={class:"vsm--dropdown"},Ie={compatConfig:{MODE:3}},Re=e.defineComponent({...Ie,__name:"SidebarMenuItemLink",props:{item:{},level:{},activeShow:{}},emits:["update-active-show"],setup(t,{emit:l}){const r=t,n=l,{getSidebarRef:a,getSidebarProps:i,getIsCollapsed:d,getMobileItem:p,getMobileItemRect:s,getCurrentRoute:h,setMobileItem:x,unsetMobileItem:E,clearMobileItemTimeout:O,emitItemClick:R}=Z(),{linkComponentName:T}=e.toRefs(i),{item:c,activeShow:z,level:$}=e.toRefs(r),A=e.ref(void 0),m=e.computed(()=>$.value===1),w=o=>{A.value=o},B=e.getCurrentInstance()?.appContext.config.globalProperties.$router,N=e.inject("SidebarMenuScroll"),G=e.ref(!1),j=e.ref(!1),M=(o,k)=>{if(o.isActive&&typeof o.isActive=="function"){const b=o.isActive(o);if(typeof b=="boolean")return b}if(!o.href||o.external)return!1;if(B){const b=B.resolve(o.href),v=B.currentRoute.value,y=Be(b,v);return k||o.exact?y>-1&&y===v.matched.length-1&&Se(v.params,b.params):y>-1&&xe(v.params,b.params)}else return o.href===h.value},J=o=>o?o.some(k=>K(k)&&(M(k)||J(k.child))):!1,W=e.computed(()=>M(c.value)||J(c.value.child)),U=e.computed(()=>M(c.value,!0)),ee=o=>{(!c.value.href||c.value.disabled)&&(o.preventDefault(),c.value.disabled)||(D(o,o.currentTarget.parentElement),S.value&&(!c.value.href||W.value)&&(_.value=!_.value),R(o,c.value))},te=o=>{o.stopPropagation(),o.preventDefault(),!c.value.disabled&&(S.value&&(_.value=!_.value),R(o,c.value))},u=o=>{c.value.disabled||(o.stopPropagation(),j.value=!0)},f=o=>{o.stopPropagation(),j.value=!1},C=o=>{c.value.disabled||(i.disableHover?g.value&&S.value&&O():(O(),D(o,o.currentTarget)))},P=()=>{i.disableHover&&!S.value||g.value&&E(!1,i.disableHover?void 0:300)},D=(o,k)=>{g.value||d.value&&setTimeout(()=>{m.value&&!g.value&&x({item:c.value,itemEl:k}),o.type==="click"&&!S.value&&E(!1,m.value?void 0:300)},0)},oe=o=>{o.style.height=o.scrollHeight+"px"},ne=o=>{if(o.style.height="auto",!d.value){if(i.smoothScroll){const k=a.value?.children[0],b=o.parentElement;if(k&&b){const v=b.getBoundingClientRect().bottom,y=k.getBoundingClientRect().bottom;v>y&&e.nextTick(()=>b.scrollIntoView({behavior:"smooth",block:"nearest"}))}}N()}},le=o=>{if(d.value&&m.value){o.style.display="none";return}o.style.height=o.scrollHeight+"px"},re=()=>{d.value||N()};function K(o){return!("header"in o)&&!("component"in o)}const _=e.computed({get:()=>S.value?d.value&&m.value?F.value:i.showChild?!0:i.showOneChild&&m.value||i.showOneChild==="deep"?c.value.id===z.value:G.value:!1,set:o=>{(i.showOneChild&&m.value||i.showOneChild==="deep")&&n("update-active-show",o?c.value.id:void 0),G.value=o}}),F=e.computed(()=>d.value&&m.value?g.value:j.value),S=e.computed(()=>"child"in c.value&&!!c.value.child?.length),V=e.computed(()=>["vsm--link",`vsm--link_level-${$.value}`,{"vsm--link_mobile":g.value,"vsm--link_hover":F.value,"vsm--link_active":W.value,"vsm--link_disabled":c.value.disabled,"vsm--link_open":_.value},c.value.class]),Y=e.computed(()=>{const o=c.value.href?c.value.href:"#",k=c.value.external?"_blank":"_self",b=c.value.disabled?-1:null,v=U.value?"page":null,y=S.value?_.value:null,ue=y?`vsm-${r.item.id}`:null;return{href:o,target:k,tabindex:b,"aria-current":v,"aria-expanded":y,"aria-controls":ue,...c.value.attributes}}),H=e.computed(()=>({id:`vsm-${c.value.id}`})),q=e.computed(()=>["vsm--item",{"vsm--item_mobile":g.value}]),g=e.computed(()=>r.item.id===p.value?.id),L=o=>i.rtl?{right:o}:{left:o},Q=e.computed(()=>({position:"absolute","max-height":`${s.value.maxHeight}px`,width:`${s.value.maxWidth}px`,"overflow-y":"auto","z-index":"20",...s.value.dropup?{bottom:`${s.value.dropup}px`}:{top:`${s.value.top+s.value.height}px`},...L(i.widthCollapsed)})),X=e.computed(()=>({position:"absolute",top:`${s.value.top}px`,...L(i.widthCollapsed),width:`${s.value.maxWidth}px`,height:`${s.value.height}px`,"padding-left":`${s.value.padding[0]}px`,"padding-right":`${s.value.padding[1]}px`,"z-index":"20"})),ae=e.computed(()=>({position:"absolute",top:`${s.value.top}px`,...i.rtl?{right:"0px"}:{left:"0px"},width:`${s.value.maxWidth+parseInt(i.widthCollapsed)}px`,height:`${s.value.height}px`,"z-index":"10"}));return e.watch(()=>W.value,o=>{o&&(_.value=!0)},{immediate:!0}),(o,k)=>(e.openBlock(),e.createElementBlock("li",e.mergeProps({class:q.value,onMouseover:u,onMouseout:f},e.toHandlers(e.unref(d)&&m.value?{mouseenter:C,mouseleave:P}:{},!0)),[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(e.unref(T)?e.unref(T):be),e.mergeProps({item:e.unref(c),class:V.value},Y.value,{onClick:ee}),{default:e.withCtx(()=>[e.unref(d)&&m.value?(e.openBlock(),e.createBlock(e.Transition,{key:0,name:"slide-animation"},{default:e.withCtx(()=>[F.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"vsm--mobile-bg",style:e.normalizeStyle(ae.value)},null,4)):e.createCommentVNode("",!0)]),_:1})):e.createCommentVNode("",!0),e.unref(c).icon?(e.openBlock(),e.createBlock(we,{key:1,icon:e.unref(c).icon},null,8,["icon"])):e.createCommentVNode("",!0),e.createElementVNode("div",{class:e.normalizeClass(["vsm--title",e.unref(d)&&m.value&&!g.value&&"vsm--title_hidden"]),style:e.normalizeStyle(g.value&&X.value)},[e.createElementVNode("span",null,e.toDisplayString(e.unref(c).title),1),e.unref(c).badge?(e.openBlock(),e.createBlock(ve,{key:0,badge:e.unref(c).badge},null,8,["badge"])):e.createCommentVNode("",!0),S.value?(e.openBlock(),e.createElementBlock("div",{key:1,class:e.normalizeClass(["vsm--arrow",{"vsm--arrow_open":_.value}]),onClick:e.withModifiers(te,["stop"])},[e.renderSlot(o.$slots,"dropdown-icon",e.normalizeProps(e.guardReactiveProps({isOpen:_.value,toggle:te})))],2)):e.createCommentVNode("",!0)],6)]),_:3},16,["item","class"])),S.value?(e.openBlock(),e.createBlock(e.Transition,{key:0,appear:g.value,name:"expand",onEnter:oe,onAfterEnter:ne,onBeforeLeave:le,onAfterLeave:re},{default:e.withCtx(()=>[_.value?(e.openBlock(),e.createElementBlock("div",e.mergeProps({key:0,class:["vsm--child",g.value&&"vsm--child_mobile"],style:g.value&&Q.value},H.value),[e.createElementVNode("ul",Ee,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(c).child,b=>(e.openBlock(),e.createBlock(de,{key:b.id,item:b,level:e.unref($)+1,"active-show":A.value,onUpdateActiveShow:w},{"dropdown-icon":e.withCtx(({isOpen:v,toggle:y})=>[e.renderSlot(o.$slots,"dropdown-icon",e.mergeProps({ref_for:!0},{isOpen:v,toggle:y}))]),_:3},8,["item","level","active-show"]))),128))])],16)):e.createCommentVNode("",!0)]),_:3},8,["appear"])):e.createCommentVNode("",!0)],16))}}),$e={key:0},Pe={compatConfig:{MODE:3}},de=e.defineComponent({...Pe,__name:"SidebarMenuItem",props:{item:{},level:{},activeShow:{}},emits:["update-active-show"],setup(t){const l=t,{getIsCollapsed:r}=Z(),{item:n,activeShow:a,level:i}=e.toRefs(l),d=e.computed(()=>r.value?l.item.hidden&&l.item.hiddenOnCollapse===void 0?!0:l.item.hiddenOnCollapse===!0:l.item.hidden===!0);return(p,s)=>d.value?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},["component"in e.unref(n)?(e.openBlock(),e.createElementBlock("li",$e,[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(e.unref(n).component),e.normalizeProps(e.guardReactiveProps(e.unref(n).props)),null,16))])):"header"in e.unref(n)?(e.openBlock(),e.createElementBlock("li",e.mergeProps({key:1,class:["vsm--header",e.unref(n).class]},e.unref(n).attributes),e.toDisplayString(e.unref(n).header),17)):(e.openBlock(),e.createBlock(Re,{key:2,item:e.unref(n),level:e.unref(i),"active-show":e.unref(a),onUpdateActiveShow:s[0]||(s[0]=h=>p.$emit("update-active-show",h))},{"dropdown-icon":e.withCtx(({isOpen:h,toggle:x})=>[e.renderSlot(p.$slots,"dropdown-icon",e.normalizeProps(e.guardReactiveProps({isOpen:h,toggle:x})))]),_:3},8,["item","level","active-show"]))],64))}}),He={compatConfig:{MODE:3}},Te=e.defineComponent({...He,__name:"SidebarMenuScroll",setup(t){const{getIsCollapsed:l}=Z(),r=e.ref(null),n=e.ref(null),a=e.ref(null),i=e.ref(!1);let d=0,p=!1;const s=e.ref(!1),h=()=>{r.value&&e.nextTick(()=>{$()})},x=()=>{requestAnimationFrame(h)},E=m=>{if(!r.value||!n.value||!a.value)return;const w=Math.abs(n.value.getBoundingClientRect().y-m.clientY),B=a.value.offsetHeight/2;A(w-B)},O=m=>{!r.value||!n.value||!a.value||(m.stopImmediatePropagation(),i.value=!0,window.addEventListener("mousemove",R),window.addEventListener("mouseup",T),d=a.value.offsetHeight-(m.clientY-a.value.getBoundingClientRect().y))},R=m=>{if(!r.value||!n.value||!a.value||!i.value)return;const w=m.clientY-n.value.getBoundingClientRect().y,B=a.value.offsetHeight-d;s.value=!0,A(w-B)},T=m=>{i.value=!1,d=0,p||(s.value=!1),window.removeEventListener("mousemove",R),window.removeEventListener("mouseup",T)},c=m=>{s.value=!0,p=!0},z=m=>{p=!1,i.value||(s.value=!1)},$=()=>{if(!r.value||!n.value||!a.value)return;const m=r.value.clientHeight*100/r.value.scrollHeight,w=m<100?m:0,B=r.value.scrollTop*100/r.value.clientHeight||0;a.value.style.height=`${w}%`,a.value.style.transform=`translateY(${B}%)`},A=m=>{if(!r.value||!n.value||!a.value)return;const w=m*100/n.value.offsetHeight;r.value.scrollTop=w*r.value.scrollHeight/100};return e.watch(()=>l.value,()=>{h()}),e.onMounted(()=>{h(),window.addEventListener("resize",h)}),e.onUnmounted(()=>{window.removeEventListener("resize",h)}),e.provide("SidebarMenuScroll",h),(m,w)=>(e.openBlock(),e.createElementBlock("div",{class:"vsm--scroll-wrapper",onMouseenter:c,onMouseleave:z},[e.createElementVNode("div",{ref_key:"scrollRef",ref:r,class:"vsm--scroll",onScroll:x},[e.renderSlot(m.$slots,"default",{},void 0,!0)],544),e.createVNode(e.Transition,null,{default:e.withCtx(()=>[e.withDirectives(e.createElementVNode("div",{ref_key:"scrollBarRef",ref:n,class:"vsm--scroll-bar",onMousedown:E},[e.createElementVNode("div",{ref_key:"scrollThumbRef",ref:a,class:e.normalizeClass(["vsm--scroll-thumb",[i.value&&"vsm--scroll-thumb_clicking"]]),onMousedown:O},null,34)],544),[[e.vShow,s.value]])]),_:1})],32))}}),Ae=((t,l)=>{const r=t.__vccOpts||t;for(const[n,a]of l)r[n]=a;return r})(Te,[["__scopeId","data-v-2640f004"]]),Le={class:"vsm--wrapper"},Oe=["aria-label"],Ne={compatConfig:{MODE:3}},me=e.defineComponent({...Ne,__name:"SidebarMenu",props:{menu:{},collapsed:{type:Boolean},width:{default:"290px"},widthCollapsed:{default:"65px"},showOneChild:{type:[Boolean,String]},showChild:{type:Boolean},rtl:{type:Boolean},relative:{type:Boolean},hideToggle:{type:Boolean},theme:{},disableHover:{type:Boolean},linkComponentName:{},smoothScroll:{type:Boolean}},emits:["item-click","update:collapsed"],setup(t,{expose:l,emit:r}){const n=t,a=r,{collapsed:i}=e.toRefs(n),d=e.ref(null),p=e.ref(i.value),s=e.reactive({item:null,rect:{top:0,height:0,padding:[0,0],maxHeight:0,maxWidth:0,dropup:0},timeout:null}),h=e.ref(""),x=e.ref(void 0),E=e.computed(()=>s.item),O=e.computed(()=>s.rect),R=e.computed(()=>p.value?n.widthCollapsed:n.width),T=e.computed(()=>["v-sidebar-menu",p.value?"vsm_collapsed":"vsm_expanded",n.theme&&`vsm_${n.theme}`,n.rtl&&"vsm_rtl",n.relative&&"vsm_relative"]);let c=0;const z=()=>`${Date.now()}${c++}`;function $(u){return u?u.map(f=>{const C={...f,id:f.id??z()};return C.child&&(C.child=$(C.child)),C}):[]}const A=e.computed(()=>$(n.menu)),m=()=>{s.timeout&&(clearTimeout(s.timeout),s.timeout=null)},w=u=>{s.item=u},B=u=>{for(const f in u)s.rect[f]=u[f]},N=(u=!0,f=800)=>{if(E.value){if(m(),u){w(null);return}s.timeout=setTimeout(()=>w(null),f)}},G=u=>{if(!d.value)return;const{top:f,bottom:C,height:P}=u.getBoundingClientRect(),{left:D,right:oe}=d.value.getBoundingClientRect(),ne=d.value.firstElementChild,{bottom:le,height:re}=ne.getBoundingClientRect(),K=u.offsetParent,_=K.offsetTop,{top:F,height:S}=K.getBoundingClientRect();let V=window.innerHeight,Y=window.innerWidth,H=0,q=Y,g=Math.max(parseInt(n.width)-parseInt(n.widthCollapsed),0);const L=d.value.parentElement;if(L&&n.relative){V=L.clientHeight,Y=L.clientWidth;const fe=L.getBoundingClientRect();H=fe.top,q=fe.right}const Q=n.rtl?Y-(q-D):q-oe;g=Q<=g?Q:g;const X=window.getComputedStyle(u),ae=parseInt(X.paddingLeft||"0",10),o=parseInt(X.paddingRight||"0",10),k=f-F,b=le-f-(re-(S+_));let v=V-(C-H);const y=Math.min(window.innerHeight,window.innerHeight-H,V,V+H),pe=y-(Math.max(C,0)-Math.max(H,0))<y*.25?b:0;return v=pe?f-H:v,{top:k,height:P,padding:[ae,o],maxWidth:g,maxHeight:v,dropup:pe}},j=({item:u,itemEl:f})=>{m();const C=f.children[0],P=G(C);P&&(w(u),B(P))},M=()=>{h.value=window.location.pathname+window.location.search+window.location.hash},J=(u,f)=>{a("item-click",u,f)},W=u=>{x.value=u},U=u=>{p.value=u},ee=()=>{N(),U(!p.value),a("update:collapsed",p.value)};return e.getCurrentInstance()?.appContext.config.globalProperties.$router||(e.onMounted(()=>{M(),window.addEventListener("hashchange",M)}),e.onUnmounted(()=>{window.removeEventListener("hashchange",M)})),e.watch(()=>i.value,u=>{N(),U(u)}),_e(n,d,p,E,O,h,U,j,N,m,M,J),e.provide("onRouteChange",M),l({onRouteChange:M}),(u,f)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"sidebarRef",ref:d,class:e.normalizeClass(T.value),style:e.normalizeStyle({"max-width":R.value})},[e.createElementVNode("div",Le,[e.renderSlot(u.$slots,"header"),e.createVNode(Ae,null,{default:e.withCtx(()=>[e.createElementVNode("ul",{class:"vsm--menu",style:e.normalizeStyle({width:R.value})},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(A.value,C=>(e.openBlock(),e.createBlock(de,{key:C.id,item:C,level:1,"active-show":x.value,onUpdateActiveShow:W},{"dropdown-icon":e.withCtx(({isOpen:P,toggle:D})=>[e.renderSlot(u.$slots,"dropdown-icon",e.mergeProps({ref_for:!0},{isOpen:P,toggle:D}),()=>[f[0]||(f[0]=e.createElementVNode("span",{class:"vsm--arrow_default"},null,-1))])]),_:3},8,["item","active-show"]))),128))],4)]),_:3}),e.renderSlot(u.$slots,"footer")]),t.hideToggle?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:0,class:"vsm--toggle-btn","aria-label":e.unref(i)?"Expand sidebar":"Collapse sidebar",onClick:ee},[e.renderSlot(u.$slots,"toggle-icon",{},()=>[f[1]||(f[1]=e.createElementVNode("span",{class:"vsm--toggle-btn_default"},null,-1))])],8,Oe))],6))}}),De={install(t){t.component("SidebarMenu",me)}};I.SidebarMenu=me,I.default=De,Object.defineProperties(I,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
//# sourceMappingURL=vue-sidebar-menu.js.map