MarkupRefineLib

Menu


Application shell

The mr-shell component provides the application-shell pattern. Presentation usesmr-shell__* classes. Behavior discovery usesdata-mr-shell, data-mr-shell-action, anddata-mr-shell-part.

Layer-backed mobile navigation

The sidebar remains ordinary document navigation for desktop and no-JavaScript use. When JavaScript enhances the shell, the mobile menu temporarily moves that same navigation DOM into a generated data-mr-layer="drawer" native <dialog>. The shared Layer core owns modal open/close state, Escape/request-close handling, native backdrop behavior, light-dismiss compatibility, and focus restoration.

Shell behavior is limited to navigation concerns: moving the existing navigation into and out of the transient drawer, choosing the dismiss button as initial focus, and synchronizingaria-expanded/aria-controls on the menu button. There is no shell-specific overlay element, document-level Escape listener, or private open/closed state machine.

Without JavaScript the sidebar remains in the document and enhancement-only toggle/dismiss controls remain hidden, preserving access to navigation content.

Complete structure

<header class="mr-shell" data-mr-shell>
  <div class="mr-shell__topbar">
    <div class="mr-shell__topbar-content">
      <button
        class="mr-shell__button mr-shell__toggle"
        data-mr-shell-action="toggle"
      >Menu</button>
      <h1 class="mr-nav-title">Sample page</h1>
      <button
        class="mr-search-trigger"
        data-mr-search
        data-mr-search-static-url="/search-index.json"
      >Search</button>
    </div>
  </div>

  <aside class="mr-shell__sidebar" data-mr-shell-part="sidebar">
    <div class="mr-shell__sidebar-header">
      <h2>Menu</h2>
      <button
        class="mr-shell__button mr-shell__dismiss"
        data-mr-shell-action="dismiss"
      >Close</button>
    </div>

    <ul class="mr-clickable-list">
      <li><a href="/">Home</a></li>
      <li><a href="/docs">Docs</a></li>
    </ul>
  </aside>

  <div class="mr-shell__subbar">
    <div class="mr-shell__subbar-content">
      <nav class="mr-nav-tabs">
        <a href="/one">One</a>
        <a href="/two" aria-current="page">Two</a>
      </nav>
    </div>
  </div>
</header>

<main class="mr-container mr-shell__main">
  ...
</main>

Live demo

The same contract is used by the documentation site and thestandalone demo.

Standalone top bar

<header class="mr-shell" data-mr-shell>
  <div class="mr-shell__topbar">
    <div class="mr-shell__topbar-content">
      <h1 class="mr-nav-title">Sample page</h1>
    </div>
  </div>
</header>

Optional shell presentation helpers

mr-shell__toolbar is an optional toolbar region whose responsive transform is normalized by the shell stylesheet. mr-shell__sidebar-section is a compact flex row for controls/content inside either the persistent sidebar or generated drawer. These classes are presentation-only and do not participate in Layer state.

Lower-capability fallback

The authored sidebar is the fallback. It remains ordinary navigation in the document until mobile enhancement can safely move those same nodes into a drawer Layer. The navigation itself therefore never depends on the generated drawer existing.

Layer migration note

The public shell hooks remain data-mr-shell,data-mr-shell-action, and data-mr-shell-part. The former private overlay element, private open/closed state attribute, and document-level Escape handler have been removed; integrations should observe native/Layer state and lifecycle rather than target those internals.