1/* Template Name: Evea - Responsive App Landing Tailwind CSS Template 2 Author: Zoyothemes 3 Email: [email protected] 4 Website: https://zoyothemes.com 5 Version: 1.0.0 6 Created: March 2024 7 File Description: Main JS file of the template 8*/ 9 10/*********************************/ 11/* INDEX */ 12/*================================ 13 * 01. Sticky Navbar * 14 * 02. Navbar active * 15 * 03. Back to top * 16 * 04. Accordions * 17 * 05. Lucide Icons * 18 ================================*/ 19 20/*********************/ 21/* Sticky Navbar */ 22/*********************/ 23function windowScroll() { 24 const navbar = document.getElementById("navbar"); 25 26 if (navbar) { 27 if ( 28 document.body.scrollTop >= 50 || 29 document.documentElement.scrollTop >= 50 30 ) { 31 navbar.classList.add("is-sticky"); 32 } else { 33 navbar.classList.remove("is-sticky"); 34 } 35 } 36} 37window.addEventListener("scroll", (ev) => { 38 ev.preventDefault(); 39 windowScroll(); 40}); 41 42 43/*********************/ 44/* Navbar Active */ 45/*********************/ 46try { 47 var spy = new Gumshoe("#navbar-navlist a", { 48 // Active classes 49 // navClass: 'active', // applied to the nav list item 50 // contentClass: 'active', // applied to the content 51 offset: 80, 52 }); 53} catch (error) {} 54 55// Smooth scroll 56try { 57 var scroll = new SmoothScroll("#navbar-navlist a", { 58 speed: 800, 59 offset: 80, 60 }); 61} catch (error) {} 62 63 64/*********************/ 65/* Menu Collapse */ 66/*********************/ 67const toggleCollapse = (elementId, show = true) => { 68 const collapseEl = document.getElementById(elementId); 69 if (show) { 70 collapseEl.classList.remove("hidden"); 71 } else { 72 collapseEl.classList.add("hidden"); 73 } 74}; 75 76document.addEventListener("DOMContentLoaded", () => { 77 // Toggle target elements using [data-collapse] 78 document 79 .querySelectorAll("[data-collapse]") 80 .forEach(function (collapseToggleEl) { 81 var collapseId = collapseToggleEl.getAttribute("data-collapse"); 82 83 collapseToggleEl.addEventListener("click", function () { 84 toggleCollapse( 85 collapseId, 86 document.getElementById(collapseId).classList.contains("hidden") 87 ); 88 }); 89 }); 90}); 91 92window.toggleCollapse = toggleCollapse; 93 94/*********************/ 95/* Back To Top */ 96/*********************/ 97var mybutton = document.getElementById("back-to-top"); 98window.onscroll = function () { 99 scrollFunction(); 100}; 101 102function scrollFunction() { 103 if(mybutton!=null){ 104 if (document.body.scrollTop > 500 || document.documentElement.scrollTop > 500) { 105 mybutton.style.display = "inline-flex"; 106 } else { 107 mybutton.style.display = "none"; 108 } 109 } 110} 111 112function topFunction() { 113 document.body.scrollTop = 0; 114 document.documentElement.scrollTop = 0; 115} 116 117/*********************/ 118/* Accordions */ 119/*********************/ 120try { 121 const Default = { 122 alwaysOpen: false, 123 activeClasses: 'bg-white text-black rounded-xl', 124 inactiveClasses: 'text-dark', 125 onOpen: () => { }, 126 onClose: () => { }, 127 onToggle: () => { } 128 } 129 130 class Accordion { 131 constructor(items = [], options = {}) { 132 this._items = items 133 this._options = { ...Default, ...options } 134 this._init() 135 } 136 137 _init() { 138 if (this._items.length) { 139 // show accordion item based on click 140 this._items.map(item => { 141 142 if (item.active) { 143 this.open(item.id) 144 } 145 146 item.triggerEl.addEventListener('click', () => { 147 this.toggle(item.id) 148 }) 149 }) 150 } 151 } 152 153 getItem(id) { 154 return this._items.filter(item => item.id === id)[0] 155 } 156 157 open(id) { 158 const item = this.getItem(id) 159 160 // don't hide other accordions if always open 161 if (!this._options.alwaysOpen) { 162 this._items.map(i => { 163 if (i !== item) { 164 i.triggerEl.classList.remove(...this._options.activeClasses.split(" ")) 165 i.triggerEl.classList.add(...this._options.inactiveClasses.split(" ")) 166 i.targetEl.classList.add('hidden') 167 i.triggerEl.setAttribute('aria-expanded', false) 168 i.active = false 169 170 // rotate icon if set 171 if (i.iconEl) { 172 i.iconEl.classList.remove('rotate-180') 173 } 174 } 175 }) 176 } 177 178 // show active item 179 item.triggerEl.classList.add(...this._options.activeClasses.split(" ")) 180 item.triggerEl.classList.remove(...this._options.inactiveClasses.split(" ")) 181 item.triggerEl.setAttribute('aria-expanded', true) 182 item.targetEl.classList.remove('hidden') 183 item.active = true 184 185 // rotate icon if set 186 if (item.iconEl) { 187 item.iconEl.classList.add('rotate-180') 188 } 189 190 // callback function 191 this._options.onOpen(this, item) 192 } 193 194 toggle(id) { 195 const item = this.getItem(id) 196 197 if (item.active) { 198 this.close(id) 199 } else { 200 this.open(id) 201 } 202 203 // callback function 204 this._options.onToggle(this, item) 205 } 206 207 close(id) { 208 const item = this.getItem(id) 209 210 item.triggerEl.classList.remove(...this._options.activeClasses.split(" ")) 211 item.triggerEl.classList.add(...this._options.inactiveClasses.split(" ")) 212 item.targetEl.classList.add('hidden') 213 item.triggerEl.setAttribute('aria-expanded', false) 214 item.active = false 215 216 // rotate icon if set 217 if (item.iconEl) { 218 item.iconEl.classList.remove('rotate-180') 219 } 220 221 // callback function 222 this._options.onClose(this, item) 223 } 224 } 225 226 window.Accordion = Accordion; 227 228 document.addEventListener('DOMContentLoaded', () => { 229 document.querySelectorAll('[data-accordion]').forEach(accordionEl => { 230 const alwaysOpen = accordionEl.getAttribute('data-accordion') 231 const activeClasses = accordionEl.getAttribute('data-active-classes') 232 const inactiveClasses = accordionEl.getAttribute('data-inactive-classes') 233 234 const items = [] 235 accordionEl.querySelectorAll('[data-accordion-target]').forEach(el => { 236 const item = { 237 id: el.getAttribute('data-accordion-target'), 238 triggerEl: el, 239 targetEl: document.querySelector(el.getAttribute('data-accordion-target')), 240 iconEl: el.querySelector('[data-accordion-icon]'), 241 active: el.getAttribute('aria-expanded') === 'true' ? true : false 242 } 243 items.push(item) 244 }) 245 246 new Accordion(items, { 247 alwaysOpen: alwaysOpen === 'open' ? true : false, 248 activeClasses: activeClasses ? activeClasses : Default.activeClasses, 249 inactiveClasses: inactiveClasses ? inactiveClasses : Default.inactiveClasses 250 }) 251 }) 252 }) 253} catch (error) { } 254 255 256/*********************/ 257/* Lucide Icons */ 258/*********************/ 259lucide.createIcons();
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.