From 311b918077d67383dd2423d70d261bd6469ac36a Mon Sep 17 00:00:00 2001
From: Adam Piontek <adam@73k.us>
Date: Mon, 26 Jul 2021 20:51:08 -0400
Subject: [PATCH] fixed menu display to support default bootstrap menus with
 minimal styling

---
 assets/css/_nav-bar-help.scss      | 104 +++++++++++++----------------
 assets/js/_main-nav-menu-helper.js |  29 --------
 assets/js/main.js                  |   6 +-
 custom-functions.php               |   1 +
 header.php                         |   3 +-
 searchform.php                     |   2 +-
 src/classes.php                    |  42 +++++++++++-
 7 files changed, 92 insertions(+), 95 deletions(-)
 delete mode 100644 assets/js/_main-nav-menu-helper.js

diff --git a/assets/css/_nav-bar-help.scss b/assets/css/_nav-bar-help.scss
index 19861e2..c325e83 100644
--- a/assets/css/_nav-bar-help.scss
+++ b/assets/css/_nav-bar-help.scss
@@ -15,7 +15,6 @@ nav#top-navbar-grid-outer {
   @include media-breakpoint-up(md) {
     grid-template-rows: calc(5.3rem / 2) calc(5.3rem / 2) auto;
   }
-  // grid-auto-rows: calc(4.3rem / 2);
   div#top-navbar-grid-brand-outer {
     grid-column-start: 1;
     grid-column-end: 2;
@@ -130,7 +129,7 @@ nav#top-navbar-grid-outer {
         @include media-breakpoint-up(lg) {
           padding: 0 0 0 1.5em !important;
         }
-        a.top-navbar-grid-main-menu-item-link {
+        .top-navbar-grid-main-menu-item-link {
           @extend .fw-bold;
           @extend .text-uppercase;
           @extend .text-decoration-none;
@@ -140,72 +139,59 @@ nav#top-navbar-grid-outer {
             text-decoration-color: $primary !important;
             color: $gray-300;
           }
+          &.active {
+            color: $primary;
+          }
         }
-        &.menu-item-has-children {
-          @extend .dropdown;
-          & > a.top-navbar-grid-main-menu-item-link {
-            @extend .dropdown-toggle;
-            cursor: pointer;
-            &.shown {
-              color: $primary;
-              text-decoration: none !important;
-              &:hover {
-                text-decoration: none !important;
-              }
+        .dropdown-toggle {
+          cursor: pointer;
+          div.icon.baseline {
+            transform: rotate(0deg);
+            transition: transform 150ms ease;
+            svg {
+              top: inherit;
+              height: .75em;
+              width: .75em;
             }
           }
-          ul.sub-menu {
+          &.show {
+            color: $primary;
+            &:hover {
+              text-decoration: none !important;
+            }
+            div.icon.baseline {
+              transform: rotate(180deg);
+              transition: transform 150ms ease;
+            }
+          }
+          &::after {
             display: none;
-            margin: 0;
-            color: $gray-300;
-            list-style: none;
-            min-width: 10rem;
-            background-color: tint-color($spaceblue-800, 5%);
-            border-radius: 0.25rem;
-            font-size: 1rem;
-            &.show {
+          }
+        }
+        .dropdown-menu.dropdown-menu-dark {
+          background-color: shade-color($gray-800, 50%);
+          li.menu-item {
+            padding: 4px 0 !important;
+            .top-navbar-grid-main-menu-item-link {
               display: block;
-            }
-            @include media-breakpoint-down(lg) {
-              position: relative;
-              margin-top: 0.25em;
-              padding: 0.25em 1em 0 1em;
-              background-clip: border-box;
-              border: 1px solid $gray-700;
-              word-wrap: break-word;
-            }
-            @include media-breakpoint-up(lg) {
-              position: absolute;
-              padding: .5rem 0;
-              background-clip: padding-box;
-              border: 1px solid rgba(0,0,0,0.15);
-              box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15);
-              z-index: 1000;
-              inset: 1.5em 0px auto auto;
-              text-align: left;
-              li.menu-item {
-                padding: 8px 0 8px 0 !important;
-                a.top-navbar-grid-main-menu-item-link {
-                  text-align: left;
-                  display: block;
-                  width: 100%;
-                  padding: .25rem 1rem 0 1rem;
-                  clear: both;
-                  font-weight: inherit;
-                  white-space: nowrap;
-                  border: 0;
-                  text-decoration: none;
+              width: 100%;
+              padding: .25rem 1rem 0 1rem;
+              &:hover {
+                text-decoration: none !important;
+                color: $gray-900;
+                background-color: $primary;
+              }
+              &.active {
+                color: $gray-900;
+                background-color: shade-color($primary, 25%);
+                &:hover {
+                  text-decoration: none !important;
+                  background-color: $primary;
                 }
               }
             }
-
           }
-          // &:hover {
-          //   ul.sub-menu {
-          //     display: block;
-          //   }
-          // }
-      }
+        }
       }
     }
   }
diff --git a/assets/js/_main-nav-menu-helper.js b/assets/js/_main-nav-menu-helper.js
deleted file mode 100644
index 303d9e5..0000000
--- a/assets/js/_main-nav-menu-helper.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * main nav menu helper
- */
-var mainMenuDropdownList = [].slice.call(document.querySelectorAll('li.menu-item.menu-item-has-children > a.top-navbar-grid-main-menu-item-link'));
-
-mainMenuDropdownList.forEach((thisMenuLink) => {
-  thisMenuLink.addEventListener("click", (e) => {
-    e.preventDefault();   // Cancel the native event
-    e.stopPropagation();  // Don't bubble/capture the event any further
-
-    // get relevant elements and note if menu is already shown
-    var thisSubMenu = thisMenuLink.parentElement.querySelector('ul.sub-menu');
-    var thisElShown = thisSubMenu.classList.contains('show');
-
-    // un-show all menus
-    document.querySelectorAll('li.menu-item.menu-item-has-children').forEach((otherEl) => {
-      var otherMenuLink = otherEl.querySelector('a.top-navbar-grid-main-menu-item-link');
-      var otherSubMenu = otherEl.querySelector('ul.sub-menu');
-      if (otherMenuLink) { otherMenuLink.classList.remove('shown'); }
-      if (otherSubMenu) { otherSubMenu.classList.remove('show'); }
-    });
-
-    // finally, if menu was not shown, show it
-    if (!thisElShown) {
-      thisMenuLink.classList.add('shown');
-      thisSubMenu.classList.add('show');
-    }
-  });
-});
diff --git a/assets/js/main.js b/assets/js/main.js
index c805d8a..45222ff 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -4,8 +4,8 @@ import '../css/app.scss'
 // Import svg files for webpack handling
 import '../raw/rdnyc-logo.svg'; // rdnyc logo
 // other:
-// import '../../node_modules/bootstrap-icons/icons/chevron-down.svg';
-// import '../../node_modules/bootstrap-icons/icons/chevron-up.svg';
+import '../../node_modules/bootstrap-icons/icons/chevron-down.svg';
+import '../../node_modules/bootstrap-icons/icons/search.svg';
 // import "../../node_modules/@mdi/svg/svg/magnify.svg"; // search form button icon
 // import "../../node_modules/@mdi/svg/svg/home.svg";
 // import "../../node_modules/@mdi/svg/svg/information.svg";
@@ -22,8 +22,6 @@ import 'bootstrap/js/dist/dropdown';
 
 // import navbar burger code
 import "./_hamburger-helper";
-// import navbar dropdown menu helper code
-import "./_main-nav-menu-helper";
 
 // highlight any code blocks tagged with class 'to-highlight'
 document.addEventListener('DOMContentLoaded', (event) => {
diff --git a/custom-functions.php b/custom-functions.php
index 7c14721..018b9b4 100644
--- a/custom-functions.php
+++ b/custom-functions.php
@@ -52,4 +52,5 @@ function inline_svg( $svg_name, $atts = array() ) {
   return $svg_content;
 };
 
+
 ?>
\ No newline at end of file
diff --git a/header.php b/header.php
index 692cf2b..425e7d4 100644
--- a/header.php
+++ b/header.php
@@ -95,7 +95,8 @@ namespace WP_RDNYC;
             'container_id' => 'top-navbar-grid-main-menu-outer',
             'menu_class'      => 'top-navbar-grid-main-menu',
             'menu_item_class' => 'top-navbar-grid-main-menu-item',
-            'link_class'      => 'top-navbar-grid-main-menu-item-link'
+            'link_class'      => 'top-navbar-grid-main-menu-item-link',
+            'walker' => new RDNYC_Menu_Walker()
           ]);
           // echo '</section>';
         }
diff --git a/searchform.php b/searchform.php
index 343418b..fecf046 100644
--- a/searchform.php
+++ b/searchform.php
@@ -21,7 +21,7 @@ $seventythreek_aria_label = ! empty( $args['aria_label'] ) ? 'aria-label="' . es
     <label id="<?php echo esc_attr( $seventythreek_unique_id ) . '-label'; ?>" for="<?php echo esc_attr( $seventythreek_unique_id ); ?>" aria-hidden class="form-label d-none"><?php _e( 'Search&hellip;', 'seventythreek' ); // phpcs:ignore: WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></label>
     <input type="search" id="<?php echo esc_attr( $seventythreek_unique_id ); ?>" class="form-control me-2 tek-search-input" value="<?php echo get_search_query(); ?>" name="s" aria-labelledby="<?php echo esc_attr( $seventythreek_unique_id ) . '-label'; ?>" placeholder="Search blog&hellip;" />
     <button type="submit" class="btn btn-outline-light" title="Search">
-      <?php echo inline_svg( 'mdi-magnify', array( 'div_class' => 'icon baseline' ) ); ?>
+      <?php echo inline_svg( 'bsi-search', array( 'div_class' => 'icon baseline' ) ); ?>
     </button>
   </div>
 </form>
diff --git a/src/classes.php b/src/classes.php
index 1c73ef0..b6023a9 100644
--- a/src/classes.php
+++ b/src/classes.php
@@ -8,6 +8,8 @@
 
 namespace WP_RDNYC;
 
+use \Walker_Nav_Menu;
+
 add_filter( 'body_class', function( $classes ) {
 
   if ( is_singular( ['post', 'page'] ) ) {
@@ -41,7 +43,7 @@ add_filter( 'nav_menu_link_attributes' , function( $atts, $item, $args ) {
   if ( 'navbar-main-menu' === $args->theme_location ) {
     $atts['class'] = (empty($atts['class'])) ? '' : $atts['class'];
     if ( in_array('current_page_item', $item->classes) ) {
-      $atts['class'] .= ' active';
+      $atts['class'] .= ' active ';
     }
     if (property_exists($args, 'link_class')) {
       $atts['class'] .= ' ' . $args->link_class;
@@ -49,3 +51,41 @@ add_filter( 'nav_menu_link_attributes' , function( $atts, $item, $args ) {
   }
   return $atts;
 }, 2, 3 );
+
+
+/**
+ * custom walker to handle nav main menu dropdowns (one level deep, bs5 doesn't have native submenu support)
+ */
+class RDNYC_Menu_Walker extends Walker_Nav_Menu {
+
+  function start_lvl(&$output, $depth = 0, $args = array()) {
+    $output .= "\n<ul class=\"dropdown-menu dropdown-menu-dark dropdown-menu-end\">\n";
+  }
+
+  function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
+      $item_html = '';
+      parent::start_el($item_html, $item, $depth, $args);
+
+      if ( $item->is_dropdown && $depth === 0 ) {
+          $item_html = str_replace( '<a', '<a class="dropdown-toggle top-navbar-grid-main-menu-item-link" data-bs-toggle="dropdown"', $item_html );
+          $item_html = str_replace( '</a>', inline_svg( 'bsi-chevron-down', array( 'div_class' => 'icon baseline ms-1' ) ) . '</a>', $item_html );
+      }
+
+      $output .= $item_html;
+   }
+
+   function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {
+       if ( $element->current )
+       $element->classes[] = 'active';
+
+       $element->is_dropdown = !empty( $children_elements[$element->ID] );
+
+       if ( $element->is_dropdown ) {
+          if ( $depth === 0 ) {
+              $element->classes[] = 'dropdown';
+          }
+       }
+
+   parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
+   }
+}
\ No newline at end of file