A draggable, sortable grid-based inventory system with item slots, stack counts, tooltips, and rarity border colors.
| Author | RobloxUI Team |
| Framework | Roblox-TS + React-Luau |
| Category | Inventory |
| Dependencies | @rbxts/react, @robloxui/theme |
| Theme Tokens | colors.bg, colors.bgTertiary, colors.border, colors.textPrimary |
| Last Updated | July 22, 2026 |
import React from "@rbxts/react";
import { useTheme } from "@robloxui/theme";
interface InventoryItem {
id: string;
name: string;
icon: string;
count: number;
rarity: "common" | "rare" | "epic" | "legendary";
}
interface InventoryGridProps {
items: (InventoryItem | null)[];
columns?: number;
slotSize?: number;
}
const RARITY_COLORS = { common: "#9CA3AF", rare: "#3B82F6", epic: "#8B5CF6", legendary: "#F59E0B" };
export function InventoryGrid({ items, columns = 6, slotSize = 64 }: InventoryGridProps) {
const { colors } = useTheme();
return (
<frame BackgroundTransparency={1} Size={new UDim2(0, columns * (slotSize + 4), 0, 0)} AutomaticSize={"Y"}>
<uigridlayout CellSize={new UDim2(0, slotSize, 0, slotSize)} CellPadding={new UDim2(0, 4, 0, 4)} FillDirectionMaxCells={columns} />
{items.map((item, i) => (
item ? (
<frame key={i} BackgroundColor3={colors.bgTertiary} Size={new UDim2(0, slotSize, 0, slotSize)}>
<uicorner CornerRadius={new UDim(0, 6)} />
<uistroke Thickness={2} Color={Color3.fromHex(RARITY_COLORS[item.rarity])} />
<imagelabel Image={item.icon} Size={new UDim2(1, -8, 1, -8)} Position={new UDim2(0.5, 0, 0.5, 0)} AnchorPoint={new Vector2(0.5, 0.5)} BackgroundTransparency={1} />
{item.count > 1 && (
<textlabel Text={tostring(item.count)} TextColor3={colors.textPrimary} BackgroundTransparency={1} Position={new UDim2(1, -4, 1, 0)} AnchorPoint={new Vector2(1, 1)} Size={new UDim2(0, 20, 0, 16)} />
)}
</frame>
) : (
<frame key={i} BackgroundColor3={colors.bg} Size={new UDim2(0, slotSize, 0, slotSize)}>
<uicorner CornerRadius={new UDim(0, 6)} />
<uistroke Thickness={1} Color={colors.border} />
</frame>
)
))}
</frame>
);
}