Skip to content

Commit

Permalink
Make some progress on tree view rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
vocksel committed Nov 18, 2024
1 parent 986d9dc commit 6c127b1
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 46 deletions.
8 changes: 4 additions & 4 deletions src/Storybook/StorybookTreeView.luau
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
local React = require("@pkg/React")
local Storyteller = require("@pkg/Storyteller")

local TreeView = require("@root/TreeView/Treeview")
local storybookTypes = require("@root/Storybook/types")
local TreeView = require("@root/TreeView/TreeView")
local treeViewTypes = require("@root/TreeView/types")

type TreeNode = treeViewTypes.TreeNode
type Storybook = storybookTypes.Storybook
type Storybook = Storyteller.Storybook

local useMemo = React.useMemo

Expand All @@ -21,7 +21,7 @@ local function StorybookTreeView(props: Props)
local leafNodes = useMemo(function()
local nodes: { TreeNode } = {}
for _, storyModule in storyModules do
table.insert(nodes, {})
-- table.insert(nodes, {})
end
return nodes
end, { storyModules })
Expand Down
75 changes: 67 additions & 8 deletions src/TreeView/TreeNode.luau
Original file line number Diff line number Diff line change
@@ -1,58 +1,117 @@
local React = require("@pkg/React")

local Sprite = require("@root/Common/Sprite")
local treeViewTypes = require("@root/TreeView/types")
local useTheme = require("@root/Common/useTheme")
local assets = require("@root/assets")

local useCallback = React.useCallback
local useMemo = React.useMemo

type TreeNode = treeViewTypes.TreeNode

export type Props = {
node: TreeNode,
onActivated: (() -> ())?,
layoutOrder: number?,
}

local function TreeNode(props: Props)
local theme = useTheme()

local children = useMemo(function()
local elements: { [string]: React.Node } = {}
if props.node.children then
local elements = {}
for _, child in props.node.children do
for index, child in props.node.children do
elements[child.id] = React.createElement(TreeNode, {
layoutOrder = index,
node = child,
})
end
return elements
end
return elements
end, { props.node.children })

local onActivated = useCallback(function()
if props.onActivated then
props.onActivated()
end
end, { props.onActivated })

return React.createElement("ImageButton", {
LayoutOrder = props.layoutOrder,
AutoButtonColor = false,
[React.Event.Activated] = function()
props.onActivated(props.node)
end,
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
[React.Event.Activated] = onActivated,
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
Padding = theme.paddingSmall,
}),

Node = React.createElement("Frame", {
LayoutOrder = 1,
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
}, {
Icon = React.createElement("ImageLabel", {}),
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Horizontal,
Padding = theme.paddingSmall,
HorizontalFlex = Enum.UIFlexAlignment.Fill,
}),

Icon = React.createElement(Sprite, {
image = assets.Component,
color = theme.story,
layoutOrder = 1,
size = UDim2.fromOffset(16, 16),
}),

Text = React.createElement("TextLabel", {
LayoutOrder = 2,
Text = props.node.label,
AutomaticSize = Enum.AutomaticSize.Y,
BackgroundTransparency = 1,
Font = theme.font,
Size = UDim2.fromScale(1, 0),
TextXAlignment = Enum.TextXAlignment.Left,
TextColor3 = theme.text,
TextSize = theme.textSize,
}, {
Flex = React.createElement("UIFlexItem", {
FlexMode = Enum.UIFlexMode.Shrink,
}),
}),

Toggle = React.createElement("ImageLabel", {}),
Toggle = if props.node.children
then React.createElement("ImageButton", {
LayoutOrder = 3,
BackgroundTransparency = 1,
Size = UDim2.fromOffset(16, 16),
}, {
Icon = React.createElement(Sprite, {
image = assets.ChevronRight,
color = theme.text,
size = UDim2.fromScale(1, 1),
}),
})
else nil,
}),

Children = React.createElement("Frame", {
LayoutOrder = 2,
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
}, {
Padding = React.createElement("UIPadding", {
PaddingLeft = theme.padding,
}),

Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
Padding = theme.paddingSmall,
}),
}, children),
})
Expand Down
42 changes: 24 additions & 18 deletions src/TreeView/TreeView.luau
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
local React = require("@pkg/React")

local useTheme = require("@root/Common/useTheme")
local treeViewTypes = require("@root/TreeView/types")
local TreeNode = require("@root/TreeView/TreeNode")

local useCallback = React.useCallback
local useMemo = React.useMemo

type TreeNode = treeViewTypes.TreeNode
Expand All @@ -15,33 +18,36 @@ export type Props = {
}

local function TreeView(props: Props)
local nodesById = useMemo(function() end, { props.tree })
local theme = useTheme()

local leafNodes = useMemo(function() end, { props.tree })
local nodesById = useMemo(function() end, { props.roots })

local children = {}
for _, node in props.roots do
children[node.label] = React.createElement("ImageButton", {
AutoButtonColor = false,
[React.Event.Activated] = function()
props.onActivated(node)
end,
}, {
Label = React.createElement("Frame", {}, {
Icon = React.createElement("ImageLabel", {}),
local leafNodes = useMemo(function() end, { props.roots })

Text = React.createElement("TextLabel", {
Text = node.label,
}),
}),
local onNodeActivated = useCallback(function(node: TreeNode)
if props.onActivated then
props.onActivated(node)
end
end, { props.onActivated })

Toggle = React.createElement("ImageLabel", {}),
local children: { [string]: React.Node } = {}
for index, node in props.roots do
children[node.label] = React.createElement(TreeNode, {
layoutOrder = index,
node = node,
onActivated = function()
onNodeActivated(node)
end,
})
end

return React.createElement("Frame", {}, {
return React.createElement("Frame", {
BackgroundTransparency = 1,
AutomaticSize = Enum.AutomaticSize.XY,
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
Padding = theme.paddingSmall,
}),
}, children)
end
Expand Down
44 changes: 28 additions & 16 deletions src/TreeView/TreeView.story.luau
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
local React = require("@pkg/React")

local ContextProviders = require("@root/Common/ContextProviders")
local MockPlugin = require("@root/Testing/MockPlugin")
local TreeView = require("./TreeView")
local types = require("./types")

return {
story = function()
return React.createElement(TreeView, {
roots = {
local tree: types.TreeNode = {
id = "1",
label = "Top",
children = {
{
id = "1",
label = "Top",
children = {
{
id = "2",
label = "Child",
parent = "1",
children = {
{},
},
},
id = "2",
label = "Child",
isExpanded = true,
children = {},
},

{
id = "3",
label = "Sibling",
children = {
{
id = "3",
label = "Sibling",
parent = "1",
id = "4",
label = "Descendant",
isExpanded = false,
children = {},
},
},
},
},
}
return React.createElement(ContextProviders, {
plugin = MockPlugin.new(),
}, {
TreeView = React.createElement(TreeView, {
roots = {
tree,
},
}),
})
end,
}
1 change: 1 addition & 0 deletions src/TreeView/types.luau
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export type TreeNode = {
id: string,
label: string,
icon: string?,
isExpanded: boolean?,
children: { TreeNode }?,
parent: TreeNode?,
}
Expand Down

0 comments on commit 6c127b1

Please sign in to comment.