symfony / ux

Symfony UX initiative: a JavaScript ecosystem for Symfony
https://ux.symfony.com/
MIT License
856 stars 315 forks source link

[LiveComponent] Easily stopping propagation for LiveActions within LiveActions #2394

Closed kilianklein closed 2 days ago

kilianklein commented 2 days ago

Hi guys,

As always thanks for this great technology, I have been using it for a few years now and I really love it.

There is one thing I could not figure out how to do "natively": how to stop the event propagation of a live action.

Imagine you have a button with a live action (on click) within a bigger div with a live action on click as well:

<div
       data-action="click->live#action"
       data-live-action-param="doDivThing"
>
       Title
       <button
                data-action="live#action"
                data-live-action-param="doButtonThing"
        >Click me</button>
</div>

In this situation, clicking the button would trigger both "doButtonThing" and "doDivThing" actions, but in most cases we'd want the button to just trigger its own action. We then need to prevent the propagation of the click to the parent div.

We have the live#action:prevent to stop the default behavior of a form submission button for example, but it does not work for this purpose (or at least it did not work for me, let me know if it should).

Since I can see this use case being a very common occurrence, my proposition is to add a similar keyword to stop propagation, which would look something as such: live#action:stop-propagation.

What do you guys think? (Please let me know if something like this already exists and I missed it.)

For those looking to solve this in the current version, I came up with a work around by making a very simple "stop_propagation_controller.js" stimulus controller that I call whenever needed:

import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
    stop(event) {
      event.stopPropagation();
    }
}

And the code simply looks like this:

<div
        data-action="click->live#action"
        data-live-action-param="doDivThing"
>
        Title
        <button
                data-action="stop-propagation#stop live#action"
                data-live-action-param="doButtonThing"
        >Click me</button>
</div>
kilianklein commented 2 days ago

Closing this as I found this solution already existed on the stimulus side:

data-action="live#action:stop"