> For the complete documentation index, see [llms.txt](https://docs.tmc.bj/v2/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tmc.bj/v2/tmc-core-object/client-menus.md).

# Client Menus

### OpenMenu

Opens a customisable menu or form. A menu can be used whilst moving around whilst a form takes full control of the users UI.

<table><thead><tr><th width="168.33333333333331">Parameter</th><th width="110" data-type="checkbox">Required</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td>settings</td><td>true</td><td><a href="#setting-object">Object</a></td><td>An object containing settings for the form</td></tr><tr><td>elements</td><td>true</td><td><a href="#element-object">Array/List</a></td><td>A list of elements to include on the form</td></tr><tr><td>closeHandler</td><td>false</td><td>Function</td><td>A function that gets triggered when the menu is closed.</td></tr><tr><td>selectHandler</td><td>false</td><td>Function</td><td>A function that gets triggered when using a menu and the highlighted field is modified.</td></tr><tr><td>changeHandler</td><td>false</td><td>Function</td><td>A function that gets triggered when a value within the form gets changed or a button element is pressed.</td></tr></tbody></table>

{% tabs %}
{% tab title="Setting Object" %}

```lua
{ -- Settings
    namespace = '', -- String, required
    title = '', -- String
    subtitle = '', -- String
    searchable = false, -- Boolean, only available for forms
    form = false, -- Boolean, enables direct input including mouse
    disableFormButtons = false, -- Boolean, disables Confirm/Cancel buttons on the form. Will always return "complete" as false within the close handler
}
```

{% endtab %}

{% tab title="Element Object" %}

```lua
{
    type = '', -- String, defaults to button (text, checkbox, toggle, slider, select, button, linebreak, subtitle, number). 'select', 'number' and 'text' automatically enable the form option for the menu
    name = '', -- String, required. Refernce for any return event. Not required for linebreak or subtitle
    label = '', -- String, required. Display label. Not required for linebreak
    value = nil, -- Anything, sets default value if applicable
    disabled = false, -- Boolean

    required = false, -- Boolean, force validation on input
    regex = '', -- String, regex string for validating input. You can also pass the term `json` in order to activate JSON validation
    validationMessage = '', -- String, required if regex is in use. Set the message to display to the end user

    -- Subtitle
    size = nil, -- Number, font size in VH units
    position = nil, -- String, any applicable text-align variables I.e. left, right, center
    margin = nil, -- Number, margin to apply in VH units. Can be negative to reduce the spacing between elements (I.e. -1)

    -- Text
    multiline = false, -- Boolean, used to change from a single line input to a text box (type of 'text' only)

    -- Button/Number
    icon = '', -- String (type of 'button' or 'number' only). Can change to any FontAwesome (including Pro) icons. Use full reference. I.e. `fad fa-heart`
    description = '', -- String (type of 'button' or 'number' only)

    -- Select
    options = { -- Array of options (type of 'select' only)
        {
            value = '', -- String, required
            label = '', -- String, falls back to value if not specified
        }
    },
    multiselect = false, -- Boolean, used to allow multiple selections

    -- Slider
    step = 1, -- Number (type of 'slider' only). Used to specify the jump step of the slider
    min = 0, -- Number (type of 'slider' or 'number' only). The minimum value of the slider
    max = 100, -- Number (type of 'slider' or 'number' only). The maxmimum value of the slider
}
```

{% endtab %}
{% endtabs %}

<details>

<summary>Example</summary>

```lua
TMC.Functions.OpenMenu({
    namespace = 'testing_namespace',
    title = 'Test',
    subtitle = 'Subtitle',
    searchable = true,
    form = true
},{
    {
        type = 'text',
        name = 'text_test',
        label = 'Text Test',
        multiline = false,
    },
    {
        type = 'slider',
        name = 'slider_test',
        label = 'Slider Test',
        disabled = true,
        min = 0,
        max = 100
    },
    {
        type = 'number',
        name = 'number_test',
        label = 'Number Test',
        min = 0,
        max = 100
    },
    {
        type = 'checkbox',
        name = 'checkbox_test',
        label = 'Checkbox Test'
    },
    {
        type = 'linebreak'
    },
    {
        type = 'subtitle',
        name = 'subtitle_break',
        label = 'More Elements',
        position = 'center',
        size = 2.5,
        margin = 2
    },
    {
        type = 'linebreak'
    },
    {
        type = 'select',
        name = 'select_test',
        label = 'Select Test',
        disabled = true,
        options = {
            {
                value = 'test1',
                label = 'Test 1'
            },
            {
                value = 'test2'
            }
        }
    },
    {
        type = 'toggle',
        name = 'toggle_test',
        label = 'Toggle Test'
    },
    {
        type = 'button',
        name = 'button_test',
        label = 'Button Test',
        description = 'Some description here',
        icon = 'fad fa-heartbeat',
        disabled = true
    }
}, function(close, confirmed) -- Close handler
--[[
    Close will return an object constructed with the `name` variable of the elements.
    
    Confirmed will return true only when the "confirm" button is present and clicked (forms).
]]
end, function(select) -- Select handler (only used for menus)
	-- Select will return an object as follows
    select = {
        elementSelected = '', -- Reference to selected/highlighted element
        value = nil, -- Referenced element's value
    }
end, function(change) -- Change handler
    -- Change will return an object as follows
    change = {
        elementChanged = '', -- Reference to changed element
        newVal = nil, -- The new value (everything but type of 'button')
        oldVal = nil, -- The old value (everything but type of 'button')
        value = nil, -- The button value (type of 'button' only)
    }
end)
```

</details>

### UpdateMenuElement

Can handle any element data apart from type. See [Menu Element Object](#element-object) for the element structure. Only name is required and it will only update the fields that are provided.

```lua
TMC.Functions.UpdateMenuElement({
    name = 'text_test',
    multiline = true,
    label = 'An Updated Text Test',
    value = 'Forced value',
    disabled = true
})

TMC.Functions.UpdateMenuElement({
    name = 'button_test',
    icon = 'fas fa-heartbeat',
    disabled = false
})
```

### RemoveMenuElement

Can handle any element. Used to remove an element from a form.

```lua
TMC.Functions.RemoveMenuElement({
    name = 'text_test'
})
```

### StartSideMenuUi

These use direct callbacks based on the menu type. You will need to use TMC.Functions.RegisterUiHandler instead of callbacks.

<table data-full-width="false"><thead><tr><th width="155.33333333333331">Parameter</th><th width="116" data-type="checkbox">Required</th><th width="118">Type</th><th>Description</th></tr></thead><tbody><tr><td>menuRef</td><td>true</td><td>String</td><td>Reference to the side menu which events should be triggered for.</td></tr><tr><td>categories</td><td>true</td><td><a href="#category-object">Array/List</a></td><td>An array of category definitions.</td></tr><tr><td>elements</td><td>true</td><td><a href="#element-object-1">Array/List</a></td><td>An array of element definitions.</td></tr><tr><td>controls</td><td>false</td><td><a href="#control-array">Array/List</a></td><td>An array of control definitions</td></tr><tr><td>disableCancel</td><td>false</td><td>Bool</td><td>Disable the cancel button.</td></tr><tr><td>closeOnly</td><td>false</td><td>Bool</td><td>Hides both <code>Confirm</code> and <code>Cancel</code> buttons and puts a <code>Close</code> button in it's place.</td></tr><tr><td>initialTab</td><td>false</td><td>String</td><td>A reference to the initial category to show. When left blank it will default to the first category in the list.</td></tr></tbody></table>

{% tabs %}
{% tab title="Category Object" %}

```lua
{
    name = '', -- String, required
    label = '', -- String, required
    icon = '', -- String, required (FontAwesome ref)
    disabled = false, -- Boolean
    searchable = false -- Boolean, add filter/search box to tab
}
```

{% endtab %}

{% tab title="Element Object" %}

```lua
{
    type = '', -- String, defaults to `default` (default, grid-slider, text, checkbox, toggle, slider, select, button, linebreak, subtitle, colour-picker, preview-select)
    name = '', -- String, required. Refernce for any return event. Not required for linebreak or subtitle
    label = '', -- String, required. Display label. Not required for linebreak
    cat = '', -- String, required. The category to place the element in
    val = nil, -- Anything, sets default value if applicable. See types of select, default and grid-slider below
    disabled = false, -- Boolean

    -- Subtitle
    size = nil, -- Number, font size in VH units
    position = nil, -- String, any applicable text-align variables I.e. left, right, center
    margin = nil, -- Number, margin to apply in VH units. Can be negative to reduce the spacing between elements (I.e. -1)

    -- Text
    multiline = false, -- Boolean, used to change from a single line input to a text box (type of 'text' only)

    -- Button / Preview Select
    icon = '', -- String (type of 'button' or 'preview-select' only). Can change to any FontAwesome (including Pro) icons. Use full reference. I.e. `fad fa-heart`
    description = '', -- String (type of 'button' only)

    -- Select / Preview Select
    options = { -- Array of options (type of 'select' or 'preview-select' only)
        {
            value = '', -- String, required
            label = '', -- String, falls back to value if not specified
            colour = '', -- String, rgba/hex code for preview colour. Only used for colourSwatch mode on 'select' type
        }
    },
    selectedOption = nil, -- Must match a value from the options table and sets the default value
    colourSwatch = false, -- Boolean, enable colour swatch mode ('select' type only)
    multiselect = false, -- Boolean, used to allow multiple selections (cannot be used in colourSwatch mode)

    -- Slider
    step = 1, -- Number (type of 'slider' only). Used to specify the jump step of the slider
    min = 0, -- Number (type of 'slider' only). The minimum value of the slider
    max = 100, -- Number (type of 'slider' only). The maxmimum value of the slider

    -- Default
    minItem = -1, -- Number
    maxItem = 100, -- Number
    minText = 0, -- Number
    maxText = 100, -- Number
    item = -1, -- Number, used for default values
    text = 0, -- Number, used for default values
    labelItem = 'Item', -- String
    labelText = 'Texture', -- String
    disableTexture = false,
    disableTextureChange = false, -- Boolean, used to disable the texture being automatically reset to 0 when the item updates

    -- Grid Slider
    minX = 0, -- Number
    maxX = 0, -- Number
    minY = 0, -- Number
    maxY = 0, -- Number
    valX = 0, -- Number, used for default values
    valY = 0, -- Number, used for default values
    labelXPos = '', -- String
    labelXNeg = '', -- String
    labelYPos = '', -- String
    labelYNeg = '', -- String
}
```

{% endtab %}

{% tab title="Control Array" %}
Controls must be formatted into rows. This allows you to add multiple rows to a list of controls. I.e.

```lua
{ -- Control rows array
    { -- Controls array
        { -- Control Object
            name = '', -- String, required
            icon = '', -- String, required
            tooltip = '', -- String, tooltip/label when button is hovered
            allowHold = false, -- Boolean, repeat button press whilst holding
            holdInterval = 200, -- Number, interval in milliseconds when holding button. Defaults to 200
        }
    }
}
```

{% endtab %}
{% endtabs %}

<details>

<summary>Example</summary>

```lua
TMC.Functions.StartSideMenuUi('test', { -- Categories
    {
        name = 'testCat1',
        label = 'Test Cat 1',
        icon = 'fad fa-home',
        searchable = true,
    },{
        name = 'testCat2',
        label = 'Test Cat 2',
        icon = 'fad fa-shield-halved',
    }
}, { -- Elements
    {
        type = 'slider',
        name = 'slider',
        label = 'Slider Field',
        cat = 'testCat1',
        value = 50
    },{
        type = 'grid-slider',
        name = 'gridslider',
        label = 'Grid Slider Field',
        cat = 'testCat1'
    },{
        type = 'select',
        name = 'select',
        label = 'Select Field',
        cat = 'testCat1',
        multiselect = true,
        options = {
            {
                value = 1,
                label = 'Test Select Value 1'
            },
            {
                value = 2,
                label = 'Test Select Value 2'
            }
		}
    },{
        type = 'linebreak',
        name = 'linebreak',
        label = 'Line Break Field',
        cat = 'testCat1'
    },{
        type = 'subtitle',
        name = 'subtitle',
        label = 'Subtitle Field',
        cat = 'testCat1'
    },{
        type = 'default',
        name = 'default',
        label = 'Default Field',
        cat = 'testCat1'
    },{
        type = 'checkbox',
        name = 'checkbox',
        label = 'Checkbox Field',
        value = true,
        cat = 'testCat1'
    },{
        type = 'toggle',
        name = 'toggle',
        label = 'Toggle Field',
        value = true,
        cat = 'testCat2'
    },{
        type = 'button',
        name = 'button',
        label = 'Button Field',
        cat = 'testCat2'
    },{
        type = 'colour-picker',
        name = 'colour-picker',
        label = 'Colour Picker Field',
        cat = 'testCat2',
        value = '#0000ff'
    },{
        type = 'select',
        name = 'colour-swatch',
        label = 'Colour Swatch Field',
        colourSwatch = true,
        cat = 'testCat2',
        options = {
            {
                colour = 'red',
                value = 'red',
                label = 'Red'
            },
            {
                colour = 'blue',
                value = 'blue',
                label = 'Blue'
            },
            {
                colour = 'green',
                value = 'green',
                label = 'Green'
            }
        }
    },{
        type = 'preview-select',
        name = 'preview-select',
        label = 'Preview Select Field',
        cat = 'testCat2',
        multiselect = true,
        options = {
            {
                value = 1,
                label = 'Test Select Value 1'
            },
            {
                value = 2,
                label = 'Test Select Value 2'
            }
        }
    },{
        type = 'text',
        name = 'text',
        label = 'Text Field',
        cat = 'testCat2'
    },{
        type = 'text',
        name = 'text2',
        label = 'Text Field 2',
        multiline = true,
        cat = 'testCat2'
    }
},{ -- Controls
    {
        {
            name = 'control1Row1',
            icon = 'fad fa-arrow-left',
            tooltip = 'An arrow pointing left'
        },{
            name = 'control2Row1',
            icon = 'fad fa-arrow-right',
            tooltip = 'An arrow pointing right'
        }
    },
    {
        {
            name = 'control1Row2',
            icon = 'fad fa-arrow-up',
            tooltip = 'An arrow pointing up'
        },{
            name = 'control2Row2',
            icon = 'fad fa-arrow-down',
            tooltip = 'An arrow pointing down'
        }
    }
}, false, false, 'test')
```

</details>

### StopSideMenuUi

Close any open side menu

```lua
TMC.Functions.StopSideMenuUi()
```

### RegisterUiHandler

In order to receive event updates for the side menu you can register UI handlers. These handlers will be triggered when the side menu changes them.

When registering a handler you will need to prepend your `menuRef` to the handler.

I.e. to register a handler for a control click with a menu type of `clothing` you would do:

```lua
TMC.Functions.RegisterUiHandler('clothingControlSideMenu', function(data, cb)
end)
```

Available events for side menu:

{% tabs %}
{% tab title="ControlSideMenu" %}
Triggered when a control is pressed. Will be triggered multiple times in rapid succession if `allowHold` is set to true.

```lua
TMC.Functions.RegisterUiHandler('testControlSideMenu', function(data)
-- Data object
    {
        name: '' -- The name of the control that is being pressed
    }
end)
```

{% endtab %}

{% tab title="ChangeSideMenu" %}
Triggered whenever a value is changed within the side menu.

```lua
TMC.Functions.RegisterUiHandler('testChangeSideMenu', function(data)
-- Data object
    {
        name: '', -- The name of the element that changed.
        type: '', -- The type of the element that changed.
        val: '', -- The value of the changed element.
        valX: 0,  -- The X value of the changed element (`grid-slider`).
        valY: 0,  -- The Y value of the changed element (`grid-slider`).

        item: 0, -- The item value of the changed element (`default`).
        text: 0, -- The texture value of the changed element (`default`).
        changeType: '' -- This will show what was changed for a `default` element. I.e. `texture` or `item`.
    }
end)
```

{% endtab %}

{% tab title="TabChangeSideMenu" %}
Triggered when the side menu active tab changes.

```lua
TMC.Functions.RegisterUiHandler('testTabChangeSideMenu', function(data)
-- Data object
    {
        newCategory: '' -- The name of the tab that the user clicked
    }
end)
```

{% endtab %}

{% tab title="SelectSideMenu" %}
This event is only fired for the `preview-select` elements. It allows you to change things based on what the user is hovering over in order to "preview" it.

```lua
TMC.Functions.RegisterUiHandler('testSelectSideMenu', function(data)
-- Data object
    {
        name: '', -- The name of the element that was selected.
        type: '', -- The type of the element that was selected.
        val: '', -- The previewd value (or array of values).
        preview: true, -- Will always be true for `preview-select`.
    }
end)
```

{% endtab %}

{% tab title="CloseSideMenu" %}
Triggered when the side menu is closed via the `Cancel`, `Close` or `Confirmed` buttons.

```lua
TMC.Functions.RegisterUiHandler('testCloseSideMenu', function(data)
-- Data object
    {
        confirm: true -- if the confirm button was clicked
    }
end)
```

{% endtab %}

{% tab title="PreviewCloseSideMenu" %}
This will only be used if you make use of the `preview-select` element. It allows you to reset previews once the preview "finishes" to the data the user has selected.

```lua
TMC.Functions.RegisterUiHandler('testPreviewCloseSideMenu', function(data)
-- Data object
    {
        name: '', -- The name of the element has finished previewing.
        val: '', -- The final value (or values) that were selected.
    }
end)
```

{% endtab %}
{% endtabs %}

### CreateSideMenuElement

Can add an element to an open side menu. See [Side Menu Element Object](#element-object-1) for the element structure.

```lua
TMC.Functions.CreateSideMenuElement({
    name = 'additionalField',
    label = 'An additional field',
    type = 'text',
    cat = 'testCat1'
})
```

### UpdateSideMenuElement

Can handle any element data apart from type. See [Side Menu Element Object](#element-object-1) for the element structure. Only name is required and it will only update the fields that are provided.

```lua
TMC.Functions.UpdateSideMenuElement({
    name = 'slider',
    label = 'Updated Slider Label'
})
```

### DeleteSideMenuElement

Remove an element from the side menu. Requires only the name of the element.

```lua
TMC.Functions.DeleteSideMenuElement('text2')
```

### UpdateSideMenuCategory

Can handle any category data. See [Side Menu Category Object](#category-object) for the category structure. Only name is required and it will only update the fields that are provided.

```lua
TMC.Functions.UpdateSideMenuElement({
    name = 'testCat2',
    disabled = true
})
```

### SetSideMenuTab

Update the current visible tab. Force the user to switch onto another tab. Requires the category name.

```lua
TMC.Functions.SetSideMenuTab('testCat2')
```
