-- 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 Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local ThemeContext = TS.import(script, script.Parent.Parent, "UIKit", "ThemeContext").default local _Collections = TS.import(script, script.Parent.Parent.Parent, "Shared", "Collections") local setsEqual = _Collections.setsEqual local toArray = _Collections.toArray local ZirconIcon = TS.import(script, script.Parent, "Icon").default local Padding = TS.import(script, script.Parent, "Padding").default local ScrollView = TS.import(script, script.Parent, "ScrollView").default local MultiSelectDropdown do MultiSelectDropdown = Roact.Component:extend("MultiSelectDropdown") function MultiSelectDropdown:init(props) self.dropdownRef = Roact.createRef() self.maid = Maid.new() local _object = { selectedItems = {}, } local _left = "selectedItemIds" local _condition = props.SelectedItemIds if _condition == nil then _condition = {} end _object[_left] = _condition _object.active = false self.state = _object self:updateSelectedIndexes() self.portalPosition, self.setPortalPosition = Roact.createBinding(UDim2.new()) self.portalSizeX, self.setPortalSizeX = Roact.createBinding(0) end function MultiSelectDropdown:getItemSet() local _binding = self local _binding_1 = _binding.props local Items = _binding_1.Items local _binding_2 = self.state local selectedItemIds = _binding_2.selectedItemIds local _arg0 = function(accumulator, current) local _id = current.Id if selectedItemIds[_id] ~= nil then -- ▼ Set.add ▼ accumulator[current] = true -- ▲ Set.add ▲ end return accumulator end -- ▼ ReadonlyArray.reduce ▼ local _result = {} local _callback = _arg0 for _i = 1, #Items do _result = _callback(_result, Items[_i], _i - 1, Items) end -- ▲ ReadonlyArray.reduce ▲ local selectedItemSet = _result return selectedItemSet end function MultiSelectDropdown:updateSelectedIndexes() self:setState({ selectedItems = self:getItemSet(), }) end function MultiSelectDropdown:setPortalPositionRelativeTo(frame) local _binding = frame local AbsolutePosition = _binding.AbsolutePosition local AbsoluteSize = _binding.AbsoluteSize self.setPortalPosition(UDim2.new(0, AbsolutePosition.X, 0, AbsolutePosition.Y + AbsoluteSize.Y)) self.setPortalSizeX(AbsoluteSize.X) end function MultiSelectDropdown:didUpdate(prevProps) if not setsEqual(prevProps.SelectedItemIds, self.props.SelectedItemIds) then local _fn = self local _object = { selectedItems = self:getItemSet(), } local _left = "selectedItemIds" local _condition = self.props.SelectedItemIds if _condition == nil then _condition = {} end _object[_left] = _condition _fn:setState(_object) end end function MultiSelectDropdown:didMount() local frame = self.dropdownRef:getValue() if frame then self.maid:GiveTask(frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() self:setPortalPositionRelativeTo(frame) end)) self.maid:GiveTask(frame:GetPropertyChangedSignal("AbsolutePosition"):Connect(function() self:setPortalPositionRelativeTo(frame) end)) self:setPortalPositionRelativeTo(frame) end -- Hack to re-render it self:setState({ selectedItems = self:getItemSet(), }) end function MultiSelectDropdown:willUnmount() self.maid:DoCleaning() end function MultiSelectDropdown:renderDropdownItems() local _binding = self.state local selectedItems = _binding.selectedItems local selectedItemIds = _binding.selectedItemIds local _items = self.props.Items local _arg0 = function(item, idx) return Roact.createElement(ThemeContext.Consumer, { render = function(theme) local _attributes = { Size = UDim2.new(1, 0, 0, 30), } local _id = item.Id _attributes.BackgroundColor3 = selectedItemIds[_id] ~= nil and theme.PrimarySelectColor3 or theme.SecondaryBackgroundColor3 _attributes.BorderSizePixel = 1 _attributes.BorderColor3 = theme.PrimaryBackgroundColor3 local _children = {} local _length = #_children local _id_1 = item.Id local _condition = selectedItemIds[_id_1] ~= nil if _condition then _condition = (Roact.createElement(ZirconIcon, { Icon = "CheckmarkHeavy", Position = UDim2.new(0, 0, 0.5, -8), })) end local _attributes_1 = { Size = UDim2.new(1, 0, 1, 0), BackgroundTransparency = 1, } local _children_1 = { Roact.createElement(Padding, { Padding = { Right = 20, Horizontal = 5, }, }), } local _length_1 = #_children_1 if _condition then if _condition.elements ~= nil or _condition.props ~= nil and _condition.component ~= nil then _children_1[_length_1 + 1] = _condition else for _k, _v in ipairs(_condition) do _children_1[_length_1 + _k] = _v end end end _length_1 = #_children_1 _children_1[_length_1 + 1] = Roact.createElement("TextButton", { Font = theme.Font, TextXAlignment = "Left", TextSize = 15, BackgroundTransparency = 1, Size = UDim2.new(1, 0, 1, 0), Position = UDim2.new(0, 20, 0, 0), TextColor3 = theme.PrimaryTextColor3, Text = item.Text, [Roact.Event.MouseButton1Click] = function() local selectedSet = {} local newSet = {} for existingItem in pairs(self.state.selectedItems) do local _id_2 = existingItem.Id -- ▼ Set.add ▼ newSet[_id_2] = true -- ▲ Set.add ▲ -- ▼ Set.add ▼ selectedSet[existingItem] = true -- ▲ Set.add ▲ end local _id_2 = item.Id if newSet[_id_2] ~= nil then local _id_3 = item.Id -- ▼ Set.delete ▼ newSet[_id_3] = nil -- ▲ Set.delete ▲ -- ▼ Set.delete ▼ selectedSet[item] = nil -- ▲ Set.delete ▲ else local _id_3 = item.Id -- ▼ Set.add ▼ newSet[_id_3] = true -- ▲ Set.add ▲ -- ▼ Set.add ▼ selectedSet[item] = true -- ▲ Set.add ▲ end if UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then -- ▼ Set.clear ▼ table.clear(newSet) -- ▲ Set.clear ▲ -- ▼ Set.clear ▼ table.clear(selectedSet) -- ▲ Set.clear ▲ local _id_3 = item.Id -- ▼ Set.add ▼ newSet[_id_3] = true -- ▲ Set.add ▲ -- ▼ Set.add ▼ selectedSet[item] = true -- ▲ Set.add ▲ end self:setState({ selectedItems = selectedSet, selectedItemIds = newSet, }) if self.props.ItemsSelected ~= nil then self.props.ItemsSelected(newSet) end end, }) _children[_length + 1] = Roact.createElement("Frame", _attributes_1, _children_1) return Roact.createElement("Frame", _attributes, _children) end, }) end -- ▼ ReadonlyArray.map ▼ local _newValue = table.create(#_items) for _k, _v in ipairs(_items) do _newValue[_k] = _arg0(_v, _k - 1, _items) end -- ▲ ReadonlyArray.map ▲ return _newValue end function MultiSelectDropdown:renderDropdown() local _binding = self.state local active = _binding.active if active == false then return Roact.createFragment() end local activeSizeY = math.min(#self.props.Items * 30, 30 * 4) local portal = (Roact.createElement(ThemeContext.Consumer, { render = function(theme) local _attributes = { BackgroundColor3 = theme.PrimaryBackgroundColor3, BorderColor3 = theme.SecondaryBackgroundColor3, Position = self.portalPosition, Size = self.portalSizeX:map(function(x) return UDim2.new(0, x, 0, activeSizeY) end), [Roact.Event.MouseLeave] = function() return self:setState({ active = false, }) end, } local _children = {} local _length = #_children local _children_1 = {} local _length_1 = #_children_1 for _k, _v in ipairs(self:renderDropdownItems()) do _children_1[_length_1 + _k] = _v end _children[_length + 1] = Roact.createElement(ScrollView, {}, _children_1) return Roact.createFragment({ DropdownPortal = Roact.createElement("Frame", _attributes, _children), }) end, })) return Roact.createElement(Roact.Portal, { target = Players.LocalPlayer:FindFirstChildOfClass("PlayerGui"), }, { HostedDropdownPortal = Roact.createElement("ScreenGui", { DisplayOrder = 10500, }, { portal, }), }) end function MultiSelectDropdown:render() local _binding = self.props local Items = _binding.Items local Disabled = _binding.Disabled local Size = _binding.Size if Size == nil then Size = UDim2.new(0, 150, 0, 30) end local _binding_1 = self.state local selectedItems = _binding_1.selectedItems local values = toArray(selectedItems) local _arg0 = function(f) local _condition = f.SelectedText if _condition == nil then _condition = f.Text end return _condition end -- ▼ ReadonlyArray.map ▼ local _newValue = table.create(#values) for _k, _v in ipairs(values) do _newValue[_k] = _arg0(_v, _k - 1, values) end -- ▲ ReadonlyArray.map ▲ local fullString = table.concat(_newValue, ", ") return Roact.createElement(ThemeContext.Consumer, { render = function(theme) local _attributes = { BackgroundColor3 = theme.SecondaryBackgroundColor3, BorderColor3 = theme.PrimaryBackgroundColor3, Size = Size, [Roact.Ref] = self.dropdownRef, } local _children = {} local _length = #_children local _attributes_1 = { Size = UDim2.new(1, -25, 1, 0), BackgroundTransparency = 1, } local _children_1 = { Roact.createElement(Padding, { Padding = { Horizontal = 10, }, }), } local _length_1 = #_children_1 local _attributes_2 = { Size = UDim2.new(1, 0, 1, 0), BackgroundTransparency = 1, Font = theme.Font, TextSize = 15, TextXAlignment = "Left", TextColor3 = Disabled and theme.PrimaryDisabledColor3 or theme.PrimaryTextColor3, } local _label = self.props.Label local _arg0_1 = #values _attributes_2.Text = string.format(_label, _arg0_1) _attributes_2[Roact.Event.MouseButton1Click] = function() return not Disabled and self:setState({ active = not self.state.active, }) end _children_1[_length_1 + 1] = Roact.createElement("TextButton", _attributes_2) _children.Content = Roact.createElement("Frame", _attributes_1, _children_1) _children[_length + 1] = Roact.createElement("ImageLabel", { Image = "rbxassetid://2657038128", ImageColor3 = Disabled and theme.PrimaryDisabledColor3 or Color3.fromRGB(255, 255, 255), Position = UDim2.new(1, -25, 0, 5), BackgroundTransparency = 1, Rotation = self.state.active and 0 or 180, Size = UDim2.new(0, 20, 0, 20), }) _children[_length + 2] = self:renderDropdown() return Roact.createElement("Frame", _attributes, _children) end, }) end end return { default = MultiSelectDropdown, }