local C=script.Parent.Parent.Parent local U=C.Parent local Z=require(C.Theme)local b=Z.WithTheme local p=C.Validators local w=require(p.StyleValidator)local m=require(U.t)local O=require(U.Roact)local M=O.createElement local r=require(C.App.List.ListDivider)local W=require(C.App.List.ListItem)local V=require(C.App.Surface.Acrylic)local X="\099\111\108\111\114\115\047\066\097\099\107\103\114\111\117\110\100\047\070\105\108\108\095\067\111\108\111\114\047\065\099\114\121\108\105\099\095\066\097\099\107\103\114\111\117\110\100\047\068\101\102\097\117\108\116"local i="\099\111\108\111\114\115\047\083\116\114\111\107\101\095\067\111\108\111\114\047\083\117\114\102\097\099\101\095\083\116\114\111\107\101\047\070\108\121\111\117\116"local l=O.PureComponent:extend(script.Name)l.defaultProps={AnchorPoint=Vector2.new();Position=UDim2.new();Size=UDim2.fromOffset(150,150),FitContents=true}l.validateProps=m.strictInterface({AnchorPoint=m.optional(m.Vector2);BackgroundTransparency=m.optional(m.number),Position=m.optional(m.UDim2),Size=m.optional(m.UDim2);UseIcon=m.optional(m.boolean),FitContents=m.optional(m.boolean),Options=m.array(m.strictInterface({Disabled=m.optional(m.boolean);IsDivider=m.optional(m.boolean);LayoutOrder=m.optional(m.numberPositive);OnClicked=m.optional(m.callback),Selected=m.optional(m.boolean),Text=m.optional(m.string),Icon=m.optional(w)}))})function l.init(C)C.ContentSize,C.SetContentSize=O.createBinding(C.props.Size)end function l.GetOptions(C)local U=C.props local Z={}for C,b in pairs(U.Options)do if b.IsDivider then Z[C]=M(r,{LayoutOrder=b.LayoutOrder or C;Size=UDim2.fromScale(1,0)})else Z[C]=M(W,{ShowIndicator=b.Selected,Disabled=b.Disabled,LayoutOrder=b.LayoutOrder or C;[O.Event.Activated]=b.OnClicked;Selected=b.Selected,Width=UDim.new(1,0);Text=b.Text,Icon=U.UseIcon and(b.Icon or{Image="";ImageRectSize=Vector2.new();ImageRectOffset=Vector2.new()})or nil})end end return O.createFragment(Z)end function l.render(C)local U=C.props return b(function(Z)local b=M("\070\114\097\109\101",{AutomaticSize=U.FitContents and"\089"or"\078\111\110\101",BackgroundTransparency=1,Position=UDim2.fromOffset(0,2);Size=UDim2.fromScale(1,U.FitContents and 0 or 1);[O.Change.AbsoluteSize]=function(Z)if U.FitContents then C.SetContentSize(UDim2.fromOffset(Z.AbsoluteSize.X,Z.AbsoluteSize.Y+4))end end},{Layout=M("\085\073\076\105\115\116\076\097\121\111\117\116",{SortOrder=Enum.SortOrder.LayoutOrder;FillDirection=Enum.FillDirection.Vertical;HorizontalAlignment=Enum.HorizontalAlignment.Center;VerticalAlignment=Enum.VerticalAlignment.Bottom}),Contents=C:GetOptions()})local p=Z[X]local w=Z[i]local m=M(V,{BackgroundColor3=p.Color,BackgroundTransparency=U.BackgroundTransparency or p.Transparency;BorderSizePixel=0;Size=C.ContentSize},{Corners=M("\085\073\067\111\114\110\101\114",{CornerRadius=UDim.new(0,Z["\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\079\117\116\101\114"]-1)}),Stroke=M("\085\073\083\116\114\111\107\101",{Color=w.Color;Transparency=w.Transparency;Thickness=1})})return M("\070\114\097\109\101",{AutomaticSize=U.FitContents and"\089"or"\078\111\110\101",AnchorPoint=U.AnchorPoint,BackgroundTransparency=1;Position=U.Position,Size=C.ContentSize},{Container=b,Base=m})end)end return l
-- ContextMenu: A Context menu element

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

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

local Validators = Winro.Validators
local StyleValidator = require(Validators.StyleValidator)

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

local ListDivider = require(Winro.App.List.ListDivider)
local ListItem = require(Winro.App.List.ListItem)

local Acrylic = require(Winro.App.Surface.Acrylic)

local CONTEXTMENU_BACKGROUND_STYLE = "colors/Background/Fill_Color/Acrylic_Background/Default"
local CONTEXTMENU_BORDER_STYLE = "colors/Stroke_Color/Surface_Stroke/Flyout"

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

ContextMenu.defaultProps = {
	AnchorPoint = Vector2.new(), --- @defaultProp
	Position = UDim2.new(), --- @defaultProp
	Size = UDim2.fromOffset(150, 150), --- @defaultProp
	FitContents = true, --- @defaultProp
}

ContextMenu.validateProps = t.strictInterface({

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

	--- @prop @optional BackgroundTransparency number Background Transparency
	BackgroundTransparency = t.optional(t.number),

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

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

	--- @prop @optional UseIcon boolean Determines the visibility of an icon on each option
	UseIcon = t.optional(t.boolean),

	--- @prop @optional FitContents boolean Determines if the Context Menu will resize to fit it's contents
	FitContents = t.optional(t.boolean),

	--- @prop Options array The options to display
	Options = t.array(t.strictInterface({
		Disabled = t.optional(t.boolean),
		IsDivider = t.optional(t.boolean),
		LayoutOrder = t.optional(t.numberPositive),
		OnClicked = t.optional(t.callback),
		Selected = t.optional(t.boolean),
		Text = t.optional(t.string),
		Icon = t.optional(StyleValidator)
	}))
})

function ContextMenu:init()

	-- Content size binding
	self.ContentSize, self.SetContentSize = Roact.createBinding(self.props.Size)
end

function ContextMenu:GetOptions()
	local props = self.props

	-- Create a list of all options to display
	local Children = {}

	-- Go through each option, creating it
	for LayoutOrder, OptionProps in pairs(props.Options) do

		-- Create divider, if set
		if OptionProps.IsDivider then
			Children[LayoutOrder] = new(ListDivider, {
				LayoutOrder = OptionProps.LayoutOrder or LayoutOrder,
				Size = UDim2.fromScale(1, 0)
			})

		-- Create list items
		else
			Children[LayoutOrder] = new(ListItem, {
				ShowIndicator = OptionProps.Selected,
				Disabled = OptionProps.Disabled,
				LayoutOrder = OptionProps.LayoutOrder or LayoutOrder,
				[Roact.Event.Activated] = OptionProps.OnClicked,
				Selected = OptionProps.Selected,
				Width = UDim.new(1, 0),
				Text = OptionProps.Text,
				Icon = props.UseIcon and (OptionProps.Icon or {
					Image = '',
					ImageRectSize = Vector2.new(),
					ImageRectOffset = Vector2.new()
				}) or nil
			})
		end
	end

	return Roact.createFragment(Children)
end

function ContextMenu:render()
	local props = self.props

	return WithTheme(function(Theme)

		-- Create a list items container
		local Container = new('Frame', {
			AutomaticSize = props.FitContents and 'Y' or 'None',
			BackgroundTransparency = 1,
			Position = UDim2.fromOffset(0, 2),
			Size = UDim2.fromScale(1, props.FitContents and 0 or 1),

			[Roact.Change.AbsoluteSize] = function(rbx)
				if props.FitContents then
					self.SetContentSize(UDim2.fromOffset(rbx.AbsoluteSize.X, rbx.AbsoluteSize.Y + 2 * 2)) -- Accont for Vertical padding
				end
			end
		}, {

			Layout = new('UIListLayout', {
				SortOrder = Enum.SortOrder.LayoutOrder,
				FillDirection = Enum.FillDirection.Vertical,
				HorizontalAlignment = Enum.HorizontalAlignment.Center,
				VerticalAlignment = Enum.VerticalAlignment.Bottom
			}),

			Contents = self:GetOptions()
		})

		local BaseStyle = Theme[CONTEXTMENU_BACKGROUND_STYLE]
		local StrokeStyle = Theme[CONTEXTMENU_BORDER_STYLE]

		local Base = new(Acrylic, {
			BackgroundColor3 = BaseStyle.Color,
			BackgroundTransparency = props.BackgroundTransparency or BaseStyle.Transparency,
			BorderSizePixel = 0,
			Size = self.ContentSize,
		}, {

			Corners = new('UICorner', {
				CornerRadius = UDim.new(0, Theme['styles/CornerRadius/Default/Outer'] - 1), -- -1px to account for stroke
			}),

			Stroke = new('UIStroke', {
				Color = StrokeStyle.Color,
				Transparency = StrokeStyle.Transparency,
				Thickness = 1
			}),
		})

		return new('Frame', {
			AutomaticSize = props.FitContents and 'Y' or 'None',
			AnchorPoint = props.AnchorPoint,
			BackgroundTransparency = 1,
			Position = props.Position,
			Size = self.ContentSize
		}, {
			Container = Container,
			Base = Base,
		})
	end)
end

return ContextMenu
