Open blaz-y opened 3 years ago
Hm, I'm not sure what you mean by "type safe interface." Bolero can consume Blazor components which are already type safe, and Blazor can host Bolero components (as elmish programs) which is certainly type safe. What other Node type were you thinking of?
Take a look at https://github.com/fsbolero/Bolero/issues/142 for details. Current implementation for components is totally reasonable approach given the limitations, but doing the (boring) work to properly wrap an external component should be able to give full type safety and I think intellisense support.
Ah, were you thinking of writing a wrapper for a specific library like MatBlazor then? Or were you thinking about writing a codegen tool that would scan the 3rd party component library's IL and generate helpers like MatButton.OnClick
to use as follows?
comp<MatButton>
[ attr.callback MatButton.OnClick (fun _ ->
this.JsRuntime.InvokeAsync<object>("window.alert", "Test") |> ignore) ]
[ text "Hello, world!" ]
I was thinking of writing a wrapper for Syncfusion, which is a pretty nice Blazor component library. I was just thinking of grinding it out by hand, So I'd want to end up with something more like
let grid = SfGrid().AllowSelection(true).AllowSorting(true).AllowFiltering(true).EnableVirtualization(true) grid.SetColumns(columns) etc
or perhaps would be necessary to do something closer to the existing HTML in F# syntax
SfGrid [AllowSelection=true ; AllowSorting=true]
Question is how I would integrate something like this into Bolero, as at some point Bolero would have to generate the corresponding Blazor/Razor representation of the above code.
My thought is I'd have to create something equivalent to the existing HTML.fs, but specifically for Syncfusion, extend the Node representation to have a new Synfusion Node type with associated function for consuming the Syncfusion Node. Naturally this wouldn't be something people would want in the main codebase, but would be pretty useful to someone who uses the given component a lot.
Hey, I'm glad someone else has had this on their mind as well! I considered a solution for something like this in the past, and I think based on the compiled output of C# Blazor components, we should be able to generate safe F#/Bolero interfaces for the components.
It's been a good 6+ months since I've looked at the compiled output of a C# component library, so things may have changed, but I think a starting point may be a simple F# script (maybe via FAKE?) that can look at a .NET assembly via reflection for classes inheriting from the base Blazor component type, and create an F# wrapper based on the properties tagged with [Parameter]
.
Long term I think there may be better options, like a type provider that uses a nuget package name or local assembly path as its input. We have a growing Bolero code base at my work, and it would be great to have seamless integration with the growing number of C# component libraries out there in the future. If others are interested in this as well I'm happy to help whenever I have the energy to contribute :smiley:
Yeah, I've thought about the type provider way, it would be perfect to create a chained method API. Plus, type providers have access to the list of full paths of all assemblies referenced by the project being compiled; so we could make a TP parameterized by an assembly name and it would be able to find and load it with eg Cecil.
If I was willing to do some work, would it be possible to integrate a specific external component library into Bolero so it would have a type safe interface? I have the idea this might be possible by creating new Node types or some such (very hand wavy) but before I try I'd appreciate any feedback on whether this is possible and any suggestions on how to do this.
Also, thanks for truly remarkable project.