htmx icon indicating copy to clipboard operation
htmx copied to clipboard

Refactor and expose `swap` in public API

Open Renerick opened this issue 1 year ago • 4 comments

Description

This PR includes swap method in htmx public API. This feature has been requested on multiple occasions, was proposed for 2.0 and finally delivered. To make it possible, I did a bit of a refactoring by gathering every swap-related piece of code in fullSwap method (name is up for discussion), which handles

  • focus and selection preservation
  • title updates
  • head merging
  • scroll
  • OOB swapping
  • normal swapping
  • settling

This means that any extension and custom script can use full power of htmx's swapping features. I also anticipate that this change should significantly simplify maintenance of swapping in the future

This is a breaking change, as extensions no longer have access to selectAndSwap method. The new method fully covers the needs for swapping, while also removing responsibility of managing settling info.

The old method covered very specific part of swapping process and had a tricky signature which I struggle to keep untouched.

On the plus side, this is the entire code that's required to perform swapping from SSE extension

let target = api.getTarget(child);
let swapSpec = api.getSwapSpecification(child);
htmx.swap(target, event.data, {spec: swapSpec});

To be done/decided:

  • [x] exposure of SwapSpecification type to the public world (are we ok with it? need to document it) - added to htmx.d.ts and documented in JS API section
  • [x] documentation - documented
  • [x] naming of the method - renamed to swap
  • [ ] upgrading official extensions (ws, sse) - TBD
  • [ ] handling view transitions from this method - TBD

Corresponding issue: 2.0

Testing

I ensured that this refactor did not affect existing tests at all. I also intend to write tests specifically for this method, if the team agrees that this approach works for us

Renerick avatar Jan 14 '24 14:01 Renerick

Fwiw, I feel like "extension-breaking" and "user breaking" are two separate concepts. I wouldn't want to break out extensions randomly, but the bar for breaking user functionality is higher than breaking the internal API.

alexpetros avatar Jan 15 '24 01:01 alexpetros

Why fullSwap and not just swap?

alexpetros avatar Jan 15 '24 01:01 alexpetros

@alexpetros this was a placeholder name. I did it because we had swap method that implements specific swapping strategies and I wasn't sure how the refactor would turn out. I will rename it before merging

Renerick avatar Jan 15 '24 07:01 Renerick

As discussed, I've renamed the method, and also cleaned up signature a bit to get rid of duplicated parameters from swapSpec and swapOptions. I decided to separate swapSpec and swapOptions as separate arguments, since the former will be used much more often compared to the latter.

Also, some basic tests for the method.

Renerick avatar Jan 17 '24 17:01 Renerick