Skip to content

Commit fa3346c

Browse files
committed
feat: add createRoot function
1 parent 4dbb622 commit fa3346c

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

README.md

+21-11
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,22 @@ React, but for Factorio. Packaged as a mod for easy consumption.
55
```lua
66
local React = require("__react__.react")
77

8-
script.on_event(defines.events.on_gui_opened, function(event)
9-
if not event.player then return end
10-
11-
local element = React.createElement(
12-
"frame",
13-
{ caption = "Reactorio" },
14-
"Hello, world!"
15-
)
16-
React.render(element, event.player.gui.screen)
8+
script.on_event(defines.events.on_player_created, function(event)
9+
local player = game.players[event.player_index]
10+
11+
-- Create the root element we are going to put our GUI into (props can be customized)
12+
local root = React.createRoot(player.gui.center, { style = "outer_frame" })
13+
14+
-- Build our virtual dom tree
15+
local vdom = React.lsx[[
16+
<frame caption="React for Factorio">
17+
Hello, world!
18+
<button>Click Me!</button>
19+
</frame>
20+
]]
21+
22+
-- Render!
23+
React.render(vdom, root)
1724
end)
1825
```
1926

@@ -29,11 +36,14 @@ end)
2936
- Plain text components (generated via `label`)
3037
- Simple event API
3138
- No need to register a separate event listener, just add a prop
39+
- LSX, Lua version of JSX
40+
- `lsx'<label caption="Hello world!" />'` is equivalent to `createElement("label", { caption = "Hello world!" })`
41+
3242

3343
### Coming Soon™
3444

35-
- Component shorthand similar to JSX (most likely going to adapt https://github.com/hishamhm/f-strings)
36-
- Save/load event handler restoration
45+
- Variable support in LSX (via additional param in lsx function)
46+
- Save/load event handler restoration (maybe this works now?)
3747
- Context API support (`createContext`/`useContext`)
3848

3949
### Running Tests

lib/core.lua

+13
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ local function render(vlist, parent, storage)
110110
for i, vnode in ipairs(vlist) do
111111
local forceUpdate = function() return render(vlist, parent, storage) end
112112

113+
-- special handling for string vnodes
114+
if type(vnode) == "string" then
115+
vnode = { type = "label", props = { caption = vnode }}
116+
end
117+
113118
while (type(vnode.type) == "function") do
114119
local k = vnode.props and vnode.props.key
115120
if not k then
@@ -187,7 +192,15 @@ local function createElement(type, props, ...)
187192
return { type = type, props = props or {}, children = children }
188193
end
189194

195+
local function createRoot(parent, props)
196+
if parent["react_root"] then
197+
parent["react_root"].destroy()
198+
end
199+
return parent.add(merge(props or {}, { type = "frame", name = "react_root", }))
200+
end
201+
190202
return {
191203
createElement = createElement,
204+
createRoot = createRoot,
192205
render = render,
193206
}

react.lua

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ local lsx = require("__react__.lib.lsx")
88

99
return {
1010
-- Core
11+
createRoot = core.createRoot,
1112
createElement = core.createElement,
1213
h = core.createElement,
1314
render = core.render,

scenarios/react-testing/control.lua

+20-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,23 @@
22
if script.active_mods["gvv"] then require("__gvv__.gvv")() end
33

44
-- Load the test suite
5-
require("init")
5+
-- require("init")
6+
local React = require("__react__.react")
7+
8+
script.on_event(defines.events.on_player_created, function(event)
9+
local player = game.players[event.player_index]
10+
11+
-- Create the root element we are going to put our GUI into (props can be customized)
12+
local root = React.createRoot(player.gui.center, { style = "outer_frame" })
13+
14+
-- Build our virtual dom tree
15+
local vdom = React.lsx[[
16+
<frame caption="React for Factorio">
17+
Hello, world!
18+
<button caption="Click Me!" />
19+
</frame>
20+
]]
21+
22+
-- Render!
23+
React.render(vdom, root)
24+
end)

0 commit comments

Comments
 (0)