From 83aac50fdc5d6df952152c1572e76c4f9878e087 Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Thu, 11 Dec 2025 13:52:34 +0200 Subject: [PATCH 1/4] fix(carousel): improve carousel context handling with async context --- src/components/carousel/carousel-slide.ts | 31 +++++++++++++++++------ src/components/carousel/carousel.ts | 7 ++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/components/carousel/carousel-slide.ts b/src/components/carousel/carousel-slide.ts index 3ed39f941..3cae6e06a 100644 --- a/src/components/carousel/carousel-slide.ts +++ b/src/components/carousel/carousel-slide.ts @@ -1,9 +1,9 @@ -import { consume } from '@lit/context'; import { html, LitElement } from 'lit'; import { property } from 'lit/decorators.js'; import { EaseInOut } from '../../animations/easings.js'; import { addAnimationController } from '../../animations/player.js'; import { carouselContext } from '../common/context.js'; +import { createAsyncContext } from '../common/controllers/async-consumer.js'; import { addInternalsController } from '../common/controllers/internals.js'; import { registerComponent } from '../common/definitions/register.js'; import { formatString } from '../common/util.js'; @@ -38,29 +38,44 @@ export default class IgcCarouselSlideComponent extends LitElement { private readonly _player = addAnimationController(this); - @consume({ context: carouselContext, subscribe: true }) - private readonly _carousel?: IgcCarouselComponent; + private _carousel?: IgcCarouselComponent; + + private readonly _context = createAsyncContext( + this, + carouselContext, + (carousel) => { + this._carousel = carousel; + } + ); + + private get _carouselInstance(): IgcCarouselComponent | undefined { + return this._carousel ?? this._context.value; + } protected get _index(): number { - return this._carousel ? this._carousel.slides.indexOf(this) : 0; + return this._carouselInstance + ? this._carouselInstance.slides.indexOf(this) + : 0; } protected get _total(): number { - return this._carousel ? this._carousel.slides.length : 0; + return this._carouselInstance ? this._carouselInstance.slides.length : 0; } protected get _animation() { - const animation = this._carousel?.animationType ?? 'slide'; + const animation = this._carouselInstance?.animationType ?? 'slide'; if (animation === 'slide') { - return this._carousel?.vertical ? 'slideVer' : 'slideHor'; + return this._carouselInstance?.vertical ? 'slideVer' : 'slideHor'; } return animation; } protected get _labelFormat(): string { - return this._carousel ? this._carousel.slidesLabelFormat : ''; + return this._carouselInstance + ? this._carouselInstance.slidesLabelFormat + : ''; } /** diff --git a/src/components/carousel/carousel.ts b/src/components/carousel/carousel.ts index 97af63bf0..2adb5b55e 100644 --- a/src/components/carousel/carousel.ts +++ b/src/components/carousel/carousel.ts @@ -145,6 +145,10 @@ export default class IgcCarouselComponent extends EventEmitterMixin< initialValue: this, }); + private _setCarouselContext(): void { + this._context.setValue(this, true); + } + @queryAll(IgcCarouselIndicatorComponent.tagName) private readonly _defaultIndicators!: NodeListOf; @@ -350,7 +354,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin< @watch('slidesLabelFormat') @watch('indicatorsLabelFormat') protected _contextChanged(): void { - this._context.setValue(this, true); + this._setCarouselContext(); } @watch('interval') @@ -421,6 +425,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin< protected override async firstUpdated(): Promise { await this.updateComplete; + this._setCarouselContext(); if (!isEmpty(this._slides)) { this._activateSlide( From dd71e9e9568809b4ae535102be642d6492fa996b Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Thu, 11 Dec 2025 14:11:54 +0200 Subject: [PATCH 2/4] chore(carousel): add comment to clarify carousel context initialization --- src/components/carousel/carousel-slide.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/carousel/carousel-slide.ts b/src/components/carousel/carousel-slide.ts index 3cae6e06a..773184973 100644 --- a/src/components/carousel/carousel-slide.ts +++ b/src/components/carousel/carousel-slide.ts @@ -40,6 +40,7 @@ export default class IgcCarouselSlideComponent extends LitElement { private _carousel?: IgcCarouselComponent; + // Set carousel reference once provider is ready private readonly _context = createAsyncContext( this, carouselContext, From b37528c598697aa9acb280b7f55dd3ee5de7013a Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Thu, 11 Dec 2025 14:24:45 +0200 Subject: [PATCH 3/4] fix(carousel): simplify carousel instance retrieval in slide component --- src/components/carousel/carousel-slide.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/components/carousel/carousel-slide.ts b/src/components/carousel/carousel-slide.ts index 773184973..9f5389626 100644 --- a/src/components/carousel/carousel-slide.ts +++ b/src/components/carousel/carousel-slide.ts @@ -49,34 +49,26 @@ export default class IgcCarouselSlideComponent extends LitElement { } ); - private get _carouselInstance(): IgcCarouselComponent | undefined { - return this._carousel ?? this._context.value; - } - protected get _index(): number { - return this._carouselInstance - ? this._carouselInstance.slides.indexOf(this) - : 0; + return this._carousel ? this._carousel.slides.indexOf(this) : 0; } protected get _total(): number { - return this._carouselInstance ? this._carouselInstance.slides.length : 0; + return this._carousel ? this._carousel.slides.length : 0; } protected get _animation() { - const animation = this._carouselInstance?.animationType ?? 'slide'; + const animation = this._carousel?.animationType ?? 'slide'; if (animation === 'slide') { - return this._carouselInstance?.vertical ? 'slideVer' : 'slideHor'; + return this._carousel?.vertical ? 'slideVer' : 'slideHor'; } return animation; } protected get _labelFormat(): string { - return this._carouselInstance - ? this._carouselInstance.slidesLabelFormat - : ''; + return this._carousel ? this._carousel.slidesLabelFormat : ''; } /** From ac5cc48bcd0eb5eeef5afbf8715da5340ad0334f Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Thu, 11 Dec 2025 15:24:32 +0200 Subject: [PATCH 4/4] refactor(carousel): move carousel context initialization to constructor --- src/components/carousel/carousel-slide.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/carousel/carousel-slide.ts b/src/components/carousel/carousel-slide.ts index 9f5389626..bee2938c7 100644 --- a/src/components/carousel/carousel-slide.ts +++ b/src/components/carousel/carousel-slide.ts @@ -40,15 +40,6 @@ export default class IgcCarouselSlideComponent extends LitElement { private _carousel?: IgcCarouselComponent; - // Set carousel reference once provider is ready - private readonly _context = createAsyncContext( - this, - carouselContext, - (carousel) => { - this._carousel = carousel; - } - ); - protected get _index(): number { return this._carousel ? this._carousel.slides.indexOf(this) : 0; } @@ -82,6 +73,15 @@ export default class IgcCarouselSlideComponent extends LitElement { @property({ type: Boolean, reflect: true }) public previous = false; + constructor() { + super(); + + // Set carousel reference once provider is ready (addresses Blazor timing issue) + createAsyncContext(this, carouselContext, (carousel) => { + this._carousel = carousel; + }); + } + /** * @hidden @internal * @deprecated since 5.4.0. Use Carousel's `select` method instead.