Button
A clickable button with icons, intents, scaling, and grouped children.
Button is a themed, clickable surface built on Roblox's native ImageButton. It automatically applies the current Clean UI theme, including background, border, corner radius, and hover styling based on intent.
Import
import { Button } from "@rbxts/react-clean-ui";Basic usage
The text prop renders a label, and icon renders a leading icon. Either can be used on its own.
<Button text="Save" />
<Button icon="save" />Responding to clicks
Button renders an ImageButton, so click handling is done through the native Event prop.
<Button
text="Submit"
intent="primary"
Event={{
Activated: () => {
print("Submitted");
},
}}
/>Intents
Set intent to control the button's background, border, and text/icon colors.
<Button text="Primary" intent="primary" />
<Button text="Secondary" intent="secondary" />
<Button text="Success" intent="success" />
<Button text="Info" intent="info" />
<Button text="Warning" intent="warning" />
<Button text="Danger" intent="danger" />Hovering a button switches its colors to the intent's hover state.
secondary is a lower-emphasis alternative to primary, such as a neutral grey button in the default theme. Every shipped theme styles it. A custom theme that doesn't define secondary still works: the button falls back to the primary colors.
Custom content
For layouts beyond an icon and a label, pass children instead of icon/text. Button.Icon and Button.Text are exposed so custom content can still pick up the button's intent and scale.
<Button intent="info">
<HStack valign="Center" spacing="sm">
<Button.Icon icon="download" intent="info" />
<Button.Text text="Download report" intent="info" />
</HStack>
</Button>When both icon/text and children are provided, the automatic icon/label row renders first, followed by children.
Scaling
Button supports the shared scale prop, which resolves the button's typography and icon size from the active theme.
<Button text="Small" scale="sm" />
<Button text="Large" scale="lg" />Available scales are xs, sm, md, lg, and xl.
Spacing
The shared spacing prop controls the gap between the icon and text, as well as the button's internal padding.
<Button icon="star" text="Spacious" spacing="lg" />Padding
Set padding to override the button's internal padding with a CSS-like value. Like CSS, it accepts one value for all sides, two values (vertical, horizontal), three values (top, horizontal, bottom), or four values (top, right, bottom, left), with or without px. A single number is also accepted.
<Button text="Even" padding={8} />
<Button text="Wide" padding="4 12" />
<Button text="Custom" padding="4px 12px 4px 12px" />padding overrides the padding derived from spacing side by side, including when spacing="None". The gap between the icon and text still follows spacing.
Disabled state
Set disabled to prevent interaction. The button switches to the intent's disabled colors (when defined in the theme) and ignores hover and click events.
<Button text="Disabled" intent="primary" disabled />Grouped buttons
Set group on a Button and wrap the group in a Group to make every grouped button match the width of the widest one. This keeps a stack of buttons with icons or labels of differing lengths visually aligned.
import { Button, Group, VStack } from "@rbxts/react-clean-ui";
<Group>
<VStack>
<Button group text="Save" intent="primary" />
<Button group text="Save and continue" intent="primary" />
<Button group icon="times" text="Cancel" />
</VStack>
</Group>Props
Button-specific props
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | undefined | Renders a label using the button's typography and intent color. |
icon | IconName | undefined | Renders a leading icon using the button's intent color. |
fontWeight | Enum.FontWeight | undefined | Overrides the font weight used by the label. |
children | React.ReactNode | undefined | Custom content rendered after the automatic icon/label row. |
group | boolean | false | Matches this button's width to the widest button in its Group. |
disabled | boolean | false | Disables hover/click interaction and switches to disabled colors. |
LayoutOrder | number | undefined | Native Roblox layout order. |
padding | CssPadding | undefined | Overrides the spacing-derived internal padding, per side (for example 8, "4 12", or "4px 12px 4px 12px"). |
styleOverride | ButtonStyleOverride | undefined | Overrides theme values (colors, corners, border, etc.) for this instance only. |
Event | React.InstanceEvent<ImageButton> | undefined | Native Roblox event handlers, including Activated. |
Shared props
The button also supports props inherited from the following interfaces.
| Interface | Purpose |
|---|---|
IntentElementProps | Configures the button's base intent. |
IconElementProps | Configures the icon prop's accepted values. |
BackgroundElementProps | Configures background colour and transparency. |
SpacedElementProps | Configures theme-based internal spacing. |
ScalableElementProps | Configures the label and icon scale. |
ShadowElementProps | Configures a box shadow. |
ZIndexElementProps | Configures the button's ZIndex. |
Behaviour
- The button automatically grows to fit its content (
AutomaticSize.XY). - Hovering the button switches its background, border, and text/icon colours to the intent's
hoverstate. - Setting
disabledsetsActive={false}, ignores hover andActivatedevents, and switches colours to the intent'sdisabledstate (when defined in the theme). - When
groupis set and aGroupancestor is present, the button's width is fixed to the widest button reporting into thatGroup; its height still grows automatically. - Without
text,icon, orchildren, the button renders with no content. - Internal padding comes from
spacing(againsttheme.spacing, with"None"meaning0). Whenpaddingis set, its parsed per-side values replace the spacing-derived ones. The resolved padding is also reported toGroup, so a grouped button's width includes it. - Background transparency resolves as
BackgroundTransparencyprop, thenstyleOverride.backgroundTransparency, then the current intent's ownbackgroundTransparency(non-primaryintents only), thentheme.components.button.backgroundTransparency. - Border thickness resolves as the intent state's
borderThickness, thenstyleOverride.borderThickness, thentheme.components.button.borderThickness.
Theme values
The button uses values from theme.components.button for:
- Corner radius
- Border thickness
- Background transparency
- Typography
- Box shadow
- Per-intent background, border, and text/icon colours for the
default,hover, anddisabledstates, plus optionalbackgroundImageandbackgroundGradient
Each intent state in theme.components.button.intents can also set:
borderThickness— overrides the button's border thickness for that intent and state.backgroundTransparency— for any intent other thanprimary, overridestheme.components.button.backgroundTransparency. It is read from that intent's current state, then that intent'sdefaultentry, and is never inherited fromprimary. Forprimary, the component-levelbackgroundTransparencyalways applies.
These values can be changed by providing a custom Clean UI theme.