Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helper functions for morph inhibition in stimulus #801

Open
brendon opened this issue Nov 4, 2024 · 0 comments
Open

Helper functions for morph inhibition in stimulus #801

brendon opened this issue Nov 4, 2024 · 0 comments

Comments

@brendon
Copy link

brendon commented Nov 4, 2024

I've been converting an app (a newsletter editor that shows changes to the newsletter in realtime via Turbo Streams) to use morphing page updates (for other users) and targeted turbo stream updates for the initiating user.

There are various interfaces in the newsletter such as image panning, dropdowns, colourpickers and a modal interface for the more complex forms. I've found I need to inhibit morphing a lot when these interfaces are active. It's simple for the modals as we never want these to be morphed so we end up with this in initialise() {}:

this.element.addEventListener('turbo:before-morph-element', (event) => {
  if (event.target === this.element) {
    event.preventDefault()
  }
})

Sometimes I just don't want something to revert to its default state (e.g. a dropdown menu should stay open even if its content changes due to a morph:

this.element.addEventListener('turbo:before-morph-attribute', (event) => {
  if (event.target === this.element &&
    this.element.classList.contains('is-active')) {

    event.preventDefault()
  }
})

I prefer to add the listener to the controller element, but sometimes we care about inhibiting on another target inside the controller:

this.element.addEventListener('turbo:before-morph-attribute', (event) => {
  if (event.target === this.buttonTarget &&
    this.buttonTarget.classList.contains('is-loading')) {

    event.preventDefault()
  }
})

I don't know about you, but I can start to see an interface developing here and I wondered if it might be time to build some of this into Stimulus? Of course I can't really see beyond my use cases but I can see perhaps some helper functions like so:

preventElementMorph() // On the controller element
preventElementMorph({target: 'button'}) // On a target element
preventAttributeMorph({classContains: 'is-active'}) // On the controller element
preventAttributeMorph({target: 'button', classContains: 'is-loading'}) // On a target element

I can see some flaws there. Perhaps you'd want to prevent an element morph if a class exists. Perhaps you'd want to be more targeted in what attribute you'd want to prevent the morph of.

I'm hoping this can act as the start of a discussion given morphing and its side effects have now turned succinct Stimulus controllers into a bit of a mess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant