Open AngelMunoz opened 1 year ago
Hey Angel,
thanks for the input. There are currently several ways of doing this, which I'll describe.
I added some small convenience functions and published 0.0.15
Untyped (ad-hoc) custom elements
The e
function creates an element with the given tag name. It provides all global attributes and events, and it's possible to set attributes using attr
/ attrBoolean
or register event handlers using on
. The e
function is just a shorthand:
let e (tagName: string) = HtmlGARenderRetCnBuilder<HTMLElement>(tagName)
Here's an example how to use it:
vide {
div {
(e "untyped-custom-elem")
.attr("untyped-custom-attribute", "Hello there")
.on("untyped-custom-event", fun evt -> ()) {
"Hello there again"
}
}
}
Typed custom elements
Like any other HTML element builder available in the Vide.Fable library, it is possible to specify custom element builders using similar pattern. How does that look like?
module MyCustomElementDefinitions =
open Browser.Types
open Vide
open Vide.HtmlElementBuilders
type typedCustomElementBuilder() =
inherit HtmlGARenderRetCnBuilder<HTMLElement>("typed-custom-element")
member this.myAttribute(value: string) =
this.attr("myAttribute", value)
member this.myBooleanAttribute(value: bool) =
this.attrBoolean("myBooleanAttribute", value)
member this.onMyEvent(handler) =
this.on("myEvent", handler)
[<AutoOpen>]
type MyCustomElements =
static member inline typedCustomElement = typedCustomElementBuilder()
Here, a typed-custom-element
is defined by inheriting from HtmlGARenderRetCnBuilder
that is based upon the HTMLElement
dom interface. Custom events and attributed are added as members, which use the same attr
, attrBoolean
, and on
methods.
As convenience, another type MyCustomElements
specifies a static property to allow omitting ()
when using the custom element in a view.
Using the element then looks like this:
open Vide
open type Vide.Html
open MyCustomElementDefinitions
let view =
vide {
div {
typedCustomElement
.myBooleanAttribute(false)
.myAttribute("Hello")
.onMyEvent(fun evt -> ()) {
"typedCustomElement can have content because it inherits from HtmlGARenderRetCnBuilder."
"if you don't like that, inherit from HtmlGARenderRetC0Builder."
}
}
}
There's a demo here.
Template / Slot
I just added the slot
element and slot
global attribute (template
element already existed), but I never used it and don't know if it will work.
I'm not sure if all of your ideas are addressed. At least I think this is missing, and I don't understand what is your intention:
// get a ref somehow here?
I'd be happy to discuss this issue further, and I appreciate more of those use cases. Thank you so much, @AngelMunoz for your help and input!
Hey there here I am with the first questions.
I'll set a little bit of context first: I'm quite a fan of custom elements and standards-based web dev in general so one of the first things that comes to my mind when trying out a web framework is how well are those supported.
This is a vanilla js use case I'd like to be able to do with vide
And in my js something like
I'm not sure if that is possible with vide right now I tried to find something in my limited experience at the moment but no luck so far
Here's how my pseudo code for vide would ideally look like
In this case I'm not very familiar with the DSL yet but if this is an area I can contribute to I'd gladly step in to see what I can do.
In the case of the typings I don't mind if everything is
string * obj
there's a "generator" project I had for Sutil for these kinds of web component libraries, I might be able to revive it to let it generate a fully typed vide DSL as well, but my concerns are more in the out of the box experience and how can we consume these standard features that are not so F# friendlyI'll keep dropping more questions as I keep trying vide but for the moment let me know what you think about that