1const { reactive, defineComponent, defineDirective, ref, computed, provide, inject, watch, h, TransitionGroup, onMounted, onUnmounted } = Vue; 2 3// function VMenu(slots) { 4// const openmenu = ref(0) 5 6// const open = function(){ 7// console.log('rets') 8// } 9 10// return /* html */ ` 11// <nav> 12// ${slots} 13// </nav> 14// ` 15// }; 16 17// Global Click Outside document evnet listener 18let clickOutsideEvents = []; 19const clickOutsideCheck = function (e) { 20 21 clickOutsideEvents.forEach(function (regEvt) { 22 if (!regEvt.el.contains(e.target)) { 23 regEvt.callback && regEvt.callback() 24 } 25 }); 26} 27document.addEventListener('click', clickOutsideCheck, false); 28const VClickOutside = { 29 mounted(el, { value }) { 30 // document.addEventListener('click', ClickOutsideCheck(el, value), false); 31 if (value) clickOutsideEvents.push({ el, callback: value }); 32 }, 33 unmounted(el, { value }) { 34 // document.removeEventListener('click', ClickOutsideCheck(el, value), false); 35 if (value) { 36 clickOutsideEvents = clickOutsideEvents.filter(function (val) { 37 return val.el !== el; 38 }); 39 } 40 } 41} 42 43// Custom Components 44const VHeader = defineComponent({ 45 props: ['alwaysSticky'], 46 setup(props) { 47 const sticky = ref(false); 48 const requestSticky = ref(false) 49 const shouldSticky = computed(() => sticky.value || requestSticky.value || props.alwaysSticky); 50 51 const setRequestSticky = (value) => { 52 requestSticky.value = value; 53 } 54 55 provide('useRequestSticky', { requestSticky, setRequestSticky }); 56 57 const detectScreen = function () { 58 sticky.value = window.scrollY > 10 || window.innerWidth < 1536; 59 } 60 61 window.addEventListener('scroll', function () { 62 detectScreen() 63 }) 64 window.addEventListener('resize', function () { 65 detectScreen() 66 }) 67 68 detectScreen(); 69 70 return { sticky, setRequestSticky, shouldSticky } 71 }, 72 template: /* html */ ` 73 <header :class="{'bg-white': shouldSticky}"> 74 <slot :requestSticky="setRequestSticky"></slot> 75 </header> 76 ` 77}) 78 79const VMenuItem = defineComponent({ 80 props: { 81 item: String 82 }, 83 setup(props, { emit, slots }) { 84 const isOpen = ref(false); 85 const isHover = ref(false); 86 const isSearch = ref(false); 87 const { requestSticky, setRequestSticky } = inject('useRequestSticky') 88 89 90 const open = function (e) { 91 setRequestSticky(true) 92 isHover.value = true; 93 94 // 95 if (!slots.body) return; 96 isOpen.value = true; 97 setTimeout(redirectToGroup, 300); 98 } 99 const close = function (e) { 100 setRequestSticky(false) 101 isHover.value = false; 102 103 if (!slots.body) return; 104 isOpen.value = false; 105 } 106 107 const isActive = ref(false) 108 109 isActive.value = ((!props.item == "") ? props.item.toUpperCase() : props.item) === window.location.pathname.split("/")[2].replaceAll("-", " ").toUpperCase() 110 111 return { isOpen, isHover, open, close, isActive } 112 }, 113 template: /* html */ ` 114 <div :class="{'hover': isHover, 'active': isActive }" @mouseenter="open" @mouseleave="close"> 115 <slot :isOpen="isOpen" :isHover="isHover"></slot> 116 117 <transition name="fx-submenu"> 118 <div class="submenu-container" v-if="isOpen"> 119 <div class="submenu"> 120 <slot name="body"></slot> 121 </div> 122 </div> 123 </transition> 124 </div> 125 ` 126}) 127 128 129const VCollapse = defineComponent({ 130 props: ['closeOnOutsideClick'], 131 setup(props, { slots }) { 132 const isOpen = ref(false); 133 const closeOnOutsideClick = props.closeOnOutsideClick !== undefined; 134 135 const toggleOpen = function () { 136 isOpen.value = !isOpen.value; 137 } 138 139 const handleClickOutside = function () { 140 if (closeOnOutsideClick) { 141 isOpen.value = false; 142 } 143 } 144 145 return { isOpen, toggleOpen, handleClickOutside }; 146 }, 147 directives: { 148 ClickOutside: VClickOutside 149 }, 150 template: /* html */` 151 <div v-click-outside="handleClickOutside"> 152 <div class="cursor-pointer" @click="toggleOpen()"><slot :isOpen="isOpen" :toggleOpen="toggleOpen"></slot></div> 153 <transition> 154 <div v-show="isOpen"><slot name="body"></slot></div> 155 </transition> 156 </div> 157 ` 158}) 159 160 161const VMobileMenu = defineComponent({ 162 setup(props, { slots }) { 163 const isOpen = ref(false) 164 const { setRequestSticky } = inject('useRequestSticky') 165 const { setIsLockScroll } = inject('useLockScroll'); 166 167 const toggleOpen = function () { 168 isOpen.value = !isOpen.value; 169 setTimeout(redirectToGroup, 300); 170 if (isOpen.value) { 171 setRequestSticky(true) 172 setIsLockScroll(true) 173 } else { 174 setRequestSticky(false) 175 setIsLockScroll(false) 176 } 177 } 178 179 return { isOpen, toggleOpen } 180 }, 181 template: /* html */ ` 182 <div> 183 <slot :isOpen="isOpen" :toggleOpen="toggleOpen"></slot> 184 </div> 185 ` 186}) 187 188const VMobileMenuItem = defineComponent({ 189 props: ['label'], 190 setup(props, { slots }) { 191 const isOpen = ref(false); 192 193 const setIsOpen = function (val) { 194 isOpen.value = val; 195 setTimeout(redirectToGroup, 300); 196 } 197 198 const hasSubmenu = !!slots.default; 199 200 return { isOpen, setIsOpen, hasSubmenu }; 201 }, 202 template: /* html */ ` 203 <a v-bind="$attrs" @click="setIsOpen(true)">{{label}} 204 <i v-if="hasSubmenu" class="fas fa-chevron-right"></i> 205 </a> 206 <transition name="custom-classes" 207 enter-active-class="animate__animated animate__slideInRight animate__faster" 208 leave-active-class="animate__animated animate__slideOutRight animate__faster"> 209 210 <div class="fixed top-0 left-0 right-0 bottom-0 bg-white divide-y" v-if="isOpen && hasSubmenu"> 211 <div class="h-16 relative px-8 flex justify-center items-center"> 212 <a class="p-3 block absolute left-2 text-base" href="javascript:;" @click="setIsOpen(false)"><i class="fas fa-chevron-left"></i></a>
213 <span class="text-lg font-bold">{{label}}</span> 214 </div> 215 <slot v-if="isOpen" v-bind="{isOpen, setIsOpen}"></slot> 216 </div> 217 </transition> 218 ` 219}) 220 221 222const VTabs = defineComponent({ 223 props: ['tabAlign'], 224 setup(props, { slots }) { 225 const formatHash = (str) => str ? str.toLowerCase().replace(/\s+/g, '-') : ''; 226 const getInitialHash = () => window.location.hash ? decodeURIComponent(window.location.hash.replace("#", "")) : ""; 227 const getTabKey = (tab) => formatHash(tab.props.hashKey || tab.props['hash-key'] || tab.props.label); 228 229 const currentIndex = ref(0); 230 let currentHash = ref(getInitialHash()); 231 232 const tabs = slots.default(); 233 234 const handleHashChange = () => { 235 currentHash.value = getInitialHash(); 236 }; 237 238 const changeTab = (idx, tab) => { 239 currentIndex.value = idx; 240 const newHash = getTabKey(tab); 241 window.location.hash = newHash; 242 currentHash.value = newHash; 243 } 244 245 const isActive = (tab, i, currentIndex) => { 246 let tempKey = getTabKey(tab); 247 if (currentHash.value != "") 248 return currentHash.value == tempKey 249 return i == currentIndex.value 250 } 251 252 onMounted(() => { 253 window.addEventListener('hashchange', handleHashChange); 254 }); 255 256 onUnmounted(() => { 257 window.removeEventListener('hashchange', handleHashChange); 258 }); 259 260 const renderControls = () => ( 261 h('div', { class: 'overflow-y-auto flex content-container pb-2 mb-3 no-scrollbar-style' }, 262 h('div', { class: ['flex space-x-6 xl:space-x-16', props.tabAlign == 'left' ? 'justify-start' : 'justify-center mx-auto'] }, 263 tabs.map((tab, i) => h('a', { 264 class: [ 265 'uppercase whitespace-nowrap font-bold text-base pb-4 lg:text-xl pb-1 relative after:absolute after:h-1 after:bottom-0 after:bg-primary after:left-0 after:transition-all', 266 isActive(tab, i, currentIndex) ? 'after:w-full text-primary' : 'after:w-0' 267 ], 268 href: tab.props.href, 269 onClick: () => tab.props.href == 'javascript:;' && changeTab(i, tab), 270 }, tab.props.label)) 271 ) 272 ) 273 ) 274 275 return () => ([ 276 renderControls(), 277 h(TransitionGroup, 278 { class: 'v-tab-panes', tag: 'div', name: "tab-fade" }, 279 { 280 default: () => 281 tabs.map((tab, i) => ({ ...tab, key: tab.props.label, props: { ...tab.props, 'show': isActive(tab, i, currentIndex) } })) 282 } 283 ) 284 ]) 285 } 286}) 287const VTab = defineComponent({ 288 props: ['label', 'show', 'href', 'hashKey'], 289 template: /* html */` 290 <div class="v-tab" v-show="show"> 291 <slot></slot> 292 </div> 293 ` 294}) 295 296 297 298 299// register components 300const App = Vue.createApp({ 301 components: { 302 VHeader, 303 VMenuItem, 304 VMobileMenu, 305 VMobileMenuItem, 306 VCollapse, 307 VTabs, 308 VTab, 309 }, 310 directives: { 311 ClickOutside: VClickOutside, 312 }, 313 setup() { 314 const isLockScroll = ref(); 315 316 const setIsLockScroll = function (value) { 317 isLockScroll.value = value; 318 } 319 320 provide('useLockScroll', { 321 isLockScroll, 322 setIsLockScroll 323 }) 324 325 watch(isLockScroll, function (newValue, oldValue) { 326 if (newValue) { 327 document.body.classList.add('lock-scroll'); 328 } else { 329 document.body.classList.remove('lock-scroll'); 330 } 331 332 }) 333 334 return { isLockScroll }; 335 } 336}) 337App.mount('#root')
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.