Controls overview
All thirteen controls, the options every one shares, and how handles work.
Every control is a method on a section. It takes one options table and returns a handle.
local handle = section:Toggle({ Text = "Enabled", Callback = print })The thirteen#
Runs a function. Four visual styles, hover and click animations.
ToggleOn or off. Two options to write one.
SliderA number in a range, with steps and a unit suffix.
InputA text field, committing on Enter or when it loses focus.
DropdownPick one, or many, with three selection styles.
KeybindCaptures a key and calls you when it is pressed.
ColorPickerA full HSV picker in a dropdown.
PaletteA fixed row of colour swatches.
IconButtonA row of small square buttons.
StatusRead-only text you update from code.
TitleA heading inside a section.
DescriptionA paragraph of explanatory text.
SeparatorA dividing line.
Options every control shares#
Anything a control adds on top is documented on its own page.
These build the row itself:
| Option | Type | Default | What it does |
|---|---|---|---|
Text | string | — | The label. Non-strings are coerced, so a number is safe. |
Description | string | — | A second, quieter line beneath the label. |
Icon | string | — | One of the 1,573 built-in icon names. |
IconColor | Color3 | — | Overrides the icon colour for this control only. |
IconSize | number | 16 | Icon size in pixels. |
LayoutOrder | number | — | Explicit ordering. Without it, controls appear in creation order. |
Flat | boolean | false | Drops the card background and its border. Set for you on controls inside a Group. |
HoverCard | boolean | true | The row lifts under the pointer. Never applies to a flat card. |
These are read after the control is built, so they work the same on a control you registered yourself:
| Option | Type | Default | What it does |
|---|---|---|---|
Callback | function | — | Runs when the value changes. On Button it runs on click, and on Keybind when the bound key is pressed. |
Save | string | boolean | — | Persists the value. true derives a key from the section and label; a string sets the key yourself. |
FireOnStart | boolean | false | Calls Callback once at creation with whatever the control holds. |
Reapply | boolean | — | Re-applies the value when the character is replaced. Set false to opt out when the window sets ReapplyOnRespawn. |
RevertOnClose | boolean | — | Applies an off value when the window closes: false for a toggle, otherwise Default. |
RevertTo | any | — | The value RevertOnClose sends instead. |
Apply | function(value) | — | What Reapply and RevertOnClose run instead of Callback. Needed on Button, Keybind and IconButton, whose Callback is an action rather than a value. |
Tooltip | string | — | Shown while the pointer is over the row. |
Disabled | boolean | false | Refuses input and dims the control. |
DisabledReason | string | — | Shown as a tooltip while it is disabled. |
Save, Reapply and RevertOnClose are covered in
Saving settings and
Lifecycle.
Title, Description and Separator return a Roblox instance instead of a
handle, so nothing in the second table reaches them. Their options are on
Title, Description & Separator.
Handles#
Stateful controls return a handle with Get and Set:
local speed = main:Slider({ Text = "Speed", Min = 0, Max = 100, Default = 50 })
speed:Get() --> 50
speed:Set(80) --> updates the UI and fires CallbackSet returns true, or false and a reason when the value is refused:
local ok, why = dropdown:Set("Nowhere") --> false, "value is not present in Options"Pass true as a second argument to set the value without firing anything. A
panic button can put every control back that way without re-running the work.
Set usually fires the callback
On Toggle, Slider, Input, Dropdown, ColorPicker, Palette and
Status, Set behaves as though the user moved the control, so calling it
inside that control's own Callback loops forever. Keybind:Set is the
exception: it fires Changed, not Callback.
Every handle carries these:
| Method | What it does |
|---|---|
Show() / Hide() / SetVisible(bool) | Shows or hides the whole control |
Destroy() | Removes it from the page and disconnects its events |
handle.Instance is the card frame, for when you need the Roblox instance.
Some controls add more. A dropdown, for example:
| Method | What it does |
|---|---|
Get() | The current value: a string, or an array when Multi |
Set(value) | Selects a value or list of values |
SetOptions(list) | Replaces the option list in place |
Open() / Close() / IsOpen() | Controls the menu |
Callbacks#
Callback fires whenever the value changes, with the new value as its first
argument:
main:Toggle({
Text = "Godmode",
Callback = function(enabled) -- boolean
print("godmode:", enabled)
end,
})
main:Slider({
Text = "FOV", Min = 70, Max = 120,
Callback = function(value) -- number
workspace.CurrentCamera.FieldOfView = value
end,
})
main:Dropdown({
Text = "Target", Options = { "Nearest", "Lowest HP" },
Callback = function(choice) -- string
targetMode = choice
end,
})A callback does not fire when a control is created. One exception: a
Saved control that restored a value calls it once with that value. See
Saving settings.
FireOnStart covers the other case: fire once at creation even when nothing was
saved, so a control that starts non-default applies itself.
A toggle can name the two halves separately with OnEnabled and OnDisabled.
See Toggle.
Turning a control off#
My Script
v1.0
Developer mode
Unlocks the action below.
Start the farm
Runs until you stop it.
Every control takes Disabled, and every handle has the methods to change it
later. A disabled control refuses input and looks like it is refusing.
local start = main:Button({
Text = "Start the farm",
ButtonText = "Go",
Disabled = true,
DisabledReason = "Pick a target first",
Callback = beginFarm,
})
targetPicker:Set("Nearest")
start:Enable()| Method | What it does |
|---|---|
SetDisabled(state, reason?) | Turns it off or on. The reason is optional and sticks. |
Disable(reason?) / Enable() | The same thing, named |
IsDisabled() | Whether it is currently off |
DisabledReason is shown as a tooltip while the control is disabled, so a dead
button can say what would bring it back.
It refuses input rather than trusting the callback
There is no overlay. Every button inside the control stops accepting input and every coloured part is faded toward its background, so this works on a control you registered yourself. Guarding inside your callback still lets the control animate as though it did something.
Explaining a control#
Any control takes Tooltip, shown while the pointer is over it.
main:Slider({
Text = "Tick rate",
Min = 1, Max = 60, Default = 30,
Tooltip = "How often the farm re-scans. Lower is cheaper.",
})SetTooltip(text) changes it later, and SetTooltip(nil) removes it.
DisabledReason takes priority while the control is disabled.
Organising a long section#
Title, Description and Separator break a section into runs. See
Title, Description & Separator.
Group puts rows in a container that collapses. See
Groups and search.
Adding your own#
RegisterControl installs a builder as a section method, so your control is
called like any built-in one and gets the same card, search indexing, Reapply
and handle methods:
Ember.RegisterControl("Badge", function(section, opts)
local card, slot = Ember.Controls.mount(section, opts)
local value = Ember.Util.label(opts.Value or "", 13, Ember.Theme.accent)
value.Size = UDim2.new(0, 0, 0, 22)
value.AutomaticSize = Enum.AutomaticSize.XY
value.Parent = slot
return {
Instance = card,
Set = function(_, text) value.Text = tostring(text) end,
}
end)
main:Badge({ Text = "Build", Value = Ember.Version })Return a table with an Instance and Ember adds Show, Hide, SetVisible,
Destroy, SetTooltip, SetDisabled, Disable, Enable and IsDisabled
to it.
| Call | What it does |
|---|---|
Ember.RegisterControl(name, build) | Installs it. Returns false, reason for a bad name, or one already taken. |
Ember.UnregisterControl(name) | Removes one of yours. Built-ins cannot be removed. |
Ember.HasControl(name) | Whether that name exists |
Ember.ControlNames() | Every control name, sorted |
See them running#
Every control page carries a live preview of the real control, and the swatches above each one repaint it into any of the nine built-in themes. For all of them working together in one window, see the docs landing page or the full showcase.