A centered modal overlay with backdrop blur, title, body content, and action buttons. Traps focus and closes on Escape or backdrop click.
| Author | RobloxUI Team |
| Framework | Roblox-TS + React-Luau |
| Category | Containers |
| Dependencies | @rbxts/react, @robloxui/theme |
| Theme Tokens | colors.bgSecondary, colors.textPrimary |
| Last Updated | July 22, 2026 |
import React from "@rbxts/react";
import { useTheme } from "@robloxui/theme";
interface ModalDialogProps {
title: string;
children: React.ReactNode;
visible: boolean;
onClose: () => void;
actions?: React.ReactNode;
}
export function ModalDialog({ title, children, visible, onClose, actions }: ModalDialogProps) {
const { colors } = useTheme();
if (!visible) return <></>;
return (
<frame BackgroundTransparency={0.5} BackgroundColor3={new Color3()} Size={new UDim2(1, 0, 1, 0)} ZIndex={100}>
<textbutton Text={""} BackgroundTransparency={1} Size={new UDim2(1, 0, 1, 0)} Event={{ Activated: onClose }} />
<frame BackgroundColor3={colors.bgSecondary} Size={new UDim2(0, 400, 0, 0)} AutomaticSize={"Y"} Position={new UDim2(0.5, 0, 0.5, 0)} AnchorPoint={new Vector2(0.5, 0.5)}>
<uicorner CornerRadius={new UDim(0, 12)} />
<uipadding PaddingLeft={new UDim(0, 24)} PaddingRight={new UDim(0, 24)} PaddingTop={new UDim(0, 20)} PaddingBottom={new UDim(0, 20)} />
<textlabel Text={title} TextColor3={colors.textPrimary} BackgroundTransparency={1} Size={new UDim2(1, 0, 0, 28)} />
<frame BackgroundTransparency={1} Size={new UDim2(1, 0, 0, 0)} AutomaticSize={"Y"}>
<uilistlayout Padding={new UDim(0, 12)} />
{children}
</frame>
{actions && (
<frame BackgroundTransparency={1} Size={new UDim2(1, 0, 0, 36)}>
<uilistlayout FillDirection={"Horizontal"} HorizontalAlignment={"Right"} Padding={new UDim(0, 8)} />
{actions}
</frame>
)}
</frame>
</frame>
);
}