Page 1 of 1

Typescript JSX based UI

Posted: Sun Sep 17, 2023 11:13 am
by soulaymenc
Hi,

After discovering typescript-to-lua, and the fact that it supports JSX, alongside typescript love type definition, I starting working on a UI framework inspired by React.

You can find the source code here https://github.com/praisethemoon/armastus

It is still very impractical to use just yet, and it is missing a lot of features. But I would love to hear your feedback and if there is anything you want to see in such a framework.

Image

Name meaning: armastus: love in Estonian.

Cheers!

Re: Typescript JSX based UI

Posted: Sun Sep 17, 2023 6:43 pm
by dusoft
Can you please provide an example of generated Lua code? Is this compatible with LÖVE graphics?

Re: Typescript JSX based UI

Posted: Mon Sep 18, 2023 7:48 am
by soulaymenc
dusoft wrote: Sun Sep 17, 2023 6:43 pm Can you please provide an example of generated Lua code? Is this compatible with LÖVE graphics?
Hello! Well personally I wouldn't really think of using the generate Lua code as it is, maybe its better to generate wrappers in typescript so its easier to handle the code on Lua level, but here is an example:

Typescript Component:

Code: Select all

<Div key="grid-1" style={{
                        width: "100%", height: "100%", backgroundColor: "#EC53B0"
                    }}>
                        <Switch>
                            <Router  route={"/play"}>
                                <Div style={{width: "100%", height: "100%", backgroundColor: "#F1EFEF"}}/>
                            </Router>

                            <Router route={"/git_gud"}>
                                <Div style={{width: "100%", height: "100%", backgroundColor: "#CCC8AA"}}/>
                            </Router>

                            <Router route={"/waste_money/{amount}"}>
                                <Div style={{width: "100%", height: "100%", backgroundColor: "#7D7C7C"}}>
                                    <SmartTextBox key="txt" style={{width: "100%", height: "100%"}}/>
                                </Div>
                            </Router>

                            <Router route={"/waste_money/{amount}/{target}"}>
                                <SmartTextBox key="txt" style={{width: "100%", height: "100%"}}/>
                            </Router>

                            <Router route={"/settings"}>
                                <Div style={{width: "100%", height: "100%", backgroundColor: "#FF00FF"}}/>
                            </Router>
                        </Switch>
                    </Div>
                </Grid>
                
Equivalent Lua code:

Code: Select all

Arma:createElement(
                Div,
                {key = "grid-1", style = {width = "100%", height = "100%", backgroundColor = "$red800"}},
                Arma:createElement(
                    Switch,
                    nil,
                    Arma:createElement(
                        Router,
                        {route = "/play"},
                        Arma:createElement(Div, {style = {width = "100%", height = "100%", backgroundColor = "#F1EFEF"}})
                    ),
                    Arma:createElement(
                        Router,
                        {route = "/git_gud"},
                        Arma:createElement(Div, {style = {width = "100%", height = "100%", backgroundColor = "#CCC8AA"}})
                    ),
                    Arma:createElement(
                        Router,
                        {route = "/waste_money/{amount}"},
                        Arma:createElement(
                            Div,
                            {style = {width = "100%", height = "100%", backgroundColor = "#7D7C7C"}},
                            Arma:createElement(SmartTextBox, {key = "txt", style = {width = "100%", height = "100%"}})
                        )
                    ),
                    Arma:createElement(
                        Router,
                        {route = "/waste_money/{amount}/{target}"},
                        Arma:createElement(SmartTextBox, {key = "txt", style = {width = "100%", height = "100%"}})
                    ),
                    Arma:createElement(
                        Router,
                        {route = "/settings"},
                        Arma:createElement(Div, {style = {width = "100%", height = "100%", backgroundColor = "#FF00FF"}})
                    )
                )
            )
            
This may look more or less okay but when defining typescript classes, the generate Lua code gets a bit more obfuscated like:

Code: Select all

SmartTextBox.name = "SmartTextBox"
__TS__ClassExtends(SmartTextBox, BaseComponent)
function SmartTextBox.prototype.____constructor(self, ...)
    BaseComponent.prototype.____constructor(self, ...)
    self.routerParams = self:useState(Arma:getRouteParamsState())
end
function SmartTextBox.prototype.render(self)
    return Arma:createElement(
        TextBox,
        {style = {width = "100%", height = "100%"}},
        self.routerParams:get().amount
    )
end
local RootComponent = __TS__Class()
RootComponent.name = "RootComponent"
__TS__ClassExtends(RootComponent, BaseComponent)
function RootComponent.prototype.____constructor(self, params)
    BaseComponent.prototype.____constructor(self, params, {})
    self.lastClickedButton = self:useState(lastClickedButton)
end
And I do not really get what you mean with this being compatible with LÖVE graphics, the generated Lua code uses love calls, so without really understanding the question, i presume yes :ultrahappy:

Re: Typescript JSX based UI

Posted: Mon Sep 18, 2023 11:05 am
by dusoft
Thanks