Guest User

Untitled

a guest
Nov 14th, 2024
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.35 KB | None | 0 0
  1. <script>
  2. import { appOptions } from '../../stores/appOptions.js';
  3. import { appTopNavMenus } from '../../stores/appTopNavMenus.js';
  4. import { onMount } from 'svelte';
  5. import { page } from '$app/stores';
  6.  
  7. function checkChildMenu(childMenu) {
  8. let check = false;
  9. if (childMenu) {
  10. for (var i = 0; i < childMenu.length; i++) {
  11. if ($page.url.pathname == childMenu[i]['url']) {
  12. check = true;
  13. }
  14. }
  15. }
  16. return check;
  17. }
  18.  
  19. function handleUnlimitedTopNavRender() {
  20. "use strict";
  21. // function handle menu button action - next / prev
  22. function handleMenuButtonAction(element, direction) {
  23. var obj = element.closest('.menu');
  24. var objStyle = window.getComputedStyle(obj);
  25. var bodyStyle = window.getComputedStyle(document.querySelector('body'));
  26. var targetCss = (bodyStyle.getPropertyValue('direction') == 'rtl') ? 'margin-right' : 'margin-left';
  27. var marginLeft = parseInt(objStyle.getPropertyValue(targetCss));
  28. var containerWidth = document.querySelector('.app-top-nav').clientWidth - document.querySelector('.app-top-nav').clientHeight * 2;
  29. var totalWidth = 0;
  30. var finalScrollWidth = 0;
  31. var controlPrevObj = obj.querySelector('.menu-control-start');
  32. var controlPrevWidth = (controlPrevObj) ? controlPrevObj.clientWidth : 0;
  33. var controlNextObj = obj.querySelector('.menu-control-end');
  34. var controlNextWidth = (controlPrevObj) ? controlNextObj.clientWidth : 0;
  35. var controlWidth = controlPrevWidth + controlNextWidth;
  36. var widthLeft = 0;
  37.  
  38. var elms = [].slice.call(obj.querySelectorAll('.menu-item'));
  39. if (elms) {
  40. elms.map(function(elm) {
  41. if (!elm.classList.contains('.menu-control')) {
  42. totalWidth += elm.clientWidth;
  43. }
  44. });
  45. }
  46.  
  47. switch (direction) {
  48. case 'next':
  49. widthLeft = totalWidth + marginLeft - containerWidth;
  50. if (widthLeft <= containerWidth) {
  51. finalScrollWidth = widthLeft - marginLeft - controlWidth;
  52. setTimeout(function() {
  53. obj.querySelector('.menu-control.menu-control-end').classList.remove('show');
  54. }, 300);
  55. } else {
  56. finalScrollWidth = containerWidth - marginLeft - controlWidth;
  57. }
  58.  
  59. if (finalScrollWidth !== 0) {
  60. obj.style.transitionProperty = 'height, margin, padding';
  61. obj.style.transitionDuration = '300ms';
  62. if (bodyStyle.getPropertyValue('direction') != 'rtl') {
  63. obj.style.marginLeft = '-' + finalScrollWidth + 'px';
  64. } else {
  65. obj.style.marginRight = '-' + finalScrollWidth + 'px';
  66. }
  67. setTimeout(function() {
  68. obj.style.transitionProperty = '';
  69. obj.style.transitionDuration = '';
  70. obj.querySelector('.menu-control.menu-control-start').classList.add('show');
  71. }, 300);
  72. }
  73. break;
  74. case 'prev':
  75. widthLeft = -marginLeft;
  76.  
  77. if (widthLeft <= containerWidth) {
  78. obj.querySelector('.menu-control.menu-control-start').classList.remove('show');
  79. finalScrollWidth = 0;
  80. } else {
  81. finalScrollWidth = widthLeft - containerWidth + controlWidth;
  82. }
  83.  
  84. obj.style.transitionProperty = 'height, margin, padding';
  85. obj.style.transitionDuration = '300ms';
  86.  
  87. if (bodyStyle.getPropertyValue('direction') != 'rtl') {
  88. obj.style.marginLeft = '-' + finalScrollWidth + 'px';
  89. } else {
  90. obj.style.marginRight = '-' + finalScrollWidth + 'px';
  91. }
  92.  
  93. setTimeout(function() {
  94. obj.style.transitionProperty = '';
  95. obj.style.transitionDuration = '';
  96. obj.querySelector('.menu-control.menu-control-end').classList.add('show');
  97. }, 300);
  98. break;
  99. }
  100. }
  101.  
  102. // handle page load active menu focus
  103. function handlePageLoadMenuFocus() {
  104. var targetMenu = document.querySelector('.app-top-nav .menu');
  105. if (!targetMenu) {
  106. return;
  107. }
  108. var targetMenuStyle = window.getComputedStyle(targetMenu);
  109. var bodyStyle = window.getComputedStyle(document.body);
  110. var targetCss = (bodyStyle.getPropertyValue('direction') == 'rtl') ? 'margin-right' : 'margin-left';
  111. var marginLeft = parseInt(targetMenuStyle.getPropertyValue(targetCss));
  112. var viewWidth = document.querySelector('.app-top-nav').clientWidth;
  113. var prevWidth = 0;
  114. var speed = 0;
  115. var fullWidth = 0;
  116. var controlPrevObj = targetMenu.querySelector('.menu-control-start');
  117. var controlPrevWidth = (controlPrevObj) ? controlPrevObj.clientWidth : 0;
  118. var controlNextObj = targetMenu.querySelector('.menu-control-end');
  119. var controlNextWidth = (controlPrevObj) ? controlNextObj.clientWidth : 0;
  120. var controlWidth = 0;
  121.  
  122. var elms = [].slice.call(document.querySelectorAll('.app-top-nav .menu > .menu-item'));
  123. if (elms) {
  124. var found = false;
  125. elms.map(function(elm) {
  126. if (!elm.classList.contains('menu-control')) {
  127. fullWidth += elm.clientWidth;
  128. if (!found) {
  129. prevWidth += elm.clientWidth;
  130. }
  131. if (elm.classList.contains('active')) {
  132. found = true;
  133. }
  134. }
  135. });
  136. }
  137.  
  138. var elm = targetMenu.querySelector('.menu-control.menu-control-end');
  139. if (prevWidth != fullWidth && fullWidth >= viewWidth) {
  140. elm.classList.add('show');
  141. controlWidth += controlNextWidth;
  142. } else {
  143. elm.classList.remove('show');
  144. }
  145.  
  146. elm = targetMenu.querySelector('.menu-control.menu-control-start');
  147. if (prevWidth >= viewWidth && fullWidth >= viewWidth) {
  148. elm.classList.add('show');
  149. } else {
  150. elm.classList.remove('show');
  151. }
  152.  
  153. if (prevWidth >= viewWidth) {
  154. var finalScrollWidth = prevWidth - viewWidth + controlWidth;
  155. if (bodyStyle.getPropertyValue('direction') != 'rtl') {
  156. targetMenu.style.marginLeft = '-' + finalScrollWidth + 'px';
  157. } else {
  158. targetMenu.style.marginRight = '-' + finalScrollWidth + 'px';
  159. }
  160. }
  161. }
  162.  
  163. // handle menu next button click action
  164. var elm = document.querySelector('[data-toggle="app-top-nav-next"]');
  165. if (elm) {
  166. elm.onclick = function(e) {
  167. e.preventDefault();
  168. handleMenuButtonAction(this,'next');
  169. };
  170. }
  171.  
  172. // handle menu prev button click action
  173. elm = document.querySelector('[data-toggle="app-top-nav-prev"]');
  174. if (elm) {
  175. elm.onclick = function(e) {
  176. e.preventDefault();
  177. handleMenuButtonAction(this,'prev');
  178. };
  179. }
  180.  
  181.  
  182. function enableFluidContainerDrag(containerClassName) {
  183. const container = document.querySelector(containerClassName);
  184. if (!container) {
  185. return;
  186. }
  187. const menu = container.querySelector('.menu');
  188. const menuItem = menu.querySelectorAll('.menu-item:not(.menu-control)');
  189.  
  190. let startX, scrollLeft, mouseDown;
  191. let menuWidth = 0;
  192. let maxScroll = 0;
  193.  
  194. menuItem.forEach((element) => {
  195. menuWidth += element.offsetWidth;
  196. });
  197.  
  198. container.addEventListener('mousedown', (e) => {
  199. mouseDown = true;
  200. startX = e.pageX;
  201. scrollLeft = (menu.style.marginLeft) ? parseInt(menu.style.marginLeft) : 0;
  202. maxScroll = container.offsetWidth - menuWidth;
  203. });
  204.  
  205. container.addEventListener('touchstart', (e) => {
  206. mouseDown = true;
  207. const touch = e.targetTouches[0];
  208. startX = touch.pageX;
  209. scrollLeft = (menu.style.marginLeft) ? parseInt(menu.style.marginLeft) : 0;
  210. maxScroll = container.offsetWidth - menuWidth;
  211. });
  212.  
  213. container.addEventListener('mouseup', () => {
  214. mouseDown = false;
  215. });
  216.  
  217. container.addEventListener('touchend', () => {
  218. mouseDown = false;
  219. });
  220.  
  221. container.addEventListener('mousemove', (e) => {
  222. if (!startX || !mouseDown) return;
  223. if (window.innerWidth < 768) return;
  224. e.preventDefault();
  225. const x = e.pageX;
  226. const walkX = (x - startX) * 1;
  227. var totalMarginLeft = scrollLeft + walkX;
  228. if (totalMarginLeft <= maxScroll) {
  229. totalMarginLeft = maxScroll;
  230. menu.querySelector('.menu-control.menu-control-end').classList.remove('show');
  231. } else {
  232. menu.querySelector('.menu-control.menu-control-end').classList.add('show');
  233. }
  234. if (menuWidth < container.offsetWidth) {
  235. menu.querySelector('.menu-control.menu-control-start').classList.remove('show');
  236. }
  237. if (maxScroll > 0) {
  238. menu.querySelector('.menu-control.menu-control-end').classList.remove('show');
  239. }
  240. if (totalMarginLeft > 0) {
  241. totalMarginLeft = 0;
  242. menu.querySelector('.menu-control.menu-control-start').classList.remove('show');
  243. } else {
  244. menu.querySelector('.menu-control.menu-control-start').classList.add('show');
  245. }
  246. menu.style.marginLeft = totalMarginLeft + 'px';
  247. });
  248.  
  249. container.addEventListener('touchmove', (e) => {
  250. if (!startX || !mouseDown) return;
  251. if (window.innerWidth < 768) return;
  252. e.preventDefault();
  253. const touch = e.targetTouches[0];
  254. const x = touch.pageX;
  255. const walkX = (x - startX) * 1;
  256. var totalMarginLeft = scrollLeft + walkX;
  257. if (totalMarginLeft <= maxScroll) {
  258. totalMarginLeft = maxScroll;
  259. menu.querySelector('.menu-control.menu-control-end').classList.remove('show');
  260. } else {
  261. menu.querySelector('.menu-control.menu-control-end').classList.add('show');
  262. }
  263. if (menuWidth < container.offsetWidth) {
  264. menu.querySelector('.menu-control.menu-control-start').classList.remove('show');
  265. }
  266. if (maxScroll > 0) {
  267. menu.querySelector('.menu-control.menu-control-end').classList.remove('show');
  268. }
  269. if (totalMarginLeft > 0) {
  270. totalMarginLeft = 0;
  271. menu.querySelector('.menu-control.menu-control-start').classList.remove('show');
  272. } else {
  273. menu.querySelector('.menu-control.menu-control-start').classList.add('show');
  274. }
  275. menu.style.marginLeft = totalMarginLeft + 'px';
  276. });
  277. }
  278.  
  279. window.addEventListener('resize', function() {
  280. if (window.innerWidth >= 768) {
  281. var targetElm = document.querySelector('.app-top-nav');
  282. if (targetElm) {
  283. targetElm.removeAttribute('style');
  284. }
  285. var targetElm2 = document.querySelector('.app-top-nav .menu');
  286. if (targetElm2) {
  287. targetElm2.removeAttribute('style');
  288. }
  289. var targetElm3 = document.querySelectorAll('.app-top-nav .menu-submenu');
  290. if (targetElm3) {
  291. targetElm3.forEach((elm3) => {
  292. elm3.removeAttribute('style');
  293. });
  294. }
  295. handlePageLoadMenuFocus();
  296. }
  297. enableFluidContainerDrag('.app-top-nav');
  298. });
  299.  
  300. if (window.innerWidth >= 768) {
  301. handlePageLoadMenuFocus();
  302. enableFluidContainerDrag('.app-top-nav');
  303. }
  304. };
  305.  
  306. function handleTopNavToggle(menus, forMobile = false) {
  307. menus.map(function(menu) {
  308. menu.onclick = function(e) {
  309. e.preventDefault();
  310.  
  311. if (!forMobile || (forMobile && document.body.clientWidth < 768)) {
  312. var target = this.nextElementSibling;
  313. menus.map(function(m) {
  314. var otherTarget = m.nextElementSibling;
  315. if (otherTarget !== target) {
  316. slideUp(otherTarget);
  317. otherTarget.closest('.menu-item').classList.remove('expand');
  318. otherTarget.closest('.menu-item').classList.add('closed');
  319. }
  320. });
  321.  
  322. slideToggle(target);
  323. }
  324. }
  325. });
  326. };
  327.  
  328. function handleTopNavSubMenu() {
  329. "use strict";
  330.  
  331. var menuBaseSelector = '.app-top-nav .menu > .menu-item.has-sub';
  332. var submenuBaseSelector = ' > .menu-submenu > .menu-item.has-sub';
  333.  
  334. // Menu - Toggle / Collapse
  335. var menuLinkSelector = menuBaseSelector + ' > .menu-link';
  336. var menus = [].slice.call(document.querySelectorAll(menuLinkSelector));
  337. handleTopNavToggle(menus, true);
  338.  
  339. // Menu - Submenu lvl 1
  340. var submenuLvl1Selector = menuBaseSelector + submenuBaseSelector;
  341. var submenusLvl1 = [].slice.call(document.querySelectorAll(submenuLvl1Selector + ' > .menu-link'));
  342. handleTopNavToggle(submenusLvl1);
  343.  
  344. // Menu - Submenu lvl 2
  345. var submenuLvl2Selector = menuBaseSelector + submenuBaseSelector + submenuBaseSelector;
  346. var submenusLvl2 = [].slice.call(document.querySelectorAll(submenuLvl2Selector + ' > .menu-link'));
  347. handleTopNavToggle(submenusLvl2);
  348. };
  349.  
  350. onMount(async () => {
  351. handleUnlimitedTopNavRender();
  352. handleTopNavSubMenu();
  353. });
  354. </script>
  355. <div id="top-nav" class="app-top-nav">
  356. <div class="menu">
  357. {#each $appTopNavMenus as menu}
  358. <div class="menu-item" class:has-sub={menu.children} class:active={$page.url.pathname === menu.url || checkChildMenu(menu.children)}>
  359. <a href={menu.url} class="menu-link">
  360. {#if menu.icon}
  361. <span class="menu-icon">
  362. <i class={menu.icon}></i>
  363. {#if menu.highlight}<span class="w-5px h-5px rounded-3 bg-theme position-absolute top-0 end-0 mt-3px me-3px"></span>{/if}
  364. </span>
  365. {/if}
  366. <span class="menu-text">{menu.text}</span>
  367. {#if menu.children}
  368. <span class="menu-caret"><b class="caret"></b></span>
  369. {/if}
  370. </a>
  371.  
  372. {#if menu.children}
  373. <div class="menu-submenu">
  374. {#each menu.children as childMenu}
  375. <div class="menu-item" class:has-sub={childMenu.children} class:active={$page.url.pathname === childMenu.url}>
  376. <a href={childMenu.url} class="menu-link">
  377. <span class="menu-text">{childMenu.text}</span>
  378. </a>
  379. </div>
  380. {/each}
  381. </div>
  382. {/if}
  383. </div>
  384. {/each}
  385. <div class="menu-item menu-control menu-control-start">
  386. <a href="#/" class="menu-link" data-toggle="app-top-nav-prev"><i class="bi bi-caret-left"></i></a>
  387. </div>
  388. <div class="menu-item menu-control menu-control-end">
  389. <a href="#/" class="menu-link" data-toggle="app-top-nav-next"><i class="bi bi-caret-right"></i></a>
  390. </div>
  391. </div>
  392. </div>
Advertisement
Add Comment
Please, Sign In to add comment