> For AI agents: the complete documentation index is available at /ooui-react/llms.txt, the full documentation bundle is available at /ooui-react/llms-full.txt.

# MenuLayout 菜单布局

> [源代码](https://github.com/BearBin1215/ooui-react/tree/main/src/layouts/MenuLayout) | [原版组件](https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.MenuLayout.html "OO.ui.MenuLayout")

菜单布局：`menu`（菜单区）与 `children`（内容区）两块，按 `menuPosition` 决定菜单位置。收起菜单时菜单子树不渲染，避免隐形焦点陷阱。

## 基本用法

```tsx preview
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: "简介" },
              { value: "usage", children: "用法" },
            ]}
          />
        }
      >
        <div style={{ padding: 12 }}>
          {section === "intro" ? "这是「简介」内容。" : "这是「用法」内容。"}
        </div>
      </MenuLayout>
    </div>
  );
}

export default App;
```

## 菜单位置与收起

`menuPosition` 取 `before`（左，缺省）/ `after`（右）/ `top` / `bottom`；`showMenu={false}` 收起菜单。`expanded` 决定铺满父元素（`true`，缺省）还是按内容收缩（`static`）。

```tsx preview
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 }}>菜单区</div>}
        >
          <div style={{ padding: 12 }}>内容区</div>
        </MenuLayout>
      </div>
    </div>
  );
}

export default App;
```

:::note
`expanded`（缺省）形态按绝对定位铺满父元素，父元素需自行定位并给定尺寸；`expanded={false}` 为 static 形态、按内容收缩排列（上面的演示即该形态）。菜单的宽度与位置细节由主题 CSS 承载；带完整菜单交互的成品见 [BookletLayout](/ooui-react/components/booklet-layout/index.md) 与 [IndexLayout](/ooui-react/components/index-layout/index.md)。
:::

## API

继承 [Layout](/ooui-react/components/layout/index.md) 全部属性（含 `hidden` 三态），另有：

| 属性             | 描述                           | 类型                                         | 默认值        |
| -------------- | ---------------------------- | ------------------------------------------ | ---------- |
| `menu`         | 菜单区内容                        | `ReactNode`                                | —          |
| `menuPosition` | 菜单位置（非法值回退 `before`）         | `'before' \| 'after' \| 'top' \| 'bottom'` | `'before'` |
| `showMenu`     | 是否显示菜单（收起时菜单子树不渲染）           | `boolean`                                  | `true`     |
| `expanded`     | 是否铺满父元素（`false` 为 static 形态） | `boolean`                                  | `true`     |

## 另见

- 用它组装的成品：[BookletLayout](/ooui-react/components/booklet-layout/index.md)、[IndexLayout](/ooui-react/components/index-layout/index.md)
- `hidden` 三态语义：[Layout](/ooui-react/components/layout/index.md)
