vinum-team / Vinum

A modern reactive state management library for correctness and speed.
MIT License
16 stars 1 forks source link

Support Roact through a Binding library #27

Closed sinlerdev closed 6 months ago

sinlerdev commented 1 year ago

It would certainly be useful to allow vinum to be used alongside Roact, as it would perhaps allow a sort of workflow that feels fusion-y (fusion users will understand how does this mean), while still using Roact, and its DOM.

I opened this issue to track formal discussions about this, though I will officially address it after Vinum v0.3 releases. Additionally, while I am not experienced with Roact itself, we could either: 1 - reference a library that is made by a community member, or a list of ones. 2 - Write a spec for how a Vinum-Roact binding should work and look like.

sinlerdev commented 1 year ago

Not that its a final design or something, but an API like this that uses Hooks could allow the user to use Vinum the way its intended to be used, while still preserving "roactness":

local function MyComponent(props)
    local value = useVinum(props.value)
    local onClick = useVinum(props.onClick

    return Roact.createElement("ScreenGui", nil, {
        Label = Roact.createElement("TextButton", {
            Text = "Current value: " .. value,
            Size = UDim2.new(1, 0, 1, 0),

            [Roact.Event.Activated] = onClick,
        })
    })
end

local element = Roact.createElement(MyComponent, {
    value = Hold(...),
    onClick = Compute(...)
})

Plus, not sure if this is possible, but perhaps useVinum hook can be directly exposed from the binding library, deleting the need to some sort of component passing.

sinlerdev commented 1 year ago

Could we perhaps do something similar to BasicState's Roact-linking implementation? We could potentially support Vinum-Roact linking by updating Roact's built-in state feature, and then allow users to normally use them?

for example:

local ClicksVinum = Hold(0, returner(true))

local component = Roact.Component:extend("Component")

function component:render()
    return Roact.createElement("TextLabel", {
        Text = self.state.Clicks
    })
end

function component:didUpdate()
    print(self.state.Clicks)
end

VinumRoact.Inject(component, {
    Clicks = ClicksVinum
})

ClicksVinum:set(1)

-- 1 is printed

Need some feedback here.

xiyler commented 6 months ago

It should be important to be transparent about how should we (in this context, the Vinum Team) deal with binding libraries. While we could work on providing official implementations for bindings between Vinum and other popular UI libraries (Fusion and react-lua most notably), this actually increases the general development time (which is something we don't have lots of), as these libraries need to be maintained to be always up to data (both to new Vinum versions, and new versions of the other library).

What I think should be beneficial for all, is to reject any requests for implementing an official binding library, and gladly accept referencing community-made bindings.