@eui/ecl 22.0.0-alpha.56 → 22.0.0-alpha.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/changelog.html +69 -0
- package/docs/components/EclCarouselComponent.html +1 -33
- package/docs/components/EclCarouselItemComponent.html +0 -26
- package/docs/interfaces/EclCarouselItem.html +0 -51
- package/docs/js/search/search_index.js +2 -2
- package/docs/json/EclCarouselComponent.md +0 -2
- package/docs/json/EclCarouselItemComponent.md +0 -2
- package/docs/json/documentation.json +87 -132
- package/docs/llms.txt +3 -6
- package/docs/properties.html +1 -1
- package/fesm2022/eui-ecl-components-ecl-carousel.mjs +2 -34
- package/fesm2022/eui-ecl-components-ecl-carousel.mjs.map +1 -1
- package/package.json +1 -1
- package/types/eui-ecl-components-ecl-carousel.d.ts +1 -24
- package/types/eui-ecl-components-ecl-carousel.d.ts.map +1 -1
package/docs/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# eui documentation
|
|
2
2
|
|
|
3
|
-
> Generated by compodoc 2.0.0 at 2026-11-
|
|
3
|
+
> Generated by compodoc 2.0.0 at 2026-11-06T14:59:45.321Z, llm-md export.
|
|
4
4
|
|
|
5
5
|
## Modules
|
|
6
6
|
|
|
@@ -322,11 +322,10 @@ Methods:
|
|
|
322
322
|
File: `packages/ecl/components/ecl-carousel/ecl-carousel.component.ts`
|
|
323
323
|
Selector: `ecl-carousel`
|
|
324
324
|
|
|
325
|
-
Description: Carousel (slideshow) component following the ECL design system. Renders a sequence of EclCarouselItemComponent slides with autoplay, keyboard navigation, responsive breakpoint awareness, and RTL layout support. The slide engine is powered by Embla (via embla-carousel-angular ), matching the upstream ECL implementation: an infinite loop , the Autoplay plugin driving the teaser loading bars, and a slider pager with previous/next/play/pause controls, a counter, and a tablist of teaser buttons (one per slide). Selector: ecl-carousel . Project ecl-carousel-item elements as slides (also via contentChildren ). ariaLabel — ARIA label for the carousel landmark; aliased as aria-label . isAutoplay — enables automatic slide advancement; boolean attribute. playInterval — milliseconds between automatic transitions; default 5000 .
|
|
325
|
+
Description: Carousel (slideshow) component following the ECL design system. Renders a sequence of EclCarouselItemComponent slides with autoplay, keyboard navigation, responsive breakpoint awareness, and RTL layout support. The slide engine is powered by Embla (via embla-carousel-angular ), matching the upstream ECL implementation: an infinite loop , the Autoplay plugin driving the teaser loading bars, and a slider pager with previous/next/play/pause controls, a counter, and a tablist of teaser buttons (one per slide). Selector: ecl-carousel . Project ecl-carousel-item elements as slides (also via contentChildren ). ariaLabel — ARIA label for the carousel landmark; aliased as aria-label . isAutoplay — enables automatic slide advancement; boolean attribute. playInterval — milliseconds between automatic transitions; default 5000 . slide — emits EclSlideEvent when the active slide changes.
|
|
326
326
|
|
|
327
327
|
Inputs:
|
|
328
328
|
- `aria-label: string | null = 'Carousel description here'` — Aria-label for screen readers to describe the carousel.
|
|
329
|
-
- `counterLabel: string = ''` — Separator label used by the counter, e.g. the "of" in "1 of 5". Defaults to the translated ecl.common.OF key.
|
|
330
329
|
- `isAutoplay: boolean = undefined` — Determines whether the carousel should autoplay.
|
|
331
330
|
- `playInterval: number = 5000` — Interval in milliseconds between automatic slide transitions.
|
|
332
331
|
- `class: string = ''`
|
|
@@ -361,10 +360,9 @@ Methods:
|
|
|
361
360
|
File: `packages/ecl/components/ecl-carousel/ecl-carousel-item.component.ts`
|
|
362
361
|
Selector: `ecl-carousel-item`
|
|
363
362
|
|
|
364
|
-
Description: Single slide item for use inside an EclCarouselComponent . Renders a role="tabpanel" element with an aria-roledescription="slide" and handles the inert attribute so only the active slide is interactive. Selector: ecl-carousel-item .
|
|
363
|
+
Description: Single slide item for use inside an EclCarouselComponent . Renders a role="tabpanel" element with an aria-roledescription="slide" and handles the inert attribute so only the active slide is interactive. Selector: ecl-carousel-item . isCurrent (input alias) — initial active state; kept as a linkedSignal so the parent carousel can update it imperatively as the user navigates. slideClick — emits EclSlideEvent when the slide is clicked. index / ariaLabel — writable signals assigned by the parent carousel. Project an optional EclBannerComponent inside the slide for banner-style slides.
|
|
365
364
|
|
|
366
365
|
Inputs:
|
|
367
|
-
- `id: string` — The unique identifier of the slide.
|
|
368
366
|
- `isCurrent: boolean = false` — Input controlling whether this slide starts as the active/visible one. Automatically coerced to a boolean value.
|
|
369
367
|
- `teaserText: string = ''` — Text shown in the carousel teaser (navigation) button for this slide. Optional; when empty, no teaser label is rendered for the slide.
|
|
370
368
|
- `class: string = ''`
|
|
@@ -7893,7 +7891,6 @@ File: `packages/ecl/components/ecl-carousel/models/ecl-carousel-item.model.ts`
|
|
|
7893
7891
|
Description: Interface implemented by EclCarouselItemComponent . Defines the minimal contract the carousel uses to manage slide state.
|
|
7894
7892
|
|
|
7895
7893
|
Properties:
|
|
7896
|
-
- `id?: Signal<string | undefined>` — Optional slide identifier used for navigation buttons.
|
|
7897
7894
|
- `index: WritableSignal<number | undefined>` — Zero-based index assigned by the parent carousel.
|
|
7898
7895
|
- `isCurrent: WritableSignal<boolean>` — Whether this slide is currently active (visible).
|
|
7899
7896
|
|
package/docs/properties.html
CHANGED
|
@@ -20,7 +20,6 @@ var EclCarouselItemComponent = class EclCarouselItemComponent extends ECLBaseDir
|
|
|
20
20
|
super(...arguments);
|
|
21
21
|
this.el = inject(ElementRef);
|
|
22
22
|
this.ariaLabel = signal(void 0, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
|
|
23
|
-
this.id = input(...ngDevMode ? [void 0, { debugName: "id" }] : /* istanbul ignore next */ []);
|
|
24
23
|
this.isCurrentInput = input(false, {
|
|
25
24
|
...ngDevMode ? { debugName: "isCurrentInput" } : /* istanbul ignore next */ {},
|
|
26
25
|
alias: "isCurrent",
|
|
@@ -54,13 +53,6 @@ var EclCarouselItemComponent = class EclCarouselItemComponent extends ECLBaseDir
|
|
|
54
53
|
isStandalone: true,
|
|
55
54
|
selector: "ecl-carousel-item",
|
|
56
55
|
inputs: {
|
|
57
|
-
id: {
|
|
58
|
-
classPropertyName: "id",
|
|
59
|
-
publicName: "id",
|
|
60
|
-
isSignal: true,
|
|
61
|
-
isRequired: false,
|
|
62
|
-
transformFunction: null
|
|
63
|
-
},
|
|
64
56
|
isCurrentInput: {
|
|
65
57
|
classPropertyName: "isCurrentInput",
|
|
66
58
|
publicName: "isCurrent",
|
|
@@ -123,14 +115,6 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
123
115
|
}]
|
|
124
116
|
}],
|
|
125
117
|
propDecorators: {
|
|
126
|
-
id: [{
|
|
127
|
-
type: i0.Input,
|
|
128
|
-
args: [{
|
|
129
|
-
isSignal: true,
|
|
130
|
-
alias: "id",
|
|
131
|
-
required: false
|
|
132
|
-
}]
|
|
133
|
-
}],
|
|
134
118
|
isCurrentInput: [{
|
|
135
119
|
type: i0.Input,
|
|
136
120
|
args: [{
|
|
@@ -173,7 +157,6 @@ var EclCarouselComponent = class EclCarouselComponent extends ECLBaseDirective {
|
|
|
173
157
|
...ngDevMode ? { debugName: "playInterval" } : /* istanbul ignore next */ {},
|
|
174
158
|
transform: numberAttribute
|
|
175
159
|
});
|
|
176
|
-
this.counterLabel = input("", ...ngDevMode ? [{ debugName: "counterLabel" }] : /* istanbul ignore next */ []);
|
|
177
160
|
this.slide = output();
|
|
178
161
|
this.carouselContainerElement = viewChild("carouselContainer", ...ngDevMode ? [{ debugName: "carouselContainerElement" }] : /* istanbul ignore next */ []);
|
|
179
162
|
this.slides = contentChildren(forwardRef(() => EclCarouselItemComponent), ...ngDevMode ? [{ debugName: "slides" }] : /* istanbul ignore next */ []);
|
|
@@ -537,13 +520,6 @@ var EclCarouselComponent = class EclCarouselComponent extends ECLBaseDirective {
|
|
|
537
520
|
isSignal: true,
|
|
538
521
|
isRequired: false,
|
|
539
522
|
transformFunction: null
|
|
540
|
-
},
|
|
541
|
-
counterLabel: {
|
|
542
|
-
classPropertyName: "counterLabel",
|
|
543
|
-
publicName: "counterLabel",
|
|
544
|
-
isSignal: true,
|
|
545
|
-
isRequired: false,
|
|
546
|
-
transformFunction: null
|
|
547
523
|
}
|
|
548
524
|
},
|
|
549
525
|
outputs: { slide: "slide" },
|
|
@@ -588,7 +564,7 @@ var EclCarouselComponent = class EclCarouselComponent extends ECLBaseDirective {
|
|
|
588
564
|
],
|
|
589
565
|
usesInheritance: true,
|
|
590
566
|
ngImport: i0,
|
|
591
|
-
template: "@if (hasControls()) {\n<div class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__navigation\">\n <div class=\"ecl-carousel__pager-container\">\n <ecl-slider-pager\n class=\"ecl-carousel__pager\"\n [variant]=\"pagerVariant()\"\n size=\"m\"\n [isPlaying]=\"isPagerPlaying()\"\n [activeIndex]=\"getCurrentSlideIndex()\"\n [dotIndices]=\"getDotIndices()\"\n [dotAriaLabels]=\"getDotAriaLabels()\"\n prevExtraClasses=\"ecl-carousel__prev\"\n nextExtraClasses=\"ecl-carousel__next\"\n dotsExtraClasses=\"ecl-carousel__dots\"\n dotExtraClasses=\"ecl-carousel__dot\"\n playExtraClasses=\"ecl-carousel__play\"\n pauseExtraClasses=\"ecl-carousel__pause\"\n (play)=\"onPlayClick()\"\n (pause)=\"onPauseClick()\"\n (prev)=\"onPreviousSlideClick()\"\n (next)=\"onNextSlideClick()\"\n (goTo)=\"onDotClick($event)\">\n </ecl-slider-pager>\n <div class=\"ecl-carousel__counter\" dir=\"ltr\">\n {{ getCounterCurrent() }} {{
|
|
567
|
+
template: "@if (hasControls()) {\n<div class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__navigation\">\n <div class=\"ecl-carousel__pager-container\">\n <ecl-slider-pager\n class=\"ecl-carousel__pager\"\n [variant]=\"pagerVariant()\"\n size=\"m\"\n [isPlaying]=\"isPagerPlaying()\"\n [activeIndex]=\"getCurrentSlideIndex()\"\n [dotIndices]=\"getDotIndices()\"\n [dotAriaLabels]=\"getDotAriaLabels()\"\n prevExtraClasses=\"ecl-carousel__prev\"\n nextExtraClasses=\"ecl-carousel__next\"\n dotsExtraClasses=\"ecl-carousel__dots\"\n dotExtraClasses=\"ecl-carousel__dot\"\n playExtraClasses=\"ecl-carousel__play\"\n pauseExtraClasses=\"ecl-carousel__pause\"\n (play)=\"onPlayClick()\"\n (pause)=\"onPauseClick()\"\n (prev)=\"onPreviousSlideClick()\"\n (next)=\"onNextSlideClick()\"\n (goTo)=\"onDotClick($event)\">\n </ecl-slider-pager>\n <div class=\"ecl-carousel__counter\" dir=\"ltr\">\n {{ getCounterCurrent() }} {{ ('ecl.common.OF' | translate) }} {{ getCounterTotal() }}\n </div>\n </div>\n\n <div class=\"ecl-carousel__teasers\" role=\"tablist\">\n @for (slide of slides(); let i = $index; track slide) {\n <button #teaserButton type=\"button\" class=\"ecl-carousel__teaser-button\" role=\"tab\"\n [attr.data-ecl-carousel-slide-index]=\"i\"\n [attr.aria-current]=\"i === getCurrentSlideIndex() ? true : null\"\n [attr.tabindex]=\"i === getCurrentSlideIndex() ? null : -1\"\n [style.display]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.pointer-events]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.order]=\"getTeaserOrder(i)\" (click)=\"onTeaserClick(i)\"\n (keydown)=\"onTeaserKeyboardPress($event, i)\">\n <span class=\"ecl-carousel__teaser-loading-bar\" aria-hidden=\"true\"\n [class.is-active]=\"(isPlaying() || isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\"\n [class.is-paused]=\"(isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\">\n <span #loadingBar class=\"ecl-carousel__teaser-loading-bar-completion\"></span>\n </span>\n <span class=\"ecl-carousel__teaser-content\">\n @if (slide.teaserText()) {\n <span class=\"ecl-carousel__teaser-title\">{{ slide.teaserText() }}</span>\n }\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n</div>\n}\n<div #carouselContainer class=\"ecl-carousel__viewport\" [class.ecl-carousel-container--padded]=\"isPadded()\"\n emblaCarousel #embla=\"emblaCarousel\" [options]=\"emblaOptions\" [plugins]=\"emblaPlugins\"\n [subscribeToEvents]=\"emblaEvents\" (emblaChange)=\"onEmblaEvent($event)\"\n (mouseenter)=\"onViewportPause()\" (mouseleave)=\"onViewportResume()\"\n (focusin)=\"onViewportPause()\" (focusout)=\"onViewportResume()\">\n <div class=\"ecl-carousel__slides\">\n <ng-content></ng-content>\n </div>\n</div>\n",
|
|
592
568
|
dependencies: [
|
|
593
569
|
{
|
|
594
570
|
kind: "directive",
|
|
@@ -660,7 +636,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
660
636
|
"[class]": "cssClasses()",
|
|
661
637
|
"[style.--ecl-carousel-slide-duration]": "playInterval() + \"ms\""
|
|
662
638
|
},
|
|
663
|
-
template: "@if (hasControls()) {\n<div class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__navigation\">\n <div class=\"ecl-carousel__pager-container\">\n <ecl-slider-pager\n class=\"ecl-carousel__pager\"\n [variant]=\"pagerVariant()\"\n size=\"m\"\n [isPlaying]=\"isPagerPlaying()\"\n [activeIndex]=\"getCurrentSlideIndex()\"\n [dotIndices]=\"getDotIndices()\"\n [dotAriaLabels]=\"getDotAriaLabels()\"\n prevExtraClasses=\"ecl-carousel__prev\"\n nextExtraClasses=\"ecl-carousel__next\"\n dotsExtraClasses=\"ecl-carousel__dots\"\n dotExtraClasses=\"ecl-carousel__dot\"\n playExtraClasses=\"ecl-carousel__play\"\n pauseExtraClasses=\"ecl-carousel__pause\"\n (play)=\"onPlayClick()\"\n (pause)=\"onPauseClick()\"\n (prev)=\"onPreviousSlideClick()\"\n (next)=\"onNextSlideClick()\"\n (goTo)=\"onDotClick($event)\">\n </ecl-slider-pager>\n <div class=\"ecl-carousel__counter\" dir=\"ltr\">\n {{ getCounterCurrent() }} {{
|
|
639
|
+
template: "@if (hasControls()) {\n<div class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__navigation\">\n <div class=\"ecl-carousel__pager-container\">\n <ecl-slider-pager\n class=\"ecl-carousel__pager\"\n [variant]=\"pagerVariant()\"\n size=\"m\"\n [isPlaying]=\"isPagerPlaying()\"\n [activeIndex]=\"getCurrentSlideIndex()\"\n [dotIndices]=\"getDotIndices()\"\n [dotAriaLabels]=\"getDotAriaLabels()\"\n prevExtraClasses=\"ecl-carousel__prev\"\n nextExtraClasses=\"ecl-carousel__next\"\n dotsExtraClasses=\"ecl-carousel__dots\"\n dotExtraClasses=\"ecl-carousel__dot\"\n playExtraClasses=\"ecl-carousel__play\"\n pauseExtraClasses=\"ecl-carousel__pause\"\n (play)=\"onPlayClick()\"\n (pause)=\"onPauseClick()\"\n (prev)=\"onPreviousSlideClick()\"\n (next)=\"onNextSlideClick()\"\n (goTo)=\"onDotClick($event)\">\n </ecl-slider-pager>\n <div class=\"ecl-carousel__counter\" dir=\"ltr\">\n {{ getCounterCurrent() }} {{ ('ecl.common.OF' | translate) }} {{ getCounterTotal() }}\n </div>\n </div>\n\n <div class=\"ecl-carousel__teasers\" role=\"tablist\">\n @for (slide of slides(); let i = $index; track slide) {\n <button #teaserButton type=\"button\" class=\"ecl-carousel__teaser-button\" role=\"tab\"\n [attr.data-ecl-carousel-slide-index]=\"i\"\n [attr.aria-current]=\"i === getCurrentSlideIndex() ? true : null\"\n [attr.tabindex]=\"i === getCurrentSlideIndex() ? null : -1\"\n [style.display]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.pointer-events]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.order]=\"getTeaserOrder(i)\" (click)=\"onTeaserClick(i)\"\n (keydown)=\"onTeaserKeyboardPress($event, i)\">\n <span class=\"ecl-carousel__teaser-loading-bar\" aria-hidden=\"true\"\n [class.is-active]=\"(isPlaying() || isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\"\n [class.is-paused]=\"(isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\">\n <span #loadingBar class=\"ecl-carousel__teaser-loading-bar-completion\"></span>\n </span>\n <span class=\"ecl-carousel__teaser-content\">\n @if (slide.teaserText()) {\n <span class=\"ecl-carousel__teaser-title\">{{ slide.teaserText() }}</span>\n }\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n</div>\n}\n<div #carouselContainer class=\"ecl-carousel__viewport\" [class.ecl-carousel-container--padded]=\"isPadded()\"\n emblaCarousel #embla=\"emblaCarousel\" [options]=\"emblaOptions\" [plugins]=\"emblaPlugins\"\n [subscribeToEvents]=\"emblaEvents\" (emblaChange)=\"onEmblaEvent($event)\"\n (mouseenter)=\"onViewportPause()\" (mouseleave)=\"onViewportResume()\"\n (focusin)=\"onViewportPause()\" (focusout)=\"onViewportResume()\">\n <div class=\"ecl-carousel__slides\">\n <ng-content></ng-content>\n </div>\n</div>\n"
|
|
664
640
|
}]
|
|
665
641
|
}],
|
|
666
642
|
ctorParameters: () => [],
|
|
@@ -689,14 +665,6 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
689
665
|
required: false
|
|
690
666
|
}]
|
|
691
667
|
}],
|
|
692
|
-
counterLabel: [{
|
|
693
|
-
type: i0.Input,
|
|
694
|
-
args: [{
|
|
695
|
-
isSignal: true,
|
|
696
|
-
alias: "counterLabel",
|
|
697
|
-
required: false
|
|
698
|
-
}]
|
|
699
|
-
}],
|
|
700
668
|
slide: [{
|
|
701
669
|
type: i0.Output,
|
|
702
670
|
args: ["slide"]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eui-ecl-components-ecl-carousel.mjs","names":[],"sources":["../../components/ecl-carousel/events/ecl-slide.event.ts","../../components/ecl-carousel/ecl-carousel-item.component.ts","../../components/ecl-carousel/ecl-carousel-item.component.html","../../components/ecl-carousel/ecl-carousel.component.ts","../../components/ecl-carousel/ecl-carousel.component.html","../../components/ecl-carousel/index.ts"],"sourcesContent":["import { EclBaseEvent } from '@eui/ecl/core';\nimport { EclCarouselItem } from '../models/ecl-carousel-item.model';\n\n/**\n * Event emitted by `EclCarouselComponent` when the active slide changes, and by\n * `EclCarouselItemComponent` when a slide is clicked.\n * Carries the `EclCarouselItem` that became active or was clicked.\n */\nexport class EclSlideEvent extends EclBaseEvent {\n /**\n * @param item The carousel item that was activated or clicked.\n */\n constructor(public item: EclCarouselItem) {\n super();\n }\n}","import {\n Component,\n ElementRef,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n contentChild,\n} from '@angular/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EclBannerComponent } from '@eui/ecl/components/ecl-banner';\nimport { EclSlideEvent } from './events/ecl-slide.event';\nimport { EclCarouselItem } from './models/ecl-carousel-item.model';\n\n/**\n * Single slide item for use inside an `EclCarouselComponent`.\n * Renders a `role=\"tabpanel\"` element with an `aria-roledescription=\"slide\"` and handles\n * the `inert` attribute so only the active slide is interactive.\n *\n * - Selector: `ecl-carousel-item`.\n * - `id` — optional unique identifier; used by the carousel for navigation buttons.\n * - `isCurrent` (input alias) — initial active state; kept as a `linkedSignal` so the parent\n * carousel can update it imperatively as the user navigates.\n * - `slideClick` — emits `EclSlideEvent` when the slide is clicked.\n * - `index` / `ariaLabel` — writable signals assigned by the parent carousel.\n * - Project an optional `EclBannerComponent` inside the slide for banner-style slides.\n */\n@Component({\n selector: 'ecl-carousel-item',\n templateUrl: './ecl-carousel-item.component.html',\n host: {\n role: 'tabpanel',\n '[attr.aria-label]': 'ariaLabel()',\n '[attr.aria-roledescription]': '\"slide\"',\n '[attr.inert]': '!isCurrent() || undefined',\n '[class]': 'cssClasses()',\n '(click)': 'onSlideClick()',\n },\n styles: [\n `\n /* TODO: remove by implementing full ECL specs */\n :host:before {\n left: 0 !important;\n display: none;\n }\n `,\n ],\n})\nexport class EclCarouselItemComponent extends ECLBaseDirective implements EclCarouselItem {\n el = inject(ElementRef);\n\n /**\n * The aria-label for the slide, assigned dynamically by the carousel.\n */\n readonly ariaLabel = signal<string | undefined>(undefined);\n\n /**\n * The unique identifier of the slide.\n */\n readonly id = input<string>();\n\n /**\n * Input controlling whether this slide starts as the active/visible one.\n * Automatically coerced to a boolean value.\n */\n readonly isCurrentInput = input(false, { alias: 'isCurrent', transform: booleanAttribute });\n\n /**\n * Indicates whether this slide is currently active/visible.\n * Seeded from the `isCurrent` input but can be updated imperatively by the\n * parent carousel as the user navigates between slides.\n */\n readonly isCurrent = linkedSignal(() => this.isCurrentInput());\n\n /**\n * Text shown in the carousel teaser (navigation) button for this slide.\n * Optional; when empty, no teaser label is rendered for the slide.\n */\n readonly teaserText = input<string>('');\n\n /**\n * Emits an event when the slide is clicked.\n */\n readonly slideClick = output<EclSlideEvent>();\n\n /**\n * Optionally captures a banner component projected into the slide.\n */\n readonly banner = contentChild(forwardRef(() => EclBannerComponent));\n\n /**\n * Internal slide index, assigned dynamically by the carousel.\n */\n readonly index = signal<number | undefined>(undefined);\n\n /**\n * Computes the slide's CSS class.\n */\n protected readonly cssClasses = computed<string>(() =>\n super.getCssClasses('ecl-carousel__slide'));\n\n /**\n * Handles click events on the slide and emits a slideClick event.\n */\n onSlideClick(): void {\n this.slideClick.emit(new EclSlideEvent(this));\n }\n}\n","<ng-content></ng-content>\n","import { BreakpointObserver } from '@angular/cdk/layout';\nimport {\n AfterContentInit,\n ChangeDetectorRef,\n Component,\n DOCUMENT,\n ElementRef,\n OnDestroy,\n OnInit,\n Renderer2,\n afterNextRender,\n booleanAttribute,\n computed,\n contentChildren,\n forwardRef,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { EUI_ECL_SLIDER } from '@eui/ecl/components/ecl-slider';\nimport { ECLBaseDirective, EclRtlService, KeyCode } from '@eui/ecl/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport {\n EmblaEventType,\n EmblaOptionsType,\n EmblaPluginType,\n} from 'embla-carousel';\nimport { EmblaCarouselDirective } from 'embla-carousel-angular';\nimport Autoplay from 'embla-carousel-autoplay';\nimport { Subject, auditTime, fromEvent, takeUntil } from 'rxjs';\nimport { EclCarouselItemComponent } from './ecl-carousel-item.component';\nimport { EclSlideEvent } from './events/ecl-slide.event';\n\n/**\n * Number of teaser buttons visible at once on the desktop breakpoint.\n */\nconst VISIBLE_TEASERS = 4;\n\n/**\n * Carousel (slideshow) component following the ECL design system.\n * Renders a sequence of `EclCarouselItemComponent` slides with autoplay, keyboard navigation,\n * responsive breakpoint awareness, and RTL layout support.\n *\n * The slide engine is powered by Embla (via `embla-carousel-angular`), matching the upstream\n * ECL implementation: an infinite `loop`, the `Autoplay` plugin driving the teaser loading bars,\n * and a slider pager with previous/next/play/pause controls, a counter, and a tablist of teaser\n * buttons (one per slide).\n *\n * - Selector: `ecl-carousel`.\n * - Project `ecl-carousel-item` elements as slides (also via `contentChildren`).\n * - `ariaLabel` — ARIA label for the carousel landmark; aliased as `aria-label`.\n * - `isAutoplay` — enables automatic slide advancement; boolean attribute.\n * - `playInterval` — milliseconds between automatic transitions; default `5000`.\n * - `counterLabel` — separator label used by the counter, defaults to `ecl.common.OF`.\n * - `slide` — emits `EclSlideEvent` when the active slide changes.\n */\n@Component({\n selector: 'ecl-carousel',\n templateUrl: './ecl-carousel.component.html',\n imports: [\n TranslatePipe,\n EmblaCarouselDirective,\n ...EUI_ECL_SLIDER,\n ],\n host: {\n '[attr.aria-label]': 'ariaLabel()',\n '[attr.aria-roledescription]': '\"carousel\"',\n '[class]': 'cssClasses()',\n // Drives the teaser loading-bar animation duration (see @eui/styles).\n // It has no CSS fallback, so without it the progress animation never\n // runs; it must match the autoplay delay.\n '[style.--ecl-carousel-slide-duration]': 'playInterval() + \"ms\"',\n },\n})\nexport class EclCarouselComponent extends ECLBaseDirective implements OnInit, OnDestroy, AfterContentInit {\n /**\n * Aria-label for screen readers to describe the carousel.\n */\n readonly ariaLabel = input<string | null>('Carousel description here', { alias: 'aria-label' });\n\n /**\n * Determines whether the carousel should autoplay.\n */\n readonly isAutoplay = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Interval in milliseconds between automatic slide transitions.\n */\n readonly playInterval = input(5000, { transform: numberAttribute });\n\n /**\n * Separator label used by the counter, e.g. the \"of\" in \"1 of 5\".\n * Defaults to the translated `ecl.common.OF` key.\n */\n readonly counterLabel = input<string>('');\n\n /**\n * Event emitted when a slide change occurs.\n */\n readonly slide = output<EclSlideEvent>();\n\n /**\n * Reference to the main carousel viewport element (the Embla root).\n */\n readonly carouselContainerElement = viewChild<ElementRef>('carouselContainer');\n\n /**\n * Collection of slide components rendered inside the carousel.\n */\n readonly slides = contentChildren(forwardRef(() => EclCarouselItemComponent));\n\n /**\n * Indicates whether autoplay is currently active.\n */\n readonly isPlaying = signal(false);\n\n /**\n * Indicates whether autoplay was manually paused (via the pause button or\n * on mobile). When paused this way the loading bar is cleared.\n */\n readonly isPausedForced = signal(false);\n\n /**\n * Indicates whether the layout is currently in RTL mode.\n */\n isRtl = false;\n\n /**\n * Zero-based index of the currently active slide (mirrors Embla's selected snap).\n */\n private activeIndex = 0;\n\n /**\n * Start index of the currently visible teaser window (desktop only).\n */\n private teaserWindowStart = 0;\n\n /**\n * Indicates whether autoplay is temporarily paused by hover/focus. Unlike a\n * manual pause, the loading bar stays visible and frozen at its current\n * progress (matching ECL), resuming when the pointer/focus leaves.\n */\n protected readonly isHoverPaused = signal(false);\n\n /**\n * Whether the current viewport is at the mobile breakpoint. A signal so the\n * template can react (the pager drops play/pause on mobile, matching ECL,\n * where play/pause is a desktop-only control).\n */\n protected readonly isMobileBreakpoint = signal(false);\n\n /**\n * Whether the viewport is at or above the ECL desktop breakpoint (1140px).\n * This is the boundary the ECL CSS uses to show the play/pause controls and\n * the teaser tablist (and to hide the mobile dots). A signal so the pager\n * variant can react: play/pause only renders at/above this width, matching\n * the CSS so the pause button never leaks onto narrower viewports.\n */\n protected readonly isDesktopBreakpointActive = signal(false);\n\n /**\n * Embla options, mirroring the upstream ECL configuration.\n */\n protected emblaOptions: EmblaOptionsType = {\n loop: true,\n align: 'start',\n duration: 20,\n };\n\n /**\n * Embla plugins. Built once so the Embla directive does not needlessly re-init.\n */\n protected emblaPlugins: EmblaPluginType[] = [];\n\n /**\n * Embla events the component reacts to.\n */\n protected readonly emblaEvents: EmblaEventType[] = [\n 'select',\n 'reInit',\n 'autoplay:timerset',\n ];\n\n /**\n * Reference to the Embla directive driving the slide engine.\n */\n private readonly embla = viewChild<EmblaCarouselDirective>('embla');\n\n /**\n * References to the teaser navigation buttons corresponding to each slide.\n */\n private readonly teaserButtons = viewChildren<ElementRef>('teaserButton');\n\n /**\n * References to the teaser loading-bar completion elements (one per slide),\n * used to restart the progress animation when the active slide changes.\n */\n private readonly loadingBars = viewChildren<ElementRef>('loadingBar');\n\n private isTabletBreakpoint = false;\n private isLargeBreakpoint = false;\n private isDesktopBreakpoint = false;\n\n private destroy$: Subject<boolean> = new Subject<boolean>();\n\n /**\n * Debounce interval (ms) used internally for timing and transitions.\n */\n private readonly TIMEOUT_INTERVAL = 400;\n private readonly cdkBreakpointObserver = inject(BreakpointObserver);\n private readonly cd = inject(ChangeDetectorRef);\n private readonly renderer2 = inject(Renderer2);\n private readonly eclRtlService = inject(EclRtlService);\n private readonly translate = inject(TranslateService);\n private readonly document = inject<Document>(DOCUMENT);\n private readonly window = this.document.defaultView;\n /**\n * Host element, used to locate the slider pager's play/pause buttons by their\n * ECL classes for focus management after a play/pause toggle.\n */\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /**\n * Returns the computed CSS class list for the component.\n */\n protected readonly cssClasses = computed<string>(() =>\n super.getCssClasses('ecl-carousel'));\n\n constructor() {\n super();\n afterNextRender(() => {\n this.observeElementSizeChanges();\n this.observeBreakpointChanges();\n this.syncFromEmbla();\n\n if (this.window) {\n fromEvent(this.window, 'resize')\n .pipe(auditTime(50), takeUntil(this.destroy$))\n .subscribe(() => this.observeElementSizeChanges());\n }\n });\n }\n\n /**\n * Angular lifecycle hook: initializes RTL detection and the Embla plugins.\n */\n ngOnInit(): void {\n this.emblaOptions = {\n ...this.emblaOptions,\n direction: this.isRtl ? 'rtl' : 'ltr',\n };\n const autoplayDesired = this.isAutoplayDesired();\n // Reflect the initial play state so the current slide's loading bar is\n // shown on load (the plugin self-starts via playOnInit).\n this.isPlaying.set(autoplayDesired);\n this.emblaPlugins = [\n Autoplay({\n delay: this.playInterval(),\n // Autoplay is on by default (matching ECL) unless explicitly\n // disabled via [isAutoplay]=\"false\". Letting the plugin start\n // itself avoids a race with Embla's own initialization.\n playOnInit: autoplayDesired,\n stopOnInteraction: false,\n stopOnMouseEnter: true,\n stopOnFocusIn: true,\n }),\n ];\n this.handleRtlChangeState();\n }\n\n /**\n * Angular lifecycle hook: called after content (slides) is initialized.\n */\n ngAfterContentInit(): void {\n setTimeout(() => {\n this.initSlides();\n });\n }\n\n /**\n * Angular lifecycle hook: cleans up subscriptions.\n */\n ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.unsubscribe();\n }\n\n /**\n * Returns whether the carousel has padding applied (e.g., on desktop breakpoint).\n */\n isPadded(): boolean {\n return this.isDesktopBreakpoint;\n }\n\n /**\n * Checks whether there are enough slides to render controls.\n */\n hasControls(): boolean {\n return this.getSlidesCount() > 1;\n }\n\n /**\n * Retrieves the current active slide index (zero-based).\n */\n getCurrentSlideIndex(): number {\n return this.activeIndex;\n }\n\n /**\n * Returns the 1-based position of the active slide (for the counter).\n */\n getCounterCurrent(): number {\n return this.activeIndex + 1;\n }\n\n /**\n * Returns the total number of slides (for the counter).\n */\n getCounterTotal(): number {\n return this.getSlidesCount();\n }\n\n /**\n * Dot indices for the mobile slider pager (one dot per slide). The dots are\n * hidden on desktop via the ECL CSS (`.ecl-carousel__dots { display: none }`)\n * and shown at the mobile breakpoint.\n */\n getDotIndices(): number[] {\n return Array.from({ length: this.getSlidesCount() }, (_unused, dotIndex) => dotIndex);\n }\n\n /**\n * Pre-translated accessible label for each pager dot. Translated here since\n * the shared `ecl-slider-pager` receives plain strings.\n */\n getDotAriaLabels(): string[] {\n const total = this.getSlidesCount();\n return Array.from({ length: total }, (_unused, dotIndex) =>\n this.translate.instant('ecl.carousel.GO-TO-SLIDE', {\n current: dotIndex + 1,\n total,\n }),\n );\n }\n\n /**\n * Returns whether a teaser button should be visible in the current window.\n */\n isTeaserVisible(index: number): boolean {\n const count = this.getSlidesCount();\n if (count <= VISIBLE_TEASERS) {\n return true;\n }\n const position = ((index - this.teaserWindowStart) % count + count) % count;\n return position < VISIBLE_TEASERS;\n }\n\n /**\n * Returns the flex order of a teaser button within the visible window.\n */\n getTeaserOrder(index: number): number {\n const count = this.getSlidesCount();\n return ((index - this.teaserWindowStart) % count + count) % count;\n }\n\n /**\n * Whether the pager should show the \"pause\" control (i.e. autoplay is\n * actively running). While the pointer/focus hover-pauses the carousel the\n * timer is suspended, so the pager must show \"play\" even though a manual\n * pause was not triggered. Mirrors upstream ECL, where hovering flips the\n * control to play.\n */\n protected isPagerPlaying(): boolean {\n return this.isPlaying() && !this.isHoverPaused();\n }\n\n /**\n * Pager variant by breakpoint. Below the ECL desktop breakpoint (1140px)\n * the carousel shows only the dots navigation (prev / dots / next);\n * play/pause is a desktop-only control in ECL. Rendering `'dots'` there\n * avoids the pager's inline play/pause `display` style (which would\n * otherwise beat the ECL CSS and leave the pause button visible on narrower\n * viewports). At/above 1140px the dots are hidden by CSS, so\n * `'play-pause-dots'` yields play/pause + prev/next + teasers.\n *\n * The 1140px boundary mirrors the media query the ECL CSS uses to toggle\n * `.ecl-carousel__play/__pause` and `.ecl-carousel__teasers`.\n */\n protected pagerVariant(): 'dots' | 'play-pause-dots' {\n return this.isDesktopBreakpointActive() ? 'play-pause-dots' : 'dots';\n }\n\n /**\n * Handles the throttled Embla events the component subscribed to.\n */\n protected onEmblaEvent(event: EmblaEventType): void {\n switch (event) {\n case 'select':\n case 'reInit':\n this.syncFromEmbla();\n break;\n case 'autoplay:timerset':\n // Fired each time the autoplay timer (re)starts for the current\n // slide; replay the loading-bar fill animation from zero.\n this.restartActiveLoadingBar();\n break;\n default:\n break;\n }\n }\n\n /**\n * Starts autoplay.\n *\n * @param moveFocus when true (a user clicked play) focus moves to the pause\n * button. Auto-starts (e.g. on breakpoint changes) pass false so the\n * page is not scrolled to the carousel on load.\n */\n protected onPlayClick(moveFocus = true): void {\n this.getAutoplay()?.play();\n this.isPlaying.set(true);\n this.isPausedForced.set(false);\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n if (moveFocus) {\n this.focusPagerButton('.ecl-carousel__pause');\n }\n }\n\n /**\n * Stops autoplay and focuses the play button.\n */\n protected onPauseClick(): void {\n // Pause (not full stop): halt the autoplay timer but keep the active\n // teaser loading bar visible, frozen at its current progress (matching\n // upstream ECL's `handleAutoPlay(false, true)`). The installed\n // embla-carousel-autoplay exposes no `pause()`, so we call `stop()`\n // WITHOUT `reset()` — the frozen bar is driven by our `is-paused` CSS\n // class, not the plugin. A full stop+reset (which clears the bar) only\n // happens on prev/next/teaser navigation via `stopAutoplay()`.\n this.getAutoplay()?.stop();\n this.isPlaying.set(false);\n this.isPausedForced.set(true);\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n this.focusPagerButton('.ecl-carousel__play');\n }\n\n /**\n * Navigates to the next slide and stops autoplay.\n */\n protected onNextSlideClick(): void {\n this.stopAutoplay();\n this.embla()?.scrollNext();\n }\n\n /**\n * Navigates to the previous slide and stops autoplay.\n */\n protected onPreviousSlideClick(): void {\n this.stopAutoplay();\n this.embla()?.scrollPrev();\n }\n\n /**\n * Handles user interaction with a teaser button: activates the matching slide.\n */\n protected onTeaserClick(index: number): void {\n this.stopAutoplay();\n this.embla()?.scrollTo(index);\n }\n\n /**\n * Handles a dot activation from the mobile slider pager: scrolls to the\n * matching slide and stops autoplay (same behavior as a teaser click).\n */\n protected onDotClick(index: number): void {\n this.stopAutoplay();\n this.embla()?.scrollTo(index);\n }\n\n /**\n * Handles keyboard navigation (ArrowLeft/ArrowRight) across teaser buttons.\n */\n protected onTeaserKeyboardPress(event: KeyboardEvent, index: number): void {\n if (event.key !== KeyCode.ARROW_RIGHT && event.key !== KeyCode.ARROW_LEFT) {\n return;\n }\n event.preventDefault();\n const direction = event.key === KeyCode.ARROW_RIGHT ? 1 : -1;\n const count = this.getSlidesCount();\n const nextIndex = (index + direction + count) % count;\n this.stopAutoplay();\n this.embla()?.scrollTo(nextIndex);\n this.focusOnButton(this.teaserButtons()[nextIndex]);\n }\n\n /**\n * Freezes the loading bar while the pointer/focus is over the carousel.\n * The Embla autoplay plugin pauses the timer itself (stopOnMouseEnter /\n * stopOnFocusIn); this only mirrors that as a visible paused state.\n */\n protected onViewportPause(): void {\n if (this.isPlaying() && !this.isPausedForced()) {\n this.isHoverPaused.set(true);\n this.cd.detectChanges();\n }\n }\n\n /**\n * Resumes the loading bar once the pointer/focus leaves the carousel.\n */\n protected onViewportResume(): void {\n if (this.isHoverPaused()) {\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n }\n }\n\n /**\n * Sets focus on the specified button.\n */\n private focusOnButton(button: ElementRef): void {\n if (!button) {\n return;\n }\n button.nativeElement.focus();\n }\n\n /**\n * Focuses the slider pager button matching the given ECL class selector\n * (e.g. `.ecl-carousel__play`). Used after a play/pause toggle so focus\n * follows the now-visible control, since the pager swaps play/pause\n * visibility via CSS. No-op if the button is not rendered (e.g. mobile).\n */\n private focusPagerButton(selector: string): void {\n const button = this.hostEl.nativeElement.querySelector<HTMLElement>(selector);\n button?.focus();\n }\n\n /**\n * Returns the Embla autoplay plugin instance, but only when the carousel\n * actually has more than one scroll snap.\n *\n * The `embla-carousel-autoplay` plugin skips its own initialization when\n * `scrollSnapList().length <= 1` (see the plugin's `init`), which leaves its\n * internal `delay` lookup table undefined. Calling `play()` in that state\n * throws (`delay[selectedScrollSnap()]` -> reading `0` of undefined). This\n * happens whenever Embla cannot lay out multiple snaps — notably in a jsdom\n * test or during SSR. Gating on the same `> 1` condition the plugin uses\n * keeps autoplay a safe no-op until the carousel is genuinely slideable.\n */\n private getAutoplay() {\n const api = this.embla()?.emblaApi;\n if (!api || api.scrollSnapList().length <= 1) {\n return undefined;\n }\n return api.plugins()?.autoplay;\n }\n\n /**\n * Whether autoplay should run. On by default (matching ECL); only disabled\n * when the consumer explicitly sets `[isAutoplay]=\"false\"`.\n */\n private isAutoplayDesired(): boolean {\n const isAutoplay = this.isAutoplay();\n return isAutoplay || isAutoplay === undefined;\n }\n\n /**\n * Stops autoplay and resets it (mirrors ECL's `handleAutoPlay(true)`),\n * clearing the loading-bar state.\n */\n private stopAutoplay(): void {\n const autoplay = this.getAutoplay();\n autoplay?.stop();\n autoplay?.reset();\n this.isPlaying.set(false);\n this.isPausedForced.set(false);\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n }\n\n /**\n * Synchronizes component state from Embla's current selected snap:\n * active index, slide `isCurrent` flags, teaser window and the slide event.\n */\n private syncFromEmbla(): void {\n const api = this.embla()?.emblaApi;\n if (!api) {\n return;\n }\n const selected = api.selectedScrollSnap();\n this.setActiveIndex(selected);\n this.updateTeaserWindow();\n this.slide.emit(new EclSlideEvent(this.slides().at(this.activeIndex)));\n this.cd.detectChanges();\n }\n\n /**\n * Subscribes to RTL layout state changes to adapt carousel direction.\n */\n private handleRtlChangeState(): void {\n this.eclRtlService.currentRtlState$.pipe(takeUntil(this.destroy$)).subscribe((rtlState) => {\n const changed = this.isRtl !== rtlState;\n this.isRtl = rtlState;\n if (changed) {\n this.emblaOptions = {\n ...this.emblaOptions,\n direction: this.isRtl ? 'rtl' : 'ltr',\n };\n this.cd.detectChanges();\n }\n });\n }\n\n /**\n * Initializes slides (index, ARIA label, banner height management).\n */\n private initSlides(): void {\n const slides = this.slides();\n slides.forEach((item, idx) => {\n item.index.set(idx);\n item.ariaLabel.set(`slide ${idx + 1} of ${slides.length}`);\n item.isCurrent.set(idx === 0);\n const banner = item.banner();\n if (banner) {\n banner.skipHeightManagement = true;\n }\n });\n this.cd.detectChanges();\n }\n\n /**\n * Updates the active index and synchronizes slide active/inert state.\n */\n private setActiveIndex(index: number): void {\n this.activeIndex = index;\n this.slides().forEach((item, idx) => {\n item.isCurrent.set(idx === index);\n });\n }\n\n /**\n * Restarts the CSS progress animation on the active slide's loading bar.\n * The animation uses `forwards`, so re-applying the `is-active` class alone\n * will not replay it; the animation must be reset explicitly.\n */\n private restartActiveLoadingBar(): void {\n if (!this.getAutoplay()?.isPlaying()) {\n return;\n }\n const bar = this.loadingBars()[this.activeIndex]?.nativeElement as HTMLElement | undefined;\n if (!bar) {\n return;\n }\n bar.style.animation = 'none';\n // Force reflow so the browser registers the reset before re-enabling.\n void bar.offsetWidth;\n bar.style.animation = '';\n }\n\n /**\n * Advances the visible teaser window when the active slide moves out of it.\n */\n private updateTeaserWindow(): void {\n const count = this.getSlidesCount();\n if (count <= VISIBLE_TEASERS) {\n this.teaserWindowStart = 0;\n return;\n }\n const firstHiddenIndex = (this.teaserWindowStart + VISIBLE_TEASERS) % count;\n if (this.activeIndex === firstHiddenIndex) {\n this.teaserWindowStart = firstHiddenIndex;\n }\n }\n\n /**\n * Returns the number of actual visible slides.\n */\n private getSlidesCount(): number {\n return this.slides()?.length ?? 0;\n }\n\n /**\n * Observes screen breakpoint changes to adjust autoplay and layout behavior.\n */\n private observeBreakpointChanges(): void {\n this.cdkBreakpointObserver\n .observe([\n '(max-width: 768px)',\n '(min-width: 998px)',\n '(min-width: 1140px)',\n '(min-width: 1140px) and (max-width: 1260px)',\n ])\n .pipe(takeUntil(this.destroy$))\n .subscribe((result) => {\n this.isMobileBreakpoint.set(result.breakpoints['(max-width: 768px)']);\n this.isTabletBreakpoint = result.breakpoints['(min-width: 998px)'];\n this.isLargeBreakpoint = result.breakpoints['(min-width: 1140px)'];\n this.isDesktopBreakpointActive.set(result.breakpoints['(min-width: 1140px)']);\n this.isDesktopBreakpoint = result.breakpoints['(min-width: 1140px) and (max-width: 1260px)'];\n\n // Deactivate autoplay on mobile; (re)activate it on larger\n // screens if autoplay is desired. Focus is never moved here so\n // the page is not scrolled to the carousel on load/resize.\n if (this.isMobileBreakpoint()) {\n this.stopAutoplay();\n return;\n }\n\n if (this.isTabletBreakpoint && this.isAutoplayDesired() && !this.isPausedForced()) {\n this.onPlayClick(false);\n }\n });\n }\n\n /**\n * Observes changes to the carousel's viewport element size using a timeout debounce.\n */\n private observeElementSizeChanges(): void {\n setTimeout(() => {\n if (this.isLargeBreakpoint) {\n this.checkBannerHeights();\n } else {\n this.resetHeight();\n }\n this.embla()?.reInit();\n }, this.TIMEOUT_INTERVAL);\n }\n\n /**\n * Normalizes the height of all banners to match the tallest banner.\n */\n private checkBannerHeights(): void {\n this.slides().forEach((slide) => {\n const banner = slide.banner();\n if (banner) {\n banner.calculateHeight();\n }\n });\n\n const heightValues = this.slides().map((slide) => {\n const el = slide.banner()?.el.nativeElement;\n if (!el) return undefined;\n\n const styleHeight = el.style.height;\n\n if (styleHeight === 'auto' || styleHeight === '') {\n return el.offsetHeight;\n }\n\n const height = parseInt(styleHeight, 10);\n if (Number.isNaN(height) || height === 100) {\n return 1;\n }\n\n return height;\n });\n\n const elementHeights = heightValues.filter((h) => h !== undefined) as number[];\n const tallestElementHeight = Math.max(...elementHeights);\n\n const slides = this.slides();\n if (tallestElementHeight > 1 && elementHeights.length === slides.length) {\n slides.forEach((slide) => {\n const banner = slide.banner();\n if (!banner) return;\n\n const el = banner.el.nativeElement;\n const bannerImage = banner.eclBannerImage();\n const bannerVideo = banner.eclBannerVideo();\n\n this.renderer2.setStyle(el, 'height', `${tallestElementHeight}px`);\n this.renderer2.setStyle(el, 'aspect-ratio', 'auto');\n\n if (bannerImage) {\n this.renderer2.setStyle(bannerImage.el.nativeElement, 'aspect-ratio', 'auto');\n }\n if (bannerVideo) {\n this.renderer2.setStyle(bannerVideo.el.nativeElement, 'aspect-ratio', 'auto');\n }\n });\n }\n }\n\n /**\n * Clears all explicit banner height and aspect ratio styling for smaller breakpoints.\n */\n private resetHeight(): void {\n this.slides().forEach((slide) => {\n const banner = slide.banner();\n if (banner) {\n const bannerImage = banner.eclBannerImage();\n const bannerVideo = banner.eclBannerVideo();\n this.renderer2.removeStyle(banner.el.nativeElement, 'height');\n this.renderer2.removeStyle(banner.el.nativeElement, 'aspect-ratio');\n if (bannerImage) {\n this.renderer2.removeStyle(bannerImage.el.nativeElement, 'aspect-ratio');\n }\n if (bannerVideo) {\n this.renderer2.removeStyle(bannerVideo.el.nativeElement, 'aspect-ratio');\n }\n }\n });\n }\n}\n","@if (hasControls()) {\n<div class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__navigation\">\n <div class=\"ecl-carousel__pager-container\">\n <ecl-slider-pager\n class=\"ecl-carousel__pager\"\n [variant]=\"pagerVariant()\"\n size=\"m\"\n [isPlaying]=\"isPagerPlaying()\"\n [activeIndex]=\"getCurrentSlideIndex()\"\n [dotIndices]=\"getDotIndices()\"\n [dotAriaLabels]=\"getDotAriaLabels()\"\n prevExtraClasses=\"ecl-carousel__prev\"\n nextExtraClasses=\"ecl-carousel__next\"\n dotsExtraClasses=\"ecl-carousel__dots\"\n dotExtraClasses=\"ecl-carousel__dot\"\n playExtraClasses=\"ecl-carousel__play\"\n pauseExtraClasses=\"ecl-carousel__pause\"\n (play)=\"onPlayClick()\"\n (pause)=\"onPauseClick()\"\n (prev)=\"onPreviousSlideClick()\"\n (next)=\"onNextSlideClick()\"\n (goTo)=\"onDotClick($event)\">\n </ecl-slider-pager>\n <div class=\"ecl-carousel__counter\" dir=\"ltr\">\n {{ getCounterCurrent() }} {{ counterLabel() || ('ecl.common.OF' | translate) }} {{ getCounterTotal() }}\n </div>\n </div>\n\n <div class=\"ecl-carousel__teasers\" role=\"tablist\">\n @for (slide of slides(); let i = $index; track slide) {\n <button #teaserButton type=\"button\" class=\"ecl-carousel__teaser-button\" role=\"tab\"\n [attr.data-ecl-carousel-slide-index]=\"i\"\n [attr.aria-current]=\"i === getCurrentSlideIndex() ? true : null\"\n [attr.tabindex]=\"i === getCurrentSlideIndex() ? null : -1\"\n [style.display]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.pointer-events]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.order]=\"getTeaserOrder(i)\" (click)=\"onTeaserClick(i)\"\n (keydown)=\"onTeaserKeyboardPress($event, i)\">\n <span class=\"ecl-carousel__teaser-loading-bar\" aria-hidden=\"true\"\n [class.is-active]=\"(isPlaying() || isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\"\n [class.is-paused]=\"(isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\">\n <span #loadingBar class=\"ecl-carousel__teaser-loading-bar-completion\"></span>\n </span>\n <span class=\"ecl-carousel__teaser-content\">\n @if (slide.teaserText()) {\n <span class=\"ecl-carousel__teaser-title\">{{ slide.teaserText() }}</span>\n }\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n</div>\n}\n<div #carouselContainer class=\"ecl-carousel__viewport\" [class.ecl-carousel-container--padded]=\"isPadded()\"\n emblaCarousel #embla=\"emblaCarousel\" [options]=\"emblaOptions\" [plugins]=\"emblaPlugins\"\n [subscribeToEvents]=\"emblaEvents\" (emblaChange)=\"onEmblaEvent($event)\"\n (mouseenter)=\"onViewportPause()\" (mouseleave)=\"onViewportResume()\"\n (focusin)=\"onViewportPause()\" (focusout)=\"onViewportResume()\">\n <div class=\"ecl-carousel__slides\">\n <ng-content></ng-content>\n </div>\n</div>\n","import { EclCarouselComponent } from './ecl-carousel.component';\nimport { EclCarouselItemComponent } from './ecl-carousel-item.component';\n\nexport * from './ecl-carousel.component';\nexport * from './ecl-carousel-item.component';\nexport * from './events/ecl-slide.event';\nexport * from './models/ecl-carousel-item.model';\n\nexport const EUI_ECL_CAROUSEL = [\n EclCarouselComponent,\n EclCarouselItemComponent,\n] as const;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"eui-ecl-components-ecl-carousel.mjs","names":[],"sources":["../../components/ecl-carousel/events/ecl-slide.event.ts","../../components/ecl-carousel/ecl-carousel-item.component.ts","../../components/ecl-carousel/ecl-carousel-item.component.html","../../components/ecl-carousel/ecl-carousel.component.ts","../../components/ecl-carousel/ecl-carousel.component.html","../../components/ecl-carousel/index.ts"],"sourcesContent":["import { EclBaseEvent } from '@eui/ecl/core';\nimport { EclCarouselItem } from '../models/ecl-carousel-item.model';\n\n/**\n * Event emitted by `EclCarouselComponent` when the active slide changes, and by\n * `EclCarouselItemComponent` when a slide is clicked.\n * Carries the `EclCarouselItem` that became active or was clicked.\n */\nexport class EclSlideEvent extends EclBaseEvent {\n /**\n * @param item The carousel item that was activated or clicked.\n */\n constructor(public item: EclCarouselItem) {\n super();\n }\n}","import {\n Component,\n ElementRef,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n contentChild,\n} from '@angular/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EclBannerComponent } from '@eui/ecl/components/ecl-banner';\nimport { EclSlideEvent } from './events/ecl-slide.event';\nimport { EclCarouselItem } from './models/ecl-carousel-item.model';\n\n/**\n * Single slide item for use inside an `EclCarouselComponent`.\n * Renders a `role=\"tabpanel\"` element with an `aria-roledescription=\"slide\"` and handles\n * the `inert` attribute so only the active slide is interactive.\n *\n * - Selector: `ecl-carousel-item`.\n * - `isCurrent` (input alias) — initial active state; kept as a `linkedSignal` so the parent\n * carousel can update it imperatively as the user navigates.\n * - `slideClick` — emits `EclSlideEvent` when the slide is clicked.\n * - `index` / `ariaLabel` — writable signals assigned by the parent carousel.\n * - Project an optional `EclBannerComponent` inside the slide for banner-style slides.\n */\n@Component({\n selector: 'ecl-carousel-item',\n templateUrl: './ecl-carousel-item.component.html',\n host: {\n role: 'tabpanel',\n '[attr.aria-label]': 'ariaLabel()',\n '[attr.aria-roledescription]': '\"slide\"',\n '[attr.inert]': '!isCurrent() || undefined',\n '[class]': 'cssClasses()',\n '(click)': 'onSlideClick()',\n },\n styles: [\n `\n /* TODO: remove by implementing full ECL specs */\n :host:before {\n left: 0 !important;\n display: none;\n }\n `,\n ],\n})\nexport class EclCarouselItemComponent extends ECLBaseDirective implements EclCarouselItem {\n el = inject(ElementRef);\n\n /**\n * The aria-label for the slide, assigned dynamically by the carousel.\n */\n readonly ariaLabel = signal<string | undefined>(undefined);\n\n /**\n * Input controlling whether this slide starts as the active/visible one.\n * Automatically coerced to a boolean value.\n */\n readonly isCurrentInput = input(false, { alias: 'isCurrent', transform: booleanAttribute });\n\n /**\n * Indicates whether this slide is currently active/visible.\n * Seeded from the `isCurrent` input but can be updated imperatively by the\n * parent carousel as the user navigates between slides.\n */\n readonly isCurrent = linkedSignal(() => this.isCurrentInput());\n\n /**\n * Text shown in the carousel teaser (navigation) button for this slide.\n * Optional; when empty, no teaser label is rendered for the slide.\n */\n readonly teaserText = input<string>('');\n\n /**\n * Emits an event when the slide is clicked.\n */\n readonly slideClick = output<EclSlideEvent>();\n\n /**\n * Optionally captures a banner component projected into the slide.\n */\n readonly banner = contentChild(forwardRef(() => EclBannerComponent));\n\n /**\n * Internal slide index, assigned dynamically by the carousel.\n */\n readonly index = signal<number | undefined>(undefined);\n\n /**\n * Computes the slide's CSS class.\n */\n protected readonly cssClasses = computed<string>(() =>\n super.getCssClasses('ecl-carousel__slide'));\n\n /**\n * Handles click events on the slide and emits a slideClick event.\n */\n onSlideClick(): void {\n this.slideClick.emit(new EclSlideEvent(this));\n }\n}\n","<ng-content></ng-content>\n","import { BreakpointObserver } from '@angular/cdk/layout';\nimport {\n AfterContentInit,\n ChangeDetectorRef,\n Component,\n DOCUMENT,\n ElementRef,\n OnDestroy,\n OnInit,\n Renderer2,\n afterNextRender,\n booleanAttribute,\n computed,\n contentChildren,\n forwardRef,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { EUI_ECL_SLIDER } from '@eui/ecl/components/ecl-slider';\nimport { ECLBaseDirective, EclRtlService, KeyCode } from '@eui/ecl/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport {\n EmblaEventType,\n EmblaOptionsType,\n EmblaPluginType,\n} from 'embla-carousel';\nimport { EmblaCarouselDirective } from 'embla-carousel-angular';\nimport Autoplay from 'embla-carousel-autoplay';\nimport { Subject, auditTime, fromEvent, takeUntil } from 'rxjs';\nimport { EclCarouselItemComponent } from './ecl-carousel-item.component';\nimport { EclSlideEvent } from './events/ecl-slide.event';\n\n/**\n * Number of teaser buttons visible at once on the desktop breakpoint.\n */\nconst VISIBLE_TEASERS = 4;\n\n/**\n * Carousel (slideshow) component following the ECL design system.\n * Renders a sequence of `EclCarouselItemComponent` slides with autoplay, keyboard navigation,\n * responsive breakpoint awareness, and RTL layout support.\n *\n * The slide engine is powered by Embla (via `embla-carousel-angular`), matching the upstream\n * ECL implementation: an infinite `loop`, the `Autoplay` plugin driving the teaser loading bars,\n * and a slider pager with previous/next/play/pause controls, a counter, and a tablist of teaser\n * buttons (one per slide).\n *\n * - Selector: `ecl-carousel`.\n * - Project `ecl-carousel-item` elements as slides (also via `contentChildren`).\n * - `ariaLabel` — ARIA label for the carousel landmark; aliased as `aria-label`.\n * - `isAutoplay` — enables automatic slide advancement; boolean attribute.\n * - `playInterval` — milliseconds between automatic transitions; default `5000`.\n * - `slide` — emits `EclSlideEvent` when the active slide changes.\n */\n@Component({\n selector: 'ecl-carousel',\n templateUrl: './ecl-carousel.component.html',\n imports: [\n TranslatePipe,\n EmblaCarouselDirective,\n ...EUI_ECL_SLIDER,\n ],\n host: {\n '[attr.aria-label]': 'ariaLabel()',\n '[attr.aria-roledescription]': '\"carousel\"',\n '[class]': 'cssClasses()',\n // Drives the teaser loading-bar animation duration (see @eui/styles).\n // It has no CSS fallback, so without it the progress animation never\n // runs; it must match the autoplay delay.\n '[style.--ecl-carousel-slide-duration]': 'playInterval() + \"ms\"',\n },\n})\nexport class EclCarouselComponent extends ECLBaseDirective implements OnInit, OnDestroy, AfterContentInit {\n /**\n * Aria-label for screen readers to describe the carousel.\n */\n readonly ariaLabel = input<string | null>('Carousel description here', { alias: 'aria-label' });\n\n /**\n * Determines whether the carousel should autoplay.\n */\n readonly isAutoplay = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Interval in milliseconds between automatic slide transitions.\n */\n readonly playInterval = input(5000, { transform: numberAttribute });\n\n /**\n * Event emitted when a slide change occurs.\n */\n readonly slide = output<EclSlideEvent>();\n\n /**\n * Reference to the main carousel viewport element (the Embla root).\n */\n readonly carouselContainerElement = viewChild<ElementRef>('carouselContainer');\n\n /**\n * Collection of slide components rendered inside the carousel.\n */\n readonly slides = contentChildren(forwardRef(() => EclCarouselItemComponent));\n\n /**\n * Indicates whether autoplay is currently active.\n */\n readonly isPlaying = signal(false);\n\n /**\n * Indicates whether autoplay was manually paused (via the pause button or\n * on mobile). When paused this way the loading bar is cleared.\n */\n readonly isPausedForced = signal(false);\n\n /**\n * Indicates whether the layout is currently in RTL mode.\n */\n isRtl = false;\n\n /**\n * Zero-based index of the currently active slide (mirrors Embla's selected snap).\n */\n private activeIndex = 0;\n\n /**\n * Start index of the currently visible teaser window (desktop only).\n */\n private teaserWindowStart = 0;\n\n /**\n * Indicates whether autoplay is temporarily paused by hover/focus. Unlike a\n * manual pause, the loading bar stays visible and frozen at its current\n * progress (matching ECL), resuming when the pointer/focus leaves.\n */\n protected readonly isHoverPaused = signal(false);\n\n /**\n * Whether the current viewport is at the mobile breakpoint. A signal so the\n * template can react (the pager drops play/pause on mobile, matching ECL,\n * where play/pause is a desktop-only control).\n */\n protected readonly isMobileBreakpoint = signal(false);\n\n /**\n * Whether the viewport is at or above the ECL desktop breakpoint (1140px).\n * This is the boundary the ECL CSS uses to show the play/pause controls and\n * the teaser tablist (and to hide the mobile dots). A signal so the pager\n * variant can react: play/pause only renders at/above this width, matching\n * the CSS so the pause button never leaks onto narrower viewports.\n */\n protected readonly isDesktopBreakpointActive = signal(false);\n\n /**\n * Embla options, mirroring the upstream ECL configuration.\n */\n protected emblaOptions: EmblaOptionsType = {\n loop: true,\n align: 'start',\n duration: 20,\n };\n\n /**\n * Embla plugins. Built once so the Embla directive does not needlessly re-init.\n */\n protected emblaPlugins: EmblaPluginType[] = [];\n\n /**\n * Embla events the component reacts to.\n */\n protected readonly emblaEvents: EmblaEventType[] = [\n 'select',\n 'reInit',\n 'autoplay:timerset',\n ];\n\n /**\n * Reference to the Embla directive driving the slide engine.\n */\n private readonly embla = viewChild<EmblaCarouselDirective>('embla');\n\n /**\n * References to the teaser navigation buttons corresponding to each slide.\n */\n private readonly teaserButtons = viewChildren<ElementRef>('teaserButton');\n\n /**\n * References to the teaser loading-bar completion elements (one per slide),\n * used to restart the progress animation when the active slide changes.\n */\n private readonly loadingBars = viewChildren<ElementRef>('loadingBar');\n\n private isTabletBreakpoint = false;\n private isLargeBreakpoint = false;\n private isDesktopBreakpoint = false;\n\n private destroy$: Subject<boolean> = new Subject<boolean>();\n\n /**\n * Debounce interval (ms) used internally for timing and transitions.\n */\n private readonly TIMEOUT_INTERVAL = 400;\n private readonly cdkBreakpointObserver = inject(BreakpointObserver);\n private readonly cd = inject(ChangeDetectorRef);\n private readonly renderer2 = inject(Renderer2);\n private readonly eclRtlService = inject(EclRtlService);\n private readonly translate = inject(TranslateService);\n private readonly document = inject<Document>(DOCUMENT);\n private readonly window = this.document.defaultView;\n /**\n * Host element, used to locate the slider pager's play/pause buttons by their\n * ECL classes for focus management after a play/pause toggle.\n */\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /**\n * Returns the computed CSS class list for the component.\n */\n protected readonly cssClasses = computed<string>(() =>\n super.getCssClasses('ecl-carousel'));\n\n constructor() {\n super();\n afterNextRender(() => {\n this.observeElementSizeChanges();\n this.observeBreakpointChanges();\n this.syncFromEmbla();\n\n if (this.window) {\n fromEvent(this.window, 'resize')\n .pipe(auditTime(50), takeUntil(this.destroy$))\n .subscribe(() => this.observeElementSizeChanges());\n }\n });\n }\n\n /**\n * Angular lifecycle hook: initializes RTL detection and the Embla plugins.\n */\n ngOnInit(): void {\n this.emblaOptions = {\n ...this.emblaOptions,\n direction: this.isRtl ? 'rtl' : 'ltr',\n };\n const autoplayDesired = this.isAutoplayDesired();\n // Reflect the initial play state so the current slide's loading bar is\n // shown on load (the plugin self-starts via playOnInit).\n this.isPlaying.set(autoplayDesired);\n this.emblaPlugins = [\n Autoplay({\n delay: this.playInterval(),\n // Autoplay is on by default (matching ECL) unless explicitly\n // disabled via [isAutoplay]=\"false\". Letting the plugin start\n // itself avoids a race with Embla's own initialization.\n playOnInit: autoplayDesired,\n stopOnInteraction: false,\n stopOnMouseEnter: true,\n stopOnFocusIn: true,\n }),\n ];\n this.handleRtlChangeState();\n }\n\n /**\n * Angular lifecycle hook: called after content (slides) is initialized.\n */\n ngAfterContentInit(): void {\n setTimeout(() => {\n this.initSlides();\n });\n }\n\n /**\n * Angular lifecycle hook: cleans up subscriptions.\n */\n ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.unsubscribe();\n }\n\n /**\n * Returns whether the carousel has padding applied (e.g., on desktop breakpoint).\n */\n isPadded(): boolean {\n return this.isDesktopBreakpoint;\n }\n\n /**\n * Checks whether there are enough slides to render controls.\n */\n hasControls(): boolean {\n return this.getSlidesCount() > 1;\n }\n\n /**\n * Retrieves the current active slide index (zero-based).\n */\n getCurrentSlideIndex(): number {\n return this.activeIndex;\n }\n\n /**\n * Returns the 1-based position of the active slide (for the counter).\n */\n getCounterCurrent(): number {\n return this.activeIndex + 1;\n }\n\n /**\n * Returns the total number of slides (for the counter).\n */\n getCounterTotal(): number {\n return this.getSlidesCount();\n }\n\n /**\n * Dot indices for the mobile slider pager (one dot per slide). The dots are\n * hidden on desktop via the ECL CSS (`.ecl-carousel__dots { display: none }`)\n * and shown at the mobile breakpoint.\n */\n getDotIndices(): number[] {\n return Array.from({ length: this.getSlidesCount() }, (_unused, dotIndex) => dotIndex);\n }\n\n /**\n * Pre-translated accessible label for each pager dot. Translated here since\n * the shared `ecl-slider-pager` receives plain strings.\n */\n getDotAriaLabels(): string[] {\n const total = this.getSlidesCount();\n return Array.from({ length: total }, (_unused, dotIndex) =>\n this.translate.instant('ecl.carousel.GO-TO-SLIDE', {\n current: dotIndex + 1,\n total,\n }),\n );\n }\n\n /**\n * Returns whether a teaser button should be visible in the current window.\n */\n isTeaserVisible(index: number): boolean {\n const count = this.getSlidesCount();\n if (count <= VISIBLE_TEASERS) {\n return true;\n }\n const position = ((index - this.teaserWindowStart) % count + count) % count;\n return position < VISIBLE_TEASERS;\n }\n\n /**\n * Returns the flex order of a teaser button within the visible window.\n */\n getTeaserOrder(index: number): number {\n const count = this.getSlidesCount();\n return ((index - this.teaserWindowStart) % count + count) % count;\n }\n\n /**\n * Whether the pager should show the \"pause\" control (i.e. autoplay is\n * actively running). While the pointer/focus hover-pauses the carousel the\n * timer is suspended, so the pager must show \"play\" even though a manual\n * pause was not triggered. Mirrors upstream ECL, where hovering flips the\n * control to play.\n */\n protected isPagerPlaying(): boolean {\n return this.isPlaying() && !this.isHoverPaused();\n }\n\n /**\n * Pager variant by breakpoint. Below the ECL desktop breakpoint (1140px)\n * the carousel shows only the dots navigation (prev / dots / next);\n * play/pause is a desktop-only control in ECL. Rendering `'dots'` there\n * avoids the pager's inline play/pause `display` style (which would\n * otherwise beat the ECL CSS and leave the pause button visible on narrower\n * viewports). At/above 1140px the dots are hidden by CSS, so\n * `'play-pause-dots'` yields play/pause + prev/next + teasers.\n *\n * The 1140px boundary mirrors the media query the ECL CSS uses to toggle\n * `.ecl-carousel__play/__pause` and `.ecl-carousel__teasers`.\n */\n protected pagerVariant(): 'dots' | 'play-pause-dots' {\n return this.isDesktopBreakpointActive() ? 'play-pause-dots' : 'dots';\n }\n\n /**\n * Handles the throttled Embla events the component subscribed to.\n */\n protected onEmblaEvent(event: EmblaEventType): void {\n switch (event) {\n case 'select':\n case 'reInit':\n this.syncFromEmbla();\n break;\n case 'autoplay:timerset':\n // Fired each time the autoplay timer (re)starts for the current\n // slide; replay the loading-bar fill animation from zero.\n this.restartActiveLoadingBar();\n break;\n default:\n break;\n }\n }\n\n /**\n * Starts autoplay.\n *\n * @param moveFocus when true (a user clicked play) focus moves to the pause\n * button. Auto-starts (e.g. on breakpoint changes) pass false so the\n * page is not scrolled to the carousel on load.\n */\n protected onPlayClick(moveFocus = true): void {\n this.getAutoplay()?.play();\n this.isPlaying.set(true);\n this.isPausedForced.set(false);\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n if (moveFocus) {\n this.focusPagerButton('.ecl-carousel__pause');\n }\n }\n\n /**\n * Stops autoplay and focuses the play button.\n */\n protected onPauseClick(): void {\n // Pause (not full stop): halt the autoplay timer but keep the active\n // teaser loading bar visible, frozen at its current progress (matching\n // upstream ECL's `handleAutoPlay(false, true)`). The installed\n // embla-carousel-autoplay exposes no `pause()`, so we call `stop()`\n // WITHOUT `reset()` — the frozen bar is driven by our `is-paused` CSS\n // class, not the plugin. A full stop+reset (which clears the bar) only\n // happens on prev/next/teaser navigation via `stopAutoplay()`.\n this.getAutoplay()?.stop();\n this.isPlaying.set(false);\n this.isPausedForced.set(true);\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n this.focusPagerButton('.ecl-carousel__play');\n }\n\n /**\n * Navigates to the next slide and stops autoplay.\n */\n protected onNextSlideClick(): void {\n this.stopAutoplay();\n this.embla()?.scrollNext();\n }\n\n /**\n * Navigates to the previous slide and stops autoplay.\n */\n protected onPreviousSlideClick(): void {\n this.stopAutoplay();\n this.embla()?.scrollPrev();\n }\n\n /**\n * Handles user interaction with a teaser button: activates the matching slide.\n */\n protected onTeaserClick(index: number): void {\n this.stopAutoplay();\n this.embla()?.scrollTo(index);\n }\n\n /**\n * Handles a dot activation from the mobile slider pager: scrolls to the\n * matching slide and stops autoplay (same behavior as a teaser click).\n */\n protected onDotClick(index: number): void {\n this.stopAutoplay();\n this.embla()?.scrollTo(index);\n }\n\n /**\n * Handles keyboard navigation (ArrowLeft/ArrowRight) across teaser buttons.\n */\n protected onTeaserKeyboardPress(event: KeyboardEvent, index: number): void {\n if (event.key !== KeyCode.ARROW_RIGHT && event.key !== KeyCode.ARROW_LEFT) {\n return;\n }\n event.preventDefault();\n const direction = event.key === KeyCode.ARROW_RIGHT ? 1 : -1;\n const count = this.getSlidesCount();\n const nextIndex = (index + direction + count) % count;\n this.stopAutoplay();\n this.embla()?.scrollTo(nextIndex);\n this.focusOnButton(this.teaserButtons()[nextIndex]);\n }\n\n /**\n * Freezes the loading bar while the pointer/focus is over the carousel.\n * The Embla autoplay plugin pauses the timer itself (stopOnMouseEnter /\n * stopOnFocusIn); this only mirrors that as a visible paused state.\n */\n protected onViewportPause(): void {\n if (this.isPlaying() && !this.isPausedForced()) {\n this.isHoverPaused.set(true);\n this.cd.detectChanges();\n }\n }\n\n /**\n * Resumes the loading bar once the pointer/focus leaves the carousel.\n */\n protected onViewportResume(): void {\n if (this.isHoverPaused()) {\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n }\n }\n\n /**\n * Sets focus on the specified button.\n */\n private focusOnButton(button: ElementRef): void {\n if (!button) {\n return;\n }\n button.nativeElement.focus();\n }\n\n /**\n * Focuses the slider pager button matching the given ECL class selector\n * (e.g. `.ecl-carousel__play`). Used after a play/pause toggle so focus\n * follows the now-visible control, since the pager swaps play/pause\n * visibility via CSS. No-op if the button is not rendered (e.g. mobile).\n */\n private focusPagerButton(selector: string): void {\n const button = this.hostEl.nativeElement.querySelector<HTMLElement>(selector);\n button?.focus();\n }\n\n /**\n * Returns the Embla autoplay plugin instance, but only when the carousel\n * actually has more than one scroll snap.\n *\n * The `embla-carousel-autoplay` plugin skips its own initialization when\n * `scrollSnapList().length <= 1` (see the plugin's `init`), which leaves its\n * internal `delay` lookup table undefined. Calling `play()` in that state\n * throws (`delay[selectedScrollSnap()]` -> reading `0` of undefined). This\n * happens whenever Embla cannot lay out multiple snaps — notably in a jsdom\n * test or during SSR. Gating on the same `> 1` condition the plugin uses\n * keeps autoplay a safe no-op until the carousel is genuinely slideable.\n */\n private getAutoplay() {\n const api = this.embla()?.emblaApi;\n if (!api || api.scrollSnapList().length <= 1) {\n return undefined;\n }\n return api.plugins()?.autoplay;\n }\n\n /**\n * Whether autoplay should run. On by default (matching ECL); only disabled\n * when the consumer explicitly sets `[isAutoplay]=\"false\"`.\n */\n private isAutoplayDesired(): boolean {\n const isAutoplay = this.isAutoplay();\n return isAutoplay || isAutoplay === undefined;\n }\n\n /**\n * Stops autoplay and resets it (mirrors ECL's `handleAutoPlay(true)`),\n * clearing the loading-bar state.\n */\n private stopAutoplay(): void {\n const autoplay = this.getAutoplay();\n autoplay?.stop();\n autoplay?.reset();\n this.isPlaying.set(false);\n this.isPausedForced.set(false);\n this.isHoverPaused.set(false);\n this.cd.detectChanges();\n }\n\n /**\n * Synchronizes component state from Embla's current selected snap:\n * active index, slide `isCurrent` flags, teaser window and the slide event.\n */\n private syncFromEmbla(): void {\n const api = this.embla()?.emblaApi;\n if (!api) {\n return;\n }\n const selected = api.selectedScrollSnap();\n this.setActiveIndex(selected);\n this.updateTeaserWindow();\n this.slide.emit(new EclSlideEvent(this.slides().at(this.activeIndex)));\n this.cd.detectChanges();\n }\n\n /**\n * Subscribes to RTL layout state changes to adapt carousel direction.\n */\n private handleRtlChangeState(): void {\n this.eclRtlService.currentRtlState$.pipe(takeUntil(this.destroy$)).subscribe((rtlState) => {\n const changed = this.isRtl !== rtlState;\n this.isRtl = rtlState;\n if (changed) {\n this.emblaOptions = {\n ...this.emblaOptions,\n direction: this.isRtl ? 'rtl' : 'ltr',\n };\n this.cd.detectChanges();\n }\n });\n }\n\n /**\n * Initializes slides (index, ARIA label, banner height management).\n */\n private initSlides(): void {\n const slides = this.slides();\n slides.forEach((item, idx) => {\n item.index.set(idx);\n item.ariaLabel.set(`slide ${idx + 1} of ${slides.length}`);\n item.isCurrent.set(idx === 0);\n const banner = item.banner();\n if (banner) {\n banner.skipHeightManagement = true;\n }\n });\n this.cd.detectChanges();\n }\n\n /**\n * Updates the active index and synchronizes slide active/inert state.\n */\n private setActiveIndex(index: number): void {\n this.activeIndex = index;\n this.slides().forEach((item, idx) => {\n item.isCurrent.set(idx === index);\n });\n }\n\n /**\n * Restarts the CSS progress animation on the active slide's loading bar.\n * The animation uses `forwards`, so re-applying the `is-active` class alone\n * will not replay it; the animation must be reset explicitly.\n */\n private restartActiveLoadingBar(): void {\n if (!this.getAutoplay()?.isPlaying()) {\n return;\n }\n const bar = this.loadingBars()[this.activeIndex]?.nativeElement as HTMLElement | undefined;\n if (!bar) {\n return;\n }\n bar.style.animation = 'none';\n // Force reflow so the browser registers the reset before re-enabling.\n void bar.offsetWidth;\n bar.style.animation = '';\n }\n\n /**\n * Advances the visible teaser window when the active slide moves out of it.\n */\n private updateTeaserWindow(): void {\n const count = this.getSlidesCount();\n if (count <= VISIBLE_TEASERS) {\n this.teaserWindowStart = 0;\n return;\n }\n const firstHiddenIndex = (this.teaserWindowStart + VISIBLE_TEASERS) % count;\n if (this.activeIndex === firstHiddenIndex) {\n this.teaserWindowStart = firstHiddenIndex;\n }\n }\n\n /**\n * Returns the number of actual visible slides.\n */\n private getSlidesCount(): number {\n return this.slides()?.length ?? 0;\n }\n\n /**\n * Observes screen breakpoint changes to adjust autoplay and layout behavior.\n */\n private observeBreakpointChanges(): void {\n this.cdkBreakpointObserver\n .observe([\n '(max-width: 768px)',\n '(min-width: 998px)',\n '(min-width: 1140px)',\n '(min-width: 1140px) and (max-width: 1260px)',\n ])\n .pipe(takeUntil(this.destroy$))\n .subscribe((result) => {\n this.isMobileBreakpoint.set(result.breakpoints['(max-width: 768px)']);\n this.isTabletBreakpoint = result.breakpoints['(min-width: 998px)'];\n this.isLargeBreakpoint = result.breakpoints['(min-width: 1140px)'];\n this.isDesktopBreakpointActive.set(result.breakpoints['(min-width: 1140px)']);\n this.isDesktopBreakpoint = result.breakpoints['(min-width: 1140px) and (max-width: 1260px)'];\n\n // Deactivate autoplay on mobile; (re)activate it on larger\n // screens if autoplay is desired. Focus is never moved here so\n // the page is not scrolled to the carousel on load/resize.\n if (this.isMobileBreakpoint()) {\n this.stopAutoplay();\n return;\n }\n\n if (this.isTabletBreakpoint && this.isAutoplayDesired() && !this.isPausedForced()) {\n this.onPlayClick(false);\n }\n });\n }\n\n /**\n * Observes changes to the carousel's viewport element size using a timeout debounce.\n */\n private observeElementSizeChanges(): void {\n setTimeout(() => {\n if (this.isLargeBreakpoint) {\n this.checkBannerHeights();\n } else {\n this.resetHeight();\n }\n this.embla()?.reInit();\n }, this.TIMEOUT_INTERVAL);\n }\n\n /**\n * Normalizes the height of all banners to match the tallest banner.\n */\n private checkBannerHeights(): void {\n this.slides().forEach((slide) => {\n const banner = slide.banner();\n if (banner) {\n banner.calculateHeight();\n }\n });\n\n const heightValues = this.slides().map((slide) => {\n const el = slide.banner()?.el.nativeElement;\n if (!el) return undefined;\n\n const styleHeight = el.style.height;\n\n if (styleHeight === 'auto' || styleHeight === '') {\n return el.offsetHeight;\n }\n\n const height = parseInt(styleHeight, 10);\n if (Number.isNaN(height) || height === 100) {\n return 1;\n }\n\n return height;\n });\n\n const elementHeights = heightValues.filter((h) => h !== undefined) as number[];\n const tallestElementHeight = Math.max(...elementHeights);\n\n const slides = this.slides();\n if (tallestElementHeight > 1 && elementHeights.length === slides.length) {\n slides.forEach((slide) => {\n const banner = slide.banner();\n if (!banner) return;\n\n const el = banner.el.nativeElement;\n const bannerImage = banner.eclBannerImage();\n const bannerVideo = banner.eclBannerVideo();\n\n this.renderer2.setStyle(el, 'height', `${tallestElementHeight}px`);\n this.renderer2.setStyle(el, 'aspect-ratio', 'auto');\n\n if (bannerImage) {\n this.renderer2.setStyle(bannerImage.el.nativeElement, 'aspect-ratio', 'auto');\n }\n if (bannerVideo) {\n this.renderer2.setStyle(bannerVideo.el.nativeElement, 'aspect-ratio', 'auto');\n }\n });\n }\n }\n\n /**\n * Clears all explicit banner height and aspect ratio styling for smaller breakpoints.\n */\n private resetHeight(): void {\n this.slides().forEach((slide) => {\n const banner = slide.banner();\n if (banner) {\n const bannerImage = banner.eclBannerImage();\n const bannerVideo = banner.eclBannerVideo();\n this.renderer2.removeStyle(banner.el.nativeElement, 'height');\n this.renderer2.removeStyle(banner.el.nativeElement, 'aspect-ratio');\n if (bannerImage) {\n this.renderer2.removeStyle(bannerImage.el.nativeElement, 'aspect-ratio');\n }\n if (bannerVideo) {\n this.renderer2.removeStyle(bannerVideo.el.nativeElement, 'aspect-ratio');\n }\n }\n });\n }\n}\n","@if (hasControls()) {\n<div class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__navigation\">\n <div class=\"ecl-carousel__pager-container\">\n <ecl-slider-pager\n class=\"ecl-carousel__pager\"\n [variant]=\"pagerVariant()\"\n size=\"m\"\n [isPlaying]=\"isPagerPlaying()\"\n [activeIndex]=\"getCurrentSlideIndex()\"\n [dotIndices]=\"getDotIndices()\"\n [dotAriaLabels]=\"getDotAriaLabels()\"\n prevExtraClasses=\"ecl-carousel__prev\"\n nextExtraClasses=\"ecl-carousel__next\"\n dotsExtraClasses=\"ecl-carousel__dots\"\n dotExtraClasses=\"ecl-carousel__dot\"\n playExtraClasses=\"ecl-carousel__play\"\n pauseExtraClasses=\"ecl-carousel__pause\"\n (play)=\"onPlayClick()\"\n (pause)=\"onPauseClick()\"\n (prev)=\"onPreviousSlideClick()\"\n (next)=\"onNextSlideClick()\"\n (goTo)=\"onDotClick($event)\">\n </ecl-slider-pager>\n <div class=\"ecl-carousel__counter\" dir=\"ltr\">\n {{ getCounterCurrent() }} {{ ('ecl.common.OF' | translate) }} {{ getCounterTotal() }}\n </div>\n </div>\n\n <div class=\"ecl-carousel__teasers\" role=\"tablist\">\n @for (slide of slides(); let i = $index; track slide) {\n <button #teaserButton type=\"button\" class=\"ecl-carousel__teaser-button\" role=\"tab\"\n [attr.data-ecl-carousel-slide-index]=\"i\"\n [attr.aria-current]=\"i === getCurrentSlideIndex() ? true : null\"\n [attr.tabindex]=\"i === getCurrentSlideIndex() ? null : -1\"\n [style.display]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.pointer-events]=\"isTeaserVisible(i) ? null : 'none'\"\n [style.order]=\"getTeaserOrder(i)\" (click)=\"onTeaserClick(i)\"\n (keydown)=\"onTeaserKeyboardPress($event, i)\">\n <span class=\"ecl-carousel__teaser-loading-bar\" aria-hidden=\"true\"\n [class.is-active]=\"(isPlaying() || isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\"\n [class.is-paused]=\"(isHoverPaused() || isPausedForced()) && i === getCurrentSlideIndex()\">\n <span #loadingBar class=\"ecl-carousel__teaser-loading-bar-completion\"></span>\n </span>\n <span class=\"ecl-carousel__teaser-content\">\n @if (slide.teaserText()) {\n <span class=\"ecl-carousel__teaser-title\">{{ slide.teaserText() }}</span>\n }\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n</div>\n}\n<div #carouselContainer class=\"ecl-carousel__viewport\" [class.ecl-carousel-container--padded]=\"isPadded()\"\n emblaCarousel #embla=\"emblaCarousel\" [options]=\"emblaOptions\" [plugins]=\"emblaPlugins\"\n [subscribeToEvents]=\"emblaEvents\" (emblaChange)=\"onEmblaEvent($event)\"\n (mouseenter)=\"onViewportPause()\" (mouseleave)=\"onViewportResume()\"\n (focusin)=\"onViewportPause()\" (focusout)=\"onViewportResume()\">\n <div class=\"ecl-carousel__slides\">\n <ng-content></ng-content>\n </div>\n</div>\n","import { EclCarouselComponent } from './ecl-carousel.component';\nimport { EclCarouselItemComponent } from './ecl-carousel-item.component';\n\nexport * from './ecl-carousel.component';\nexport * from './ecl-carousel-item.component';\nexport * from './events/ecl-slide.event';\nexport * from './models/ecl-carousel-item.model';\n\nexport const EUI_ECL_CAROUSEL = [\n EclCarouselComponent,\n EclCarouselItemComponent,\n] as const;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { AfterContentInit, ElementRef, OnDestroy, OnInit,
|
|
2
|
+
import { AfterContentInit, ElementRef, OnDestroy, OnInit, WritableSignal } from "@angular/core";
|
|
3
3
|
import { ECLBaseDirective, EclBaseEvent } from "@eui/ecl/core";
|
|
4
4
|
import { EmblaEventType, EmblaOptionsType, EmblaPluginType } from "embla-carousel";
|
|
5
5
|
/**
|
|
@@ -11,8 +11,6 @@ export interface EclCarouselItem {
|
|
|
11
11
|
isCurrent: WritableSignal<boolean>;
|
|
12
12
|
/** Zero-based index assigned by the parent carousel. */
|
|
13
13
|
index: WritableSignal<number | undefined>;
|
|
14
|
-
/** Optional slide identifier used for navigation buttons. */
|
|
15
|
-
id?: Signal<string | undefined>;
|
|
16
14
|
}
|
|
17
15
|
/**
|
|
18
16
|
* Event emitted by `EclCarouselComponent` when the active slide changes, and by
|
|
@@ -41,7 +39,6 @@ export declare class EclSlideEvent extends EclBaseEvent {
|
|
|
41
39
|
* - `ariaLabel` — ARIA label for the carousel landmark; aliased as `aria-label`.
|
|
42
40
|
* - `isAutoplay` — enables automatic slide advancement; boolean attribute.
|
|
43
41
|
* - `playInterval` — milliseconds between automatic transitions; default `5000`.
|
|
44
|
-
* - `counterLabel` — separator label used by the counter, defaults to `ecl.common.OF`.
|
|
45
42
|
* - `slide` — emits `EclSlideEvent` when the active slide changes.
|
|
46
43
|
*/
|
|
47
44
|
export declare class EclCarouselComponent extends ECLBaseDirective implements OnInit, OnDestroy, AfterContentInit {
|
|
@@ -57,11 +54,6 @@ export declare class EclCarouselComponent extends ECLBaseDirective implements On
|
|
|
57
54
|
* Interval in milliseconds between automatic slide transitions.
|
|
58
55
|
*/
|
|
59
56
|
readonly playInterval: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
60
|
-
/**
|
|
61
|
-
* Separator label used by the counter, e.g. the "of" in "1 of 5".
|
|
62
|
-
* Defaults to the translated `ecl.common.OF` key.
|
|
63
|
-
*/
|
|
64
|
-
readonly counterLabel: import("@angular/core").InputSignal<string>;
|
|
65
57
|
/**
|
|
66
58
|
* Event emitted when a slide change occurs.
|
|
67
59
|
*/
|
|
@@ -382,11 +374,6 @@ export declare class EclCarouselComponent extends ECLBaseDirective implements On
|
|
|
382
374
|
"required": false;
|
|
383
375
|
"isSignal": true;
|
|
384
376
|
};
|
|
385
|
-
"counterLabel": {
|
|
386
|
-
"alias": "counterLabel";
|
|
387
|
-
"required": false;
|
|
388
|
-
"isSignal": true;
|
|
389
|
-
};
|
|
390
377
|
}, {
|
|
391
378
|
"slide": "slide";
|
|
392
379
|
}, ["slides"], ["*"], true, never>;
|
|
@@ -397,7 +384,6 @@ export declare class EclCarouselComponent extends ECLBaseDirective implements On
|
|
|
397
384
|
* the `inert` attribute so only the active slide is interactive.
|
|
398
385
|
*
|
|
399
386
|
* - Selector: `ecl-carousel-item`.
|
|
400
|
-
* - `id` — optional unique identifier; used by the carousel for navigation buttons.
|
|
401
387
|
* - `isCurrent` (input alias) — initial active state; kept as a `linkedSignal` so the parent
|
|
402
388
|
* carousel can update it imperatively as the user navigates.
|
|
403
389
|
* - `slideClick` — emits `EclSlideEvent` when the slide is clicked.
|
|
@@ -410,10 +396,6 @@ export declare class EclCarouselItemComponent extends ECLBaseDirective implement
|
|
|
410
396
|
* The aria-label for the slide, assigned dynamically by the carousel.
|
|
411
397
|
*/
|
|
412
398
|
readonly ariaLabel: import("@angular/core").WritableSignal<string>;
|
|
413
|
-
/**
|
|
414
|
-
* The unique identifier of the slide.
|
|
415
|
-
*/
|
|
416
|
-
readonly id: import("@angular/core").InputSignal<string>;
|
|
417
399
|
/**
|
|
418
400
|
* Input controlling whether this slide starts as the active/visible one.
|
|
419
401
|
* Automatically coerced to a boolean value.
|
|
@@ -452,11 +434,6 @@ export declare class EclCarouselItemComponent extends ECLBaseDirective implement
|
|
|
452
434
|
onSlideClick(): void;
|
|
453
435
|
static ɵfac: i0.ɵɵFactoryDeclaration<EclCarouselItemComponent, never>;
|
|
454
436
|
static ɵcmp: i0.ɵɵComponentDeclaration<EclCarouselItemComponent, "ecl-carousel-item", never, {
|
|
455
|
-
"id": {
|
|
456
|
-
"alias": "id";
|
|
457
|
-
"required": false;
|
|
458
|
-
"isSignal": true;
|
|
459
|
-
};
|
|
460
437
|
"isCurrentInput": {
|
|
461
438
|
"alias": "isCurrent";
|
|
462
439
|
"required": false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eui-ecl-components-ecl-carousel.d.ts","names":[],"sources":["../../components/ecl-carousel/models/ecl-carousel-item.model.ts","../../components/ecl-carousel/events/ecl-slide.event.ts","../../components/ecl-carousel/ecl-carousel.component.ts","../../components/ecl-carousel/ecl-carousel-item.component.ts","../../components/ecl-carousel/index.ts"],"mappings":";;;;;;;;iBAMiB;;EAEhB,WAAW;;EAEX,OAAO
|
|
1
|
+
{"version":3,"file":"eui-ecl-components-ecl-carousel.d.ts","names":[],"sources":["../../components/ecl-carousel/models/ecl-carousel-item.model.ts","../../components/ecl-carousel/events/ecl-slide.event.ts","../../components/ecl-carousel/ecl-carousel.component.ts","../../components/ecl-carousel/ecl-carousel-item.component.ts","../../components/ecl-carousel/index.ts"],"mappings":";;;;;;;;iBAMiB;;EAEhB,WAAW;;EAEX,OAAO;;;;;;;qBCFK,sBAAsB;EAIZ,MAAM;;;;EAAN,YAAA,MAAM;;;;;;;;;;;;;;;;;;;qBCiEhB,6BAA6B,4BAA4B,QAAQ,WAAW;;;;WAI5E,mCAAS;;;;WAKT,oCAAU;;;;WAKV,sCAAY;;;;WAKZ,+BAAK,iBAAA;;;;WAKL,kDAAwB,OAAA;;;;WAKxB,gCAAM;;;;WAKN,mCAAS;;;;;WAMT,wCAAc;;;;EAKvB;;;;UAKQ;;;;UAKA;;;;;;qBAOW,uCAAa;;;;;;qBAOb,4CAAkB;;;;;;;;qBASlB,mDAAyB;;;;YAKlC,cAAc;;;;YASd,cAAc;;;;qBAKL,aAAa;;;;mBASf;;;;mBAKA;;;;;mBAMA;UAET;UACA;UACA;UAEA;;;;mBAKS;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;;;;;mBAKA;;;;qBAKE,oCAAU;;;;;EAqB7B;;;;EA2BA;;;;EASA;;;;EAQA;;;;EAOA;;;;EAOA;;;;EAOA;;;;EAOA;;;;;;EASA;;;;;EAQA;;;;EAaA,gBAAgB;;;;EAYhB,eAAe;;;;;;;;YAYL;;;;;;;;;;;;;YAgBA;;;;YAOA,aAAa,OAAO;;;;;;;;YAuBpB,YAAY;;;;YAcZ;;;;YAmBA;;;;YAQA;;;;YAQA,cAAc;;;;;YASd,WAAW;;;;YAQX,sBAAsB,OAAO,eAAe;;;;;;YAkB5C;;;;YAUA;;;;UAUF;;;;;;;UAaA;;;;;;;;;;;;;UAiBA;;;;;UAYA;;;;;UASA;;;;;UAcA;;;;UAeA;;;;UAiBA;;;;UAiBA;;;;;;UAYA;;;;UAiBA;;;;UAeA;;;;UAOA;;;;UAiCA;;;;UAcA;;;;UAuDA;SArsBC,MAAA,GAAA,qBAAA;SAAA,MAAA,GAAA,uBAAA;IAAoB;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;;IAAA;;;;;;;;;;;;;;;qBC1BpB,iCAAiC,4BAA4B;EACtE,IAAE;;;;WAKO,mCAAS;;;;;WAMT,wCAAc;;;;;;WAOd,mCAAS;;;;;WAMT,oCAAU;;;;WAKV,oCAAU,iBAAA;;;;WAKV,gCAAM;;;;WAKN,+BAAK;;;;qBAKK,oCAAU;;;;EAM7B;SAnDS,MAAA,GAAA,qBAAA;SAAA,MAAA,GAAA,uBAAA;IAAwB;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;;IAAA;;;qBC3CxB,mCAAgB,6BAAA"}
|