-- Roblox GUI Template with Tab System + Icons + Highlight Animation (LocalScript)
-- This version adds optional tab icons and smooth highlight animation when switching tabs.

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local player = Players.LocalPlayer

-- CONFIG -----------------------------------------------------------
local CONFIG = {
    GuiName = "TabbedEditableGUI",
    TitleText = "My GUI",
    Width = 480,
    Height = 340,
    BackgroundColor = Color3.fromRGB(30,30,35),
    AccentColor = Color3.fromRGB(0,170,255),
    CornerRadius = UDim.new(0,8),
    TabInactiveColor = Color3.fromRGB(50,50,60),
    TabHighlightTweenTime = 0.25,
}

-- UTILITIES --------------------------------------------------------
local function new(class, props)
    local inst = Instance.new(class)
    for k,v in pairs(props or {}) do
        pcall(function() inst[k] = v end)
    end
    return inst
end
local function makeCorner(parent, radius)
    local c = Instance.new("UICorner")
    c.CornerRadius = radius or CONFIG.CornerRadius
    c.Parent = parent
end

-- ROOT GUI ---------------------------------------------------------
local screenGui = new("ScreenGui", {Name = CONFIG.GuiName, ResetOnSpawn = false, Parent = player:WaitForChild("PlayerGui")})
local mainFrame = new("Frame", {
    Name = "MainFrame",
    Size = UDim2.new(0, CONFIG.Width, 0, CONFIG.Height),
    Position = UDim2.new(0.5, -CONFIG.Width/2, 0.5, -CONFIG.Height/2),
    BackgroundColor3 = CONFIG.BackgroundColor,
    BorderSizePixel = 0,
    Parent = screenGui,
})
makeCorner(mainFrame)

-- TITLE BAR --------------------------------------------------------
local titleBar = new("Frame", {
    Name = "TitleBar",
    Size = UDim2.new(1, 0, 0, 36),
    BackgroundTransparency = 1,
    Parent = mainFrame,
})
local titleLabel = new("TextLabel", {
    Text = CONFIG.TitleText,
    Size = UDim2.new(1, -10, 1, 0),
    Position = UDim2.new(0, 10, 0, 0),
    BackgroundTransparency = 1,
    TextXAlignment = Enum.TextXAlignment.Left,
    TextColor3 = Color3.fromRGB(240,240,240),
    Font = Enum.Font.GothamSemibold,
    TextSize = 18,
    Parent = titleBar,
})
local closeButton = new("TextButton", {
    Text = "X",
    Size = UDim2.new(0,28,0,28),
    Position = UDim2.new(1,-36,0,4),
    BackgroundColor3 = Color3.fromRGB(40,40,44),
    TextColor3 = Color3.fromRGB(220,220,220),
    Font = Enum.Font.GothamBold,
    TextSize = 16,
    Parent = titleBar,
})
makeCorner(closeButton, UDim.new(0,6))

-- TAB BAR ----------------------------------------------------------
local tabBar = new("Frame", {
    Name = "TabBar",
    Size = UDim2.new(1, -20, 0, 36),
    Position = UDim2.new(0,10,0,40),
    BackgroundTransparency = 1,
    Parent = mainFrame,
})
local tabList = new("UIListLayout", {FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0,6), SortOrder = Enum.SortOrder.LayoutOrder})
tabList.Parent = tabBar

-- TAB CONTENT CONTAINER --------------------------------------------
local contentHolder = new("Frame", {
    Name = "ContentHolder",
    Size = UDim2.new(1,-20,1,-90),
    Position = UDim2.new(0,10,0,80),
    BackgroundTransparency = 1,
    Parent = mainFrame,
})

-- DRAGGING ----------------------------------------------------------
local dragging, dragInput, dragStart, startPos
local function updateDrag(input)
    local delta = input.Position - dragStart
    mainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end
titleBar.InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        dragging = true
        dragStart = input.Position
        startPos = mainFrame.Position
        input.Changed:Connect(function()
            if input.UserInputState == Enum.UserInputState.End then dragging=false end
        end)
    end
end)
titleBar.InputChanged:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseMovement then dragInput=input end
end)
game:GetService("UserInputService").InputChanged:Connect(function(input)
    if dragging and input==dragInput then updateDrag(input) end
end)

closeButton.MouseButton1Click:Connect(function()
    mainFrame.Visible = not mainFrame.Visible
end)

-- TAB SYSTEM --------------------------------------------------------
local Tabs = {}
local ActiveTab = nil

local function highlightTab(tabName)
    for name, data in pairs(Tabs) do
        local goalColor = name == tabName and CONFIG.AccentColor or CONFIG.TabInactiveColor
        TweenService:Create(data.Button, TweenInfo.new(CONFIG.TabHighlightTweenTime), {BackgroundColor3 = goalColor}):Play()
        data.Highlight.Visible = (name == tabName)
    end
end

local function switchTab(tabName)
    for name, data in pairs(Tabs) do
        data.Content.Visible = (name == tabName)
    end
    ActiveTab = tabName
    highlightTab(tabName)
end

local function createTab(tabName, iconId)
    local tabButton = new("TextButton", {
        Name = tabName.."Button",
        Size = UDim2.new(0,110,1,0),
        BackgroundColor3 = CONFIG.TabInactiveColor,
        Text = "",
        Parent = tabBar,
    })
    makeCorner(tabButton)

    local icon = new("ImageLabel", {
        Size = UDim2.new(0,20,0,20),
        Position = UDim2.new(0,8,0.5,-10),
        BackgroundTransparency = 1,
        Image = iconId or "rbxassetid://3926305904",
        ImageRectOffset = Vector2.new(4, 4),
        ImageRectSize = Vector2.new(36,36),
        Parent = tabButton,
    })

    local label = new("TextLabel", {
        Size = UDim2.new(1,-36,1,0),
        Position = UDim2.new(0,32,0,0),
        BackgroundTransparency = 1,
        Text = tabName,
        TextColor3 = Color3.fromRGB(240,240,240),
        Font = Enum.Font.GothamBold,
        TextSize = 14,
        Parent = tabButton,
    })

    local highlightBar = new("Frame", {
        Size = UDim2.new(1,0,0,3),
        Position = UDim2.new(0,0,1,-3),
        BackgroundColor3 = CONFIG.AccentColor,
        Visible = false,
        Parent = tabButton,
    })

    local contentFrame = new("ScrollingFrame", {
        Name = tabName.."Content",
        Size = UDim2.new(1,0,1,0),
        BackgroundTransparency = 1,
        Visible = false,
        Parent = contentHolder,
        CanvasSize = UDim2.new(0,0,0,0),
        ScrollBarThickness = 6,
    })
    local uiList = new("UIListLayout", {Padding = UDim.new(0,8), SortOrder = Enum.SortOrder.LayoutOrder})
    uiList.Parent = contentFrame

    Tabs[tabName] = {Button=tabButton, Content=contentFrame, Layout=uiList, Highlight=highlightBar}

    tabButton.MouseButton1Click:Connect(function()
        switchTab(tabName)
    end)

    if not ActiveTab then switchTab(tabName) end
    return Tabs[tabName]
end

-- BUILDER -----------------------------------------------------------
local builder = {}
function builder:GetTab(tabName, iconId)
    return Tabs[tabName] or createTab(tabName, iconId)
end

local function recalc(tab)
    local height=0
    for _,child in ipairs(tab.Content:GetChildren()) do
        if child:IsA("GuiObject") and child~=tab.Layout then
            height += child.AbsoluteSize.Y + tab.Layout.Padding.Offset
        end
    end
    tab.Content.CanvasSize = UDim2.new(0,0,0,height+8)
end

function builder:AddLabel(tabName,text)
    local tab=self:GetTab(tabName)
    local lbl=new("TextLabel",{Size=UDim2.new(1,-8,0,28),BackgroundTransparency=1,Text=text or "Label",TextColor3=Color3.fromRGB(230,230,230),Font=Enum.Font.Gotham,TextSize=14,Parent=tab.Content})
    recalc(tab)
    return lbl
end
function builder:AddButton(tabName,text,onClick)
    local tab=self:GetTab(tabName)
    local btn=new("TextButton",{Size=UDim2.new(1,-8,0,34),BackgroundColor3=Color3.fromRGB(50,50,60),Text=text or "Button",TextColor3=Color3.fromRGB(240,240,240),Font=Enum.Font.GothamBold,TextSize=15,Parent=tab.Content})
    makeCorner(btn)
    btn.MouseButton1Click:Connect(function() if onClick then pcall(onClick,btn) end end)
    recalc(tab)
    return btn
end
function builder:AddTextBox(tabName,placeholder,onEnter)
    local tab=self:GetTab(tabName)
    local box=new("TextBox",{Size=UDim2.new(1,-8,0,32),BackgroundColor3=Color3.fromRGB(50,50,60),Text="",PlaceholderText=placeholder or "Enter text...",ClearTextOnFocus=false,Font=Enum.Font.Gotham,TextSize=14,TextColor3=Color3.fromRGB(240,240,240),Parent=tab.Content})
    makeCorner(box)
    box.FocusLost:Connect(function(enter) if enter and onEnter then pcall(onEnter,box.Text) end end)
    recalc(tab)
    return box
end

-- EXAMPLES ----------------------------------------------------------
builder:AddLabel("Main","Welcome to the main tab!")
builder:AddButton("Main","Click Me",function() print("Main Tab Button Clicked") end)

builder:AddLabel("Settings","Settings Tab Example")
builder:AddTextBox("Settings","Change name...",function(txt) print("Settings input:",txt) end)

-- ANIMATION ---------------------------------------------------------
mainFrame.BackgroundTransparency=1
TweenService:Create(mainFrame,TweenInfo.new(0.3),{BackgroundTransparency=0}):Play()

screenGui:SetAttribute("GuiAPI",true)
return builder

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: