# Context-Menu

<figure><img src="/files/pkHYl3vMbUlA6YAhqfcD" alt=""><figcaption></figcaption></figure>

### 🧭 Menu Types: Context vs. Menu

Before diving into the functions, it's important to understand the two distinct ways you can display data using `ak47_lib`:

1. Context Menus (`RegisterContext` & `ShowContext`): Best for static lists of actions where the user clicks an option to trigger an event, server event, or function. Usually mouse-driven.
2. Interactive Menus (`RegisterMenu` & `ShowMenu`): Best for complex interactions like checkboxes, side-scrolling lists, and real-time navigation feedback. Completely keyboard-driven (Arrow Keys, Enter, Backspace).

***

### 🛠️ Core Functions

#### `RegisterContext`

Registers a mouse-driven context menu. This data is cached and can be called anytime using `ShowContext`.

Syntax:

```lua
exports.ak47_lib:RegisterContext(data)
```

Example:

```lua
exports.ak47_lib:RegisterContext({
    id = 'player_actions',
    title = 'Player Actions', 
    position = 'top-right',
    canClose = true,
    options = {
        {
            title = 'Heal Player',
            description = 'Restores health to **100%**',
            icon = 'heart',
            iconColor = '#ff5555',
            onSelect = function() print("Heal button pressed!") end
        },
        {
            title = 'Give Weapon',
            description = 'Triggers a client event',
            icon = 'gun', 
            event = 'my_custom_client_event',
            args = { weapon = 'WEAPON_PISTOL', ammo = 250 }
        }
    }
})
```

#### `RegisterMenu`

Registers a keyboard-driven interactive menu. Features a master callback that triggers when the user presses `Enter` on an item.

Syntax:

```lua
exports.ak47_lib:RegisterMenu(data, callback(selected, scrollIndex, args))
```

Example:

```lua
exports.ak47_lib:RegisterMenu({
    id = 'settings_menu',
    title = 'Server Settings',
    position = 'top-left',
    onClose = function(keyPressed)
        print('Menu closed using: ' .. tostring(keyPressed))
    end,
    options = {
        { label = 'Godmode', icon = 'shield', checked = false, args = { setting = 'godmode' } },
        { label = 'Time of Day', icon = 'clock', values = {'Morning', 'Noon', 'Night'}, defaultIndex = 2 }
    }
}, function(selected, scrollIndex, args)
    print(('Selected Item: %s, Scroll Index: %s'):format(selected, tostring(scrollIndex)))
    if args then print('Args: ', json.encode(args)) end
end)
```

#### Display & Hide Functions

| **Function**  | **Description**                                                                 | **Example Usage**                                       |
| ------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `ShowContext` | Opens a registered context menu. You can specify if it should be keyboard only. | `exports.ak47_lib:ShowContext('player_actions', false)` |
| `ShowMenu`    | Opens a registered menu in strict keyboard-only mode.                           | `exports.ak47_lib:ShowMenu('settings_menu')`            |
| `HideContext` | Closes the active context menu.                                                 | `exports.ak47_lib:HideContext(true)`                    |
| `HideMenu`    | Closes the active interactive menu.                                             | `exports.ak47_lib:HideMenu(true)`                       |
| `GetOpenMenu` | Returns the string `id` of the currently open menu, or `nil`.                   | `local current = exports.ak47_lib:GetOpenMenu()`        |

#### `SetMenuOptions`

Dynamically updates the options of a registered menu without needing to re-register it.

Syntax:

```lua
-- Update ALL options
exports.ak47_lib:SetMenuOptions('menu_id', newOptionsTable)

-- Update a SINGLE option (e.g., updating the 2nd item)
exports.ak47_lib:SetMenuOptions('menu_id', updatedOptionData, 2)
```

***

### ⚙️ Configuration Properties

#### Menu Configuration (`data` table)

These properties are used at the root level of `RegisterContext` or `RegisterMenu`.

| **Property**   | **Type**   | **Description**                                                    |
| -------------- | ---------- | ------------------------------------------------------------------ |
| `id`           | `string`   | Required. A unique identifier for the menu.                        |
| `title`        | `string`   | The display title at the top of the menu.                          |
| `position`     | `string`   | `'top-left'`, `'top-right'`, `'bottom-left'`, or `'bottom-right'`. |
| `canClose`     | `boolean`  | If `true`, the user can press ESC/Backspace to close.              |
| `disableInput` | `boolean`  | If `true`, disables all player controls while the menu is open.    |
| `options`      | `table`    | Required. An array of option objects (see below).                  |
| `onClose`      | `function` | Triggers when the menu is closed (receives the key pressed).       |
| `onSelected`   | `function` | (*RegisterMenu only*) Triggers when an item is hovered.            |
| `onSideScroll` | `function` | (*RegisterMenu only*) Triggers when a side-scrolling list changes. |
| `onCheck`      | `function` | (*RegisterMenu only*) Triggers when a checkbox is toggled.         |

#### Option Configuration (Items inside `options`)

| **Property**      | **Type**  | **Description**                                                                              |
| ----------------- | --------- | -------------------------------------------------------------------------------------------- |
| `title` / `label` | `string`  | Required. The main text of the button. (`title` is preferred for Context, `label` for Menu). |
| `description`     | `string`  | Secondary text displayed as a tooltip or subtext.                                            |
| `icon`            | `string`  | FontAwesome icon name (e.g., `'car'`, `'shield'`) or an image URL/Path.                      |
| `iconColor`       | `string`  | Hex or RGB color for the icon (e.g., `'#ff5555'`).                                           |
| `iconAnimation`   | `string`  | FontAwesome animation class (e.g., `'spin'`, `'beat'`).                                      |
| `disabled`        | `boolean` | Grays out the button and prevents interaction.                                               |
| `readOnly`        | `boolean` | Prevents hovering/clicking, but doesn't look completely disabled.                            |
| `progress`        | `number`  | `0-100`. Displays a progress bar inside the button.                                          |
| `colorScheme`     | `string`  | Color used for the progress bar.                                                             |
| `args`            | `table`   | Custom data passed to events/callbacks when this item is interacted with.                    |
| `close`           | `boolean` | Set to `false` to keep the menu open after clicking. Defaults to `true`.                     |

#### Advanced Option Properties (Context Menus)

* `event` (`string`): Triggers a client event when clicked. Passes `args`.
* `serverEvent` (`string`): Triggers a server event when clicked. Passes `args`.
* `onSelect` (`function`): Anonymous function executed when clicked. Passes `args`.
* `menu` (`string`): The `id` of another menu to open when clicked (Submenu).

#### Advanced Option Properties (Interactive Menus)

* `checked` (`boolean`): Turns the option into a Checkbox.
* `values` (`table`): Array of strings or `{label, description}` objects. Turns the option into a Side-Scroller (Left/Right arrows).
* `defaultIndex` (`number`): The starting index (1-based) for a `values` list.

#### Metadata Panel (Player/Vehicle Stats)

You can attach a beautiful side-panel to any option by adding `image` and `metadata`.

```lua
{
    label = 'Inspect Vehicle',
    icon = 'magnifying-glass',
    image = 'https://docs.fivem.net/vehicles/t20.webp',
    metadata = {
        { label = 'Model', value = 'T20' },
        { label = 'Plate', value = 'LIB47DEV' },
        { label = 'Engine Health', value = '85%', progress = 85, colorScheme = '#fbc531' }
    }
}
```

***

### 📝 Complete Usage Example

Here is a comprehensive example demonstrating submenus, side-scrolling, checkboxes, and metadata all working together seamlessly:

```lua
-- 1. Register a Sub-Menu
exports.ak47_lib:RegisterContext({
    id = 'vehicle_options',
    title = 'Vehicle Options',
    position = 'top-right',
    options = {
        { title = 'Toggle Engine', icon = 'power-off', iconColor = '#e1b12c' },
        { title = 'Lock Doors', icon = 'key' }
    }
})

-- 2. Register the Main Menu
exports.ak47_lib:RegisterMenu({
    id = 'main_showcase',
    title = 'Interaction Menu',
    position = 'top-right',
    onSideScroll = function(selected, scrollIndex, args)
        print(("Scrolled item %s to index %s"):format(selected, scrollIndex))
    end,
    options = {
        {
            label = 'Give Weapon',
            description = 'Triggers an event instantly.',
            icon = 'gun',
            args = { weapon = 'WEAPON_APPISTOL' }
        },
        {
            label = 'Vehicle Settings',
            description = 'Open vehicle options menu.',
            icon = 'car',
            menu = 'vehicle_options' -- Links to the submenu created above
        },
        {
            label = 'Select Ammo Type',
            icon = 'box-archive',
            values = {'Standard', 'Tracer', 'Incendiary', 'Armor Piercing'},
            defaultIndex = 2, -- Starts on 'Tracer'
            args = { type = 'ammo_selection' }
        },
        {
            label = 'Player Stats',
            description = 'Hover to view details.',
            icon = 'user',
            metadata = {
                { label = 'Job', value = 'Police' },
                { label = 'Rank', value = 'Captain' },
                { label = 'Hunger', value = '75%', progress = 75, colorScheme = '#e67e22' }
            }
        }
    }
}, function(selected, scrollIndex, args)
    -- Master Callback for RegisterMenu
    print(('You pressed Enter on item #%s'):format(selected))
    if args then
        print('With Arguments: ', json.encode(args))
    end
end)

-- 3. Open the Menu via Command
RegisterCommand('openmenu', function()
    exports.ak47_lib:ShowMenu('main_showcase')
end)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.menanak47.com/plugins/ak47_lib/interface/context-menu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
