Skip to content

Commit

Permalink
Detect heading click and provide clicked cell in table widget (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
memorycode authored Feb 1, 2024
1 parent f59e163 commit b3b54bc
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 24 deletions.
85 changes: 61 additions & 24 deletions src/widgets/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@ 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.Gotham,
AutomaticSize = Enum.AutomaticSize.XY,
TextColor3 = style.textColor,
TextSize = 16,
TextXAlignment = Enum.TextXAlignment.Left,
RichText = true,
AutoButtonColor = false,
Active = true,

Activated = function()
setClicked(true)
end,

create("UIPadding", {
PaddingBottom = UDim.new(0, 6),
Expand All @@ -27,22 +34,31 @@ local cell = Runtime.widget(function(text, font)
})
end)

refs.label.Font = font or Enum.Font.Gotham
refs.label.Text = text
refs.button.Font = font or Enum.Font.Gotham
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,

Expand All @@ -53,10 +69,6 @@ local row = Runtime.widget(function(columns, darken, selectable, font)
MouseLeave = function()
setHovering(false)
end,

Activated = function()
setClicked(true)
end,
})
end)

Expand All @@ -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
Expand All @@ -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 = {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
58 changes: 58 additions & 0 deletions stories/table.story.lua
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit b3b54bc

Please sign in to comment.