---
title: "Settings"
description: "Every control a module panel can hold, the menu item API behind it, nested menus and color pickers."
---

> Documentation Index
> Fetch the complete documentation index at: https://aesthetic-docs.pages.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Settings

Each declarator adds one row to the module panel, top to bottom in declaration order, and
returns a menu item.

```lua
local flag   = module:switch("Flag", true)
local speed  = module:slider("Speed", 0.1, 10.0, 1.0, 0.1, "x")
local msg    = module:input("Message", "hello")
local key    = module:hotkey("Boost", "R")
local color  = module:color_picker("Color", 0xFF4FF2A6)
local mode   = module:combo("Mode", "A", "B", "C")
local who    = module:selectable("Targets", { "Players", "Mobs" }, { "Players" })
module:button("Reset", function() aesthetic.log("clicked") end)
module:label("Just a text line")
module:separator()
```

| Declarator | Notes |
|------------|-------|
| `switch(name[, default])` | On/off toggle |
| `slider(name, min, max[, default[, step[, unit]]])` | `default` falls back to `min`, `step` to `1`; `unit` is a label like `"ms"` |
| `combo(name, options...)` | Pick one. Varargs or a string table; the first option is the default |
| `selectable(name, options[, defaults[, allow_empty]])` | Multi-select. `defaults = nil` selects the first option; the value is a string array |
| `color_picker(name[, argb[, alpha]])` | `0xAARRGGBB`. `alpha = false` hides the alpha slider; a color list makes it [multi-color](#multi-color-pickers) |
| `input(name[, default])` | Text field |
| `hotkey(name[, default])` | Key bind. `default` is a key name or a table of names |
| `button(name, fn[, icon])` | `fn()` runs on click |
| `label(text)` | Plain text line |
| `separator()` | Horizontal rule |

## MenuItem

```lua
speed:get()                 -- current value
speed:set(5)                -- numbers clamp to [min, max]
speed:reset()               -- back to default
speed:type()                -- "slider", "switch", "combo", ...
speed:name()                -- GUI label; speed:name("Velocity") renames it live
speed:tooltip("Max speed")  -- hover text; speed:tooltip() reads it
speed:visibility(false)     -- hide the row; speed:visibility() reads it
speed:parent()              -- owning item from create(), or nil

mode:set("B")                     -- combo picks by option name
mode:list()                       -- { "A", "B", "C" } on combo and selectable
mode:update("A", "B", "C", "D")   -- swap options, keeping the selection when possible
```

Colors come back as unsigned numbers, so comparing against `0xAARRGGBB` literals works.

## Callbacks

```lua
local function on_speed(item)
aesthetic.log("speed = " .. item:get())
end

speed:set_callback(on_speed)        -- on every change
speed:set_callback(on_speed, true)  -- same, plus one call right now
speed:unset_callback(on_speed)      -- detach by the same function reference
```

One item can carry several callbacks, each receiving the item. Setting the same value again
does not fire them, which also bounds recursion when a callback calls `item:set()` on itself.
An error inside one disables the module.

## Key binds

```lua
local boost = module:hotkey("Boost", "R")   -- or { "LCtrl", "R" }

module:event("tick", function()
if boost:pressed() then
    -- held right now, always false while a screen is open
end
end)

boost:get()                  -- { "R" }
boost:set({ "LCtrl", "R" })
```

Key names match the GUI labels: `"R"`, `"Space"`, `"LShift"`, `"LCtrl"`, `"LAlt"`, `"Enter"`,
`"Tab"`, `"F1"`–`"F25"`, and mouse `"MMB"`, `"M4"`, `"M5"`.

Binds are editable in the panel, and right-clicking any row opens the hotkey menu. The GUI
caps a combo at 3 keys; `:set(...)` and a `hotkey` default are not capped.

## Nested menus

`item:create()` puts a gear button on the row and returns a menu with the same declarators.
Nesting is unlimited, and nested settings persist under `"Parent.Child"`.

```lua
local esp = module:switch("ESP", true)
local esp_menu = esp:create()
local thickness = esp_menu:slider("Thickness", 1, 5, 2)
local glow = esp_menu:switch("Glow", false)
glow:create():slider("Radius", 1, 10, 4)
```

## Color pickers

`item:color_picker([argb[, alpha]])` attaches a swatch to an existing row and returns it as
its own item (stored as `"<item>.Color"`):

```lua
esp:color_picker(0xFF4FF2A6)
```

### Multi-color pickers

Pass a list of named colors and the popup gets one tab per name. Each entry is
`{ name = color }`, stored under `"<picker>.<name>"`.

```lua
local esp = module:color_picker("ESP", {
{ Visible  = 0xFF4FF2A6 },
{ Occluded = 0xFFFF5050 },
})

esp:get()                       -- { Visible = ..., Occluded = ... }
esp:get("Visible")              -- one color by name
esp:set("Occluded", 0xFFFFFFFF)
esp:set({ Visible = 0xFF00FF00 })
esp:colors()                    -- { "Visible", "Occluded" }
esp:color("Visible"):set(0xFF000000)
```

A name may map to a list of colors (`{ Trail = { 0xFFFF0000, 0xFF0000FF } }`) for a
multi-stop swatch. Extra stops are named `"Trail 2"`, `"Trail 3"`, and so on.

Source: https://aesthetic-docs.pages.dev/settings/index.md
