thoughtbot / superglue

A productive library for Classic Rails, React and Redux
https://thoughtbot.github.io/superglue/
MIT License
327 stars 8 forks source link

Add ability to set UJS handlers on a different HTML element. #64

Open jho406 opened 3 weeks ago

jho406 commented 3 weeks ago

Superglue brings back UJS handers to Rails. In superglue they often look like this

<a href={"/posts"} data-sg-remote>

They're very convenient and adds SPA functionality without the complexity of javascript. Its behavior is overridable in your application_visit.js that gets generated when you start a new superglue project so you can handle all your edge cases.

In superglue, its installed on the same appEl in application.js, also generated into your project.

https://github.com/thoughtbot/superglue/blob/091c076a45927237d8f8cc3dd7574cc70a6169ec/superglue_rails/lib/install/templates/web/application.js#L31

The appEl also gets passed internally to superglue's ApplicationBase (your application.js overrides this) here:

https://github.com/thoughtbot/superglue/blob/091c076a45927237d8f8cc3dd7574cc70a6169ec/superglue/lib/index.js#L158

where the event listeners are added to appEl immediately after that.

    appEl.addEventListener('click', onClick)

In other words, the UJS handers only listen on the appEl, which when considering some component libraries uses react portals to build modals or dropdowns, means that UJS doesn't work on those components because they exist outside the appEl. I'd like to see superglue optionally support passing a custom element to put the listeners on. It can be as simple as allowing a subclass of of ApplicationBase to more easily override. For example:

class Application extends ApplicationBase {
   ujsElement () {
  }


In that scenario `ApplicationBase` would need to define its ujsElement as defaulting to the `appEl` that gets passed to it.