fix: widget constructor assigning order

assign children first, so props that depend on them work
for example Stack.shown
This commit is contained in:
Aylur
2024-09-12 22:56:08 +00:00
parent 3a057f53a2
commit 6fce8da11a
3 changed files with 36 additions and 31 deletions

View File

@@ -129,16 +129,17 @@ function ctor(self: any, config: any = {}, children: any = []) {
const { setup, ...props } = config const { setup, ...props } = config
props.visible ??= true props.visible ??= true
// collect bindings
const bindings = Object.keys(props).reduce((acc: any, prop) => { const bindings = Object.keys(props).reduce((acc: any, prop) => {
if (props[prop] instanceof Binding) { if (props[prop] instanceof Binding) {
const binding = props[prop] const binding = props[prop]
setProp(self, prop, binding.get())
delete props[prop] delete props[prop]
return [...acc, [prop, binding]] return [...acc, [prop, binding]]
} }
return acc return acc
}, []) }, [])
// collect signal handlers
const onHandlers = Object.keys(props).reduce((acc: any, key) => { const onHandlers = Object.keys(props).reduce((acc: any, key) => {
if (key.startsWith("on")) { if (key.startsWith("on")) {
const sig = kebabify(key).split("-").slice(1).join("-") const sig = kebabify(key).split("-").slice(1).join("-")
@@ -149,8 +150,21 @@ function ctor(self: any, config: any = {}, children: any = []) {
return acc return acc
}, []) }, [])
Object.assign(self, props) // set children
children = mergeBindings(children.flat(Infinity))
if (children instanceof Binding) {
setChildren(self, children.get())
self.connect("destroy", children.subscribe((v) => {
setChildren(self, v)
}))
}
else {
if (children.length > 0) {
setChildren(self, children)
}
}
// setup signal handlers
for (const [signal, callback] of onHandlers) { for (const [signal, callback] of onHandlers) {
if (typeof callback === "function") { if (typeof callback === "function") {
self.connect(signal, callback) self.connect(signal, callback)
@@ -161,29 +175,20 @@ function ctor(self: any, config: any = {}, children: any = []) {
} }
} }
for (const [prop, bind] of bindings) { // setup bindings handlers
for (const [prop, binding] of bindings) {
if (prop === "child" || prop === "children") { if (prop === "child" || prop === "children") {
self.connect("destroy", bind.subscribe((v: any) => { self.connect("destroy", binding.subscribe((v: any) => {
setChildren(self, v) setChildren(self, v)
})) }))
} }
self.connect("destroy", bind.subscribe((v: any) => { self.connect("destroy", binding.subscribe((v: any) => {
setProp(self, prop, v) setProp(self, prop, v)
})) }))
setProp(self, prop, binding.get())
} }
children = mergeBindings(children.flat(Infinity)) Object.assign(self, props)
if (children instanceof Binding) {
setChildren(self, children.get())
self.connect("destroy", children.subscribe((v) => {
setChildren(self, v)
}))
}
else {
if (children.length > 0)
setChildren(self, children)
}
setup?.(self) setup?.(self)
return self return self
} }

View File

@@ -154,12 +154,12 @@ local function astalify(ctor)
tbl.visible = true tbl.visible = true
end end
-- filter props -- collect props
local props = filter(tbl, function(_, key) local props = filter(tbl, function(_, key)
return type(key) == "string" and key ~= "setup" return type(key) == "string" and key ~= "setup"
end) end)
-- handle on_ handlers that are strings -- collect signal handlers
for prop, value in pairs(props) do for prop, value in pairs(props) do
if string.sub(prop, 0, 2) == "on" and type(value) ~= "function" then if string.sub(prop, 0, 2) == "on" and type(value) ~= "function" then
props[prop] = function() props[prop] = function()
@@ -168,7 +168,7 @@ local function astalify(ctor)
end end
end end
-- handle bindings -- collect bindings
for prop, value in pairs(props) do for prop, value in pairs(props) do
if getmetatable(value) == Binding then if getmetatable(value) == Binding then
bindings[prop] = value bindings[prop] = value
@@ -179,16 +179,6 @@ local function astalify(ctor)
-- construct, attach bindings, add children -- construct, attach bindings, add children
local widget = ctor() local widget = ctor()
for prop, value in pairs(props) do
widget[prop] = value
end
for prop, binding in pairs(bindings) do
widget.on_destroy = binding:subscribe(function(v)
widget[prop] = v
end)
end
if getmetatable(children) == Binding then if getmetatable(children) == Binding then
set_children(widget, children:get()) set_children(widget, children:get())
widget.on_destroy = children:subscribe(function(v) widget.on_destroy = children:subscribe(function(v)
@@ -200,6 +190,16 @@ local function astalify(ctor)
end end
end end
for prop, binding in pairs(bindings) do
widget.on_destroy = binding:subscribe(function(v)
widget[prop] = v
end)
end
for prop, value in pairs(props) do
widget[prop] = value
end
if type(setup) == "function" then if type(setup) == "function" then
setup(widget) setup(widget)
end end

View File

@@ -62,7 +62,7 @@ in
preFixup = '' preFixup = ''
gappsWrapperArgs+=( gappsWrapperArgs+=(
--prefix PATH : ${pkgs.lib.makeBinPath extraPackages} --prefix PATH : "${pkgs.lib.makeBinPath extraPackages}"
) )
''; '';
} }