What is the equivalent of this react component if made using C# and Blazor?
I'm used to just doing .NET + React, but since they improved Blazor so much with .net 8 I'm having some fun there, but there's one thing I haven't figured out yet. How to wrap existing components/create reusable ones in an easy user friendly way.
With React you can easily wrap components like the example below, pass down and do whatever you want with the props, and then just spread the rest onto them. And by directly using the correct interface (or extending it to create extra props) you get full auto complete/intellisense for the props.
Here is a simple example where you can create a styled input where the user can use it just like they would the underlying component. It would also be easy to modify this to add other props or change the behaviour. In here I add some basic styling which can be overwritten by the calling component if needed, but they also can use all the existing attributes for the input tag.
I've tried a few things. Wrapping it and using
@ChildContent
is easy, but then you're not really creating a new input, you're creating something around it unlike the react version.
Ideally I would want to use it like this, where I can use the field just as if it was a regular <InputText>
field, but my custom component could then set some defaults or modify the different inputs.
Is this possible or am I just too influenced by the JS/React way of solving things and I should be looking at it entirely differently? 😄9 Replies
ASP.NET Core Blazor attribute splatting and arbitrary parameters
Learn how components can capture and render additional attributes in addition to the component's declared parameters.
This could be helpful for regular HTML attributes
But for passing component parameters through, I'm not sure
I see that the components, such as
InputText
, are just classes that I can inherit and perhaps edit and override what I need from there. Seems like I can do this just using code and not bother with the html syntax at all. Seems a lot easier and more maintainable. I'll have to experiment, but seems like it will be easier than I feared 😄
Back to reading the source codeAh, right. regular old inheritance
@mg
Got it working in a simple example here. Also using tailwind, which is where I think this can be a huge win.
I'm basically just checking to see if the class is there, kinda wonky since it can be null
Kinda wonky since the attributes is a nullable readonly dictionary and there isn't exactly an upsert for dictionary. That part can just be taken out as a utility function/extension method or something and then it can look quite clean in usage
Definition
Usage
And it works fine by overriding the base value as I do here.
Only problem is this does not work well with MudBlazor since all of their utility clases have
!important
on them 💀 The specificity got weird it seems like.
With Tailwind you can use the @apply
directive to reuse styles, but this method can do more than just template the stylesExtracted it to a utility class and put the project into a public repo so it doesn't get lost
https://github.com/Lundeful/reusable-blazor-components
Hopefully we'll get a better solution for this soon
GitHub
GitHub - Lundeful/reusable-blazor-components
Contribute to Lundeful/reusable-blazor-components development by creating an account on GitHub.
I solved the issue in a similar way:
https://github.com/PaulBraetz/RhoMicro.ApplicationFramework/blob/54dc5f2398dc3acf3007c769ffcb203486d76d52/Presentation.Views.Blazor/Abstractions/ComponentBase.cs#L120
GitHub
RhoMicro.ApplicationFramework/Presentation.Views.Blazor/Abstraction...
Contains helper types & structure for creating web or desktop Blazor (Photino) Applications. - PaulBraetz/RhoMicro.ApplicationFramework
Cool stuff! Looks like you've been going down that rabbithole a lot more than me 😄
Does sort of feel like we're working against the framework when doing this, but if it works it works.
Comes with the territory of representing all attributes/parameters as
KVP<String, Object?>
but what can you do :catshrug:
I just wrote today a nice type that encapsulates the html class names issue rather neatly, no more string checking operations, just
Attributes["class"] = HtmlClassNames.Create(Attributes["class"]).Add("new-class-to-add").Remove("first-to-remove", "second-to-remove")
I can share if you're interested