Skip to content

Commit b02207a

Browse files
committed
fix(esl-carousel): improve collision handling, introduce special type of Error - ESLCarouselNavRejection it represents renderer rejection but not produce noisy log in console
1 parent 2ef7880 commit b02207a

12 files changed

+44
-19
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Custom error that ESLCarousel throws when navigation is rejected due to ongoing animation.
3+
* By default, it does not include a stack trace to avoid cluttering the console.
4+
*/
5+
export class ESLCarouselNavRejection extends Error {
6+
/** Debug mode to enable stack trace in the error log */
7+
public static debug = false;
8+
9+
constructor(index: number | string) {
10+
super(`Navigation skipped to index ${index} due to ongoing animation`);
11+
this.name = '[ESL] Carousel Rejection';
12+
if (!ESLCarouselNavRejection.debug) this.stack = undefined; // disable stack trace
13+
}
14+
}

packages/esl/src/esl-carousel/core/esl-carousel.renderer.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,21 @@ export abstract class ESLCarouselRenderer implements ESLCarouselConfig {
142142
const details = {...params, direction, indexesBefore, indexesAfter};
143143
if (!this.$carousel.dispatchEvent(ESLCarouselSlideEvent.create('BEFORE', details))) return;
144144

145-
this.$carousel.dispatchEvent(ESLCarouselSlideEvent.create('CHANGE', details));
146145
this.setPreActive(index);
146+
this.$carousel.dispatchEvent(ESLCarouselSlideEvent.create('CHANGE', details));
147147

148148
this.transitionDuration = params.stepDuration;
149149
try {
150150
await this.onBeforeAnimate(index, direction, params);
151151
await this.onAnimate(index, direction, params);
152152
await this.onAfterAnimate(index, direction, params);
153+
154+
this.setActive(index, {direction, ...params});
153155
} catch (e: unknown) {
154-
console.error(e);
156+
if (e instanceof Error) throw e;
157+
} finally {
158+
this.transitionDuration = null;
155159
}
156-
this.transitionDuration = null;
157-
158-
this.setActive(index, {direction, ...params});
159160
}
160161

161162
/** Pre-processing animation action. */

packages/esl/src/esl-carousel/core/esl-carousel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export class ESLCarousel extends ESLBaseElement {
228228
const detail = e.detail || {};
229229
if (!isMatches(this, detail.match)) return;
230230
const index = this.$slides.findIndex(($slide) => $slide.contains(e.target as Element));
231-
if (index !== -1 && !this.isActive(index)) this.goTo(index);
231+
if (index !== -1 && !this.isActive(index)) this.goTo(index).catch(console.debug);
232232
}
233233

234234
/** @returns slides that are processed by the current carousel. */

packages/esl/src/esl-carousel/plugin/autoplay/esl-carousel.autoplay.mixin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export class ESLCarouselAutoplayMixin extends ESLCarouselPlugin<ESLCarouselAutop
117117
protected async _onCycle(exec?: boolean): Promise<void> {
118118
this._duration && window.clearTimeout(this._duration);
119119
this._duration = null;
120-
if (exec) await this.$host?.goTo(this.config.command);
120+
if (exec) await this.$host?.goTo(this.config.command).catch(console.debug);
121121
if (!this.enabled || this.active) return;
122122
const {duration} = this;
123123
this._duration = window.setTimeout(() => this._onCycle(true), duration);

packages/esl/src/esl-carousel/plugin/dots/esl-carousel.nav.dots.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export class ESLCarouselNavDots extends ESLBaseElement {
189189
if (!this.$carousel || typeof this.$carousel.goTo !== 'function') return;
190190
const $btn = event.$delegate as HTMLElement;
191191
const target = $btn.getAttribute('esl-carousel-dot') || '';
192-
this.$carousel.goTo(`group:${+target}`);
192+
this.$carousel.goTo(`group:${+target}`).catch(console.debug);
193193
(this.tabIndex >= 0 ? this : $btn).focus({preventScroll: true});
194194
}
195195

packages/esl/src/esl-carousel/plugin/keyboard/esl-carousel.keyboard.mixin.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,21 @@ export class ESLCarouselKeyboardMixin extends ESLCarouselPlugin<ESLCarouselKeybo
2828
return this.$host.config.vertical ? ARROW_UP : ARROW_LEFT;
2929
}
3030

31+
/** @returns result command for carousel */
32+
protected getCommandFromKey(key: string): string {
33+
const {command} = this.config;
34+
if (command === 'none') return '';
35+
if (key === this.nextKey) return `${command || 'slide'}:next`;
36+
if (key === this.prevKey) return `${command || 'slide'}:prev`;
37+
return '';
38+
}
39+
3140
/** Handles `keydown` event */
3241
@listen('keydown')
3342
protected _onKeydown(event: KeyboardEvent): void {
34-
const {command} = this.config;
35-
if (!this.$host || this.$host.animating || command === 'none') return;
36-
if (event.key === this.nextKey) this.$host.goTo(`${command || 'slide'}:next`);
37-
if (event.key === this.prevKey) this.$host.goTo(`${command || 'slide'}:prev`);
43+
if (!this.$host || this.$host.animating) return;
44+
const command = this.getCommandFromKey(event.key);
45+
command && this.$host.goTo(command).catch(console.debug);
3846
}
3947
}
4048

packages/esl/src/esl-carousel/plugin/nav/esl-carousel.nav.mixin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class ESLCarouselNavMixin extends ESLMixinElement {
7676
@listen('click')
7777
protected _onClick(e: PointerEvent): void {
7878
if (!this.$carousel || typeof this.$carousel.goTo !== 'function') return;
79-
this.$carousel.goTo(this.command).catch(console.error);
79+
this.$carousel.goTo(this.command).catch(console.debug);
8080
e.preventDefault();
8181
}
8282
}

packages/esl/src/esl-carousel/plugin/relation/esl-carousel.relation.mixin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export class ESLCarouselRelateToMixin extends ESLCarouselPlugin<ESLCarouselRelat
4444
@listen({event: ($this: ESLCarouselRelateToMixin) => $this.event})
4545
protected _onSlideChange(e: ESLCarouselSlideEvent): void {
4646
if (!this.$target || e.activator === this) return;
47-
this.$target.goTo(this.$host.activeIndex, {activator: this});
47+
this.$target.goTo(this.$host.activeIndex, {activator: this}).catch(console.debug);
4848
}
4949
}
5050

packages/esl/src/esl-carousel/plugin/touch/esl-carousel.touch.mixin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export class ESLCarouselTouchMixin extends ESLCarouselPlugin<ESLCarouselTouchCon
143143
// Swipe final check
144144
if (this.isSwipeMode && offset && !this.isPrevented && this.isSwipeAccepted(event)) {
145145
const target = `${this.config.swipeType}:${offset < 0 ? 'next' : 'prev'}`;
146-
if (this.$host.canNavigate(target)) this.$host.goTo(target, {activator: this});
146+
if (this.$host.canNavigate(target)) this.$host.goTo(target, {activator: this}).catch(console.debug);
147147
}
148148
}
149149
}

packages/esl/src/esl-carousel/plugin/wheel/esl-carousel.wheel.mixin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class ESLCarouselWheelMixin extends ESLCarouselPlugin<ESLCarouselWheelCon
7777
if (!this.$host || this.$host.animating) return;
7878
const delta = this.isVertical ? e.deltaY : e.deltaX;
7979
const direction = delta > 0 ? 'next' : 'prev';
80-
this.$host?.goTo(`${this.config.command || 'slide'}:${direction}`);
80+
this.$host?.goTo(`${this.config.command || 'slide'}:${direction}`).catch(console.debug);
8181
}
8282
}
8383

0 commit comments

Comments
 (0)