@neural-ui/core 1.7.1 → 1.7.3

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.
Files changed (129) hide show
  1. package/bottom-sheet/package.json +4 -0
  2. package/confirm-popup/package.json +4 -0
  3. package/data-view/package.json +4 -0
  4. package/fesm2022/neural-ui-core-alert.mjs +48 -21
  5. package/fesm2022/neural-ui-core-alert.mjs.map +1 -1
  6. package/fesm2022/neural-ui-core-autocomplete.mjs +153 -71
  7. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
  8. package/fesm2022/neural-ui-core-block-ui.mjs +2 -2
  9. package/fesm2022/neural-ui-core-block-ui.mjs.map +1 -1
  10. package/fesm2022/neural-ui-core-bottom-sheet.mjs +121 -0
  11. package/fesm2022/neural-ui-core-bottom-sheet.mjs.map +1 -0
  12. package/fesm2022/neural-ui-core-breadcrumb.mjs +2 -2
  13. package/fesm2022/neural-ui-core-breadcrumb.mjs.map +1 -1
  14. package/fesm2022/neural-ui-core-button.mjs +2 -2
  15. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  16. package/fesm2022/neural-ui-core-calendar.mjs +2 -2
  17. package/fesm2022/neural-ui-core-calendar.mjs.map +1 -1
  18. package/fesm2022/neural-ui-core-checkbox.mjs +69 -39
  19. package/fesm2022/neural-ui-core-checkbox.mjs.map +1 -1
  20. package/fesm2022/neural-ui-core-chip.mjs +2 -2
  21. package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
  22. package/fesm2022/neural-ui-core-code-block.mjs +2 -2
  23. package/fesm2022/neural-ui-core-code-block.mjs.map +1 -1
  24. package/fesm2022/neural-ui-core-confirm-popup.mjs +105 -0
  25. package/fesm2022/neural-ui-core-confirm-popup.mjs.map +1 -0
  26. package/fesm2022/neural-ui-core-dashboard-grid.mjs +9 -3
  27. package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
  28. package/fesm2022/neural-ui-core-data-view.mjs +386 -0
  29. package/fesm2022/neural-ui-core-data-view.mjs.map +1 -0
  30. package/fesm2022/neural-ui-core-date-input.mjs +185 -10
  31. package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
  32. package/fesm2022/neural-ui-core-empty-state.mjs +19 -5
  33. package/fesm2022/neural-ui-core-empty-state.mjs.map +1 -1
  34. package/fesm2022/neural-ui-core-form-field.mjs +81 -0
  35. package/fesm2022/neural-ui-core-form-field.mjs.map +1 -0
  36. package/fesm2022/neural-ui-core-inline-editor.mjs +428 -0
  37. package/fesm2022/neural-ui-core-inline-editor.mjs.map +1 -0
  38. package/fesm2022/neural-ui-core-input-mask.mjs +110 -0
  39. package/fesm2022/neural-ui-core-input-mask.mjs.map +1 -0
  40. package/fesm2022/neural-ui-core-input.mjs +2 -2
  41. package/fesm2022/neural-ui-core-input.mjs.map +1 -1
  42. package/fesm2022/neural-ui-core-listbox.mjs +219 -0
  43. package/fesm2022/neural-ui-core-listbox.mjs.map +1 -0
  44. package/fesm2022/neural-ui-core-menu.mjs +229 -0
  45. package/fesm2022/neural-ui-core-menu.mjs.map +1 -0
  46. package/fesm2022/neural-ui-core-modal.mjs +34 -10
  47. package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
  48. package/fesm2022/neural-ui-core-multiselect.mjs +170 -179
  49. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  50. package/fesm2022/neural-ui-core-number-input.mjs +2 -2
  51. package/fesm2022/neural-ui-core-number-input.mjs.map +1 -1
  52. package/fesm2022/neural-ui-core-panel.mjs +92 -0
  53. package/fesm2022/neural-ui-core-panel.mjs.map +1 -0
  54. package/fesm2022/neural-ui-core-password.mjs +106 -0
  55. package/fesm2022/neural-ui-core-password.mjs.map +1 -0
  56. package/fesm2022/neural-ui-core-pick-list.mjs +133 -0
  57. package/fesm2022/neural-ui-core-pick-list.mjs.map +1 -0
  58. package/fesm2022/neural-ui-core-select.mjs +128 -166
  59. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  60. package/fesm2022/neural-ui-core-sidebar.mjs +14 -3
  61. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  62. package/fesm2022/neural-ui-core-slider.mjs +2 -2
  63. package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
  64. package/fesm2022/neural-ui-core-spinner.mjs +19 -9
  65. package/fesm2022/neural-ui-core-spinner.mjs.map +1 -1
  66. package/fesm2022/neural-ui-core-split-button.mjs +2 -2
  67. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  68. package/fesm2022/neural-ui-core-table.mjs +503 -62
  69. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  70. package/fesm2022/neural-ui-core-tabs.mjs +11 -4
  71. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
  72. package/fesm2022/neural-ui-core-tags.mjs +134 -0
  73. package/fesm2022/neural-ui-core-tags.mjs.map +1 -0
  74. package/fesm2022/neural-ui-core-textarea.mjs +2 -2
  75. package/fesm2022/neural-ui-core-textarea.mjs.map +1 -1
  76. package/fesm2022/neural-ui-core-toggle-button-group.mjs +2 -2
  77. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
  78. package/fesm2022/neural-ui-core-toolbar.mjs +16 -4
  79. package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -1
  80. package/fesm2022/neural-ui-core-tree-select.mjs +259 -0
  81. package/fesm2022/neural-ui-core-tree-select.mjs.map +1 -0
  82. package/fesm2022/neural-ui-core-tree-table.mjs +267 -8
  83. package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -1
  84. package/fesm2022/neural-ui-core-tree.mjs +15 -14
  85. package/fesm2022/neural-ui-core-tree.mjs.map +1 -1
  86. package/fesm2022/neural-ui-core-uploader.mjs +103 -12
  87. package/fesm2022/neural-ui-core-uploader.mjs.map +1 -1
  88. package/form-field/package.json +4 -0
  89. package/inline-editor/package.json +4 -0
  90. package/input-mask/package.json +4 -0
  91. package/listbox/package.json +4 -0
  92. package/menu/package.json +4 -0
  93. package/package.json +53 -1
  94. package/panel/package.json +4 -0
  95. package/password/package.json +4 -0
  96. package/pick-list/package.json +4 -0
  97. package/styles/_tokens.scss +33 -17
  98. package/tags/package.json +4 -0
  99. package/tree-select/package.json +4 -0
  100. package/types/neural-ui-core-alert.d.ts +2 -1
  101. package/types/neural-ui-core-autocomplete.d.ts +22 -2
  102. package/types/neural-ui-core-bottom-sheet.d.ts +20 -0
  103. package/types/neural-ui-core-checkbox.d.ts +6 -1
  104. package/types/neural-ui-core-confirm-popup.d.ts +38 -0
  105. package/types/neural-ui-core-dashboard-grid.d.ts +1 -0
  106. package/types/neural-ui-core-data-view.d.ts +95 -0
  107. package/types/neural-ui-core-date-input.d.ts +35 -5
  108. package/types/neural-ui-core-empty-state.d.ts +11 -1
  109. package/types/neural-ui-core-form-field.d.ts +33 -0
  110. package/types/neural-ui-core-inline-editor.d.ts +66 -0
  111. package/types/neural-ui-core-input-mask.d.ts +26 -0
  112. package/types/neural-ui-core-listbox.d.ts +54 -0
  113. package/types/neural-ui-core-menu.d.ts +49 -0
  114. package/types/neural-ui-core-modal.d.ts +10 -2
  115. package/types/neural-ui-core-multiselect.d.ts +10 -1
  116. package/types/neural-ui-core-panel.d.ts +25 -0
  117. package/types/neural-ui-core-password.d.ts +29 -0
  118. package/types/neural-ui-core-pick-list.d.ts +40 -0
  119. package/types/neural-ui-core-select.d.ts +7 -1
  120. package/types/neural-ui-core-sidebar.d.ts +5 -1
  121. package/types/neural-ui-core-spinner.d.ts +4 -2
  122. package/types/neural-ui-core-table.d.ts +89 -5
  123. package/types/neural-ui-core-tabs.d.ts +2 -0
  124. package/types/neural-ui-core-tags.d.ts +32 -0
  125. package/types/neural-ui-core-toolbar.d.ts +8 -2
  126. package/types/neural-ui-core-tree-select.d.ts +57 -0
  127. package/types/neural-ui-core-tree-table.d.ts +111 -4
  128. package/types/neural-ui-core-tree.d.ts +1 -1
  129. package/types/neural-ui-core-uploader.d.ts +26 -3
@@ -201,7 +201,7 @@ class NeuInputComponent {
201
201
  } @else if (hint()) {
202
202
  <p class="neu-input__hint" [id]="inputId() + '-hint'">{{ hint() }}</p>
203
203
  }
204
- `, isInline: true, styles: [".neu-input-host{display:block}.neu-input-host--sm .neu-input__wrapper{height:36px}.neu-input-host--sm .neu-input__field{font-size:var(--neu-text-sm)}.neu-input-host--lg .neu-input__wrapper{height:56px}.neu-input__wrapper{position:relative;display:flex;align-items:center;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);height:48px;transition:border-color var(--neu-transition),box-shadow var(--neu-transition),background-color var(--neu-transition)}.neu-input__wrapper:hover:not(.neu-input__wrapper--disabled){border-color:var(--neu-border-hover)}.neu-input__wrapper--focused{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-input__wrapper--error{border-color:var(--neu-error)}.neu-input__wrapper--error.neu-input__wrapper--focused{box-shadow:0 0 0 3px #ef44441f}.neu-input__wrapper--disabled{background:var(--neu-surface-2);opacity:.6;cursor:not-allowed}.neu-input__wrapper--has-start-icon .neu-input__field{padding-left:40px}.neu-input__wrapper--has-end-icon .neu-input__field{padding-right:40px}.neu-input__field{width:100%;height:100%;padding:0 var(--neu-space-3);border:none;background:transparent;outline:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-base);color:var(--neu-text);caret-color:var(--neu-primary)}.neu-input__field:disabled{cursor:not-allowed;color:var(--neu-text-disabled)}.neu-input__field::placeholder{color:transparent;transition:color var(--neu-transition)}.neu-input__wrapper--focused .neu-input__field::placeholder{color:var(--neu-text-disabled)}.neu-input__label{position:absolute;left:var(--neu-space-3);top:50%;transform:translateY(-50%);font-size:var(--neu-text-base);color:var(--neu-text-muted);pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - var(--neu-space-6));transition:top var(--neu-transition),font-size var(--neu-transition),color var(--neu-transition),transform var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-input__wrapper--focused .neu-input__label,.neu-input__wrapper--has-value .neu-input__label{top:0;transform:translateY(-50%);font-size:12px;font-weight:600;letter-spacing:.01em;background:var(--neu-surface);padding:0 4px;left:calc(var(--neu-space-3) - 4px)}.neu-input__wrapper--focused .neu-input__label{color:var(--neu-primary)}.neu-input__wrapper--error .neu-input__label{color:var(--neu-error)}.neu-input__wrapper--disabled .neu-input__label{background:var(--neu-surface-2)}.neu-input__wrapper--has-start-icon .neu-input__label{left:40px}.neu-input__wrapper--has-start-icon .neu-input__label.neu-input__wrapper--focused,.neu-input__wrapper--focused .neu-input__wrapper--has-start-icon .neu-input__label,.neu-input__wrapper--has-value .neu-input__wrapper--has-start-icon .neu-input__label{left:calc(var(--neu-space-3) - 4px)}.neu-input__icon{position:absolute;display:flex;align-items:center;justify-content:center;width:36px;height:36px;color:var(--neu-text-muted);pointer-events:none;flex-shrink:0}.neu-input__icon svg{width:18px;height:18px}.neu-input__icon--start{left:0}.neu-input__icon--end{right:0}.neu-input__error{display:flex;align-items:center;gap:4px;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text);font-family:var(--neu-font-sans);line-height:1.4}.neu-input__hint{margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted);font-family:var(--neu-font-sans)}.neu-input__static-label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-input__wrapper--no-float .neu-input__field{padding:0 var(--neu-space-3)}.neu-input__wrapper--no-float .neu-input__field::placeholder{color:var(--neu-text-disabled)}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
204
+ `, isInline: true, styles: [".neu-input-host{display:block}.neu-input-host--sm .neu-input__wrapper{height:36px}.neu-input-host--sm .neu-input__field{font-size:var(--neu-text-sm)}.neu-input-host--lg .neu-input__wrapper{height:56px}.neu-input__wrapper{position:relative;display:flex;align-items:center;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);height:48px;transition:border-color var(--neu-transition),box-shadow var(--neu-transition),background-color var(--neu-transition)}.neu-input__wrapper:hover:not(.neu-input__wrapper--disabled){border-color:var(--neu-border-hover)}.neu-input__wrapper--focused{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-input__wrapper--error{border-color:var(--neu-error)}.neu-input__wrapper--error.neu-input__wrapper--focused{box-shadow:0 0 0 3px #ef44441f}.neu-input__wrapper--disabled{background:var(--neu-surface-2);cursor:not-allowed}.neu-input__wrapper--has-start-icon .neu-input__field{padding-left:40px}.neu-input__wrapper--has-end-icon .neu-input__field{padding-right:40px}.neu-input__field{width:100%;height:100%;padding:0 var(--neu-space-3);border:none;background:transparent;outline:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-base);color:var(--neu-text);caret-color:var(--neu-primary)}.neu-input__field:disabled{cursor:not-allowed;color:var(--neu-text-disabled)}.neu-input__field::placeholder{color:transparent;transition:color var(--neu-transition)}.neu-input__wrapper--focused .neu-input__field::placeholder{color:var(--neu-text-disabled)}.neu-input__label{position:absolute;left:var(--neu-space-3);top:50%;transform:translateY(-50%);font-size:var(--neu-text-base);color:var(--neu-text-muted);pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - var(--neu-space-6));transition:top var(--neu-transition),font-size var(--neu-transition),color var(--neu-transition),transform var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-input__wrapper--focused .neu-input__label,.neu-input__wrapper--has-value .neu-input__label{top:0;transform:translateY(-50%);font-size:12px;font-weight:600;letter-spacing:.01em;background:var(--neu-surface);padding:0 4px;left:calc(var(--neu-space-3) - 4px)}.neu-input__wrapper--focused .neu-input__label{color:var(--neu-primary)}.neu-input__wrapper--error .neu-input__label{color:var(--neu-error)}.neu-input__wrapper--disabled .neu-input__label{background:var(--neu-surface-2)}.neu-input__wrapper--has-start-icon .neu-input__label{left:40px}.neu-input__wrapper--has-start-icon .neu-input__label.neu-input__wrapper--focused,.neu-input__wrapper--focused .neu-input__wrapper--has-start-icon .neu-input__label,.neu-input__wrapper--has-value .neu-input__wrapper--has-start-icon .neu-input__label{left:calc(var(--neu-space-3) - 4px)}.neu-input__icon{position:absolute;display:flex;align-items:center;justify-content:center;width:36px;height:36px;color:var(--neu-text-muted);pointer-events:none;flex-shrink:0}.neu-input__icon svg{width:18px;height:18px}.neu-input__icon--start{left:0}.neu-input__icon--end{right:0}.neu-input__error{display:flex;align-items:center;gap:4px;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text);font-family:var(--neu-font-sans);line-height:1.4}.neu-input__hint{margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted);font-family:var(--neu-font-sans)}.neu-input__static-label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-input__wrapper--no-float .neu-input__field{padding:0 var(--neu-space-3)}.neu-input__wrapper--no-float .neu-input__field::placeholder{color:var(--neu-text-disabled)}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
205
205
  }
206
206
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuInputComponent, decorators: [{
207
207
  type: Component,
@@ -309,7 +309,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
309
309
  } @else if (hint()) {
310
310
  <p class="neu-input__hint" [id]="inputId() + '-hint'">{{ hint() }}</p>
311
311
  }
312
- `, styles: [".neu-input-host{display:block}.neu-input-host--sm .neu-input__wrapper{height:36px}.neu-input-host--sm .neu-input__field{font-size:var(--neu-text-sm)}.neu-input-host--lg .neu-input__wrapper{height:56px}.neu-input__wrapper{position:relative;display:flex;align-items:center;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);height:48px;transition:border-color var(--neu-transition),box-shadow var(--neu-transition),background-color var(--neu-transition)}.neu-input__wrapper:hover:not(.neu-input__wrapper--disabled){border-color:var(--neu-border-hover)}.neu-input__wrapper--focused{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-input__wrapper--error{border-color:var(--neu-error)}.neu-input__wrapper--error.neu-input__wrapper--focused{box-shadow:0 0 0 3px #ef44441f}.neu-input__wrapper--disabled{background:var(--neu-surface-2);opacity:.6;cursor:not-allowed}.neu-input__wrapper--has-start-icon .neu-input__field{padding-left:40px}.neu-input__wrapper--has-end-icon .neu-input__field{padding-right:40px}.neu-input__field{width:100%;height:100%;padding:0 var(--neu-space-3);border:none;background:transparent;outline:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-base);color:var(--neu-text);caret-color:var(--neu-primary)}.neu-input__field:disabled{cursor:not-allowed;color:var(--neu-text-disabled)}.neu-input__field::placeholder{color:transparent;transition:color var(--neu-transition)}.neu-input__wrapper--focused .neu-input__field::placeholder{color:var(--neu-text-disabled)}.neu-input__label{position:absolute;left:var(--neu-space-3);top:50%;transform:translateY(-50%);font-size:var(--neu-text-base);color:var(--neu-text-muted);pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - var(--neu-space-6));transition:top var(--neu-transition),font-size var(--neu-transition),color var(--neu-transition),transform var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-input__wrapper--focused .neu-input__label,.neu-input__wrapper--has-value .neu-input__label{top:0;transform:translateY(-50%);font-size:12px;font-weight:600;letter-spacing:.01em;background:var(--neu-surface);padding:0 4px;left:calc(var(--neu-space-3) - 4px)}.neu-input__wrapper--focused .neu-input__label{color:var(--neu-primary)}.neu-input__wrapper--error .neu-input__label{color:var(--neu-error)}.neu-input__wrapper--disabled .neu-input__label{background:var(--neu-surface-2)}.neu-input__wrapper--has-start-icon .neu-input__label{left:40px}.neu-input__wrapper--has-start-icon .neu-input__label.neu-input__wrapper--focused,.neu-input__wrapper--focused .neu-input__wrapper--has-start-icon .neu-input__label,.neu-input__wrapper--has-value .neu-input__wrapper--has-start-icon .neu-input__label{left:calc(var(--neu-space-3) - 4px)}.neu-input__icon{position:absolute;display:flex;align-items:center;justify-content:center;width:36px;height:36px;color:var(--neu-text-muted);pointer-events:none;flex-shrink:0}.neu-input__icon svg{width:18px;height:18px}.neu-input__icon--start{left:0}.neu-input__icon--end{right:0}.neu-input__error{display:flex;align-items:center;gap:4px;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text);font-family:var(--neu-font-sans);line-height:1.4}.neu-input__hint{margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted);font-family:var(--neu-font-sans)}.neu-input__static-label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-input__wrapper--no-float .neu-input__field{padding:0 var(--neu-space-3)}.neu-input__wrapper--no-float .neu-input__field::placeholder{color:var(--neu-text-disabled)}\n"] }]
312
+ `, styles: [".neu-input-host{display:block}.neu-input-host--sm .neu-input__wrapper{height:36px}.neu-input-host--sm .neu-input__field{font-size:var(--neu-text-sm)}.neu-input-host--lg .neu-input__wrapper{height:56px}.neu-input__wrapper{position:relative;display:flex;align-items:center;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);height:48px;transition:border-color var(--neu-transition),box-shadow var(--neu-transition),background-color var(--neu-transition)}.neu-input__wrapper:hover:not(.neu-input__wrapper--disabled){border-color:var(--neu-border-hover)}.neu-input__wrapper--focused{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-input__wrapper--error{border-color:var(--neu-error)}.neu-input__wrapper--error.neu-input__wrapper--focused{box-shadow:0 0 0 3px #ef44441f}.neu-input__wrapper--disabled{background:var(--neu-surface-2);cursor:not-allowed}.neu-input__wrapper--has-start-icon .neu-input__field{padding-left:40px}.neu-input__wrapper--has-end-icon .neu-input__field{padding-right:40px}.neu-input__field{width:100%;height:100%;padding:0 var(--neu-space-3);border:none;background:transparent;outline:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-base);color:var(--neu-text);caret-color:var(--neu-primary)}.neu-input__field:disabled{cursor:not-allowed;color:var(--neu-text-disabled)}.neu-input__field::placeholder{color:transparent;transition:color var(--neu-transition)}.neu-input__wrapper--focused .neu-input__field::placeholder{color:var(--neu-text-disabled)}.neu-input__label{position:absolute;left:var(--neu-space-3);top:50%;transform:translateY(-50%);font-size:var(--neu-text-base);color:var(--neu-text-muted);pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - var(--neu-space-6));transition:top var(--neu-transition),font-size var(--neu-transition),color var(--neu-transition),transform var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-input__wrapper--focused .neu-input__label,.neu-input__wrapper--has-value .neu-input__label{top:0;transform:translateY(-50%);font-size:12px;font-weight:600;letter-spacing:.01em;background:var(--neu-surface);padding:0 4px;left:calc(var(--neu-space-3) - 4px)}.neu-input__wrapper--focused .neu-input__label{color:var(--neu-primary)}.neu-input__wrapper--error .neu-input__label{color:var(--neu-error)}.neu-input__wrapper--disabled .neu-input__label{background:var(--neu-surface-2)}.neu-input__wrapper--has-start-icon .neu-input__label{left:40px}.neu-input__wrapper--has-start-icon .neu-input__label.neu-input__wrapper--focused,.neu-input__wrapper--focused .neu-input__wrapper--has-start-icon .neu-input__label,.neu-input__wrapper--has-value .neu-input__wrapper--has-start-icon .neu-input__label{left:calc(var(--neu-space-3) - 4px)}.neu-input__icon{position:absolute;display:flex;align-items:center;justify-content:center;width:36px;height:36px;color:var(--neu-text-muted);pointer-events:none;flex-shrink:0}.neu-input__icon svg{width:18px;height:18px}.neu-input__icon--start{left:0}.neu-input__icon--end{right:0}.neu-input__error{display:flex;align-items:center;gap:4px;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text);font-family:var(--neu-font-sans);line-height:1.4}.neu-input__hint{margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted);font-family:var(--neu-font-sans)}.neu-input__static-label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-input__wrapper--no-float .neu-input__field{padding:0 var(--neu-space-3)}.neu-input__wrapper--no-float .neu-input__field::placeholder{color:var(--neu-text-disabled)}\n"] }]
313
313
  }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], floatingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], startIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "startIcon", required: false }] }], endIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "endIcon", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], minlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minlength", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }] } });
314
314
 
315
315
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-input.mjs","sources":["../../../../projects/ui-core/input/neu-input.component.ts","../../../../projects/ui-core/input/neural-ui-core-input.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n forwardRef,\n input,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\n/** Contador global para IDs estables — seguro en SSR, predecible en hidratación / Global counter for stable IDs — SSR-safe, predictable on hydration */\nlet _neuInputIdSeq = 0;\n\nexport type NeuInputType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'search';\n\n/**\n * NeuralUI Input Component\n *\n * Input con floating label, iconos y soporte completo para Angular Forms.\n * Compatible con Reactive Forms mediante FormControl y formularios reactivos.\n *\n * Uso standalone:\n * <neu-input label=\"Correo\" type=\"email\" />\n *\n * Con Reactive Forms:\n * <neu-input label=\"Correo\" [formControl]=\"emailCtrl\" [errorMessage]=\"emailError()\" />\n */\n@Component({\n selector: 'neu-input',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n // Los atributos del host (class, style, data-*) no deben llegar al <input> nativo\n // — se gestionan de forma explícita con los inputs del componente.\n host: {\n class: 'neu-input-host',\n '[class.neu-input-host--sm]': 'size() === \"sm\"',\n '[class.neu-input-host--lg]': 'size() === \"lg\"',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuInputComponent),\n multi: true,\n },\n ],\n template: `\n @if (!floatingLabel() && label()) {\n <label class=\"neu-input__static-label\" [for]=\"inputId()\">{{ label() }}</label>\n }\n <div\n class=\"neu-input__wrapper\"\n [class.neu-input__wrapper--focused]=\"_focused()\"\n [class.neu-input__wrapper--has-value]=\"hasValue()\"\n [class.neu-input__wrapper--error]=\"hasError()\"\n [class.neu-input__wrapper--disabled]=\"isDisabledFinal()\"\n [class.neu-input__wrapper--has-start-icon]=\"!!startIcon() || _hasIconLeft()\"\n [class.neu-input__wrapper--has-end-icon]=\"!!endIcon() || _hasIconRight()\"\n [class.neu-input__wrapper--no-float]=\"!floatingLabel()\"\n >\n <!-- Icono izquierdo (proyección) -->\n @if (startIcon()) {\n <span class=\"neu-input__icon neu-input__icon--start\" aria-hidden=\"true\">\n <ng-content select=\"[neu-input-start]\" />\n @if (!hasStartContent()) {\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [innerHTML]=\"startIconPath()\"\n ></svg>\n }\n </span>\n }\n\n <!-- Icono izquierdo (por nombre) -->\n @if (_hasIconLeft()) {\n <span class=\"neu-input__icon neu-input__icon--start\" aria-hidden=\"true\">\n <neu-icon [name]=\"icon()\" size=\"16px\" />\n </span>\n }\n\n <!-- Campo nativo -->\n <input\n class=\"neu-input__field\"\n [id]=\"inputId()\"\n [type]=\"type()\"\n [disabled]=\"isDisabledFinal()\"\n [attr.name]=\"name() || null\"\n [attr.required]=\"required() ? '' : null\"\n [attr.readonly]=\"readonly() ? '' : null\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.minlength]=\"minlength() ?? null\"\n [attr.min]=\"min() ?? null\"\n [attr.max]=\"max() ?? null\"\n [attr.pattern]=\"pattern() ?? null\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\n [attr.aria-describedby]=\"\n hasError() ? inputId() + '-error' : hint() ? inputId() + '-hint' : null\n \"\n [value]=\"_value()\"\n [attr.placeholder]=\"floatingLabel() ? ' ' : placeholder() || null\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n />\n\n <!-- Floating Label -->\n @if (floatingLabel() && label()) {\n <label class=\"neu-input__label\" [for]=\"inputId()\">{{ label() }}</label>\n }\n\n <!-- Icono derecho (proyección) -->\n @if (endIcon()) {\n <span class=\"neu-input__icon neu-input__icon--end\" aria-hidden=\"true\">\n <ng-content select=\"[neu-input-end]\" />\n </span>\n }\n\n <!-- Icono derecho (por nombre) -->\n @if (_hasIconRight()) {\n <span class=\"neu-input__icon neu-input__icon--end\" aria-hidden=\"true\">\n <neu-icon [name]=\"icon()\" size=\"16px\" />\n </span>\n }\n </div>\n\n <!-- Mensajes de ayuda / error -->\n @if (hasError()) {\n <p class=\"neu-input__error\" [id]=\"inputId() + '-error'\" role=\"alert\">\n <neu-icon name=\"lucideAlertCircle\" size=\"13px\" aria-hidden=\"true\" />\n {{ errorMessage() }}\n </p>\n } @else if (hint()) {\n <p class=\"neu-input__hint\" [id]=\"inputId() + '-hint'\">{{ hint() }}</p>\n }\n `,\n styleUrl: './neu-input.component.scss',\n})\nexport class NeuInputComponent implements ControlValueAccessor {\n /** Tipo de input HTML / HTML input type */\n type = input<NeuInputType>('text');\n\n /** Texto del floating label / Floating label text */\n label = input<string>('');\n\n /** Placeholder visible cuando floatingLabel=false / Visible placeholder when floatingLabel=false */\n placeholder = input<string>('');\n\n /** Muestra el label como flotante (true) o estático encima del campo (false) / Shows the label as floating (true) or static above the field (false) */\n floatingLabel = input<boolean>(true);\n\n /** Tamaño del campo: 'sm' = 36px | 'md' = 48px | 'lg' = 56px / Field size */\n size = input<'sm' | 'md' | 'lg'>('md');\n\n /** Hint de ayuda (visible cuando no hay error) / Help hint (visible when there is no error) */\n hint = input<string>('');\n\n /** Mensaje de error (activa el estado de error) / Error message (activates the error state) */\n errorMessage = input<string>('');\n\n /** Deshabilita el campo / Disables the field */\n disabled = input<boolean>(false);\n\n /** Atributo autocomplete HTML / HTML autocomplete attribute */\n autocomplete = input<string>('off');\n\n /** Muestra zona para icono al inicio / Shows icon slot at the start */\n startIcon = input<boolean>(false);\n\n /** Muestra zona para icono al final / Shows icon slot at the end */\n endIcon = input<boolean>(false);\n\n /** Nombre del icono lucide a renderizar dentro del campo / Lucide icon name to render inside the field */\n icon = input<string>('');\n\n /** Posición del icono cuando se usa `icon` / Icon position when using `icon` */\n iconPosition = input<'left' | 'right'>('left');\n\n /** ID accesible para el input — generado con contador estable (seguro en SSR) / Accessible ID for the input — generated with stable counter (SSR-safe) */\n inputId = input<string>(`neu-input-${++_neuInputIdSeq}`);\n\n /** Nombre del campo para formularios nativos / Field name for native forms */\n name = input<string>('');\n\n /** Marca el campo como requerido / Marks the field as required */\n required = input<boolean>(false);\n\n /** Hace el campo de solo lectura / Makes the field read-only */\n readonly = input<boolean>(false);\n\n /** Longitud máxima de caracteres / Maximum character length */\n maxlength = input<number | null>(null);\n\n /** Longitud mínima de caracteres / Minimum character length */\n minlength = input<number | null>(null);\n\n /** Valor mínimo (para type=number/date) / Minimum value (for type=number/date) */\n min = input<string | null>(null);\n\n /** Valor máximo (para type=number/date) / Maximum value (for type=number/date) */\n max = input<string | null>(null);\n\n /** Patrón de validación HTML5 / HTML5 validation pattern */\n pattern = input<string | null>(null);\n\n // --- Estado interno reactivo ---\n protected readonly _value = signal('');\n protected readonly _focused = signal(false);\n\n readonly hasValue = computed(() => this._value().length > 0);\n readonly hasError = computed(() => !!this.errorMessage());\n readonly startIconPath = computed(() => '');\n readonly hasStartContent = computed(() => false);\n readonly _hasIconLeft = computed(() => !!this.icon() && this.iconPosition() === 'left');\n readonly _hasIconRight = computed(() => !!this.icon() && this.iconPosition() === 'right');\n\n // --- ControlValueAccessor ---\n private _onChange: (v: string) => void = () => {};\n private _onTouched: () => void = () => {};\n\n writeValue(val: unknown): void {\n this._value.set(val == null ? '' : String(val));\n }\n\n registerOnChange(fn: (v: string) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n private readonly _cvaDisabled = signal(false);\n setDisabledState(isDisabled: boolean): void {\n this._cvaDisabled.set(isDisabled);\n }\n\n readonly isDisabledFinal = computed(() => this.disabled() || this._cvaDisabled());\n\n onInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this._value.set(value);\n this._onChange(value);\n }\n\n onFocus(): void {\n this._focused.set(true);\n }\n\n onBlur(): void {\n this._focused.set(false);\n this._onTouched();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"neural-ui-core-input.mjs","sources":["../../../../projects/ui-core/input/neu-input.component.ts","../../../../projects/ui-core/input/neural-ui-core-input.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n forwardRef,\n input,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\n/** Contador global para IDs estables — seguro en SSR, predecible en hidratación / Global counter for stable IDs — SSR-safe, predictable on hydration */\nlet _neuInputIdSeq = 0;\n\nexport type NeuInputType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'search';\n\n/**\n * NeuralUI Input Component\n *\n * Input con floating label, iconos y soporte completo para Angular Forms.\n * Compatible con Reactive Forms mediante FormControl y formularios reactivos.\n *\n * Uso standalone:\n * <neu-input label=\"Correo\" type=\"email\" />\n *\n * Con Reactive Forms:\n * <neu-input label=\"Correo\" [formControl]=\"emailCtrl\" [errorMessage]=\"emailError()\" />\n */\n@Component({\n selector: 'neu-input',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n // Los atributos del host (class, style, data-*) no deben llegar al <input> nativo\n // — se gestionan de forma explícita con los inputs del componente.\n host: {\n class: 'neu-input-host',\n '[class.neu-input-host--sm]': 'size() === \"sm\"',\n '[class.neu-input-host--lg]': 'size() === \"lg\"',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuInputComponent),\n multi: true,\n },\n ],\n template: `\n @if (!floatingLabel() && label()) {\n <label class=\"neu-input__static-label\" [for]=\"inputId()\">{{ label() }}</label>\n }\n <div\n class=\"neu-input__wrapper\"\n [class.neu-input__wrapper--focused]=\"_focused()\"\n [class.neu-input__wrapper--has-value]=\"hasValue()\"\n [class.neu-input__wrapper--error]=\"hasError()\"\n [class.neu-input__wrapper--disabled]=\"isDisabledFinal()\"\n [class.neu-input__wrapper--has-start-icon]=\"!!startIcon() || _hasIconLeft()\"\n [class.neu-input__wrapper--has-end-icon]=\"!!endIcon() || _hasIconRight()\"\n [class.neu-input__wrapper--no-float]=\"!floatingLabel()\"\n >\n <!-- Icono izquierdo (proyección) -->\n @if (startIcon()) {\n <span class=\"neu-input__icon neu-input__icon--start\" aria-hidden=\"true\">\n <ng-content select=\"[neu-input-start]\" />\n @if (!hasStartContent()) {\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [innerHTML]=\"startIconPath()\"\n ></svg>\n }\n </span>\n }\n\n <!-- Icono izquierdo (por nombre) -->\n @if (_hasIconLeft()) {\n <span class=\"neu-input__icon neu-input__icon--start\" aria-hidden=\"true\">\n <neu-icon [name]=\"icon()\" size=\"16px\" />\n </span>\n }\n\n <!-- Campo nativo -->\n <input\n class=\"neu-input__field\"\n [id]=\"inputId()\"\n [type]=\"type()\"\n [disabled]=\"isDisabledFinal()\"\n [attr.name]=\"name() || null\"\n [attr.required]=\"required() ? '' : null\"\n [attr.readonly]=\"readonly() ? '' : null\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.minlength]=\"minlength() ?? null\"\n [attr.min]=\"min() ?? null\"\n [attr.max]=\"max() ?? null\"\n [attr.pattern]=\"pattern() ?? null\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\n [attr.aria-describedby]=\"\n hasError() ? inputId() + '-error' : hint() ? inputId() + '-hint' : null\n \"\n [value]=\"_value()\"\n [attr.placeholder]=\"floatingLabel() ? ' ' : placeholder() || null\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n />\n\n <!-- Floating Label -->\n @if (floatingLabel() && label()) {\n <label class=\"neu-input__label\" [for]=\"inputId()\">{{ label() }}</label>\n }\n\n <!-- Icono derecho (proyección) -->\n @if (endIcon()) {\n <span class=\"neu-input__icon neu-input__icon--end\" aria-hidden=\"true\">\n <ng-content select=\"[neu-input-end]\" />\n </span>\n }\n\n <!-- Icono derecho (por nombre) -->\n @if (_hasIconRight()) {\n <span class=\"neu-input__icon neu-input__icon--end\" aria-hidden=\"true\">\n <neu-icon [name]=\"icon()\" size=\"16px\" />\n </span>\n }\n </div>\n\n <!-- Mensajes de ayuda / error -->\n @if (hasError()) {\n <p class=\"neu-input__error\" [id]=\"inputId() + '-error'\" role=\"alert\">\n <neu-icon name=\"lucideAlertCircle\" size=\"13px\" aria-hidden=\"true\" />\n {{ errorMessage() }}\n </p>\n } @else if (hint()) {\n <p class=\"neu-input__hint\" [id]=\"inputId() + '-hint'\">{{ hint() }}</p>\n }\n `,\n styleUrl: './neu-input.component.scss',\n})\nexport class NeuInputComponent implements ControlValueAccessor {\n /** Tipo de input HTML / HTML input type */\n type = input<NeuInputType>('text');\n\n /** Texto del floating label / Floating label text */\n label = input<string>('');\n\n /** Placeholder visible cuando floatingLabel=false / Visible placeholder when floatingLabel=false */\n placeholder = input<string>('');\n\n /** Muestra el label como flotante (true) o estático encima del campo (false) / Shows the label as floating (true) or static above the field (false) */\n floatingLabel = input<boolean>(true);\n\n /** Tamaño del campo: 'sm' = 36px | 'md' = 48px | 'lg' = 56px / Field size */\n size = input<'sm' | 'md' | 'lg'>('md');\n\n /** Hint de ayuda (visible cuando no hay error) / Help hint (visible when there is no error) */\n hint = input<string>('');\n\n /** Mensaje de error (activa el estado de error) / Error message (activates the error state) */\n errorMessage = input<string>('');\n\n /** Deshabilita el campo / Disables the field */\n disabled = input<boolean>(false);\n\n /** Atributo autocomplete HTML / HTML autocomplete attribute */\n autocomplete = input<string>('off');\n\n /** Muestra zona para icono al inicio / Shows icon slot at the start */\n startIcon = input<boolean>(false);\n\n /** Muestra zona para icono al final / Shows icon slot at the end */\n endIcon = input<boolean>(false);\n\n /** Nombre del icono lucide a renderizar dentro del campo / Lucide icon name to render inside the field */\n icon = input<string>('');\n\n /** Posición del icono cuando se usa `icon` / Icon position when using `icon` */\n iconPosition = input<'left' | 'right'>('left');\n\n /** ID accesible para el input — generado con contador estable (seguro en SSR) / Accessible ID for the input — generated with stable counter (SSR-safe) */\n inputId = input<string>(`neu-input-${++_neuInputIdSeq}`);\n\n /** Nombre del campo para formularios nativos / Field name for native forms */\n name = input<string>('');\n\n /** Marca el campo como requerido / Marks the field as required */\n required = input<boolean>(false);\n\n /** Hace el campo de solo lectura / Makes the field read-only */\n readonly = input<boolean>(false);\n\n /** Longitud máxima de caracteres / Maximum character length */\n maxlength = input<number | null>(null);\n\n /** Longitud mínima de caracteres / Minimum character length */\n minlength = input<number | null>(null);\n\n /** Valor mínimo (para type=number/date) / Minimum value (for type=number/date) */\n min = input<string | null>(null);\n\n /** Valor máximo (para type=number/date) / Maximum value (for type=number/date) */\n max = input<string | null>(null);\n\n /** Patrón de validación HTML5 / HTML5 validation pattern */\n pattern = input<string | null>(null);\n\n // --- Estado interno reactivo ---\n protected readonly _value = signal('');\n protected readonly _focused = signal(false);\n\n readonly hasValue = computed(() => this._value().length > 0);\n readonly hasError = computed(() => !!this.errorMessage());\n readonly startIconPath = computed(() => '');\n readonly hasStartContent = computed(() => false);\n readonly _hasIconLeft = computed(() => !!this.icon() && this.iconPosition() === 'left');\n readonly _hasIconRight = computed(() => !!this.icon() && this.iconPosition() === 'right');\n\n // --- ControlValueAccessor ---\n private _onChange: (v: string) => void = () => {};\n private _onTouched: () => void = () => {};\n\n writeValue(val: unknown): void {\n this._value.set(val == null ? '' : String(val));\n }\n\n registerOnChange(fn: (v: string) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n private readonly _cvaDisabled = signal(false);\n setDisabledState(isDisabled: boolean): void {\n this._cvaDisabled.set(isDisabled);\n }\n\n readonly isDisabledFinal = computed(() => this.disabled() || this._cvaDisabled());\n\n onInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this._value.set(value);\n this._onChange(value);\n }\n\n onFocus(): void {\n this._focused.set(true);\n }\n\n onBlur(): void {\n this._focused.set(false);\n this._onTouched();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Directive, input, output, contentChild, signal, computed, forwardRef, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
5
+
6
+ class NeuListboxItemDirective {
7
+ templateRef;
8
+ constructor(templateRef) {
9
+ this.templateRef = templateRef;
10
+ }
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuListboxItemDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
12
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: NeuListboxItemDirective, isStandalone: true, selector: "ng-template[neuListboxItem]", ngImport: i0 });
13
+ }
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuListboxItemDirective, decorators: [{
15
+ type: Directive,
16
+ args: [{ selector: 'ng-template[neuListboxItem]' }]
17
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
18
+ class NeuListboxComponent {
19
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
20
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
21
+ ariaLabel = input('Options', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
22
+ hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
23
+ emptyLabel = input('No options found', ...(ngDevMode ? [{ debugName: "emptyLabel" }] : /* istanbul ignore next */ []));
24
+ multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
25
+ searchable = input(false, ...(ngDevMode ? [{ debugName: "searchable" }] : /* istanbul ignore next */ []));
26
+ searchPlaceholder = input('Search...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
27
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
28
+ selectionChange = output();
29
+ itemTpl = contentChild(NeuListboxItemDirective, ...(ngDevMode ? [{ debugName: "itemTpl" }] : /* istanbul ignore next */ []));
30
+ query = signal('', ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
31
+ activeIndex = signal(0, ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
32
+ values = signal([], ...(ngDevMode ? [{ debugName: "values" }] : /* istanbul ignore next */ []));
33
+ cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
34
+ labelId = `neu-listbox-label-${Math.random().toString(36).slice(2)}`;
35
+ isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
36
+ filteredOptions = computed(() => {
37
+ const q = this.query().trim().toLowerCase();
38
+ return q ? this.options().filter((option) => option.label.toLowerCase().includes(q)) : this.options();
39
+ }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
40
+ onChange = () => { };
41
+ onTouched = () => { };
42
+ writeValue(value) {
43
+ this.values.set(Array.isArray(value) ? value : value ? [value] : []);
44
+ }
45
+ registerOnChange(fn) {
46
+ this.onChange = fn;
47
+ }
48
+ registerOnTouched(fn) {
49
+ this.onTouched = fn;
50
+ }
51
+ setDisabledState(isDisabled) {
52
+ this.cvaDisabled.set(isDisabled);
53
+ }
54
+ isSelected(value) {
55
+ return this.values().includes(value);
56
+ }
57
+ toggleOption(option) {
58
+ if (option.disabled || this.isDisabled()) {
59
+ return;
60
+ }
61
+ const next = this.multiple()
62
+ ? this.isSelected(option.value)
63
+ ? this.values().filter((value) => value !== option.value)
64
+ : [...this.values(), option.value]
65
+ : [option.value];
66
+ this.values.set(next);
67
+ this.onTouched();
68
+ this.onChange(this.multiple() ? next : (next[0] ?? null));
69
+ this.selectionChange.emit(this.options().filter((item) => next.includes(item.value)));
70
+ }
71
+ onKeyDown(event) {
72
+ const enabled = this.filteredOptions().filter((option) => !option.disabled);
73
+ if (!enabled.length) {
74
+ return;
75
+ }
76
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
77
+ event.preventDefault();
78
+ const step = event.key === 'ArrowDown' ? 1 : -1;
79
+ this.activeIndex.set(Math.max(0, Math.min(this.filteredOptions().length - 1, this.activeIndex() + step)));
80
+ }
81
+ if (event.key === 'Enter' || event.key === ' ') {
82
+ event.preventDefault();
83
+ const option = this.filteredOptions()[this.activeIndex()];
84
+ if (option) {
85
+ this.toggleOption(option);
86
+ }
87
+ }
88
+ }
89
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuListboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
90
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuListboxComponent, isStandalone: true, selector: "neu-listbox", inputs: { options: { classPropertyName: "options", publicName: "options", 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 }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { properties: { "class.neu-listbox--disabled": "isDisabled()" }, classAttribute: "neu-listbox" }, providers: [
91
+ {
92
+ provide: NG_VALUE_ACCESSOR,
93
+ useExisting: forwardRef(() => NeuListboxComponent),
94
+ multi: true,
95
+ },
96
+ ], queries: [{ propertyName: "itemTpl", first: true, predicate: NeuListboxItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
97
+ @if (label()) {
98
+ <div class="neu-listbox__label" [id]="labelId">{{ label() }}</div>
99
+ }
100
+ @if (searchable()) {
101
+ <input
102
+ class="neu-listbox__search"
103
+ type="search"
104
+ [placeholder]="searchPlaceholder()"
105
+ [value]="query()"
106
+ [disabled]="isDisabled()"
107
+ (input)="query.set($any($event.target).value)"
108
+ />
109
+ }
110
+ <div
111
+ class="neu-listbox__options"
112
+ role="listbox"
113
+ [attr.aria-labelledby]="label() ? labelId : null"
114
+ [attr.aria-label]="label() ? null : ariaLabel()"
115
+ [attr.aria-multiselectable]="multiple()"
116
+ tabindex="0"
117
+ (keydown)="onKeyDown($event)"
118
+ >
119
+ @for (option of filteredOptions(); track option.value; let i = $index) {
120
+ <button
121
+ type="button"
122
+ class="neu-listbox__option"
123
+ role="option"
124
+ [class.neu-listbox__option--active]="activeIndex() === i"
125
+ [class.neu-listbox__option--selected]="isSelected(option.value)"
126
+ [disabled]="isDisabled() || option.disabled"
127
+ [attr.aria-selected]="isSelected(option.value)"
128
+ (click)="toggleOption(option)"
129
+ >
130
+ @if (itemTpl()) {
131
+ <ng-container
132
+ [ngTemplateOutlet]="itemTpl()!.templateRef"
133
+ [ngTemplateOutletContext]="{ $implicit: option }"
134
+ />
135
+ } @else {
136
+ {{ option.label }}
137
+ }
138
+ </button>
139
+ }
140
+ @if (!filteredOptions().length) {
141
+ <div class="neu-listbox__empty">{{ emptyLabel() }}</div>
142
+ }
143
+ </div>
144
+ @if (hint()) {
145
+ <p class="neu-listbox__hint">{{ hint() }}</p>
146
+ }
147
+ `, isInline: true, styles: [".neu-listbox{display:block}.neu-listbox__label{margin-bottom:.375rem;font-size:.875rem;font-weight:600;color:var(--neu-text, #111827)}.neu-listbox__search{width:100%;min-height:2.25rem;margin-bottom:.5rem;border:1px solid var(--neu-border, #d1d5db);border-radius:.5rem;background:var(--neu-surface, #fff);color:var(--neu-text, #111827);padding:0 .75rem}.neu-listbox__options{display:grid;gap:.25rem;max-height:18rem;overflow:auto;border:1px solid var(--neu-border, #d1d5db);border-radius:.625rem;padding:.375rem;background:var(--neu-surface, #fff)}.neu-listbox__option{border:0;border-radius:.5rem;background:transparent;color:var(--neu-text, #111827);padding:.625rem .75rem;text-align:left;cursor:pointer}.neu-listbox__option--active{outline:2px solid var(--neu-primary, #2563eb);outline-offset:1px}.neu-listbox__option--selected{background:color-mix(in srgb,var(--neu-primary, #2563eb) 14%,transparent)}.neu-listbox__empty,.neu-listbox__hint{color:var(--neu-text-muted, #6b7280);font-size:.875rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
148
+ }
149
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuListboxComponent, decorators: [{
150
+ type: Component,
151
+ args: [{ selector: 'neu-listbox', imports: [NgTemplateOutlet], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
152
+ {
153
+ provide: NG_VALUE_ACCESSOR,
154
+ useExisting: forwardRef(() => NeuListboxComponent),
155
+ multi: true,
156
+ },
157
+ ], host: {
158
+ class: 'neu-listbox',
159
+ '[class.neu-listbox--disabled]': 'isDisabled()',
160
+ }, template: `
161
+ @if (label()) {
162
+ <div class="neu-listbox__label" [id]="labelId">{{ label() }}</div>
163
+ }
164
+ @if (searchable()) {
165
+ <input
166
+ class="neu-listbox__search"
167
+ type="search"
168
+ [placeholder]="searchPlaceholder()"
169
+ [value]="query()"
170
+ [disabled]="isDisabled()"
171
+ (input)="query.set($any($event.target).value)"
172
+ />
173
+ }
174
+ <div
175
+ class="neu-listbox__options"
176
+ role="listbox"
177
+ [attr.aria-labelledby]="label() ? labelId : null"
178
+ [attr.aria-label]="label() ? null : ariaLabel()"
179
+ [attr.aria-multiselectable]="multiple()"
180
+ tabindex="0"
181
+ (keydown)="onKeyDown($event)"
182
+ >
183
+ @for (option of filteredOptions(); track option.value; let i = $index) {
184
+ <button
185
+ type="button"
186
+ class="neu-listbox__option"
187
+ role="option"
188
+ [class.neu-listbox__option--active]="activeIndex() === i"
189
+ [class.neu-listbox__option--selected]="isSelected(option.value)"
190
+ [disabled]="isDisabled() || option.disabled"
191
+ [attr.aria-selected]="isSelected(option.value)"
192
+ (click)="toggleOption(option)"
193
+ >
194
+ @if (itemTpl()) {
195
+ <ng-container
196
+ [ngTemplateOutlet]="itemTpl()!.templateRef"
197
+ [ngTemplateOutletContext]="{ $implicit: option }"
198
+ />
199
+ } @else {
200
+ {{ option.label }}
201
+ }
202
+ </button>
203
+ }
204
+ @if (!filteredOptions().length) {
205
+ <div class="neu-listbox__empty">{{ emptyLabel() }}</div>
206
+ }
207
+ </div>
208
+ @if (hint()) {
209
+ <p class="neu-listbox__hint">{{ hint() }}</p>
210
+ }
211
+ `, styles: [".neu-listbox{display:block}.neu-listbox__label{margin-bottom:.375rem;font-size:.875rem;font-weight:600;color:var(--neu-text, #111827)}.neu-listbox__search{width:100%;min-height:2.25rem;margin-bottom:.5rem;border:1px solid var(--neu-border, #d1d5db);border-radius:.5rem;background:var(--neu-surface, #fff);color:var(--neu-text, #111827);padding:0 .75rem}.neu-listbox__options{display:grid;gap:.25rem;max-height:18rem;overflow:auto;border:1px solid var(--neu-border, #d1d5db);border-radius:.625rem;padding:.375rem;background:var(--neu-surface, #fff)}.neu-listbox__option{border:0;border-radius:.5rem;background:transparent;color:var(--neu-text, #111827);padding:.625rem .75rem;text-align:left;cursor:pointer}.neu-listbox__option--active{outline:2px solid var(--neu-primary, #2563eb);outline-offset:1px}.neu-listbox__option--selected{background:color-mix(in srgb,var(--neu-primary, #2563eb) 14%,transparent)}.neu-listbox__empty,.neu-listbox__hint{color:var(--neu-text-muted, #6b7280);font-size:.875rem}\n"] }]
212
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", 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 }] }], emptyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyLabel", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], itemTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NeuListboxItemDirective), { isSignal: true }] }] } });
213
+
214
+ /**
215
+ * Generated bundle index. Do not edit.
216
+ */
217
+
218
+ export { NeuListboxComponent, NeuListboxItemDirective };
219
+ //# sourceMappingURL=neural-ui-core-listbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neural-ui-core-listbox.mjs","sources":["../../../../projects/ui-core/listbox/neu-listbox.component.ts","../../../../projects/ui-core/listbox/neural-ui-core-listbox.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Directive,\n TemplateRef,\n ViewEncapsulation,\n computed,\n contentChild,\n forwardRef,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface NeuListboxOption {\n value: string;\n label: string;\n disabled?: boolean;\n data?: unknown;\n}\n\n@Directive({ selector: 'ng-template[neuListboxItem]' })\nexport class NeuListboxItemDirective {\n constructor(readonly templateRef: TemplateRef<{ $implicit: NeuListboxOption }>) {}\n}\n\n@Component({\n selector: 'neu-listbox',\n imports: [NgTemplateOutlet],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuListboxComponent),\n multi: true,\n },\n ],\n host: {\n class: 'neu-listbox',\n '[class.neu-listbox--disabled]': 'isDisabled()',\n },\n template: `\n @if (label()) {\n <div class=\"neu-listbox__label\" [id]=\"labelId\">{{ label() }}</div>\n }\n @if (searchable()) {\n <input\n class=\"neu-listbox__search\"\n type=\"search\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"query()\"\n [disabled]=\"isDisabled()\"\n (input)=\"query.set($any($event.target).value)\"\n />\n }\n <div\n class=\"neu-listbox__options\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"label() ? labelId : null\"\n [attr.aria-label]=\"label() ? null : ariaLabel()\"\n [attr.aria-multiselectable]=\"multiple()\"\n tabindex=\"0\"\n (keydown)=\"onKeyDown($event)\"\n >\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <button\n type=\"button\"\n class=\"neu-listbox__option\"\n role=\"option\"\n [class.neu-listbox__option--active]=\"activeIndex() === i\"\n [class.neu-listbox__option--selected]=\"isSelected(option.value)\"\n [disabled]=\"isDisabled() || option.disabled\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option)\"\n >\n @if (itemTpl()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTpl()!.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: option }\"\n />\n } @else {\n {{ option.label }}\n }\n </button>\n }\n @if (!filteredOptions().length) {\n <div class=\"neu-listbox__empty\">{{ emptyLabel() }}</div>\n }\n </div>\n @if (hint()) {\n <p class=\"neu-listbox__hint\">{{ hint() }}</p>\n }\n `,\n styleUrl: './neu-listbox.component.scss',\n})\nexport class NeuListboxComponent implements ControlValueAccessor {\n readonly options = input<NeuListboxOption[]>([]);\n readonly label = input('');\n readonly ariaLabel = input('Options');\n readonly hint = input('');\n readonly emptyLabel = input('No options found');\n readonly multiple = input(false);\n readonly searchable = input(false);\n readonly searchPlaceholder = input('Search...');\n readonly disabled = input(false);\n\n readonly selectionChange = output<NeuListboxOption[]>();\n readonly itemTpl = contentChild(NeuListboxItemDirective);\n\n readonly query = signal('');\n readonly activeIndex = signal(0);\n readonly values = signal<string[]>([]);\n readonly cvaDisabled = signal(false);\n readonly labelId = `neu-listbox-label-${Math.random().toString(36).slice(2)}`;\n\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n readonly filteredOptions = computed(() => {\n const q = this.query().trim().toLowerCase();\n return q ? this.options().filter((option) => option.label.toLowerCase().includes(q)) : this.options();\n });\n\n private onChange: (value: string | string[] | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: string | string[] | null): void {\n this.values.set(Array.isArray(value) ? value : value ? [value] : []);\n }\n\n registerOnChange(fn: (value: string | string[] | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n isSelected(value: string): boolean {\n return this.values().includes(value);\n }\n\n toggleOption(option: NeuListboxOption): void {\n if (option.disabled || this.isDisabled()) {\n return;\n }\n const next = this.multiple()\n ? this.isSelected(option.value)\n ? this.values().filter((value) => value !== option.value)\n : [...this.values(), option.value]\n : [option.value];\n this.values.set(next);\n this.onTouched();\n this.onChange(this.multiple() ? next : (next[0] ?? null));\n this.selectionChange.emit(this.options().filter((item) => next.includes(item.value)));\n }\n\n onKeyDown(event: KeyboardEvent): void {\n const enabled = this.filteredOptions().filter((option) => !option.disabled);\n if (!enabled.length) {\n return;\n }\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n const step = event.key === 'ArrowDown' ? 1 : -1;\n this.activeIndex.set(\n Math.max(0, Math.min(this.filteredOptions().length - 1, this.activeIndex() + step)),\n );\n }\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n const option = this.filteredOptions()[this.activeIndex()];\n if (option) {\n this.toggleOption(option);\n }\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}