Icons
All 1,573 Lucide icons are built in. Finding one, and adding your own.
Anywhere Ember takes an Icon, it takes a name: a plain string.
local main = win:Section("Main", "home")
main:Toggle({ Text = "God mode", Icon = "shield" })
main:Button({ Text = "Refresh", ButtonIcon = "refresh-cw" })If Ember does not know the name, nothing is drawn. The control still renders
without a glyph, nothing errors, and Ember warns
[Ember] unknown icon "<name>" to the console.
Where they come from#
The icons are Lucide, an open-source set. All 1,573 of them are baked into the library as sprites, so they load with it.
Names match lucide.dev exactly
If you find an icon on lucide.dev called
sliders-horizontal, that is the exact string Ember expects. Browse there,
then check it is in the list below.
Find one#
Type to filter. Click any icon to copy its name.
Checking at runtime#
Two helpers, useful when the name comes from somewhere you do not control:
Ember.HasIcon("shield") --> true
Ember.HasIcon("not-an-icon") --> false
local names = Ember.Icons() -- every registered name, sorted
print(#names) --> 1573Using an image directly#
Icon also takes an asset id, with no registration step:
main:Toggle({ Text = "Custom", Icon = "rbxassetid://1234567890" })
main:Toggle({ Text = "Custom", Icon = 1234567890 }) -- or the bare number
main:Toggle({ Text = "Avatar", Icon = "rbxthumb://type=AvatarHeadShot&id=1&w=48&h=48" })A table is a sprite descriptor: { assetId, rectX, rectY, cell }, the last
three optional. cell may be a number or a Vector2 for non-square cells.
main:Toggle({ Text = "Sword", Icon = { 1234567890, 96, 48, 48 } })Register a name instead once you use the same image in more than one place.
Adding your own#
RegisterIcon takes a name and a Roblox asset ID. Once registered, the name
works anywhere a built-in name does:
Ember.RegisterIcon("mylogo", "rbxassetid://1234567890")
main:Toggle({ Text = "Custom", Icon = "mylogo" })If your image is a sprite sheet, pass the offset and cell size as well:
-- name, assetId, rectX, rectY, cell
Ember.RegisterIcon("swordIcon", "rbxassetid://1234567890", 96, 48, 48)| Option | Type | Default | What it does |
|---|---|---|---|
namereq | string | — | What you will pass as Icon. Any non-empty string. |
assetIdreq | string | number | — | A rbxassetid:// or rbxthumb:// string, or a bare asset id number. |
rectX | number | 0 | X offset into a sprite sheet. |
rectY | number | 0 | Y offset into a sprite sheet. |
cell | number | Vector2 | — | Size of one cell in the sheet. |
RegisterIcons adds several at once. Each value is a sprite descriptor table,
the same { assetId, rectX, rectY, cell } shape as above. The call is
all-or-nothing: if any entry is malformed, none are added.
local ok, err = Ember.RegisterIcons({
mylogo = { "rbxassetid://1234567890" },
myBadge = { "rbxassetid://1234567891", 96, 48, 48 },
})
if not ok then
warn("icon set rejected:", err)
endNeither function throws. RegisterIcon returns the name on success,
RegisterIcons returns true, and both return false, reason on failure.
Where icons show up#
| Place | Option | Notes |
|---|---|---|
| Section tab | second argument to win:Section | win:Section("Main", "home") |
| Any control | Icon | Before the label |
| Button | ButtonIcon | Inside the button, alongside its text |
| Group header | Icon | Before the group's name |
| Notification | Icon | In the toast |
| Status bar item | Icon | win.StatusBar:Item("fps", { Text = "60", Icon = "gauge" }) |
Colour and size are adjustable per control with IconColor and IconSize:
main:Toggle({
Text = "Danger zone",
Icon = "triangle-alert",
IconColor = Color3.fromRGB(232, 93, 93),
IconSize = 18,
})Left alone, an icon is drawn in the theme's muted colour at 16 pixels on a
control row and 13 on a group header.
ButtonIcon is the exception
A button's ButtonIcon ignores IconColor and IconSize. It is drawn at 14
pixels in the colour of the button style it sits in, so a filled button's icon
is always accentInk and a Danger button's is the danger colour. The row's
own Icon honours both options normally.