Button

Runs a function when pressed. Start with two lines; add styles and animations only if you want them.

The smallest button#

Two options. That is all you need:

Luau
main:Button({
    Text = "Rejoin server",
    Callback = function()
        game:GetService("TeleportService"):Teleport(game.PlaceId)
    end,
})

Text is the label on the left. Callback runs when it is pressed. The button itself says Run, because that is the default.

Live preview

My Script

v1.0

Outlined

The house style, and the default.

Save configuration

Delete config

Building it up#

Add options one at a time, and only when you want what they do.

Name the action — replace the default Run:

Luau
main:Button({
    Text = "Rejoin server",
    ButtonText = "Rejoin",
    Callback = rejoin,
})

Explain it — a second, quieter line:

Luau
main:Button({
    Text = "Rejoin server",
    Description = "Leaves and rejoins the same place.",
    ButtonText = "Rejoin",
    Callback = rejoin,
})

Add an icon — shown inside the button, before its text:

Luau
main:Button({
    Text = "Rejoin server",
    ButtonText = "Rejoin",
    ButtonIcon = "refresh-cw",
    Callback = rejoin,
})

Mark it dangerous — anything destructive:

Luau
main:Button({
    Text = "Delete config",
    ButtonText = "Delete",
    Danger = true,
    Callback = deleteConfig,
})

That is 95% of the buttons you will ever write. Everything below is optional.

Styles#

Live preview

My Script

v1.0

Outlined

The house style, and the default.

Filled

Ghost

Soft

Danger

Luau
main:Button({ Text = "Outline", ButtonText = "Run" })                   -- default
main:Button({ Text = "Filled",  ButtonText = "Run", Style = "filled" })
main:Button({ Text = "Ghost",   ButtonText = "Run", Style = "ghost" })
main:Button({ Text = "Soft",    ButtonText = "Run", Style = "soft" })
main:Button({ Text = "Primary", ButtonText = "Go",  Primary = true })
StyleLooks likeUse it for
outlineA border, no fillThe default. Most buttons.
filledSolid accentThe single most important action on a page
ghostNo border or fill until hoveredLow-priority actions, dense lists
softTranslucent accent tintA middle weight between outline and filled

One primary per section

Primary works because it is rare. If three buttons on a page are all filled accent, none of them reads as the main action.

Hover and click animations#

Optional. Both Hover and Click take the same spec:

Luau
main:Button({
    Text = "Refresh data",
    ButtonText = "Refresh",
    ButtonIcon = "refresh-cw",
    Click = { Rotate = 360 },     -- the icon spins once on press
    Callback = refresh,
})
OptionTypeDefaultWhat it does
RotatenumberDegrees to spin the icon. 360 is the classic refresh spin; 90 reads as a state change.
ScalenumberMultiplier on the icon's size, e.g. 1.1 for a subtle grow.
IconstringSwap to a different icon for the duration.
TextstringSwap the button's text for the duration.
HoldnumberSeconds to keep the swapped icon or text before reverting.

A confirmation, with no extra state to manage:

Luau
main:Button({
    Text = "Save configuration",
    ButtonText = "Save",
    ButtonIcon = "save",
    Click = { Icon = "check", Text = "Saved", Hold = 1.4 },
    Callback = saveConfig,
})

The button shows a tick and Saved for 1.4 seconds, then goes back by itself.

Every option#

OptionTypeDefaultWhat it does
TextreqstringThe label on the left.
CallbackfunctionCalled on press. Takes no arguments.
ButtonTextstring"Run"The text inside the button.
ButtonIconstringAn icon inside the button, before its text. Works alongside ButtonText.
DescriptionstringA quieter second line under the label.
IconstringAn icon for the row itself, before the label.
Stylestring"outline"outline, filled, ghost or soft.
PrimarybooleanfalseShorthand for the filled accent style.
DangerbooleanfalsePaints it with the theme's danger colour.
HovertableAnimation spec played while hovered.
ClicktableAnimation spec played on press.
HoverColorColor3Overrides the hover tint.
HoverFillnumberHow strongly the hover state fills, 0 to 1.