From 61ca1a4def9f004d54926fd7dbe1722cdd4ec952 Mon Sep 17 00:00:00 2001 From: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:57:49 +0100 Subject: [PATCH] Nav Bar Fixes for Mobile Devices (#3927) # Description of Changes --- ## Checklist ### General - [x ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ x] I have performed a self-review of my own code - [ x] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Ethan --- .../src/main/resources/static/js/navbar.js | 80 +++++++++++++++++-- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/app/core/src/main/resources/static/js/navbar.js b/app/core/src/main/resources/static/js/navbar.js index 57f916f8a..1fd46ed70 100644 --- a/app/core/src/main/resources/static/js/navbar.js +++ b/app/core/src/main/resources/static/js/navbar.js @@ -42,6 +42,39 @@ function toolsManager() { }); } +function setupDropdowns() { + const dropdowns = document.querySelectorAll('.navbar-nav > .nav-item.dropdown'); + + dropdowns.forEach((dropdown) => { + const toggle = dropdown.querySelector('[data-bs-toggle="dropdown"]'); + if (!toggle) return; + + // Skip search dropdown, it has its own logic + if (toggle.id === 'searchDropdown') { + return; + } + + dropdown.addEventListener('show.bs.dropdown', () => { + // Find all other open dropdowns and hide them + const openDropdowns = document.querySelectorAll('.navbar-nav .dropdown-menu.show'); + openDropdowns.forEach((menu) => { + const parentDropdown = menu.closest('.dropdown'); + if (parentDropdown && parentDropdown !== dropdown) { + const parentToggle = parentDropdown.querySelector('[data-bs-toggle="dropdown"]'); + if (parentToggle) { + // Get or create Bootstrap dropdown instance + let instance = bootstrap.Dropdown.getInstance(parentToggle); + if (!instance) { + instance = new bootstrap.Dropdown(parentToggle); + } + instance.hide(); + } + } + }); + }); + }); +} + window.tooltipSetup = () => { const tooltipElements = document.querySelectorAll('[title]'); @@ -56,26 +89,55 @@ window.tooltipSetup = () => { document.body.appendChild(customTooltip); element.addEventListener('mouseenter', (event) => { - customTooltip.style.display = 'block'; - customTooltip.style.left = `${event.pageX + 10}px`; // Position tooltip slightly away from the cursor - customTooltip.style.top = `${event.pageY + 10}px`; + if (window.innerWidth >= 1200) { + customTooltip.style.display = 'block'; + customTooltip.style.left = `${event.pageX + 10}px`; + customTooltip.style.top = `${event.pageY + 10}px`; + } }); - // Update the position of the tooltip as the user moves the mouse element.addEventListener('mousemove', (event) => { - customTooltip.style.left = `${event.pageX + 10}px`; - customTooltip.style.top = `${event.pageY + 10}px`; + if (window.innerWidth >= 1200) { + customTooltip.style.left = `${event.pageX + 10}px`; + customTooltip.style.top = `${event.pageY + 10}px`; + } }); - // Hide the tooltip when the mouse leaves element.addEventListener('mouseleave', () => { customTooltip.style.display = 'none'; }); }); }; + +// Override the bootstrap dropdown styles for mobile +function fixNavbarDropdownStyles() { + if (window.innerWidth < 1200) { + document.querySelectorAll('.navbar .dropdown-menu').forEach(function(menu) { + menu.style.transform = 'none'; + menu.style.transformOrigin = 'none'; + menu.style.left = '0'; + menu.style.right = '0'; + menu.style.maxWidth = '95vw'; + menu.style.width = '100vw'; + menu.style.marginBottom = '0'; + }); + } else { + document.querySelectorAll('.navbar .dropdown-menu').forEach(function(menu) { + menu.style.transform = ''; + menu.style.transformOrigin = ''; + menu.style.left = ''; + menu.style.right = ''; + menu.style.maxWidth = ''; + menu.style.width = ''; + menu.style.marginBottom = ''; + }); + } +} + document.addEventListener('DOMContentLoaded', () => { tooltipSetup(); - + setupDropdowns(); + fixNavbarDropdownStyles(); // Setup logout button functionality const logoutButton = document.querySelector('a[href="/logout"]'); if (logoutButton) { @@ -89,4 +151,6 @@ document.addEventListener('DOMContentLoaded', () => { } }); } + }); +window.addEventListener('resize', fixNavbarDropdownStyles);