Item types
Every row has the common fields (id, label, sublabel, description, icon, tint, permissions, callbacks…). The table lists the extra fields per type and the value your onChange receives.

| Type | Extra fields | onChange(value) / onSelect value | Notes |
|---|---|---|---|
button | rightLabel (string), key (string, key cap like 'F2') | – | Enter runs onSelect |
action | variant ('confirm' | 'danger' | 'warning'), hold (ms), confirm (true | table) | – | hold = hold Enter to confirm; confirm asks a dialog first |
info | value (string) | – | Read-only. Not selectable with Enter |
number | value, min, max, step, bigStep (numbers), unit (string), format (fn) | number | Stepper. Left / right changes by step, Shift by bigStep |
list | options (array of strings / numbers or { label, value }), index (1-based), wrap (bool, default true), format | number (index, 1-based) | Position dots under the value. Read item.options[index] for the value |
slider | value, min, max, step, bigStep, unit, format | number | Same keys as number, plus mouse wheel |
color | value ('#RRGGBB'), palette (array of hex strings) | string ('#rrggbb', lowercase) | Opens a picker with the palette and a hex field |
input | value, inputType ('text' | 'number' | 'password' | 'money'), placeholder, maxLength, min, max, unit | string, or number for number / money | Enter edits inline (takes focus in walk mode). money is floored to whole numbers |
keybind | value (key name, e.g. 'F2') | string (FiveM key name) | Enter starts a "press a key" capture |
checkbox | checked (bool) | boolean | Multi-select |
radio | group (string), checked (bool) | true | Only the newly checked row fires. Lua unchecks the rest of the group in the same menu |
switch | checked (bool) | boolean | |
submenu | menu (menu id) or build (fn), count (number) | – | build(childId, item, parent) returns items or a definition. See Submenus |
link | – | – | Opens another UI. Shows an external icon and closes the menu after onSelect (unless close = false) |
section | label | – | Small capitals heading. Not selectable |
separator | – | – | Divider line. Not selectable |
Value rules
numberandslidervalues are clamped tomin/maxon the Lua side.listindexes outside the options are rejected and the row snaps back.format(value, item, menu)runs in Lua and its result is sent as the display text. The web keeps the old text until the new one arrives.- The current value is written back into the item (
value,indexorchecked), sogetItemand a reopened menu show it. inputtext is capped atmaxLength(max 4096). Colours accept#rgb,#rrggbbandrrggbb.
Row states
| Field | Type | Effect |
|---|---|---|
disabled | boolean | Greyed out, Enter plays the error sound |
disabledReason | string | Shown on a disabled row (also filled by showLocked) |
loading | boolean | Spinner. The row can't be used |
badge | number | string | true | Count, short label (≤ 16 chars) or a dot |
cooldown | number (ms) | { remaining, total } | Countdown bar. Using the row shows a "Not ready yet" toast |
pinned | computed | Set by np_menu when the player pinned the row (hold Y). Pinned rows of a grid menu appear in its dock |
visible | boolean | fn(item, menu) | false hides the row |
Text limits
The serializer trims text before it goes to the web: label / sublabel 160, description 1024, rightLabel 80, placeholder 120, unit 16, key 24 characters. Icons must be plain Font Awesome names ('car-side'); fa-solid prefixes are stripped.