Closed glennsl closed 2 years ago
I think using createElementVariadic
might take one already quite far. Here is an idea (haven't tested, but I think should work):
Picking from the ppx tests, e.g.:
We can do st like:
module Brick_flipbox = struct
let make ~custom_prop ~data_text () =
let open Js_of_ocaml.Js in
React.Dom.createDOMElementVariadic "brick-flipbox"
~props:
( Unsafe.obj
[| ("custom-prop", Unsafe.inject (bool custom_prop))
; ("data-text", Unsafe.inject (string data_text)) |]
: React.Dom.domProps )
[]
end
Then this can be consumed from either OCaml or Reason components, e.g.:
Reason
let el = <Brick_flipbox custom_prop=false data_text="foo" />
or OCaml
let el = Brick_flipbox.make ~custom_prop:true ~data_text:"foo" ()
TIL attrs can only be strings, so the example above wouldn't work in real world (should convert bool to string 😅 ) https://open-wc.org/guides/knowledge/attributes-and-properties/#attributes
But the main idea / approach still stands
Thanks for the example! That already doesn't look too bad. I think we could do even better though, especially if we assume only string props, by providing a little helper function:
let custom name ?props=[||] children =
let open Js_of_ocaml.Js in
let props: domProps =
props |> Array.map (fun (key, value) -> (key, Unsafe.inject (string value)))
|> Unsafe.obj
in
createDOMElementVariadic "brick-flipbox" ~props children
module Brick_flipbox = struct
let make ~custom_prop ~data_text () =
React.Dom.custom "brick-flipbox"
~props:
[| ("custom-prop", custom_prop)
; ("data-text", data_text)
|]
[]
end
Unfortunately it isn't the case that all props are attributes. We might for example want to allow onClick
and other event handlers to be passed. On the other hand, any custom events would have to use a ref
and be attached directly to the DOM anyway, so perhaps it wouldn't be so bad to do that for all events if we gain the convenience of having a helper function such as this.
Yeah, I think including this helper function makes sense, even if some cases would still require manual creation as you said.
As you seem to be exploring with custom components 🙂 maybe once you explore this approach with real world cases, you could submit a PR with the function(s) that you think are really valuable to include in the library? 🙏 I have zero experience with custom elements.
Yeah, absolutely! I don't know if we're actually going to use web components (in the near future) though. We do today, and that's what prompted me to look into this, but one of the benefits of using React is the large ecosystem, so it's very possible that we'll just bind to a set of React components instead. I'll eventually get to this one way or the other though :)
@glennsl I consider this done with h
function you added + DSL. Do you think we can close it?
Absolutely. Although we might still tweak the exact details of how to do this, it's definitely possible now. Thanks for the reminder!
To interact with web components there needs to be some way to instantiate custom elements, and to have those elements take custom attributes.
Three options I can see that I believe would work today:
React.createDOMElementVariadic
manuallyAre there any other options? It would be nice to have a bit more convenience.
Somewhat related to #93, as having a way to pass custom attributes to any element would also solve that.