local C=script.Parent.Parent.Parent.Parent local U=C.Parent local Z=require(C.Theme)local b=Z.WithTheme local p=Z.ApplyDescription local w=Z.RegisterStateAction local m=require(U.Sift)local O=require(U.t)local M=require(U.Roact)local r=M.createElement local W=require(C.App.Effect.UIStroke)local V="\105\109\097\103\101\115\047\070\108\117\101\110\116\047\067\104\101\118\114\111\110\068\111\119\110\077\101\100\047\049\050\112\120"local X="\115\116\121\108\101\115\047\065\110\105\109\097\116\105\111\110\083\112\114\105\110\103\080\097\114\097\109\115\047\067\111\110\116\114\111\108\047\073\110\112\117\116\047\066\117\116\116\111\110\047\067\111\108\111\114"local i="\115\116\121\108\101\115\047\065\110\105\109\097\116\105\111\110\083\112\114\105\110\103\080\097\114\097\109\115\047\067\111\110\116\114\111\108\047\073\110\112\117\116\047\066\117\116\116\111\110\047\084\114\097\110\115\112\097\114\101\110\099\121"local l=11 local n=11 local o=4 local x=script.Parent local G=require(x.Descriptions.DropdownButtonDescriptions)local A=M.PureComponent:extend(script.Name)A.Descriptions=G A.StyleBindings={"\083\116\114\111\107\101";"\070\105\108\108";"\084\101\120\116"}A.defaultProps={Size=UDim2.fromOffset(120,32)}A.validateProps=O.strictInterface({Text=O.optional(O.string);AnchorPoint=O.optional(O.Vector2),Disabled=O.optional(O.boolean),LayoutOrder=O.optional(O.number);Position=O.optional(O.UDim2),Size=O.optional(O.UDim2),Native=O.optional(O.table),[M.Children]=O.optional(O.table);[M.Event.Activated]=O.optional(O.callback);[M.Event.MouseButton1Down]=O.optional(O.callback);[M.Event.MouseButton1Up]=O.optional(O.callback),[M.Event.MouseEnter]=O.optional(O.callback),[M.Event.MouseLeave]=O.optional(O.callback)})function A.init(C)for U,Z in pairs(C.StyleBindings)do C[Z],C["\083\101\116"..Z]=M.createBinding({})end w(C,M.Event.Activated,nil)w(C,M.Event.MouseButton1Down,"\080\114\101\115\115\101\100")w(C,M.Event.MouseButton1Up,"\072\111\118\101\114")w(C,M.Event.MouseEnter,"\072\111\118\101\114")w(C,M.Event.MouseLeave,"\082\101\115\116")C:setState({State="\082\101\115\116"})end function A.ApplyDescription(Z,C,U)p(Z,C,U,U[X],U[i])end function A.render(C)local U=C.props local Z=C.state return b(function(b)if U.Disabled then C:ApplyDescription(C.Descriptions.Disabled,b)elseif Z.State=="\082\101\115\116"then C:ApplyDescription(C.Descriptions.Rest,b)elseif Z.State=="\072\111\118\101\114"then C:ApplyDescription(C.Descriptions.Hover,b)elseif Z.State=="\080\114\101\115\115\101\100"then C:ApplyDescription(C.Descriptions.Pressed,b)end local p=b[V]local w=r("\073\109\097\103\101\066\117\116\116\111\110",{AnchorPoint=Vector2.new(1,.5);BackgroundTransparency=1;Image=p.Image,ImageRectOffset=p.ImageRectOffset,ImageRectSize=p.ImageRectSize;Position=UDim2.new(1,-n,.5,0);Size=UDim2.fromOffset(p.ImageRectSize.X,p.ImageRectSize.Y),ImageColor3=C.Text:map(function(C)return C.Color end);ImageTransparency=C.Text:map(function(C)return C.Transparency end)})local O=b["\102\111\110\116\115\047\066\111\100\121"]local X=r("\084\101\120\116\076\097\098\101\108",{AnchorPoint=Vector2.new(0,.5);BackgroundTransparency=1;FontFace=O.Font;LineHeight=O.LineHeight;Position=UDim2.new(0,n,.5,0),Size=UDim2.new(0,0),Text=U.Text;TextSize=O.Size;TextXAlignment=Enum.TextXAlignment.Left,TextColor3=C.Text:map(function(C)return C.Color end);TextTransparency=C.Text:map(function(C)return C.Transparency end)})local i=r("\070\114\097\109\101",{AnchorPoint=Vector2.new(.5,.5);Position=UDim2.fromScale(.5,.5);Size=UDim2.new(1,-2,1,-2),BackgroundColor3=C.Fill:map(function(C)return C.Color end),BackgroundTransparency=C.Fill:map(function(C)return C.Transparency end)},{Corners=r("\085\073\067\111\114\110\101\114",{CornerRadius=UDim.new(0,b["\115\116\121\108\101\115\047\067\111\114\110\101\114\082\097\100\105\117\115\047\068\101\102\097\117\108\116\047\073\110\110\101\114"])});Stroke=r(W,{BorderMode=Enum.BorderMode.Outline},{Gradient=r("\085\073\071\114\097\100\105\101\110\116",{Rotation=90;Color=C.Stroke:map(function(C)return C.ColorSequence or ColorSequence.new(C.Color)end);Transparency=C.Stroke:map(function(C)return C.TransparencySequence or NumberSequence.new(C.Transparency)end)})})})return r("\073\109\097\103\101\066\117\116\116\111\110",m.Dictionary.join({AnchorPoint=U.AnchorPoint,BackgroundTransparency=1,Size=U.Size,Position=U.Position;LayoutOrder=U.LayoutOrder,[M.Event.Activated]=C[M.Event.Activated];[M.Event.MouseButton1Down]=C[M.Event.MouseButton1Down],[M.Event.MouseButton1Up]=C[M.Event.MouseButton1Up];[M.Event.MouseEnter]=C[M.Event.MouseEnter];[M.Event.MouseLeave]=C[M.Event.MouseLeave]},U.Native),{Label=X,Chevron=w;Fill=i,ChildWrapper=U[M.Children]and r("\070\114\097\109\101",{BackgroundTransparency=1,Size=UDim2.fromScale(1,1),ZIndex=2},U[M.Children])})end)end return A
-- DropdownButton: A button that is meant to be used as the button for dropdown components

local Winro = script.Parent.Parent.Parent.Parent
local Packages = Winro.Parent

local Theme = require(Winro.Theme)
local WithTheme = Theme.WithTheme
local ApplyDescription = Theme.ApplyDescription
local RegisterStateAction = Theme.RegisterStateAction

local Sift = require(Packages.Sift)
local t = require(Packages.t)
local Roact = require(Packages.Roact)
local new = Roact.createElement

local UIStroke = require(Winro.App.Effect.UIStroke)

local DROPDOWNBUTTON_CHEVRONDOWN_IMAGE = 'images/Fluent/ChevronDownMed/12px'
local DROPDOWNBUTTON_COLOR_ANIMATION_SPRING_SETTINGS = 'styles/AnimationSpringParams/Control/Input/Button/Color'
local DROPDOWNBUTTON_TRANSPARENCY_ANIMATION_SPRING_SETTINGS = 'styles/AnimationSpringParams/Control/Input/Button/Transparency'
local DROPDOWNBUTTON_LAYOUT_PADDING = 11
local DROPDOWNBUTTON_PADDING_HORIZONTAL = 11
local DROPDOWNBUTTON_PADDING_VERTICAL = 4

local DropdownRoot = script.Parent
local Descriptions = require(DropdownRoot.Descriptions.DropdownButtonDescriptions)

local DropdownButton = Roact.PureComponent:extend(script.Name)

DropdownButton.Descriptions = Descriptions

DropdownButton.StyleBindings = {
	'Stroke',
	'Fill',
	'Text',
}

DropdownButton.defaultProps = {
	Size = UDim2.fromOffset(120, 32), --- @defaultProp
}

DropdownButton.validateProps = t.strictInterface({

	--- @prop @optional Text string The DropdownButton's text
	Text = t.optional(t.string),

	--- @prop @optional AnchorPoint Vector2 The DropdownButton's anchor point
	AnchorPoint = t.optional(t.Vector2),

	--- @prop @optional Disabled boolean Determines if the DropdownButton is shown as disabled
	Disabled = t.optional(t.boolean),

	--- @prop @optional LayoutOrder number The DropdownButton's Layout order
	LayoutOrder = t.optional(t.number),

	--- @prop @optional Position UDim2 The DropdownButton's position
	Position = t.optional(t.UDim2),

	--- @prop @optional Size UDim2 The DropdownButton's size
	Size = t.optional(t.UDim2),

	--- @prop @optional Native table Native props
	Native = t.optional(t.table),

	--- @prop @optional [Roact.Children] table Roact.Children
	[Roact.Children] = t.optional(t.table),

	--- @prop @optional [Roact.Event.Activated] function Roact.Event.Activated
	[Roact.Event.Activated] = t.optional(t.callback),

	--- @prop @optional [Roact.Event.MouseButton1Down] function Roact.Event.MouseButton1Down
	[Roact.Event.MouseButton1Down] = t.optional(t.callback),

	--- @prop @optional [Roact.Event.MouseButton1Up] function Roact.Event.MouseButton1Up
	[Roact.Event.MouseButton1Up] = t.optional(t.callback),

	--- @prop @optional [Roact.Event.MouseEnter] function Roact.Event.MouseEnter
	[Roact.Event.MouseEnter] = t.optional(t.callback),

	--- @prop @optional [Roact.Event.MouseLeave] function Roact.Event.MouseLeave
	[Roact.Event.MouseLeave] = t.optional(t.callback),
})

function DropdownButton:init()

	-- Create Style Bindings
	for _, StyleBinding in pairs(self.StyleBindings) do
		self[StyleBinding], self['Set' .. StyleBinding] = Roact.createBinding({})
	end

	-- Actions
	RegisterStateAction(self, Roact.Event.Activated, nil)
	RegisterStateAction(self, Roact.Event.MouseButton1Down, 'Pressed')
	RegisterStateAction(self, Roact.Event.MouseButton1Up, 'Hover')
	RegisterStateAction(self, Roact.Event.MouseEnter, 'Hover')
	RegisterStateAction(self, Roact.Event.MouseLeave, 'Rest')

	-- Initial State
	self:setState({
		State = 'Rest',
	})
end

function DropdownButton:ApplyDescription(Description, Theme)
	ApplyDescription(self, Description, Theme, Theme[DROPDOWNBUTTON_COLOR_ANIMATION_SPRING_SETTINGS], Theme[DROPDOWNBUTTON_TRANSPARENCY_ANIMATION_SPRING_SETTINGS])
end

function DropdownButton:render()
	local props = self.props
	local state = self.state

	return WithTheme(function(Theme)

		-- Apply description
		if props.Disabled then
			self:ApplyDescription(self.Descriptions.Disabled, Theme)
		elseif state.State == 'Rest' then
			self:ApplyDescription(self.Descriptions.Rest, Theme)
		elseif state.State == 'Hover' then
			self:ApplyDescription(self.Descriptions.Hover, Theme)
		elseif state.State == 'Pressed' then
			self:ApplyDescription(self.Descriptions.Pressed, Theme)
		end

		-- ////////// Chevron Icon
		
		local ChevronImageIcon = Theme[DROPDOWNBUTTON_CHEVRONDOWN_IMAGE]

		local Chevron = new('ImageButton', {
			AnchorPoint = Vector2.new(1, 0.5),
			BackgroundTransparency = 1,
			Image = ChevronImageIcon.Image,
			ImageRectOffset = ChevronImageIcon.ImageRectOffset,
			ImageRectSize = ChevronImageIcon.ImageRectSize,
			Position = UDim2.new(1, -DROPDOWNBUTTON_PADDING_HORIZONTAL, 0.5, 0),
			Size = UDim2.fromOffset(ChevronImageIcon.ImageRectSize.X, ChevronImageIcon.ImageRectSize.Y),

			ImageColor3 = self.Text:map(function(Style)
				return Style.Color
			end),
			ImageTransparency = self.Text:map(function(Style)
				return Style.Transparency
			end),
		})

		-- ////////// Button Label

		local LabelFontStyle = Theme['fonts/Body']

		local Label = new('TextLabel', {
			AnchorPoint = Vector2.new(0, 0.5),
			BackgroundTransparency = 1,
			FontFace = LabelFontStyle.Font,
			LineHeight = LabelFontStyle.LineHeight,
			Position = UDim2.new(0, DROPDOWNBUTTON_PADDING_HORIZONTAL, 0.5, 0),
			Size = UDim2.new(0, 0),
			Text = props.Text,
			TextSize = LabelFontStyle.Size,
			TextXAlignment = Enum.TextXAlignment.Left,

			TextColor3 = self.Text:map(function(Style)
				return Style.Color
			end),
			TextTransparency = self.Text:map(function(Style)
				return Style.Transparency
			end)
		})

		-- ////////// Button Fill

		local Fill = new('Frame', {
			AnchorPoint = Vector2.new(0.5, 0.5),
			Position = UDim2.fromScale(0.5, 0.5),
			Size = UDim2.new(1, -2, 1, -2), -- Account for stroke thickness

			BackgroundColor3 = self.Fill:map(function(Style)
				return Style.Color
			end),
			BackgroundTransparency = self.Fill:map(function(Style)
				return Style.Transparency
			end),
		}, {

			Corners = new('UICorner', {
				CornerRadius = UDim.new(0, Theme['styles/CornerRadius/Default/Inner']),
			}),
			Stroke = new(UIStroke, {
				BorderMode = Enum.BorderMode.Outline,
			}, {

				Gradient = new('UIGradient', {
					Rotation = 90,

					Color = self.Stroke:map(function(Style)
						return Style.ColorSequence or ColorSequence.new(Style.Color)
					end),
					Transparency = self.Stroke:map(function(Style)
						return Style.TransparencySequence or NumberSequence.new(Style.Transparency)
					end),
				}),
			}),
		})

		-- ////////// Dropdown Button
		return new('ImageButton', Sift.Dictionary.join({
			AnchorPoint = props.AnchorPoint,
			BackgroundTransparency = 1,
			Size = props.Size,
			Position = props.Position,
			LayoutOrder = props.LayoutOrder,

			[Roact.Event.Activated] = self[Roact.Event.Activated],
			[Roact.Event.MouseButton1Down] = self[Roact.Event.MouseButton1Down],
			[Roact.Event.MouseButton1Up] = self[Roact.Event.MouseButton1Up],
			[Roact.Event.MouseEnter] = self[Roact.Event.MouseEnter],
			[Roact.Event.MouseLeave] = self[Roact.Event.MouseLeave],
		}, props.Native), {
			Label = Label,
			Chevron = Chevron,
			Fill = Fill,

			ChildWrapper = props[Roact.Children] and new('Frame', {
				BackgroundTransparency = 1,
				Size = UDim2.fromScale(1, 1),
				ZIndex = 2,
			}, props[Roact.Children])
		})
	end)
end

return DropdownButton
