local t=game:GetService("\084\101\120\116\083\101\114\118\105\099\101")local function f(f,h,x,g)return(t:GetTextSize(f,h,x,Vector2.new(g,10000))).Y+2 end local function h(f,h,x)return(t:GetTextSize(f,h,x,Vector2.new(10000,10000))).X+2 end local x=Roact.PureComponent:extend("\070\105\116\084\101\120\116\076\097\098\101\108")x.Width={FitToText={}}x.defaultProps={Font=Enum.Font.SourceSans,Text="\076\097\098\101\108",TextSize=12,TextWrapped=true,maximumWidth=math.huge}function x.init(t)t.frameRef=Roact.createRef()t.onResize=function()if not t.frameRef.current then return end t.frameRef.current.Size=t:__getSize(t.frameRef.current)end end function x.render(t)return Roact.createElement("\084\101\120\116\076\097\098\101\108",t:__getFilteredProps())end function x.didMount(t)t.onResize()end function x.didUpdate(t)t.onResize()end function x.__getFilteredProps(t)local f={width=Cryo.None;maximumWidth=Cryo.None,Size=UDim2.new(t.props.width,UDim.new(0,0)),[Roact.Ref]=t.frameRef;[Roact.Children]=Cryo.Dictionary.join(t.props[Roact.Children]or{},{sizeConstraint=t.props.maximumWidth<math.huge and Roact.createElement("\085\073\083\105\122\101\067\111\110\115\116\114\097\105\110\116",{MaxSize=Vector2.new(t.props.maximumWidth,math.huge)})})}return Cryo.Dictionary.join(t.props,f)end function x.__getSize(g,t)local W=g.props.maximumWidth local a=g.props.width if a==x.Width.FitToText then local t=h(g.props.Text,g.props.TextSize,g.props.Font)a=UDim.new(0,math.min(t,W))end local U=math.max(W<math.huge and W or 0,t.AbsoluteSize.X)local T=f(g.props.Text,g.props.TextSize,g.props.Font,U)return UDim2.new(a,UDim.new(0,T))end return x

local TextService = game:GetService("TextService")
local function getTextHeight(text, fontSize, font, widthCap)
	return TextService:GetTextSize(text, fontSize, font, Vector2.new(widthCap, 10000)).Y + 2
end

local function getTextWidth(text, fontSize, font)
	return TextService:GetTextSize(text, fontSize, font, Vector2.new(10000, 10000)).X + 2
end

local FitTextLabel = Roact.PureComponent:extend("FitTextLabel")
FitTextLabel.Width = {
	FitToText = {},
}
FitTextLabel.defaultProps = {
	Font = Enum.Font.SourceSans,
	Text = "Label",
	TextSize = 12,
	TextWrapped = true,

	maximumWidth = math.huge,
}

function FitTextLabel:init()
	self.frameRef = Roact.createRef()

	self.onResize = function()
		if not self.frameRef.current then
			return
		end

		self.frameRef.current.Size = self:__getSize(self.frameRef.current)
	end
end

function FitTextLabel:render()
	return Roact.createElement("TextLabel", self:__getFilteredProps())
end

function FitTextLabel:didMount()
	self.onResize()
end

function FitTextLabel:didUpdate()
	self.onResize()
end

function FitTextLabel:__getFilteredProps()
	-- Will return a new prop map after removing
	-- Roact.Children and any defaultProps in an effort
	-- to only return safe Roblox Instance "TextLabel"
	-- properties that may be present.
	local filteredProps = {
		width = Cryo.None,
		maximumWidth = Cryo.None,
		Size = UDim2.new(self.props.width, UDim.new(0, 0)),
		[Roact.Ref] = self.frameRef,

		[Roact.Children] = Cryo.Dictionary.join(self.props[Roact.Children] or {}, {
			sizeConstraint = self.props.maximumWidth < math.huge and Roact.createElement("UISizeConstraint", {
				MaxSize = Vector2.new(self.props.maximumWidth, math.huge),
			})
		})
	}

	return Cryo.Dictionary.join(self.props, filteredProps)
end

function FitTextLabel:__getSize(rbx)
	local maximumWidth = self.props.maximumWidth
	local width = self.props.width
	if width == FitTextLabel.Width.FitToText then
		local textWidth = getTextWidth(self.props.Text, self.props.TextSize, self.props.Font)
		width = UDim.new(0, math.min(textWidth, maximumWidth))
	end

	local widthCap = math.max(maximumWidth < math.huge and maximumWidth or 0, rbx.AbsoluteSize.X)
	local textHeight = getTextHeight(
		self.props.Text,
		self.props.TextSize,
		self.props.Font,
		widthCap
	)

	return UDim2.new(width, UDim.new(0, textHeight))
end

return FitTextLabel
