@coreui/angular-pro 5.7.12 → 5.7.14

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.
@@ -1,7 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, Directive, input, Renderer2, effect, TemplateRef, booleanAttribute, untracked, NgModule, computed, Injectable, Component, afterNextRender, linkedSignal, output, signal, contentChildren, DestroyRef, forwardRef, DOCUMENT, NgZone, ChangeDetectorRef, contentChild, Input, IterableDiffers, numberAttribute, ViewChild, ContentChildren, ViewChildren, ChangeDetectionStrategy, PLATFORM_ID, RendererFactory2, viewChildren, viewChild, Injector, ViewContainerRef, inputBinding, outputBinding, MAX_ANIMATION_TIMEOUT, KeyValueDiffers, Pipe, HostBinding, model, afterEveryRender, afterRenderEffect, HostListener, runInInjectionContext, ViewEncapsulation } from '@angular/core';
2
+ import { inject, ElementRef, Directive, input, Renderer2, effect, TemplateRef, booleanAttribute, untracked, NgModule, computed, Injectable, Component, linkedSignal, output, signal, contentChildren, DestroyRef, forwardRef, DOCUMENT, NgZone, ChangeDetectorRef, contentChild, afterNextRender, Input, IterableDiffers, numberAttribute, ViewChild, ContentChildren, ViewChildren, ChangeDetectionStrategy, PLATFORM_ID, RendererFactory2, viewChildren, viewChild, Injector, ViewContainerRef, inputBinding, outputBinding, MAX_ANIMATION_TIMEOUT, KeyValueDiffers, Pipe, HostBinding, model, afterEveryRender, afterRenderEffect, HostListener, runInInjectionContext, ViewEncapsulation } from '@angular/core';
3
3
  import { NgTemplateOutlet, I18nPluralPipe, NgStyle, AsyncPipe, isPlatformServer, isPlatformBrowser, formatDate } from '@angular/common';
4
- import { animation, animate, style, AnimationBuilder, useAnimation, group, query, trigger, state, transition, animateChild } from '@angular/animations';
5
4
  import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
6
5
  import * as i1 from '@angular/forms';
7
6
  import { FormsModule, NG_VALUE_ACCESSOR, FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
@@ -16,6 +15,7 @@ import { DomSanitizer } from '@angular/platform-browser';
16
15
  import * as i1$1 from '@angular/router';
17
16
  import { RouterModule, Router, ActivatedRoute, NavigationEnd, RouterLink } from '@angular/router';
18
17
  import { BreakpointObserver } from '@angular/cdk/layout';
18
+ import { trigger, state, style, transition, animate } from '@angular/animations';
19
19
  import { IconDirective } from '@coreui/icons-angular';
20
20
 
21
21
  var BreakpointInfix;
@@ -266,74 +266,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
266
266
  args: [{ selector: 'c-accordion', template: '<ng-content />', exportAs: 'cAccordionItem', providers: [AccordionService], host: { '[class]': 'hostClasses()' }, styles: [":host{display:block}\n"] }]
267
267
  }], propDecorators: { flush: [{ type: i0.Input, args: [{ isSignal: true, alias: "flush", required: false }] }], alwaysOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "alwaysOpen", required: false }] }] } });
268
268
 
269
- const expandAnimation = animation([animate('{{ time }} {{ easing }}')]);
270
- const collapseAnimation = animation([
271
- style({ height: '*', minHeight: '*' }),
272
- animate('{{ time }} {{ easing }}', style({ height: 0, minHeight: 0 }))
273
- ]);
274
- const expandHorizontalAnimation = animation([animate('{{ time }} {{ easing }}')]);
275
- const collapseHorizontalAnimation = animation([animate('{{ time }} {{ easing }}')]);
276
-
277
269
  class CollapseDirective {
278
- #animationBuilder = inject(AnimationBuilder);
270
+ static ngAcceptInputType_animate;
271
+ static ngAcceptInputType_horizontal;
272
+ static ngAcceptInputType_navbar;
273
+ static ngAcceptInputType_visible;
279
274
  #hostElement = inject(ElementRef);
280
275
  #renderer = inject(Renderer2);
281
- #player = undefined;
282
- constructor() {
283
- afterNextRender({
284
- read: () => {
285
- this.#initialized.set(true);
286
- }
287
- });
288
- }
276
+ #unlistenTransitionEnd;
277
+ #isFirstChange = true;
289
278
  /**
290
- * @ignore
279
+ * @ignore internal
291
280
  */
292
281
  animateInput = input(true, { ...(ngDevMode ? { debugName: "animateInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'animate' });
293
- animate = linkedSignal({ ...(ngDevMode ? { debugName: "animate" } : /* istanbul ignore next */ {}), source: this.animateInput,
294
- computation: (value) => value });
282
+ animate = linkedSignal(this.animateInput, /* @ts-ignore */
283
+ ...(ngDevMode ? [{ debugName: "animate" }] : /* istanbul ignore next */ []));
295
284
  /**
296
285
  * Set horizontal collapsing to transition the width instead of height.
297
- * @type boolean
286
+ * @return boolean
298
287
  * @default false
299
288
  */
300
289
  horizontal = input(false, { ...(ngDevMode ? { debugName: "horizontal" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
301
290
  /**
302
- * Toggle the visibility of collapsible element.
303
- * @type boolean
291
+ * Toggle the visibility of a collapsible element.
292
+ * @return boolean
304
293
  * @default false
305
294
  */
306
295
  visibleInput = input(false, { ...(ngDevMode ? { debugName: "visibleInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'visible' });
296
+ /**
297
+ * Event emitted on visibility change. [docs]
298
+ * @return boolean
299
+ */
307
300
  visibleChange = output();
308
- visible = linkedSignal({ ...(ngDevMode ? { debugName: "visible" } : /* istanbul ignore next */ {}), source: this.visibleInput, computation: (value) => value });
309
- #initialized = signal(false, /* @ts-ignore */
310
- ...(ngDevMode ? [{ debugName: "#initialized" }] : /* istanbul ignore next */ []));
301
+ visible = linkedSignal(this.visibleInput, /* @ts-ignore */
302
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
311
303
  #visibleEffect = effect(() => {
312
304
  const visible = this.visible();
313
- if (this.#initialized()) {
314
- this.createPlayer(visible);
305
+ if (this.#isFirstChange || !untracked(() => this.animate())) {
306
+ // no transition
307
+ this.#isFirstChange = false;
308
+ this.setInitialState(visible);
309
+ return;
315
310
  }
311
+ untracked(() => {
312
+ this.runTransition(visible);
313
+ });
316
314
  }, /* @ts-ignore */
317
315
  ...(ngDevMode ? [{ debugName: "#visibleEffect" }] : /* istanbul ignore next */ []));
318
316
  /**
319
- * Add `navbar` prop for grouping and hiding navbar contents by a parent breakpoint.
320
- * @type boolean
317
+ * Add a `navbar` prop for grouping and hiding navbar contents by a parent breakpoint.
318
+ * @return boolean
321
319
  * @default false
322
320
  */
323
321
  navbar = input(false, { ...(ngDevMode ? { debugName: "navbar" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
324
- /**
325
- * @ignore
326
- */
327
- duration = input('350ms', /* @ts-ignore */
328
- ...(ngDevMode ? [{ debugName: "duration" }] : /* istanbul ignore next */ []));
329
- /**
330
- * @ignore
331
- */
332
- transition = input('ease', /* @ts-ignore */
333
- ...(ngDevMode ? [{ debugName: "transition" }] : /* istanbul ignore next */ []));
334
322
  /**
335
323
  * Event emitted on visibility change. [docs]
336
- * @type string
324
+ * @return string
337
325
  */
338
326
  collapseChange = output();
339
327
  hostClasses = computed(() => {
@@ -344,60 +332,88 @@ class CollapseDirective {
344
332
  }, /* @ts-ignore */
345
333
  ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
346
334
  ngOnDestroy() {
347
- this.destroyPlayer();
335
+ this.clearPendingCallbacks();
348
336
  }
349
337
  toggle(visible = !this.visible()) {
350
338
  this.visible.set(visible);
351
339
  }
352
- destroyPlayer() {
353
- this.#player?.destroy();
354
- this.#player = undefined;
340
+ clearPendingCallbacks() {
341
+ this.#unlistenTransitionEnd?.();
342
+ this.#unlistenTransitionEnd = undefined;
355
343
  }
356
- createPlayer(visible = this.visible()) {
357
- if (this.#player?.hasStarted()) {
358
- this.destroyPlayer();
359
- }
344
+ setInitialState(visible) {
360
345
  const host = this.#hostElement.nativeElement;
346
+ this.#renderer.addClass(host, 'collapse');
347
+ this.#renderer.removeClass(host, 'collapsing');
361
348
  if (visible) {
362
- this.#renderer.removeStyle(host, 'display');
349
+ this.#renderer.addClass(host, 'show');
350
+ }
351
+ else {
352
+ this.#renderer.removeClass(host, 'show');
363
353
  }
364
- const duration = this.animate() ? this.duration() : '0ms';
365
- const expand = this.horizontal() ? expandHorizontalAnimation : expandAnimation;
366
- const collapse = this.horizontal() ? collapseHorizontalAnimation : collapseAnimation;
354
+ }
355
+ runTransition(visible) {
356
+ this.clearPendingCallbacks();
357
+ const host = this.#hostElement.nativeElement;
367
358
  const dimension = this.horizontal() ? 'width' : 'height';
368
359
  const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
369
360
  const scrollSize = `scroll${capitalizedDimension}`;
370
- const animationFactory = this.#animationBuilder?.build(useAnimation(visible ? expand : collapse, { params: { time: duration, easing: this.transition() } }));
371
- this.#player = animationFactory.create(host);
372
- !visible && host.offsetHeight && host.style[dimension] && host.scrollHeight;
373
- this.#renderer.setStyle(host, dimension, visible ? 0 : `${host.getBoundingClientRect()[dimension]}px`);
374
- this.#player.onStart(() => {
361
+ const animate = this.animate();
362
+ if (visible) {
375
363
  this.setMaxSize();
364
+ // Switch off `collapse`/`show` before we measure its scroll size below.
376
365
  this.#renderer.removeClass(host, 'collapse');
366
+ this.#renderer.removeClass(host, 'show');
377
367
  this.#renderer.addClass(host, 'collapsing');
368
+ this.collapseChange?.emit('opening');
369
+ // Reading scrollHeight/scrollWidth forces a synchronous reflow, committing the 0-size
370
+ // starting point before we set the target size below, so the browser animates the change.
371
+ const targetSize = host[scrollSize];
372
+ this.#renderer.setStyle(host, dimension, `${targetSize}px`);
373
+ }
374
+ else {
375
+ // Lock in the current pixel size first so the browser has a committed starting point,
376
+ // then switch to the collapsing state and clear it so the size can animate down to 0.
377
+ const startSize = host.getBoundingClientRect()[dimension];
378
+ this.#renderer.setStyle(host, dimension, `${startSize}px`);
379
+ // Force a reflow so the browser registers the starting size before the next style change.
380
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
381
+ host.offsetHeight;
382
+ this.#renderer.removeClass(host, 'collapse');
378
383
  this.#renderer.removeClass(host, 'show');
379
- this.#renderer.setStyle(host, dimension, visible ? `${host[scrollSize]}px` : '');
380
- if (this.#player) {
381
- this.collapseChange?.emit(visible ? 'opening' : 'collapsing');
382
- }
383
- });
384
- this.#player.onDone(() => {
385
- this.#renderer.removeClass(host, 'collapsing');
386
- this.#renderer.addClass(host, 'collapse');
387
- if (visible) {
388
- this.#renderer.addClass(host, 'show');
389
- this.#renderer.setStyle(host, dimension, '');
390
- }
391
- else {
392
- this.#renderer.removeClass(host, 'show');
393
- }
394
- if (this.#player) {
395
- this.collapseChange?.emit(visible ? 'open' : 'collapsed');
396
- this.visibleChange?.emit(visible);
397
- }
398
- this.destroyPlayer();
399
- });
400
- this.#player?.play();
384
+ this.#renderer.addClass(host, 'collapsing');
385
+ this.collapseChange?.emit('collapsing');
386
+ // Now that the starting size is committed, set the target size (0) so the browser
387
+ // animates the transition down.
388
+ this.#renderer.setStyle(host, dimension, '0px');
389
+ }
390
+ const finish = () => this.finishTransition(visible, host, dimension);
391
+ if (animate) {
392
+ this.#unlistenTransitionEnd = this.#renderer.listen(host, 'transitionend', (event) => {
393
+ // Ignore bubbled transitionend events from descendant elements.
394
+ if (event.target === host && event.propertyName === dimension) {
395
+ finish();
396
+ }
397
+ });
398
+ }
399
+ else {
400
+ finish();
401
+ }
402
+ }
403
+ finishTransition(visible, host, dimension) {
404
+ this.clearPendingCallbacks();
405
+ this.#renderer.removeClass(host, 'collapsing');
406
+ this.#renderer.addClass(host, 'collapse');
407
+ if (visible) {
408
+ this.#renderer.addClass(host, 'show');
409
+ }
410
+ else {
411
+ this.#renderer.removeClass(host, 'show');
412
+ }
413
+ this.#renderer.removeStyle(host, 'transition');
414
+ this.#renderer.removeStyle(host, dimension);
415
+ this.collapseChange?.emit(visible ? 'open' : 'collapsed');
416
+ this.visibleChange?.emit(visible);
401
417
  }
402
418
  setMaxSize() {
403
419
  const host = this.#hostElement.nativeElement;
@@ -408,16 +424,16 @@ class CollapseDirective {
408
424
  }
409
425
  }
410
426
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CollapseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
411
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: CollapseDirective, isStandalone: true, selector: "[cCollapse]", inputs: { animateInput: { classPropertyName: "animateInput", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null }, horizontal: { classPropertyName: "horizontal", publicName: "horizontal", isSignal: true, isRequired: false, transformFunction: null }, visibleInput: { classPropertyName: "visibleInput", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, navbar: { classPropertyName: "navbar", publicName: "navbar", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibleChange: "visibleChange", collapseChange: "collapseChange" }, host: { properties: { "class": "hostClasses()", "style": "{ display: \"none\" }" } }, exportAs: ["cCollapse"], ngImport: i0 });
427
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: CollapseDirective, isStandalone: true, selector: "[cCollapse]", inputs: { animateInput: { classPropertyName: "animateInput", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null }, horizontal: { classPropertyName: "horizontal", publicName: "horizontal", isSignal: true, isRequired: false, transformFunction: null }, visibleInput: { classPropertyName: "visibleInput", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, navbar: { classPropertyName: "navbar", publicName: "navbar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibleChange: "visibleChange", collapseChange: "collapseChange" }, host: { properties: { "class": "hostClasses()" } }, exportAs: ["cCollapse"], ngImport: i0 });
412
428
  }
413
429
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CollapseDirective, decorators: [{
414
430
  type: Directive,
415
431
  args: [{
416
432
  selector: '[cCollapse]',
417
433
  exportAs: 'cCollapse',
418
- host: { '[class]': 'hostClasses()', '[style]': '{ display: "none" }' }
434
+ host: { '[class]': 'hostClasses()' }
419
435
  }]
420
- }], ctorParameters: () => [], propDecorators: { animateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }], horizontal: [{ type: i0.Input, args: [{ isSignal: true, alias: "horizontal", required: false }] }], visibleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], visibleChange: [{ type: i0.Output, args: ["visibleChange"] }], navbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "navbar", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], transition: [{ type: i0.Input, args: [{ isSignal: true, alias: "transition", required: false }] }], collapseChange: [{ type: i0.Output, args: ["collapseChange"] }] } });
436
+ }], propDecorators: { animateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }], horizontal: [{ type: i0.Input, args: [{ isSignal: true, alias: "horizontal", required: false }] }], visibleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], visibleChange: [{ type: i0.Output, args: ["visibleChange"] }], navbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "navbar", required: false }] }], collapseChange: [{ type: i0.Output, args: ["collapseChange"] }] } });
421
437
 
422
438
  class CollapseModule {
423
439
  static forRoot() {
@@ -478,7 +494,7 @@ class AccordionItemComponent {
478
494
  this.#accordionService.toggleItem(this);
479
495
  }
480
496
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: AccordionItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
481
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: AccordionItemComponent, isStandalone: true, selector: "c-accordion-item", inputs: { visibleInput: { classPropertyName: "visibleInput", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "accordion-item" }, queries: [{ propertyName: "contentTemplates", predicate: TemplateIdDirective, descendants: true, isSignal: true }], exportAs: ["cAccordionItem"], ngImport: i0, template: "@let tmpl = templates();\n<ng-container>\n <div class=\"accordion-header\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionHeaderTemplate'] || defaultAccordionHeaderTemplate; context: itemContext\" />\n </div>\n <div class=\"accordion-collapse\" cCollapse [visible]=\"itemVisible()\" [attr.aria-expanded]=\"itemVisible()\" [id]=\"contentId\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionBodyTemplate'] || defaultAccordionBodyTemplate; context: itemContext\" />\n </div>\n</ng-container>\n\n<ng-template #defaultAccordionHeaderTemplate>\n <button cAccordionButton [collapsed]=\"!itemVisible()\" [attr.aria-controls]=\"contentId\" (click)=\"toggleItem()\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionHeader'] || defaultAccordionHeaderContentTemplate; context: itemContext\" />\n </button>\n</ng-template>\n\n<ng-template #defaultAccordionHeaderContentTemplate>\n <ng-content />\n</ng-template>\n\n<ng-template #defaultAccordionBodyTemplate>\n <div class=\"accordion-body\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionBody'] || defaultAccordionBodyContentTemplate; context: itemContext\" />\n </div>\n</ng-template>\n\n<ng-template #defaultAccordionBodyContentTemplate>\n <ng-content />\n</ng-template>\n", styles: [":host{display:block;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: AccordionButtonDirective, selector: "[cAccordionButton]", inputs: ["collapsed", "type"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CollapseDirective, selector: "[cCollapse]", inputs: ["animate", "horizontal", "visible", "navbar", "duration", "transition"], outputs: ["visibleChange", "collapseChange"], exportAs: ["cCollapse"] }] });
497
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: AccordionItemComponent, isStandalone: true, selector: "c-accordion-item", inputs: { visibleInput: { classPropertyName: "visibleInput", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "accordion-item" }, queries: [{ propertyName: "contentTemplates", predicate: TemplateIdDirective, descendants: true, isSignal: true }], exportAs: ["cAccordionItem"], ngImport: i0, template: "@let tmpl = templates();\n<ng-container>\n <div class=\"accordion-header\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionHeaderTemplate'] || defaultAccordionHeaderTemplate; context: itemContext\" />\n </div>\n <div class=\"accordion-collapse\" cCollapse [visible]=\"itemVisible()\" [attr.aria-expanded]=\"itemVisible()\" [id]=\"contentId\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionBodyTemplate'] || defaultAccordionBodyTemplate; context: itemContext\" />\n </div>\n</ng-container>\n\n<ng-template #defaultAccordionHeaderTemplate>\n <button cAccordionButton [collapsed]=\"!itemVisible()\" [attr.aria-controls]=\"contentId\" (click)=\"toggleItem()\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionHeader'] || defaultAccordionHeaderContentTemplate; context: itemContext\" />\n </button>\n</ng-template>\n\n<ng-template #defaultAccordionHeaderContentTemplate>\n <ng-content />\n</ng-template>\n\n<ng-template #defaultAccordionBodyTemplate>\n <div class=\"accordion-body\">\n <ng-container *ngTemplateOutlet=\"tmpl['accordionBody'] || defaultAccordionBodyContentTemplate; context: itemContext\" />\n </div>\n</ng-template>\n\n<ng-template #defaultAccordionBodyContentTemplate>\n <ng-content />\n</ng-template>\n", styles: [":host{display:block;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: AccordionButtonDirective, selector: "[cAccordionButton]", inputs: ["collapsed", "type"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CollapseDirective, selector: "[cCollapse]", inputs: ["animate", "horizontal", "visible", "navbar"], outputs: ["visibleChange", "collapseChange"], exportAs: ["cCollapse"] }] });
482
498
  }
483
499
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: AccordionItemComponent, decorators: [{
484
500
  type: Component,
@@ -8217,15 +8233,8 @@ class CarouselService {
8217
8233
  setIndex(index) {
8218
8234
  this.#carouselIndex.next(index);
8219
8235
  }
8220
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8221
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselService });
8222
- }
8223
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselService, decorators: [{
8224
- type: Injectable
8225
- }] });
8226
-
8227
- class CarouselState {
8228
- #carouselService = inject(CarouselService);
8236
+ animating = signal(false, /* @ts-ignore */
8237
+ ...(ngDevMode ? [{ debugName: "animating" }] : /* istanbul ignore next */ []));
8229
8238
  #state = {
8230
8239
  activeItemIndex: -1,
8231
8240
  animate: true,
@@ -8244,7 +8253,7 @@ class CarouselState {
8244
8253
  if (prevState.activeItemIndex !== nextState.activeItemIndex) {
8245
8254
  const activeItemIndex = this.state.activeItemIndex || 0;
8246
8255
  const itemInterval = (this.state.items && this.state.items[activeItemIndex]?.interval()) || -1;
8247
- this.#carouselService.setIndex({
8256
+ this.setIndex({
8248
8257
  active: nextState.activeItemIndex,
8249
8258
  interval: itemInterval,
8250
8259
  lastItemIndex: (nextState.items?.length ?? 0) - 1
@@ -8266,7 +8275,7 @@ class CarouselState {
8266
8275
  }
8267
8276
  }
8268
8277
  setNextIndex(nextIndex) {
8269
- this.#carouselService.setIndex(nextIndex);
8278
+ this.setIndex(nextIndex);
8270
8279
  }
8271
8280
  direction(direction = 'next') {
8272
8281
  this.state = { direction };
@@ -8295,10 +8304,10 @@ class CarouselState {
8295
8304
  interval: 0
8296
8305
  };
8297
8306
  }
8298
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselState, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8299
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselState });
8307
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8308
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselService });
8300
8309
  }
8301
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselState, decorators: [{
8310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselService, decorators: [{
8302
8311
  type: Injectable
8303
8312
  }] });
8304
8313
 
@@ -8307,9 +8316,9 @@ class CarouselConfig {
8307
8316
  activeIndex = 0;
8308
8317
  /* Animate transition of slides */
8309
8318
  animate = true;
8310
- /* Default direction of auto changing of slides */
8319
+ /* Default direction of auto-changing of slides */
8311
8320
  direction = 'next';
8312
- /* Default interval of auto changing of slides */
8321
+ /* Default interval of auto-changing of slides */
8313
8322
  interval;
8314
8323
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8315
8324
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselConfig, providedIn: 'root' });
@@ -8323,7 +8332,6 @@ class CarouselComponent {
8323
8332
  config = inject(CarouselConfig);
8324
8333
  #hostElement = inject(ElementRef);
8325
8334
  #carouselService = inject(CarouselService);
8326
- #carouselState = inject(CarouselState);
8327
8335
  #intersectionService = inject(IntersectionService);
8328
8336
  #listenersService = inject(ListenersService);
8329
8337
  constructor() {
@@ -8331,7 +8339,7 @@ class CarouselComponent {
8331
8339
  }
8332
8340
  loadConfig() {
8333
8341
  this.activeIndex.update((activeIndex) => this.config?.activeIndex ?? activeIndex);
8334
- this.animate.update((animate) => this.config?.animate ?? animate);
8342
+ this.animate.update((animate) => (animate === false ? animate : (this.config?.animate ?? animate)));
8335
8343
  this.direction.update((direction) => this.config?.direction ?? direction);
8336
8344
  this.interval.update((interval) => this.config?.interval ?? interval);
8337
8345
  }
@@ -8347,8 +8355,8 @@ class CarouselComponent {
8347
8355
  * @return boolean
8348
8356
  */
8349
8357
  animateInput = input(true, { ...(ngDevMode ? { debugName: "animateInput" } : /* istanbul ignore next */ {}), alias: 'animate' });
8350
- animate = linkedSignal({ ...(ngDevMode ? { debugName: "animate" } : /* istanbul ignore next */ {}), source: this.animateInput,
8351
- computation: (value) => value });
8358
+ animate = linkedSignal(this.animateInput, /* @ts-ignore */
8359
+ ...(ngDevMode ? [{ debugName: "animate" }] : /* istanbul ignore next */ []));
8352
8360
  /**
8353
8361
  * Carousel direction. [docs]
8354
8362
  * @return {'next' | 'prev'}
@@ -8366,7 +8374,7 @@ class CarouselComponent {
8366
8374
  computation: (value) => value });
8367
8375
  #intervalEffect = effect(() => {
8368
8376
  const interval = this.interval();
8369
- this.#carouselState.state = { interval: interval };
8377
+ this.#carouselService.state = { interval: interval };
8370
8378
  interval ? this.setTimer() : this.resetTimer();
8371
8379
  }, /* @ts-ignore */
8372
8380
  ...(ngDevMode ? [{ debugName: "#intervalEffect" }] : /* istanbul ignore next */ []));
@@ -8384,7 +8392,7 @@ class CarouselComponent {
8384
8392
  touch = input(true, /* @ts-ignore */
8385
8393
  ...(ngDevMode ? [{ debugName: "touch" }] : /* istanbul ignore next */ []));
8386
8394
  /**
8387
- * Set type of the transition.
8395
+ * Set the type of the transition.
8388
8396
  * @return {'slide' | 'crossfade'}
8389
8397
  * @default 'slide'
8390
8398
  */
@@ -8407,16 +8415,18 @@ class CarouselComponent {
8407
8415
  swipeSubscription;
8408
8416
  #destroyRef = inject(DestroyRef);
8409
8417
  ngOnInit() {
8410
- this.carouselStateSubscribe();
8418
+ this.carouselServiceSubscribe();
8411
8419
  }
8412
8420
  ngOnDestroy() {
8413
8421
  this.resetTimer();
8414
8422
  this.clearListeners();
8415
8423
  this.swipeSubscribe(false);
8424
+ // Ensure IntersectionObserver is cleaned up
8425
+ this.#intersectionService?.unobserve(this.#hostElement);
8416
8426
  }
8417
8427
  ngAfterContentInit() {
8418
8428
  this.intersectionServiceSubscribe();
8419
- this.#carouselState.state = {
8429
+ this.#carouselService.state = {
8420
8430
  activeItemIndex: this.activeIndex(),
8421
8431
  animate: this.animate(),
8422
8432
  interval: this.interval(),
@@ -8454,8 +8464,8 @@ class CarouselComponent {
8454
8464
  this.resetTimer();
8455
8465
  if (interval > 0) {
8456
8466
  this.timerId = setTimeout(() => {
8457
- const nextIndex = this.#carouselState.direction(direction);
8458
- this.#carouselState.state = { activeItemIndex: nextIndex };
8467
+ const nextIndex = this.#carouselService.direction(direction);
8468
+ this.#carouselService.state = { activeItemIndex: nextIndex };
8459
8469
  }, interval);
8460
8470
  }
8461
8471
  }
@@ -8463,7 +8473,7 @@ class CarouselComponent {
8463
8473
  clearTimeout(this.timerId);
8464
8474
  this.timerId = undefined;
8465
8475
  }
8466
- carouselStateSubscribe() {
8476
+ carouselServiceSubscribe() {
8467
8477
  this.#carouselService.carouselIndex$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((nextItem) => {
8468
8478
  if ('active' in nextItem && typeof nextItem.active === 'number') {
8469
8479
  this.itemChange?.emit(nextItem.active);
@@ -8480,7 +8490,7 @@ class CarouselComponent {
8480
8490
  this.#intersectionService.createIntersectionObserver(this.#hostElement);
8481
8491
  this.#intersectionService.intersecting$
8482
8492
  .pipe(filter((next) => next.hostElement === this.#hostElement), finalize(() => {
8483
- this.#intersectionService.unobserve(this.#hostElement);
8493
+ this.#intersectionService?.unobserve(this.#hostElement);
8484
8494
  }), takeUntilDestroyed(this.#destroyRef))
8485
8495
  .subscribe((next) => {
8486
8496
  this.visible = next.isIntersecting;
@@ -8498,10 +8508,13 @@ class CarouselComponent {
8498
8508
  .subscribe(([touchstart, [touchend, touchmove]]) => {
8499
8509
  touchstart.stopPropagation();
8500
8510
  touchmove.stopPropagation();
8511
+ if (this.#carouselService.animating()) {
8512
+ return;
8513
+ }
8501
8514
  const distanceX = touchstart.touches[0]?.clientX - touchmove.touches[0]?.clientX || 0;
8502
8515
  if (Math.abs(distanceX) > 0.3 * carouselElement.clientWidth && touchstart.timeStamp <= touchmove.timeStamp) {
8503
- const nextIndex = this.#carouselState.direction(distanceX > 0 ? 'next' : 'prev');
8504
- this.#carouselState.state = { activeItemIndex: nextIndex };
8516
+ const nextIndex = this.#carouselService.direction(distanceX > 0 ? 'next' : 'prev');
8517
+ this.#carouselService.state = { activeItemIndex: nextIndex };
8505
8518
  }
8506
8519
  });
8507
8520
  }
@@ -8510,11 +8523,11 @@ class CarouselComponent {
8510
8523
  }
8511
8524
  }
8512
8525
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8513
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: CarouselComponent, isStandalone: true, selector: "c-carousel", inputs: { activeIndexInput: { classPropertyName: "activeIndexInput", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, animateInput: { classPropertyName: "animateInput", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null }, directionInput: { classPropertyName: "directionInput", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, intervalInput: { classPropertyName: "intervalInput", publicName: "interval", isSignal: true, isRequired: false, transformFunction: null }, pause: { classPropertyName: "pause", publicName: "pause", isSignal: true, isRequired: false, transformFunction: null }, touch: { classPropertyName: "touch", publicName: "touch", isSignal: true, isRequired: false, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemChange: "itemChange" }, host: { properties: { "class.carousel-fade": "transition() === \"crossfade\" && animate()" }, classAttribute: "carousel slide" }, providers: [CarouselService, CarouselState, ListenersService], exportAs: ["cCarousel"], hostDirectives: [{ directive: ThemeDirective, inputs: ["dark", "dark"] }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:block}\n"] });
8526
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: CarouselComponent, isStandalone: true, selector: "c-carousel", inputs: { activeIndexInput: { classPropertyName: "activeIndexInput", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, animateInput: { classPropertyName: "animateInput", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null }, directionInput: { classPropertyName: "directionInput", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, intervalInput: { classPropertyName: "intervalInput", publicName: "interval", isSignal: true, isRequired: false, transformFunction: null }, pause: { classPropertyName: "pause", publicName: "pause", isSignal: true, isRequired: false, transformFunction: null }, touch: { classPropertyName: "touch", publicName: "touch", isSignal: true, isRequired: false, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemChange: "itemChange" }, host: { properties: { "class.carousel-fade": "transition() === \"crossfade\" && animate()" }, classAttribute: "carousel slide" }, providers: [CarouselService, ListenersService], exportAs: ["cCarousel"], hostDirectives: [{ directive: ThemeDirective, inputs: ["dark", "dark"] }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:block}\n"] });
8514
8527
  }
8515
8528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselComponent, decorators: [{
8516
8529
  type: Component,
8517
- args: [{ selector: 'c-carousel', template: '<ng-content />', providers: [CarouselService, CarouselState, ListenersService], hostDirectives: [{ directive: ThemeDirective, inputs: ['dark'] }], exportAs: 'cCarousel', host: {
8530
+ args: [{ selector: 'c-carousel', template: '<ng-content />', providers: [CarouselService, ListenersService], hostDirectives: [{ directive: ThemeDirective, inputs: ['dark'] }], exportAs: 'cCarousel', host: {
8518
8531
  class: 'carousel slide',
8519
8532
  '[class.carousel-fade]': 'transition() === "crossfade" && animate()'
8520
8533
  }, styles: [":host{display:block}\n"] }]
@@ -8532,7 +8545,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
8532
8545
  }] });
8533
8546
 
8534
8547
  class CarouselControlComponent {
8535
- #carouselState = inject(CarouselState);
8548
+ #carouselService = inject(CarouselService);
8536
8549
  /**
8537
8550
  * Carousel control caption. [docs]
8538
8551
  * @return string
@@ -8574,11 +8587,14 @@ class CarouselControlComponent {
8574
8587
  }
8575
8588
  }
8576
8589
  onClick($event) {
8590
+ if (this.#carouselService.animating()) {
8591
+ return;
8592
+ }
8577
8593
  this.#play();
8578
8594
  }
8579
8595
  #play(direction = this.direction()) {
8580
- const nextIndex = this.#carouselState.direction(direction);
8581
- this.#carouselState.state = { activeItemIndex: nextIndex };
8596
+ const nextIndex = this.#carouselService.direction(direction);
8597
+ this.#carouselService.state = { activeItemIndex: nextIndex };
8582
8598
  }
8583
8599
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8584
8600
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: CarouselControlComponent, isStandalone: true, selector: "c-carousel-control", inputs: { captionInput: { classPropertyName: "captionInput", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keyup": "onKeyUp($event)", "click": "onClick($event)" }, properties: { "attr.role": "role()", "class": "hostClasses()" } }, exportAs: ["cCarouselControl"], ngImport: i0, template: "<ng-content>\n <span [attr.aria-hidden]=\"true\" [class]=\"carouselControlIconClass()\"></span>\n <span class=\"visually-hidden\">{{ caption() }}</span>\n</ng-content>\n" });
@@ -8596,7 +8612,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
8596
8612
  class CarouselIndicatorsComponent {
8597
8613
  #destroyRef = inject(DestroyRef);
8598
8614
  #carouselService = inject(CarouselService);
8599
- #carouselState = inject(CarouselState);
8600
8615
  items = [];
8601
8616
  active = signal(0, /* @ts-ignore */
8602
8617
  ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
@@ -8610,16 +8625,19 @@ class CarouselIndicatorsComponent {
8610
8625
  ...(ngDevMode ? [{ debugName: "templates" }] : /* istanbul ignore next */ []));
8611
8626
  ngOnInit() {
8612
8627
  this.#carouselService.carouselIndex$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((nextIndex) => {
8613
- this.items = this.#carouselState?.state?.items?.map((item) => item.index) ?? [];
8628
+ this.items = this.#carouselService?.state?.items?.map((item) => item.index) ?? [];
8614
8629
  if ('active' in nextIndex) {
8615
8630
  this.active.set(nextIndex.active ?? 0);
8616
8631
  }
8617
8632
  });
8618
8633
  }
8619
8634
  onClick(index) {
8635
+ if (this.#carouselService.animating()) {
8636
+ return;
8637
+ }
8620
8638
  if (index !== this.active()) {
8621
8639
  const direction = index < this.active() ? 'prev' : 'next';
8622
- this.#carouselState.state = { direction, activeItemIndex: index };
8640
+ this.#carouselService.state = { direction, activeItemIndex: index };
8623
8641
  }
8624
8642
  }
8625
8643
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselIndicatorsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -8631,19 +8649,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
8631
8649
  }], propDecorators: { contentTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TemplateIdDirective), { ...{ descendants: true }, isSignal: true }] }] } });
8632
8650
 
8633
8651
  class CarouselItemComponent {
8652
+ #elementRef = inject((ElementRef));
8634
8653
  #destroyRef = inject(DestroyRef);
8635
8654
  #carouselService = inject(CarouselService);
8655
+ #timeoutId;
8656
+ #rafId;
8636
8657
  index;
8637
8658
  /**
8638
8659
  * @ignore
8639
8660
  */
8640
8661
  activeInput = input(false, { ...(ngDevMode ? { debugName: "activeInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'active' });
8641
- active = linkedSignal({ ...(ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {}), source: this.activeInput,
8642
- computation: (value) => {
8643
- return value;
8644
- } });
8662
+ active = linkedSignal(this.activeInput, /* @ts-ignore */
8663
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
8645
8664
  /**
8646
- * Time delay before cycling to next item. If -1, uses carousel interval value.
8665
+ * Time delay before cycling to the next item. If -1, uses carousel interval value.
8647
8666
  * @return number
8648
8667
  * @default -1
8649
8668
  */
@@ -8657,102 +8676,119 @@ class CarouselItemComponent {
8657
8676
  role = input('group', /* @ts-ignore */
8658
8677
  ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
8659
8678
  constructor() {
8679
+ this.#elementRef.nativeElement.style.transition = '1ms';
8680
+ }
8681
+ ngOnInit() {
8682
+ console.log('OnInit', this.#carouselService.state.animate);
8660
8683
  this.#carouselService.carouselIndex$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((nextIndex) => {
8661
8684
  if ('active' in nextIndex) {
8685
+ console.log('#carouselService', this.#carouselService.state.animate, this.#elementRef.nativeElement.style.transition);
8686
+ if (this.#carouselService.state.animate && this.#elementRef.nativeElement.style.transition !== '') {
8687
+ this.#timeoutId = setTimeout(() => {
8688
+ this.#elementRef.nativeElement.style.transition = '';
8689
+ this.#timeoutId = undefined;
8690
+ }, 500);
8691
+ }
8692
+ this.prevActive.set(this.active());
8662
8693
  this.active.set(nextIndex.active === this.index);
8663
8694
  }
8664
8695
  });
8696
+ // Clean up timeout on destroy
8697
+ this.#destroyRef.onDestroy(() => {
8698
+ if (this.#timeoutId !== undefined) {
8699
+ clearTimeout(this.#timeoutId);
8700
+ }
8701
+ if (this.#rafId !== undefined) {
8702
+ cancelAnimationFrame(this.#rafId);
8703
+ }
8704
+ });
8665
8705
  }
8706
+ hostClasses = computed(() => {
8707
+ const order = this.orderClassName();
8708
+ const direction = this.directionClassName();
8709
+ return {
8710
+ active: this.activeClass(),
8711
+ [`${order}`]: !!order,
8712
+ [`${direction}`]: !!direction,
8713
+ 'd-none': !this.activeClass() && !order && !direction
8714
+ };
8715
+ }, /* @ts-ignore */
8716
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
8717
+ prevActive = signal(false, /* @ts-ignore */
8718
+ ...(ngDevMode ? [{ debugName: "prevActive" }] : /* istanbul ignore next */ []));
8719
+ activeClass = signal(false, /* @ts-ignore */
8720
+ ...(ngDevMode ? [{ debugName: "activeClass" }] : /* istanbul ignore next */ []));
8721
+ orderClassName = signal('', /* @ts-ignore */
8722
+ ...(ngDevMode ? [{ debugName: "orderClassName" }] : /* istanbul ignore next */ []));
8723
+ directionClassName = signal('', /* @ts-ignore */
8724
+ ...(ngDevMode ? [{ debugName: "directionClassName" }] : /* istanbul ignore next */ []));
8725
+ #activeEffect = effect((OnCleanup) => {
8726
+ const active = this.active();
8727
+ const prevActive = untracked(this.prevActive);
8728
+ const direction = this.#carouselService.state?.direction;
8729
+ this.activeClass.set(prevActive);
8730
+ if (active) {
8731
+ this.orderClassName.set(`carousel-item-${direction}`);
8732
+ }
8733
+ if (prevActive || active) {
8734
+ if (this.#rafId) {
8735
+ cancelAnimationFrame(this.#rafId);
8736
+ }
8737
+ this.#rafId = requestAnimationFrame(() => {
8738
+ // reflow is necessary to proper transition
8739
+ void this.#elementRef.nativeElement.offsetHeight;
8740
+ this.directionClassName.set(`carousel-item-${direction === 'next' ? 'start' : 'end'}`);
8741
+ this.#rafId = undefined;
8742
+ });
8743
+ }
8744
+ const handleTransitionStart = () => {
8745
+ if (active) {
8746
+ this.#carouselService.animating.set(true);
8747
+ }
8748
+ };
8749
+ const handleTransitionEnd = () => {
8750
+ if (active) {
8751
+ this.#carouselService.animating.set(false);
8752
+ }
8753
+ this.directionClassName.set('');
8754
+ this.orderClassName.set('');
8755
+ this.activeClass.set(active);
8756
+ };
8757
+ this.#elementRef.nativeElement.addEventListener('transitionstart', handleTransitionStart);
8758
+ this.#elementRef.nativeElement.addEventListener('transitionend', handleTransitionEnd);
8759
+ OnCleanup(() => {
8760
+ this.#elementRef.nativeElement.removeEventListener('transitionstart', handleTransitionStart);
8761
+ this.#elementRef.nativeElement.removeEventListener('transitionend', handleTransitionEnd);
8762
+ });
8763
+ }, /* @ts-ignore */
8764
+ ...(ngDevMode ? [{ debugName: "#activeEffect" }] : /* istanbul ignore next */ []));
8666
8765
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8667
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: CarouselItemComponent, isStandalone: true, selector: "c-carousel-item", inputs: { activeInput: { classPropertyName: "activeInput", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, interval: { classPropertyName: "interval", publicName: "interval", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.active": "active()", "attr.role": "role()" }, classAttribute: "carousel-item" }, exportAs: ["cCarouselItem"], ngImport: i0, template: "@if (active()) {\n <ng-content />\n}\n", styles: [":host{display:block}\n"] });
8766
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: CarouselItemComponent, isStandalone: true, selector: "c-carousel-item", inputs: { activeInput: { classPropertyName: "activeInput", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, interval: { classPropertyName: "interval", publicName: "interval", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.role": "role()" }, classAttribute: "carousel-item" }, exportAs: ["cCarouselItem"], ngImport: i0, template: `
8767
+ <!-- @if (this.activeClass() || (this.orderClassName() && this.directionClassName())) {-->
8768
+ <ng-content />
8769
+ <!-- }-->
8770
+ `, isInline: true });
8668
8771
  }
8669
8772
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselItemComponent, decorators: [{
8670
8773
  type: Component,
8671
- args: [{ selector: 'c-carousel-item', exportAs: 'cCarouselItem', host: {
8774
+ args: [{
8775
+ selector: 'c-carousel-item',
8776
+ template: `
8777
+ <!-- @if (this.activeClass() || (this.orderClassName() && this.directionClassName())) {-->
8778
+ <ng-content />
8779
+ <!-- }-->
8780
+ `,
8781
+ exportAs: 'cCarouselItem',
8782
+ host: {
8672
8783
  class: 'carousel-item',
8673
- '[class.active]': 'active()',
8784
+ '[class]': 'hostClasses()',
8674
8785
  '[attr.role]': 'role()'
8675
- }, template: "@if (active()) {\n <ng-content />\n}\n", styles: [":host{display:block}\n"] }]
8786
+ }
8787
+ }]
8676
8788
  }], ctorParameters: () => [], propDecorators: { activeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], interval: [{ type: i0.Input, args: [{ isSignal: true, alias: "interval", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }] } });
8677
8789
 
8678
- function toSlideLeft(fromState, toState) {
8679
- return toState.left === true && toState.type === 'slide';
8680
- }
8681
- function toSlideRight(fromState, toState) {
8682
- return toState.left === false && toState.type === 'slide';
8683
- }
8684
- function toFadeLeft(fromState, toState) {
8685
- return toState.left === true && toState.type !== 'slide';
8686
- }
8687
- function toFadeRight(fromState, toState) {
8688
- return toState.left === false && toState.type !== 'slide';
8689
- }
8690
- const slideAnimationLeft = animation(group([
8691
- query(':leave', [
8692
- animate('0.6s ease-in-out', style({
8693
- transform: 'translateX(-100%)'
8694
- }))
8695
- ], { optional: true }),
8696
- query(':enter', [
8697
- style({
8698
- transform: 'translateX(100%)'
8699
- }),
8700
- animate('0.6s ease-in-out', style('*'))
8701
- ], { optional: true })
8702
- ]));
8703
- const slideAnimationRight = animation(group([
8704
- query(':enter', [
8705
- style({
8706
- transform: 'translateX(-100%)'
8707
- }),
8708
- animate('0.6s ease-in-out', style('*'))
8709
- ], { optional: true }),
8710
- query(':leave', [
8711
- animate('0.6s ease-in-out', style({
8712
- transform: 'translateX(100%)'
8713
- }))
8714
- ], { optional: true })
8715
- ]));
8716
- const fadeAnimationLeft = animation(group([
8717
- query(':leave', [
8718
- animate('0.9s ease-in-out', style({
8719
- zIndex: 0,
8720
- opacity: 0
8721
- }))
8722
- ], { optional: true }),
8723
- query(':enter', [
8724
- style({
8725
- zIndex: 1,
8726
- opacity: 1
8727
- }),
8728
- animate('0.6s ease-in-out', style('*'))
8729
- ], { optional: true })
8730
- ]));
8731
- const fadeAnimationRight = animation(group([
8732
- query(':enter', [
8733
- style({
8734
- zIndex: 1,
8735
- opacity: 1
8736
- }),
8737
- animate('0.6s ease-in-out', style('*'))
8738
- ], { optional: true }),
8739
- query(':leave', [
8740
- animate('0.9s ease-in-out', style({
8741
- zIndex: 0,
8742
- opacity: 0
8743
- }))
8744
- ], { optional: true })
8745
- ]));
8746
- const carouselPlay = trigger('carouselPlay', [
8747
- state('*', style({ transform: 'translateX(0)', display: 'block', opacity: 1 })),
8748
- transition(toFadeLeft, useAnimation(fadeAnimationLeft)),
8749
- transition(toFadeRight, useAnimation(fadeAnimationRight)),
8750
- transition(toSlideLeft, useAnimation(slideAnimationLeft)),
8751
- transition(toSlideRight, useAnimation(slideAnimationRight))
8752
- ]);
8753
-
8754
8790
  class CarouselInnerComponent {
8755
- #carouselState = inject(CarouselState);
8791
+ #carouselService = inject(CarouselService);
8756
8792
  activeIndex = signal(undefined, /* @ts-ignore */
8757
8793
  ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
8758
8794
  animate = signal(true, /* @ts-ignore */
@@ -8780,7 +8816,7 @@ class CarouselInnerComponent {
8780
8816
  }
8781
8817
  ngAfterContentChecked() {
8782
8818
  this.setItems();
8783
- const state = this.#carouselState?.state;
8819
+ const state = this.#carouselService?.state;
8784
8820
  const nextIndex = state?.activeItemIndex;
8785
8821
  const nextDirection = state?.direction;
8786
8822
  if (this.activeIndex() !== nextIndex) {
@@ -8795,18 +8831,16 @@ class CarouselInnerComponent {
8795
8831
  const contentItems = this.contentItems();
8796
8832
  if (this.#prevContentItems() !== contentItems) {
8797
8833
  this.#prevContentItems.set([...contentItems]);
8798
- this.#carouselState.setItems(contentItems);
8834
+ this.#carouselService.setItems(contentItems);
8799
8835
  }
8800
8836
  }
8801
8837
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselInnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8802
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: CarouselInnerComponent, isStandalone: true, selector: "c-carousel-inner", host: { properties: { "@carouselPlay": "slideType()", "@.disabled": "!animate()", "attr.aria-live": "ariaLive()" }, classAttribute: "carousel-inner" }, queries: [{ propertyName: "contentItems", predicate: CarouselItemComponent, isSignal: true }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:block}\n"], animations: [carouselPlay] });
8838
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: CarouselInnerComponent, isStandalone: true, selector: "c-carousel-inner", host: { properties: { "attr.aria-live": "ariaLive()" }, classAttribute: "carousel-inner" }, queries: [{ propertyName: "contentItems", predicate: CarouselItemComponent, isSignal: true }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:block}\n"] });
8803
8839
  }
8804
8840
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselInnerComponent, decorators: [{
8805
8841
  type: Component,
8806
- args: [{ selector: 'c-carousel-inner', animations: [carouselPlay], template: '<ng-content />', host: {
8842
+ args: [{ selector: 'c-carousel-inner', template: '<ng-content />', host: {
8807
8843
  class: 'carousel-inner',
8808
- '[@carouselPlay]': 'slideType()',
8809
- '[@.disabled]': '!animate()',
8810
8844
  '[attr.aria-live]': 'ariaLive()'
8811
8845
  }, styles: [":host{display:block}\n"] }]
8812
8846
  }], propDecorators: { contentItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => CarouselItemComponent), { isSignal: true }] }] } });
@@ -8827,7 +8861,7 @@ class CarouselModule {
8827
8861
  CarouselIndicatorsComponent,
8828
8862
  CarouselInnerComponent,
8829
8863
  CarouselItemComponent] });
8830
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselModule, providers: [CarouselService, CarouselState, CarouselConfig] });
8864
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselModule, providers: [CarouselService, CarouselConfig] });
8831
8865
  }
8832
8866
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CarouselModule, decorators: [{
8833
8867
  type: NgModule,
@@ -8840,7 +8874,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
8840
8874
  CarouselInnerComponent,
8841
8875
  CarouselItemComponent
8842
8876
  ],
8843
- providers: [CarouselService, CarouselState, CarouselConfig],
8877
+ providers: [CarouselService, CarouselConfig],
8844
8878
  exports: [
8845
8879
  CarouselComponent,
8846
8880
  CarouselCaptionComponent,
@@ -12464,46 +12498,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
12464
12498
  }]
12465
12499
  }] });
12466
12500
 
12467
- const loadingButtonAnimation = trigger('loadingButton', [
12468
- transition(':enter', [
12469
- style({
12470
- opacity: 0,
12471
- marginRight: '1rem',
12472
- marginLeft: '-2rem'
12473
- }),
12474
- animate('.15s ease-in-out', style({
12475
- opacity: 1,
12476
- marginRight: '1rem',
12477
- marginLeft: '0rem'
12478
- }))
12479
- ]),
12480
- transition(':leave', [
12481
- style({
12482
- opacity: 1
12483
- }),
12484
- animate('.15s ease-in-out', style({
12485
- opacity: 0,
12486
- marginRight: '1rem',
12487
- marginLeft: '-2rem'
12488
- }))
12489
- ])
12490
- ]);
12491
-
12492
12501
  class LoadingButtonComponent extends ButtonDirective {
12493
12502
  /**
12494
- * Makes button disabled when loading.
12495
- * @type boolean
12503
+ * Makes a button disabled when loading.
12504
+ * @return boolean
12496
12505
  * @default false
12497
12506
  */
12498
12507
  disabledOnLoading = input(false, { ...(ngDevMode ? { debugName: "disabledOnLoading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
12499
12508
  /**
12500
12509
  * Loading state (set to true to start animation).
12501
- * @type boolean
12510
+ * @return boolean
12502
12511
  */
12503
12512
  loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
12504
12513
  /**
12505
12514
  * Event emitted on loading change
12506
- * @type boolean
12515
+ * @return boolean
12507
12516
  */
12508
12517
  loadingChange = output();
12509
12518
  loadingEffect = effect(() => {
@@ -12511,8 +12520,8 @@ class LoadingButtonComponent extends ButtonDirective {
12511
12520
  }, /* @ts-ignore */
12512
12521
  ...(ngDevMode ? [{ debugName: "loadingEffect" }] : /* istanbul ignore next */ []));
12513
12522
  /**
12514
- * Sets type of spinner.
12515
- * @type {'border' | 'grow'}
12523
+ * Sets a type of spinner.
12524
+ * @return {'border' | 'grow'}
12516
12525
  */
12517
12526
  spinnerType = input('border', /* @ts-ignore */
12518
12527
  ...(ngDevMode ? [{ debugName: "spinnerType" }] : /* istanbul ignore next */ []));
@@ -12541,11 +12550,22 @@ class LoadingButtonComponent extends ButtonDirective {
12541
12550
  }, /* @ts-ignore */
12542
12551
  ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
12543
12552
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: LoadingButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12544
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: LoadingButtonComponent, isStandalone: true, selector: "button[cLoadingButton], a[cLoadingButton]", inputs: { disabledOnLoading: { classPropertyName: "disabledOnLoading", publicName: "disabledOnLoading", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, spinnerType: { classPropertyName: "spinnerType", publicName: "spinnerType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loadingChange: "loadingChange" }, host: { properties: { "class": "hostClasses()", "attr.aria-disabled": "ariaDisabled()", "attr.aria-pressed": "isActive()", "attr.disabled": "attrDisabled()", "attr.tabindex": "tabIndex()", "attr.type": "type()" }, classAttribute: "btn-loading" }, exportAs: ["cLoadingButton"], usesInheritance: true, ngImport: i0, template: "@if (loading()) {\n <c-spinner [variant]=\"spinnerType()\" size=\"sm\" class=\"btn-loading-spinner\" @loadingButton />\n}\n<ng-content />\n", dependencies: [{ kind: "component", type: SpinnerComponent, selector: "c-spinner", inputs: ["color", "label", "size", "variant", "role"] }], animations: [loadingButtonAnimation] });
12553
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: LoadingButtonComponent, isStandalone: true, selector: "button[cLoadingButton], a[cLoadingButton]", inputs: { disabledOnLoading: { classPropertyName: "disabledOnLoading", publicName: "disabledOnLoading", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, spinnerType: { classPropertyName: "spinnerType", publicName: "spinnerType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loadingChange: "loadingChange" }, host: { properties: { "class": "hostClasses()", "attr.aria-disabled": "ariaDisabled()", "attr.aria-pressed": "isActive()", "attr.disabled": "attrDisabled()", "attr.tabindex": "tabIndex()", "attr.type": "type()" }, classAttribute: "btn-loading" }, exportAs: ["cLoadingButton"], usesInheritance: true, ngImport: i0, template: `
12554
+ @if (loading()) {
12555
+ <c-spinner
12556
+ [variant]="spinnerType()"
12557
+ size="sm"
12558
+ class="btn-loading-spinner"
12559
+ animate.enter="spinner-enter"
12560
+ animate.leave="spinner-leave"
12561
+ />
12562
+ }
12563
+ <ng-content />
12564
+ `, isInline: true, styles: [":host ::ng-deep .btn-loading-spinner{margin-inline-end:1rem;margin-inline-start:0}.spinner-enter{animation:spinnerEnter .15s ease-in-out}@keyframes spinnerEnter{0%{opacity:0;margin-inline-start:-2rem}to{opacity:1;margin-inline-start:0}}.spinner-leave{animation:spinnerLeave .15s ease-in-out}@keyframes spinnerLeave{0%{opacity:1;margin-inline-start:0}to{opacity:0;margin-inline-start:-2rem}}\n"], dependencies: [{ kind: "component", type: SpinnerComponent, selector: "c-spinner", inputs: ["color", "label", "size", "variant", "role"] }] });
12545
12565
  }
12546
12566
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: LoadingButtonComponent, decorators: [{
12547
12567
  type: Component,
12548
- args: [{ selector: 'button[cLoadingButton], a[cLoadingButton]', exportAs: 'cLoadingButton', imports: [SpinnerComponent], animations: [loadingButtonAnimation], host: {
12568
+ args: [{ selector: 'button[cLoadingButton], a[cLoadingButton]', exportAs: 'cLoadingButton', imports: [SpinnerComponent], host: {
12549
12569
  class: 'btn-loading',
12550
12570
  '[class]': 'hostClasses()',
12551
12571
  '[attr.aria-disabled]': 'ariaDisabled()',
@@ -12553,7 +12573,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
12553
12573
  '[attr.disabled]': 'attrDisabled()',
12554
12574
  '[attr.tabindex]': 'tabIndex()',
12555
12575
  '[attr.type]': 'type()'
12556
- }, template: "@if (loading()) {\n <c-spinner [variant]=\"spinnerType()\" size=\"sm\" class=\"btn-loading-spinner\" @loadingButton />\n}\n<ng-content />\n" }]
12576
+ }, template: `
12577
+ @if (loading()) {
12578
+ <c-spinner
12579
+ [variant]="spinnerType()"
12580
+ size="sm"
12581
+ class="btn-loading-spinner"
12582
+ animate.enter="spinner-enter"
12583
+ animate.leave="spinner-leave"
12584
+ />
12585
+ }
12586
+ <ng-content />
12587
+ `, styles: [":host ::ng-deep .btn-loading-spinner{margin-inline-end:1rem;margin-inline-start:0}.spinner-enter{animation:spinnerEnter .15s ease-in-out}@keyframes spinnerEnter{0%{opacity:0;margin-inline-start:-2rem}to{opacity:1;margin-inline-start:0}}.spinner-leave{animation:spinnerLeave .15s ease-in-out}@keyframes spinnerLeave{0%{opacity:1;margin-inline-start:0}to{opacity:0;margin-inline-start:-2rem}}\n"] }]
12557
12588
  }], ctorParameters: () => [], propDecorators: { disabledOnLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledOnLoading", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingChange: [{ type: i0.Output, args: ["loadingChange"] }], spinnerType: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinnerType", required: false }] }] } });
12558
12589
 
12559
12590
  class LoadingButtonModule {
@@ -12887,12 +12918,11 @@ class NavbarComponent {
12887
12918
  if (!collapse) {
12888
12919
  return;
12889
12920
  }
12890
- const animate = collapse.animate();
12891
12921
  collapse.animate.set(false);
12892
12922
  collapse.toggle(false);
12893
12923
  setTimeout(() => {
12894
12924
  collapse.toggle(result.matches);
12895
- setTimeout(() => collapse.animate.set(animate));
12925
+ setTimeout(() => collapse.animate.set(collapse.animateInput()));
12896
12926
  });
12897
12927
  });
12898
12928
  onCleanup(() => subscription.unsubscribe());
@@ -12973,27 +13003,29 @@ class NavbarTogglerDirective {
12973
13003
  }
12974
13004
  /**
12975
13005
  * Reference to navbar collapse element (via # template variable) . [docs]
12976
- * @type string
13006
+ * @return string
12977
13007
  * @default 'button'
12978
13008
  */
12979
13009
  collapseRef = input(undefined, { ...(ngDevMode ? { debugName: "collapseRef" } : /* istanbul ignore next */ {}), alias: 'cNavbarToggler' });
12980
13010
  /**
12981
13011
  * Default type for navbar-toggler. [docs]
12982
- * @type string
13012
+ * @return string
12983
13013
  * @default 'button'
12984
13014
  */
12985
13015
  type = input('button', /* @ts-ignore */
12986
13016
  ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
12987
13017
  /**
12988
13018
  * Default aria-label attr for navbar-toggler. [docs]
12989
- * @type string
13019
+ * @return string
12990
13020
  * @default 'Toggle navigation'
12991
13021
  */
12992
13022
  ariaLabel = input('Toggle navigation', /* @ts-ignore */
12993
13023
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
12994
13024
  handleClick($event) {
12995
13025
  const collapseRef = this.collapseRef();
12996
- collapseRef?.toggle(!collapseRef?.visible());
13026
+ if (collapseRef) {
13027
+ collapseRef?.toggle(!collapseRef?.visible());
13028
+ }
12997
13029
  }
12998
13030
  addDefaultIcon() {
12999
13031
  const span = this.#renderer.createElement('span');
@@ -13893,6 +13925,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
13893
13925
  }] });
13894
13926
 
13895
13927
  class OtpService {
13928
+ count = signal(0, /* @ts-ignore */
13929
+ ...(ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []));
13896
13930
  disabled = signal(false, /* @ts-ignore */
13897
13931
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
13898
13932
  masked = signal(false, /* @ts-ignore */
@@ -13966,12 +14000,22 @@ class OtpDirective {
13966
14000
  ...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
13967
14001
  index = signal(undefined, /* @ts-ignore */
13968
14002
  ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
14003
+ // Only the first slot advertises the one-time code, so SMS autofill and
14004
+ // password managers target a single field instead of every slot.
14005
+ autocomplete = computed(() => (this.index() === 0 ? 'one-time-code' : 'off'), /* @ts-ignore */
14006
+ ...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ []));
14007
+ // An empty first slot is where autofill lands, so it has to accept the whole
14008
+ // code; once it holds a character, it behaves like every other slot.
14009
+ maxLength = computed(() => (this.index() === 0 && !this.value() ? this.#otpService.count() || 1 : 1), /* @ts-ignore */
14010
+ ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
14011
+ enterKeyHint = computed(() => (this.index() === this.#otpService.count() - 1 ? 'done' : 'next'), /* @ts-ignore */
14012
+ ...(ngDevMode ? [{ debugName: "enterKeyHint" }] : /* istanbul ignore next */ []));
13969
14013
  focus(origin) {
13970
14014
  if (!this.disabled) {
13971
14015
  this.hostElement.nativeElement.focus();
13972
14016
  this.focusable.set(true);
13973
14017
  }
13974
- // console.log('focus called with origin:', origin, this.index());
14018
+ // console.log('focus called with origin: ', origin, this.index());
13975
14019
  }
13976
14020
  #otpServiceEffect = effect(() => {
13977
14021
  this.#disabled.set(this.#otpService.disabled());
@@ -13997,7 +14041,7 @@ class OtpDirective {
13997
14041
  }
13998
14042
  }
13999
14043
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: OtpDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
14000
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: OtpDirective, isStandalone: true, selector: "input[cOtp]", inputs: { placeholderInput: { classPropertyName: "placeholderInput", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "selectionchange": "handleSelectionChange($event)" }, properties: { "class": "hostClasses()", "attr.inputMode": "inputMode()", "attr.maxLength": "1", "autocomplete": "\"one-time-code\"", "attr.pattern": "pattern()", "placeholder": "placeholder()", "readOnly": "readOnly()", "tabIndex": "tabIndex()", "attr.type": "inputType()" }, classAttribute: "form-otp-control" }, ngImport: i0 });
14044
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: OtpDirective, isStandalone: true, selector: "input[cOtp]", inputs: { placeholderInput: { classPropertyName: "placeholderInput", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "selectionchange": "handleSelectionChange($event)" }, properties: { "class": "hostClasses()", "attr.inputMode": "inputMode()", "attr.maxLength": "maxLength()", "autocomplete": "autocomplete()", "attr.autocapitalize": "\"off\"", "attr.autocorrect": "\"off\"", "attr.enterkeyhint": "enterKeyHint()", "attr.spellcheck": "\"false\"", "attr.pattern": "pattern()", "placeholder": "placeholder()", "readOnly": "readOnly()", "tabIndex": "tabIndex()", "attr.type": "inputType()" }, classAttribute: "form-otp-control" }, ngImport: i0 });
14001
14045
  }
14002
14046
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: OtpDirective, decorators: [{
14003
14047
  type: Directive,
@@ -14008,8 +14052,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
14008
14052
  class: 'form-otp-control',
14009
14053
  '[class]': 'hostClasses()',
14010
14054
  '[attr.inputMode]': 'inputMode()',
14011
- '[attr.maxLength]': '1',
14012
- '[autocomplete]': '"one-time-code"',
14055
+ '[attr.maxLength]': 'maxLength()',
14056
+ '[autocomplete]': 'autocomplete()',
14057
+ '[attr.autocapitalize]': '"off"',
14058
+ '[attr.autocorrect]': '"off"',
14059
+ '[attr.enterkeyhint]': 'enterKeyHint()',
14060
+ '[attr.spellcheck]': '"false"',
14013
14061
  '[attr.pattern]': 'pattern()',
14014
14062
  '[placeholder]': 'placeholder()',
14015
14063
  '[readOnly]': 'readOnly()',
@@ -14087,19 +14135,18 @@ class OneTimePasswordComponent {
14087
14135
  ariaLabel = input((index, total) => `Digit ${index + 1} of ${total}`, /* @ts-ignore */
14088
14136
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
14089
14137
  /**
14090
- * Automatically submit the form when all one time password fields are filled.
14138
+ * Automatically submit the form when all one-time password fields are filled.
14091
14139
  * @default: false
14092
14140
  */
14093
14141
  autoSubmit = input(false, { ...(ngDevMode ? { debugName: "autoSubmit" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
14094
- // readonly children = input();
14095
14142
  /**
14096
- * Initial value for Angular one time password input.
14143
+ * Initial value for Angular one-time password input.
14097
14144
  * @default: undefined
14098
14145
  */
14099
14146
  defaultValue = input(/* @ts-ignore */
14100
14147
  ...(ngDevMode ? [undefined, { debugName: "defaultValue" }] : /* istanbul ignore next */ []));
14101
14148
  /**
14102
- * Disable all one time password (OTP) input fields.
14149
+ * Disable all one-time password (OTP) input fields.
14103
14150
  * @default: false
14104
14151
  */
14105
14152
  disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'disabled' });
@@ -14111,7 +14158,7 @@ class OneTimePasswordComponent {
14111
14158
  */
14112
14159
  linear = input(true, { ...(ngDevMode ? { debugName: "linear" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
14113
14160
  /**
14114
- * Show input as password (masked characters).
14161
+ * Show input as a password (masked characters).
14115
14162
  * @default: false
14116
14163
  */
14117
14164
  masked = input(false, { ...(ngDevMode ? { debugName: "masked" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -14122,12 +14169,12 @@ class OneTimePasswordComponent {
14122
14169
  placeholder = input('', /* @ts-ignore */
14123
14170
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
14124
14171
  /**
14125
- * Make Angular OTP input component read-only.
14172
+ * Make the Angular OTP input component read-only.
14126
14173
  * @default: false
14127
14174
  */
14128
14175
  readOnly = input(false, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
14129
14176
  /**
14130
- * Sets the visual size of the React.js one time password (OTP) input. Use 'sm' for small or 'lg' for large input fields.
14177
+ * Sets the visual size of the Angular one-time password (OTP) input. Use 'sm' for small or 'lg' for large input fields.
14131
14178
  * @default: undefined
14132
14179
  */
14133
14180
  sizing = input(/* @ts-ignore */
@@ -14176,14 +14223,15 @@ class OneTimePasswordComponent {
14176
14223
  }, /* @ts-ignore */
14177
14224
  ...(ngDevMode ? [{ debugName: "#valueEffect" }] : /* istanbul ignore next */ []));
14178
14225
  /**
14179
- * Event triggered when the Angular one time password (OTP) value changes.
14226
+ * Event triggered when the Angular one-time password (OTP) value changes.
14180
14227
  */
14181
14228
  valueChange = output();
14182
14229
  /**
14183
- * Callback triggered when all Angular one time password (OTP) fields are filled.
14230
+ * Callback triggered when all Angular one-time password (OTP) fields are filled.
14184
14231
  */
14185
14232
  complete = output();
14186
14233
  #otpServiceEffect = effect(() => {
14234
+ this.#otpService.count.set(this.inputCount());
14187
14235
  this.#otpService.disabled.set(this.disabled());
14188
14236
  this.#otpService.masked.set(this.masked());
14189
14237
  this.#otpService.placeholder.set(this.placeholder());
@@ -14203,7 +14251,6 @@ class OneTimePasswordComponent {
14203
14251
  };
14204
14252
  }, /* @ts-ignore */
14205
14253
  ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
14206
- // protected readonly inputElementRefs = contentChildren(OtpDirective, { read: ElementRef<HTMLInputElement>, descendants: true });
14207
14254
  inputRefs = contentChildren(OtpDirective, { ...(ngDevMode ? { debugName: "inputRefs" } : /* istanbul ignore next */ {}), descendants: true });
14208
14255
  inputCount = computed(() => this.inputRefs().length, /* @ts-ignore */
14209
14256
  ...(ngDevMode ? [{ debugName: "inputCount" }] : /* istanbul ignore next */ []));
@@ -14282,9 +14329,48 @@ class OneTimePasswordComponent {
14282
14329
  });
14283
14330
  }, /* @ts-ignore */
14284
14331
  ...(ngDevMode ? [{ debugName: "#inputsArrayEffect" }] : /* istanbul ignore next */ []));
14332
+ // Write `chars` across the slots starting at `startIndex`, then move focus.
14333
+ // Shared by paste and by multi-character `input` events.
14334
+ #distributeChars(startIndex, chars) {
14335
+ const inputCount = this.inputCount();
14336
+ if (!inputCount) {
14337
+ return;
14338
+ }
14339
+ // A value at least as long as the field is a complete code: fill from the
14340
+ // first slot, whichever slot happens to be focused.
14341
+ const start = chars.length >= inputCount ? 0 : startIndex;
14342
+ const newValues = [...this.#inputValues()];
14343
+ for (let i = 0; i < chars.length && start + i < inputCount; i++) {
14344
+ newValues[start + i] = chars[i];
14345
+ }
14346
+ this.#inputValues.set(newValues);
14347
+ setTimeout(() => {
14348
+ // Focus the next empty input or the last filled one
14349
+ const nextEmptyIndex = start + chars.length;
14350
+ if (nextEmptyIndex < inputCount) {
14351
+ this.#focusKeyManager.setActiveItem(nextEmptyIndex);
14352
+ }
14353
+ else {
14354
+ this.#focusKeyManager.setLastItemActive();
14355
+ }
14356
+ });
14357
+ }
14285
14358
  handleInputChange($event, index) {
14286
14359
  this.#focusKeyManager.updateActiveItem(index);
14287
14360
  const inputValue = $event.target.value;
14361
+ // SMS autofill, password managers, dictation and IME commits insert the
14362
+ // whole code at once and fire `input`, not `paste`. Spread it across the
14363
+ // slots instead of leaving it in one of them.
14364
+ if (inputValue.length > 1) {
14365
+ const chars = extractValidChars(inputValue, this.type());
14366
+ // The slot is written from the state, so restore what it holds — an
14367
+ // all-invalid value leaves the state untouched.
14368
+ $event.target.value = this.#inputValues()[index] ?? '';
14369
+ if (chars) {
14370
+ this.#distributeChars(index, chars);
14371
+ }
14372
+ return;
14373
+ }
14288
14374
  if (inputValue.length === 1 && !isValidInput(inputValue, this.type())) {
14289
14375
  $event.target.value = '';
14290
14376
  this.#inputValues.update((value) => {
@@ -14356,30 +14442,11 @@ class OneTimePasswordComponent {
14356
14442
  }
14357
14443
  handlePaste($event, index) {
14358
14444
  $event.preventDefault();
14359
- const inputCount = this.inputCount();
14360
14445
  const pastedData = $event.clipboardData?.getData('text') ?? '';
14361
14446
  const validChars = extractValidChars(pastedData, this.type());
14362
14447
  if (!validChars)
14363
14448
  return;
14364
- const newValues = [...this.#inputValues()];
14365
- const startIndex = index;
14366
- for (let i = 0; i < validChars.length && startIndex + i < inputCount; i++) {
14367
- newValues[startIndex + i] = validChars[i];
14368
- }
14369
- // untracked(() => {
14370
- this.#inputValues.set(newValues);
14371
- // });
14372
- setTimeout(() => {
14373
- // Focus the next empty input or the last filled input
14374
- const nextEmptyIndex = startIndex + validChars.length;
14375
- if (nextEmptyIndex < inputCount) {
14376
- this.#focusKeyManager.setActiveItem(nextEmptyIndex);
14377
- // this.#focusKeyManager.setNextItemActive();
14378
- }
14379
- else {
14380
- this.#focusKeyManager.setLastItemActive();
14381
- }
14382
- });
14449
+ this.#distributeChars(index, validChars);
14383
14450
  }
14384
14451
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: OneTimePasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14385
14452
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: OneTimePasswordComponent, isStandalone: true, selector: "c-one-time-password", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, autoSubmit: { classPropertyName: "autoSubmit", publicName: "autoSubmit", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, masked: { classPropertyName: "masked", publicName: "masked", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, sizing: { classPropertyName: "sizing", publicName: "sizing", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, valid: { classPropertyName: "valid", publicName: "valid", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", complete: "complete" }, host: { attributes: { "role": "group" }, properties: { "class": "hostClasses()" } }, providers: [
@@ -14419,8 +14486,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
14419
14486
  }]
14420
14487
  }] });
14421
14488
 
14422
- // export * from './one-time-password.types';
14423
-
14424
14489
  class PageLinkDirective {
14425
14490
  static ngAcceptInputType_disabled;
14426
14491
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -19538,7 +19603,7 @@ class StepperComponent {
19538
19603
  }, /* @ts-ignore */
19539
19604
  ...(ngDevMode ? [{ debugName: "allStepsValid" }] : /* istanbul ignore next */ []));
19540
19605
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: StepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19541
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: StepperComponent, isStandalone: true, selector: "c-stepper", inputs: { activeStepIndexInput: { classPropertyName: "activeStepIndexInput", publicName: "activeStepIndex", isSignal: true, isRequired: false, transformFunction: null }, defaultActiveStepIndex: { classPropertyName: "defaultActiveStepIndex", publicName: "defaultActiveStepIndex", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, stepButtonLayout: { classPropertyName: "stepButtonLayout", publicName: "stepButtonLayout", isSignal: true, isRequired: false, transformFunction: null }, validation: { classPropertyName: "validation", publicName: "validation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { finished: "finished", onReset: "onReset", activeStepIndexChange: "activeStepIndexChange" }, host: { properties: { "class": "hostClasses()", "id": "id()" }, classAttribute: "stepper" }, queries: [{ propertyName: "stepsContent", predicate: StepperStepComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "stepButtons", predicate: StepButtonDirective, descendants: true, isSignal: true }], exportAs: ["cStepper"], ngImport: i0, template: "@let isVertical = layout() === 'vertical';\n@let activeIdx = activeStepIndex();\n@let finished = finishing();\n<ol [attr.aria-orientation]=\"layout()\" class=\"stepper-steps\" role=\"tablist\">\n @for (step of steps(); track step.id; let idx = $index, last = $last) {\n @let isActive = !finished && activeIdx === idx;\n @let isComplete = finished || idx < activeIdx;\n @let isDisabled = step.disabled || finished || (linear() && idx > activeIdx + 1 && step.disabled);\n @let stepId = step.id;\n @let panelId = `${step.id}-panel`;\n <li [class]=\"['stepper-step', stepButtonLayout()]\" role=\"presentation\">\n <button\n #stepButton\n cStepButton\n [attr.inert]=\"step.disabled || null\"\n [attr.aria-selected]=\"isActive || null\"\n [attr.aria-controls]=\"panelId\"\n [tabindex]=\"isActive ? 0 : -1\"\n [disabled]=\"isDisabled\"\n [class]=\"{ 'stepper-step-button': true, active: isActive, complete: isComplete }\"\n id=\"{{ stepId }}\"\n type=\"button\"\n role=\"tab\"\n (click)=\"step.disabled || handleStepClick($event, idx)\"\n (keydown)=\"handleKeyDown($event)\"\n >\n <span class=\"stepper-step-indicator\">\n @if (isComplete) {\n <span class=\"stepper-step-indicator-icon\"></span>\n } @else {\n <span class=\"stepper-step-indicator-text\">\n <ng-container\n [ngTemplateOutlet]=\"step.indicatorRef || indicatorTpl\"\n [ngTemplateOutletContext]=\"step.indicatorCtx\"\n />\n <ng-template #indicatorTpl>{{ step.indicator }}</ng-template>\n </span>\n }\n </span>\n <span class=\"stepper-step-label\">\n <ng-container [ngTemplateOutlet]=\"step.labelRef || labelTpl\" [ngTemplateOutletContext]=\"step.labelCtx\" />\n <ng-template #labelTpl>{{ step.label }}</ng-template>\n </span>\n </button>\n @if (!last) {\n <div class=\"stepper-step-connector\"></div>\n }\n @if (isVertical) {\n <div\n class=\"stepper-step-content\"\n cCollapse\n [visible]=\"!resetting() && isActive\"\n [attr.inert]=\"isActive ? null : true\"\n id=\"{{ panelId }}\"\n role=\"tabpanel\"\n [attr.aria-hidden]=\"!isActive || null\"\n [attr.aria-labelledby]=\"stepId\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"step.templateRef ?? emptyTpl\" />\n </div>\n }\n </li>\n }\n</ol>\n@if (!isVertical) {\n <div class=\"stepper-content\">\n @for (step of steps(); track step.id; let idx = $index) {\n @let isActive = !finished && activeIdx === idx;\n @let stepId = step.id;\n @let panelId = `${step.id}-panel`;\n <div\n [attr.inert]=\"isActive ? null : true\"\n [class]=\"{ 'stepper-pane': true, show: isActive, active: isActive }\"\n id=\"{{ panelId }}\"\n role=\"tabpanel\"\n [attr.aria-hidden]=\"!isActive || null\"\n [attr.aria-labelledby]=\"stepId\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"step.templateRef ?? emptyTpl\" />\n </div>\n }\n </div>\n}\n\n<ng-template #contentTpl>\n <ng-content />\n</ng-template>\n<ng-template #emptyTpl />\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: StepButtonDirective, selector: "button[cStepButton]", exportAs: ["cStepButton"] }, { kind: "directive", type: CollapseDirective, selector: "[cCollapse]", inputs: ["animate", "horizontal", "visible", "navbar", "duration", "transition"], outputs: ["visibleChange", "collapseChange"], exportAs: ["cCollapse"] }] });
19606
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: StepperComponent, isStandalone: true, selector: "c-stepper", inputs: { activeStepIndexInput: { classPropertyName: "activeStepIndexInput", publicName: "activeStepIndex", isSignal: true, isRequired: false, transformFunction: null }, defaultActiveStepIndex: { classPropertyName: "defaultActiveStepIndex", publicName: "defaultActiveStepIndex", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, stepButtonLayout: { classPropertyName: "stepButtonLayout", publicName: "stepButtonLayout", isSignal: true, isRequired: false, transformFunction: null }, validation: { classPropertyName: "validation", publicName: "validation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { finished: "finished", onReset: "onReset", activeStepIndexChange: "activeStepIndexChange" }, host: { properties: { "class": "hostClasses()", "id": "id()" }, classAttribute: "stepper" }, queries: [{ propertyName: "stepsContent", predicate: StepperStepComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "stepButtons", predicate: StepButtonDirective, descendants: true, isSignal: true }], exportAs: ["cStepper"], ngImport: i0, template: "@let isVertical = layout() === 'vertical';\n@let activeIdx = activeStepIndex();\n@let finished = finishing();\n<ol [attr.aria-orientation]=\"layout()\" class=\"stepper-steps\" role=\"tablist\">\n @for (step of steps(); track step.id; let idx = $index, last = $last) {\n @let isActive = !finished && activeIdx === idx;\n @let isComplete = finished || idx < activeIdx;\n @let isDisabled = step.disabled || finished || (linear() && idx > activeIdx + 1 && step.disabled);\n @let stepId = step.id;\n @let panelId = `${step.id}-panel`;\n <li [class]=\"['stepper-step', stepButtonLayout()]\" role=\"presentation\">\n <button\n #stepButton\n cStepButton\n [attr.inert]=\"step.disabled || null\"\n [attr.aria-selected]=\"isActive || null\"\n [attr.aria-controls]=\"panelId\"\n [tabindex]=\"isActive ? 0 : -1\"\n [disabled]=\"isDisabled\"\n [class]=\"{ 'stepper-step-button': true, active: isActive, complete: isComplete }\"\n id=\"{{ stepId }}\"\n type=\"button\"\n role=\"tab\"\n (click)=\"step.disabled || handleStepClick($event, idx)\"\n (keydown)=\"handleKeyDown($event)\"\n >\n <span class=\"stepper-step-indicator\">\n @if (isComplete) {\n <span class=\"stepper-step-indicator-icon\"></span>\n } @else {\n <span class=\"stepper-step-indicator-text\">\n <ng-container\n [ngTemplateOutlet]=\"step.indicatorRef || indicatorTpl\"\n [ngTemplateOutletContext]=\"step.indicatorCtx\"\n />\n <ng-template #indicatorTpl>{{ step.indicator }}</ng-template>\n </span>\n }\n </span>\n <span class=\"stepper-step-label\">\n <ng-container [ngTemplateOutlet]=\"step.labelRef || labelTpl\" [ngTemplateOutletContext]=\"step.labelCtx\" />\n <ng-template #labelTpl>{{ step.label }}</ng-template>\n </span>\n </button>\n @if (!last) {\n <div class=\"stepper-step-connector\"></div>\n }\n @if (isVertical) {\n <div\n class=\"stepper-step-content\"\n cCollapse\n [visible]=\"!resetting() && isActive\"\n [attr.inert]=\"isActive ? null : true\"\n id=\"{{ panelId }}\"\n role=\"tabpanel\"\n [attr.aria-hidden]=\"!isActive || null\"\n [attr.aria-labelledby]=\"stepId\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"step.templateRef ?? emptyTpl\" />\n </div>\n }\n </li>\n }\n</ol>\n@if (!isVertical) {\n <div class=\"stepper-content\">\n @for (step of steps(); track step.id; let idx = $index) {\n @let isActive = !finished && activeIdx === idx;\n @let stepId = step.id;\n @let panelId = `${step.id}-panel`;\n <div\n [attr.inert]=\"isActive ? null : true\"\n [class]=\"{ 'stepper-pane': true, show: isActive, active: isActive }\"\n id=\"{{ panelId }}\"\n role=\"tabpanel\"\n [attr.aria-hidden]=\"!isActive || null\"\n [attr.aria-labelledby]=\"stepId\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"step.templateRef ?? emptyTpl\" />\n </div>\n }\n </div>\n}\n\n<ng-template #contentTpl>\n <ng-content />\n</ng-template>\n<ng-template #emptyTpl />\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: StepButtonDirective, selector: "button[cStepButton]", exportAs: ["cStepButton"] }, { kind: "directive", type: CollapseDirective, selector: "[cCollapse]", inputs: ["animate", "horizontal", "visible", "navbar"], outputs: ["visibleChange", "collapseChange"], exportAs: ["cCollapse"] }] });
19542
19607
  }
19543
19608
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: StepperComponent, decorators: [{
19544
19609
  type: Component,
@@ -20166,85 +20231,116 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
20166
20231
  }]
20167
20232
  }] });
20168
20233
 
20234
+ const getTransitionDurationFromElement = (element) => {
20235
+ if (!element) {
20236
+ return 0;
20237
+ }
20238
+ // Get transition-duration of the element
20239
+ let { transitionDuration, transitionDelay } = window.getComputedStyle(element);
20240
+ const floatTransitionDuration = Number.parseFloat(transitionDuration);
20241
+ const floatTransitionDelay = Number.parseFloat(transitionDelay);
20242
+ // Return 0 if element or transition duration is not found
20243
+ if (!floatTransitionDuration && !floatTransitionDelay) {
20244
+ return 0;
20245
+ }
20246
+ // If multiple durations are defined, take the first
20247
+ transitionDuration = transitionDuration.split(',')[0];
20248
+ transitionDelay = transitionDelay.split(',')[0];
20249
+ return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * 1000;
20250
+ };
20251
+
20169
20252
  class TabPanelComponent {
20170
- tabsService = inject(TabsService);
20253
+ #tabsService = inject(TabsService);
20254
+ #elementRef = inject(ElementRef);
20171
20255
  /**
20172
20256
  * aria-labelledby attribute
20173
- * @type string
20257
+ * @return string
20174
20258
  * @default undefined
20175
20259
  */
20176
20260
  ariaLabelledBy = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelledBy" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
20177
20261
  /**
20178
20262
  * Element id attribute
20179
- * @type string
20263
+ * @return string
20180
20264
  * @default undefined
20181
20265
  */
20182
20266
  id = input(/* @ts-ignore */
20183
20267
  ...(ngDevMode ? [undefined, { debugName: "id" }] : /* istanbul ignore next */ []));
20184
20268
  /**
20185
20269
  * Item key.
20186
- * @type string | number
20270
+ * @return string | number
20187
20271
  * @required
20188
20272
  */
20189
20273
  itemKey = input.required(/* @ts-ignore */
20190
20274
  ...(ngDevMode ? [{ debugName: "itemKey" }] : /* istanbul ignore next */ []));
20191
20275
  /**
20192
20276
  * Element role.
20193
- * @type string
20277
+ * @return string
20194
20278
  * @default 'tabpanel'
20195
20279
  */
20196
20280
  role = input('tabpanel', /* @ts-ignore */
20197
20281
  ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
20198
20282
  /**
20199
20283
  * tabindex attribute.
20200
- * @type number
20284
+ * @return number
20201
20285
  * @default 0
20202
20286
  */
20203
20287
  tabindex = input(0, { ...(ngDevMode ? { debugName: "tabindex" } : /* istanbul ignore next */ {}), transform: numberAttribute });
20204
20288
  /**
20205
20289
  * Enable fade in transition.
20206
- * @type boolean
20290
+ * @return boolean
20207
20291
  * @default true
20208
20292
  */
20209
20293
  transition = input(true, /* @ts-ignore */
20210
20294
  ...(ngDevMode ? [{ debugName: "transition" }] : /* istanbul ignore next */ []));
20211
20295
  /**
20212
20296
  * visible change output
20213
- * @type OutputEmitterRef<VisibleChangeEvent>
20297
+ * @return VisibleChangeEvent
20214
20298
  */
20215
20299
  visibleChange = output();
20216
20300
  show = signal(false, /* @ts-ignore */
20217
20301
  ...(ngDevMode ? [{ debugName: "show" }] : /* istanbul ignore next */ []));
20218
20302
  visible = computed(() => {
20219
- const visible = this.tabsService.activeItemKey() === this.itemKey() && !this.tabsService.activeItem()?.disabled;
20303
+ const visible = this.#tabsService.activeItemKey() === this.itemKey() && !this.#tabsService.activeItem()?.disabled;
20220
20304
  this.visibleChange?.emit({ itemKey: this.itemKey(), visible });
20221
20305
  return visible;
20222
20306
  }, /* @ts-ignore */
20223
20307
  ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
20224
- propId = computed(() => this.id() ?? `${this.tabsService.id()}-panel-${this.itemKey()}`, /* @ts-ignore */
20308
+ #transitionDuration = 0;
20309
+ #visibleEffect = effect(() => {
20310
+ const isVisible = this.visible();
20311
+ const hasTransition = this.transition();
20312
+ if (!hasTransition) {
20313
+ this.show.set(isVisible);
20314
+ }
20315
+ else {
20316
+ requestAnimationFrame(() => {
20317
+ if (this.#transitionDuration === 0) {
20318
+ this.#transitionDuration = getTransitionDurationFromElement(this.#elementRef.nativeElement);
20319
+ }
20320
+ setTimeout(() => this.show.set(isVisible), this.#transitionDuration || 0);
20321
+ });
20322
+ }
20323
+ }, /* @ts-ignore */
20324
+ ...(ngDevMode ? [{ debugName: "#visibleEffect" }] : /* istanbul ignore next */ []));
20325
+ propId = computed(() => this.id() ?? `${this.#tabsService.id()}-panel-${this.itemKey()}`, /* @ts-ignore */
20225
20326
  ...(ngDevMode ? [{ debugName: "propId" }] : /* istanbul ignore next */ []));
20226
- attrAriaLabelledBy = computed(() => this.ariaLabelledBy() ?? `${this.tabsService.id()}-tab-${this.itemKey()}`, /* @ts-ignore */
20327
+ attrAriaLabelledBy = computed(() => this.ariaLabelledBy() ?? `${this.#tabsService.id()}-tab-${this.itemKey()}`, /* @ts-ignore */
20227
20328
  ...(ngDevMode ? [{ debugName: "attrAriaLabelledBy" }] : /* istanbul ignore next */ []));
20228
20329
  hostClasses = computed(() => ({
20229
20330
  'tab-pane': true,
20230
- active: this.show(),
20331
+ active: this.visible(),
20231
20332
  fade: this.transition(),
20232
20333
  show: this.show(),
20233
- invisible: this.tabsService.activeItem()?.disabled
20334
+ invisible: this.#tabsService.activeItem()?.disabled
20234
20335
  }), /* @ts-ignore */
20235
20336
  ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
20236
- onAnimationDone($event) {
20237
- this.show.set(this.visible());
20337
+ onTransitionEnd($event) {
20338
+ if ($event.propertyName === 'opacity' && $event.target === this.#elementRef.nativeElement) {
20339
+ this.show.set(this.visible());
20340
+ }
20238
20341
  }
20239
20342
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: TabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20240
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: TabPanelComponent, isStandalone: true, selector: "c-tab-panel", inputs: { ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, itemKey: { classPropertyName: "itemKey", publicName: "itemKey", isSignal: true, isRequired: true, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, tabindex: { classPropertyName: "tabindex", publicName: "tabindex", isSignal: true, isRequired: false, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibleChange: "visibleChange" }, host: { listeners: { "@fadeInOut.done": "onAnimationDone($event)" }, properties: { "class": "hostClasses()", "tabindex": "visible() ? tabindex() : -1", "attr.aria-labelledby": "attrAriaLabelledBy()", "id": "propId()", "attr.role": "role()", "@.disabled": "!transition()", "@fadeInOut": "visible() ? \"show\" : \"hide\"" } }, exportAs: ["cTabPanel"], ngImport: i0, template: '<ng-content />', isInline: true, animations: [
20241
- trigger('fadeInOut', [
20242
- state('show', style({ opacity: 1 })),
20243
- state('hide', style({ opacity: 0 })),
20244
- state('void', style({ opacity: 1 })),
20245
- transition('* => *', [query('@*', [animateChild()], { optional: true }), animate('150ms linear')])
20246
- ])
20247
- ] });
20343
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: TabPanelComponent, isStandalone: true, selector: "c-tab-panel", inputs: { ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, itemKey: { classPropertyName: "itemKey", publicName: "itemKey", isSignal: true, isRequired: true, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, tabindex: { classPropertyName: "tabindex", publicName: "tabindex", isSignal: true, isRequired: false, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibleChange: "visibleChange" }, host: { listeners: { "transitionend": "onTransitionEnd($event)" }, properties: { "class": "hostClasses()", "tabindex": "visible() ? tabindex() : -1", "attr.aria-labelledby": "attrAriaLabelledBy()", "id": "propId()", "attr.role": "role()" } }, exportAs: ["cTabPanel"], ngImport: i0, template: '<ng-content />', isInline: true });
20248
20344
  }
20249
20345
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: TabPanelComponent, decorators: [{
20250
20346
  type: Component,
@@ -20258,18 +20354,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
20258
20354
  '[attr.aria-labelledby]': 'attrAriaLabelledBy()',
20259
20355
  '[id]': 'propId()',
20260
20356
  '[attr.role]': 'role()',
20261
- '[@.disabled]': '!transition()',
20262
- '[@fadeInOut]': 'visible() ? "show" : "hide"',
20263
- '(@fadeInOut.done)': 'onAnimationDone($event)'
20264
- },
20265
- animations: [
20266
- trigger('fadeInOut', [
20267
- state('show', style({ opacity: 1 })),
20268
- state('hide', style({ opacity: 0 })),
20269
- state('void', style({ opacity: 1 })),
20270
- transition('* => *', [query('@*', [animateChild()], { optional: true }), animate('150ms linear')])
20271
- ])
20272
- ]
20357
+ '(transitionend)': 'onTransitionEnd($event)'
20358
+ }
20273
20359
  }]
20274
20360
  }], propDecorators: { ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], itemKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemKey", required: true }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], tabindex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabindex", required: false }] }], transition: [{ type: i0.Input, args: [{ isSignal: true, alias: "transition", required: false }] }], visibleChange: [{ type: i0.Output, args: ["visibleChange"] }] } });
20275
20361