centau / vide

A reactive Luau library for creating UI.
https://centau.github.io/vide/
MIT License
95 stars 16 forks source link

Dynamically rendered 'component sources' #8

Closed littensy closed 1 year ago

littensy commented 1 year ago

Currently, to render a component conditionally, you need to create and destroy it from a watch() call, which can get tedious.

To make it easy to dynamically render content, Solid provides the <Dynamic> component. Vide can provide a similar API where you'd pass a derived source that returns a component:

Dynamic {
    component = function()
        return options[selected()]
    end,
    -- ...props
}

I don't think it's necessary to make it a component, considering that Vide doesn't seem to provide built-in components yet. An API more similar to this would be nice as well:

dynamic(function()
    local Option = options[selected()]

    return Option {
        -- ...props
    }
end)
littensy commented 1 year ago

The second proposed API may cause issues if your component creates its own sources and effects, as they will run on the same scope and risk excessive re-renders. After some discussion, the API for dynamic() may instead look like this:

function dynamic<T, U>(source: Source<T>, render: (T) => U): Source<U>;
dynamic(currentOption, function(Option)
    return Option {
        -- ...props
    }
end)

This makes it easier to untrack() the component and isolate it from the input source.

centau commented 1 year ago

Given that we now have the likes of show() and switch() to dynamically render components, do you still think it worthwhile to add this? We can already do what dynamic() is supposed to with:

effect(function()
    currentOption() -- track currentOption
    local unmount = mount(component, target) -- mount component on current option update
    cleanup(unmount) -- unmount previously mounted component
end)

The current control flow functions we have should cover the majority of cases already and I'd like to keep Vide's API minimal, unless it will definitely save a lot of boilerplate, but I'm not sure.

littensy commented 1 year ago

Given that we now have the likes of show() and switch() to dynamically render components, do you still think it worthwhile to add this? We can already do what dynamic() is supposed to with:

I can only think of it being useful in cases where conditions rely on a source's value, but that's still doable by passing a derived source to switch(). I don't think Dynamic is as useful in Vide as it might be in Solid, so I don't think its worthwhile.

littensy commented 1 year ago

Closed since I no longer feel this should be a core feature of Vide, but it may be re-opened in the future.