# Context-Menu

<figure><img src="https://2088945756-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkHcyR2RbVMcj5NHJ2HEa%2Fuploads%2Fa1WZblrcWL9qpnXmYdhV%2Fimage.png?alt=media&#x26;token=9df78f68-5518-40a0-97ca-32cee3bbc839" 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)
```
