davedawkins / Sutil

Lightweight front-end framework for F# / Fable. No dependencies.
https://sutil.dev
MIT License
299 stars 19 forks source link

RFC: Web Component API #32

Closed AngelMunoz closed 3 years ago

AngelMunoz commented 3 years ago

RFC - Web Components API

Summary

Since Sutil doesn't have any frontend library dependency (other than Fable libraries) it should be possible to register Sutil nodes as custom elements. These would allow Sutil users to author component libraries in a way that they will be able to be consumed in any browser environment, framework, library knowing they are backed by the safety of F#

Design

Nothing is set in stone but ideally I'd be looking to offer an API like this

[<WebComponent("my-element")>]
let MyElement (el: HTMLElement, props: ElementProps) =
    let hidden = Store.make props.hidden
    Html.div [
        Bind.attr("hidden" hidden)
        text $"My Element's message: {props.message}"
    ]

this should generate/emit a component that would be similar in functionality (not in code) as the following example

https://stackblitz.com/edit/js-vfmi1a?devtoolsheight=33&file=index.js

Since Sutil view functions are evaluated once we might not need to handle

Drawbacks

Unresolved questions

Links And References

alfonsogarciacaro commented 3 years ago

I think this a great proposal @AngelMunoz, although I have some mixed feelings about it. As you've already noticed in the posted links, there're already a couple of alternatives to create web components with Fable but if I'm not mistaken they're still not widely used. In my experience, although some users show much enthusiasm for writing Fable apps using HTML-like syntax, at the end not many pick one of the current alternatives, like using Svelte or writing React components in JSX, when writing a web app. Probably the main reason is the need of some boilerplate to glue the logic between F# and the view, but I believe at the end users realize that HTML-like template languages are not a big improvement over using F# directly to declare the UI>

So I'm not sure if the ability of using components directly from HTML would help make Sutil more widely used. Same way as, in general, the possibility of publishing JS libraries written in F# hasn't been a driving factor for Fable widespread. On the other hand, being able to consume JS libraries or (web) components is very important for Fable users, so things like Sutil.Shoelace do have a lot of value.

About Feliz.Engine, my intention was indeed that people could write an F# library like Feliz.Bulma and make it easily compatible with different renderers like React or Sutil. But at the end Feliz.Engine is not 100% compatible with (original) Feliz so it's going to be difficult that it becomes popular, but I'm happy that it's already helping Sutil :)

AngelMunoz commented 3 years ago

Thanks for your comments and feelings about it Alfonso,

Warning I might get a little philosophical here

My reasoning with Sutil is that is closer to the web than anything else and I believe being close to the web helps it's long term viability as some of the drivers of the web components movement I feel they apply to this, frameworks will change libraries will come and go but the web will still be the web, html will be html. In that aspect I'd like to enable the platform features for Fable users (and users from JS land looking for alternatives to JS/TS) just as Sutil has enable them (perhaps this has not been communicated enough) to do web development in one of it's simplest forms just JS/HTML/CSS

So I'm not sure if the ability of using components directly from HTML would help make Sutil more widely used. Same way as, in general, the possibility of publishing JS libraries written in F# hasn't been a driving factor for Fable widespread.

Right now I think fable solutions only reach the F# community which is not a bad thing in itself but I think that also is a limited scope, Ideally anyone should be able to create their own design system and either use it as a branding mechanism, or just share it with the world, the Lit (previously lit-element/polymer) slack channel is full with people doing cool things like shoelace and others doing shoelace-like libraries for internal use in their companies, even Microsoft is doing that so perhaps having ways to author web components can increase the scope outside the F# space into a more mainstream part of the web community

I might also be miss-interpreting the F# community perhaps they are just dedicated to do LoB applications, I'd like to think there are really creative minds there that just need the right tools and if there is not an "Idiomatic" way of doing things then ideas are often scrapped

For that matter I think the alternatives I found regarding F# and web components are merely exploratory and not meant to actually generate production grade web components, in the case of Onur Gumus’s blog I wouldn't really expect anyone to create web components that way it's simply not the F# way, I think @DieselMeister came up with a closer version to what other F# devs would expect the bad thing there is that it takes react as a dependency which in one way defeats the purpose of using web components (Unless I'm mistaken again as I was with Sutil and Svelte and it doesn't take a dependency on React🤣)

On the other hand, being able to consume JS libraries or (web) components is very important for Fable users, so things like Sutil.Shoelace do have a lot of value.

I do believe this is an important aspect as well and it was enabled precisely by Web Components (which for all purposes we don't care what they're written with) and the fact that Sutil it's just native HTML/JS I'd like to think that sums in one way to my point

About Feliz.Engine, my intention was indeed that people could write an F# library like Feliz.Bulma and make it easily compatible with different renderers like React or Sutil. But at the end Feliz.Engine is not 100% compatible with (original) Feliz so it's going to be difficult that it becomes popular, but I'm happy that it's already helping Sutil :)

I see, so this is the right repository for that, Sorry for the letter, hopefully it helps it make more sense :D

davedawkins commented 3 years ago

As long as you can * create custom Web Components with Sutil, is it necessary to offer anything other than a "how to" in the documentation?

Once the Fable JS is loaded, and the components are registered, the only API that matters to the downstream consumer is the existing Web Components API. We shouldn't care what framework they're using, and they shouldn't care what we used to create the component.

I think I am not sure who the consumer of this API is - if it's just the Sutil developer making a web component, then this is a proposal for Sutil features in support of Web Components - is that right?

Apologies if I've misunderstood something basic here.


AngelMunoz commented 3 years ago

As long as you can * create custom Web Components with Sutil, is it necessary to offer anything other than a "how to" in the documentation?

Yes, anything beyond that would be community effort since web components are basically a shareable piece of work with a dedicated purpose

I think I am not sure who the consumer of this API is - if it's just the Sutil developer making a web component, then this is a proposal for Sutil features in support of Web Components - is that right?

Yes, it's a proposal to make it easier to create web components with Sutil

I'll be experimenting with this now that I've found a way to auto-generate special (but not required) bindings for 3rd party web components

davedawkins commented 3 years ago

As long as you can * create custom Web Components with Sutil, is it necessary to offer anything other than a "how to" in the documentation?

Yes, anything beyond that would be community effort since web components are basically a shareable piece of work with a dedicated purpose

Can you elaborate on this? I’m not sure what you mean.

AngelMunoz commented 3 years ago

Yes, what I mean if there is a way to produce web components within Sutil, a simple guide or "how to" should be enough.

Any kind of component library, styling or extra things are not part of this proposal.

AngelMunoz commented 3 years ago

due to recent exposure of Lit thanks to Alfonso's amazing work I think we could reach the web component route in a simpler way by writing a binding, and providing a render function that gives us the final HTML DOM Element Haunted besides providing hooks it also "componentizes" functions (very similar to what my function does, take a function spit back a custom element) that would let Sutil on the same playing field as lit and since Haunted provides hooks, it could also level the ground for the people who like react stuff https://hauntedhooks.netlify.app/docs/guides/renderers/#guides-bring-your-own-renderer

AngelMunoz commented 3 years ago

I will close this issue, I just confirmed the above theory and I will conduct a further research inside the Fable.Haunted repository you can check the last commit on that pull request to see what it took to make it work 😁