Skip to content

Commit

Permalink
Merge pull request #2487 from exadel-inc/tech/carousel-upd
Browse files Browse the repository at this point in the history
fix(esl-carousel): fix handling of pointercancel event by touch plugin
  • Loading branch information
ala-n committed Jul 4, 2024
2 parents b5aa526 + c51ac99 commit 2169caf
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 13 deletions.
47 changes: 47 additions & 0 deletions site/views/examples/carousel/vertical.sample.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Vertical Carousel (Single)
order: 4
tags: carousel-sample
---

<div class="esl-carousel-no-extra-space" esl-carousel-container>
<button class="esl-carousel-arrow inner prev hide-xs" esl-carousel-nav="group:prev">
<span class="sr-only">Previous Slide</span>
</button>

<esl-carousel demo-options-target
style="aspect-ratio: 16 / 9"
esl-carousel-touch="swipe"
vertical
loop="true">
<ul esl-carousel-slides>
{% for i in range(0, 4) -%}
<li esl-carousel-slide>
<div class="card">
<div class="img-container img-container-16-9">
<esl-image mode="cover" lazy
data-alt="Alt Text Test"
data-src="{{ '/assets/carousel/' + loop.index + '-sm.jpg' | url }}"></esl-image>
<div class="h1 text-slide text-white">Slide {{ loop.index }}</div>
</div>
</div>
</li>
{%- endfor %}
</ul>
</esl-carousel>

<button class="esl-carousel-arrow inner next hide-xs" esl-carousel-nav="group:next">
<span class="sr-only">Next Slide</span>
</button>

<esl-carousel-dots class="carousel-dots-wrapper"></esl-carousel-dots>

<style>
.text-slide {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</div>
2 changes: 2 additions & 0 deletions src/modules/esl-base-element/core/esl-base-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ export abstract class ESLBaseElement extends HTMLElement implements ESLBaseCompo
return this._connected;
}

/** Subscribes (or resubscribes) all known descriptors that matches criteria */
public $$on(criteria: ESLListenerCriteria): ESLEventListener[];
/** Subscribes `handler` method marked with `@listen` decorator */
public $$on(handler: ESLListenerHandler): ESLEventListener[];
/** Subscribes `handler` function by the passed DOM event descriptor {@link ESLListenerDescriptor} or event name */
Expand Down
21 changes: 8 additions & 13 deletions src/modules/esl-carousel/plugin/touch/esl-carousel.touch.mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class ESLCarouselTouchMixin extends ESLCarouselPlugin {
/** Defines distance tolerance to swipe */
@attr({name: 'esl-carousel-swipe-distance', defaultValue: 20, parser: parseInt}) public swipeDistance: number;
/** Defines timeout tolerance to swipe */
@attr({name: 'esl-carousel-swipe-timeout', defaultValue: 2000, parser: parseInt}) public swipeTimeout: number;
@attr({name: 'esl-carousel-swipe-timeout', defaultValue: 400, parser: parseInt}) public swipeTimeout: number;

/** Start pointer event to detect action */
protected startEvent?: PointerEvent;
Expand Down Expand Up @@ -85,6 +85,7 @@ export class ESLCarouselTouchMixin extends ESLCarouselPlugin {

/** @returns offset between start point and passed event point */
protected getOffset(event: PointerEvent): number {
if (event.type === 'pointercancel') return 0;
const property = this.$host.config.vertical ? 'clientY' : 'clientX';
return this.startEvent ? (event[property] - this.startEvent[property]) : 0;
}
Expand All @@ -106,12 +107,11 @@ export class ESLCarouselTouchMixin extends ESLCarouselPlugin {
this.startEvent = event;
this.startScrollOffsets = getParentScrollOffsets(event.target as Element, this.$host);

this.$$on('pointermove', this._onPointerMove);
this.$$on('pointerup pointercancel', this._onPointerUp);
this.$$on({group: 'pointer'});
}

/** Processes `mousemove` and `touchmove` events. */
@listen({auto: false})
@listen({auto: false, event: 'pointermove', group: 'pointer'})
protected _onPointerMove(event: PointerEvent): void {
const offset = this.getOffset(event);

Expand All @@ -129,11 +129,10 @@ export class ESLCarouselTouchMixin extends ESLCarouselPlugin {
}

/** Processes `mouseup` and `touchend` events. */
@listen({auto: false})
@listen({auto: false, event: 'pointerup pointercancel', group: 'pointer'})
protected _onPointerUp(event: PointerEvent): void {
// Unbinds drag listeners
this.$$off(this._onPointerMove);
this.$$off(this._onPointerUp);
this.$$off({group: 'pointer'});

if (this.$host.hasPointerCapture(event.pointerId)) {
this.$host.releasePointerCapture(event.pointerId);
Expand All @@ -142,17 +141,13 @@ export class ESLCarouselTouchMixin extends ESLCarouselPlugin {
if (this.$$attr('dragging', false) === null) return;

const offset = this.getOffset(event);
// ignore single click
if (offset === 0) return;
// Commit drag offset
// Commit drag offset (should be commited to 0 if the event is canceled)
if (this.isDragMode) this.$host.renderer.commit(offset);
// Swipe final check
if (this.isSwipeMode && !this.isPrevented && this.isSwipeAccepted(event)) {
if (this.isSwipeMode && offset && !this.isPrevented && this.isSwipeAccepted(event)) {
const target = `${this.swipeType}:${offset < 0 ? 'next' : 'prev'}`;
if (this.$host.canNavigate(target)) this.$host.goTo(target);
}

delete this.startEvent;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/modules/esl-mixin-element/ui/esl-mixin-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export class ESLMixinElement implements ESLBaseComponent, ESLDomElementRelated {
*/
protected attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {}

/** Subscribes (or resubscribes) all known descriptors that matches criteria */
public $$on(criteria: ESLListenerCriteria): ESLEventListener[];
/** Subscribes `handler` method marked with `@listen` decorator */
public $$on(handler: ESLListenerHandler): ESLEventListener[];
/** Subscribes `handler` function by the passed DOM event descriptor {@link ESLListenerDescriptor} or event name */
Expand Down
2 changes: 2 additions & 0 deletions src/modules/esl-utils/abstract/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import type {
} from '../../esl-event-listener/core';

export interface ESLBaseComponent {
/** Subscribes (or resubscribes) all known descriptors that matches criteria */
$$on(criteria: ESLListenerCriteria): ESLEventListener[];
/** Subscribes `handler` method marked with `@listen` decorator */
$$on(handler: ESLListenerHandler): ESLEventListener[];
/** Subscribes `handler` function by the passed DOM event descriptor {@link ESLListenerDescriptor} or event name */
Expand Down

0 comments on commit 2169caf

Please sign in to comment.