Skip to content

Commit

Permalink
Make a functional dropdown component (help me)
Browse files Browse the repository at this point in the history
  • Loading branch information
ImAvafe committed Oct 24, 2024
1 parent ec190e0 commit fbf74b3
Show file tree
Hide file tree
Showing 6 changed files with 312 additions and 60 deletions.
32 changes: 32 additions & 0 deletions samples/SettingsMenu/init.luau
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,38 @@ return function(Scope: Fusion.Scope<any>, Props: Props)
PlaceholderText = "Nickname",
CharacterLimit = 20,
},
Scope:Dropdown {
Items = {
"R$1,000,000",
"End world hunger",
"Infinite Skibidi Toilet",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
"Another option",
},
},
},
},
Scope:Button {
Expand Down
56 changes: 0 additions & 56 deletions src/Components/Dropdown.luau

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
local OnyxUI = script.Parent.Parent
local OnyxUI = script.Parent.Parent.Parent
local Fusion = require(OnyxUI.Parent.Fusion)
local Util = require(OnyxUI.Util)
local Themer = require(OnyxUI.Themer)

local Children = Fusion.Children

local Components = {
Dropdown = require(script.Parent.Dropdown),
Frame = require(script.Parent.Frame),
Dropdown = require(script.Parent),
Frame = require(script.Parent.Parent.Frame),
Text = require(script.Parent.Parent.Text),
}

return {
Expand All @@ -20,9 +21,15 @@ return {
Padding = Scope:Computed(function(Use)
return UDim.new(0, Use(Theme.StrokeThickness["1"]))
end),
ListEnabled = true,

[Children] = {
Scope:Dropdown {},
Scope:Dropdown {
Items = { "R$1,000,000", "End world hunger", "Infinite Skibidi Toilet" },
},
Scope:Text {
Text = "This text should not move.",
},
},
}

Expand Down
194 changes: 194 additions & 0 deletions src/Components/Dropdown/DropdownHandler.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local CoreGui = game:GetService("CoreGui")

local OnyxUI = script.Parent.Parent.Parent
local Fusion = require(OnyxUI.Parent.Fusion)
local Util = require(OnyxUI.Util)
local Themer = require(OnyxUI.Themer)
local Signal = require(OnyxUI.Parent.Signal)

local Children = Fusion.Children

local Components = {
TextInput = require(OnyxUI.Components.TextInput),
Scroller = require(OnyxUI.Components.Scroller),
Button = require(OnyxUI.Components.Button),
Group = require(OnyxUI.Components.Group),
}

local Scope = Fusion.scoped(Fusion, Components, Util)

local States = {
Object = Scope:Value(nil),
Items = Scope:Value(Scope:Value({})),
Selection = Scope:Value(Scope:Value(nil)),
Theme = Scope:Value(Themer.Theme:now()),
OnSelected = Scope:Value(Scope:Value(function() end)),
FocusLost = Signal.new(),
}

local Open = Scope:Computed(function(Use)
return Use(States.Object) ~= nil
end)
local CanvasPosition = Scope:Value(Vector2.new())
local OnFocusLost = function(SelectedItem)
if SelectedItem then
Fusion.peek(States.Selection):set(SelectedItem)
end

States.Items:set({})
States.Object:set(nil)

Fusion.peek(Fusion.peek(States.OnSelected))()
States.OnSelected:set(function() end)

CanvasPosition:set(Vector2.new(), true)
end

States.FocusLost:Connect(function()
OnFocusLost()
end)

local function WatchPositionAndSize(GuiObject: Fusion.UsedAs<GuiObject>)
local AbsolutePosition = Scope:Value(Vector2.new())
local AbsoluteSize = Scope:Value(Vector2.new())

local PositionConnection: RBXScriptConnection?
local SizeConnection: RBXScriptConnection?

Scope:Observer(GuiObject):onChange(function()
local ObjectValue = Fusion.peek(GuiObject)

if PositionConnection then
PositionConnection:Disconnect()
end
if SizeConnection then
SizeConnection:Disconnect()
end

if ObjectValue ~= nil then
AbsolutePosition:set(ObjectValue.AbsolutePosition)
AbsoluteSize:set(ObjectValue.AbsoluteSize)

SizeConnection = ObjectValue:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
AbsoluteSize:set(ObjectValue.AbsoluteSize)
end)

task.delay(1, function()
PositionConnection = ObjectValue:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
States.Object:set(nil)
end)
end)
end
end)

return AbsolutePosition, AbsoluteSize
end

local AbsolutePosition, AbsoluteSize = WatchPositionAndSize(States.Object)

Scope:New "ScreenGui" {
Name = "DropdownHandler",
DisplayOrder = 1000,
Parent = Scope:Computed(function(Use)
if RunService:IsRunning() and (Players.LocalPlayer ~= nil) then
return Players.LocalPlayer:FindFirstChild("PlayerGui")
else
return CoreGui
end
end),
Enabled = Open,

[Children] = {
Scope:Group {
Name = "List",
AnchorPoint = Vector2.new(0, -1),
Position = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
local AbsolutePositionValue = Use(AbsolutePosition)
local AbsoluteSizeValue = Use(AbsoluteSize)
return UDim2.fromOffset(
AbsolutePositionValue.X,
(AbsolutePositionValue.Y + AbsoluteSizeValue.Y) + (Use(Theme.StrokeThickness["1"]) * 2)
)
end),
Size = Scope:Computed(function(Use)
local AbsoluteSizeValue = Use(AbsoluteSize)
return UDim2.new(UDim.new(0, AbsoluteSizeValue.X), UDim.new(0, 0))
end),
AutomaticSize = Enum.AutomaticSize.Y,
CornerRadius = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
return Use(UDim.new(0, Use(Theme.CornerRadius["1"])))
end),

[Children] = {
Scope:Scroller {
Size = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
return UDim2.new(UDim.new(1, 0), UDim.new(0, Use(Theme.Spacing["16"])))
end),
AutomaticSize = Enum.AutomaticSize.None,
StrokeEnabled = true,
StrokeColor = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
return Use(Theme.Colors.Neutral.Main)
end),
ListEnabled = true,
ListPadding = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
return Use(UDim.new(0, Use(Theme.Spacing["0"])))
end),
ListHorizontalFlex = Enum.UIFlexAlignment.Fill,
BackgroundTransparency = 0,
BackgroundColor3 = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
return Use(Theme.Colors.Neutral.Main)
end),
Active = true,
CanvasPosition = CanvasPosition,

[Children] = {
Scope:Computed(function(Use)
return Scope:ForValues(Use(States.Items), function(Use, Scope, Item)
local IsHovering = Scope:Value(false)

return Themer.Theme:is(Use(States.Theme)):during(function()
return Scope:Button {
Name = "ItemButton",
Content = { Item },
Style = "Ghost",
Color = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
return Use(Theme.Colors.BaseContent.Main)
end),
BackgroundTransparency = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
if Use(IsHovering) then
return 1 - Use(Theme.Emphasis.Light)
else
return 1
end
end),
IsHovering = IsHovering,
CornerRadius = Scope:Computed(function(Use)
local Theme = Use(States.Theme)
return UDim.new(0, Use(Theme.CornerRadius["0"]))
end),

OnActivated = function()
OnFocusLost(Item)
end,
}
end)
end)
end),
},
},
},
},
},
}

return States
Loading

0 comments on commit fbf74b3

Please sign in to comment.