local h=game:GetService("\084\101\120\116\083\101\114\118\105\099\101")local function f(f,j,H,B)return(h:GetTextSize(f,j,H,Vector2.new(B,10000))).Y+2 end local function j(f,j,H)return(h:GetTextSize(f,j,H,Vector2.new(10000,10000))).X+2 end local H=Roact.PureComponent:extend("\070\105\116\084\101\120\116\076\097\098\101\108")H.Width={FitToText={}}H.defaultProps={Font=Enum.Font.SourceSans;Text="\076\097\098\101\108";TextSize=12;TextWrapped=true;maximumWidth=math.huge}function H.init(h)h.frameRef=Roact.createRef()h.onResize=function()if not h.frameRef.current then return end h.frameRef.current.Size=h:__getSize(h.frameRef.current)end end function H.render(h)return Roact.createElement("\084\101\120\116\076\097\098\101\108",h:__getFilteredProps())end function H.didMount(h)h.onResize()end function H.didUpdate(h)h.onResize()end function H.__getFilteredProps(h)local f={width=Cryo.None,maximumWidth=Cryo.None,Size=UDim2.new(h.props.width,UDim.new(0,0));[Roact.Ref]=h.frameRef;[Roact.Children]=Cryo.Dictionary.join(h.props[Roact.Children]or{},{sizeConstraint=h.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(h.props.maximumWidth,math.huge)})})}return Cryo.Dictionary.join(h.props,f)end function H.__getSize(B,h)local u=B.props.maximumWidth local F=B.props.width if F==H.Width.FitToText then local h=j(B.props.Text,B.props.TextSize,B.props.Font)F=UDim.new(0,math.min(h,u))end local d=math.max(u<math.huge and u or 0,h.AbsoluteSize.X)local V=f(B.props.Text,B.props.TextSize,B.props.Font,d)return UDim2.new(F,UDim.new(0,V))end return H
-- We need to add 2 to these values as a workaround to a documented engine bug
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
