seed-rs / seed

A Rust framework for creating web apps
MIT License
3.81k stars 155 forks source link

Experimental component API #599

Closed glennsl closed 2 years ago

glennsl commented 3 years ago

This is a proposal for a component API that offers:

Perhaps more importantly though, the comp! macro provides the indirection necessary to intercept and create boundaries in the vdom tree, which enables state to be attached to nodes, local updates to be triggered, and paves the path towards implementing proper hooks.

I expect there to be some discussion around this, of course, but once we're reasonably confident in the design we could bring this in behind an experimental feature flag, and while it matures start looking into all the possible features it enables.

glennsl commented 3 years ago

There, I've moved the comp! macro to seed and added a Component trait that can eventually be expanded upon, along with a comment outlining my thoughts a bit more. I'm not entirely sure I've put them in their appropriate places though.

glennsl commented 3 years ago

Some further thoughts:

  1. There's currently no way to conditionally set a property. Perhaps something like disabled => ?maybe_disabled to apply an Option would work. This makes the macro significantly more complicated though.

  2. It would be nice to have a macro provide a simpler interface for defining a component. Ideally something like:

#[component(Button)]
fn view<Ms: 'static>(label: String, disabled: Option<bool>) -> Node<Ms> {
  // ...
}

I can already see several limitations with this though, like lack of polymorphic arguments (assuming we need to store the component configuration to be able to instantiate it in local updates later). And depending on how we want to manage component state, we might want to extend the Component trait with a Model, Msg and init and update functions instead.

  1. Again assuming we need to store the component configuration for later instantiation in local updates, the component will need to own all its data. That's a relatively minor limitation though.
mankinskin commented 3 years ago

I have earlier wanted something like this, you might want to look at my components implementation for inspiration.

flosse commented 2 years ago

Feel free to re-open this PR but as long as #672 is not solved I think this is issue not relevant :disappointed: