Menu Structure & Examples

The Quasar Radial Menu is based on a tree-style structure, where each menu can contain items and categories, and categories can contain other categories infinitely.

The entire structure is defined in config.lua using plain Lua tables and functions.


Basic Structure Overview

Every radial menu follows this base structure:

Config.Menu = {
    title = "Main Menu",
    items = {
        -- Items and categories go here
    }
}
  • title: Text displayed at the top of the radial menu

  • items: List of menu entries (items or categories)


Item Types

There are two possible types:

There are two possible types:

1️⃣ Item (Action)

An item executes an action when clicked.

Required fields:

  • label – Text shown in the menu

  • icon – Lucide icon name

  • type = "item"

  • action – Lua function executed on click


2️⃣ Category (Submenu)

A category opens a new submenu and can contain more items or categories.

Required fields:

  • label

  • icon

  • type = "category"

  • items – List of nested items or categories


Simple Example


Infinite Nested Categories

There is no depth limit. Categories can be nested as deeply as needed.


Job Restricted Items

Items and categories can be restricted by job.

  • jobGrade is optional

  • Uses minimum grade logic (>=)


Multiple Job Support

You can allow multiple jobs with different grades:

The item will appear if any job condition is met (OR logic).


Gang Restricted Items


CanInteract examples

The canInteract function lets you control the visibility of items or categories using real-time conditions. It must return true to show the item, or false to hide it.

Use it when visibility depends on player state, position, or context.


Examples


Dynamic Visibility with canInteract

The canInteract function allows real-time checks.

If canInteract returns false, the item or category is hidden.


Category Auto-Hiding

Categories are automatically hidden if:

  • All child items are filtered by job, gang, or canInteract

  • The category becomes empty after filtering

No extra configuration is needed.