tschuehly / spring-view-component

Server-side UI components with spring boot
MIT License
208 stars 11 forks source link

Support for HTMX OOB swaps #2

Closed checketts closed 1 year ago

checketts commented 1 year ago

I like the direction of this project. To use HTMX out-of-band swaps with Thymeleaf, I need the ability to return multiple components:

<div>my main component</div>
<div id="total">A separate component. A total perhaps</div>

Is this supportable with your library? Any tips on how that might be implemented if a PR were desired?

tschuehly commented 1 year ago

Hey @checketts thanks for the suggestion! You are happily invited to submit a PR.

A bit of context: Currently there are two different ways the viewcomponents are rendered. The one way where you render a nested component shouldn't be a problem because you could just insert multiple components next to each other.

<div view:component="parameterViewComponent.render(coffee, null)"></div>
<div view:component="footerViewComponent"></div>

The one that would need some investment to implement is the way where you return a ViewContext from your Controller Method -> the root component.

The ViewComponentMethodReturnValueHandler is responsible for this. It checks if a controller method returns a viewcontext and then puts that into a ModelAndViewContainer and returns that -> then the standard thymeleaf renderer takes over.

To implement multiple component returns we would need to create a new MethodReturnValueHandler that looks for a list of ViewComponents and then renders them directly into a ResponseEntity body. The code from the ViewComponentProcessor could be used. Part of it should be extracted that they render the exact same way.

I'll look at it later this weekend!

tschuehly commented 1 year ago

I got it working! I'll release a new version tomorrow!

checketts commented 1 year ago

That is great! I look forward to trying it out!

tschuehly commented 1 year ago

Hey @checketts I just released version v0.4.2 you can grab from jitpack. I updated the docs and published an example

Please try it out and give me feedback!