> ## Documentation Index
> Fetch the complete documentation index at: https://gabibou-ui.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Controls

> Add buttons, toggles, sliders, and other controls to a window.

A **window** is the main panel for your menu. A **tab** is a page inside that panel. A **control** is an item the player can use, such as a button or slider. This page starts with a complete example, then shows the available controls.

| What the player needs to do | Control | Callback receives |
| - | - | - |
| Run an action | `Button` | Nothing |
| Turn a setting on or off | `Toggle` | `true` or `false` |
| Choose a number | `Slider` | Number |
| Choose one item | `Dropdown` | String |
| Enter text | `Input` | String, after confirming or leaving the field |
| Run an action with a key | `Keybind` | Key name when pressed |
| Choose a color | `ColorPicker` | Hex color string |
| Show text | `Paragraph` | Nothing |
| Group controls | `Section` | Nothing |
| Add custom Roblox UI | `Custom` | Nothing |

![Running rc.21 Gabibou UI demo with a button, one toggle off, one toggle on, and a slider](https://mintcdn.com/gabibou-ui/I5Uhr5uQ-CiiLlxQ/images/controls-examples.png?fit=max\&auto=format\&n=I5Uhr5uQ-CiiLlxQ\&q=85\&s=f3b4f6338b94091208dd7fa5c51030de)

*A live rc.21 example window; it shows a button, one toggle off, one toggle on, and a slider.*

## Complete example

Choose an installation method in [Installation](https://gabibou-ui.mintlify.site/getting-started/installation.md). Paste the complete block below into the same client script as your loader. For Roblox Studio, replace the first line with the two `require` lines shown in the installation steps; keep the remaining lines below them in the same `LocalScript`.

```lua theme={null}
local UI = loadstring(game:HttpGet('https://raw.githubusercontent.com/Gabibou455/GabibouUI/main/gabibou_ui.luau'))()
local window = UI:CreateWindow('My project')
local tab = window:Tab('Home', 'home')
local settings = tab:Section('Settings')

settings:Toggle('Shadows', function(enabled)
    print('Shadows:', enabled)
end)

settings:Button('Refresh', function()
    print('Refresh clicked')
end)
```

This creates a window called **My project**, a tab named **Home**, and a **Settings** heading containing a toggle and a button. Click the toggle to print `Shadows: true` or `Shadows: false`. Click the button to print `Refresh clicked`.

The function passed to a control is its **callback**. It runs when the player uses the control. A toggle callback receives the new on/off value (`true` or `false`); a button callback receives no value because it represents an action.

## Add one control to your example

Use these short examples to extend the complete example above. Put each new call after the `local settings = ...` line if you want the control under Settings. Put it after `local tab = ...` and use `tab:` if you want it directly on the Home page.

### Button: run an action

```lua theme={null}
settings:Button('Refresh', function()
    print('Refresh clicked')
end)
```

Runs its callback when clicked. The callback receives no arguments. Optional settings include `Text` for the button caption (default `Run`), `Description`, `Icon`, `IconVariant`, and `Variant`; the first string labels the control.

`Variant` sets the button's visual weight. `Primary` uses the accent color and is the default. `Secondary` uses a raised surface. `Subtle` uses a softer, quieter surface for supporting actions. Use one primary action when a section has a clear main action, then give supporting actions a lighter variant:

```lua theme={null}
settings:Button({
    Title = 'Save settings',
    Text = 'Save',
    Variant = 'Primary',
    Callback = function()
        print('Settings saved')
    end,
})

settings:Button({
    Title = 'Restore defaults',
    Text = 'Restore defaults',
    Variant = 'Subtle',
    Callback = function()
        print('Defaults restored')
    end,
})
```

The accepted values are `Primary`, `Secondary`, and `Subtle`. If you omit `Variant`, the button uses `Primary`.

On rc.21, custom button labels are shortened with an ending ellipsis when they exceed the available button width, whether or not the button has an icon. The configured `Text` string and callback stay unchanged.

### Toggle: turn a setting on or off

```lua theme={null}
local shadows = settings:Toggle('Shadows', {Value = false}, function(enabled)
    print('Shadows:', enabled)
end)
```

`Value` sets the starting state and defaults to `false`. The callback receives a boolean: `true` when on, `false` when off. The callback runs after the player changes the toggle, not when it is created.

To read or change the value later, add these lines below the toggle:

```lua theme={null}
print(shadows:Get())
shadows:Set(true) -- changes the value without calling the callback
shadows:Set(false, true) -- changes the value and calls the callback if it changed
```

### Slider: choose a number

Add this after the toggle example:

```lua theme={null}
local volume = settings:Slider('Music volume', {
    Min = 0,
    Max = 100,
    Step = 1,
    Value = 50,
}, function(value)
    print('Volume:', value)
end)
```

The callback receives the selected number. `Min` and `Max` set the range, `Step` sets the allowed increments, and `Value` sets the starting number. They default to `0`, `100`, `1`, and `Min` respectively. Values stay within the range and round to steps counted from `Min`; for example, `Min = 10` and `Step = 4` allow 10, 14, 18, and so on. Save the returned control if you want to read or change it later: `volume:Get()` reads the current number, and `volume:Set(75, true)` sets it and calls the callback if it changed.

### Dropdown: choose one item from a list

```lua theme={null}
local quality = settings:Dropdown('Quality', {
    Options = {'Low', 'Medium', 'High'},
    Value = 'Medium',
}, function(choice)
    print('Quality:', choice)
end)
```

The callback receives the selected string. `Options` must contain at least one unique, nonempty string. `Value` must match an option; if omitted, the first option is selected. Use `quality:Get()` to read the current selection and `quality:Set('High', true)` to change it and call the callback if it changed. Use `quality:SetOptions({'Low', 'High'})` to replace the choices; if the current choice is missing from the new list, the first new choice is selected.

### Input: enter text

```lua theme={null}
local playerName = settings:Input('Player name', {
    Value = '',
    Placeholder = 'Enter a name',
    MaxLength = 24,
}, function(text)
    print('Player name:', text)
end)
```

The callback receives the changed text when the player confirms it or leaves the text box. `Value` defaults to an empty string, `Placeholder` to `Type here...`, and `MaxLength` to `120`. The maximum length must be from `1` to `4096`; longer text is trimmed to that limit.

![Live rc.21 settings window showing a Quality dropdown and Player name input](https://mintcdn.com/gabibou-ui/I5Uhr5uQ-CiiLlxQ/images/controls-input.png?fit=max\&auto=format\&n=I5Uhr5uQ-CiiLlxQ\&q=85\&s=99c67062d1c547c8eb6568c41ff289cb)

*A live rc.21 screenshot of a dropdown and text input in the Settings panel.*

### Keybind: run an action when a key is pressed

```lua theme={null}
local actionKey = settings:Keybind('Action key', {Value = Enum.KeyCode.K}, function(keyName)
    print('Pressed:', keyName)
end)
```

Click the key control and press a key to assign it. The callback runs when that key is pressed outside key capture, and receives its name as a string such as `K`. `Value` accepts an `Enum.KeyCode` or its name as a string and defaults to `F6`.

### Color picker: choose a color

```lua theme={null}
local accent = settings:ColorPicker('Accent color', {
    Value = '#78B8FF',
    Palette = {'#78B8FF', '#A18FFF', '#F08B8B'},
}, function(hex)
    print('Accent:', hex)
end)
```

The callback receives a `#RRGGBB` string. `Value` accepts that format or a Roblox `Color3` value and defaults to `#F2F4F8`. A custom `Palette` must contain 1 to 32 hex strings or `Color3` values. Save the returned control to use `accent:Get()` for its hex value, `accent:GetColor()` for its `Color3` value, or `accent:Set('#A18FFF', true)` to change the color and call the callback if it changed.

### Paragraph: display text

```lua theme={null}
settings:Paragraph('Connection status', {Description = 'Connected to the server.'})
```

Displays a title and description. It has no value or callback.

### Section: group related controls

```lua theme={null}
local audio = tab:Section('Audio')
audio:Toggle('Music', function(enabled)
    print('Music:', enabled)
end)
```

Pass a title string or `{Title = 'Audio'}`. `Section` returns an object that accepts controls just like a tab.

### Custom: place your own Roblox UI inside a control

```lua theme={null}
tab:Custom({
    Title = 'Preview',
    Height = 48,
    Build = function(content, control, window, options)
        local label = Instance.new('TextLabel')
        label.BackgroundTransparency = 1
        label.Size = UDim2.fromScale(1, 1)
        label.Text = 'Preview is ready'
        label.TextColor3 = window.Theme.Text
        label.Parent = content
    end,
})
```

`Build` receives the content area, control, window, and options. Parent Roblox UI instances to `content` to show them inside the control. `Height` is the content area's height in pixels; it defaults to `80` and accepts `0` to `2000`. `Build` is optional. Custom controls have no stored value or built-in callback.

## Value controls and options

`Toggle`, `Slider`, `Dropdown`, `Input`, `Keybind`, and `ColorPicker` return a control object. Save it in a variable, such as `local volume = settings:Slider(...)`, when you want to use `Get()` or `Set()` later.

* `Get()` reads the current value.
* `Set(value)` changes it without running the callback.
* `Set(value, true)` changes it and runs the callback if the value changed.
* User changes run the callback automatically, except assigning a key during key capture.

For value controls, pass the label, an optional settings table, then the callback. For example: `settings:Slider('Volume', {Min = 0, Max = 100}, callback)`. If you do not need settings, pass the callback second: `settings:Toggle('Music', callback)`. The older table form remains available: `settings:Toggle({Title = 'Music', Value = false, Callback = callback})`.

Settings can include `Description`, `Id`, `Disabled`, and `Layout`; `Desc` is an alias for `Description`. Direct controls get an ID automatically. Declarative controls require `Id`. Give each window a distinct `Id` when showing multiple windows at once. Set `Persistent = false` to exclude a value from configuration snapshots.

For saving and restoring values, see [Values and configuration](https://gabibou-ui.mintlify.site/customization/values-and-config.md). For custom components and animation, see [Animations and custom components](https://gabibou-ui.mintlify.site/customization/animations-and-components.md).

Next: [Values and configuration](https://gabibou-ui.mintlify.site/customization/values-and-config.md) · [Events and lifecycle](https://gabibou-ui.mintlify.site/customization/events-and-lifecycle.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.