Skip to content

Commit 0a23b82

Browse files
committed
feat(esl-carousel): implement updated esl-carousel-relate-to plugin that follows specification and expected flow
1 parent b0ef66c commit 0a23b82

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import {ESLCarouselPlugin} from '../esl-carousel.plugin';
77
import {ESLCarouselSlideEvent} from '../../core/esl-carousel.events';
88

99
export interface ESLCarouselRelateToConfig {
10-
/** Target carousel selector */
10+
/** Target carousel selector. Set to '' or 'none' to disable */
1111
target: string;
12-
/** Proactive mode to relate to the target immediately */
12+
/** A proactive mode to relate to the target immediately */
1313
proactive: boolean;
1414
}
1515

@@ -19,37 +19,52 @@ export interface ESLCarouselRelateToConfig {
1919
@ExportNs('Carousel.RelateTo')
2020
export class ESLCarouselRelateToMixin extends ESLCarouselPlugin<ESLCarouselRelateToConfig> {
2121
public static override is = 'esl-carousel-relate-to';
22+
public static override DEFAULT_CONFIG: ESLCarouselRelateToConfig = {
23+
target: 'none',
24+
proactive: false
25+
};
2226
public static override DEFAULT_CONFIG_KEY = 'target';
2327

28+
/** @returns events name to listen for carousel state changes */
2429
protected get event(): string {
2530
return [this.config.proactive ? ESLCarouselSlideEvent.CHANGE : null, ESLCarouselSlideEvent.AFTER].filter(Boolean).join(' ');
2631
}
2732

2833
/** @returns ESLCarousel target to share state changes */
2934
@memoize()
3035
public get $target(): ESLCarousel | null {
31-
const $target = ESLTraversingQuery.first(this.config.target);
32-
return ($target instanceof ESLCarousel) ? $target : null;
36+
const {target} = this.config;
37+
if (!target || target === 'none') return null;
38+
const $target = ESLTraversingQuery.first(target, this.$host);
39+
// Prevent cyclic reference - target should not be the host itself
40+
if (!($target instanceof ESLCarousel) || $target === this.$host) return null;
41+
return $target;
3342
}
3443

3544
protected override onInit(): void {
3645
if (!this.$target) return;
37-
this.$target.goTo(this.$host.activeIndex, {activator: this}).catch(console.debug);
46+
// Sync host carousel to target's current position
47+
this.$host.goTo(this.$target.activeIndex, {activator: this}).catch(console.debug);
3848
}
3949

4050
@listen({inherit: true})
4151
protected override onConfigChange(): void {
4252
// Listener event change is not handled by resubscribe automatically
4353
this.$$off(this._onSlideChange);
54+
super.onConfigChange();
4455
memoize.clear(this, '$target');
4556
this.$$on(this._onSlideChange);
4657
}
4758

48-
/** Handles event that fires when the carousel slides state is changed. */
49-
@listen({event: ($this: ESLCarouselRelateToMixin) => $this.event})
59+
/** Handles event that fires when the target carousel slides state is changed. */
60+
@listen({
61+
event: ($this: ESLCarouselRelateToMixin) => $this.event,
62+
target: ($this: ESLCarouselRelateToMixin) => $this.$target
63+
})
5064
protected _onSlideChange(e: ESLCarouselSlideEvent): void {
5165
if (!this.$target || e.activator === this) return;
52-
this.$target.goTo(e.indexAfter, {activator: this}).catch(console.debug);
66+
// Make host carousel follow the target carousel
67+
this.$host.goTo(e.indexAfter, {activator: this}).catch(console.debug);
5368
}
5469
}
5570

@@ -58,3 +73,4 @@ declare global {
5873
RelateTo: typeof ESLCarouselRelateToMixin;
5974
}
6075
}
76+

0 commit comments

Comments
 (0)