exadel-inc / esl

Lightweight and flexible UI component library based on web components technology for creating basic UX modules
https://esl-ui.com
MIT License
58 stars 9 forks source link

[🐛 esl-event-listener]: `intersects` event with option `once: true` is being triggered even if target is not intersects viewport #2300

Closed grechihinrhp closed 6 months ago

grechihinrhp commented 7 months ago

Input Code

export class MyCustomElement extends ESLBaseElement {
...
  @listen({
    event: 'intersects',
    target: ESLIntersectionTarget.for,
    once: true
  })
  _onIntersect(e: ESLIntersectionEvent): void {
    if (e.isIntersecting) {
      //do something
    }
  }
}

Expected behavior/code intersects event should be triggered when target element intersects viewport first time

Environment

ala-n commented 7 months ago

Introduction

The code described above is expected to track the first intersection of the observed element. However, according to the current ESLIntersectionTarget spec, it will produce ESLIntersectionEvent (intersects) each time the IntersectionObserver callback is called. So, the original intersects event will (and should) be produced each time the intersection observer configuration is satisfied (for both positive and negative intersections, with all of the passed ratios).

The recommended way to handle this expected behavior is as follows:

@listen({
  event: 'intersects',
  target: ESLIntersectionTarget.for
})
_onIntersect(e: ESLIntersectionEvent): void {
  if (e.isIntersecting) {
    // do something

    // Unsubscribe manually
    this.$$off(this._onIntersect);
  }
}

Note: This is the most common way to handle such scenarios and should continue to be used to handle complex intersection settings and conditions.

However, the following proposal was discussed and approved (as a POC) by the @exadel-inc/esl-core-maintainers :

The Proposal

To simplify the most common case described above, it is proposed to introduce intersects:in and intersects:out events:

Example

@listen({
  event: 'intersects:in',
  target: ESLIntersectionTarget.for,
  once: true
}) // Happens once a positive intersection happens
_onIntersect(e: ESLIntersectionEvent): void {
  if (e.isIntersecting) {
    // do something
  }
}

Implementation Acceptance Criteria

ala-n commented 6 months ago

:tada: This issue has been resolved in version 5.0.0-beta.14 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

ala-n commented 5 months ago

:tada: This issue has been resolved in version 4.17.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: