@tolle_/tolle-ui 18.2.20 → 18.2.22

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.
@@ -676,6 +676,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
676
676
 
677
677
  class SelectComponent {
678
678
  selectService;
679
+ cdr;
679
680
  placeholder = 'Select an option';
680
681
  class = '';
681
682
  disabled = false;
@@ -687,6 +688,8 @@ class SelectComponent {
687
688
  container;
688
689
  items;
689
690
  sub = new Subscription();
691
+ itemsChangeSub;
692
+ pendingValue = undefined;
690
693
  searchQuery = '';
691
694
  noResults = false;
692
695
  isOpen = false;
@@ -696,8 +699,9 @@ class SelectComponent {
696
699
  onChange = () => { };
697
700
  onTouched = () => { };
698
701
  cn = cn;
699
- constructor(selectService) {
702
+ constructor(selectService, cdr) {
700
703
  this.selectService = selectService;
704
+ this.cdr = cdr;
701
705
  this.sub.add(this.selectService.selectedValue$.subscribe(val => {
702
706
  this.value = val;
703
707
  this.onChange(val);
@@ -729,8 +733,24 @@ class SelectComponent {
729
733
  return cn('ri-arrow-down-s-line text-muted-foreground ml-2 transition-transform duration-200', this.isOpen ? 'rotate-180' : '', (this.size === 'xs' || this.size === 'sm') ? 'text-[14px]' : 'text-[18px]', (this.disabled || this.readonly) && 'opacity-30');
730
734
  }
731
735
  ngAfterContentInit() {
736
+ // Subscribe to items changes to handle dynamic content
737
+ this.itemsChangeSub = this.items.changes.subscribe(() => {
738
+ this.updateItemSelection();
739
+ this.applyPendingValue();
740
+ });
741
+ // Apply initial selection if items are already available
732
742
  this.updateItemSelection();
733
- this.items.changes.subscribe(() => this.updateItemSelection());
743
+ this.applyPendingValue();
744
+ }
745
+ applyPendingValue() {
746
+ if (this.pendingValue !== undefined && this.items && this.items.length > 0) {
747
+ const found = this.items.find(i => i.value === this.pendingValue);
748
+ if (found) {
749
+ this.selectedLabel = found.getLabel();
750
+ this.cdr.markForCheck();
751
+ }
752
+ this.pendingValue = undefined;
753
+ }
734
754
  }
735
755
  updateItemSelection() {
736
756
  if (this.items) {
@@ -739,6 +759,15 @@ class SelectComponent {
739
759
  });
740
760
  }
741
761
  }
762
+ syncSelectedLabel() {
763
+ if (this.items) {
764
+ const found = this.items.find(i => i.value === this.value);
765
+ if (found) {
766
+ this.selectedLabel = found.getLabel();
767
+ this.cdr.markForCheck();
768
+ }
769
+ }
770
+ }
742
771
  _outsideClickHandler = (event) => {
743
772
  if (!this.trigger.nativeElement.contains(event.target) && !this.popover?.nativeElement.contains(event.target)) {
744
773
  this.close();
@@ -752,7 +781,7 @@ class SelectComponent {
752
781
  open() {
753
782
  this.isOpen = true;
754
783
  this.trigger.nativeElement.focus();
755
- setTimeout(() => {
784
+ requestAnimationFrame(() => {
756
785
  this.updatePosition();
757
786
  document.addEventListener('mousedown', this._outsideClickHandler);
758
787
  });
@@ -811,10 +840,16 @@ class SelectComponent {
811
840
  writeValue(value) {
812
841
  this.value = value;
813
842
  this.updateItemSelection();
814
- if (this.items) {
843
+ if (this.items && this.items.length > 0) {
815
844
  const found = this.items.find(i => i.value === value);
816
- if (found)
845
+ if (found) {
817
846
  this.selectedLabel = found.getLabel();
847
+ this.cdr.markForCheck();
848
+ }
849
+ }
850
+ else {
851
+ // Queue the value for when items become available
852
+ this.pendingValue = value;
818
853
  }
819
854
  }
820
855
  registerOnChange(fn) { this.onChange = fn; }
@@ -822,11 +857,12 @@ class SelectComponent {
822
857
  setDisabledState(isDisabled) { this.disabled = isDisabled; }
823
858
  ngOnDestroy() {
824
859
  this.sub.unsubscribe();
860
+ this.itemsChangeSub?.unsubscribe();
825
861
  if (this.cleanupAutoUpdate)
826
862
  this.cleanupAutoUpdate();
827
863
  document.removeEventListener('mousedown', this._outsideClickHandler);
828
864
  }
829
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectComponent, deps: [{ token: SelectService }], target: i0.ɵɵFactoryTarget.Component });
865
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectComponent, deps: [{ token: SelectService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
830
866
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SelectComponent, isStandalone: true, selector: "tolle-select", inputs: { placeholder: "placeholder", class: "class", disabled: "disabled", searchable: "searchable", size: "size", readonly: "readonly" }, providers: [
831
867
  SelectService,
832
868
  {
@@ -851,7 +887,7 @@ class SelectComponent {
851
887
 
852
888
  <div
853
889
  #popover
854
- *ngIf="isOpen"
890
+ [class.hidden-dropdown]="!isOpen"
855
891
  class="fixed bg-popover z-[999] overflow-auto flex flex-col rounded-md border border-border text-popover-foreground shadow-md"
856
892
  style="visibility: hidden; top: 0; left: 0;">
857
893
  <div *ngIf="searchable" class="p-2 border-b border-border bg-popover h-auto">
@@ -873,23 +909,18 @@ class SelectComponent {
873
909
  </div>
874
910
  </div>
875
911
  </div>
876
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error", "hideHintOnFocus"] }] });
912
+ `, isInline: true, styles: [".hidden-dropdown{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error", "hideHintOnFocus"] }] });
877
913
  }
878
914
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectComponent, decorators: [{
879
915
  type: Component,
880
- args: [{
881
- selector: 'tolle-select',
882
- standalone: true,
883
- imports: [CommonModule, FormsModule, InputComponent],
884
- providers: [
916
+ args: [{ selector: 'tolle-select', standalone: true, imports: [CommonModule, FormsModule, InputComponent], providers: [
885
917
  SelectService,
886
918
  {
887
919
  provide: NG_VALUE_ACCESSOR,
888
920
  useExisting: forwardRef(() => SelectComponent),
889
921
  multi: true
890
922
  }
891
- ],
892
- template: `
923
+ ], template: `
893
924
  <div [class]="cn('relative w-full', 'size-' + size)" #container>
894
925
  <button
895
926
  type="button"
@@ -906,7 +937,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
906
937
 
907
938
  <div
908
939
  #popover
909
- *ngIf="isOpen"
940
+ [class.hidden-dropdown]="!isOpen"
910
941
  class="fixed bg-popover z-[999] overflow-auto flex flex-col rounded-md border border-border text-popover-foreground shadow-md"
911
942
  style="visibility: hidden; top: 0; left: 0;">
912
943
  <div *ngIf="searchable" class="p-2 border-b border-border bg-popover h-auto">
@@ -928,9 +959,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
928
959
  </div>
929
960
  </div>
930
961
  </div>
931
- `,
932
- }]
933
- }], ctorParameters: () => [{ type: SelectService }], propDecorators: { placeholder: [{
962
+ `, styles: [".hidden-dropdown{display:none!important}\n"] }]
963
+ }], ctorParameters: () => [{ type: SelectService }, { type: i0.ChangeDetectorRef }], propDecorators: { placeholder: [{
934
964
  type: Input
935
965
  }], class: [{
936
966
  type: Input
@@ -1323,6 +1353,335 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1323
1353
  type: Input
1324
1354
  }] } });
1325
1355
 
1356
+ class TagInputComponent {
1357
+ cdr;
1358
+ tagInputElement;
1359
+ id = `tag-input-${Math.random().toString(36).substr(2, 9)}`;
1360
+ label = '';
1361
+ hint = '';
1362
+ errorMessage = '';
1363
+ placeholder = 'Type and press Enter...';
1364
+ size = 'default';
1365
+ class = '';
1366
+ // State inputs
1367
+ disabled = false;
1368
+ readonly = false;
1369
+ error = false;
1370
+ // Tag-specific inputs
1371
+ delimiter = ',';
1372
+ maxTags = null;
1373
+ allowDuplicates = false;
1374
+ tagPrefix = '';
1375
+ tagSuffix = '';
1376
+ tags = [];
1377
+ inputValue = '';
1378
+ isFocused = false;
1379
+ onChange = () => { };
1380
+ onTouched = () => { };
1381
+ constructor(cdr) {
1382
+ this.cdr = cdr;
1383
+ }
1384
+ writeValue(values) {
1385
+ this.tags = Array.isArray(values) ? [...values] : [];
1386
+ this.cdr.markForCheck();
1387
+ }
1388
+ registerOnChange(fn) { this.onChange = fn; }
1389
+ registerOnTouched(fn) { this.onTouched = fn; }
1390
+ setDisabledState(isDisabled) {
1391
+ this.disabled = isDisabled;
1392
+ this.cdr.markForCheck();
1393
+ }
1394
+ onKeydown(event) {
1395
+ if (this.disabled || this.readonly)
1396
+ return;
1397
+ const key = event.key;
1398
+ // Enter creates a tag
1399
+ if (key === 'Enter') {
1400
+ event.preventDefault();
1401
+ this.commitInput();
1402
+ return;
1403
+ }
1404
+ // Delimiter creates a tag (strip the delimiter)
1405
+ if (key === this.delimiter) {
1406
+ event.preventDefault();
1407
+ this.commitInput();
1408
+ return;
1409
+ }
1410
+ // Backspace on empty input removes the last tag
1411
+ if (key === 'Backspace' && this.inputValue === '') {
1412
+ if (this.tags.length > 0) {
1413
+ this.removeTag(this.tags.length - 1);
1414
+ }
1415
+ return;
1416
+ }
1417
+ }
1418
+ onBlur() {
1419
+ this.isFocused = false;
1420
+ this.onTouched();
1421
+ this.commitInput();
1422
+ }
1423
+ onFocus() {
1424
+ this.isFocused = true;
1425
+ }
1426
+ removeTag(index, event) {
1427
+ if (this.disabled || this.readonly)
1428
+ return;
1429
+ if (event) {
1430
+ event.stopPropagation();
1431
+ }
1432
+ this.tags.splice(index, 1);
1433
+ this.emitChange();
1434
+ this.focusInput();
1435
+ }
1436
+ focusInput() {
1437
+ if (!this.disabled && this.tagInputElement) {
1438
+ this.tagInputElement.nativeElement.focus();
1439
+ }
1440
+ }
1441
+ commitInput() {
1442
+ const value = this.inputValue.trim();
1443
+ if (value === '') {
1444
+ return;
1445
+ }
1446
+ // Check max tags
1447
+ if (this.maxTags != null && this.tags.length >= this.maxTags) {
1448
+ this.inputValue = '';
1449
+ return;
1450
+ }
1451
+ // Check duplicates (case-insensitive)
1452
+ if (!this.allowDuplicates) {
1453
+ const exists = this.tags.some(t => t.toLowerCase() === value.toLowerCase());
1454
+ if (exists) {
1455
+ this.inputValue = '';
1456
+ return;
1457
+ }
1458
+ }
1459
+ this.tags.push(value);
1460
+ this.inputValue = '';
1461
+ this.emitChange();
1462
+ }
1463
+ emitChange() {
1464
+ this.onChange([...this.tags]);
1465
+ this.cdr.markForCheck();
1466
+ }
1467
+ cn = cn;
1468
+ get computedLabelClass() {
1469
+ return cn("text-sm font-medium text-foreground leading-none transition-opacity duration-200", this.disabled && "opacity-50");
1470
+ }
1471
+ get computedContainerClass() {
1472
+ return cn(
1473
+ // Base styles — flex-wrap so tags flow onto multiple lines
1474
+ "group relative flex flex-wrap items-center w-full rounded-md border transition-all duration-200", "bg-background",
1475
+ // Border and shadow
1476
+ "border-input shadow-sm",
1477
+ // Sizing — min-h instead of fixed h so tags can wrap
1478
+ this.size === 'xs' && "min-h-8 px-2 py-1 gap-1 text-xs", this.size === 'sm' && "min-h-9 px-3 py-1 gap-1.5 text-sm", this.size === 'default' && "min-h-10 px-3 py-1.5 gap-2 text-sm", this.size === 'lg' && "min-h-11 px-4 py-2 gap-3 text-base",
1479
+ // Focus state
1480
+ !(this.readonly || this.disabled) && [
1481
+ "focus-within:border-primary/80",
1482
+ "focus-within:ring-4",
1483
+ "focus-within:ring-ring/30",
1484
+ "focus-within:ring-offset-0",
1485
+ "focus-within:shadow-none",
1486
+ ],
1487
+ // Error state
1488
+ this.error && [
1489
+ "border-destructive",
1490
+ !(this.readonly || this.disabled) && [
1491
+ "focus-within:border-destructive/80",
1492
+ "focus-within:ring-destructive/30"
1493
+ ]
1494
+ ],
1495
+ // Disabled state
1496
+ this.disabled && [
1497
+ "cursor-not-allowed opacity-50",
1498
+ "border-opacity-50"
1499
+ ],
1500
+ // Readonly state
1501
+ this.readonly && [
1502
+ "cursor-default",
1503
+ "border-dashed",
1504
+ !this.disabled && "focus-within:ring-0 focus-within:border-opacity-100"
1505
+ ], this.class);
1506
+ }
1507
+ get computedInputClass() {
1508
+ return cn(
1509
+ // Base styles — inline within the flex-wrap container
1510
+ "flex-1 bg-transparent border-none p-0 min-w-[80px]", "placeholder:text-muted-foreground",
1511
+ // Remove all default focus styles
1512
+ "focus:outline-none focus:ring-0 focus:shadow-none",
1513
+ // Text sizing
1514
+ this.size === 'xs' && "text-xs", this.size === 'sm' && "text-sm", this.size === 'default' && "text-sm", this.size === 'lg' && "text-base",
1515
+ // Cursor states
1516
+ this.disabled && "cursor-not-allowed", this.readonly && "cursor-default",
1517
+ // Text color
1518
+ "text-foreground",
1519
+ // Selection color
1520
+ "selection:bg-primary/20 selection:text-foreground", this.class);
1521
+ }
1522
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TagInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1523
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TagInputComponent, isStandalone: true, selector: "tolle-tag-input", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", placeholder: "placeholder", size: "size", class: "class", disabled: "disabled", readonly: "readonly", error: "error", delimiter: "delimiter", maxTags: "maxTags", allowDuplicates: "allowDuplicates", tagPrefix: "tagPrefix", tagSuffix: "tagSuffix" }, providers: [
1524
+ {
1525
+ provide: NG_VALUE_ACCESSOR,
1526
+ useExisting: forwardRef(() => TagInputComponent),
1527
+ multi: true
1528
+ }
1529
+ ], viewQueries: [{ propertyName: "tagInputElement", first: true, predicate: ["tagInput"], descendants: true }], ngImport: i0, template: `
1530
+ <div class="flex flex-col gap-1.5 w-full">
1531
+ <label
1532
+ *ngIf="label"
1533
+ [for]="id"
1534
+ [class]="computedLabelClass">
1535
+ {{ label }}
1536
+ </label>
1537
+
1538
+ <div
1539
+ [class]="computedContainerClass"
1540
+ (click)="focusInput()"
1541
+ >
1542
+ <tolle-badge
1543
+ *ngFor="let tag of tags; let i = index"
1544
+ size="xs"
1545
+ variant="secondary"
1546
+ [removable]="!disabled && !readonly"
1547
+ (onRemove)="removeTag(i, $event)">
1548
+ {{ tagPrefix }}{{ tag }}{{ tagSuffix }}
1549
+ </tolle-badge>
1550
+
1551
+ <input
1552
+ #tagInput
1553
+ [id]="id"
1554
+ type="text"
1555
+ [placeholder]="tags.length === 0 ? placeholder : ''"
1556
+ [disabled]="disabled"
1557
+ [readOnly]="readonly || (maxTags != null && tags.length >= maxTags)"
1558
+ [(ngModel)]="inputValue"
1559
+ (keydown)="onKeydown($event)"
1560
+ (blur)="onBlur()"
1561
+ (focus)="onFocus()"
1562
+ [class]="computedInputClass"
1563
+ />
1564
+ </div>
1565
+
1566
+ <ng-container *ngIf="!disabled">
1567
+ <p
1568
+ *ngIf="hint && !error"
1569
+ class="text-xs text-muted-foreground px-1 transition-opacity duration-200"
1570
+ >
1571
+ {{ hint }}
1572
+ </p>
1573
+ <p
1574
+ *ngIf="error && errorMessage"
1575
+ class="text-xs text-destructive px-1"
1576
+ >
1577
+ {{ errorMessage }}
1578
+ </p>
1579
+ </ng-container>
1580
+ </div>
1581
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BadgeComponent, selector: "tolle-badge", inputs: ["variant", "size", "removable", "class"], outputs: ["onRemove"] }] });
1582
+ }
1583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TagInputComponent, decorators: [{
1584
+ type: Component,
1585
+ args: [{
1586
+ selector: 'tolle-tag-input',
1587
+ standalone: true,
1588
+ imports: [CommonModule, FormsModule, BadgeComponent],
1589
+ providers: [
1590
+ {
1591
+ provide: NG_VALUE_ACCESSOR,
1592
+ useExisting: forwardRef(() => TagInputComponent),
1593
+ multi: true
1594
+ }
1595
+ ],
1596
+ template: `
1597
+ <div class="flex flex-col gap-1.5 w-full">
1598
+ <label
1599
+ *ngIf="label"
1600
+ [for]="id"
1601
+ [class]="computedLabelClass">
1602
+ {{ label }}
1603
+ </label>
1604
+
1605
+ <div
1606
+ [class]="computedContainerClass"
1607
+ (click)="focusInput()"
1608
+ >
1609
+ <tolle-badge
1610
+ *ngFor="let tag of tags; let i = index"
1611
+ size="xs"
1612
+ variant="secondary"
1613
+ [removable]="!disabled && !readonly"
1614
+ (onRemove)="removeTag(i, $event)">
1615
+ {{ tagPrefix }}{{ tag }}{{ tagSuffix }}
1616
+ </tolle-badge>
1617
+
1618
+ <input
1619
+ #tagInput
1620
+ [id]="id"
1621
+ type="text"
1622
+ [placeholder]="tags.length === 0 ? placeholder : ''"
1623
+ [disabled]="disabled"
1624
+ [readOnly]="readonly || (maxTags != null && tags.length >= maxTags)"
1625
+ [(ngModel)]="inputValue"
1626
+ (keydown)="onKeydown($event)"
1627
+ (blur)="onBlur()"
1628
+ (focus)="onFocus()"
1629
+ [class]="computedInputClass"
1630
+ />
1631
+ </div>
1632
+
1633
+ <ng-container *ngIf="!disabled">
1634
+ <p
1635
+ *ngIf="hint && !error"
1636
+ class="text-xs text-muted-foreground px-1 transition-opacity duration-200"
1637
+ >
1638
+ {{ hint }}
1639
+ </p>
1640
+ <p
1641
+ *ngIf="error && errorMessage"
1642
+ class="text-xs text-destructive px-1"
1643
+ >
1644
+ {{ errorMessage }}
1645
+ </p>
1646
+ </ng-container>
1647
+ </div>
1648
+ `,
1649
+ }]
1650
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { tagInputElement: [{
1651
+ type: ViewChild,
1652
+ args: ['tagInput']
1653
+ }], id: [{
1654
+ type: Input
1655
+ }], label: [{
1656
+ type: Input
1657
+ }], hint: [{
1658
+ type: Input
1659
+ }], errorMessage: [{
1660
+ type: Input
1661
+ }], placeholder: [{
1662
+ type: Input
1663
+ }], size: [{
1664
+ type: Input
1665
+ }], class: [{
1666
+ type: Input
1667
+ }], disabled: [{
1668
+ type: Input
1669
+ }], readonly: [{
1670
+ type: Input
1671
+ }], error: [{
1672
+ type: Input
1673
+ }], delimiter: [{
1674
+ type: Input
1675
+ }], maxTags: [{
1676
+ type: Input
1677
+ }], allowDuplicates: [{
1678
+ type: Input
1679
+ }], tagPrefix: [{
1680
+ type: Input
1681
+ }], tagSuffix: [{
1682
+ type: Input
1683
+ }] } });
1684
+
1326
1685
  class TooltipDirective {
1327
1686
  el;
1328
1687
  content = '';
@@ -1459,9 +1818,9 @@ class ToastContainerComponent {
1459
1818
  getVariantClasses(variant = 'default') {
1460
1819
  switch (variant) {
1461
1820
  case 'destructive':
1462
- return 'border-destructive/50 bg-destructive/5 dark:bg-destructive/10 text-destructive dark:text-red-400';
1821
+ return 'border-destructive/50 bg-destructive/5 dark:bg-red-950 text-destructive dark:text-red-400';
1463
1822
  case 'success':
1464
- return 'border-emerald-500/50 bg-emerald-50 dark:bg-emerald-500/10 text-emerald-700 dark:text-emerald-400';
1823
+ return 'border-emerald-500/50 bg-emerald-50 dark:bg-emerald-950 text-emerald-700 dark:text-emerald-400';
1465
1824
  default:
1466
1825
  return 'bg-background text-foreground border-border';
1467
1826
  }
@@ -2886,7 +3245,7 @@ class MaskedInputComponent {
2886
3245
  size = 'default';
2887
3246
  returnRaw = false;
2888
3247
  hideHintOnFocus = true;
2889
- mergedPosition = 'none';
3248
+ externalFocused;
2890
3249
  inputEl;
2891
3250
  hasPrefix = false;
2892
3251
  hasSuffix = false;
@@ -2918,13 +3277,14 @@ class MaskedInputComponent {
2918
3277
  return cn('text-sm font-medium text-foreground leading-none transition-opacity duration-200', this.disabled && 'opacity-50');
2919
3278
  }
2920
3279
  get computedContainerClass() {
3280
+ const focused = this.externalFocused !== undefined ? this.externalFocused : this.isFocused;
2921
3281
  return cn(
2922
3282
  // Base styles
2923
3283
  'group relative flex items-center w-full border transition-all duration-200', 'bg-background border-input shadow-sm',
2924
3284
  // Sizing
2925
3285
  this.size === 'xs' && 'h-8 px-2 gap-1.5 text-xs', this.size === 'sm' && 'h-9 px-3 gap-2 text-sm', this.size === 'default' && 'h-10 px-3 gap-2 text-sm', this.size === 'lg' && 'h-11 px-4 gap-3 text-base',
2926
- // Merged position - handle border radius
2927
- this.mergedPosition === 'left' && 'rounded-l-md rounded-r-none border-r-0 pr-0', this.mergedPosition === 'right' && 'rounded-r-md rounded-l-none border-l-0 pl-0 flex-1', this.mergedPosition === 'none' && 'rounded-md',
3286
+ // Rounded corners
3287
+ 'rounded-md',
2928
3288
  // Focus state
2929
3289
  !(this.readonly || this.disabled) && [
2930
3290
  'focus-within:ring-4',
@@ -3026,7 +3386,7 @@ class MaskedInputComponent {
3026
3386
  }
3027
3387
  cn = cn;
3028
3388
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MaskedInputComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3029
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MaskedInputComponent, isStandalone: true, selector: "tolle-masked-input", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", mask: "mask", placeholder: "placeholder", type: "type", disabled: "disabled", readonly: "readonly", class: "class", containerClass: "containerClass", error: "error", size: "size", returnRaw: "returnRaw", hideHintOnFocus: "hideHintOnFocus", mergedPosition: "mergedPosition" }, providers: [
3389
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MaskedInputComponent, isStandalone: true, selector: "tolle-masked-input", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", mask: "mask", placeholder: "placeholder", type: "type", disabled: "disabled", readonly: "readonly", class: "class", containerClass: "containerClass", error: "error", size: "size", returnRaw: "returnRaw", hideHintOnFocus: "hideHintOnFocus", externalFocused: "externalFocused" }, providers: [
3030
3390
  {
3031
3391
  provide: NG_VALUE_ACCESSOR,
3032
3392
  useExisting: forwardRef(() => MaskedInputComponent),
@@ -3034,7 +3394,7 @@ class MaskedInputComponent {
3034
3394
  },
3035
3395
  ], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, static: true }], ngImport: i0, template: `
3036
3396
  <div class="flex w-full flex-col gap-1.5">
3037
- <label *ngIf="label && mergedPosition === 'none'" [for]="id" [class]="computedLabelClass">
3397
+ <label *ngIf="label" [for]="id" [class]="computedLabelClass">
3038
3398
  {{ label }}
3039
3399
  </label>
3040
3400
 
@@ -3067,7 +3427,7 @@ class MaskedInputComponent {
3067
3427
  </div>
3068
3428
  </div>
3069
3429
 
3070
- <ng-container *ngIf="!disabled && mergedPosition === 'none'">
3430
+ <ng-container *ngIf="!disabled">
3071
3431
  <p
3072
3432
  *ngIf="hint && !error"
3073
3433
  class="px-1 text-xs text-muted-foreground transition-opacity duration-200"
@@ -3096,7 +3456,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3096
3456
  ],
3097
3457
  template: `
3098
3458
  <div class="flex w-full flex-col gap-1.5">
3099
- <label *ngIf="label && mergedPosition === 'none'" [for]="id" [class]="computedLabelClass">
3459
+ <label *ngIf="label" [for]="id" [class]="computedLabelClass">
3100
3460
  {{ label }}
3101
3461
  </label>
3102
3462
 
@@ -3129,7 +3489,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3129
3489
  </div>
3130
3490
  </div>
3131
3491
 
3132
- <ng-container *ngIf="!disabled && mergedPosition === 'none'">
3492
+ <ng-container *ngIf="!disabled">
3133
3493
  <p
3134
3494
  *ngIf="hint && !error"
3135
3495
  class="px-1 text-xs text-muted-foreground transition-opacity duration-200"
@@ -3173,7 +3533,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3173
3533
  type: Input
3174
3534
  }], hideHintOnFocus: [{
3175
3535
  type: Input
3176
- }], mergedPosition: [{
3536
+ }], externalFocused: [{
3177
3537
  type: Input
3178
3538
  }], inputEl: [{
3179
3539
  type: ViewChild,
@@ -3405,7 +3765,7 @@ class DatePickerComponent {
3405
3765
  ></tolle-calendar>
3406
3766
  </div>
3407
3767
  </div>
3408
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MaskedInputComponent, selector: "tolle-masked-input", inputs: ["id", "label", "hint", "errorMessage", "mask", "placeholder", "type", "disabled", "readonly", "class", "containerClass", "error", "size", "returnRaw", "hideHintOnFocus", "mergedPosition"] }, { kind: "component", type: CalendarComponent, selector: "tolle-calendar", inputs: ["class", "mode", "disablePastDates", "showQuickActions", "minDate", "maxDate", "formatMonthFn", "formatYearFn", "formatDateFn"], outputs: ["dateSelect"] }] });
3768
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MaskedInputComponent, selector: "tolle-masked-input", inputs: ["id", "label", "hint", "errorMessage", "mask", "placeholder", "type", "disabled", "readonly", "class", "containerClass", "error", "size", "returnRaw", "hideHintOnFocus", "externalFocused"] }, { kind: "component", type: CalendarComponent, selector: "tolle-calendar", inputs: ["class", "mode", "disablePastDates", "showQuickActions", "minDate", "maxDate", "formatMonthFn", "formatYearFn", "formatDateFn"], outputs: ["dateSelect"] }] });
3409
3769
  }
3410
3770
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatePickerComponent, decorators: [{
3411
3771
  type: Component,
@@ -4651,7 +5011,7 @@ class ModalComponent {
4651
5011
  // Base classes: Added 'w-full' and 'mx-auto'
4652
5012
  'bg-background border border-border shadow-lg relative flex flex-col w-full mx-auto ', size === 'fullscreen' ? 'h-screen w-screen rounded-none' : 'rounded-md',
4653
5013
  // Sizing scale with explicit max-widths
4654
- size === 'xs' && 'max-w-[320px]', size === 'sm' && 'max-w-[425px]', size === 'default' && 'max-w-[544px]', size === 'lg' && 'max-w-[1024px]');
5014
+ size === 'xs' && 'max-w-[320px]', size === 'sm' && 'max-w-[425px]', size === 'default' && 'max-w-[544px]', size === 'lg' && 'max-w-[1024px]', size === 'xl' && 'max-w-[1280px]');
4655
5015
  }
4656
5016
  determineContentType() {
4657
5017
  if (typeof this.content === 'string')
@@ -4815,6 +5175,7 @@ class Modal {
4815
5175
  * - sm: 425px (Standard dialogs)
4816
5176
  * - default: 544px (Forms)
4817
5177
  * - lg: 90% / 1024px (Data tables)
5178
+ * - xl: 1280px (Large forms, dashboards)
4818
5179
  * - fullscreen: 100vw/100vh (Complex workflows)
4819
5180
  */
4820
5181
  size = 'default';
@@ -12905,7 +13266,7 @@ class CountrySelectorComponent {
12905
13266
  defaultCountryCode = 'GH';
12906
13267
  returnValue = 'isoAlpha2';
12907
13268
  showName = true;
12908
- mergedPosition = 'none';
13269
+ externalFocused;
12909
13270
  onSelect = new EventEmitter();
12910
13271
  onFocusChange = new EventEmitter();
12911
13272
  onBlurChange = new EventEmitter();
@@ -12932,12 +13293,22 @@ class CountrySelectorComponent {
12932
13293
  }
12933
13294
  }
12934
13295
  get computedTriggerClass() {
13296
+ const focused = this.externalFocused !== undefined ? this.externalFocused : this.isFocused;
12935
13297
  return cn('flex w-full items-center justify-between border transition-all duration-200', 'bg-background text-foreground', 'border-input shadow-sm', this.size === 'xs' && 'h-8 px-2 text-xs', this.size === 'sm' && 'h-9 px-3 text-sm', this.size === 'default' && 'h-10 px-3 text-sm', this.size === 'lg' && 'h-11 px-4 text-base',
12936
- // Merged position
12937
- this.mergedPosition === 'left' && 'rounded-l-md rounded-r-none border-r-0', this.mergedPosition === 'none' && 'rounded-md',
13298
+ // Rounded corners
13299
+ 'rounded-md',
12938
13300
  // Focus state
13301
+ !(this.readonly || this.disabled) && [
13302
+ 'focus:outline-none',
13303
+ 'focus:ring-4',
13304
+ 'focus:ring-ring/30',
13305
+ 'focus:ring-offset-0',
13306
+ 'shadow-none',
13307
+ this.error ? 'focus:border-destructive/80' : 'focus:border-primary/80',
13308
+ ],
13309
+ // External focus state (when controlled by parent)
12939
13310
  !(this.readonly || this.disabled) &&
12940
- this.isFocused && [
13311
+ focused && [
12941
13312
  'ring-4',
12942
13313
  'ring-ring/30',
12943
13314
  'ring-offset-0',
@@ -12945,7 +13316,10 @@ class CountrySelectorComponent {
12945
13316
  this.error ? 'border-destructive/80' : 'border-primary/80',
12946
13317
  ], !(this.readonly || this.disabled) && 'hover:border-accent',
12947
13318
  // Error state
12948
- this.error && ['border-destructive', this.isFocused && 'ring-destructive/30'], this.disabled && 'cursor-not-allowed opacity-50 border-opacity-50', this.readonly && 'cursor-default border-dashed', this.class);
13319
+ this.error && [
13320
+ 'border-destructive',
13321
+ !(this.readonly || this.disabled) && focused && 'ring-destructive/30',
13322
+ ], this.disabled && 'cursor-not-allowed opacity-50 border-opacity-50', this.readonly && 'cursor-default border-dashed', this.class);
12949
13323
  }
12950
13324
  get computedLabelClass() {
12951
13325
  return cn('text-sm font-medium text-foreground leading-none transition-opacity duration-200', this.disabled && 'opacity-50');
@@ -13036,7 +13410,7 @@ class CountrySelectorComponent {
13036
13410
  this.disabled = isDisabled;
13037
13411
  }
13038
13412
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CountrySelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13039
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CountrySelectorComponent, isStandalone: true, selector: "tolle-country-selector", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", error: "error", hideHintOnFocus: "hideHintOnFocus", placeholder: "placeholder", class: "class", disabled: "disabled", readonly: "readonly", size: "size", defaultCountryCode: "defaultCountryCode", returnValue: "returnValue", showName: "showName", mergedPosition: "mergedPosition" }, outputs: { onSelect: "onSelect", onFocusChange: "onFocusChange", onBlurChange: "onBlurChange" }, providers: [
13413
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CountrySelectorComponent, isStandalone: true, selector: "tolle-country-selector", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", error: "error", hideHintOnFocus: "hideHintOnFocus", placeholder: "placeholder", class: "class", disabled: "disabled", readonly: "readonly", size: "size", defaultCountryCode: "defaultCountryCode", returnValue: "returnValue", showName: "showName", externalFocused: "externalFocused" }, outputs: { onSelect: "onSelect", onFocusChange: "onFocusChange", onBlurChange: "onBlurChange" }, providers: [
13040
13414
  {
13041
13415
  provide: NG_VALUE_ACCESSOR,
13042
13416
  useExisting: forwardRef(() => CountrySelectorComponent),
@@ -13044,7 +13418,7 @@ class CountrySelectorComponent {
13044
13418
  },
13045
13419
  ], viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: `
13046
13420
  <div class="flex w-full flex-col gap-1.5">
13047
- <label *ngIf="label && mergedPosition === 'none'" [for]="id" [class]="computedLabelClass">
13421
+ <label *ngIf="label" [for]="id" [class]="computedLabelClass">
13048
13422
  {{ label }}
13049
13423
  </label>
13050
13424
 
@@ -13121,7 +13495,7 @@ class CountrySelectorComponent {
13121
13495
  </div>
13122
13496
  </tolle-popover>
13123
13497
 
13124
- <ng-container *ngIf="!disabled && mergedPosition === 'none'">
13498
+ <ng-container *ngIf="!disabled">
13125
13499
  <p
13126
13500
  *ngIf="hint && !error"
13127
13501
  class="px-1 text-xs text-muted-foreground transition-opacity duration-200"
@@ -13153,7 +13527,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13153
13527
  ],
13154
13528
  template: `
13155
13529
  <div class="flex w-full flex-col gap-1.5">
13156
- <label *ngIf="label && mergedPosition === 'none'" [for]="id" [class]="computedLabelClass">
13530
+ <label *ngIf="label" [for]="id" [class]="computedLabelClass">
13157
13531
  {{ label }}
13158
13532
  </label>
13159
13533
 
@@ -13230,7 +13604,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13230
13604
  </div>
13231
13605
  </tolle-popover>
13232
13606
 
13233
- <ng-container *ngIf="!disabled && mergedPosition === 'none'">
13607
+ <ng-container *ngIf="!disabled">
13234
13608
  <p
13235
13609
  *ngIf="hint && !error"
13236
13610
  class="px-1 text-xs text-muted-foreground transition-opacity duration-200"
@@ -13275,7 +13649,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13275
13649
  type: Input
13276
13650
  }], showName: [{
13277
13651
  type: Input
13278
- }], mergedPosition: [{
13652
+ }], externalFocused: [{
13279
13653
  type: Input
13280
13654
  }], onSelect: [{
13281
13655
  type: Output
@@ -13312,6 +13686,7 @@ class PhoneNumberInputComponent {
13312
13686
  displayValue = '';
13313
13687
  selectedIso = '';
13314
13688
  rawValue = '';
13689
+ isFocused = false;
13315
13690
  cn = cn;
13316
13691
  onChange = () => { };
13317
13692
  onTouched = () => { };
@@ -13321,23 +13696,14 @@ class PhoneNumberInputComponent {
13321
13696
  get computedLabelClass() {
13322
13697
  return cn('text-sm font-medium text-foreground leading-none transition-opacity duration-200', this.disabled && 'opacity-50');
13323
13698
  }
13324
- get computedMergedClass() {
13325
- return cn('group relative flex items-center w-full rounded-md border transition-all duration-200', 'bg-background border-input shadow-sm', this.size === 'xs' && 'h-8', this.size === 'sm' && 'h-9', this.size === 'default' && 'h-10', this.size === 'lg' && 'h-11',
13326
- // Focus state
13327
- !this.readonly &&
13328
- !this.disabled && [
13329
- 'focus-within:ring-4',
13330
- 'focus-within:ring-ring/30',
13331
- 'focus-within:ring-offset-0',
13332
- 'focus-within:shadow-none',
13333
- this.error ? 'focus-within:border-destructive/80' : 'focus-within:border-primary/80',
13334
- ],
13335
- // Error state
13336
- this.error && 'border-destructive', this.error && !this.readonly && !this.disabled && 'focus-within:ring-destructive/30',
13337
- // Disabled state
13338
- this.disabled && ['cursor-not-allowed opacity-50', 'border-opacity-50'],
13339
- // Readonly state
13340
- this.readonly && 'cursor-default border-dashed', this.class);
13699
+ onFocusIn() {
13700
+ this.isFocused = true;
13701
+ this.cdr.markForCheck();
13702
+ }
13703
+ onFocusOut() {
13704
+ this.isFocused = false;
13705
+ this.onTouched();
13706
+ this.cdr.markForCheck();
13341
13707
  }
13342
13708
  writeValue(value) {
13343
13709
  if (value) {
@@ -13420,16 +13786,18 @@ class PhoneNumberInputComponent {
13420
13786
  {{ label }}
13421
13787
  </label>
13422
13788
 
13423
- <div [class]="computedMergedClass">
13789
+ <div class="flex gap-2" (focusin)="onFocusIn()" (focusout)="onFocusOut()">
13424
13790
  <tolle-country-selector
13425
13791
  class="flex-shrink-0"
13426
13792
  [showName]="false"
13427
13793
  [size]="size"
13428
13794
  [disabled]="disabled || !enableCountrySelector"
13429
13795
  [readonly]="readonly"
13430
- [mergedPosition]="'left'"
13796
+ [externalFocused]="isFocused"
13431
13797
  [(ngModel)]="selectedIso"
13432
- (ngModelChange)="onCountryChange($event)"></tolle-country-selector>
13798
+ (ngModelChange)="onCountryChange($event)"
13799
+ (onFocusChange)="onFocusIn()"
13800
+ (onBlurChange)="onFocusOut()"></tolle-country-selector>
13433
13801
 
13434
13802
  <tolle-masked-input
13435
13803
  class="min-w-0 flex-1"
@@ -13440,7 +13808,7 @@ class PhoneNumberInputComponent {
13440
13808
  [readonly]="readonly"
13441
13809
  [placeholder]="placeholder"
13442
13810
  [error]="error"
13443
- [mergedPosition]="'right'"
13811
+ [externalFocused]="isFocused"
13444
13812
  [(ngModel)]="displayValue"
13445
13813
  (ngModelChange)="onMaskInputChange($event)"></tolle-masked-input>
13446
13814
  </div>
@@ -13448,7 +13816,8 @@ class PhoneNumberInputComponent {
13448
13816
  <ng-container *ngIf="!disabled">
13449
13817
  <p
13450
13818
  *ngIf="hint && !error"
13451
- class="px-1 text-xs text-muted-foreground transition-opacity duration-200">
13819
+ class="px-1 text-xs text-muted-foreground transition-opacity duration-200"
13820
+ [class.opacity-0]="isFocused && hideHintOnFocus">
13452
13821
  {{ hint }}
13453
13822
  </p>
13454
13823
  <p *ngIf="error && errorMessage" [id]="id + '-error'" class="px-1 text-xs text-destructive">
@@ -13456,7 +13825,7 @@ class PhoneNumberInputComponent {
13456
13825
  </p>
13457
13826
  </ng-container>
13458
13827
  </div>
13459
- `, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CountrySelectorComponent, selector: "tolle-country-selector", inputs: ["id", "label", "hint", "errorMessage", "error", "hideHintOnFocus", "placeholder", "class", "disabled", "readonly", "size", "defaultCountryCode", "returnValue", "showName", "mergedPosition"], outputs: ["onSelect", "onFocusChange", "onBlurChange"] }, { kind: "component", type: MaskedInputComponent, selector: "tolle-masked-input", inputs: ["id", "label", "hint", "errorMessage", "mask", "placeholder", "type", "disabled", "readonly", "class", "containerClass", "error", "size", "returnRaw", "hideHintOnFocus", "mergedPosition"] }] });
13828
+ `, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CountrySelectorComponent, selector: "tolle-country-selector", inputs: ["id", "label", "hint", "errorMessage", "error", "hideHintOnFocus", "placeholder", "class", "disabled", "readonly", "size", "defaultCountryCode", "returnValue", "showName", "externalFocused"], outputs: ["onSelect", "onFocusChange", "onBlurChange"] }, { kind: "component", type: MaskedInputComponent, selector: "tolle-masked-input", inputs: ["id", "label", "hint", "errorMessage", "mask", "placeholder", "type", "disabled", "readonly", "class", "containerClass", "error", "size", "returnRaw", "hideHintOnFocus", "externalFocused"] }] });
13460
13829
  }
13461
13830
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PhoneNumberInputComponent, decorators: [{
13462
13831
  type: Component,
@@ -13466,16 +13835,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13466
13835
  {{ label }}
13467
13836
  </label>
13468
13837
 
13469
- <div [class]="computedMergedClass">
13838
+ <div class="flex gap-2" (focusin)="onFocusIn()" (focusout)="onFocusOut()">
13470
13839
  <tolle-country-selector
13471
13840
  class="flex-shrink-0"
13472
13841
  [showName]="false"
13473
13842
  [size]="size"
13474
13843
  [disabled]="disabled || !enableCountrySelector"
13475
13844
  [readonly]="readonly"
13476
- [mergedPosition]="'left'"
13845
+ [externalFocused]="isFocused"
13477
13846
  [(ngModel)]="selectedIso"
13478
- (ngModelChange)="onCountryChange($event)"></tolle-country-selector>
13847
+ (ngModelChange)="onCountryChange($event)"
13848
+ (onFocusChange)="onFocusIn()"
13849
+ (onBlurChange)="onFocusOut()"></tolle-country-selector>
13479
13850
 
13480
13851
  <tolle-masked-input
13481
13852
  class="min-w-0 flex-1"
@@ -13486,7 +13857,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13486
13857
  [readonly]="readonly"
13487
13858
  [placeholder]="placeholder"
13488
13859
  [error]="error"
13489
- [mergedPosition]="'right'"
13860
+ [externalFocused]="isFocused"
13490
13861
  [(ngModel)]="displayValue"
13491
13862
  (ngModelChange)="onMaskInputChange($event)"></tolle-masked-input>
13492
13863
  </div>
@@ -13494,7 +13865,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13494
13865
  <ng-container *ngIf="!disabled">
13495
13866
  <p
13496
13867
  *ngIf="hint && !error"
13497
- class="px-1 text-xs text-muted-foreground transition-opacity duration-200">
13868
+ class="px-1 text-xs text-muted-foreground transition-opacity duration-200"
13869
+ [class.opacity-0]="isFocused && hideHintOnFocus">
13498
13870
  {{ hint }}
13499
13871
  </p>
13500
13872
  <p *ngIf="error && errorMessage" [id]="id + '-error'" class="px-1 text-xs text-destructive">
@@ -13629,5 +14001,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13629
14001
  * Generated bundle index. Do not edit.
13630
14002
  */
13631
14003
 
13632
- export { AccordionComponent, AccordionItemComponent, AlertComponent, AlertDialogActionComponent, AlertDialogCancelComponent, AlertDialogComponent, AlertDialogContentComponent, AlertDialogDescriptionComponent, AlertDialogDynamicComponent, AlertDialogFooterComponent, AlertDialogHeaderComponent, AlertDialogPortalComponent, AlertDialogRef, AlertDialogService, AlertDialogTitleComponent, AlertDialogTriggerComponent, AvatarComponent, AvatarFallbackComponent, BadgeComponent, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbLinkComponent, BreadcrumbSeparatorComponent, ButtonComponent, ButtonGroupComponent, CalendarComponent, CardComponent, CardContentComponent, CardFooterComponent, CardHeaderComponent, CardTitleComponent, CarouselComponent, CarouselContainerDirective, CarouselContentDirective, CarouselContext, CarouselItemDirective, CarouselNextDirective, CarouselPreviousDirective, CheckboxComponent, CollapsibleComponent, CollapsibleContentComponent, CollapsibleTriggerComponent, CountryCodesService, CountrySelectorComponent, DataTableComponent, DatePickerComponent, DateRangePickerComponent, DropdownItemComponent, DropdownLabelComponent, DropdownMenuComponent, DropdownSeparatorComponent, DropdownTriggerDirective, EmptyStateComponent, HoverCardComponent, HoverCardContentComponent, HoverCardTriggerComponent, InputComponent, LabelComponent, MaskedInputComponent, Modal, ModalComponent, ModalRef, ModalService, ModalStackService, MultiSelectComponent, OtpComponent, OtpGroupComponent, OtpSlotComponent, PaginationComponent, PhoneNumberInputComponent, PhoneNumberService, PopoverComponent, PopoverContentComponent, ProgressComponent, RadioGroupComponent, RadioItemComponent, RangeCalendarComponent, ScrollAreaComponent, SegmentedComponent, SelectComponent, SelectGroupComponent, SelectItemComponent, SelectSeparatorComponent, SeparatorComponent, SheetComponent, SheetContentComponent, SheetDescriptionComponent, SheetFooterComponent, SheetHeaderComponent, SheetRef, SheetService, SheetTitleComponent, SheetTriggerComponent, SheetWrapperComponent, SidebarComponent, SkeletonComponent, SliderComponent, SwitchComponent, TOLLE_CONFIG, TabsComponent, TabsContentComponent, TabsListComponent, TabsTriggerComponent, TextareaComponent, ThemeService, ToastContainerComponent, ToastService, ToggleComponent, ToggleGroupComponent, ToggleGroupItemComponent, TolleCellDirective, TooltipDirective, cn, provideTolleConfig };
14004
+ export { AccordionComponent, AccordionItemComponent, AlertComponent, AlertDialogActionComponent, AlertDialogCancelComponent, AlertDialogComponent, AlertDialogContentComponent, AlertDialogDescriptionComponent, AlertDialogDynamicComponent, AlertDialogFooterComponent, AlertDialogHeaderComponent, AlertDialogPortalComponent, AlertDialogRef, AlertDialogService, AlertDialogTitleComponent, AlertDialogTriggerComponent, AvatarComponent, AvatarFallbackComponent, BadgeComponent, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbLinkComponent, BreadcrumbSeparatorComponent, ButtonComponent, ButtonGroupComponent, CalendarComponent, CardComponent, CardContentComponent, CardFooterComponent, CardHeaderComponent, CardTitleComponent, CarouselComponent, CarouselContainerDirective, CarouselContentDirective, CarouselContext, CarouselItemDirective, CarouselNextDirective, CarouselPreviousDirective, CheckboxComponent, CollapsibleComponent, CollapsibleContentComponent, CollapsibleTriggerComponent, CountryCodesService, CountrySelectorComponent, DataTableComponent, DatePickerComponent, DateRangePickerComponent, DropdownItemComponent, DropdownLabelComponent, DropdownMenuComponent, DropdownSeparatorComponent, DropdownTriggerDirective, EmptyStateComponent, HoverCardComponent, HoverCardContentComponent, HoverCardTriggerComponent, InputComponent, LabelComponent, MaskedInputComponent, Modal, ModalComponent, ModalRef, ModalService, ModalStackService, MultiSelectComponent, OtpComponent, OtpGroupComponent, OtpSlotComponent, PaginationComponent, PhoneNumberInputComponent, PhoneNumberService, PopoverComponent, PopoverContentComponent, ProgressComponent, RadioGroupComponent, RadioItemComponent, RangeCalendarComponent, ScrollAreaComponent, SegmentedComponent, SelectComponent, SelectGroupComponent, SelectItemComponent, SelectSeparatorComponent, SeparatorComponent, SheetComponent, SheetContentComponent, SheetDescriptionComponent, SheetFooterComponent, SheetHeaderComponent, SheetRef, SheetService, SheetTitleComponent, SheetTriggerComponent, SheetWrapperComponent, SidebarComponent, SkeletonComponent, SliderComponent, SwitchComponent, TOLLE_CONFIG, TabsComponent, TabsContentComponent, TabsListComponent, TabsTriggerComponent, TagInputComponent, TextareaComponent, ThemeService, ToastContainerComponent, ToastService, ToggleComponent, ToggleGroupComponent, ToggleGroupItemComponent, TolleCellDirective, TooltipDirective, cn, provideTolleConfig };
13633
14005
  //# sourceMappingURL=tolle-ui.mjs.map