what is the relationship between `CustomOperationAttribute` and the conventional CE Yield member?

57 views Asked by At

The excellent ElementBuilder [GitHub] of Bolero inspires me to try to share/centralize certain HTML-DSL expressions for reuse. So, in almost total ignorance, I start with this:

open Bolero
open Bolero.Builders
open Bolero.Html

type ElementBuilder with
    [<CustomOperation "bulmaStuff">]
    member this.BulmaStuff(n: Node) =
        div {
            attr.``class`` ["custom"]
            n
        }

and then I try this:

section {
    bulmaStuff span { text "wrap me" }
}

This does not compile. There is the error message:

Error: input.fsx (2,5)-(2,15) typecheck error 'bulmaStuff' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 0 argument(s), but given 2.
input.fsx (2,5)-(2,39) typecheck error No overloads match for method 'Yield'.

And, finally, there is this very helpful message:

Known type of argument: unit

Available overloads:
- member ElementBuilder.Yield: _comp: ComponentBuilder<#AspNetCore.Components.IComponent> -> Node // Argument '_comp' doesn't match
- member ElementBuilder.Yield: attr: Attr -> Attr // Argument 'attr' doesn't match
- member ElementBuilder.Yield: comp: ComponentBuilder -> Node // Argument 'comp' doesn't match
- member ElementBuilder.Yield: comp: ComponentWithAttrsAndNoChildrenBuilder<#AspNetCore.Components.IComponent> -> Node // Argument 'comp' doesn't match
- member ElementBuilder.Yield: comp: ComponentWithAttrsBuilder<#AspNetCore.Components.IComponent> -> Node // Argument 'comp' doesn't match
- member ElementBuilder.Yield: eb: ElementBuilder -> Node // Argument 'eb' doesn't match
- member ElementBuilder.Yield: fragment: AspNetCore.Components.RenderFragment -> Node // Argument 'fragment' doesn't match
- member ElementBuilder.Yield: node: Node -> Node // Argument 'node' doesn't match
- member ElementBuilder.Yield: ref: HtmlRef -> RefContent // Argument 'ref' doesn't match
- member ElementBuilder.Yield: ref: RefContent -> RefContent // Argument 'ref' doesn't match
- member ElementBuilder.Yield: text: string -> Node // Argument 'text' doesn't match

My main question is, What is the relationship between CustomOperationAttribute and the conventional Yield member? The equally excellent Scott Wlaschin series on CEs does not cover CustomOperation.

Should I use CustomOperation like this in the first place? Should I avoid the advanced complexity of ElementBuilder and just made a seperate CE only based on yielding Node (elevating ElementBuilder to Node)?

0

There are 0 answers