@besaitech/ng-design-system 0.0.33 → 0.0.35

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, input, computed, ChangeDetectionStrategy, Component, booleanAttribute, isDevMode, effect, output, signal, forwardRef, viewChild, numberAttribute, afterRenderEffect, ElementRef, model, Injector, afterNextRender, Injectable, TemplateRef, Directive, contentChildren, contentChild } from '@angular/core';
2
+ import { inject, input, computed, ChangeDetectionStrategy, Component, booleanAttribute, isDevMode, effect, output, signal, forwardRef, numberAttribute, viewChildren, afterRenderEffect, viewChild, ElementRef, model, Injector, afterNextRender, Injectable, TemplateRef, Directive, contentChildren, contentChild } from '@angular/core';
3
3
  import { DomSanitizer } from '@angular/platform-browser';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule } from '@angular/forms';
@@ -27,6 +27,7 @@ const SDS_ICONS = {
27
27
  'user-round': '<circle cx="12" cy="8" r="5"/><path d="M20 21a8 8 0 0 0-16 0"/>',
28
28
  home: '<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>',
29
29
  'user-plus': '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" x2="19" y1="8" y2="14"/><line x1="22" x2="16" y1="11" y2="11"/>',
30
+ 'user-check': '<path d="m16 11 2 2 4-4"/><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/>',
30
31
  hand: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-hand-icon lucide-hand"><path d="M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2"/><path d="M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2"/><path d="M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8"/><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"/></svg>',
31
32
  users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
32
33
  // Couriers. The back-office and the courier-facing screens both name a rider, and every Belvigo
@@ -152,7 +153,7 @@ const VARIANTS$2 = {
152
153
  ghost: 'bg-transparent text-ink-soft hover:bg-black/5 active:bg-black/10',
153
154
  danger: 'bg-danger text-white shadow-sm hover:brightness-95 active:brightness-90',
154
155
  };
155
- const SIZES$9 = {
156
+ const SIZES$a = {
156
157
  sm: 'h-8 px-3 text-sm',
157
158
  md: 'h-10 px-4 text-sm',
158
159
  lg: 'h-12 px-5 text-base',
@@ -212,7 +213,7 @@ class SdsButton {
212
213
  BASE,
213
214
  this.shape() === 'pill' ? 'rounded-full' : 'rounded-control',
214
215
  VARIANTS$2[this.variant()],
215
- SIZES$9[size],
216
+ SIZES$a[size],
216
217
  this.iconOnly() ? ICON_ONLY[size] : '',
217
218
  this.block() ? 'w-full' : '',
218
219
  ]
@@ -264,8 +265,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
264
265
  `, styles: [".sds-spinner{width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:9999px;animation:sds-spin .6s linear infinite}@keyframes sds-spin{to{transform:rotate(360deg)}}\n"] }]
265
266
  }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
266
267
 
267
- let nextId$a = 0;
268
- const SIZES$8 = {
268
+ let nextId$b = 0;
269
+ const SIZES$9 = {
269
270
  sm: 'h-9 text-sm',
270
271
  md: 'h-10 text-sm',
271
272
  lg: 'h-12 text-base',
@@ -277,7 +278,7 @@ const SIZES$8 = {
277
278
  * sidebar search field).
278
279
  */
279
280
  class SdsInput {
280
- inputId = `sds-input-${nextId$a++}`;
281
+ inputId = `sds-input-${nextId$b++}`;
281
282
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
282
283
  /** Accessible name used when no visible [label] is provided. */
283
284
  ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
@@ -354,7 +355,7 @@ class SdsInput {
354
355
  return `${left} ${right}`;
355
356
  }, ...(ngDevMode ? [{ debugName: "fieldPadding" }] : []));
356
357
  wrapperClasses = computed(() => {
357
- const parts = [SIZES$8[this.size()], this.pill() ? 'rounded-full' : 'rounded-control'];
358
+ const parts = [SIZES$9[this.size()], this.pill() ? 'rounded-full' : 'rounded-control'];
358
359
  if (this.isDisabled())
359
360
  parts.push('opacity-60 cursor-not-allowed');
360
361
  if (this.filled()) {
@@ -598,6 +599,323 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
598
599
  `, styles: ["input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{transition:background-color 100000s ease-in-out 0s;-webkit-text-fill-color:currentColor;caret-color:currentColor}\n"] }]
599
600
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], trailingAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingAction", required: false }] }], trailingActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingActionLabel", required: false }] }], trailingActionPressed: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingActionPressed", required: false }] }], trailingActionClick: [{ type: i0.Output, args: ["trailingActionClick"] }] } });
600
601
 
602
+ let nextId$a = 0;
603
+ const SIZES$8 = {
604
+ md: 'h-12 w-11 text-lg',
605
+ lg: 'h-14 w-12 text-xl',
606
+ };
607
+ /**
608
+ * A segmented one-time-code field: one box per character, for the short numeric codes emailed or
609
+ * texted for sign-in and verification. Implements ControlValueAccessor — bind
610
+ * `formControlName`/`[(ngModel)]`; the value is the concatenated string (e.g. `"483920"`), and
611
+ * {@link completed} fires the moment every box is filled.
612
+ *
613
+ * <p>Only digits are accepted (`inputMode` is `numeric` by default). Typing auto-advances,
614
+ * Backspace steps back and clears, the arrow keys move between boxes, and pasting a whole code
615
+ * distributes it across the boxes from the focused one — so a user can paste `483920` into the
616
+ * first box and have it land correctly.
617
+ */
618
+ class SdsOtpInput {
619
+ groupId = `sds-otp-${nextId$a++}`;
620
+ /** How many boxes / characters the code has. */
621
+ length = input(6, ...(ngDevMode ? [{ debugName: "length", transform: numberAttribute }] : [{ transform: numberAttribute }]));
622
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
623
+ /** Accessible name for the whole group when no visible [label] is provided. */
624
+ ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
625
+ hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : []));
626
+ error = input('', ...(ngDevMode ? [{ debugName: "error" }] : []));
627
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
628
+ /** `numeric` for digit codes (the default); `text` for alphanumeric codes. */
629
+ inputMode = input('numeric', ...(ngDevMode ? [{ debugName: "inputMode" }] : []));
630
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
631
+ /** Focus the first box on first render. */
632
+ autoFocus = input(false, ...(ngDevMode ? [{ debugName: "autoFocus", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
633
+ /**
634
+ * Accessible name for an individual box, suffixed with its 1-based position ("Digit 1", "Digit
635
+ * 2", …). French default so existing consumers are unchanged; translate it in an app serving more
636
+ * than one language, since each box is an icon-less control whose only name this is.
637
+ */
638
+ cellLabel = input('Chiffre', ...(ngDevMode ? [{ debugName: "cellLabel" }] : []));
639
+ /** Emitted with the full value the moment the last box is filled. */
640
+ completed = output();
641
+ cells = viewChildren('cell', ...(ngDevMode ? [{ debugName: "cells" }] : []));
642
+ /** One entry per box; the source of truth, kept exactly {@link length} long. */
643
+ chars = signal([], ...(ngDevMode ? [{ debugName: "chars" }] : []));
644
+ cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : []));
645
+ indexes = computed(() => Array.from({ length: this.length() }, (_, i) => i), ...(ngDevMode ? [{ debugName: "indexes" }] : []));
646
+ isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
647
+ describedBy = computed(() => {
648
+ if (this.error())
649
+ return `${this.groupId}-err`;
650
+ if (this.hint())
651
+ return `${this.groupId}-hint`;
652
+ return null;
653
+ }, ...(ngDevMode ? [{ debugName: "describedBy" }] : []));
654
+ cellClasses = computed(() => {
655
+ const parts = ['rounded-control border', SIZES$8[this.size()]];
656
+ parts.push(this.error()
657
+ ? 'border-danger focus:border-danger focus:ring-2 focus:ring-danger/25'
658
+ : 'border-border text-ink focus:border-brand-500 focus:ring-2 focus:ring-brand-500/25');
659
+ if (this.isDisabled())
660
+ parts.push('opacity-60');
661
+ return parts.join(' ');
662
+ }, ...(ngDevMode ? [{ debugName: "cellClasses" }] : []));
663
+ constructor() {
664
+ // Autofocus once the boxes are in the DOM. afterRenderEffect re-runs on signal reads, but the
665
+ // guard keeps it to the first paint — refocusing on every value change would fight the user.
666
+ let focused = false;
667
+ afterRenderEffect(() => {
668
+ if (this.autoFocus() && !focused && !this.isDisabled()) {
669
+ this.cells()[0]?.nativeElement.focus();
670
+ focused = true;
671
+ }
672
+ });
673
+ }
674
+ // --- ControlValueAccessor -------------------------------------------------
675
+ onChange = () => { };
676
+ onTouched = () => { };
677
+ writeValue(value) {
678
+ // Programmatic set never emits — CVA writeValue must not call onChange.
679
+ this.chars.set(this.spread(value ?? ''));
680
+ }
681
+ registerOnChange(fn) {
682
+ this.onChange = fn;
683
+ }
684
+ registerOnTouched(fn) {
685
+ this.onTouched = fn;
686
+ }
687
+ setDisabledState(isDisabled) {
688
+ this.cvaDisabled.set(isDisabled);
689
+ }
690
+ // --- events ---------------------------------------------------------------
691
+ charAt(index) {
692
+ return this.chars()[index] ?? '';
693
+ }
694
+ onInput(event, index) {
695
+ const el = event.target;
696
+ const raw = el.value;
697
+ const digits = this.sanitize(raw);
698
+ if (digits.length === 0) {
699
+ if (raw.length === 0) {
700
+ // Genuinely emptied (cut, or a deletion the keydown handler did not catch) — clear the box.
701
+ this.setChar(index, '');
702
+ }
703
+ else {
704
+ // A rejected character (letter, symbol) — reassert the box's real content, since the
705
+ // [value] binding will not repaint an unchanged signal.
706
+ el.value = this.charAt(index);
707
+ }
708
+ return;
709
+ }
710
+ if (digits.length > 1) {
711
+ // Fast typing or an autofill dropped several characters into one box — spread them.
712
+ this.fill(digits, index);
713
+ return;
714
+ }
715
+ this.setChar(index, digits);
716
+ this.focusIndex(index + 1);
717
+ }
718
+ onKeydown(event, index) {
719
+ switch (event.key) {
720
+ case 'Backspace':
721
+ event.preventDefault();
722
+ if (this.charAt(index)) {
723
+ this.setChar(index, '');
724
+ }
725
+ else if (index > 0) {
726
+ this.setChar(index - 1, '');
727
+ this.focusIndex(index - 1);
728
+ }
729
+ break;
730
+ case 'ArrowLeft':
731
+ event.preventDefault();
732
+ this.focusIndex(index - 1);
733
+ break;
734
+ case 'ArrowRight':
735
+ event.preventDefault();
736
+ this.focusIndex(index + 1);
737
+ break;
738
+ case 'Delete':
739
+ event.preventDefault();
740
+ this.setChar(index, '');
741
+ break;
742
+ default:
743
+ break;
744
+ }
745
+ }
746
+ onPaste(event, index) {
747
+ const digits = this.sanitize(event.clipboardData?.getData('text') ?? '');
748
+ if (!digits)
749
+ return;
750
+ event.preventDefault();
751
+ this.fill(digits, index);
752
+ }
753
+ onFocus(event) {
754
+ // Select the box's content so a keystroke overwrites rather than being rejected by maxlength.
755
+ event.target.select();
756
+ }
757
+ // --- internals ------------------------------------------------------------
758
+ sanitize(raw) {
759
+ return this.inputMode() === 'numeric'
760
+ ? raw.replace(/\D/g, '')
761
+ : raw.replace(/[^A-Za-z0-9]/g, '');
762
+ }
763
+ /** Normalize any input string into an array exactly {@link length} long. */
764
+ spread(raw) {
765
+ const cleaned = this.sanitize(raw).slice(0, this.length());
766
+ return Array.from({ length: this.length() }, (_, i) => cleaned[i] ?? '');
767
+ }
768
+ setChar(index, value) {
769
+ const next = this.normalized();
770
+ next[index] = value;
771
+ this.commit(next);
772
+ }
773
+ /** Write `digits` across the boxes starting at `start`, then focus the next empty box. */
774
+ fill(digits, start) {
775
+ const next = this.normalized();
776
+ let cursor = start;
777
+ for (const ch of digits) {
778
+ if (cursor >= this.length())
779
+ break;
780
+ next[cursor] = ch;
781
+ cursor += 1;
782
+ }
783
+ this.commit(next);
784
+ this.focusIndex(Math.min(cursor, this.length() - 1));
785
+ }
786
+ commit(next) {
787
+ this.chars.set(next);
788
+ const value = next.join('');
789
+ this.onChange(value);
790
+ if (next.every((c) => c !== '')) {
791
+ this.completed.emit(value);
792
+ }
793
+ }
794
+ /** The current boxes as a fresh, correctly-sized array to mutate. */
795
+ normalized() {
796
+ const current = this.chars();
797
+ return Array.from({ length: this.length() }, (_, i) => current[i] ?? '');
798
+ }
799
+ focusIndex(index) {
800
+ const clamped = Math.max(0, Math.min(index, this.length() - 1));
801
+ const cell = this.cells()[clamped]?.nativeElement;
802
+ if (cell) {
803
+ cell.focus();
804
+ cell.select();
805
+ }
806
+ }
807
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsOtpInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
808
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsOtpInput, isStandalone: true, selector: "sds-otp-input", inputs: { length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, inputMode: { classPropertyName: "inputMode", publicName: "inputMode", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, cellLabel: { classPropertyName: "cellLabel", publicName: "cellLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { completed: "completed" }, host: { classAttribute: "block" }, providers: [
809
+ {
810
+ provide: NG_VALUE_ACCESSOR,
811
+ useExisting: forwardRef(() => SdsOtpInput),
812
+ multi: true,
813
+ },
814
+ ], viewQueries: [{ propertyName: "cells", predicate: ["cell"], descendants: true, isSignal: true }], ngImport: i0, template: `
815
+ @if (label()) {
816
+ <label [id]="groupId + '-label'" class="mb-1.5 block text-sm font-medium text-ink">
817
+ {{ label() }}
818
+ </label>
819
+ }
820
+
821
+ <div
822
+ class="flex items-center gap-2"
823
+ role="group"
824
+ [attr.aria-labelledby]="label() ? groupId + '-label' : null"
825
+ [attr.aria-label]="!label() && ariaLabel() ? ariaLabel() : null"
826
+ [attr.aria-describedby]="describedBy()"
827
+ >
828
+ @for (i of indexes(); track i) {
829
+ <input
830
+ #cell
831
+ type="text"
832
+ [attr.data-index]="i"
833
+ [inputMode]="inputMode()"
834
+ autocomplete="one-time-code"
835
+ maxlength="1"
836
+ [value]="charAt(i)"
837
+ [disabled]="isDisabled()"
838
+ [attr.aria-label]="cellLabel() + ' ' + (i + 1)"
839
+ [attr.aria-invalid]="error() ? 'true' : null"
840
+ class="bg-white text-center font-semibold tabular-nums outline-none transition-colors
841
+ disabled:cursor-not-allowed"
842
+ [class]="cellClasses()"
843
+ (input)="onInput($event, i)"
844
+ (keydown)="onKeydown($event, i)"
845
+ (paste)="onPaste($event, i)"
846
+ (focus)="onFocus($event)"
847
+ (blur)="onTouched()"
848
+ />
849
+ }
850
+ </div>
851
+
852
+ @if (error()) {
853
+ <p [id]="groupId + '-err'" class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
854
+ } @else if (hint()) {
855
+ <p [id]="groupId + '-hint'" class="mt-1.5 text-xs text-ink-faint">{{ hint() }}</p>
856
+ }
857
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
858
+ }
859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsOtpInput, decorators: [{
860
+ type: Component,
861
+ args: [{
862
+ selector: 'sds-otp-input',
863
+ changeDetection: ChangeDetectionStrategy.OnPush,
864
+ providers: [
865
+ {
866
+ provide: NG_VALUE_ACCESSOR,
867
+ useExisting: forwardRef(() => SdsOtpInput),
868
+ multi: true,
869
+ },
870
+ ],
871
+ host: { class: 'block' },
872
+ template: `
873
+ @if (label()) {
874
+ <label [id]="groupId + '-label'" class="mb-1.5 block text-sm font-medium text-ink">
875
+ {{ label() }}
876
+ </label>
877
+ }
878
+
879
+ <div
880
+ class="flex items-center gap-2"
881
+ role="group"
882
+ [attr.aria-labelledby]="label() ? groupId + '-label' : null"
883
+ [attr.aria-label]="!label() && ariaLabel() ? ariaLabel() : null"
884
+ [attr.aria-describedby]="describedBy()"
885
+ >
886
+ @for (i of indexes(); track i) {
887
+ <input
888
+ #cell
889
+ type="text"
890
+ [attr.data-index]="i"
891
+ [inputMode]="inputMode()"
892
+ autocomplete="one-time-code"
893
+ maxlength="1"
894
+ [value]="charAt(i)"
895
+ [disabled]="isDisabled()"
896
+ [attr.aria-label]="cellLabel() + ' ' + (i + 1)"
897
+ [attr.aria-invalid]="error() ? 'true' : null"
898
+ class="bg-white text-center font-semibold tabular-nums outline-none transition-colors
899
+ disabled:cursor-not-allowed"
900
+ [class]="cellClasses()"
901
+ (input)="onInput($event, i)"
902
+ (keydown)="onKeydown($event, i)"
903
+ (paste)="onPaste($event, i)"
904
+ (focus)="onFocus($event)"
905
+ (blur)="onTouched()"
906
+ />
907
+ }
908
+ </div>
909
+
910
+ @if (error()) {
911
+ <p [id]="groupId + '-err'" class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
912
+ } @else if (hint()) {
913
+ <p [id]="groupId + '-hint'" class="mt-1.5 text-xs text-ink-faint">{{ hint() }}</p>
914
+ }
915
+ `,
916
+ }]
917
+ }], ctorParameters: () => [], propDecorators: { length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], inputMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputMode", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], cellLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellLabel", required: false }] }], completed: [{ type: i0.Output, args: ["completed"] }], cells: [{ type: i0.ViewChildren, args: ['cell', { isSignal: true }] }] } });
918
+
601
919
  let nextId$9 = 0;
602
920
  const SIZES$7 = {
603
921
  sm: 'text-sm px-3 py-2',
@@ -7467,5 +7785,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
7467
7785
  * Generated bundle index. Do not edit.
7468
7786
  */
7469
7787
 
7470
- export { SDS_ICONS, SDS_PHONE_COUNTRIES, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAvatar, SdsBadge, SdsButton, SdsCalendar, SdsCard, SdsCheckbox, SdsDatePicker, SdsIcon, SdsInput, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsPaginator, SdsPhoneInput, SdsSelect, SdsShell, SdsSidebar, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsToggleSwitch, SdsTopbar, SidebarStore, addDays, addMonths, addMonthsKeepDay, formatDdMmYyyy, isOutOfRange, isSameDay, isoDay, sdsFormatNational, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth };
7788
+ export { SDS_ICONS, SDS_PHONE_COUNTRIES, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAvatar, SdsBadge, SdsButton, SdsCalendar, SdsCard, SdsCheckbox, SdsDatePicker, SdsIcon, SdsInput, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsOtpInput, SdsPaginator, SdsPhoneInput, SdsSelect, SdsShell, SdsSidebar, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsToggleSwitch, SdsTopbar, SidebarStore, addDays, addMonths, addMonthsKeepDay, formatDdMmYyyy, isOutOfRange, isSameDay, isoDay, sdsFormatNational, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth };
7471
7789
  //# sourceMappingURL=besaitech-ng-design-system.mjs.map