Mmenu

npm docs github

Актуальная версия на момент написания 9.1.6

npm i mmenu-js

Особенности работы с TS

Необходим файл деклараций: mmenu-js.d.ts

declare module "mmenu-js" {
  /** An object with any value. */
  interface mmLooseObject {
    [key: string]: any;
  }

  /** An object with string values. */
  interface mmStringObject {
    [key: string]: string;
  }

  /** An object with boolean values. */
  interface mmBooleanObject {
    [key: string]: boolean;
  }

  /** An object with function values. */
  interface mmFunctionObject {
    [key: string]: Function;
  }

  /** An object with even listeners. */
  interface mmEventObject {
    [key: string]: EventListener;
  }

  /** An object with HTMLElement values. */
  interface mmHtmlObject {
    [key: string]: HTMLElement;
  }

  /** The menu API. */
  interface mmApi {
    bind: Function;

    openPanel: Function;
    closePanel: Function;
    setSelected: Function;

    //offCanvas add-on
    open: Function;
    close: Function;
    setPage: Function;
  }

  //Class methods interfaces.
  interface mmMethodUniqueid {
    (): string;
  }

  interface mmMethodI18n {
    (text?: object, language?: string): object;

    (text?: string, language?: string): string;

    (text?: undefined, language?: string): object;
  }

  /**  Options for the menu. */
  interface mmOptions {
    /** A collection of functions to hook into the API methods before the menu is initialised. */
    hooks?: mmFunctionObject;

    /** Options for the navbar. */
    navbar?: mmOptionsNavbar;

    /** Whether or not submenus should come sliding in from the right. */
    slidingSubmenus?: boolean;

    //Core add-ons

    /** Options for the off-canvas add-on. */
    offCanvas?: mmOptionsOffcanvas;

    /** Options for the scroll bug fix add-on. */
    scrollBugFix?: mmOptionsScrollbugfix;

    /** Options for the themes add-on. */
    theme?: string;

    //Add-ons

    /** Options for the back button add-on. */
    backButton?: mmOptionsBackbutton;

    /** Options for the counters add-on. */
    counters?: mmOptionsCounters;

    /** Options for the iconbar add-on. */
    iconbar?: mmOptionsIconbar;

    /** Options for the icon panels add-on. */
    iconPanels?: mmOptionsIconpanels;

    /** List of navbar options for the navbars add-on. */
    navbars?: mmOptionsNavbarsNavbar[];

    /** Options for the page scroll add-on. */
    pageScroll?: mmOptionsPagescroll;

    /** Options for the searchfield add-on. */
    searchfield?: mmOptionsSearchfield;

    /** Options for the section indexer add-on. */
    sectionIndexer?: mmOptionsSectionindexer;

    /** Options for the set selected add-on. */
    setSelected?: mmOptionsSetselected;

    /** Options for the sidebar add-on. */
    sidebar?: mmOptionsSidebar;
  }

  /**  Navbar options for the menu. */
  interface mmOptionsNavbar {
    /** Whether or not to add a navbar above the panels. */
    add?: boolean;

    /** The title above the panels. */
    title?: string;

    /** The type of link to set for the title. */
    titleLink?: "parent" | "anchor" | "none";
  }

  /**  Configuration for the menu. */
  interface mmConfigs {
    /** Object with classnames to refactor. */
    classNames?: mmLooseObject;

    /** The language to translate the menu to. */
    language?: string;

    /** List of possible node-type of panels. */
    panelNodetype?: string[];

    /** Configuration for the screen reader add-on. */
    screenReader?: mmConfigsScreenreader;

    //Core add-ons

    /** Configuration for the off-canvas add-on. */
    offCanvas?: mmConfigsOffcanvas;

    //Add-ons

    /** Configuration for the navbars add-on. */
    navbars?: mmConfigsNavbars;

    /** Configuration for the page scroll add-on. */
    pageScroll?: mmConfigsPagescroll;

    /** Configuration for the searchfield add-on. */
    searchfield?: mmConfigsSearchfield;
  }

  //  ScreenReader configs interfaces.
  interface mmConfigsScreenreader {
    closeMenu?: string;
    closeSubmenu?: string;
    openMenu?: string;
    openSubmenu?: string;
    toggleSubmenu?: string;
  }

  export = class Mmenu {
    constructor(
      menu: HTMLElement | string,
      options?: mmOptions,
      configs?: mmConfigs
    );

    open(): void;

    close(): void;
  };
}

Пример использования

Ссылка на пример

HTML разметка


<div>
  <button class="js-mobile-menu-trigger">Open menu</button>
</div>
<div class="js-mobile-menu" hidden>
  <ul>
    <li>
      <a href="/">Home</a>
    </li>
    <li>
      <a href="/catalog">Catalog</a>
      <ul>
        <li>
          <a href="/test-1">Test 1</a>
        </li>
        <li>
          <a href="/test-2">Test 2</a>
        </li>
      </ul>
    </li>
  </ul>
</div>

TS код

import Menu from "mmenu-js";
import "mmenu-js/dist/mmenu.css";

const menuElement = document.querySelector<HTMLElement>(".js-mobile-menu");
const menuTriggerElement = document.querySelector<HTMLElement>(
  ".js-mobile-menu-trigger",
);
if (menuElement && menuTriggerElement) {
  const menu = new Menu(menuElement, {
    navbar: {
      title: "Меню",
    },
  });
  menuTriggerElement.addEventListener("click", () => {
    menu.open();
  });
}

Требования

Сценарии использования

Добавление социалок и логотипа

Добавить блоки можно используя секцию navbars в настройках:

const menu = new Menu(menuElement, {
  navbar: {
    title: "Меню",
  },
  navbars: [
    {
      content: ["You can post logo here"],
      position: "top",
    },
    {
      content: ["You can post social links here"],
      position: "bottom",
    },
  ],
});

top и bottom указывают на расположение секции.

Для добавления html в navbars используйте <template>Doka, MDN:


<template class="js-mobile-menu-socials">
  <div>
    <ul class="mobile-menu-socials">
      <li class="mobile-menu-socials__item">
        <a
          href="https://vk.com/"
          target="_blank"
          rel="nofollow noreferrer"
          class="mobile-menu-socials__link"
        >VK</a
        >
      </li>
      <li class="mobile-menu-socials__item">
        <a
          href="https://youtube.com/"
          target="_blank"
          rel="nofollow noreferrer"
          class="mobile-menu-socials__link"
        >Youtube</a
        >
      </li>
    </ul>
  </div>
</template>
const socials = document.querySelector<HTMLTemplateElement>(
  ".js-mobile-menu-socials",
);
// ...
if (/*... && */ socials)
  const menu = new Menu(menuElement, {
    // ...
    navbars: [
      // ...
      {
        content: [socials.content.cloneNode(true)],
        position: "bottom",
      },
    ],
  });

Асинхронная загрузка

mmenu-js можно грузить не сразу, а только при клике на кнопку меню

menuTriggerElement.addEventListener("click", async () => {
  const Menu = await import("mmenu-js");
  const menu = new Menu(menuElement, {
    navbar: {
      title: "Меню",
    },
  });
});