]> git.openstreetmap.org Git - rails.git/commitdiff
Move secondary menu items to "more" dropdown dynamically
authorAnton Khorev <tony29@yandex.ru>
Tue, 28 May 2024 02:03:31 +0000 (05:03 +0300)
committerAnton Khorev <tony29@yandex.ru>
Wed, 12 Feb 2025 12:36:59 +0000 (15:36 +0300)
app/assets/javascripts/application.js
app/assets/stylesheets/common.scss
app/views/layouts/_header.html.erb

index c6d7c4fe3b8aafdaf12498e191fcc5c60c0e01f5..bb6f46590a05b59e644d1ac354e8e6241cf4de81 100644 (file)
@@ -90,45 +90,74 @@ $(document).ready(function () {
   // See https://turbo.hotwired.dev/reference/drive#turbo.session.drive
   Turbo.session.drive = false;
 
-  let headerWidth = 0;
-  const breakpointWidth = 768;
+  const $expandedSecondaryMenu = $("header nav.secondary > ul"),
+        $collapsedSecondaryMenu = $("#compact-secondary-nav > ul"),
+        secondaryMenuItems = [],
+        breakpointWidth = 768;
+  let moreItemWidth = 0;
 
   function updateHeader() {
     var windowWidth = $(window).width();
 
     if (windowWidth < breakpointWidth) {
       $("body").addClass("small-nav");
-      expandSecondaryMenu();
-    } else if (windowWidth < headerWidth) {
-      $("body").removeClass("small-nav");
-      collapseSecondaryMenu();
+      expandAllSecondaryMenuItems();
     } else {
       $("body").removeClass("small-nav");
-      expandSecondaryMenu();
+      const availableWidth = $expandedSecondaryMenu.width();
+      secondaryMenuItems.forEach(function (item) {
+        $(item[0]).remove();
+      });
+      let runningWidth = 0,
+          i = 0,
+          requiredWidth;
+      for (; i < secondaryMenuItems.length; i++) {
+        runningWidth += secondaryMenuItems[i][1];
+        if (i < secondaryMenuItems.length - 1) {
+          requiredWidth = runningWidth + moreItemWidth;
+        } else {
+          requiredWidth = runningWidth;
+        }
+        if (requiredWidth > availableWidth) {
+          break;
+        }
+        expandSecondaryMenuItem($(secondaryMenuItems[i][0]));
+      }
+      for (; i < secondaryMenuItems.length; i++) {
+        collapseSecondaryMenuItem($(secondaryMenuItems[i][0]));
+      }
     }
   }
 
-  function expandSecondaryMenu() {
-    $("#compact-secondary-nav > ul").find("li").children("a")
+  function expandAllSecondaryMenuItems() {
+    secondaryMenuItems.forEach(function (item) {
+      expandSecondaryMenuItem($(item[0]));
+    });
+  }
+
+  function expandSecondaryMenuItem($item) {
+    $item.children("a")
       .removeClass("dropdown-item")
       .addClass("nav-link")
       .addClass(function () {
         return $(this).hasClass("active") ? "text-secondary-emphasis" : "text-secondary";
       });
-    $("#compact-secondary-nav > ul").find("li")
-      .addClass("nav-item")
-      .prependTo("header nav.secondary > ul");
-    $("#compact-secondary-nav").hide();
+    $item.addClass("nav-item").insertBefore("#compact-secondary-nav");
+    toggleCompactSecondaryNav();
   }
 
-  function collapseSecondaryMenu() {
-    $("header nav.secondary > ul").find("li:not(#compact-secondary-nav)").children("a")
+  function collapseSecondaryMenuItem($item) {
+    $item.children("a")
       .addClass("dropdown-item")
       .removeClass("nav-link text-secondary text-secondary-emphasis");
-    $("header nav.secondary > ul").find("li:not(#compact-secondary-nav)")
-      .removeClass("nav-item")
-      .prependTo("#compact-secondary-nav > ul");
-    $("#compact-secondary-nav").show();
+    $item.removeClass("nav-item").appendTo($collapsedSecondaryMenu);
+    toggleCompactSecondaryNav();
+  }
+
+  function toggleCompactSecondaryNav() {
+    $("#compact-secondary-nav").toggle(
+      $collapsedSecondaryMenu.find("li").length > 0
+    );
   }
 
   /*
@@ -138,9 +167,10 @@ $(document).ready(function () {
    * to defer the measurement slightly as a workaround.
    */
   setTimeout(function () {
-    $("header").children(":visible").each(function (i, e) {
-      headerWidth += $(e).outerWidth();
+    $expandedSecondaryMenu.find("li:not(#compact-secondary-nav)").each(function () {
+      secondaryMenuItems.push([this, $(this).width()]);
     });
+    moreItemWidth = $("#compact-secondary-nav").width();
 
     $("header").removeClass("text-nowrap");
     $("header nav.secondary > ul").removeClass("flex-nowrap");
index d0524fcbc19620fb811909bd5a2dbaef16698fde..a536f527f297520ca97c77b002a2186317805ab8 100644 (file)
@@ -131,10 +131,6 @@ header {
     font-size: 14px;
   }
 
-  nav.primary {
-    margin-right: auto;
-  }
-
   .username {
     max-width: 12em;
   }
@@ -231,6 +227,10 @@ body.small-nav {
   nav.secondary {
     flex-direction: column;
 
+    > ul {
+      justify-content: unset !important;
+    }
+
     .user-menu, .login-menu {
       width: 100%;
     }
index 926d623c03e5177d8aecc9b14109a7b5db096d11..8cfe93313261701fa8ca09c84ab5345b2797f8a2 100644 (file)
@@ -27,8 +27,8 @@
       </ul>
     </div>
   </nav>
-  <nav class='secondary d-flex gap-2 align-items-center'>
-    <ul class='nav flex-nowrap'>
+  <nav class='secondary d-flex gap-2 flex-grow-1 align-items-center'>
+    <ul class='nav flex-grow-1 justify-content-end flex-nowrap'>
       <% if Settings.status != "database_offline" && can?(:index, Issue) %>
         <li class="nav-item">
           <%= link_to issues_path(:status => "open"), :class => header_nav_link_class(issues_path) do %>