For AI agents: the complete documentation index is available at /ooui-react/en/llms.txt, the full documentation bundle is available at /ooui-react/en/llms-full.txt, and this page is available as Markdown at /ooui-react/en/components/menu-layout/index.md.
  • English
  • MenuLayout

    Source | Original component

    A menu layout: a menu area and a content area (children), with the menu placed by menuPosition. When the menu is collapsed its subtree is not rendered, avoiding invisible focus traps.

    Basic usage

    Intro
    Usage
    This is the Intro content.
    import { useState } from "react";
    import { MenuLayout, OutlineSelect } from "ooui-react";
    
    function App() {
      const [section, setSection] = useState("intro");
    
      return (
        <div style={{ height: 200 }}>
          <MenuLayout
            menuPosition="before"
            expanded={false}
            menu={
              <OutlineSelect
                value={section}
                onChange={(value) => setSection(String(value))}
                options={[
                  { value: "intro", children: "Intro" },
                  { value: "usage", children: "Usage" },
                ]}
              />
            }
          >
            <div style={{ padding: 12 }}>
              {section === "intro" ? "This is the Intro content." : "This is the Usage content."}
            </div>
          </MenuLayout>
        </div>
      );
    }
    
    export default App;

    menuPosition takes before (left, default) / after (right) / top / bottom; showMenu={false} collapses the menu. expanded decides whether the layout fills the parent (true, default) or shrinks to content (static).

    Menu area
    Content area
    import { useState } from "react";
    import { MenuLayout } from "ooui-react";
    
    const positions = ["before", "after", "top", "bottom"] as const;
    
    function App() {
      const [position, setPosition] = useState<(typeof positions)[number]>("before");
    
      return (
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          <div style={{ display: "flex", gap: 8 }}>
            {positions.map((item) => (
              <button key={item} onClick={() => setPosition(item)}>
                {item}
              </button>
            ))}
          </div>
          <div style={{ height: 160 }}>
            <MenuLayout
              menuPosition={position}
              expanded={false}
              menu={<div style={{ padding: 12 }}>Menu area</div>}
            >
              <div style={{ padding: 12 }}>Content area</div>
            </MenuLayout>
          </div>
        </div>
      );
    }
    
    export default App;
    Note

    The expanded (default) form fills the parent with absolute positioning — the parent must position and size itself; expanded={false} is the static form that shrinks to content (the demos above use it). Menu width and placement details come from the theme CSS. For finished components with full menu interaction, see BookletLayout and IndexLayout.

    API

    Inherits all Layout props (including the hidden three states), plus:

    PropDescriptionTypeDefault
    menuThe menu area contentReactNode—
    menuPositionMenu position (invalid values fall back to before)'before' | 'after' | 'top' | 'bottom''before'
    showMenuWhether to show the menu (the subtree is not rendered when collapsed)booleantrue
    expandedWhether to fill the parent (false is the static form)booleantrue

    See also