-- Compiled with roblox-ts v1.2.7 local TS = _G[script] local Maid = TS.import(script, TS.getModule(script, "@rbxts", "maid").Maid) local Roact = TS.import(script, TS.getModule(script, "@rbxts", "roact").src) local ThemeContext = TS.import(script, script.Parent.Parent, "UIKit", "ThemeContext").default local delayAsync = TS.import(script, script.Parent.Parent, "BuiltInConsole", "DelayAsync").default local ZirconIcon = TS.import(script, script.Parent, "Icon").default local _Padding = TS.import(script, script.Parent, "Padding") local CalculatePadding = _Padding.CalculatePadding local CalculatePaddingUDim2 = _Padding.CalculatePaddingUDim2 local ScrollView do ScrollView = Roact.Component:extend("ScrollView") function ScrollView:init(props) self.initScrollToBottom = false self.invokeUpdate = function() local size = self.scrollListLayout.AbsoluteContentSize if self.props.ContentSizeChanged ~= nil then local canvasSize = self.scrollFrame.AbsoluteSize local contentSize = Vector2.new(canvasSize.X - 20, size.Y) self.props.ContentSizeChanged(contentSize, self) end end self.canvasPositionUpdated = function() local canvasPosition = self.scrollFrame.CanvasPosition local _condition = self.props.Padding if _condition == nil then _condition = {} end local padding = CalculatePadding(_condition) local _result = padding.PaddingBottom if _result ~= nil then _result = _result.Offset end local _condition_1 = _result if _condition_1 == nil then _condition_1 = 0 end local paddingBottomOffset = _condition_1 local _result_1 = padding.PaddingTop if _result_1 ~= nil then _result_1 = _result_1.Offset end local _condition_2 = _result_1 if _condition_2 == nil then _condition_2 = 0 end local paddingTopOffset = _condition_2 local _absoluteContentSize = self.scrollListLayout.AbsoluteContentSize local _vector2 = Vector2.new(0, paddingBottomOffset + paddingTopOffset) local size = _absoluteContentSize + _vector2 self:setState({ barPos = canvasPosition.Y / (size.Y - self.scrollFrame.AbsoluteSize.Y), }) self.initScrollToBottom = false local _ = self.props.CanvasPositionChanged ~= nil and self.props.CanvasPositionChanged(canvasPosition, self) end self.absoluteContentSizeChanged = function() local _binding = self.props local AutoScrollToEndThreshold = _binding.AutoScrollToEndThreshold if AutoScrollToEndThreshold == nil then AutoScrollToEndThreshold = 0.8 end local AutoScrollToEnd = _binding.AutoScrollToEnd local _condition = self.props.Padding if _condition == nil then _condition = {} end local padding = CalculatePadding(_condition) local _result = padding.PaddingBottom if _result ~= nil then _result = _result.Offset end local _condition_1 = _result if _condition_1 == nil then _condition_1 = 0 end local paddingBottomOffset = _condition_1 local _result_1 = padding.PaddingTop if _result_1 ~= nil then _result_1 = _result_1.Offset end local _condition_2 = _result_1 if _condition_2 == nil then _condition_2 = 0 end local paddingTopOffset = _condition_2 local _absoluteContentSize = self.scrollListLayout.AbsoluteContentSize local _vector2 = Vector2.new(0, paddingBottomOffset + paddingTopOffset) local size = _absoluteContentSize + _vector2 self:setState({ size = size, }) local scale = self.scrollFrame.AbsoluteSize.Y / size.Y local canvasPosition = self.scrollFrame.CanvasPosition local canvasSize = self.scrollFrame.AbsoluteSize local canvasAbsoluteSize = self.scrollListLayout.AbsoluteContentSize self:setState({ barScale = scale, barShown = scale < 1, barPos = canvasPosition.Y / (size.Y - canvasSize.Y), }) if self.props.ContentSizeChanged ~= nil then local contentSize = Vector2.new(canvasSize.X - 20, size.Y) self.props.ContentSizeChanged(contentSize, self) end local calculatedSize = canvasAbsoluteSize.Y - self.scrollFrame.AbsoluteWindowSize.Y + paddingBottomOffset if AutoScrollToEnd and (canvasPosition.Y / calculatedSize >= AutoScrollToEndThreshold or self.initScrollToBottom) then self:scrollToEnd() end end self.state = { size = Vector2.new(), barScale = 1, barPos = 0, barShown = false, loaded = false, } self.maid = Maid.new() end function ScrollView:didMount() local _binding = self.props local AutoScrollToEnd = _binding.AutoScrollToEnd if AutoScrollToEnd then self.initScrollToBottom = true end if self.scrollFrame == nil then warn("Missing ScrollFrame to ScrollView") return nil end if self.scrollListLayout == nil then warn("Missing UIListLayout to ScrollView") return nil end local size = self.scrollListLayout.AbsoluteContentSize -- Have to wait a frame because of ROBLOX's quirkiness. local _exp = delayAsync() local _arg0 = function() return self.absoluteContentSizeChanged() end _exp:andThen(_arg0) self:setState({ size = size, }) if self.props.ViewRef then self.props.ViewRef(self) end end function ScrollView:willUnmount() self.maid:DoCleaning() end function ScrollView:renderBar() if self.state.barShown then return Roact.createElement(ThemeContext.Consumer, { render = function(theme) local scale = self.state.barScale local _attributes = { BorderSizePixel = 0, BackgroundTransparency = 0, BackgroundColor3 = theme.SecondaryBackgroundColor3, Size = UDim2.new(1, 0, self.state.barScale, 0), Position = UDim2.new(0, 0, self.state.barPos * (1 - self.state.barScale), 0), } local _children = {} local _length = #_children local _child = scale >= 0.1 and Roact.createElement(ZirconIcon, { Icon = "UpArrow", Position = UDim2.fromOffset(2, 0), }) if _child then if _child.elements ~= nil or _child.props ~= nil and _child.component ~= nil then _children[_length + 1] = _child else for _k, _v in ipairs(_child) do _children[_length + _k] = _v end end end _length = #_children local _child_1 = scale >= 0.1 and Roact.createElement(ZirconIcon, { Icon = "DownArrow", Position = UDim2.new(0, 2, 1, -16), }) if _child_1 then if _child_1.elements ~= nil or _child_1.props ~= nil and _child_1.component ~= nil then _children[_length + 1] = _child_1 else for _k, _v in ipairs(_child_1) do _children[_length + _k] = _v end end end return Roact.createElement("Frame", _attributes, _children) end, }) else return nil end end function ScrollView:scrollToPositionY(position) self.scrollFrame.CanvasPosition = Vector2.new(0, position) end function ScrollView:scrollToEnd() self.scrollFrame.CanvasPosition = Vector2.new(0, self.scrollFrame.CanvasSize.Height.Offset) self.initScrollToBottom = true end function ScrollView:getScrollFrame() return self.scrollFrame end function ScrollView:renderContentHandler() local _binding = self.props local ItemPadding = _binding.ItemPadding local computedPadding if typeof(ItemPadding) == "UDim" then computedPadding = ItemPadding elseif type(ItemPadding) == "number" then computedPadding = UDim.new(0, ItemPadding) end if self.props.GridLayout == true then local _binding_1 = (self.props) local ItemSize = _binding_1.ItemSize local ItemPadding = _binding_1.ItemPadding if ItemPadding == nil then ItemPadding = 0 end local _attributes = { CellSize = ItemSize, [Roact.Change.AbsoluteContentSize] = self.absoluteContentSizeChanged, CellPadding = CalculatePaddingUDim2(ItemPadding), [Roact.Ref] = function(ref) self.scrollListLayout = ref return self.scrollListLayout end, } local _condition = self.props.SortOrder if _condition == nil then _condition = Enum.SortOrder.LayoutOrder end _attributes.SortOrder = _condition return Roact.createFragment({ ScrollViewGrid = Roact.createElement("UIGridLayout", _attributes), }) else local _attributes = { VerticalAlignment = self.props.ItemAlignment, [Roact.Change.AbsoluteContentSize] = self.absoluteContentSizeChanged, Padding = computedPadding, } local _condition = self.props.SortOrder if _condition == nil then _condition = Enum.SortOrder.LayoutOrder end _attributes.SortOrder = _condition _attributes[Roact.Ref] = function(ref) self.scrollListLayout = ref return self.scrollListLayout end return Roact.createFragment({ ScrollViewList = Roact.createElement("UIListLayout", _attributes), }) end end function ScrollView:render() local _binding = self.props local Style = _binding.Style if Style == nil then Style = "NoButtons" end local Padding = _binding.Padding if Padding == nil then Padding = 0 end local padding = CalculatePadding(Padding) -- Include the scrollbar in the equation local _condition = padding.PaddingRight if _condition == nil then _condition = UDim.new(0, 0) end local _uDim = UDim.new(0, 20) padding.PaddingRight = _condition + _uDim local useButtons = Style == "Buttons" return Roact.createElement(ThemeContext.Consumer, { render = function(theme) local _attributes = { Size = self.props.Size or UDim2.new(1, 0, 1, 0), BackgroundTransparency = 1, } local _children = {} local _length = #_children local _attributes_1 = { [Roact.Ref] = function(frame) self.scrollFrame = frame return self.scrollFrame end, Size = UDim2.new(1, 0, 1, 0), Position = self.props.Position, BackgroundTransparency = 1, BorderSizePixel = 0, CanvasSize = UDim2.new(0, self.state.size.X, 0, self.state.size.Y), BottomImage = "", MidImage = "", ScrollingDirection = "Y", TopImage = "", [Roact.Change.AbsoluteSize] = self.absoluteContentSizeChanged, [Roact.Change.CanvasPosition] = self.canvasPositionUpdated, ScrollBarThickness = 20, } local _children_1 = { self:renderContentHandler(), } local _length_1 = #_children_1 local _attributes_2 = {} for _k, _v in pairs(padding) do _attributes_2[_k] = _v end _children_1.ScrollPadding = Roact.createElement("UIPadding", _attributes_2) local _child = self.props[Roact.Children] if _child then for _k, _v in pairs(_child) do if type(_k) == "number" then _children_1[_length_1 + _k] = _v else _children_1[_k] = _v end end end _children.ScrollFrameHost = Roact.createElement("ScrollingFrame", _attributes_1, _children_1) local _attributes_3 = { BackgroundTransparency = 1, Size = true and UDim2.new(0, 20, 1, 0) or UDim2.new(0, 0, 1, 0), Position = UDim2.new(1, -20, 0, 0), } local _children_2 = { ScrollFrameBarTrackUpButtonContainer = Roact.createElement("Frame", { Size = UDim2.new(0, 20, 0, 20), BackgroundTransparency = 1, }), } local _length_2 = #_children_2 local _attributes_4 = { Size = useButtons and UDim2.new(1, 0, 1, -40) or UDim2.new(1, 0, 1, 0), Position = UDim2.new(0, 0, 0, useButtons and 20 or 0), BackgroundTransparency = 0, BackgroundColor3 = theme.PrimaryBackgroundColor3, BorderColor3 = theme.SecondaryBackgroundColor3, BorderSizePixel = 1, } local _children_3 = {} local _length_3 = #_children_3 local _child_1 = self:renderBar() if _child_1 then if _child_1.elements ~= nil or _child_1.props ~= nil and _child_1.component ~= nil then _children_3[_length_3 + 1] = _child_1 else for _k, _v in ipairs(_child_1) do _children_3[_length_3 + _k] = _v end end end _children_2.ScrollFrameBarTrack = Roact.createElement("Frame", _attributes_4, _children_3) _children_2.ScrollFrameBarTrackDnButtonContainer = Roact.createElement("Frame", { Size = UDim2.new(0, 20, 0, 20), Position = UDim2.new(0, 0, 1, -20), BackgroundTransparency = 1, }) _children.ScrollFrameBar = Roact.createElement("Frame", _attributes_3, _children_2) return Roact.createElement("Frame", _attributes, _children) end, }) end end return { default = ScrollView, }