diff --git a/src/widgets/table.lua b/src/widgets/table.lua index 8d31acb..9aafdfe 100644 --- a/src/widgets/table.lua +++ b/src/widgets/table.lua @@ -5,11 +5,12 @@ local create = require(script.Parent.Parent.create) local automaticSize = require(script.Parent.Parent.automaticSize) local cell = Runtime.widget(function(text, font) + local clicked, setClicked = Runtime.useState(false) local refs = Runtime.useInstance(function(ref) local style = Style.get() - return create("TextLabel", { - [ref] = "label", + return create("TextButton", { + [ref] = "button", BackgroundTransparency = 1, Font = Enum.Font.SourceSans, AutomaticSize = Enum.AutomaticSize.XY, @@ -17,6 +18,12 @@ local cell = Runtime.widget(function(text, font) TextSize = 20, TextXAlignment = Enum.TextXAlignment.Left, RichText = true, + AutoButtonColor = false, + Active = true, + + Activated = function() + setClicked(true) + end, create("UIPadding", { PaddingBottom = UDim.new(0, 8), @@ -27,22 +34,31 @@ local cell = Runtime.widget(function(text, font) }) end) - refs.label.Font = font or Enum.Font.SourceSans - refs.label.Text = text + refs.button.Font = font or Enum.Font.SourceSans + refs.button.Text = text + + return { + clicked = function() + if clicked then + setClicked(false) + return true + end + + return false + end, + } end) local row = Runtime.widget(function(columns, darken, selectable, font) - local clicked, setClicked = Runtime.useState(false) + local clicked, setClicked = Runtime.useState() local hovering, setHovering = Runtime.useState(false) - local selected = columns.selected local refs = Runtime.useInstance(function(ref) - return create("TextButton", { + return create("TextLabel", { [ref] = "row", BackgroundTransparency = if darken then 0.7 else 1, BackgroundColor3 = Color3.fromRGB(0, 0, 0), - AutoButtonColor = false, Text = "", Active = false, @@ -53,10 +69,6 @@ local row = Runtime.widget(function(columns, darken, selectable, font) MouseLeave = function() setHovering(false) end, - - Activated = function() - setClicked(true) - end, }) end) @@ -75,21 +87,24 @@ local row = Runtime.widget(function(columns, darken, selectable, font) refs.row.BackgroundTransparency = transparency refs.row.BackgroundColor3 = selected and Color3.fromHex("bd515c") or Color3.fromRGB(0, 0, 0) - for _, column in ipairs(columns) do + for index, column in ipairs(columns) do if type(column) == "function" then Runtime.scope(column) else - cell(column, font) + if cell(column, font):clicked() then + setClicked(index) + end end end return { clicked = function() if clicked then - setClicked(false) - return true + setClicked(nil) + return clicked end - return false + + return nil end, hovered = function() return hovering @@ -103,8 +118,15 @@ end) @param items {{string}} @param options {marginTop?: number, selectable?: boolean, font?: Font, headings?: boolean} @tag widgets + @return TableWidgetHandle + + A table widget. Items is a list of rows, with each row being a list of cells. - A table widget. Items is a list of rows, with each row being a list of cells. + Returns a widget handle, which has the fields: + + - `selected`, a function you can call to check what row and cell were selected this frame, if any + - `selectedHeading`, a function you can call to check which heading was selected this frame, if any + - `hovered`, a function you can call to check what row is being hovered over ```lua local items = { @@ -162,21 +184,26 @@ return Runtime.widget(function(items, options) end) local selected, setSelected = Runtime.useState() + local selectedHeading, setSelectedHeading = Runtime.useState() local hovered for i, columns in items do local selectable = options.selectable local font = options.font + local isHeading = options.headings and i == 1 - if options.headings and i == 1 then - selectable = false + if isHeading then font = Enum.Font.GothamBold end local currentRow = row(columns, i % 2 == 1, selectable, font) - - if currentRow:clicked() then - setSelected(columns) + local clickedCell = currentRow:clicked() + if clickedCell then + if isHeading then + setSelectedHeading(clickedCell) + else + setSelected({ row = columns, cellIndex = clickedCell }) + end end if currentRow:hovered() then @@ -185,11 +212,21 @@ return Runtime.widget(function(items, options) end return { + selectedHeading = function() + if selectedHeading then + setSelectedHeading(nil) + return selectedHeading + end + + return nil + end, selected = function() if selected then setSelected(nil) - return selected + return selected.row, selected.cellIndex end + + return nil end, hovered = function() return hovered diff --git a/stories/table.story.lua b/stories/table.story.lua new file mode 100644 index 0000000..fe5a7df --- /dev/null +++ b/stories/table.story.lua @@ -0,0 +1,58 @@ +local RunService = game:GetService("RunService") +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local Plasma = require(ReplicatedStorage.Plasma) + +return function(target) + local root = Plasma.new(target) + + local headings = { "Name", "Count" } + local items = {} + for index, letter in { "A", "B", "C", "D", "E" } do + table.insert(items, { letter, 100 - index }) + end + + local connection = RunService.Heartbeat:Connect(function() + Plasma.start(root, function() + Plasma.window("Table", function() + Plasma.row({ + alignment = Enum.HorizontalAlignment.Center, + }, function() + local entries = table.clone(items) + table.insert(entries, 1, headings) + + local tbl = Plasma.table(entries, { + headings = true, + selectable = true, + }) + + local selectedHeading = tbl:selectedHeading() + if headings[selectedHeading] == headings[1] then + -- Sort alphabetically + table.sort(items, function(a, b) + return a[1] < b[1] + end) + elseif headings[selectedHeading] == headings[2] then + -- Sort by count + table.sort(items, function(a, b) + return a[2] < b[2] + end) + end + + local selectedRow, cellIndex = tbl:selected() + if cellIndex == 1 then + -- Remove row if click name + table.remove(items, table.find(items, selectedRow)) + elseif cellIndex == 2 then + -- Shuffle number if click count + selectedRow[cellIndex] = Random.new():NextInteger(1, 100) + end + end) + end) + end) + end) + + return function() + connection:Disconnect() + Plasma.start(root, function() end) + end +end