@coreui/angular-pro 5.7.12 → 5.7.13

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';
@@ -15,6 +14,7 @@ import { DomPortal, CdkPortalOutlet } from '@angular/cdk/portal';
15
14
  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';
17
+ import { animation, group, query, animate, style, trigger, state, transition, useAnimation, animateChild } from '@angular/animations';
18
18
  import { BreakpointObserver } from '@angular/cdk/layout';
19
19
  import { IconDirective } from '@coreui/icons-angular';
20
20
 
@@ -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,
@@ -12464,46 +12480,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
12464
12480
  }]
12465
12481
  }] });
12466
12482
 
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
12483
  class LoadingButtonComponent extends ButtonDirective {
12493
12484
  /**
12494
- * Makes button disabled when loading.
12495
- * @type boolean
12485
+ * Makes a button disabled when loading.
12486
+ * @return boolean
12496
12487
  * @default false
12497
12488
  */
12498
12489
  disabledOnLoading = input(false, { ...(ngDevMode ? { debugName: "disabledOnLoading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
12499
12490
  /**
12500
12491
  * Loading state (set to true to start animation).
12501
- * @type boolean
12492
+ * @return boolean
12502
12493
  */
12503
12494
  loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
12504
12495
  /**
12505
12496
  * Event emitted on loading change
12506
- * @type boolean
12497
+ * @return boolean
12507
12498
  */
12508
12499
  loadingChange = output();
12509
12500
  loadingEffect = effect(() => {
@@ -12511,8 +12502,8 @@ class LoadingButtonComponent extends ButtonDirective {
12511
12502
  }, /* @ts-ignore */
12512
12503
  ...(ngDevMode ? [{ debugName: "loadingEffect" }] : /* istanbul ignore next */ []));
12513
12504
  /**
12514
- * Sets type of spinner.
12515
- * @type {'border' | 'grow'}
12505
+ * Sets a type of spinner.
12506
+ * @return {'border' | 'grow'}
12516
12507
  */
12517
12508
  spinnerType = input('border', /* @ts-ignore */
12518
12509
  ...(ngDevMode ? [{ debugName: "spinnerType" }] : /* istanbul ignore next */ []));
@@ -12541,11 +12532,22 @@ class LoadingButtonComponent extends ButtonDirective {
12541
12532
  }, /* @ts-ignore */
12542
12533
  ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
12543
12534
  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] });
12535
+ 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: `
12536
+ @if (loading()) {
12537
+ <c-spinner
12538
+ [variant]="spinnerType()"
12539
+ size="sm"
12540
+ class="btn-loading-spinner"
12541
+ animate.enter="spinner-enter"
12542
+ animate.leave="spinner-leave"
12543
+ />
12544
+ }
12545
+ <ng-content />
12546
+ `, 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
12547
  }
12546
12548
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: LoadingButtonComponent, decorators: [{
12547
12549
  type: Component,
12548
- args: [{ selector: 'button[cLoadingButton], a[cLoadingButton]', exportAs: 'cLoadingButton', imports: [SpinnerComponent], animations: [loadingButtonAnimation], host: {
12550
+ args: [{ selector: 'button[cLoadingButton], a[cLoadingButton]', exportAs: 'cLoadingButton', imports: [SpinnerComponent], host: {
12549
12551
  class: 'btn-loading',
12550
12552
  '[class]': 'hostClasses()',
12551
12553
  '[attr.aria-disabled]': 'ariaDisabled()',
@@ -12553,7 +12555,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
12553
12555
  '[attr.disabled]': 'attrDisabled()',
12554
12556
  '[attr.tabindex]': 'tabIndex()',
12555
12557
  '[attr.type]': 'type()'
12556
- }, template: "@if (loading()) {\n <c-spinner [variant]=\"spinnerType()\" size=\"sm\" class=\"btn-loading-spinner\" @loadingButton />\n}\n<ng-content />\n" }]
12558
+ }, template: `
12559
+ @if (loading()) {
12560
+ <c-spinner
12561
+ [variant]="spinnerType()"
12562
+ size="sm"
12563
+ class="btn-loading-spinner"
12564
+ animate.enter="spinner-enter"
12565
+ animate.leave="spinner-leave"
12566
+ />
12567
+ }
12568
+ <ng-content />
12569
+ `, 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
12570
  }], 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
12571
 
12559
12572
  class LoadingButtonModule {
@@ -12887,12 +12900,11 @@ class NavbarComponent {
12887
12900
  if (!collapse) {
12888
12901
  return;
12889
12902
  }
12890
- const animate = collapse.animate();
12891
12903
  collapse.animate.set(false);
12892
12904
  collapse.toggle(false);
12893
12905
  setTimeout(() => {
12894
12906
  collapse.toggle(result.matches);
12895
- setTimeout(() => collapse.animate.set(animate));
12907
+ setTimeout(() => collapse.animate.set(collapse.animateInput()));
12896
12908
  });
12897
12909
  });
12898
12910
  onCleanup(() => subscription.unsubscribe());
@@ -12973,27 +12985,29 @@ class NavbarTogglerDirective {
12973
12985
  }
12974
12986
  /**
12975
12987
  * Reference to navbar collapse element (via # template variable) . [docs]
12976
- * @type string
12988
+ * @return string
12977
12989
  * @default 'button'
12978
12990
  */
12979
12991
  collapseRef = input(undefined, { ...(ngDevMode ? { debugName: "collapseRef" } : /* istanbul ignore next */ {}), alias: 'cNavbarToggler' });
12980
12992
  /**
12981
12993
  * Default type for navbar-toggler. [docs]
12982
- * @type string
12994
+ * @return string
12983
12995
  * @default 'button'
12984
12996
  */
12985
12997
  type = input('button', /* @ts-ignore */
12986
12998
  ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
12987
12999
  /**
12988
13000
  * Default aria-label attr for navbar-toggler. [docs]
12989
- * @type string
13001
+ * @return string
12990
13002
  * @default 'Toggle navigation'
12991
13003
  */
12992
13004
  ariaLabel = input('Toggle navigation', /* @ts-ignore */
12993
13005
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
12994
13006
  handleClick($event) {
12995
13007
  const collapseRef = this.collapseRef();
12996
- collapseRef?.toggle(!collapseRef?.visible());
13008
+ if (collapseRef) {
13009
+ collapseRef?.toggle(!collapseRef?.visible());
13010
+ }
12997
13011
  }
12998
13012
  addDefaultIcon() {
12999
13013
  const span = this.#renderer.createElement('span');
@@ -13893,6 +13907,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
13893
13907
  }] });
13894
13908
 
13895
13909
  class OtpService {
13910
+ count = signal(0, /* @ts-ignore */
13911
+ ...(ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []));
13896
13912
  disabled = signal(false, /* @ts-ignore */
13897
13913
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
13898
13914
  masked = signal(false, /* @ts-ignore */
@@ -13966,12 +13982,22 @@ class OtpDirective {
13966
13982
  ...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
13967
13983
  index = signal(undefined, /* @ts-ignore */
13968
13984
  ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
13985
+ // Only the first slot advertises the one-time code, so SMS autofill and
13986
+ // password managers target a single field instead of every slot.
13987
+ autocomplete = computed(() => (this.index() === 0 ? 'one-time-code' : 'off'), /* @ts-ignore */
13988
+ ...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ []));
13989
+ // An empty first slot is where autofill lands, so it has to accept the whole
13990
+ // code; once it holds a character, it behaves like every other slot.
13991
+ maxLength = computed(() => (this.index() === 0 && !this.value() ? this.#otpService.count() || 1 : 1), /* @ts-ignore */
13992
+ ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
13993
+ enterKeyHint = computed(() => (this.index() === this.#otpService.count() - 1 ? 'done' : 'next'), /* @ts-ignore */
13994
+ ...(ngDevMode ? [{ debugName: "enterKeyHint" }] : /* istanbul ignore next */ []));
13969
13995
  focus(origin) {
13970
13996
  if (!this.disabled) {
13971
13997
  this.hostElement.nativeElement.focus();
13972
13998
  this.focusable.set(true);
13973
13999
  }
13974
- // console.log('focus called with origin:', origin, this.index());
14000
+ // console.log('focus called with origin: ', origin, this.index());
13975
14001
  }
13976
14002
  #otpServiceEffect = effect(() => {
13977
14003
  this.#disabled.set(this.#otpService.disabled());
@@ -13997,7 +14023,7 @@ class OtpDirective {
13997
14023
  }
13998
14024
  }
13999
14025
  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 });
14026
+ 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
14027
  }
14002
14028
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: OtpDirective, decorators: [{
14003
14029
  type: Directive,
@@ -14008,8 +14034,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
14008
14034
  class: 'form-otp-control',
14009
14035
  '[class]': 'hostClasses()',
14010
14036
  '[attr.inputMode]': 'inputMode()',
14011
- '[attr.maxLength]': '1',
14012
- '[autocomplete]': '"one-time-code"',
14037
+ '[attr.maxLength]': 'maxLength()',
14038
+ '[autocomplete]': 'autocomplete()',
14039
+ '[attr.autocapitalize]': '"off"',
14040
+ '[attr.autocorrect]': '"off"',
14041
+ '[attr.enterkeyhint]': 'enterKeyHint()',
14042
+ '[attr.spellcheck]': '"false"',
14013
14043
  '[attr.pattern]': 'pattern()',
14014
14044
  '[placeholder]': 'placeholder()',
14015
14045
  '[readOnly]': 'readOnly()',
@@ -14087,19 +14117,18 @@ class OneTimePasswordComponent {
14087
14117
  ariaLabel = input((index, total) => `Digit ${index + 1} of ${total}`, /* @ts-ignore */
14088
14118
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
14089
14119
  /**
14090
- * Automatically submit the form when all one time password fields are filled.
14120
+ * Automatically submit the form when all one-time password fields are filled.
14091
14121
  * @default: false
14092
14122
  */
14093
14123
  autoSubmit = input(false, { ...(ngDevMode ? { debugName: "autoSubmit" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
14094
- // readonly children = input();
14095
14124
  /**
14096
- * Initial value for Angular one time password input.
14125
+ * Initial value for Angular one-time password input.
14097
14126
  * @default: undefined
14098
14127
  */
14099
14128
  defaultValue = input(/* @ts-ignore */
14100
14129
  ...(ngDevMode ? [undefined, { debugName: "defaultValue" }] : /* istanbul ignore next */ []));
14101
14130
  /**
14102
- * Disable all one time password (OTP) input fields.
14131
+ * Disable all one-time password (OTP) input fields.
14103
14132
  * @default: false
14104
14133
  */
14105
14134
  disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'disabled' });
@@ -14111,7 +14140,7 @@ class OneTimePasswordComponent {
14111
14140
  */
14112
14141
  linear = input(true, { ...(ngDevMode ? { debugName: "linear" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
14113
14142
  /**
14114
- * Show input as password (masked characters).
14143
+ * Show input as a password (masked characters).
14115
14144
  * @default: false
14116
14145
  */
14117
14146
  masked = input(false, { ...(ngDevMode ? { debugName: "masked" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -14122,12 +14151,12 @@ class OneTimePasswordComponent {
14122
14151
  placeholder = input('', /* @ts-ignore */
14123
14152
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
14124
14153
  /**
14125
- * Make Angular OTP input component read-only.
14154
+ * Make the Angular OTP input component read-only.
14126
14155
  * @default: false
14127
14156
  */
14128
14157
  readOnly = input(false, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
14129
14158
  /**
14130
- * Sets the visual size of the React.js one time password (OTP) input. Use 'sm' for small or 'lg' for large input fields.
14159
+ * Sets the visual size of the Angular one-time password (OTP) input. Use 'sm' for small or 'lg' for large input fields.
14131
14160
  * @default: undefined
14132
14161
  */
14133
14162
  sizing = input(/* @ts-ignore */
@@ -14176,14 +14205,15 @@ class OneTimePasswordComponent {
14176
14205
  }, /* @ts-ignore */
14177
14206
  ...(ngDevMode ? [{ debugName: "#valueEffect" }] : /* istanbul ignore next */ []));
14178
14207
  /**
14179
- * Event triggered when the Angular one time password (OTP) value changes.
14208
+ * Event triggered when the Angular one-time password (OTP) value changes.
14180
14209
  */
14181
14210
  valueChange = output();
14182
14211
  /**
14183
- * Callback triggered when all Angular one time password (OTP) fields are filled.
14212
+ * Callback triggered when all Angular one-time password (OTP) fields are filled.
14184
14213
  */
14185
14214
  complete = output();
14186
14215
  #otpServiceEffect = effect(() => {
14216
+ this.#otpService.count.set(this.inputCount());
14187
14217
  this.#otpService.disabled.set(this.disabled());
14188
14218
  this.#otpService.masked.set(this.masked());
14189
14219
  this.#otpService.placeholder.set(this.placeholder());
@@ -14203,7 +14233,6 @@ class OneTimePasswordComponent {
14203
14233
  };
14204
14234
  }, /* @ts-ignore */
14205
14235
  ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
14206
- // protected readonly inputElementRefs = contentChildren(OtpDirective, { read: ElementRef<HTMLInputElement>, descendants: true });
14207
14236
  inputRefs = contentChildren(OtpDirective, { ...(ngDevMode ? { debugName: "inputRefs" } : /* istanbul ignore next */ {}), descendants: true });
14208
14237
  inputCount = computed(() => this.inputRefs().length, /* @ts-ignore */
14209
14238
  ...(ngDevMode ? [{ debugName: "inputCount" }] : /* istanbul ignore next */ []));
@@ -14282,9 +14311,48 @@ class OneTimePasswordComponent {
14282
14311
  });
14283
14312
  }, /* @ts-ignore */
14284
14313
  ...(ngDevMode ? [{ debugName: "#inputsArrayEffect" }] : /* istanbul ignore next */ []));
14314
+ // Write `chars` across the slots starting at `startIndex`, then move focus.
14315
+ // Shared by paste and by multi-character `input` events.
14316
+ #distributeChars(startIndex, chars) {
14317
+ const inputCount = this.inputCount();
14318
+ if (!inputCount) {
14319
+ return;
14320
+ }
14321
+ // A value at least as long as the field is a complete code: fill from the
14322
+ // first slot, whichever slot happens to be focused.
14323
+ const start = chars.length >= inputCount ? 0 : startIndex;
14324
+ const newValues = [...this.#inputValues()];
14325
+ for (let i = 0; i < chars.length && start + i < inputCount; i++) {
14326
+ newValues[start + i] = chars[i];
14327
+ }
14328
+ this.#inputValues.set(newValues);
14329
+ setTimeout(() => {
14330
+ // Focus the next empty input or the last filled one
14331
+ const nextEmptyIndex = start + chars.length;
14332
+ if (nextEmptyIndex < inputCount) {
14333
+ this.#focusKeyManager.setActiveItem(nextEmptyIndex);
14334
+ }
14335
+ else {
14336
+ this.#focusKeyManager.setLastItemActive();
14337
+ }
14338
+ });
14339
+ }
14285
14340
  handleInputChange($event, index) {
14286
14341
  this.#focusKeyManager.updateActiveItem(index);
14287
14342
  const inputValue = $event.target.value;
14343
+ // SMS autofill, password managers, dictation and IME commits insert the
14344
+ // whole code at once and fire `input`, not `paste`. Spread it across the
14345
+ // slots instead of leaving it in one of them.
14346
+ if (inputValue.length > 1) {
14347
+ const chars = extractValidChars(inputValue, this.type());
14348
+ // The slot is written from the state, so restore what it holds — an
14349
+ // all-invalid value leaves the state untouched.
14350
+ $event.target.value = this.#inputValues()[index] ?? '';
14351
+ if (chars) {
14352
+ this.#distributeChars(index, chars);
14353
+ }
14354
+ return;
14355
+ }
14288
14356
  if (inputValue.length === 1 && !isValidInput(inputValue, this.type())) {
14289
14357
  $event.target.value = '';
14290
14358
  this.#inputValues.update((value) => {
@@ -14356,30 +14424,11 @@ class OneTimePasswordComponent {
14356
14424
  }
14357
14425
  handlePaste($event, index) {
14358
14426
  $event.preventDefault();
14359
- const inputCount = this.inputCount();
14360
14427
  const pastedData = $event.clipboardData?.getData('text') ?? '';
14361
14428
  const validChars = extractValidChars(pastedData, this.type());
14362
14429
  if (!validChars)
14363
14430
  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
- });
14431
+ this.#distributeChars(index, validChars);
14383
14432
  }
14384
14433
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: OneTimePasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14385
14434
  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 +14468,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
14419
14468
  }]
14420
14469
  }] });
14421
14470
 
14422
- // export * from './one-time-password.types';
14423
-
14424
14471
  class PageLinkDirective {
14425
14472
  static ngAcceptInputType_disabled;
14426
14473
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -19538,7 +19585,7 @@ class StepperComponent {
19538
19585
  }, /* @ts-ignore */
19539
19586
  ...(ngDevMode ? [{ debugName: "allStepsValid" }] : /* istanbul ignore next */ []));
19540
19587
  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"] }] });
19588
+ 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
19589
  }
19543
19590
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: StepperComponent, decorators: [{
19544
19591
  type: Component,