Open jkone27 opened 4 years ago
This could definitely be done! It would have to be a reimplementation though, rather than a direct use of the Feliz library, since Feliz itself uses React types directly.
Hi,
Would this library help? https://github.com/dbrattli/Feliz.ViewEngine
It basically returns a HTML formatted string using Feliz more succinct syntax
It looks like it still uses ReactElement as an intermediate step, so I doubt we can use it directly.
I'm not sure if that's something I would even want. Is Feliz really less verbose? I see two different examples as a form of comparison, and I'm seeing that "Html." is mandatory before each element, which seems more verbose. I think there would have to be more proof or a better pitch to help realize if anything needs to be changed syntactically. I do like some of the aesthetics in certain areas in Feliz, but Bolero seems fine in the way it's been evolving.
Inline HTML is silly: changes to it need recompilation, which is prohibitively more expensive compared to just putting your UI pieces (small and large) into external HTML files and using the templating TP. I have seen people "rationalizing" the use of inline HTML: how it makes it easier to create components and whatever, but you can do all that with snippets you read via the TP too, while keeping the original speed/convenience benefit. All in all: I'd recommend to externalize your UI instead of trying to mingle it into your application code.
I'm not sure if that's something I would even want. Is Feliz really less verbose? I see two different examples as a form of comparison, and I'm seeing that "Html." is mandatory before each element, which seems more verbose. I think there would have to be more proof or a better pitch to help realize if anything needs to be changed syntactically. I do like some of the aesthetics in certain areas in Feliz, but Bolero seems fine in the way it's been evolving.
The main appeal of Feliz syntax to me is the simpler formatting. The two list function raises questions about how to format your code, and it can get a little hairy once you have multiple attributes and multiple children each with their own attributes. There's a good discussion on the Feliz repo about this and Isaac posted a sample of how they format in the dual list style
https://github.com/Zaid-Ajaj/Feliz/issues/155#issuecomment-610816990
Yes, this is clean, but using Bolero myself on an internal app over the past year it took time and experience to settle on a similar format. It's also not trivial to do either, I find it's something I often have to actively think about while writing the code.
I haven't used Feliz or the Fable ecosystem myself other than playing with some sample apps, so maybe there's some hidden dragons in Feliz, but it seems like a win for writing readable view code without having to think about your formatting
The other pain point is maintaining two lists as things becomes more nested can be legitimately difficult. I still run into weird compiler errors from a missing ]
, even after months of experience and using VSCode + Rainbow Brackets. Not all editors have good support for coloring matching brackets either, so that's something to consider.
Inline HTML is silly: changes to it need recompilation, which is prohibitively more expensive compared to just putting your UI pieces (small and large) into external HTML files and using the templating TP. I have seen people "rationalizing" the use of inline HTML: how it makes it easier to create components and whatever, but you can do all that with snippets you read via the TP too, while keeping the original speed/convenience benefit. All in all: I'd recommend to externalize your UI instead of trying to mingle it into your application code.
@granicz I can't speak much on the templating TP as I haven't used it, but I think it's a little unfair to categorize inline HTML as silly. The HTML DSL's created by the F# community was one of the things that drew me to the language when I discovered Giraffe. Most HTML derived view/template engines I've worked with end up being yet another non-trivial abstraction to learn, while being less expressive than what you see in a good language level DSL. That's not to say there's anything wrong with HTML templates, and from what I've seen Bolero's have a better design than most, but I personally get a lot of value from the DSL
Let's compare the friendList template example with the inline DSL
<p>Here are my best friends:</p>
<ul>
${Friends}
<template id="Friend">
<li>${Name}</li>
</template>
</ul>
type FriendList = Template<"friendList.html">
// Use the nested template `Friend`.
let showFriend (name: string) =
FriendList.Friend()
.Name(name)
.Elt()
// Use the main template (full HTML file minus the <template> tag).
let listFriends (names: list<string>) =
FriendList()
.Friends(forEach names showFriend)
.Elt()
let showFriend (friend: string) =
li [] [ text friend ]
let listFriends (names: string list) =
concat [
p [] [ text "Here are my best friends:" ]
ul [] [ forEach names showFriend ]
]
To do this with templates you have to understand the inline HTML concepts, as well as:
That being said, templates do provide their own advantages, and they do seem like they're implemented well in Bolero. I think your point about separating view code from the application is particularly interesting. Application logic rarely finds its way into our view functions, but it has before and templates creating an explicit barrier is appealing.
For hot reloading, that seems like more of a technical problem than an abstraction issue. Fable React already has hot reloading for their HTML DSL if you can serialize your app model, and from what I understand you still need to rebuild a Bolero app with templates whenever app logic changes anyway.
@weebs Yes, hot reloading code changes is a technical problem and the situation around it will improve over time, but currently you need to recompile your full app and it takes time. Going the templating way helps deciding on the right model types early on, and most of the subsequent UI changes can thus be applied in a streamlined, efficient manner.
Most real-life apps will have sophisticated, deeply structured UIs, and experimenting with enhancements and even replacing large parts of the UI is often a dreaded requirement. Having to do that over inline HTML will be a massive hit.
In all honesty, although I agree with @granicz, in this case, because there are no inline F# within HTML templates like there is in Blazor, it makes using inline HTML more intuitive. There is more outside the box mentality to get things to work with templates than there would be using inline HTML. It's unfortunate yet necessary. My rule of thumb is, create templates as much as you can first, where changes are to the values of the DOM element, if there's any kind of logical flow that determines considerable changes to the DOM elements themselves, then inline HTML is the way to go.
I am experimenting this kind of project: https://github.com/slaveOftime/Fun.Blazor
I made couple of helper functions like html.inject to create a component and inject service like ComponentHook which can manage observable state and lifecycle event and no elmish style needed. Of course we like elmish we can still use elmish style model. I also made an html.watch to check the state of chanages and only rerender if some data changed.
Just for fun now, not production ready 😂
Here is a docs link: https://funblazor.slaveoftime.fun/helper-functions
Would it be possible to make Feliz HTML view an option ?
https://zaid-ajaj.github.io/Feliz/#/Feliz/Syntax
instead of the current "more verbose"