alpinejs / alpine

A rugged, minimal framework for composing JavaScript behavior in your markup.
https://alpinejs.dev
MIT License
28.46k stars 1.24k forks source link

feat: `x-on` `.passive.false` modifier #4404

Open hirasso opened 1 month ago

hirasso commented 1 month ago

As discussed in #4403 , this PR adds a way to set event listeners to {passive: false}:

<div x-on.touchmove.passive.false="console.log($event.cancelable)"></div>

Use case

In horizontal sliders, it's necessary to stop vertical scrolling of the viewport when flicking through the slides. Registering a non-passive touchmove handler makes this possible:

{
  touching: false,
  touchStartCoords: {x: 0, y: 0},

  bindings: {
    "@touchstart.document.capture": "onTouchStart",
    "@touchmove.document.passive.false": "onTouchMove", // possible through this PR
  },

  onTouchStart(e: TouchEvent) {
    const target = e.target as HTMLElement;
    this.touching = this.$root.contains(target);

    this.touchStartCoords = {
      x: e.touches[0].pageX,
      y: e.touches[0].pageY,
    };
  },

  onTouchMove(e: TouchEvent) {
    const { cancelable } = e;
    const { touching } = this;

    if (!touching || !cancelable) return;

    const moveVector = {
      x: e.touches[0].pageX - this.touchStartCoords.x,
      y: e.touches[0].pageY - this.touchStartCoords.y,
    };

    if (Math.abs(moveVector.x) > 3) {
      e.preventDefault();
    }
  },
}

Checks

Questions

hirasso commented 1 month ago

@ekwoka thank you for approving this.

While I'm mostly against the idea of someone actually preventing default on any of these events

Sure... but I would still prefer if Alpine.js would make all native event listener options available instead of deciding for users what's good for them 🙂

I'd hope that the opt-in shape of the modifier .passive.false is a good-enough safeguard for not using this unintentionally.

ekwoka commented 1 month ago

An alternative would be no-passive...not sure if that's better.

hirasso commented 1 month ago

An alternative would be no-passive...not sure if that's better.

Added naming to the questions section in the PR description.