Skip to main content

Menu

The Menu module opens a keyboard navigated list menu in the style of a classic NativeUI menu. It supports a highlighted row, side scroll values, checkboxes and progress bars.

The player keeps full control

A menu deliberately does not take NUI focus. The arrow keys are read through the game controls, and only those navigation controls are disabled while the menu is open. Everything else keeps working, so the player can walk, drive and do anything else with the menu on screen. If you need mouse interaction instead, use the Context Menu.

Naming

The namespaced form MSK.Menu.* is the recommended one. The flat names MSK.RegisterMenu, MSK.ShowMenu, MSK.UpdateMenu, MSK.HideMenu and MSK.GetOpenMenu point at the exact same functions and stay supported. MSK.Menu.Close is an alias of MSK.Menu.Hide.

The exports are always flat: exports.msk_core:RegisterMenu(...).

The whole menu state (selected row, current values, checkbox states) lives in Lua. The NUI is only a render layer, which means your callbacks always receive the authoritative state.

MSK.Menu.Register

Registers (or overwrites) a menu under an id.

Parameters
id - string - Unique id of the menu
data - table - The menu definition

FieldTypeDescription
titlestringHeader text
positionstringtop-left (default), center, left, right, top, bottom, top-right, bottom-left, bottom-right
canClosebooleanfalse prevents closing with the back key. Default true
disableInputbooleantrue freezes the navigation completely
startIndexnumberRow that is selected when the menu opens. Default 1
onSelectedfunction(selected, item, args) - fires whenever the highlight moves
onSideScrollfunction(selected, index, args) - fires when a value is scrolled left/right
onCheckfunction(selected, checked, args) - fires when a checkbox is toggled
onClosefunction(key) - fires when the menu closes. key is select, cancel, replace or forced
itemstableArray of items (see below)

Item fields

FieldTypeDescription
idstringStable id of the item. Required if you want to use MSK.Menu.Update on it
labelstringLabel. Supports FiveM color codes such as ~g~
descriptionstringSmaller text below the label
iconstringFontAwesome icon. Short name (car) or full class (fas fa-car)
iconColorstringOverrides the icon color
valuestableTurns the row into a side scroll selector. Array of strings, or of { label = '...', description = '...' }
defaultIndexnumberPreselected entry of values. Default 1
checkedbooleanTurns the row into a checkbox. Enter toggles it and fires onCheck
progressnumber0 to 100. Renders a progress bar inside the row
colorSchemestringColor of the progress bar
closebooleanfalse keeps the menu open after selecting. Default true
onSelectfunctionCalled with args when the item is selected with Enter
eventstringClient event triggered with args on select
serverEventstringServer event triggered with args on select
argsanyPassed to onSelect, event, serverEvent and the menu callbacks
disabledbooleanGreyed out and skipped while navigating
MSK.Menu.Register('tuning_menu', {
title = 'Options',
position = 'top-left',
onSideScroll = function(selected, index, args)
print(('row %s switched to value %s'):format(selected, index))
end,
onCheck = function(selected, checked, args)
MSK.Notification('MSK', 'Neon: ' .. (checked and 'ON' or 'OFF'), 'info', 4000)
end,
onClose = function(key)
print('menu closed via ' .. key)
end,
items = {
{ id = 'engine', label = 'Engine', description = 'Condition', icon = 'gauge-high', progress = 82 },
{ id = 'color', label = 'Color', icon = 'palette', values = { 'Black', 'White', 'MSK Green' }, defaultIndex = 1 },
{ id = 'neon', label = 'Neon', icon = 'lightbulb', checked = false },
{ id = 'apply', label = 'Apply', icon = 'check', onSelect = function() print('applied') end },
{ id = 'locked', label = 'Disabled', icon = 'ban', disabled = true },
}
})

-- Backwards compatible alias:
MSK.RegisterMenu('tuning_menu', data)

-- As an Export:
exports.msk_core:RegisterMenu('tuning_menu', data)

MSK.Menu.Show

Opens a menu. Accepts either the id of a registered menu or an inline table, which is registered automatically. Opening a menu while another one is open closes the old one first (its onClose fires with replace).

Parameters
idOrData - string/table - Id of a registered menu, or an inline menu definition

MSK.Menu.Show('tuning_menu')

-- The module table itself is callable and forwards to Show:
MSK.Menu('tuning_menu')

-- Backwards compatible alias:
MSK.ShowMenu('tuning_menu')

-- As an Export:
exports.msk_core:ShowMenu('tuning_menu')

MSK.Menu.Update

Updates a single item of a registered menu. The item is addressed through its id and the given fields are merged into it. If exactly this menu is currently open, the UI is refreshed live.

Parameters
menuId - string - Id of the menu
dataId - string - Id of the item inside that menu
updatedData - table - The fields to merge into the item

MSK.Menu.Update('tuning_menu', 'engine', {
progress = 100,
description = 'Fully repaired',
})

-- Also works for checkbox and value state while the menu is open
MSK.Menu.Update('tuning_menu', 'neon', { checked = true })
MSK.Menu.Update('tuning_menu', 'color', { defaultIndex = 3 })

-- Backwards compatible alias:
MSK.UpdateMenu('tuning_menu', 'engine', { progress = 100 })

-- As an Export:
exports.msk_core:UpdateMenu('tuning_menu', 'engine', { progress = 100 })

MSK.Menu.Hide

Closes the currently open menu. MSK.Menu.Close is an alias of this function.

Parameters
key - string - (optional) Value handed to onClose. Default forced

MSK.Menu.Hide()

-- Alias:
MSK.Menu.Close()

-- Backwards compatible alias:
MSK.HideMenu()

-- As an Export:
exports.msk_core:HideMenu()

MSK.Menu.GetOpen

Returns the id of the currently open menu.

Returns
id - string/nil - Id of the open menu, or nil if none is open

local id = MSK.Menu.GetOpen()

-- Backwards compatible alias:
local id = MSK.GetOpenMenu()

-- As an Export:
local id = exports.msk_core:GetOpenMenu()

Controls

KeyAction
Arrow Up / DownMove the highlight (disabled rows are skipped)
Arrow Left / RightChange the value of a side scroll row
EnterSelect the row, or toggle its checkbox
BackspaceClose the menu (unless canClose = false)

All other controls stay untouched, so the player can keep moving and driving.