Create an item list that grows as you add rows. Selecting an item updates a label. This is a local UI exercise with sample data, not a saved inventory or purchase system.
1. Prepare the screen
Create a ScreenGui named ListGui directly inside StarterGui. Set ScreenInsets to CoreUISafeInsets. Insert one LocalScript into ListGui. The script below creates the rest of the interface, so you do not need to add rows by hand.
2. Create the list and rows
Paste this complete script into the LocalScript:
local gui = script.Parent
local panel = Instance.new("Frame")
panel.AnchorPoint = Vector2.new(0.5, 0.5)
panel.Position = UDim2.fromScale(0.5, 0.5)
panel.Size = UDim2.fromScale(0.9, 0.8)
panel.BackgroundColor3 = Color3.fromRGB(30, 33, 40)
panel.Parent = gui
local limit = Instance.new("UISizeConstraint")
limit.MaxSize = Vector2.new(560, 500)
limit.Parent = panel
local selected = Instance.new("TextLabel")
selected.Position = UDim2.fromOffset(12, 8)
selected.Size = UDim2.new(1, -24, 0, 40)
selected.BackgroundTransparency = 1
selected.TextColor3 = Color3.new(1, 1, 1)
selected.TextSize = 18
selected.TextWrapped = true
selected.Text = "Select an item"
selected.Parent = panel
local list = Instance.new("ScrollingFrame")
list.Name = "Items"
list.Position = UDim2.fromOffset(12, 56)
list.Size = UDim2.new(1, -24, 1, -68)
list.BackgroundTransparency = 1
list.BorderSizePixel = 0
list.CanvasSize = UDim2.fromOffset(0, 0)
list.AutomaticCanvasSize = Enum.AutomaticSize.Y
list.ScrollingDirection = Enum.ScrollingDirection.Y
list.ScrollBarThickness = 6
list.Parent = panel
local layout = Instance.new("UIListLayout")
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Padding = UDim.new(0, 8)
layout.Parent = list
for index = 1, 20 do
local itemName = "Sample item " .. index
local row = Instance.new("TextButton")
row.Name = "Item" .. index
row.Size = UDim2.new(1, -12, 0, 48)
row.LayoutOrder = index
row.BackgroundColor3 = Color3.fromRGB(55, 60, 72)
row.TextColor3 = Color3.new(1, 1, 1)
row.TextSize = 18
row.Text = itemName
row.Parent = list
row.Activated:Connect(function()
selected.Text = "Selected: " .. itemName
end)
end
3. Understand the two sizes
The panel and list Size values define the visible area. AutomaticCanvasSize expands the area inside the list as content grows. UIListLayout places each row below the previous one, using LayoutOrder for predictable ordering.
The rows have fixed pixel heights and flexible widths. Their 12-pixel width allowance keeps the text clear of the scrollbar. Avoid making row height a fraction of a canvas whose height those same rows determine.
4. Test adding and removing content
Run the game and scroll to Sample item 20. Select it and confirm the label changes. Stop the test, change the loop count to 3, and run again. The interface should no longer need the long scroll area.
Repeat on a phone emulator and test dragging the list as well as tapping a row. For real data, generate rows from your item table and rebuild or update them when that data changes.
Troubleshooting
- Rows overlap: check that UIListLayout is inside Items.
- Ordering looks wrong: set SortOrder to LayoutOrder and assign each row a number.
- Large blank scroll area: check that CanvasSize starts at zero.
- Selection does not award an item: this lesson only updates presentation. Validate actual inventory changes on the server.