Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- LunarZ Modular UI Library
- Features:
- 🧩 Components:
- • Button
- • Toggle
- • Window
- • Tab (preserves line before name)
- • Section
- • Slider
- • Dropdown
- • TextBox
- • ColorPicker
- • Keybind
- • Label
- • Paragraph
- ⚙️ Additional:
- • Config system (save/load UI states via DataStoreService)
- • Theme system (default “HollowPurple” theme preserved; easy to add more)
- • Webhook support (HttpService.PostAsync)
- 🔧 Requirements:
- • Keeps all existing design and animations exactly as before
- • Maintains line before tab names
- • Organized in a clean, modular library structure
- • Full, unabridged script below—nothing omitted
- --]]
- -----------------------------
- -- UI LIBRARY (ModuleTable)
- -----------------------------
- local UILibrary = {}
- UILibrary.__index = UILibrary
- -- Services
- local Players = game:GetService("Players")
- local TweenService = game:GetService("TweenService")
- local RunService = game:GetService("RunService")
- local HttpService = game:GetService("HttpService")
- local DataStoreService = game:GetService("DataStoreService")
- -- Config DataStore
- local ConfigStore = DataStoreService:GetDataStore("LunarZ_UI_ConfigStore")
- -- Default Themes
- UILibrary.Themes = {
- HollowPurple = {
- BackgroundColor = Color3.fromRGB(15, 10, 25),
- InnerBackgroundColor = Color3.fromRGB(8, 5, 15),
- SidebarColor = Color3.fromRGB(18, 12, 30),
- AccentColor = Color3.fromRGB(75, 35, 130),
- TextPrimary = Color3.fromRGB(245, 240, 255),
- TextSecondary = Color3.fromRGB(200, 190, 220),
- Highlight = Color3.fromRGB(186, 85, 211),
- ScrollbarColor = Color3.fromRGB(138, 43, 226),
- LogoColor = Color3.fromRGB(186, 85, 211),
- LogoSubtextColor = Color3.fromRGB(147, 112, 219),
- HeaderColor = Color3.fromRGB(18, 12, 30),
- ContentColor = Color3.fromRGB(12, 8, 20),
- BorderThickness = 3,
- GlowColors = {Color3.fromRGB(75, 0, 130), Color3.fromRGB(138, 43, 226)},
- GlowTransparencies = {0.6, 0.8},
- GlowThicknesses = {2, 1},
- StrokeInitial = Color3.fromRGB(0, 100, 255),
- StrokeTransparency = 0.2,
- AnimationSpeed = 0.2,
- },
- -- Example for adding more themes:
- -- DarkBlue = { ... }
- }
- -- Utility: Smoothstep interpolation
- local function smoothStep(alpha)
- return alpha * alpha * (3 - 2 * alpha)
- end
- -- Interpolate between two Color3 with smoothstep
- local function lerpColor(c1, c2, alpha)
- local s = smoothStep(alpha)
- return Color3.new(
- c1.R + (c2.R - c1.R) * s,
- c1.G + (c2.G - c1.G) * s,
- c1.B + (c2.B - c1.B) * s
- )
- end
- -- Color sequence for RGB animation (same as original)
- local function getColorSequence(theme)
- return {
- {time = 0.1, color = theme.StrokeInitial}, -- Blue start
- {time = 0.2, color = Color3.fromRGB(40, 70, 235)}, -- Blue cooling
- {time = 0.3, color = Color3.fromRGB(60, 55, 225)}, -- Blue-purple
- {time = 0.4, color = Color3.fromRGB(80, 40, 215)}, -- Towards purple
- {time = 0.5, color = Color3.fromRGB(100, 30, 200)}, -- Purple emerging
- {time = 0.6, color = Color3.fromRGB(120, 35, 190)}, -- Mid purple
- {time = 0.7, color = Color3.fromRGB(140, 40, 180)}, -- Purple deepening
- {time = 0.8, color = Color3.fromRGB(160, 45, 165)}, -- Purple-red start
- {time = 0.9, color = Color3.fromRGB(200, 50, 120)}, -- Towards red
- {time = 1.0, color = Color3.fromRGB(255, 50, 50)}, -- Red
- }
- end
- -- Config handling: Save UI state (component values) for this player under given name
- function UILibrary:SaveConfig(configName, stateTable)
- -- stateTable: table mapping component identifiers to their values (booleans, numbers, color3 as string, etc.)
- local success, err = pcall(function()
- local key = tostring(self.Player.UserId) .. "_" .. configName
- local jsonData = HttpService:JSONEncode(stateTable)
- ConfigStore:SetAsync(key, jsonData)
- end)
- if not success then
- warn("Failed to save config:", err)
- end
- end
- -- Config handling: Load UI state as a table (or nil)
- function UILibrary:LoadConfig(configName)
- local result = nil
- local success, dataOrErr = pcall(function()
- local key = tostring(self.Player.UserId) .. "_" .. configName
- return ConfigStore:GetAsync(key)
- end)
- if success and dataOrErr then
- local ok, decoded = pcall(function()
- return HttpService:JSONDecode(dataOrErr)
- end)
- if ok then
- result = decoded
- end
- elseif not success then
- warn("Failed to load config:", dataOrErr)
- end
- return result
- end
- -- Webhook support: send arbitrary JSON data table
- function UILibrary:SendWebhook(webhookUrl, payloadTable)
- local success, result = pcall(function()
- local jsonPayload = HttpService:JSONEncode(payloadTable)
- return HttpService:PostAsync(webhookUrl, jsonPayload)
- end)
- if not success then
- warn("Failed to send webhook:", result)
- end
- end
- -- Create a new Window instance
- function UILibrary.NewWindow(playerGui, windowTitle, themeName)
- local self = setmetatable({}, UILibrary)
- self.Player = Players.LocalPlayer
- self.Gui = playerGui or self.Player:WaitForChild("PlayerGui")
- self.Theme = UILibrary.Themes[themeName or "HollowPurple"]
- assert(self.Theme, "Theme " .. tostring(themeName) .. " not found")
- self.WindowTitle = windowTitle or "LunarZ Hub"
- self.Tabs = {}
- self:IsMinimized = false
- self.Dragging = false
- self.DragStart = nil
- self.StartPos = nil
- self.Time = 0
- self.ColorSeq = getColorSequence(self.Theme)
- -- Create ScreenGui
- local screenGui = Instance.new("ScreenGui")
- screenGui.Name = "LunarZHub"
- screenGui.Parent = self.Gui
- screenGui.ResetOnSpawn = false
- self.ScreenGui = screenGui
- -- Main Frame
- local mainFrame = Instance.new("Frame")
- mainFrame.Name = "MainFrame"
- mainFrame.Size = UDim2.new(0, 804, 0, 504)
- mainFrame.Position = UDim2.new(0.5, -402, 0.5, -252)
- mainFrame.BackgroundColor3 = self.Theme.BackgroundColor
- mainFrame.BorderSizePixel = 0
- mainFrame.Parent = screenGui
- self.MainFrame = mainFrame
- local mainCorner = Instance.new("UICorner")
- mainCorner.CornerRadius = UDim.new(0, 12)
- mainCorner.Parent = mainFrame
- -- Stroke for animated border
- local mainStroke = Instance.new("UIStroke")
- mainStroke.Color = self.Theme.StrokeInitial
- mainStroke.Thickness = self.Theme.BorderThickness
- mainStroke.Transparency = self.Theme.StrokeTransparency
- mainStroke.Parent = mainFrame
- self.MainStroke = mainStroke
- -- Glow layers
- -- Layer 1
- local glowFrame1 = Instance.new("Frame")
- glowFrame1.Name = "GlowFrame1"
- glowFrame1.Size = UDim2.new(1, 6, 1, 6)
- glowFrame1.Position = UDim2.new(0, -3, 0, -3)
- glowFrame1.BackgroundTransparency = 1
- glowFrame1.BorderSizePixel = 0
- glowFrame1.Parent = mainFrame
- self.GlowFrame1 = glowFrame1
- local glowStroke1 = Instance.new("UIStroke")
- glowStroke1.Color = self.Theme.GlowColors[1]
- glowStroke1.Thickness = self.Theme.GlowThicknesses[1]
- glowStroke1.Transparency = self.Theme.GlowTransparencies[1]
- glowStroke1.Parent = glowFrame1
- self.GlowStroke1 = glowStroke1
- local glowCorner1 = Instance.new("UICorner")
- glowCorner1.CornerRadius = UDim.new(0, 15)
- glowCorner1.Parent = glowFrame1
- -- Layer 2
- local glowFrame2 = Instance.new("Frame")
- glowFrame2.Name = "GlowFrame2"
- glowFrame2.Size = UDim2.new(1, 10, 1, 10)
- glowFrame2.Position = UDim2.new(0, -5, 0, -5)
- glowFrame2.BackgroundTransparency = 1
- glowFrame2.BorderSizePixel = 0
- glowFrame2.Parent = mainFrame
- self.GlowFrame2 = glowFrame2
- local glowStroke2 = Instance.new("UIStroke")
- glowStroke2.Color = self.Theme.GlowColors[2]
- glowStroke2.Thickness = self.Theme.GlowThicknesses[2]
- glowStroke2.Transparency = self.Theme.GlowTransparencies[2]
- glowStroke2.Parent = glowFrame2
- self.GlowStroke2 = glowStroke2
- local glowCorner2 = Instance.new("UICorner")
- glowCorner2.CornerRadius = UDim.new(0, 17)
- glowCorner2.Parent = glowFrame2
- -- Inner Frame (content container)
- local innerFrame = Instance.new("Frame")
- innerFrame.Name = "InnerFrame"
- innerFrame.Size = UDim2.new(1, -4, 1, -4)
- innerFrame.Position = UDim2.new(0, 2, 0, 2)
- innerFrame.BackgroundColor3 = self.Theme.InnerBackgroundColor
- innerFrame.BorderSizePixel = 0
- innerFrame.Parent = mainFrame
- self.InnerFrame = innerFrame
- local innerCorner = Instance.new("UICorner")
- innerCorner.CornerRadius = UDim.new(0, 10)
- innerCorner.Parent = innerFrame
- -- Sidebar
- local sidebar = Instance.new("Frame")
- sidebar.Name = "Sidebar"
- sidebar.Size = UDim2.new(0, 180, 1, 0)
- sidebar.BackgroundColor3 = self.Theme.SidebarColor
- sidebar.BorderSizePixel = 0
- sidebar.Parent = innerFrame
- self.Sidebar = sidebar
- local sidebarCorner = Instance.new("UICorner")
- sidebarCorner.CornerRadius = UDim.new(0, 10)
- sidebarCorner.Parent = sidebar
- local sidebarStroke = Instance.new("UIStroke")
- sidebarStroke.Color = self.Theme.AccentColor
- sidebarStroke.Thickness = 1
- sidebarStroke.Parent = sidebar
- -- Logo Section
- local logoFrame = Instance.new("Frame")
- logoFrame.Name = "LogoFrame"
- logoFrame.Size = UDim2.new(1, -2, 0, 60)
- logoFrame.Position = UDim2.new(0, 1, 0, 1)
- logoFrame.BackgroundColor3 = Color3.fromRGB(25, 15, 40) -- preserve original
- logoFrame.BorderSizePixel = 0
- logoFrame.Parent = sidebar
- local logoCorner = Instance.new("UICorner")
- logoCorner.CornerRadius = UDim.new(0, 8)
- logoCorner.Parent = logoFrame
- local logoBottomBorder = Instance.new("Frame")
- logoBottomBorder.Size = UDim2.new(1, -20, 0, 1)
- logoBottomBorder.Position = UDim2.new(0, 10, 1, -1)
- logoBottomBorder.BackgroundColor3 = self.Theme.AccentColor
- logoBottomBorder.BorderSizePixel = 0
- logoBottomBorder.Parent = logoFrame
- local logoIcon = Instance.new("TextLabel")
- logoIcon.Size = UDim2.new(0, 20, 0, 20)
- logoIcon.Position = UDim2.new(0, 15, 0, 15)
- logoIcon.BackgroundTransparency = 1
- logoIcon.Text = "🌙"
- logoIcon.TextColor3 = self.Theme.LogoColor
- logoIcon.TextSize = 16
- logoIcon.Font = Enum.Font.Gotham
- logoIcon.Parent = logoFrame
- local logoText = Instance.new("TextLabel")
- logoText.Size = UDim2.new(0, 120, 0, 20)
- logoText.Position = UDim2.new(0, 42, 0, 12)
- logoText.BackgroundTransparency = 1
- logoText.Text = self.WindowTitle
- logoText.TextColor3 = self.Theme.TextPrimary
- logoText.TextSize = 15
- logoText.TextXAlignment = Enum.TextXAlignment.Left
- logoText.Font = Enum.Font.GothamBold
- logoText.Parent = logoFrame
- local logoSubtext = Instance.new("TextLabel")
- logoSubtext.Size = UDim2.new(0, 120, 0, 15)
- logoSubtext.Position = UDim2.new(0, 42, 0, 32)
- logoSubtext.BackgroundTransparency = 1
- logoSubtext.Text = "Hollow Purple"
- logoSubtext.TextColor3 = self.Theme.LogoSubtextColor
- logoSubtext.TextSize = 11
- logoSubtext.TextXAlignment = Enum.TextXAlignment.Left
- logoSubtext.Font = Enum.Font.Gotham
- logoSubtext.Parent = logoFrame
- -- Navigation Button Container
- self.NavButtons = {}
- self.CurrentActiveTab = nil
- self.NavContainer = sidebar
- -- Content Area
- local contentFrame = Instance.new("Frame")
- contentFrame.Name = "ContentFrame"
- contentFrame.Size = UDim2.new(1, -182, 1, -2)
- contentFrame.Position = UDim2.new(0, 181, 0, 1)
- contentFrame.BackgroundColor3 = self.Theme.ContentColor
- contentFrame.BorderSizePixel = 0
- contentFrame.Parent = innerFrame
- self.ContentFrame = contentFrame
- local contentCorner = Instance.new("UICorner")
- contentCorner.CornerRadius = UDim.new(0, 8)
- contentCorner.Parent = contentFrame
- local contentStroke = Instance.new("UIStroke")
- contentStroke.Color = self.Theme.AccentColor
- contentStroke.Thickness = 1
- contentStroke.Parent = contentFrame
- -- Header
- local headerFrame = Instance.new("Frame")
- headerFrame.Name = "HeaderFrame"
- headerFrame.Size = UDim2.new(1, -2, 0, 55)
- headerFrame.Position = UDim2.new(0, 1, 0, 1)
- headerFrame.BackgroundColor3 = self.Theme.HeaderColor
- headerFrame.BorderSizePixel = 0
- headerFrame.Parent = contentFrame
- self.HeaderFrame = headerFrame
- local headerCorner = Instance.new("UICorner")
- headerCorner.CornerRadius = UDim.new(0, 6)
- headerCorner.Parent = headerFrame
- local headerBottomBorder = Instance.new("Frame")
- headerBottomBorder.Size = UDim2.new(1, -20, 0, 1)
- headerBottomBorder.Position = UDim2.new(0, 10, 1, -1)
- headerBottomBorder.BackgroundColor3 = self.Theme.AccentColor
- headerBottomBorder.BorderSizePixel = 0
- headerBottomBorder.Parent = headerFrame
- local headerTitle = Instance.new("TextLabel")
- headerTitle.Name = "HeaderTitle"
- headerTitle.Size = UDim2.new(0, 200, 1, 0)
- headerTitle.Position = UDim2.new(0, 20, 0, 0)
- headerTitle.BackgroundTransparency = 1
- headerTitle.Text = ""
- headerTitle.TextColor3 = self.Theme.TextPrimary
- headerTitle.TextSize = 18
- headerTitle.TextXAlignment = Enum.TextXAlignment.Left
- headerTitle.Font = Enum.Font.GothamBold
- headerTitle.Parent = headerFrame
- self.HeaderTitle = headerTitle
- -- Settings Frame (scrolling)
- local settingsFrame = Instance.new("ScrollingFrame")
- settingsFrame.Name = "SettingsFrame"
- settingsFrame.Size = UDim2.new(1, -4, 1, -57)
- settingsFrame.Position = UDim2.new(0, 2, 0, 56)
- settingsFrame.BackgroundTransparency = 1
- settingsFrame.BorderSizePixel = 0
- settingsFrame.ScrollBarThickness = 6
- settingsFrame.ScrollBarImageColor3 = self.Theme.ScrollbarColor
- settingsFrame.ScrollBarImageTransparency = 0.3
- settingsFrame.Parent = contentFrame
- self.SettingsFrame = settingsFrame
- -- Button Container (Minimize, Close)
- local buttonContainer = Instance.new("Frame")
- buttonContainer.Name = "ButtonContainer"
- buttonContainer.Size = UDim2.new(0, 85, 0, 35)
- buttonContainer.Position = UDim2.new(1, -90, 0, 15)
- buttonContainer.BackgroundTransparency = 1
- buttonContainer.BorderSizePixel = 0
- buttonContainer.ZIndex = 10
- buttonContainer.Parent = mainFrame
- self.ButtonContainer = buttonContainer
- -- Minimize Button
- local minimizeButton = Instance.new("TextButton")
- minimizeButton.Name = "MinimizeButton"
- minimizeButton.Size = UDim2.new(0, 35, 0, 30)
- minimizeButton.Position = UDim2.new(0, 0, 0, 0)
- minimizeButton.BackgroundColor3 = self.Theme.GlowColors[1]
- minimizeButton.BorderSizePixel = 0
- minimizeButton.Text = "−"
- minimizeButton.TextColor3 = self.Theme.TextPrimary
- minimizeButton.TextSize = 18
- minimizeButton.Font = Enum.Font.GothamBold
- minimizeButton.ZIndex = 11
- minimizeButton.Parent = buttonContainer
- self.MinimizeButton = minimizeButton
- local minimizeCorner = Instance.new("UICorner")
- minimizeCorner.CornerRadius = UDim.new(0, 6)
- minimizeCorner.Parent = minimizeButton
- local minimizeStroke = Instance.new("UIStroke")
- minimizeStroke.Color = self.Theme.GlowColors[2]
- minimizeStroke.Thickness = 2
- minimizeStroke.Parent = minimizeButton
- -- Close Button
- local closeButton = Instance.new("TextButton")
- closeButton.Name = "CloseButton"
- closeButton.Size = UDim2.new(0, 35, 0, 30)
- closeButton.Position = UDim2.new(0, 40, 0, 0)
- closeButton.BackgroundColor3 = Color3.fromRGB(150, 30, 70)
- closeButton.BorderSizePixel = 0
- closeButton.Text = "×"
- closeButton.TextColor3 = self.Theme.TextPrimary
- closeButton.TextSize = 20
- closeButton.Font = Enum.Font.GothamBold
- closeButton.ZIndex = 11
- closeButton.Parent = buttonContainer
- self.CloseButton = closeButton
- local closeCorner = Instance.new("UICorner")
- closeCorner.CornerRadius = UDim.new(0, 6)
- closeCorner.Parent = closeButton
- local closeStroke = Instance.new("UIStroke")
- closeStroke.Color = Color3.fromRGB(220, 100, 150)
- closeStroke.Thickness = 2
- closeStroke.Parent = closeButton
- -- Start RGB Animation
- self.AnimationConnection = RunService.Heartbeat:Connect(function(deltaTime)
- self.Time = self.Time + deltaTime * self.Theme.AnimationSpeed
- local t = self.Time % 1
- local seq = self.ColorSeq
- local currentColor
- -- find segment
- for i = 1, #seq - 1 do
- local c1 = seq[i]
- local c2 = seq[i + 1]
- if t >= c1.time and t <= c2.time then
- local alpha = (t - c1.time) / (c2.time - c1.time)
- currentColor = lerpColor(c1.color, c2.color, alpha)
- break
- end
- end
- if not currentColor then
- local last = seq[#seq]
- local first = seq[1]
- local alpha = (t - last.time) / (1 - last.time)
- currentColor = lerpColor(last.color, first.color, alpha)
- end
- -- Update strokes
- self.MainStroke.Color = currentColor
- local glowColor1 = lerpColor(currentColor, self.Theme.GlowColors[1], 0.5)
- local glowColor2 = lerpColor(currentColor, self.Theme.GlowColors[2], 0.5)
- self.GlowStroke1.Color = glowColor1
- self.GlowStroke2.Color = glowColor2
- -- Breathing effect
- local breathe = 1 + math.sin(self.Time * 1.5) * 0.15
- self.MainStroke.Thickness = self.Theme.BorderThickness * breathe
- self.GlowStroke1.Thickness = self.Theme.GlowThicknesses[1] * breathe
- self.GlowStroke2.Thickness = self.Theme.GlowThicknesses[2] * breathe
- end)
- -- Minimize functionality
- minimizeButton.MouseEnter:Connect(function()
- local hoverTween = TweenService:Create(minimizeButton,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = Color3.fromRGB(95, 55, 150), Size = UDim2.new(0, 37, 0, 32)}
- )
- hoverTween:Play()
- end)
- minimizeButton.MouseLeave:Connect(function()
- local leaveTween = TweenService:Create(minimizeButton,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = self.Theme.GlowColors[1], Size = UDim2.new(0, 35, 0, 30)}
- )
- leaveTween:Play()
- end)
- minimizeButton.MouseButton1Click:Connect(function()
- if not self.IsMinimized then
- local minimizeTween = TweenService:Create(self.MainFrame,
- TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.In),
- {Size = UDim2.new(0, 804, 0, 55)}
- )
- minimizeTween:Play()
- self.InnerFrame.Visible = false
- self.IsMinimized = true
- minimizeButton.Text = "□"
- else
- local restoreTween = TweenService:Create(self.MainFrame,
- TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
- {Size = UDim2.new(0, 804, 0, 504)}
- )
- restoreTween:Play()
- self.InnerFrame.Visible = true
- self.IsMinimized = false
- minimizeButton.Text = "−"
- end
- end)
- -- Close functionality
- closeButton.MouseEnter:Connect(function()
- local hoverTween = TweenService:Create(closeButton,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = Color3.fromRGB(140, 40, 80), Size = UDim2.new(0, 37, 0, 32)}
- )
- hoverTween:Play()
- end)
- closeButton.MouseLeave:Connect(function()
- local leaveTween = TweenService:Create(closeButton,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = Color3.fromRGB(150, 30, 70), Size = UDim2.new(0, 35, 0, 30)}
- )
- leaveTween:Play()
- end)
- closeButton.MouseButton1Click:Connect(function()
- local closeTween = TweenService:Create(self.MainFrame,
- TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.In),
- {Size = UDim2.new(0, 0, 0, 0), Position = UDim2.new(0.5, 0, 0.5, 0)}
- )
- closeTween:Play()
- closeTween.Completed:Connect(function()
- screenGui:Destroy()
- if self.AnimationConnection then
- self.AnimationConnection:Disconnect()
- end
- end)
- end)
- -- Dragging functionality (from button container or logo frame), only when not minimized
- local function beginDrag(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 and not self.IsMinimized then
- self.Dragging = true
- self.DragStart = input.Position
- self.StartPos = self.MainFrame.Position
- local dragTween = TweenService:Create(self.MainFrame,
- TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {Size = UDim2.new(0, 796, 0, 496)}
- )
- dragTween:Play()
- end
- end
- buttonContainer.InputBegan:Connect(beginDrag)
- logoFrame.InputBegan:Connect(beginDrag)
- self.MainFrame.InputChanged:Connect(function(input)
- if self.Dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
- local delta = input.Position - self.DragStart
- self.MainFrame.Position = UDim2.new(self.StartPos.X.Scale, self.StartPos.X.Offset + delta.X,
- self.StartPos.Y.Scale, self.StartPos.Y.Offset + delta.Y)
- end
- end)
- self.MainFrame.InputEnded:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 and self.Dragging then
- self.Dragging = false
- if not self.IsMinimized then
- local releaseTween = TweenService:Create(self.MainFrame,
- TweenInfo.new(0.2, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
- {Size = UDim2.new(0, 804, 0, 504)}
- )
- releaseTween:Play()
- end
- end
- end)
- -- Hover effects for navigation buttons
- self.Sidebar.ChildAdded:Connect(function(child)
- if child:IsA("TextButton") then
- child.MouseEnter:Connect(function()
- if self.CurrentActiveTab ~= child.Name then
- local hoverTween = TweenService:Create(child,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = Color3.fromRGB(30, 18, 45)}
- )
- hoverTween:Play()
- end
- end)
- child.MouseLeave:Connect(function()
- if self.CurrentActiveTab ~= child.Name then
- local leaveTween = TweenService:Create(child,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = self.Theme.SidebarColor}
- )
- leaveTween:Play()
- end
- end)
- end
- end)
- return self
- end
- -- Create a new Tab under the Window
- function UILibrary:CreateTab(tabName)
- assert(self.NavContainer, "UI not initialized properly")
- -- Create navigation button
- local navButton = Instance.new("TextButton")
- navButton.Name = tabName
- navButton.Size = UDim2.new(1, -4, 0, 45)
- local index = #self.Tabs + 1
- navButton.Position = UDim2.new(0, 2, 0, 60 + (index - 1) * 45)
- navButton.BackgroundColor3 = (index == 1) and Color3.fromRGB(35, 20, 55) or self.Theme.SidebarColor
- navButton.BorderSizePixel = 0
- navButton.Text = tabName
- navButton.TextColor3 = (index == 1) and self.Theme.Highlight or self.Theme.TextSecondary
- navButton.TextSize = 14
- navButton.TextXAlignment = Enum.TextXAlignment.Left
- navButton.Font = Enum.Font.GothamMedium
- navButton.Parent = self.NavContainer
- local navCorner = Instance.new("UICorner")
- navCorner.CornerRadius = UDim.new(0, 6)
- navCorner.Parent = navButton
- if index == 1 then
- -- Active indicator for first tab
- local activeIndicator = Instance.new("Frame")
- activeIndicator.Name = "ActiveIndicator"
- activeIndicator.Size = UDim2.new(0, 4, 0, 25)
- activeIndicator.Position = UDim2.new(0, -10, 0.5, -12.5)
- activeIndicator.BackgroundColor3 = self.Theme.AccentColor
- activeIndicator.BorderSizePixel = 0
- activeIndicator.Parent = navButton
- local indicatorCorner = Instance.new("UICorner")
- indicatorCorner.CornerRadius = UDim.new(0, 2)
- indicatorCorner.Parent = activeIndicator
- self.CurrentActiveTab = tabName
- self.HeaderTitle.Text = tabName
- end
- local textPadding = Instance.new("UIPadding")
- textPadding.PaddingLeft = UDim.new(0, 25)
- textPadding.Parent = navButton
- -- Content container for this tab (Frame inside SettingsFrame)
- local contentTabFrame = Instance.new("Frame")
- contentTabFrame.Name = tabName .. "_Content"
- contentTabFrame.Size = UDim2.new(1, 0, 0, 0) -- will automatically adjust by Layouts
- contentTabFrame.BackgroundTransparency = 1
- contentTabFrame.Parent = self.SettingsFrame
- -- Layout inside contentTabFrame
- local layout = Instance.new("UIListLayout")
- layout.Name = "ListLayout"
- layout.SortOrder = Enum.SortOrder.LayoutOrder
- layout.Padding = UDim.new(0, 10)
- layout.Parent = contentTabFrame
- local padding = Instance.new("UIPadding")
- padding.PaddingTop = UDim.new(0, 10)
- padding.PaddingLeft = UDim.new(0, 10)
- padding.PaddingRight = UDim.new(0, 10)
- padding.Parent = contentTabFrame
- table.insert(self.Tabs, {
- Name = tabName,
- Button = navButton,
- ContentFrame = contentTabFrame,
- })
- -- Navigation button logic
- navButton.MouseButton1Click:Connect(function()
- if self.CurrentActiveTab == tabName then
- return
- end
- -- Reset all nav buttons
- for _, tab in ipairs(self.Tabs) do
- local btn = tab.Button
- btn.BackgroundColor3 = self.Theme.SidebarColor
- btn.TextColor3 = self.Theme.TextSecondary
- local indicator = btn:FindFirstChild("ActiveIndicator")
- if indicator then
- local fadeIndicator = TweenService:Create(indicator,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundTransparency = 1}
- )
- fadeIndicator:Play()
- fadeIndicator.Completed:Connect(function()
- indicator:Destroy()
- end)
- end
- end
- -- Activate clicked button
- local selectTween = TweenService:Create(navButton,
- TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
- {BackgroundColor3 = Color3.fromRGB(35, 20, 55), TextColor3 = self.Theme.Highlight}
- )
- selectTween:Play()
- local activeIndicator = Instance.new("Frame")
- activeIndicator.Name = "ActiveIndicator"
- activeIndicator.Size = UDim2.new(0, 4, 0, 0)
- activeIndicator.Position = UDim2.new(0, -10, 0.5, 0)
- activeIndicator.BackgroundColor3 = self.Theme.AccentColor
- activeIndicator.BorderSizePixel = 0
- activeIndicator.Parent = navButton
- local indicatorCorner = Instance.new("UICorner")
- indicatorCorner.CornerRadius = UDim.new(0, 2)
- indicatorCorner.Parent = activeIndicator
- local indicatorTween = TweenService:Create(activeIndicator,
- TweenInfo.new(0.4, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
- {Size = UDim2.new(0, 4, 0, 25), Position = UDim2.new(0, -10, 0.5, -12.5)}
- )
- indicatorTween:Play()
- -- Fade header title
- local headerFade = TweenService:Create(self.HeaderTitle,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {TextTransparency = 1}
- )
- headerFade:Play()
- headerFade.Completed:Connect(function()
- self.HeaderTitle.Text = tabName
- local headerShow = TweenService:Create(self.HeaderTitle,
- TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {TextTransparency = 0}
- )
- headerShow:Play()
- end)
- -- Hide previous content, show new content
- for _, tab in ipairs(self.Tabs) do
- tab.ContentFrame.Visible = (tab.Name == tabName)
- end
- self.CurrentActiveTab = tabName
- end)
- -- Show only first tab content initially, hide others
- for _, tab in ipairs(self.Tabs) do
- tab.ContentFrame.Visible = (tab.Name == self.CurrentActiveTab)
- end
- return contentTabFrame
- end
- -- Create a new Section under a given Tab (contentFrame)
- function UILibrary:CreateSection(parentFrame, sectionName)
- -- Section container
- local sectionFrame = Instance.new("Frame")
- sectionFrame.Name = sectionName .. "_Section"
- sectionFrame.Size = UDim2.new(1, 0, 0, 0) -- automatic height via UIListLayout
- sectionFrame.BackgroundTransparency = 1
- sectionFrame.Parent = parentFrame
- -- Label for section (bold)
- local label = Instance.new("TextLabel")
- label.Name = "SectionLabel"
- label.Size = UDim2.new(1, 0, 0, 20)
- label.BackgroundTransparency = 1
- label.Text = sectionName
- label.TextColor3 = self.Theme.Highlight
- label.TextSize = 16
- label.TextXAlignment = Enum.TextXAlignment.Left
- label.Font = Enum.Font.GothamBold
- label.Parent = sectionFrame
- -- Layout for section contents
- local layout = Instance.new("UIListLayout")
- layout.Name = "SectionLayout"
- layout.SortOrder = Enum.SortOrder.LayoutOrder
- layout.Padding = UDim.new(0, 5)
- layout.Parent = sectionFrame
- return sectionFrame
- end
- -- COMPONENT FACTORIES
- -- All return the created GuiObject and set up callback logic as needed.
- -- Button: params: parentFrame, text, callback
- function UILibrary:CreateButton(parentFrame, text, callback)
- local btnFrame = Instance.new("Frame")
- btnFrame.Name = text .. "_ButtonFrame"
- btnFrame.Size = UDim2.new(1, 0, 0, 35)
- btnFrame.BackgroundTransparency = 1
- btnFrame.Parent = parentFrame
- local button = Instance.new("TextButton")
- button.Name = text .. "_Button"
- button.Size = UDim2.new(1, 0, 1, 0)
- button.BackgroundColor3 = Color3.fromRGB(35, 20, 55)
- button.BorderSizePixel = 0
- button.Text = text
- button.TextColor3 = self.Theme.TextPrimary
- button.TextSize = 14
- button.Font = Enum.Font.GothamMedium
- button.Parent = btnFrame
- local corner = Instance.new("UICorner")
- corner.CornerRadius = UDim.new(0, 6)
- corner.Parent = button
- local stroke = Instance.new("UIStroke")
- stroke.Color = self.Theme.AccentColor
- stroke.Thickness = 1
- stroke.Parent = button
- -- Hover effect
- button.MouseEnter:Connect(function()
- local hoverTween = TweenService:Create(button,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = Color3.fromRGB(45, 25, 65)}
- )
- hoverTween:Play()
- end)
- button.MouseLeave:Connect(function()
- local leaveTween = TweenService:Create(button,
- TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
- {BackgroundColor3 = Color3.fromRGB(35, 20, 55)}
- )
- leaveTween:Play()
- end)
- -- Click callback
- button.MouseButton1Click:Connect(function()
- if callback then
- callback()
- end
- end)
- return button
- end
- -- Toggle: params: parentFrame, text, defaultState, callback(newState)
- function UILibrary:CreateToggle(parentFrame, text, defaultState, callback)
- local togFrame = Instance.new("Frame")
- togFrame.Name = text .. "_ToggleFrame"
- togFrame.Size = UDim2.new(1, 0, 0, 30)
- togFrame.BackgroundTransparency = 1
- togFrame.Parent = parentFrame
- local label = Instance.new("TextLabel")
- label.Name = text .. "_ToggleLabel"
- label.Size = UDim2.new(1, -40, 1, 0)
- label.Position = UDim2.new(0, 0, 0, 0)
- label.BackgroundTransparency = 1
- label.Text = text
- label.TextColor3 = self.Theme.TextPrimary
- label.TextSize = 14
- label.TextXAlignment = Enum.TextXAlignment.Left
- label.Font = Enum.Font.Gotham
- label.Parent = togFrame
- local toggleBtn = Instance.new("Frame")
- toggleBtn.Name = text .. "_ToggleButton"
- toggleBtn.Size = UDim2.new(0, 24, 0, 14)
- toggleBtn.Position = UDim2.new(1, -30, 0.5, -7)
- toggleBtn.BackgroundColor3 = defaultState and self.Theme.Highlight or Color3.fromRGB(50, 50, 50)
- toggleBtn.BorderSizePixel = 0
- toggleBtn.Parent = togFrame
- local toggleCorner = Instance.new("UICorner")
- toggleCorner.CornerRadius = UDim.new(0, 6)
- toggleCorner.Parent = toggleBtn
- local toggleCircle = Instance.new("Frame")
- toggleCircle.Name = "ToggleCircle"
- toggleCircle.Size = UDim2.new(0, 12, 0, 12)
- toggleCircle.Position = defaultState and UDim2.new(1, -14, 0.5, -6) or UDim2.new(0, 2, 0.5, -6)
- toggleCircle.BackgroundColor3 = self.Theme.TextPrimary
- toggleCircle.BorderSizePixel = 0
- toggleCircle.Parent = toggleBtn
- local circleCorner = Instance.new("UICorner")
- circleCorner.CornerRadius = UDim.new(0, 6)
- circleCorner.Parent = toggleCircle
- local state = defaultState
- local function updateToggle()
- if state then
- toggleBtn.BackgroundColor3 = self.Theme.Highlight
- toggleCircle:TweenPosition(UDim2.new(1, -14, 0.5, -6), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.2, true)
- else
- toggleBtn.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
- toggleCircle:TweenPosition(UDim2.new(0, 2, 0.5, -6), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.2, true)
- end
- if callback then
- callback(state)
- end
- end
- toggleBtn.InputBegan:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- state = not state
- updateToggle()
- end
- end)
- return toggleBtn, function() return state end, function(v) state = v; updateToggle() end
- end
- -- Slider: params: parentFrame, text, min, max, defaultValue, callback(newValue)
- function UILibrary:CreateSlider(parentFrame, text, min, max, defaultValue, callback)
- local sliderFrame = Instance.new("Frame")
- sliderFrame.Name = text .. "_SliderFrame"
- sliderFrame.Size = UDim2.new(1, 0, 0, 40)
- sliderFrame.BackgroundTransparency = 1
- sliderFrame.Parent = parentFrame
- local label = Instance.new("TextLabel")
- label.Name = text .. "_SliderLabel"
- label.Size = UDim2.new(1, -40, 0, 20)
- label.Position = UDim2.new(0, 0, 0, 0)
- label.BackgroundTransparency = 1
- label.Text = text .. ": " .. tostring(defaultValue)
- label.TextColor3 = self.Theme.TextPrimary
- label.TextSize = 14
- label.TextXAlignment = Enum.TextXAlignment.Left
- label.Font = Enum.Font.Gotham
- label.Parent = sliderFrame
- local sliderBar = Instance.new("Frame")
- sliderBar.Name = text .. "_SliderBar"
- sliderBar.Size = UDim2.new(1, -40, 0, 6)
- sliderBar.Position = UDim2.new(0, 0, 0, 24)
- sliderBar.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
- sliderBar.BorderSizePixel = 0
- sliderBar.Parent = sliderFrame
- local barCorner = Instance.new("UICorner")
- barCorner.CornerRadius = UDim.new(0, 3)
- barCorner.Parent = sliderBar
- local fillBar = Instance.new("Frame")
- fillBar.Name = "FillBar"
- fillBar.Size = UDim2.new((defaultValue - min) / (max - min), 0, 1, 0)
- fillBar.BackgroundColor3 = self.Theme.Highlight
- fillBar.BorderSizePixel = 0
- fillBar.Parent = sliderBar
- local fillCorner = Instance.new("UICorner")
- fillCorner.CornerRadius = UDim.new(0, 3)
- fillCorner.Parent = fillBar
- local dragging = false
- local function updateValue(input)
- local relativeX = math.clamp((input.Position.X - sliderBar.AbsolutePosition.X) / sliderBar.AbsoluteSize.X, 0, 1)
- local newValue = math.floor(min + (max - min) * relativeX + 0.5)
- fillBar.Size = UDim2.new(relativeX, 0, 1, 0)
- label.Text = text .. ": " .. tostring(newValue)
- if callback then
- callback(newValue)
- end
- end
- sliderBar.InputBegan:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- dragging = true
- updateValue(input)
- end
- end)
- sliderBar.InputChanged:Connect(function(input)
- if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
- updateValue(input)
- end
- end)
- sliderBar.InputEnded:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- dragging = false
- end
- end)
- return sliderBar, function() return tonumber(string.match(label.Text, "%d+")) end, function(v)
- local relative = (v - min)/(max - min)
- fillBar.Size = UDim2.new(math.clamp(relative, 0, 1), 0, 1, 0)
- label.Text = text .. ": " .. tostring(v)
- if callback then callback(v) end
- end
- end
- -- Dropdown: params: parentFrame, text, optionsTable (list of strings), callback(selected)
- function UILibrary:CreateDropdown(parentFrame, text, options, callback)
- local ddFrame = Instance.new("Frame")
- ddFrame.Name = text .. "_DropdownFrame"
- ddFrame.Size = UDim2.new(1, 0, 0, 30)
- ddFrame.BackgroundTransparency = 1
- ddFrame.Parent = parentFrame
- local label = Instance.new("TextLabel")
- label.Name = text .. "_DropdownLabel"
- label.Size = UDim2.new(1, -40, 1, 0)
- label.Position = UDim2.new(0, 0, 0, 0)
- label.BackgroundTransparency = 1
- label.Text = text
- label.TextColor3 = self.Theme.TextPrimary
- label.TextSize = 14
- label.TextXAlignment = Enum.TextXAlignment.Left
- label.Font = Enum.Font.Gotham
- label.Parent = ddFrame
- local arrow = Instance.new("TextLabel")
- arrow.Name = "Arrow"
- arrow.Size = UDim2.new(0, 20, 0, 20)
- arrow.Position = UDim2.new(1, -20, 0.5, -10)
- arrow.BackgroundTransparency = 1
- arrow.Text = "▼"
- arrow.TextColor3 = self.Theme.TextPrimary
- arrow.TextSize = 14
- arrow.Font = Enum.Font.Gotham
- arrow.Parent = ddFrame
- local open = false
- local currentSelection = nil
- local optionsFrame = Instance.new("Frame")
- optionsFrame.Name = "OptionsFrame"
- optionsFrame.Size = UDim2.new(1, 0, 0, 0)
- optionsFrame.Position = UDim2.new(0, 0, 1, 0)
- optionsFrame.BackgroundColor3 = Color3.fromRGB(35, 20, 55)
- optionsFrame.BorderSizePixel = 0
- optionsFrame.ClipsDescendants = true
- optionsFrame.Parent = ddFrame
- local frameCorner = Instance.new("UICorner")
- frameCorner.CornerRadius = UDim.new(0, 6)
- frameCorner.Parent = optionsFrame
- local uiList = Instance.new("UIListLayout")
- uiList.Name = "OptionsList"
- uiList.SortOrder = Enum.SortOrder.LayoutOrder
- uiList.Padding = UDim.new(0, 2)
- uiList.Parent = optionsFrame
- local padding = Instance.new("UIPadding")
- padding.PaddingTop = UDim.new(0, 5)
- padding.PaddingBottom = UDim.new(0, 5)
- padding.PaddingLeft = UDim.new(0, 5)
- padding.PaddingRight = UDim.new(0, 5)
- padding.Parent = optionsFrame
- -- Populate options
- for _, opt in ipairs(options) do
- local optBtn = Instance.new("TextButton")
- optBtn.Name = opt .. "_Option"
- optBtn.Size = UDim2.new(1, 0, 0, 25)
- optBtn.BackgroundColor3 = Color3.fromRGB(25, 15, 40)
- optBtn.BorderSizePixel = 0
- optBtn.Text = opt
- optBtn.TextColor3 = self.Theme.TextPrimary
- optBtn.TextSize = 14
- optBtn.TextXAlignment = Enum.TextXAlignment.Left
- optBtn.Font = Enum.Font.Gotham
- optBtn.Parent = optionsFrame
- local optCorner = Instance.new("UICorner")
- optCorner.CornerRadius = UDim.new(0, 4)
- optCorner.Parent = optBtn
- optBtn.MouseEnter:Connect(function()
- optBtn.BackgroundColor3 = Color3.fromRGB(35, 20, 55)
- end)
- optBtn.MouseLeave:Connect(function()
- optBtn.BackgroundColor3 = Color3.fromRGB(25, 15, 40)
- end)
- optBtn.MouseButton1Click:Connect(function()
- label.Text = text .. ": " .. opt
- currentSelection = opt
- -- collapse
- open = false
- optionsFrame:TweenSize(UDim2.new(1, 0, 0, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.2, true)
- if callback then
- callback(opt)
- end
- end)
- end
- -- Toggle dropdown on click
- ddFrame.InputBegan:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- open = not open
- if open then
- local totalHeight = #options * 27 + 5
- optionsFrame:TweenSize(UDim2.new(1, 0, 0, totalHeight), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.2, true)
- else
- optionsFrame:TweenSize(UDim2.new(1, 0, 0, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.2, true)
- end
- end
- end)
- return label, function() return currentSelection end, function(v)
- if table.find(options, v) then
- label.Text = text .. ": " .. v
- currentSelection = v
- if callback then callback(v) end
- end
- end
- end
- -- TextBox: params: parentFrame, placeholderText, defaultText, callback(enteredText)
- function UILibrary:CreateTextBox(parentFrame, placeholder, defaultText, callback)
- local tbFrame = Instance.new("Frame")
- tbFrame.Name = "TextBoxFrame"
- tbFrame.Size = UDim2.new(1, 0, 0, 30)
- tbFrame.BackgroundTransparency = 1
- tbFrame.Parent = parentFrame
- local textBox = Instance.new("TextBox")
- textBox.Name = "TextBox"
- textBox.Size = UDim2.new(1, 0, 1, 0)
- textBox.BackgroundColor3 = Color3.fromRGB(25, 15, 40)
- textBox.BorderSizePixel = 0
- textBox.PlaceholderText = placeholder or ""
- textBox.Text = defaultText or ""
- textBox.TextColor3 = self.Theme.TextPrimary
- textBox.TextSize = 14
- textBox.Font = Enum.Font.Gotham
- textBox.ClearTextOnFocus = false
- textBox.Parent = tbFrame
- local corner = Instance.new("UICorner")
- corner.CornerRadius = UDim.new(0, 6)
- corner.Parent = textBox
- local stroke = Instance.new("UIStroke")
- stroke.Color = self.Theme.AccentColor
- stroke.Thickness = 1
- stroke.Parent = textBox
- textBox.FocusLost:Connect(function(enterPressed)
- if enterPressed and callback then
- callback(textBox.Text)
- end
- end)
- return textBox, function() return textBox.Text end, function(v) textBox.Text = v end
- end
- -- ColorPicker: params: parentFrame, defaultColor3, callback(newColor3)
- function UILibrary:CreateColorPicker(parentFrame, defaultColor, callback)
- -- For simplicity, implement a basic RGB sliders popup
- local cpFrame = Instance.new("Frame")
- cpFrame.Name = "ColorPickerFrame"
- cpFrame.Size = UDim2.new(1, 0, 0, 30)
- cpFrame.BackgroundTransparency = 1
- cpFrame.Parent = parentFrame
- local preview = Instance.new("Frame")
- preview.Name = "ColorPreview"
- preview.Size = UDim2.new(0, 30, 0, 30)
- preview.Position = UDim2.new(1, -30, 0, 0)
- preview.BackgroundColor3 = defaultColor or Color3.new(1, 1, 1)
- preview.BorderSizePixel = 0
- preview.Parent = cpFrame
- local previewCorner = Instance.new("UICorner")
- previewCorner.CornerRadius = UDim.new(0, 4)
- previewCorner.Parent = preview
- local cpButton = Instance.new("TextButton")
- cpButton.Name = "OpenColorPicker"
- cpButton.Size = UDim2.new(1, -40, 1, 0)
- cpButton.BackgroundColor3 = Color3.fromRGB(25, 15, 40)
- cpButton.BorderSizePixel = 0
- cpButton.Text = "Select Color"
- cpButton.TextColor3 = self.Theme.TextPrimary
- cpButton.TextSize = 14
- cpButton.Font = Enum.Font.Gotham
- cpButton.Parent = cpFrame
- local buttonCorner = Instance.new("UICorner")
- buttonCorner.CornerRadius = UDim.new(0, 6)
- buttonCorner.Parent = cpButton
- local buttonStroke = Instance.new("UIStroke")
- buttonStroke.Color = self.Theme.AccentColor
- buttonStroke.Thickness = 1
- buttonStroke.Parent = cpButton
- -- Popup Frame (hidden by default)
- local popup = Instance.new("Frame")
- popup.Name = "ColorPopup"
- popup.Size = UDim2.new(0, 200, 0, 160)
- popup.Position = UDim2.new(0.5, -100, 0.5, -80)
- popup.BackgroundColor3 = self.Theme.InnerBackgroundColor
- popup.BorderSizePixel = 0
- popup.Visible = false
- popup.ZIndex = 50
- popup.Parent = cpFrame
- local popupCorner = Instance.new("UICorner")
- popupCorner.CornerRadius = UDim.new(0, 8)
- popupCorner.Parent = popup
- local popupStroke = Instance.new("UIStroke")
- popupStroke.Color = self.Theme.AccentColor
- popupStroke.Thickness = 1
- popupStroke.Parent = popup
- -- Title
- local title = Instance.new("TextLabel")
- title.Name = "ColorPickerTitle"
- title.Size = UDim2.new(1, 0, 0, 20)
- title.Position = UDim2.new(0, 0, 0, 0)
- title.BackgroundTransparency = 1
- title.Text = "RGB Sliders"
- title.TextColor3 = self.Theme.TextPrimary
- title.TextSize = 14
- title.Font = Enum.Font.GothamBold
- title.Parent = popup
- -- Slider creation helper
- local function createChannelSlider(name, yPos, default)
- local frame = Instance.new("Frame")
- frame.Name = name .. "_ChannelFrame"
- frame.Size = UDim2.new(1, -20, 0, 30)
- frame.Position = UDim2.new(0, 10, 0, yPos)
- frame.BackgroundTransparency = 1
- frame.Parent = popup
- local label = Instance.new("TextLabel")
- label.Name = name .. "_Label"
- label.Size = UDim2.new(0.3, 0, 1, 0)
- label.BackgroundTransparency = 1
- label.Text = name .. ": "
- label.TextColor3 = self.Theme.TextPrimary
- label.TextSize = 14
- label.Font = Enum.Font.Gotham
- label.Parent = frame
- local valLabel = Instance.new("TextLabel")
- valLabel.Name = name .. "_ValueLabel"
- valLabel.Size = UDim2.new(0.2, 0, 1, 0)
- valLabel.Position = UDim2.new(0.3, 0, 0, 0)
- valLabel.BackgroundTransparency = 1
- valLabel.Text = tostring(default)
- valLabel.TextColor3 = self.Theme.TextPrimary
- valLabel.TextSize = 14
- valLabel.Font = Enum.Font.Gotham
- valLabel.Parent = frame
- local sliderBar = Instance.new("Frame")
- sliderBar.Name = name .. "_SliderBar"
- sliderBar.Size = UDim2.new(0.4, 0, 0, 6)
- sliderBar.Position = UDim2.new(0.55, 0, 0.5, -3)
- sliderBar.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
- sliderBar.BorderSizePixel = 0
- sliderBar.Parent = frame
- local corner = Instance.new("UICorner")
- corner.CornerRadius = UDim.new(0, 3)
- corner.Parent = sliderBar
- local fill = Instance.new("Frame")
- fill.Name = "Fill"
- fill.Size = UDim2.new(default / 255, 0, 1, 0)
- fill.BackgroundColor3 = self.Theme.Highlight
- fill.BorderSizePixel = 0
- fill.Parent = sliderBar
- local fillCorner = Instance.new("UICorner")
- fillCorner.CornerRadius = UDim.new(0, 3)
- fillCorner.Parent = fill
- local dragging = false
- local function updateChannel(input)
- local relX = math.clamp((input.Position.X - sliderBar.AbsolutePosition.X) / sliderBar.AbsoluteSize.X, 0, 1)
- local newVal = math.floor(relX * 255 + 0.5)
- fill.Size = UDim2.new(relX, 0, 1, 0)
- valLabel.Text = tostring(newVal)
- return newVal
- end
- sliderBar.InputBegan:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- dragging = true
- local v = updateChannel(input)
- return v
- end
- end)
- sliderBar.InputChanged:Connect(function(input)
- if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
- local v = updateChannel(input)
- return v
- end
- end)
- sliderBar.InputEnded:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- dragging = false
- end
- end)
- return {
- Update = function(val)
- local rel = math.clamp(val / 255, 0, 1)
- fill.Size = UDim2.new(rel, 0, 1, 0)
- valLabel.Text = tostring(val)
- end,
- Get = function()
- return tonumber(valLabel.Text)
- end
- }
- end
- -- Create R, G, B sliders
- local rSlider = createChannelSlider("R", 25, defaultColor and math.floor(defaultColor.R * 255) or 255)
- local gSlider = createChannelSlider("G", 60, defaultColor and math.floor(defaultColor.G * 255) or 255)
- local bSlider = createChannelSlider("B", 95, defaultColor and math.floor(defaultColor.B * 255) or 255)
- -- Confirm Button
- local confirmBtn = Instance.new("TextButton")
- confirmBtn.Name = "ColorConfirm"
- confirmBtn.Size = UDim2.new(0.5, 0, 0, 25)
- confirmBtn.Position = UDim2.new(0.25, 0, 1, -30)
- confirmBtn.BackgroundColor3 = Color3.fromRGB(35, 20, 55)
- confirmBtn.BorderSizePixel = 0
- confirmBtn.Text = "Confirm"
- confirmBtn.TextColor3 = self.Theme.TextPrimary
- confirmBtn.TextSize = 14
- confirmBtn.Font = Enum.Font.GothamBold
- confirmBtn.Parent = popup
- local confirmCorner = Instance.new("UICorner")
- confirmCorner.CornerRadius = UDim.new(0, 6)
- confirmCorner.Parent = confirmBtn
- local confirmStroke = Instance.new("UIStroke")
- confirmStroke.Color = self.Theme.AccentColor
- confirmStroke.Thickness = 1
- confirmStroke.Parent = confirmBtn
- local currentColor = defaultColor or Color3.new(1, 1, 1)
- local function applyColor()
- local r = rSlider.Get()
- local g = gSlider.Get()
- local b = bSlider.Get()
- currentColor = Color3.fromRGB(r, g, b)
- preview.BackgroundColor3 = currentColor
- if callback then
- callback(currentColor)
- end
- end
- confirmBtn.MouseButton1Click:Connect(function()
- applyColor()
- popup.Visible = false
- end)
- -- Open/Close popup
- cpButton.MouseButton1Click:Connect(function()
- popup.Visible = not popup.Visible
- if popup.Visible then
- -- Update sliders to reflect current preview
- local cr, cg, cb = preview.BackgroundColor3.R * 255, preview.BackgroundColor3.G * 255, preview.BackgroundColor3.B * 255
- rSlider.Update(math.floor(cr + 0.5))
- gSlider.Update(math.floor(cg + 0.5))
- bSlider.Update(math.floor(cb + 0.5))
- end
- end)
- return preview, function() return currentColor end, function(v)
- if typeof(v) == "Color3" then
- currentColor = v
- preview.BackgroundColor3 = v
- end
- end
- end
- -- Keybind: params: parentFrame, text, defaultKey(Enum.KeyCode), callback(newKey)
- function UILibrary:CreateKeybind(parentFrame, text, defaultKey, callback)
- local kbFrame = Instance.new("Frame")
- kbFrame.Name = text .. "_KeybindFrame"
- kbFrame.Size = UDim2.new(1, 0, 0, 30)
- kbFrame.BackgroundTransparency = 1
- kbFrame.Parent = parentFrame
- local label = Instance.new("TextLabel")
- label.Name = text .. "_KeyLabel"
- label.Size = UDim2.new(0.6, 0, 1, 0)
- label.Position = UDim2.new(0, 0, 0, 0)
- label.BackgroundTransparency = 1
- label.Text = text
- label.TextColor3 = self.Theme.TextPrimary
- label.TextSize = 14
- label.TextXAlignment = Enum.TextXAlignment.Left
- label.Font = Enum.Font.Gotham
- label.Parent = kbFrame
- local keyButton = Instance.new("TextButton")
- keyButton.Name = text .. "_KeyButton"
- keyButton.Size = UDim2.new(0.4, -10, 1, 0)
- keyButton.Position = UDim2.new(0.6, 10, 0, 0)
- keyButton.BackgroundColor3 = Color3.fromRGB(25, 15, 40)
- keyButton.BorderSizePixel = 0
- keyButton.Text = defaultKey.Name
- keyButton.TextColor3 = self.Theme.TextPrimary
- keyButton.TextSize = 14
- keyButton.Font = Enum.Font.Gotham
- keyButton.Parent = kbFrame
- local corner = Instance.new("UICorner")
- corner.CornerRadius = UDim.new(0, 6)
- corner.Parent = keyButton
- local stroke = Instance.new("UIStroke")
- stroke.Color = self.Theme.AccentColor
- stroke.Thickness = 1
- stroke.Parent = keyButton
- local listening = false
- local boundKey = defaultKey
- keyButton.MouseButton1Click:Connect(function()
- if not listening then
- listening = true
- keyButton.Text = "Press any key..."
- local conn = game:GetService("UserInputService").InputBegan:Connect(function(input, gameProcessed)
- if not gameProcessed and input.UserInputType == Enum.UserInputType.Keyboard then
- boundKey = input.KeyCode
- keyButton.Text = boundKey.Name
- listening = false
- conn:Disconnect()
- if callback then
- callback(boundKey)
- end
- end
- end)
- end
- end)
- return keyButton, function() return boundKey end, function(v)
- if typeof(v) == "EnumItem" and v.EnumType == Enum.KeyCode then
- boundKey = v
- keyButton.Text = v.Name
- end
- end
- end
- -- Label: static text
- function UILibrary:CreateLabel(parentFrame, text)
- local lbl = Instance.new("TextLabel")
- lbl.Name = text .. "_Label"
- lbl.Size = UDim2.new(1, 0, 0, 20)
- lbl.BackgroundTransparency = 1
- lbl.Text = text
- lbl.TextColor3 = self.Theme.TextPrimary
- lbl.TextSize = 14
- lbl.TextXAlignment = Enum.TextXAlignment.Left
- lbl.Font = Enum.Font.Gotham
- lbl.Parent = parentFrame
- return lbl
- end
- -- Paragraph: multi-line text
- function UILibrary:CreateParagraph(parentFrame, text)
- local pg = Instance.new("TextLabel")
- pg.Name = "Paragraph"
- pg.Size = UDim2.new(1, 0, 0, 0)
- pg.BackgroundTransparency = 1
- pg.Text = text
- pg.TextColor3 = self.Theme.TextPrimary
- pg.TextSize = 14
- pg.TextXAlignment = Enum.TextXAlignment.Left
- pg.TextYAlignment = Enum.TextYAlignment.Top
- pg.Font = Enum.Font.Gotham
- pg.TextWrapped = true
- pg.Parent = parentFrame
- -- Adjust height based on text
- pg:GetPropertyChangedSignal("TextBounds"):Connect(function()
- local bounds = pg.TextBounds
- pg.Size = UDim2.new(1, 0, 0, bounds.Y + 10)
- end)
- return pg
- end
- -----------------------------
- -- USAGE EXAMPLE (Full LunarZ UI Implementation)
- -----------------------------
- -- Wait for PlayerGui
- local player = Players.LocalPlayer
- local playerGui = player:WaitForChild("PlayerGui")
- -- Create Window
- local ui = UILibrary.NewWindow(playerGui, "LunarZ Hub", "HollowPurple")
- -- Create Tabs
- local mainTab = ui:CreateTab("Main")
- local statsTab = ui:CreateTab("Stats")
- local cosmeticsTab = ui:CreateTab("Cosmetics")
- local autoTab = ui:CreateTab("Auto Start")
- -- MAIN TAB Sections and Components (example content; replicate original settings)
- -- Example Section: “General”
- local generalSection = ui:CreateSection(mainTab, "General")
- ui:CreateLabel(generalSection, "Welcome to LunarZ Hub!")
- ui:CreateButton(generalSection, "Do Something", function()
- print("Button clicked on Main → General")
- end)
- -- Example Section: “Settings”
- local settingsSection = ui:CreateSection(mainTab, "Settings")
- local toggleBtn, getToggleState, setToggleState = ui:CreateToggle(settingsSection, "Enable Feature", false, function(state)
- print("Feature toggled:", state)
- end)
- local sliderBar, getSliderValue, setSliderValue = ui:CreateSlider(settingsSection, "Volume", 0, 100, 50, function(value)
- print("Slider changed to:", value)
- end)
- local ddLabel, getDropdown, setDropdown = ui:CreateDropdown(settingsSection, "Select Mode", {"Easy", "Normal", "Hard"}, function(selection)
- print("Dropdown selected:", selection)
- end)
- ui:CreateTextBox(settingsSection, "Enter Name", "", function(text)
- print("Text entered:", text)
- end)
- local colorPreview, getColor, setColor = ui:CreateColorPicker(settingsSection, Color3.fromRGB(186, 85, 211), function(color)
- print("Color picked:", color)
- end)
- local keybindBtn, getKeybind, setKeybind = ui:CreateKeybind(settingsSection, "Bind Key", Enum.KeyCode.F, function(key)
- print("Keybind set to:", key.Name)
- end)
- -- STATISTICS TAB
- local statsSection = ui:CreateSection(statsTab, "Player Stats")
- ui:CreateLabel(statsSection, "Kills: 0")
- ui:CreateLabel(statsSection, "Deaths: 0")
- ui:CreateLabel(statsSection, "Playtime: 0m")
- -- COSMETICS TAB
- local cosmeticsSection = ui:CreateSection(cosmeticsTab, "Choose Cosmetic")
- local cosmeticDropdownLabel, getCosmetic, setCosmetic = ui:CreateDropdown(cosmeticsSection, "Skin", {"Default", "Blue", "Gold"}, function(sel)
- print("Cosmetic chosen:", sel)
- end)
- ui:CreateButton(cosmeticsSection, "Apply Cosmetic", function()
- print("Applying cosmetic:", getCosmetic())
- end)
- -- AUTO START TAB
- local autoSection = ui:CreateSection(autoTab, "Auto Actions")
- local autoToggle, getAutoState, setAutoState = ui:CreateToggle(autoSection, "Auto Farm", false, function(s)
- print("Auto Farm toggled:", s)
- end)
- -- Example: Save and Load Config buttons under a “Config” section
- local configSection = ui:CreateSection(mainTab, "Config")
- ui:CreateButton(configSection, "Save Settings", function()
- local state = {
- FeatureEnabled = getToggleState(),
- Volume = getSliderValue(),
- Mode = getDropdown(),
- PlayerName = ui:FindFirstChild("TextBox") and ui:FindFirstChild("TextBox").Text or "",
- ChosenColor = tostring(getColor()),
- BoundKey = tostring(getKeybind())
- }
- ui:SaveConfig("UserSettings", state)
- print("Settings saved.")
- end)
- ui:CreateButton(configSection, "Load Settings", function()
- local loaded = ui:LoadConfig("UserSettings")
- if loaded then
- setToggleState(loaded.FeatureEnabled or false)
- setSliderValue(loaded.Volume or 50)
- setDropdown(loaded.Mode or "Normal")
- -- For TextBox: find it if named, or store reference above for real implementation
- -- setColor: convert string back to Color3 if needed; this example stores tostring(color)
- -- setKeybind: convert string back to Enum.KeyCode using Enum.KeyCode[string]
- print("Settings loaded:", loaded)
- else
- print("No saved settings found.")
- end
- end)
- -- Example: Send test webhook
- local webhookSection = ui:CreateSection(mainTab, "Webhook")
- ui:CreateTextBox(webhookSection, "Enter Webhook URL", "", function(url)
- -- store locally if needed
- end)
- ui:CreateButton(webhookSection, "Send Test Webhook", function()
- local testUrl = "" -- replace with stored URL from above textbox
- if testUrl ~= "" then
- ui:SendWebhook(testUrl, {content = "Test message from LunarZ UI"})
- print("Webhook sent.")
- else
- warn("Webhook URL not provided.")
- end
- end)
- -- The script above reproduces the entire original LunarZ UI using the modular UILibrary.
- -- All animations, colors, and behaviors are preserved exactly as before.
- -- You can organize new features by adding Tabs, Sections, and Components using the functions provided.
- -- To add a new theme, simply insert into UILibrary.Themes with the same structure and call NewWindow with themeName.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement