How to build this menu functionality

Code:
<?php
// Register shortcode to display a menu by ID
function custom_menu_shortcode($atts)
{
// Extract shortcode attributes
$atts = shortcode_atts(array(
'menu_id' => '14', // Default menu ID
), $atts, 'custom_menu');
if (empty($atts['menu_id'])) {
return 'Menu ID not provided';
}
// Output buffer to capture the menu HTML
ob_start(); ?>
<style>
/* mobile and tab menu */
div#modal_overlay[data-active="true"] {
position: fixed;
height: 100%;
width: 100%;
left: 0;
top: 0;
z-index: -1;
overflow: hidden;
z-index: 0;
background-color: rgba(0, 0, 0, 0.2);
}
.PrimaryNavigation_icon {
position: relative;
top: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
width: 3.25rem;
height: 3.25rem;
border: 2px solid var(--primary);
border-radius: 100%;
pointer-events: all;
z-index: 100;
background-color: #fff;
}
.PrimaryNavigation_icon:hover,
.PrimaryNavigation_icon:focus {
background-color: #fff !important;
}
.PrimaryNavigation_line {
position: absolute;
width: 24px;
height: 2px;
background: var(--primary);
will-change: transform;
border-radius: 2px;
transition: transform 0.3s cubic-bezier(0.75, 0, 0.25, 1);
}
.PrimaryNavigation_line:first-child {
transform: translateY(-3px);
}
.PrimaryNavigation_line:last-child {
transform: translateY(3px);
}
#header_menu_box[data-active="true"] .PrimaryNavigation_line:first-child {
transform: translateY(0) rotate(45deg);
}
#header_menu_box[data-active="true"] .PrimaryNavigation_line:last-child {
transform: translateY(0) rotate(-45deg);
}
.PrimaryNavigation_flyout {
width: 350px;
height: auto;
background: var(--white);
position: absolute;
right: 0;
top: 20px;
z-index: 99;
padding: 50px 30px 30px;
border-radius: 20px;
transform: scale(0.4);
/* Initial scale */
opacity: 0;
/* Initial opacity */
transform-origin: top right;
transition: transform 0.3s ease-out, opacity 0.4s ease-out;
}
#header_menu_box[data-active="true"] .PrimaryNavigation_flyout {
transform: scale(1);
opacity: 1;
}
#header_menu_box[data-active="false"] .PrimaryNavigation_flyout {
transform: scale(0.4);
opacity: 0;
pointer-events: none;
}
ul#header_menu_ul {
margin: 0;
display: flex;
flex-direction: column;
gap: 10px;
list-style: none;
}
ul#header_menu_ul li a {
display: flex;
gap: 5px;
align-items: center;
text-decoration: none;
color: var(--black);
font-size: 1.125rem;
font-size: 1rem;
cursor: pointer !important;
}
ul#header_menu_ul li:hover a,
a.submenu-open * {
color: var(--primary) !important;
}
ul#header_menu_ul .menu-item {
opacity: 0;
/* Initially hidden */
transition: opacity 0.5s ease-in-out;
/* Smooth transition for opacity */
}
#header_menu_box[data-active="true"] ul#header_menu_ul .menu-item {
opacity: 1;
}
ul#header_menu_ul ul.sub-menu {
display: flex;
flex-direction: column;
gap: 5px;
}
/* Rotate animation */
@keyframes rotate-360 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
/* Apply rotation animation */
.submenu-open #animated-svg {
animation: rotate-360 0.3s linear forwards;
}
/* Hide the minus icon after animation with delay */
.submenu-open #minus-icon {
display: block;
opacity: 1;
animation: hide-icon 0.2s forwards;
animation-delay: 0.25s;
}
@keyframes hide-icon {
0% {
opacity: 1;
}
100% {
opacity: 0;
display: none;
}
}
/* menu mobile */
ul#mobile-menu {
display: flex !important;
flex-direction: column !important;
gap: 20px;
list-style-type: none;
margin: 0px;
}
ul#mobile-menu li a {
display: block;
color: #000;
font-family: Poppins;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: normal;
text-transform: capitalize;
text-decoration: none;
padding: 10px 0px;
}
span#mobile_menu_toggler,
span#modal_menu_close {
padding: 10px;
background: var(--primary);
border-radius: 38px;
}
span#mobile_menu_toggler svg,
span#modal_menu_close svg {
width: 25px;
height: 25px;
}
span#modal_menu_close {
position: absolute;
top: 10px;
right: 10px;
}
div#mobile_menu_modal {
position: absolute;
width: 300px;
background: #fffbff;
border: 3px solid var(--primary);
border-radius: 10px;
right: -300px;
top: 45px;
transition: right 0.5s ease, opacity 0.5s ease;
opacity: 0;
display: none;
padding: 75px 20px 30px;
}
span#modal_menu_close {
position: absolute;
top: 10px;
right: 10px;
}
div#mobile_menu_modal.active {
right: 0;
opacity: 1;
z-index: 99;
display: inline-block !important;
}
</style>
<div id="PrimaryNavigation">
<button class="PrimaryNavigation_icon" data-modal-hide="true">
<div class="PrimaryNavigation_line"></div>
<div class="PrimaryNavigation_line"></div>
</button>
<aside class="PrimaryNavigation_flyout">
<nav class="PrimaryNavigation_navigation">
<ul id="header_menu_ul" class="menu">
<?php
wp_nav_menu(array(
'menu' => $atts['menu_id'], // Use the menu ID here
'container' => false,
'items_wrap' => '%3$s',
'walker' => new Custom_Walker_Nav_Menu(),
)); ?>
</ul>
</nav>
<div class="PrimaryNavigation_background"></div>
</aside>
<figure class="PrimaryNavigation_pageOverlay"></figure>
</div>
<script>
(function($) {
$(document).ready(function() {
// Cached selectors to avoid multiple DOM lookups
const $menuButton = $("#PrimaryNavigation .PrimaryNavigation_icon");
const $headerMenu = $("#header_menu_box");
const $modalOverlay = $("#modal_overlay");
const $mobileMenuModal = $("#mobile_menu_modal");
// Toggle the mobile menu visibility
function toggleMobileMenu() {
if (!$mobileMenuModal.hasClass("active")) {
$mobileMenuModal.css("display", "inline-block");
setTimeout(() => $mobileMenuModal.addClass("active"), 10); // Trigger transition
} else {
$mobileMenuModal.removeClass("active");
setTimeout(() => $mobileMenuModal.css("display", "none"), 500); // Match transition duration
}
}
// Toggle the main menu visibility
function toggleMenu() {
const isActive = $headerMenu.attr("data-active") === "true";
$headerMenu.attr("data-active", !isActive);
}
// Toggle the modal overlay visibility
function toggleModalOverlay() {
const isActive = $modalOverlay.attr("data-active") === "true";
$modalOverlay.attr("data-active", !isActive);
}
// Bind events to buttons and overlays
$menuButton.on("click", () => {
toggleMenu();
toggleModalOverlay();
});
$modalOverlay.on("click", () => {
toggleMenu();
toggleModalOverlay();
});
$("#mobile_menu_toggler, #modal_menu_close").on("click", toggleMobileMenu);
// Handle submenu toggling
function handleSubMenuToggle(e) {
const $clickedElement = $(e.target);
const $parentItem = $(this).parent();
const $subMenu = $(this).next(".sub-menu");
// Prevent default if clicking on the icon
if ($clickedElement.closest(".svg-wrapper").length > 0) {
e.preventDefault();
if ($subMenu.is(":visible")) {
$subMenu.slideUp();
$parentItem.find("svg #minus-icon").hide();
$parentItem.find("svg #plus-icon").show();
$parentItem.removeClass("active");
} else {
// Close other submenus and open the current one
$parentItem.siblings().find(".sub-menu").slideUp();
$parentItem.siblings().find("svg #minus-icon").hide();
$parentItem.siblings().find("svg #plus-icon").show();
$parentItem.siblings().removeClass("active");
$subMenu.slideDown();
$parentItem.find("svg #plus-icon").hide();
$parentItem.find("svg #minus-icon").show();
$parentItem.addClass("active");
// Hide nested submenus
$parentItem.find(".sub-menu .menu-item-has-children .sub-menu").slideUp();
$parentItem.find(".sub-menu .menu-item-has-children svg #minus-icon").hide();
$parentItem.find(".sub-menu .menu-item-has-children svg #plus-icon").show();
}
}
}
// Initialize submenu states and bind events
function initSubMenu() {
$(".sub-menu").hide();
$("svg #plus-icon").show();
$("svg #minus-icon").hide();
$(".menu-item-has-children > a").on("click", handleSubMenuToggle);
}
// Initialize all handlers and menu states
function init() {
initSubMenu();
}
init(); // Run initialization
});
})(jQuery);
</script>
<?php
// Get the buffered content and clean the buffer
$output = ob_get_clean();
return $output;
}
add_shortcode('menus', 'custom_menu_shortcode');
?>