Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Detect heading click and provide clicked cell in table widget #15

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.SourceSans,
AutomaticSize = Enum.AutomaticSize.XY,
TextColor3 = style.textColor,
TextSize = 20,
TextXAlignment = Enum.TextXAlignment.Left,
RichText = true,
AutoButtonColor = false,
Active = true,

Activated = function()
setClicked(true)
end,

create("UIPadding", {
PaddingBottom = UDim.new(0, 8),
Expand All @@ -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,

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