Closed AngelMunoz closed 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 :)
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
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.
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
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.
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.
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
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 😁
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
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
Custom Elements are defined as classes
This might be troublesome since we'd ideally want to stick to a functional approach but I believe we can get
Unresolved questions
Should we handle shadow DOM?
How do we handle attribute callbacks? (AFAIK Sutil views are evaluated once)
Should we expose the element instance (this) as a context object?
Should we expose functionality related to lifecycle hooks?
Should this be in Feliz.Engine instead? (cc @alfonsogarciacaro)
Links And References
https://github.com/DieselMeister/Fable.React.WebComponent
I think this last one might have good input on how to work with the Fable Plugins