This commit is contained in:
lx
2026-07-06 14:01:11 -04:00
commit c4f97d729d
16468 changed files with 935321 additions and 0 deletions
@@ -0,0 +1,12 @@
--[[
Package link auto-generated by Rotriever
]]
local PackageIndex = script.Parent.Parent
local package = PackageIndex["roblox_cryo"]["cryo"]
if package.ClassName == "ModuleScript" then
return require(package)
end
return package
@@ -0,0 +1,12 @@
--[[
Package link auto-generated by Rotriever
]]
local PackageIndex = script.Parent.Parent
local package = PackageIndex["roblox_roact"]["roact"]
if package.ClassName == "ModuleScript" then
return require(package)
end
return package
@@ -0,0 +1,9 @@
# Generated by Rotriever. Format subject to change in future releases.
name = "roblox/roact-fit-components"
version = "1.2.5"
commit = "b784928fdef64215d38e2febae28412a3b2a520b"
source = "url+https://github.com/roblox/roact-fit-components"
dependencies = [
"Cryo roblox/cryo 1.0.0 url+https://github.com/roblox/cryo",
"Roact roblox/roact 1.3.1 url+https://github.com/roblox/roact",
]
@@ -0,0 +1,21 @@
local root = script.Parent
local Packages = root.Parent
local Cryo = require(Packages.Cryo)
local Roact = require(Packages.Roact)
local FitFrameOnAxis = require(script.Parent.FitFrameOnAxis)
return function(props)
props = props or {}
local height = props.height
local filteredProps = Cryo.Dictionary.join(props, {
axis = FitFrameOnAxis.Axis.Horizontal,
minimumSize = UDim2.new(UDim.new(0, 0), height),
height = Cryo.None,
})
return Roact.createElement(FitFrameOnAxis, filteredProps)
end
@@ -0,0 +1,182 @@
local root = script.Parent
local Packages = root.Parent
local Cryo = require(Packages.Cryo)
local Roact = require(Packages.Roact)
local Rect = require(root.Rect)
local FitFrameOnAxis = Roact.PureComponent:extend("FitFrameOnAxis")
FitFrameOnAxis.Axis = {
Horizontal = {},
Vertical = {},
Both = {},
}
FitFrameOnAxis.defaultProps = {
axis = FitFrameOnAxis.Axis.Vertical,
minimumSize = UDim2.new(UDim.new(0, 0), UDim.new(0, 0)),
margin = Rect.square(0),
FillDirection = Enum.FillDirection.Vertical,
HorizontalAlignment = Enum.HorizontalAlignment.Left,
ImageSet = {},
VerticalAlignment = Enum.VerticalAlignment.Top,
contentPadding = UDim.new(0, 0),
textProps = nil,
}
function FitFrameOnAxis:init()
self.layoutRef = Roact.createRef()
self.frameRef = self.props[Roact.Ref] or Roact.createRef()
self.onResize = function()
local currentLayout = self.layoutRef.current
local currentFrame = self.frameRef.current
if not currentFrame or not currentLayout then
return
end
currentFrame.Size = self:__getSize(currentLayout)
end
end
function FitFrameOnAxis:render()
assert(self.props.Size == nil, "Size is not a valid property of FitFrameOnAxis. Did you mean `minimumSize`?")
local children = self.props[Roact.Children] or {}
local filteredProps = self:__getFilteredProps()
local instanceType = self.props.onActivated and "ImageButton" or "ImageLabel"
children = Cryo.Dictionary.join(children, {
["$layout"] = Roact.createElement("UIListLayout", {
FillDirection = self.props.FillDirection,
HorizontalAlignment = self.props.HorizontalAlignment,
Padding = self.props.contentPadding,
SortOrder = Enum.SortOrder.LayoutOrder,
VerticalAlignment = self.props.VerticalAlignment,
[Roact.Change.AbsoluteContentSize] = self.onResize,
[Roact.Ref] = self.layoutRef,
}),
["$margin"] = Roact.createElement("UIPadding", {
PaddingLeft = UDim.new(0, self.props.margin.left),
PaddingRight = UDim.new(0, self.props.margin.right),
PaddingTop = UDim.new(0, self.props.margin.top),
PaddingBottom = UDim.new(0, self.props.margin.bottom),
}),
})
if self.props.textProps then
return Roact.createElement(instanceType, filteredProps, {
TextLabel = Roact.createElement("TextLabel", Cryo.Dictionary.join(self.props.textProps, {
BackgroundTransparency = 1,
Size = UDim2.fromScale(1, 1),
})),
ChildFrame = Roact.createElement("Frame", {
BackgroundTransparency = 1,
Size = UDim2.fromScale(1, 1),
}, children),
})
else
return Roact.createElement(instanceType, filteredProps, children)
end
end
function FitFrameOnAxis:didMount()
self.onResize()
end
function FitFrameOnAxis:didUpdate()
self.onResize()
end
function FitFrameOnAxis:__getFilteredProps()
-- Will return a new prop map after removing
-- Roact.Children and any defaultProps in an effort
-- to only return safe Roblox Instance "ImageLabel"
-- properties that may be present.
local filteredProps = Cryo.Dictionary.join(self.props.ImageSet, {
[Roact.Ref] = self.frameRef,
[Roact.Event.Activated] = self.props.onActivated,
})
for property, _ in pairs(FitFrameOnAxis.defaultProps) do
filteredProps[property] = Cryo.None
end
filteredProps.textProps = Cryo.None
return Cryo.Dictionary.join(self.props, filteredProps, {
onActivated = Cryo.None,
[Roact.Children] = Cryo.None,
})
end
function FitFrameOnAxis:__getSize(currentLayout)
if self.props.axis == FitFrameOnAxis.Axis.Both then
return self:__getBothAxisSize(currentLayout)
else
-- Arrangement of UDims are flip-flopped based
-- on which axis is our primary axis
local axisUDim = self:__getAxisUDim(currentLayout.AbsoluteContentSize)
local otherUDim = self:__getOtherUDim()
if self.props.axis == FitFrameOnAxis.Axis.Vertical then
return UDim2.new(otherUDim, axisUDim)
elseif self.props.axis == FitFrameOnAxis.Axis.Horizontal then
return UDim2.new(axisUDim, otherUDim)
end
end
end
function FitFrameOnAxis:__getBothAxisSize(currentLayout)
local minimumSize = self.props.minimumSize
local absoluteContentSize = currentLayout.AbsoluteContentSize
local xAxis = UDim.new(minimumSize.X.Scale, absoluteContentSize.X + self:__getHorizontalMargin())
local yAxis = UDim.new(minimumSize.Y.Scale, absoluteContentSize.Y + self:__getVerticalMargin())
return UDim2.new(xAxis, yAxis)
end
function FitFrameOnAxis:__getAxisUDim(vector2)
-- Merges minimumSize with given Vector2
-- to create UDim for primary axis
local minimumSize = self.props.minimumSize
local targetUDim
local lengthOfChildren
if self.props.axis == FitFrameOnAxis.Axis.Vertical then
targetUDim = minimumSize.Y
lengthOfChildren = vector2.Y + self:__getVerticalMargin()
elseif self.props.axis == FitFrameOnAxis.Axis.Horizontal then
targetUDim = minimumSize.X
lengthOfChildren = vector2.X + self:__getHorizontalMargin()
end
return UDim.new(targetUDim.Scale, math.max(lengthOfChildren, targetUDim.Offset))
end
function FitFrameOnAxis:__getVerticalMargin()
return self.props.margin.top + self.props.margin.bottom
end
function FitFrameOnAxis:__getHorizontalMargin()
return self.props.margin.left + self.props.margin.right
end
function FitFrameOnAxis:__getOtherUDim()
-- Since there is no primary axis to merge with,
-- this UDim is entirely represented by minimumSize
local minimumSize = self.props.minimumSize
if self.props.axis == FitFrameOnAxis.Axis.Vertical then
return minimumSize.X
elseif self.props.axis == FitFrameOnAxis.Axis.Horizontal then
return minimumSize.Y
end
end
return FitFrameOnAxis
@@ -0,0 +1,21 @@
local root = script.Parent
local Packages = root.Parent
local Cryo = require(Packages.Cryo)
local Roact = require(Packages.Roact)
local FitFrameOnAxis = require(script.Parent.FitFrameOnAxis)
return function(props)
props = props or {}
local width = props.width
local filteredProps = Cryo.Dictionary.join(props, {
axis = FitFrameOnAxis.Axis.Vertical,
minimumSize = UDim2.new(width, UDim.new(0, 0)),
width = Cryo.None,
})
return Roact.createElement(FitFrameOnAxis, filteredProps)
end
@@ -0,0 +1,120 @@
local root = script.Parent
local Packages = root.Parent
local Cryo = require(Packages.Cryo)
local Roact = require(Packages.Roact)
local EngineFeatureTextBoundsRoundUp do
local success, value = pcall(function()
return game:GetEngineFeature("TextBoundsRoundUp")
end)
EngineFeatureTextBoundsRoundUp = success and value
end
-- 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)
if EngineFeatureTextBoundsRoundUp then
return TextService:GetTextSize(text, fontSize, font, Vector2.new(widthCap, 10000)).Y
else
return TextService:GetTextSize(text, fontSize, font, Vector2.new(widthCap, 10000)).Y + 2
end
end
local function getTextWidth(text, fontSize, font)
if EngineFeatureTextBoundsRoundUp then
return TextService:GetTextSize(text, fontSize, font, Vector2.new(10000, 10000)).X
else
return TextService:GetTextSize(text, fontSize, font, Vector2.new(10000, 10000)).X + 2
end
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()
local instanceType = self.props.onActivated and "TextButton" or "TextLabel"
return Roact.createElement(instanceType, 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,
onActivated = 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),
})
}),
[Roact.Event.Activated] = self.props.onActivated,
[Roact.Change.AbsoluteSize] = function(rbx)
if self.props[Roact.Change.AbsoluteSize] then
self.props[Roact.Change.AbsoluteSize](rbx)
end
self.onResize()
end,
}
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
@@ -0,0 +1,26 @@
return {
rectangle = function(horizontal, vertical)
return {
top = vertical,
bottom = vertical,
left = horizontal,
right = horizontal,
}
end,
square = function(x)
return {
top = x,
bottom = x,
left = x,
right = x,
}
end,
quad = function(top, right, bottom, left)
return {
top = top,
bottom = bottom,
left = left,
right = right,
}
end,
}
@@ -0,0 +1,7 @@
return {
FitFrameHorizontal = require(script.FitFrameHorizontal),
FitFrameOnAxis = require(script.FitFrameOnAxis),
FitFrameVertical = require(script.FitFrameVertical),
FitTextLabel = require(script.FitTextLabel),
Rect = require(script.Rect),
}