> ## Documentation Index
> Fetch the complete documentation index at: https://docs.atlasscripts.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Menus

> Two list UIs — Menu for interactive option lists with toggles and steppers, Context for a simple action list.

The bridge ships two list UIs, both with option callbacks that live in your resource:

* **`Bridge.Menu`** — a side-anchored, navigable list that can hold buttons, **toggles**, and **steppers**. A toggle/stepper change keeps the menu open; selecting a button closes it.
* **`Bridge.Context`** — a simpler list of actions, each a title + description that closes on select.

Neither blocks — you hand the menu your `onSelect` / `onChange` callbacks and they fire when the player interacts.

<Note>
  **`Bridge.Menu` is keyboard-driven and keeps the player moving.** It navigates with the arrow keys (up/down to move, left/right to step, Enter to choose, Backspace/Escape to close) and opens with `SetNuiFocusKeepInput`, so the player can still walk around while the menu is open — the ox\_lib `registerMenu` feel. **`Bridge.Context` is mouse-driven** and takes the cursor (the player stands still while it's open).
</Note>

## Availability

Client only.

```lua theme={null}
Bridge.Menu.Open(def)
Bridge.Context.Open(def)
```

## Menu

### Signature

`Bridge.Menu.Open(def)`

<ParamField path="title" type="string">
  The menu heading.
</ParamField>

<ParamField path="subtitle" type="string">
  A muted second line under the title.
</ParamField>

<ParamField path="icon" type="string">
  An icon shown in the header.
</ParamField>

<ParamField path="canClose" type="boolean" default="true">
  Whether the player can dismiss the menu without selecting.
</ParamField>

<ParamField path="options" type="table[]" required>
  The rows. Each option is shaped below.
</ParamField>

<ParamField path="onClose" type="function">
  Called when the menu closes (after a select, or on dismiss).
</ParamField>

#### Option fields

<ParamField path="options[].type" type="string" default="button">
  `button`, `toggle`, `stepper`, or `separator`.
</ParamField>

<ParamField path="options[].label" type="string">
  The row text.
</ParamField>

<ParamField path="options[].description" type="string">
  A muted sub-line.
</ParamField>

<ParamField path="options[].icon" type="string">
  A leading icon.
</ParamField>

<ParamField path="options[].disabled" type="boolean">
  Greys the row out and blocks selection.
</ParamField>

<ParamField path="options[].checked" type="boolean">
  For `toggle` rows — the initial on/off state.
</ParamField>

<ParamField path="options[].values" type="string[]">
  For `stepper` rows — the list of values to cycle through.
</ParamField>

<ParamField path="options[].index" type="number" default="0">
  For `stepper` rows — the starting index into `values`.
</ParamField>

<ParamField path="options[].arrow" type="boolean">
  Shows a submenu arrow on the right (you handle opening the next menu in `onSelect`).
</ParamField>

<ParamField path="options[].onSelect" type="function">
  Called when a `button` row is chosen. The menu then closes.
</ParamField>

<ParamField path="options[].onChange" type="function">
  Called with the new value when a `toggle` (boolean) or `stepper` (selected value) changes. The menu stays open.
</ParamField>

### Examples

<CodeGroup>
  ```lua Basic theme={null}
  Bridge.Menu.Open({
      title = 'Vehicle',
      options = {
          { label = 'Lock',  icon = 'lock',  onSelect = function() lock() end },
          { label = 'Trunk', icon = 'box',   onSelect = function() openTrunk() end },
      },
  })
  ```

  ```lua Toggles + steppers theme={null}
  Bridge.Menu.Open({
      title    = 'Vehicle controls',
      subtitle = 'Adder',
      icon     = 'car',
      options = {
          { label = 'Engine', type = 'toggle', checked = engineOn,
            onChange = function(on) setEngine(on) end },
          { label = 'Seat', type = 'stepper',
            values = { 'Driver', 'Passenger', 'Rear left', 'Rear right' }, index = 0,
            onChange = function(seat) print('seat ->', seat) end },
          { type = 'separator' },
          { label = 'Door locks', icon = 'lock', arrow = true,
            onSelect = function() openLockSubmenu() end },
      },
      onClose = function() print('menu closed') end,
  })
  ```
</CodeGroup>

<Note>
  `onChange` keeps the menu open so the player can flip several toggles/steppers in one session. Only a `button` `onSelect` (or a dismiss) ends the menu.
</Note>

## Context

A flatter list — each item is a clickable action that closes the menu on select.

### Signature

`Bridge.Context.Open(def)`

<ParamField path="title" type="string">
  The heading.
</ParamField>

<ParamField path="options" type="table[]" required>
  The items (also accepted under `items`).
</ParamField>

<ParamField path="onClose" type="function">
  Called when the context menu closes.
</ParamField>

#### Item fields

<ParamField path="options[].title" type="string" required>
  The item text (also accepted as `label`).
</ParamField>

<ParamField path="options[].description" type="string">
  A muted sub-line.
</ParamField>

<ParamField path="options[].icon" type="string">
  A leading icon.
</ParamField>

<ParamField path="options[].disabled" type="boolean">
  Greys the item out and blocks selection.
</ParamField>

<ParamField path="options[].onSelect" type="function">
  Called when the item is chosen. The menu then closes.
</ParamField>

### Example

```lua theme={null}
Bridge.Context.Open({
    title = 'Actions',
    options = {
        { title = 'Inspect', description = 'Look closer', icon = 'eye',
          onSelect = function() inspect() end },
        { title = 'Pick up', description = 'Add to inventory', icon = 'hand',
          onSelect = function() pickUp() end },
    },
})
```

<Tip>
  Both menus tint their selection highlight, icons, and toggles to the player's theme accent. Set `atlas:ui "ox"` (or `atlas:ui:menu` / `atlas:ui:context`) to render the same calls through ox\_lib instead.
</Tip>
