# Hamburger Menu

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:272px] [&:has([data-state=open])]:h-[320px]"> <HamburgerMenu closeOnOutsideClick={false}> <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">{"Slot area"}</span> <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button> <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />{"220"}</Button> <HamburgerMenuItem href="#getting-started">{"Getting started"}</HamburgerMenuItem> <HamburgerMenuItem href="#components">{"Components"}</HamburgerMenuItem> </HamburgerMenu> </div>
</div>

```astro
---
---

<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:272px] [&:has([data-state=open])]:h-[320px]">
  <HamburgerMenu closeOnOutsideClick={false}>
    <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">Slot area</span>
    <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button>
    <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />220</Button>
    <HamburgerMenuItem href="#getting-started">Getting started</HamburgerMenuItem>
    <HamburgerMenuItem href="#components">Components</HamburgerMenuItem>
  </HamburgerMenu>
</div>
```

## Installation

<DocsTabs syncKey="pkg">
  <DocsTabItem label="bun">
  ```bash
  bunx bejamas add hamburger-menu
  ```
  </DocsTabItem>
  <DocsTabItem label="npm">
  ```bash
  npx bejamas add hamburger-menu
  ```
  </DocsTabItem>
  <DocsTabItem label="pnpm">
  ```bash
  pnpm dlx bejamas add hamburger-menu
  ```
  </DocsTabItem>
  <DocsTabItem label="yarn">
  ```bash
  yarn dlx bejamas add hamburger-menu
  ```
  </DocsTabItem>
</DocsTabs>

## Usage

```astro nocollapse
---
---
<HamburgerMenu>
  <a slot="brand" href="/">Bejamas UI</a>
  <HamburgerMenuGroup label="Getting started" defaultOpen>
    <HamburgerMenuItem href="/introduction">Introduction</HamburgerMenuItem>
    <HamburgerMenuItem href="/installation">Installation</HamburgerMenuItem>
  </HamburgerMenuGroup>
</HamburgerMenu>
```

## Props

| Prop | Type | Default |
|---|---|---|
| <code>class</code> | `string` | `""` |
| <code>defaultOpen</code> | `boolean` | `false` |
| <code>closeOnOutsideClick</code> | `boolean` | `true` |
| <code>label</code> | `string` | `"Mobile navigation"` |
| <code>triggerLabel</code> | `string` | `"Menu"` |

## Examples

### Closed

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:688px] [&:has([data-state=open])]:h-[736px]"> <HamburgerMenu closeOnOutsideClick={false}> <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">{"Slot area"}</span> <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button> <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />{"220"}</Button> <HamburgerMenuItem href="#getting-started">{"Getting started"}</HamburgerMenuItem> </HamburgerMenu> </div>
</div>

```astro
---
---

<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:688px] [&:has([data-state=open])]:h-[736px]">
  <HamburgerMenu closeOnOutsideClick={false}>
    <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">Slot area</span>
    <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button>
    <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />220</Button>
    <HamburgerMenuItem href="#getting-started">Getting started</HamburgerMenuItem>
  </HamburgerMenu>
</div>
```

### Opened Simple

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:688px] [&:has([data-state=open])]:h-[736px]"> <HamburgerMenu defaultOpen closeOnOutsideClick={false}> <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">{"Slot area"}</span> <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button> <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />{"220"}</Button> <HamburgerMenuItem href="#getting-started">{"Getting started"}</HamburgerMenuItem> <HamburgerMenuItem href="#installation">{"Installation"}</HamburgerMenuItem> <HamburgerMenuItem href="#components">{"Components"}</HamburgerMenuItem> <HamburgerMenuItem href="#concepts">{"Concepts"}</HamburgerMenuItem> <HamburgerMenuItem href="#blog">{"Blog"}</HamburgerMenuItem> <HamburgerMenuItem href="#about">{"About us"}</HamburgerMenuItem> <HamburgerMenuItem href="#contact">{"Contact us"}</HamburgerMenuItem> <HamburgerMenuItem href="#faq">{"FAQ"}</HamburgerMenuItem> <Button slot="footer" as="a" href="https://x.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on X"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/social-x.svg" width="16" height="16" alt="" /></Button> <Button slot="footer" as="a" href="https://github.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on GitHub"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-footer.svg" width="16" height="16" alt="" /></Button> </HamburgerMenu> </div>
</div>

```astro
---
---

<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:688px] [&:has([data-state=open])]:h-[736px]">
  <HamburgerMenu defaultOpen closeOnOutsideClick={false}>
    <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">Slot area</span>
    <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button>
    <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />220</Button>
    <HamburgerMenuItem href="#getting-started">Getting started</HamburgerMenuItem>
    <HamburgerMenuItem href="#installation">Installation</HamburgerMenuItem>
    <HamburgerMenuItem href="#components">Components</HamburgerMenuItem>
    <HamburgerMenuItem href="#concepts">Concepts</HamburgerMenuItem>
    <HamburgerMenuItem href="#blog">Blog</HamburgerMenuItem>
    <HamburgerMenuItem href="#about">About us</HamburgerMenuItem>
    <HamburgerMenuItem href="#contact">Contact us</HamburgerMenuItem>
    <HamburgerMenuItem href="#faq">FAQ</HamburgerMenuItem>
    <Button slot="footer" as="a" href="https://x.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on X"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/social-x.svg" width="16" height="16" alt="" /></Button>
    <Button slot="footer" as="a" href="https://github.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on GitHub"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-footer.svg" width="16" height="16" alt="" /></Button>
  </HamburgerMenu>
</div>
```

### Opened Advanced

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:688px] [&:has([data-state=open])]:h-[736px]"> <HamburgerMenu defaultOpen closeOnOutsideClick={false}> <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">{"Slot area"}</span> <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button> <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />{"220"}</Button> <HamburgerMenuGroup label="Getting started" defaultOpen> <HamburgerMenuItem href="#introduction">{"Introduction"}</HamburgerMenuItem> <HamburgerMenuItem href="#installation-advanced">{"Installation"}</HamburgerMenuItem> <HamburgerMenuItem href="#cli">{"CLI"}</HamburgerMenuItem> <HamburgerMenuItem href="#forms">{"Forms with Astro Actions"}</HamburgerMenuItem> </HamburgerMenuGroup> <HamburgerMenuGroup label="Components"><HamburgerMenuItem href="#buttons">{"Buttons"}</HamburgerMenuItem></HamburgerMenuGroup> <HamburgerMenuGroup label="Concepts"><HamburgerMenuItem href="#theming">{"Theming"}</HamburgerMenuItem></HamburgerMenuGroup> <HamburgerMenuGroup label="About us"><HamburgerMenuItem href="#team">{"Team"}</HamburgerMenuItem></HamburgerMenuGroup> <HamburgerMenuGroup label="Contact us"><HamburgerMenuItem href="#contact-details">{"Contact details"}</HamburgerMenuItem></HamburgerMenuGroup> <Button slot="footer" as="a" href="https://x.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on X"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/social-x.svg" width="16" height="16" alt="" /></Button> <Button slot="footer" as="a" href="https://github.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on GitHub"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-footer.svg" width="16" height="16" alt="" /></Button> </HamburgerMenu> </div>
</div>

```astro
---
---

<div class="relative w-full max-w-[375px] self-start overflow-hidden border border-border [--hamburger-menu-panel-height:688px] [&:has([data-state=open])]:h-[736px]">
  <HamburgerMenu defaultOpen closeOnOutsideClick={false}>
    <span slot="brand" class="flex h-8 w-[100px] items-center justify-center rounded-lg bg-muted text-muted-foreground">Slot area</span>
    <Button slot="actions" type="button" variant="secondary" size="icon" aria-label="Toggle theme"><SemanticIcon name="sun" /></Button>
    <Button slot="actions" as="a" href="https://github.com/bejamas" variant="secondary" aria-label="Bejamas on GitHub, 220 stars"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-header.svg" width="14" height="14" alt="" />220</Button>
    <HamburgerMenuGroup label="Getting started" defaultOpen>
      <HamburgerMenuItem href="#introduction">Introduction</HamburgerMenuItem>
      <HamburgerMenuItem href="#installation-advanced">Installation</HamburgerMenuItem>
      <HamburgerMenuItem href="#cli">CLI</HamburgerMenuItem>
      <HamburgerMenuItem href="#forms">Forms with Astro Actions</HamburgerMenuItem>
    </HamburgerMenuGroup>
    <HamburgerMenuGroup label="Components"><HamburgerMenuItem href="#buttons">Buttons</HamburgerMenuItem></HamburgerMenuGroup>
    <HamburgerMenuGroup label="Concepts"><HamburgerMenuItem href="#theming">Theming</HamburgerMenuItem></HamburgerMenuGroup>
    <HamburgerMenuGroup label="About us"><HamburgerMenuItem href="#team">Team</HamburgerMenuItem></HamburgerMenuGroup>
    <HamburgerMenuGroup label="Contact us"><HamburgerMenuItem href="#contact-details">Contact details</HamburgerMenuItem></HamburgerMenuGroup>
    <Button slot="footer" as="a" href="https://x.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on X"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/social-x.svg" width="16" height="16" alt="" /></Button>
    <Button slot="footer" as="a" href="https://github.com/bejamas" variant="secondary" size="icon" aria-label="Bejamas on GitHub"><img class="dark:brightness-0 dark:invert" src="/figma/hamburger-menu/github-footer.svg" width="16" height="16" alt="" /></Button>
  </HamburgerMenu>
</div>
```

## API Reference

The 48px header remains visible while the panel fills the rest of the viewport. Add your own controls with the `brand`, `actions`, and `footer` slots. For a fixed-height preview, set `--hamburger-menu-panel-height` on a parent element.

The trigger is named by `triggerLabel` and reports its state with `aria-expanded`. It supports mouse, touch, Enter, and Space. Escape closes the panel and returns focus to the trigger when focus was inside the menu. Clicking outside the menu or selecting a link closes the panel. Popovers and menus opened from the menu close first and count as inside it. Set `closeOnOutsideClick={false}` to keep the panel open while interacting with the rest of the page, for example in previews. Groups use native disclosure elements and support keyboard interaction.

The open state and dismissal are managed by `@data-slot/collapsible`, so the root sets `data-state` (`open` or `closed`), emits `collapsible:change` with `{ open: boolean }`, and accepts `collapsible:set` with `{ open: boolean }` for programmatic control.