@neural-ui/core 1.7.5 → 1.8.0

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 (83) hide show
  1. package/fesm2022/neural-ui-core-accordion.mjs +22 -8
  2. package/fesm2022/neural-ui-core-accordion.mjs.map +1 -1
  3. package/fesm2022/neural-ui-core-alert.mjs +1 -1
  4. package/fesm2022/neural-ui-core-alert.mjs.map +1 -1
  5. package/fesm2022/neural-ui-core-autocomplete.mjs +50 -9
  6. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
  7. package/fesm2022/neural-ui-core-button.mjs +1 -1
  8. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  9. package/fesm2022/neural-ui-core-calendar.mjs +26 -18
  10. package/fesm2022/neural-ui-core-calendar.mjs.map +1 -1
  11. package/fesm2022/neural-ui-core-card.mjs +2 -2
  12. package/fesm2022/neural-ui-core-card.mjs.map +1 -1
  13. package/fesm2022/neural-ui-core-command-palette.mjs +22 -8
  14. package/fesm2022/neural-ui-core-command-palette.mjs.map +1 -1
  15. package/fesm2022/neural-ui-core-context-menu.mjs +24 -8
  16. package/fesm2022/neural-ui-core-context-menu.mjs.map +1 -1
  17. package/fesm2022/neural-ui-core-empty-state.mjs +1 -1
  18. package/fesm2022/neural-ui-core-empty-state.mjs.map +1 -1
  19. package/fesm2022/neural-ui-core-icon.mjs +9 -2
  20. package/fesm2022/neural-ui-core-icon.mjs.map +1 -1
  21. package/fesm2022/neural-ui-core-inline-editor.mjs +1 -1
  22. package/fesm2022/neural-ui-core-inline-editor.mjs.map +1 -1
  23. package/fesm2022/neural-ui-core-input-mask.mjs +2 -2
  24. package/fesm2022/neural-ui-core-input-mask.mjs.map +1 -1
  25. package/fesm2022/neural-ui-core-input.mjs +1 -1
  26. package/fesm2022/neural-ui-core-input.mjs.map +1 -1
  27. package/fesm2022/neural-ui-core-listbox.mjs +50 -5
  28. package/fesm2022/neural-ui-core-listbox.mjs.map +1 -1
  29. package/fesm2022/neural-ui-core-menu.mjs +38 -16
  30. package/fesm2022/neural-ui-core-menu.mjs.map +1 -1
  31. package/fesm2022/neural-ui-core-modal.mjs +1 -1
  32. package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
  33. package/fesm2022/neural-ui-core-multiselect.mjs +67 -7
  34. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  35. package/fesm2022/neural-ui-core-nav.mjs +1 -1
  36. package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
  37. package/fesm2022/neural-ui-core-password.mjs +42 -6
  38. package/fesm2022/neural-ui-core-password.mjs.map +1 -1
  39. package/fesm2022/neural-ui-core-pick-list.mjs +43 -16
  40. package/fesm2022/neural-ui-core-pick-list.mjs.map +1 -1
  41. package/fesm2022/neural-ui-core-select.mjs +64 -5
  42. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  43. package/fesm2022/neural-ui-core-sidebar.mjs +1 -1
  44. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  45. package/fesm2022/neural-ui-core-split-button.mjs +22 -8
  46. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  47. package/fesm2022/neural-ui-core-stats-card.mjs +1 -1
  48. package/fesm2022/neural-ui-core-stats-card.mjs.map +1 -1
  49. package/fesm2022/neural-ui-core-table.mjs +1 -1
  50. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  51. package/fesm2022/neural-ui-core-tabs.mjs +22 -9
  52. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
  53. package/fesm2022/neural-ui-core-tags.mjs +40 -13
  54. package/fesm2022/neural-ui-core-tags.mjs.map +1 -1
  55. package/fesm2022/neural-ui-core-timeline.mjs +39 -10
  56. package/fesm2022/neural-ui-core-timeline.mjs.map +1 -1
  57. package/fesm2022/neural-ui-core-toast.mjs +1 -1
  58. package/fesm2022/neural-ui-core-toast.mjs.map +1 -1
  59. package/fesm2022/neural-ui-core-toggle-button-group.mjs +22 -8
  60. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
  61. package/fesm2022/neural-ui-core-tree-select.mjs +86 -12
  62. package/fesm2022/neural-ui-core-tree-select.mjs.map +1 -1
  63. package/fesm2022/neural-ui-core-tree.mjs +21 -6
  64. package/fesm2022/neural-ui-core-tree.mjs.map +1 -1
  65. package/package.json +1 -1
  66. package/types/neural-ui-core-accordion.d.ts +16 -2
  67. package/types/neural-ui-core-autocomplete.d.ts +23 -2
  68. package/types/neural-ui-core-calendar.d.ts +18 -3
  69. package/types/neural-ui-core-command-palette.d.ts +24 -10
  70. package/types/neural-ui-core-context-menu.d.ts +17 -3
  71. package/types/neural-ui-core-icon.d.ts +5 -1
  72. package/types/neural-ui-core-listbox.d.ts +23 -2
  73. package/types/neural-ui-core-menu.d.ts +23 -3
  74. package/types/neural-ui-core-multiselect.d.ts +33 -2
  75. package/types/neural-ui-core-pick-list.d.ts +32 -3
  76. package/types/neural-ui-core-select.d.ts +30 -2
  77. package/types/neural-ui-core-split-button.d.ts +15 -3
  78. package/types/neural-ui-core-tabs.d.ts +16 -3
  79. package/types/neural-ui-core-tags.d.ts +35 -4
  80. package/types/neural-ui-core-timeline.d.ts +27 -2
  81. package/types/neural-ui-core-toggle-button-group.d.ts +16 -2
  82. package/types/neural-ui-core-tree-select.d.ts +51 -3
  83. package/types/neural-ui-core-tree.d.ts +18 -3
@@ -1,9 +1,22 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, signal, computed, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
2
+ import { Directive, contentChild, input, output, signal, computed, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
3
3
  import { NgTemplateOutlet } from '@angular/common';
4
4
  import { NeuCheckboxComponent } from '@neural-ui/core/checkbox';
5
5
 
6
+ class NeuTreeNodeDirective {
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: NeuTreeNodeDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
12
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: NeuTreeNodeDirective, isStandalone: true, selector: "ng-template[neuTreeNode]", ngImport: i0 });
13
+ }
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTreeNodeDirective, decorators: [{
15
+ type: Directive,
16
+ args: [{ selector: 'ng-template[neuTreeNode]' }]
17
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
6
18
  class NeuTreeComponent {
19
+ nodeTpl = contentChild(NeuTreeNodeDirective, ...(ngDevMode ? [{ debugName: "nodeTpl" }] : /* istanbul ignore next */ []));
7
20
  nodes = input([], ...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
8
21
  selectable = input(false, ...(ngDevMode ? [{ debugName: "selectable" }] : /* istanbul ignore next */ []));
9
22
  searchable = input(false, ...(ngDevMode ? [{ debugName: "searchable" }] : /* istanbul ignore next */ []));
@@ -157,7 +170,7 @@ class NeuTreeComponent {
157
170
  return filtered;
158
171
  }
159
172
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
160
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuTreeComponent, isStandalone: true, selector: "neu-tree", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null }, expandLabel: { classPropertyName: "expandLabel", publicName: "expandLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseLabel: { classPropertyName: "collapseLabel", publicName: "collapseLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", expansionChange: "expansionChange", nodeClick: "nodeClick" }, ngImport: i0, template: `
173
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuTreeComponent, isStandalone: true, selector: "neu-tree", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null }, expandLabel: { classPropertyName: "expandLabel", publicName: "expandLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseLabel: { classPropertyName: "collapseLabel", publicName: "collapseLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", expansionChange: "expansionChange", nodeClick: "nodeClick" }, queries: [{ propertyName: "nodeTpl", first: true, predicate: NeuTreeNodeDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
161
174
  <div class="neu-tree">
162
175
  @if (searchable()) {
163
176
  <label class="neu-tree__search" [attr.aria-label]="searchPlaceholder()">
@@ -255,7 +268,7 @@ class NeuTreeComponent {
255
268
  [disabled]="node.disabled"
256
269
  (click)="activateNode(node)"
257
270
  >
258
- <span class="neu-tree__main">
271
+ @if (nodeTpl()) { <ng-container [ngTemplateOutlet]="nodeTpl()!.templateRef" [ngTemplateOutletContext]="{ $implicit: node, level, selected: isSelected(node.id), expanded: isRenderedExpanded(node), toggle: toggleNode.bind(this, node) }" /> } @else { <span class="neu-tree__main">
259
272
  <span class="neu-tree__label">{{ node.label }}</span>
260
273
  @if (node.badge) {
261
274
  <span class="neu-tree__badge">{{ node.badge }}</span>
@@ -264,6 +277,7 @@ class NeuTreeComponent {
264
277
  @if (node.description) {
265
278
  <span class="neu-tree__description">{{ node.description }}</span>
266
279
  }
280
+ }
267
281
  </button>
268
282
  </div>
269
283
 
@@ -380,7 +394,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
380
394
  [disabled]="node.disabled"
381
395
  (click)="activateNode(node)"
382
396
  >
383
- <span class="neu-tree__main">
397
+ @if (nodeTpl()) { <ng-container [ngTemplateOutlet]="nodeTpl()!.templateRef" [ngTemplateOutletContext]="{ $implicit: node, level, selected: isSelected(node.id), expanded: isRenderedExpanded(node), toggle: toggleNode.bind(this, node) }" /> } @else { <span class="neu-tree__main">
384
398
  <span class="neu-tree__label">{{ node.label }}</span>
385
399
  @if (node.badge) {
386
400
  <span class="neu-tree__badge">{{ node.badge }}</span>
@@ -389,6 +403,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
389
403
  @if (node.description) {
390
404
  <span class="neu-tree__description">{{ node.description }}</span>
391
405
  }
406
+ }
392
407
  </button>
393
408
  </div>
394
409
 
@@ -404,11 +419,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
404
419
  }
405
420
  </ng-template>
406
421
  `, styles: [".neu-tree{display:flex;flex-direction:column;gap:.75rem;min-width:0}.neu-tree__search{position:relative;display:flex;align-items:center}.neu-tree__search-icon{position:absolute;left:.875rem;width:.9375rem;height:.9375rem;color:var(--neu-text-muted);pointer-events:none}.neu-tree__search-input{width:100%;min-height:2.625rem;border:1px solid var(--neu-border);border-radius:var(--neu-radius-lg, 14px);background:var(--neu-surface);color:var(--neu-text);padding:.6875rem .875rem .6875rem 2.4rem;outline:none;transition:border-color .16s ease,box-shadow .16s ease,background-color .16s ease}.neu-tree__search-input::placeholder{color:var(--neu-text-muted)}.neu-tree__search-input:focus{border-color:color-mix(in srgb,var(--neu-primary) 62%,var(--neu-border));box-shadow:0 0 0 3px color-mix(in srgb,var(--neu-primary) 16%,transparent)}.neu-tree__list{list-style:none;margin:0;padding:0}.neu-tree__list--root{display:flex;flex-direction:column;gap:.375rem}.neu-tree__node{position:relative}.neu-tree__row{display:flex;align-items:flex-start;gap:.5rem;min-width:0;border-radius:calc(var(--neu-radius-lg, 14px) - 2px);transition:background-color .16s ease,border-color .16s ease,box-shadow .16s ease}.neu-tree__row:hover{background:color-mix(in srgb,var(--neu-primary) 5%,var(--neu-surface))}.neu-tree__row--selected{background:color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 20%,var(--neu-border))}.neu-tree__row--disabled{opacity:.6}.neu-tree__toggle{flex:0 0 auto;width:1.75rem;height:1.75rem;margin-top:.4rem;border:0;border-radius:999px;background:transparent;color:var(--neu-text-muted);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background-color .16s ease,color .16s ease,transform .16s ease}.neu-tree__toggle svg{width:.95rem;height:.95rem;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;transition:transform .16s ease}.neu-tree__toggle:hover{background:color-mix(in srgb,var(--neu-primary) 9%,transparent);color:var(--neu-primary)}.neu-tree__toggle--open svg{transform:rotate(90deg)}.neu-tree__toggle--placeholder{cursor:default}.neu-tree__checkbox{flex:0 0 auto;margin:.8rem 0 0}.neu-tree__checkbox .neu-checkbox{gap:0}.neu-tree__checkbox .neu-checkbox__box{width:1rem;height:1rem}.neu-tree__content{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:.125rem;border:0;background:transparent;text-align:left;padding:.55rem .75rem .6rem 0;color:inherit;cursor:pointer}.neu-tree__main{display:inline-flex;align-items:center;gap:.5rem;min-width:0}.neu-tree__label{font-size:.9375rem;font-weight:600;color:var(--neu-text)}.neu-tree__badge{display:inline-flex;align-items:center;min-height:1.25rem;padding:0 .45rem;border-radius:999px;background:color-mix(in srgb,var(--neu-primary) 12%,transparent);color:var(--neu-primary);font-size:.6875rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.neu-tree__description{color:var(--neu-text-muted);font-size:.8125rem;line-height:1.45}.neu-tree__empty{border:1px dashed var(--neu-border);border-radius:var(--neu-radius-lg, 14px);background:color-mix(in srgb,var(--neu-surface-2) 72%,transparent);color:var(--neu-text-muted);padding:1rem 1.125rem;font-size:.875rem}.neu-tree__node>.neu-tree__list{margin-top:.125rem}\n"] }]
407
- }], ctorParameters: () => [], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyLabel", required: false }] }], expandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandLabel", required: false }] }], collapseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseLabel", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], expansionChange: [{ type: i0.Output, args: ["expansionChange"] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }] } });
422
+ }], ctorParameters: () => [], propDecorators: { nodeTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NeuTreeNodeDirective), { isSignal: true }] }], nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyLabel", required: false }] }], expandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandLabel", required: false }] }], collapseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseLabel", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], expansionChange: [{ type: i0.Output, args: ["expansionChange"] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }] } });
408
423
 
409
424
  /**
410
425
  * Generated bundle index. Do not edit.
411
426
  */
412
427
 
413
- export { NeuTreeComponent };
428
+ export { NeuTreeComponent, NeuTreeNodeDirective };
414
429
  //# sourceMappingURL=neural-ui-core-tree.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-tree.mjs","sources":["../../../../projects/ui-core/tree/neu-tree.component.ts","../../../../projects/ui-core/tree/neural-ui-core-tree.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n output,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { NeuCheckboxComponent } from '@neural-ui/core/checkbox';\n\nexport interface NeuTreeNode<T = unknown> {\n id: string;\n label: string;\n description?: string;\n badge?: string;\n children?: NeuTreeNode<T>[];\n disabled?: boolean;\n expanded?: boolean;\n selectable?: boolean;\n data?: T;\n}\n\nexport type NeuTreeSelectionMode = 'single' | 'multiple';\n\n@Component({\n selector: 'neu-tree',\n standalone: true,\n imports: [NgTemplateOutlet, NeuCheckboxComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"neu-tree\">\n @if (searchable()) {\n <label class=\"neu-tree__search\" [attr.aria-label]=\"searchPlaceholder()\">\n <svg\n class=\"neu-tree__search-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\"></circle>\n <path d=\"m20 20-3.5-3.5\"></path>\n </svg>\n <input\n class=\"neu-tree__search-input\"\n type=\"search\"\n [value]=\"searchQuery()\"\n [attr.placeholder]=\"searchPlaceholder()\"\n (input)=\"onSearch($event)\"\n />\n </label>\n }\n\n @if (visibleNodes().length) {\n <ul\n class=\"neu-tree__list neu-tree__list--root\"\n role=\"tree\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-multiselectable]=\"\n selectable() && selectionMode() === 'multiple' ? 'true' : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ $implicit: visibleNodes(), level: 1 }\"\n />\n </ul>\n } @else {\n <div class=\"neu-tree__empty\">{{ emptyLabel() }}</div>\n }\n </div>\n\n <ng-template #treeNodes let-nodes let-level=\"level\">\n @for (node of nodes; track node.id) {\n <li\n class=\"neu-tree__node\"\n role=\"treeitem\"\n [attr.aria-level]=\"level\"\n [attr.aria-expanded]=\"hasChildren(node) ? isRenderedExpanded(node) : null\"\n [attr.aria-selected]=\"canSelect(node) ? isSelected(node.id) : null\"\n [attr.aria-disabled]=\"node.disabled ? 'true' : null\"\n >\n <div\n class=\"neu-tree__row\"\n [class.neu-tree__row--selected]=\"isSelected(node.id)\"\n [class.neu-tree__row--disabled]=\"node.disabled\"\n [style.padding-inline-start.px]=\"(level - 1) * indentSize() + 6\"\n >\n @if (hasChildren(node)) {\n <button\n class=\"neu-tree__toggle\"\n type=\"button\"\n [class.neu-tree__toggle--open]=\"isRenderedExpanded(node)\"\n [attr.aria-label]=\"isRenderedExpanded(node) ? collapseLabel() : expandLabel()\"\n (click)=\"toggleNode(node, $event)\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"m7 5 6 5-6 5\" />\n </svg>\n </button>\n } @else {\n <span\n class=\"neu-tree__toggle neu-tree__toggle--placeholder\"\n aria-hidden=\"true\"\n ></span>\n }\n\n @if (canSelect(node) && selectionMode() === 'multiple') {\n <neu-checkbox\n class=\"neu-tree__checkbox\"\n [checked]=\"isSelected(node.id)\"\n [disabled]=\"node.disabled\"\n [ariaLabel]=\"'Select ' + node.label\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"onCheckboxChange(node, $event)\"\n />\n }\n\n <button\n class=\"neu-tree__content\"\n type=\"button\"\n [disabled]=\"node.disabled\"\n (click)=\"activateNode(node)\"\n >\n <span class=\"neu-tree__main\">\n <span class=\"neu-tree__label\">{{ node.label }}</span>\n @if (node.badge) {\n <span class=\"neu-tree__badge\">{{ node.badge }}</span>\n }\n </span>\n @if (node.description) {\n <span class=\"neu-tree__description\">{{ node.description }}</span>\n }\n </button>\n </div>\n\n @if (hasChildren(node) && isRenderedExpanded(node)) {\n <ul class=\"neu-tree__list\" role=\"group\">\n <ng-container\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ $implicit: node.children ?? [], level: level + 1 }\"\n />\n </ul>\n }\n </li>\n }\n </ng-template>\n `,\n styleUrl: './neu-tree.component.scss',\n})\nexport class NeuTreeComponent {\n nodes = input<NeuTreeNode[]>([]);\n selectable = input(false);\n searchable = input(false);\n selectionMode = input<NeuTreeSelectionMode>('single');\n indentSize = input(18);\n ariaLabel = input('Tree');\n searchPlaceholder = input('Search nodes');\n emptyLabel = input('No nodes available');\n expandLabel = input('Expand node');\n collapseLabel = input('Collapse node');\n\n selectionChange = output<NeuTreeNode[]>();\n expansionChange = output<string[]>();\n nodeClick = output<NeuTreeNode>();\n\n readonly searchQuery = signal('');\n\n private readonly expandedKeys = signal<Set<string>>(new Set());\n private readonly selectedKeys = signal<Set<string>>(new Set());\n\n readonly visibleNodes = computed(() => {\n const query = this.searchQuery().trim().toLowerCase();\n if (!query) {\n return this.nodes();\n }\n\n return this.filterNodes(this.nodes(), query);\n });\n\n constructor() {\n effect(() => {\n const nextExpanded = this.collectExpandedKeys(this.nodes());\n this.expandedKeys.set(nextExpanded);\n this.selectedKeys.set(new Set());\n this.searchQuery.set('');\n });\n }\n\n hasChildren(node: NeuTreeNode): boolean {\n return !!node.children?.length;\n }\n\n canSelect(node: NeuTreeNode): boolean {\n return this.selectable() && node.selectable !== false;\n }\n\n isExpanded(nodeId: string): boolean {\n return this.expandedKeys().has(nodeId);\n }\n\n isRenderedExpanded(node: NeuTreeNode): boolean {\n if (this.searchQuery().trim()) {\n return node.expanded ?? this.isExpanded(node.id);\n }\n\n return this.isExpanded(node.id);\n }\n\n isSelected(nodeId: string): boolean {\n return this.selectedKeys().has(nodeId);\n }\n\n onSearch(event: Event): void {\n const target = event.target as HTMLInputElement;\n this.searchQuery.set(target.value);\n }\n\n toggleNode(node: NeuTreeNode, event?: Event): void {\n event?.stopPropagation();\n if (node.disabled || !this.hasChildren(node)) {\n return;\n }\n\n const next = new Set(this.expandedKeys());\n if (next.has(node.id)) {\n next.delete(node.id);\n } else {\n next.add(node.id);\n }\n\n this.expandedKeys.set(next);\n this.expansionChange.emit([...next]);\n }\n\n activateNode(node: NeuTreeNode): void {\n if (node.disabled) {\n return;\n }\n\n this.nodeClick.emit(node);\n\n if (!this.canSelect(node)) {\n return;\n }\n\n if (this.selectionMode() === 'multiple') {\n const checked = !this.isSelected(node.id);\n this.updateSelection(node, checked);\n return;\n }\n\n this.updateSelection(node, true);\n }\n\n onCheckboxChange(node: NeuTreeNode, checkedOrEvent: boolean | Event): void {\n const checked =\n typeof checkedOrEvent === 'boolean'\n ? checkedOrEvent\n : (checkedOrEvent.target as HTMLInputElement).checked;\n this.updateSelection(node, checked);\n }\n\n private updateSelection(node: NeuTreeNode, checked: boolean): void {\n if (node.disabled || !this.canSelect(node)) {\n return;\n }\n\n const next = new Set(this.selectedKeys());\n\n if (this.selectionMode() === 'single') {\n next.clear();\n if (checked) {\n next.add(node.id);\n }\n } else if (checked) {\n next.add(node.id);\n } else {\n next.delete(node.id);\n }\n\n this.selectedKeys.set(next);\n this.selectionChange.emit(this.collectSelectedNodes(this.nodes(), next));\n }\n\n private collectExpandedKeys(nodes: NeuTreeNode[]): Set<string> {\n const expanded = new Set<string>();\n for (const node of nodes) {\n if (node.expanded) {\n expanded.add(node.id);\n }\n if (node.children?.length) {\n for (const childId of this.collectExpandedKeys(node.children)) {\n expanded.add(childId);\n }\n }\n }\n return expanded;\n }\n\n private collectSelectedNodes(nodes: NeuTreeNode[], selected: Set<string>): NeuTreeNode[] {\n const result: NeuTreeNode[] = [];\n for (const node of nodes) {\n if (selected.has(node.id)) {\n result.push(node);\n }\n if (node.children?.length) {\n result.push(...this.collectSelectedNodes(node.children, selected));\n }\n }\n return result;\n }\n\n private filterNodes(nodes: NeuTreeNode[], query: string): NeuTreeNode[] {\n const filtered: NeuTreeNode[] = [];\n for (const node of nodes) {\n const children = node.children?.length ? this.filterNodes(node.children, query) : [];\n const matches =\n node.label.toLowerCase().includes(query) ||\n node.description?.toLowerCase().includes(query) ||\n node.badge?.toLowerCase().includes(query);\n\n if (matches || children.length) {\n filtered.push({\n ...node,\n children,\n expanded: children.length ? true : node.expanded,\n });\n }\n }\n return filtered;\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-tree.mjs","sources":["../../../../projects/ui-core/tree/neu-tree.component.ts","../../../../projects/ui-core/tree/neural-ui-core-tree.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Directive,\n TemplateRef,\n computed,\n contentChild,\n effect,\n input,\n output,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { NeuCheckboxComponent } from '@neural-ui/core/checkbox';\n\nexport interface NeuTreeNode<T = unknown> {\n id: string;\n label: string;\n description?: string;\n badge?: string;\n children?: NeuTreeNode<T>[];\n disabled?: boolean;\n expanded?: boolean;\n selectable?: boolean;\n data?: T;\n}\n\nexport type NeuTreeSelectionMode = 'single' | 'multiple';\nexport interface NeuTreeNodeTemplateContext { $implicit: NeuTreeNode; level: number; selected: boolean; expanded: boolean; toggle: () => void; }\n@Directive({ selector: 'ng-template[neuTreeNode]' })\nexport class NeuTreeNodeDirective { constructor(readonly templateRef: TemplateRef<NeuTreeNodeTemplateContext>) {} }\n\n@Component({\n selector: 'neu-tree',\n standalone: true,\n imports: [NgTemplateOutlet, NeuCheckboxComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"neu-tree\">\n @if (searchable()) {\n <label class=\"neu-tree__search\" [attr.aria-label]=\"searchPlaceholder()\">\n <svg\n class=\"neu-tree__search-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\"></circle>\n <path d=\"m20 20-3.5-3.5\"></path>\n </svg>\n <input\n class=\"neu-tree__search-input\"\n type=\"search\"\n [value]=\"searchQuery()\"\n [attr.placeholder]=\"searchPlaceholder()\"\n (input)=\"onSearch($event)\"\n />\n </label>\n }\n\n @if (visibleNodes().length) {\n <ul\n class=\"neu-tree__list neu-tree__list--root\"\n role=\"tree\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-multiselectable]=\"\n selectable() && selectionMode() === 'multiple' ? 'true' : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ $implicit: visibleNodes(), level: 1 }\"\n />\n </ul>\n } @else {\n <div class=\"neu-tree__empty\">{{ emptyLabel() }}</div>\n }\n </div>\n\n <ng-template #treeNodes let-nodes let-level=\"level\">\n @for (node of nodes; track node.id) {\n <li\n class=\"neu-tree__node\"\n role=\"treeitem\"\n [attr.aria-level]=\"level\"\n [attr.aria-expanded]=\"hasChildren(node) ? isRenderedExpanded(node) : null\"\n [attr.aria-selected]=\"canSelect(node) ? isSelected(node.id) : null\"\n [attr.aria-disabled]=\"node.disabled ? 'true' : null\"\n >\n <div\n class=\"neu-tree__row\"\n [class.neu-tree__row--selected]=\"isSelected(node.id)\"\n [class.neu-tree__row--disabled]=\"node.disabled\"\n [style.padding-inline-start.px]=\"(level - 1) * indentSize() + 6\"\n >\n @if (hasChildren(node)) {\n <button\n class=\"neu-tree__toggle\"\n type=\"button\"\n [class.neu-tree__toggle--open]=\"isRenderedExpanded(node)\"\n [attr.aria-label]=\"isRenderedExpanded(node) ? collapseLabel() : expandLabel()\"\n (click)=\"toggleNode(node, $event)\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"m7 5 6 5-6 5\" />\n </svg>\n </button>\n } @else {\n <span\n class=\"neu-tree__toggle neu-tree__toggle--placeholder\"\n aria-hidden=\"true\"\n ></span>\n }\n\n @if (canSelect(node) && selectionMode() === 'multiple') {\n <neu-checkbox\n class=\"neu-tree__checkbox\"\n [checked]=\"isSelected(node.id)\"\n [disabled]=\"node.disabled\"\n [ariaLabel]=\"'Select ' + node.label\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"onCheckboxChange(node, $event)\"\n />\n }\n\n <button\n class=\"neu-tree__content\"\n type=\"button\"\n [disabled]=\"node.disabled\"\n (click)=\"activateNode(node)\"\n >\n @if (nodeTpl()) { <ng-container [ngTemplateOutlet]=\"nodeTpl()!.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: node, level, selected: isSelected(node.id), expanded: isRenderedExpanded(node), toggle: toggleNode.bind(this, node) }\" /> } @else { <span class=\"neu-tree__main\">\n <span class=\"neu-tree__label\">{{ node.label }}</span>\n @if (node.badge) {\n <span class=\"neu-tree__badge\">{{ node.badge }}</span>\n }\n </span>\n @if (node.description) {\n <span class=\"neu-tree__description\">{{ node.description }}</span>\n }\n }\n </button>\n </div>\n\n @if (hasChildren(node) && isRenderedExpanded(node)) {\n <ul class=\"neu-tree__list\" role=\"group\">\n <ng-container\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ $implicit: node.children ?? [], level: level + 1 }\"\n />\n </ul>\n }\n </li>\n }\n </ng-template>\n `,\n styleUrl: './neu-tree.component.scss',\n})\nexport class NeuTreeComponent {\n readonly nodeTpl = contentChild(NeuTreeNodeDirective);\n nodes = input<NeuTreeNode[]>([]);\n selectable = input(false);\n searchable = input(false);\n selectionMode = input<NeuTreeSelectionMode>('single');\n indentSize = input(18);\n ariaLabel = input('Tree');\n searchPlaceholder = input('Search nodes');\n emptyLabel = input('No nodes available');\n expandLabel = input('Expand node');\n collapseLabel = input('Collapse node');\n\n selectionChange = output<NeuTreeNode[]>();\n expansionChange = output<string[]>();\n nodeClick = output<NeuTreeNode>();\n\n readonly searchQuery = signal('');\n\n private readonly expandedKeys = signal<Set<string>>(new Set());\n private readonly selectedKeys = signal<Set<string>>(new Set());\n\n readonly visibleNodes = computed(() => {\n const query = this.searchQuery().trim().toLowerCase();\n if (!query) {\n return this.nodes();\n }\n\n return this.filterNodes(this.nodes(), query);\n });\n\n constructor() {\n effect(() => {\n const nextExpanded = this.collectExpandedKeys(this.nodes());\n this.expandedKeys.set(nextExpanded);\n this.selectedKeys.set(new Set());\n this.searchQuery.set('');\n });\n }\n\n hasChildren(node: NeuTreeNode): boolean {\n return !!node.children?.length;\n }\n\n canSelect(node: NeuTreeNode): boolean {\n return this.selectable() && node.selectable !== false;\n }\n\n isExpanded(nodeId: string): boolean {\n return this.expandedKeys().has(nodeId);\n }\n\n isRenderedExpanded(node: NeuTreeNode): boolean {\n if (this.searchQuery().trim()) {\n return node.expanded ?? this.isExpanded(node.id);\n }\n\n return this.isExpanded(node.id);\n }\n\n isSelected(nodeId: string): boolean {\n return this.selectedKeys().has(nodeId);\n }\n\n onSearch(event: Event): void {\n const target = event.target as HTMLInputElement;\n this.searchQuery.set(target.value);\n }\n\n toggleNode(node: NeuTreeNode, event?: Event): void {\n event?.stopPropagation();\n if (node.disabled || !this.hasChildren(node)) {\n return;\n }\n\n const next = new Set(this.expandedKeys());\n if (next.has(node.id)) {\n next.delete(node.id);\n } else {\n next.add(node.id);\n }\n\n this.expandedKeys.set(next);\n this.expansionChange.emit([...next]);\n }\n\n activateNode(node: NeuTreeNode): void {\n if (node.disabled) {\n return;\n }\n\n this.nodeClick.emit(node);\n\n if (!this.canSelect(node)) {\n return;\n }\n\n if (this.selectionMode() === 'multiple') {\n const checked = !this.isSelected(node.id);\n this.updateSelection(node, checked);\n return;\n }\n\n this.updateSelection(node, true);\n }\n\n onCheckboxChange(node: NeuTreeNode, checkedOrEvent: boolean | Event): void {\n const checked =\n typeof checkedOrEvent === 'boolean'\n ? checkedOrEvent\n : (checkedOrEvent.target as HTMLInputElement).checked;\n this.updateSelection(node, checked);\n }\n\n private updateSelection(node: NeuTreeNode, checked: boolean): void {\n if (node.disabled || !this.canSelect(node)) {\n return;\n }\n\n const next = new Set(this.selectedKeys());\n\n if (this.selectionMode() === 'single') {\n next.clear();\n if (checked) {\n next.add(node.id);\n }\n } else if (checked) {\n next.add(node.id);\n } else {\n next.delete(node.id);\n }\n\n this.selectedKeys.set(next);\n this.selectionChange.emit(this.collectSelectedNodes(this.nodes(), next));\n }\n\n private collectExpandedKeys(nodes: NeuTreeNode[]): Set<string> {\n const expanded = new Set<string>();\n for (const node of nodes) {\n if (node.expanded) {\n expanded.add(node.id);\n }\n if (node.children?.length) {\n for (const childId of this.collectExpandedKeys(node.children)) {\n expanded.add(childId);\n }\n }\n }\n return expanded;\n }\n\n private collectSelectedNodes(nodes: NeuTreeNode[], selected: Set<string>): NeuTreeNode[] {\n const result: NeuTreeNode[] = [];\n for (const node of nodes) {\n if (selected.has(node.id)) {\n result.push(node);\n }\n if (node.children?.length) {\n result.push(...this.collectSelectedNodes(node.children, selected));\n }\n }\n return result;\n }\n\n private filterNodes(nodes: NeuTreeNode[], query: string): NeuTreeNode[] {\n const filtered: NeuTreeNode[] = [];\n for (const node of nodes) {\n const children = node.children?.length ? this.filterNodes(node.children, query) : [];\n const matches =\n node.label.toLowerCase().includes(query) ||\n node.description?.toLowerCase().includes(query) ||\n node.badge?.toLowerCase().includes(query);\n\n if (matches || children.length) {\n filtered.push({\n ...node,\n children,\n expanded: children.length ? true : node.expanded,\n });\n }\n }\n return filtered;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neural-ui/core",
3
- "version": "1.7.5",
3
+ "version": "1.8.0",
4
4
  "description": "Modern Angular UI component library built with signals, standalone components, and OnPush change detection.",
5
5
  "author": "PedroMorenoTrujillo",
6
6
  "keywords": [
@@ -1,4 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
2
3
  import { SafeHtml } from '@angular/platform-browser';
3
4
 
4
5
  interface NeuAccordionItem {
@@ -13,6 +14,18 @@ interface NeuAccordionItem {
13
14
  /** Deshabilita este panel / Disables this panel */
14
15
  disabled?: boolean;
15
16
  }
17
+ declare class NeuAccordionHeaderDirective {
18
+ readonly templateRef: TemplateRef<{
19
+ $implicit: NeuAccordionItem;
20
+ expanded: boolean;
21
+ }>;
22
+ constructor(templateRef: TemplateRef<{
23
+ $implicit: NeuAccordionItem;
24
+ expanded: boolean;
25
+ }>);
26
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAccordionHeaderDirective, never>;
27
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuAccordionHeaderDirective, "ng-template[neuAccordionHeader]", never, {}, {}, never, never, true, never>;
28
+ }
16
29
  /**
17
30
  * NeuralUI Accordion Component
18
31
  *
@@ -24,6 +37,7 @@ interface NeuAccordionItem {
24
37
  * <neu-accordion [items]="items" [multiple]="true" />
25
38
  */
26
39
  declare class NeuAccordionComponent {
40
+ readonly headerTpl: _angular_core.Signal<NeuAccordionHeaderDirective | undefined>;
27
41
  private readonly _sanitizer;
28
42
  /** Lista de paneles / Panel list */
29
43
  items: _angular_core.InputSignal<NeuAccordionItem[]>;
@@ -48,8 +62,8 @@ declare class NeuAccordionComponent {
48
62
  sanitize(html: string): SafeHtml;
49
63
  toggle(id: string): void;
50
64
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAccordionComponent, never>;
51
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuAccordionComponent, "neu-accordion", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; }, { "panelToggle": "panelToggle"; }, never, never, true, never>;
65
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuAccordionComponent, "neu-accordion", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; }, { "panelToggle": "panelToggle"; }, ["headerTpl"], never, true, never>;
52
66
  }
53
67
 
54
- export { NeuAccordionComponent };
68
+ export { NeuAccordionComponent, NeuAccordionHeaderDirective };
55
69
  export type { NeuAccordionItem };
@@ -22,6 +22,24 @@ declare class NeuAutocompleteItemDirective {
22
22
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAutocompleteItemDirective, never>;
23
23
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuAutocompleteItemDirective, "ng-template[neuAutocompleteItem]", never, {}, {}, never, never, true, never>;
24
24
  }
25
+ declare class NeuAutocompleteHeaderDirective {
26
+ readonly templateRef: TemplateRef<void>;
27
+ constructor(templateRef: TemplateRef<void>);
28
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAutocompleteHeaderDirective, never>;
29
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuAutocompleteHeaderDirective, "ng-template[neuAutocompleteHeader]", never, {}, {}, never, never, true, never>;
30
+ }
31
+ declare class NeuAutocompleteFooterDirective {
32
+ readonly templateRef: TemplateRef<void>;
33
+ constructor(templateRef: TemplateRef<void>);
34
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAutocompleteFooterDirective, never>;
35
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuAutocompleteFooterDirective, "ng-template[neuAutocompleteFooter]", never, {}, {}, never, never, true, never>;
36
+ }
37
+ declare class NeuAutocompleteEmptyDirective {
38
+ readonly templateRef: TemplateRef<void>;
39
+ constructor(templateRef: TemplateRef<void>);
40
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAutocompleteEmptyDirective, never>;
41
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuAutocompleteEmptyDirective, "ng-template[neuAutocompleteEmpty]", never, {}, {}, never, never, true, never>;
42
+ }
25
43
  /**
26
44
  * NeuralUI Autocomplete
27
45
  *
@@ -62,6 +80,9 @@ declare class NeuAutocompleteComponent implements ControlValueAccessor {
62
80
  /** Emitido al cambiar el texto del input / Emitted on query change */
63
81
  readonly queryChange: _angular_core.OutputEmitterRef<string>;
64
82
  readonly itemTpl: _angular_core.Signal<NeuAutocompleteItemDirective | undefined>;
83
+ readonly headerTpl: _angular_core.Signal<NeuAutocompleteHeaderDirective | undefined>;
84
+ readonly footerTpl: _angular_core.Signal<NeuAutocompleteFooterDirective | undefined>;
85
+ readonly emptyTpl: _angular_core.Signal<NeuAutocompleteEmptyDirective | undefined>;
65
86
  readonly _id: string;
66
87
  readonly _listId: string;
67
88
  readonly _query: _angular_core.WritableSignal<string>;
@@ -108,8 +129,8 @@ declare class NeuAutocompleteComponent implements ControlValueAccessor {
108
129
  registerOnTouched(fn: () => void): void;
109
130
  setDisabledState(d: boolean): void;
110
131
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAutocompleteComponent, never>;
111
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuAutocompleteComponent, "neu-autocomplete", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; "isSignal": true; }; "dropdown": { "alias": "dropdown"; "required": false; "isSignal": true; }; "dropdownAriaLabel": { "alias": "dropdownAriaLabel"; "required": false; "isSignal": true; }; "forceSelection": { "alias": "forceSelection"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "virtualScrollVisibleItems": { "alias": "virtualScrollVisibleItems"; "required": false; "isSignal": true; }; }, { "optionSelected": "optionSelected"; "queryChange": "queryChange"; }, ["itemTpl"], never, true, never>;
132
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuAutocompleteComponent, "neu-autocomplete", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; "isSignal": true; }; "dropdown": { "alias": "dropdown"; "required": false; "isSignal": true; }; "dropdownAriaLabel": { "alias": "dropdownAriaLabel"; "required": false; "isSignal": true; }; "forceSelection": { "alias": "forceSelection"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "virtualScrollVisibleItems": { "alias": "virtualScrollVisibleItems"; "required": false; "isSignal": true; }; }, { "optionSelected": "optionSelected"; "queryChange": "queryChange"; }, ["itemTpl", "headerTpl", "footerTpl", "emptyTpl"], never, true, never>;
112
133
  }
113
134
 
114
- export { NeuAutocompleteComponent, NeuAutocompleteItemDirective };
135
+ export { NeuAutocompleteComponent, NeuAutocompleteEmptyDirective, NeuAutocompleteFooterDirective, NeuAutocompleteHeaderDirective, NeuAutocompleteItemDirective };
115
136
  export type { NeuAutocompleteOption };
@@ -1,4 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
2
3
 
3
4
  type NeuCalendarView = 'month' | 'week';
4
5
  type NeuCalendarEventVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';
@@ -12,6 +13,19 @@ interface NeuCalendarEvent {
12
13
  allDay?: boolean;
13
14
  variant?: NeuCalendarEventVariant;
14
15
  }
16
+ type NeuCalendarEventView = 'month' | 'week' | 'agenda';
17
+ declare class NeuCalendarEventDirective {
18
+ readonly templateRef: TemplateRef<{
19
+ $implicit: NeuCalendarEvent;
20
+ view: NeuCalendarEventView;
21
+ }>;
22
+ constructor(templateRef: TemplateRef<{
23
+ $implicit: NeuCalendarEvent;
24
+ view: NeuCalendarEventView;
25
+ }>);
26
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuCalendarEventDirective, never>;
27
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuCalendarEventDirective, "ng-template[neuCalendarEvent]", never, {}, {}, never, never, true, never>;
28
+ }
15
29
  interface NeuCalendarLabels {
16
30
  previousButtonAriaLabel: string;
17
31
  nextButtonAriaLabel: string;
@@ -34,6 +48,7 @@ interface CalendarDayCell {
34
48
  events: NormalizedCalendarEvent[];
35
49
  }
36
50
  declare class NeuCalendarComponent {
51
+ readonly eventTpl: _angular_core.Signal<NeuCalendarEventDirective | undefined>;
37
52
  readonly events: _angular_core.InputSignal<NeuCalendarEvent[]>;
38
53
  readonly view: _angular_core.InputSignal<NeuCalendarView>;
39
54
  readonly selectedDate: _angular_core.InputSignal<string | Date>;
@@ -72,8 +87,8 @@ declare class NeuCalendarComponent {
72
87
  private monthVisibleEventLimit;
73
88
  private coerceDate;
74
89
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuCalendarComponent, never>;
75
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuCalendarComponent, "neu-calendar", never, { "events": { "alias": "events"; "required": false; "isSignal": true; }; "view": { "alias": "view"; "required": false; "isSignal": true; }; "selectedDate": { "alias": "selectedDate"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "maxVisibleEvents": { "alias": "maxVisibleEvents"; "required": false; "isSignal": true; }; "showHeader": { "alias": "showHeader"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "selectedDateChange": "selectedDateChange"; "dateSelect": "dateSelect"; "eventClick": "eventClick"; }, never, never, true, never>;
90
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuCalendarComponent, "neu-calendar", never, { "events": { "alias": "events"; "required": false; "isSignal": true; }; "view": { "alias": "view"; "required": false; "isSignal": true; }; "selectedDate": { "alias": "selectedDate"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "maxVisibleEvents": { "alias": "maxVisibleEvents"; "required": false; "isSignal": true; }; "showHeader": { "alias": "showHeader"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "selectedDateChange": "selectedDateChange"; "dateSelect": "dateSelect"; "eventClick": "eventClick"; }, ["eventTpl"], never, true, never>;
76
91
  }
77
92
 
78
- export { NeuCalendarComponent };
79
- export type { NeuCalendarEvent, NeuCalendarEventVariant, NeuCalendarLabelOverrides, NeuCalendarLabels, NeuCalendarView };
93
+ export { NeuCalendarComponent, NeuCalendarEventDirective };
94
+ export type { NeuCalendarEvent, NeuCalendarEventVariant, NeuCalendarEventView, NeuCalendarLabelOverrides, NeuCalendarLabels, NeuCalendarView };
@@ -1,4 +1,5 @@
1
- import * as _angular_core from '@angular/core';
1
+ import * as i0 from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
2
3
 
3
4
  interface NeuCommand {
4
5
  id: string;
@@ -12,6 +13,18 @@ interface NeuCommand {
12
13
  /** Handler invocado al seleccionar / Handler called on select */
13
14
  action: () => void;
14
15
  }
16
+ declare class NeuCommandPaletteItemDirective {
17
+ readonly templateRef: TemplateRef<{
18
+ $implicit: NeuCommand;
19
+ index: number;
20
+ }>;
21
+ constructor(templateRef: TemplateRef<{
22
+ $implicit: NeuCommand;
23
+ index: number;
24
+ }>);
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<NeuCommandPaletteItemDirective, never>;
26
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NeuCommandPaletteItemDirective, "ng-template[neuCommandPaletteItem]", never, {}, {}, never, never, true, never>;
27
+ }
15
28
  /**
16
29
  * NeuralUI CommandPaletteService
17
30
  *
@@ -23,16 +36,16 @@ interface NeuCommand {
23
36
  */
24
37
  declare class NeuCommandPaletteService {
25
38
  private readonly _commands;
26
- readonly isOpen: _angular_core.WritableSignal<boolean>;
27
- readonly query: _angular_core.WritableSignal<string>;
28
- readonly filteredCommands: _angular_core.Signal<NeuCommand[]>;
39
+ readonly isOpen: i0.WritableSignal<boolean>;
40
+ readonly query: i0.WritableSignal<string>;
41
+ readonly filteredCommands: i0.Signal<NeuCommand[]>;
29
42
  register(...commands: NeuCommand[]): void;
30
43
  unregister(...ids: string[]): void;
31
44
  open(): void;
32
45
  close(): void;
33
46
  execute(id: string): void;
34
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuCommandPaletteService, never>;
35
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<NeuCommandPaletteService>;
47
+ static ɵfac: i0.ɵɵFactoryDeclaration<NeuCommandPaletteService, never>;
48
+ static ɵprov: i0.ɵɵInjectableDeclaration<NeuCommandPaletteService>;
36
49
  }
37
50
  /**
38
51
  * NeuralUI CommandPalette Component
@@ -44,13 +57,14 @@ declare class NeuCommandPaletteService {
44
57
  * <neu-command-palette /> <!-- colócalo una vez en el root layout -->
45
58
  */
46
59
  declare class NeuCommandPaletteComponent {
60
+ readonly itemTpl: i0.Signal<NeuCommandPaletteItemDirective | undefined>;
47
61
  readonly _svc: NeuCommandPaletteService;
48
- readonly _activeIndex: _angular_core.WritableSignal<number>;
62
+ readonly _activeIndex: i0.WritableSignal<number>;
49
63
  _onDocKey(e: KeyboardEvent): void;
50
64
  _onInputKey(e: KeyboardEvent): void;
51
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuCommandPaletteComponent, never>;
52
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuCommandPaletteComponent, "neu-command-palette", never, {}, {}, never, never, true, never>;
65
+ static ɵfac: i0.ɵɵFactoryDeclaration<NeuCommandPaletteComponent, never>;
66
+ static ɵcmp: i0.ɵɵComponentDeclaration<NeuCommandPaletteComponent, "neu-command-palette", never, {}, {}, ["itemTpl"], never, true, never>;
53
67
  }
54
68
 
55
- export { NeuCommandPaletteComponent, NeuCommandPaletteService };
69
+ export { NeuCommandPaletteComponent, NeuCommandPaletteItemDirective, NeuCommandPaletteService };
56
70
  export type { NeuCommand };
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnDestroy } from '@angular/core';
2
+ import { OnDestroy, TemplateRef } from '@angular/core';
3
3
 
4
4
  interface NeuContextMenuItem {
5
5
  /** Key para identificar la acción / Key to identify the action */
@@ -15,11 +15,24 @@ interface NeuContextMenuItem {
15
15
  /** Variante de color / Color variant */
16
16
  variant?: 'default' | 'danger';
17
17
  }
18
+ declare class NeuContextMenuItemDirective {
19
+ readonly templateRef: TemplateRef<{
20
+ $implicit: NeuContextMenuItem;
21
+ }>;
22
+ constructor(templateRef: TemplateRef<{
23
+ $implicit: NeuContextMenuItem;
24
+ }>);
25
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuContextMenuItemDirective, never>;
26
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuContextMenuItemDirective, "ng-template[neuContextMenuItem]", never, {}, {}, never, never, true, never>;
27
+ }
18
28
  /**
19
29
  * NeuralUI ContextMenu Overlay Component (internal)
20
30
  */
21
31
  declare class NeuContextMenuOverlayComponent {
22
32
  readonly _items: _angular_core.WritableSignal<NeuContextMenuItem[]>;
33
+ itemTemplate: TemplateRef<{
34
+ $implicit: NeuContextMenuItem;
35
+ }> | null;
23
36
  _selectFn: ((item: NeuContextMenuItem) => void) | null;
24
37
  _escapeFn: (() => void) | null;
25
38
  select(item: NeuContextMenuItem): void;
@@ -38,6 +51,7 @@ declare class NeuContextMenuOverlayComponent {
38
51
  * </div>
39
52
  */
40
53
  declare class NeuContextMenuDirective implements OnDestroy {
54
+ readonly itemTpl: _angular_core.Signal<NeuContextMenuItemDirective | undefined>;
41
55
  /** Ítems del menú / Menu items */
42
56
  readonly neuContextMenu: _angular_core.InputSignal<NeuContextMenuItem[]>;
43
57
  /** Desactiva el menú / Disables the menu */
@@ -59,8 +73,8 @@ declare class NeuContextMenuDirective implements OnDestroy {
59
73
  private _close;
60
74
  ngOnDestroy(): void;
61
75
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuContextMenuDirective, never>;
62
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuContextMenuDirective, "[neuContextMenu]", ["neuContextMenu"], { "neuContextMenu": { "alias": "neuContextMenu"; "required": false; "isSignal": true; }; "neuContextMenuDisabled": { "alias": "neuContextMenuDisabled"; "required": false; "isSignal": true; }; }, { "menuItemClick": "menuItemClick"; "menuOpened": "menuOpened"; "menuClosed": "menuClosed"; }, never, never, true, never>;
76
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuContextMenuDirective, "[neuContextMenu]", ["neuContextMenu"], { "neuContextMenu": { "alias": "neuContextMenu"; "required": false; "isSignal": true; }; "neuContextMenuDisabled": { "alias": "neuContextMenuDisabled"; "required": false; "isSignal": true; }; }, { "menuItemClick": "menuItemClick"; "menuOpened": "menuOpened"; "menuClosed": "menuClosed"; }, ["itemTpl"], never, true, never>;
63
77
  }
64
78
 
65
- export { NeuContextMenuDirective, NeuContextMenuOverlayComponent };
79
+ export { NeuContextMenuDirective, NeuContextMenuItemDirective, NeuContextMenuOverlayComponent };
66
80
  export type { NeuContextMenuItem };
@@ -14,6 +14,10 @@ import * as _angular_core from '@angular/core';
14
14
  declare class NeuIconComponent {
15
15
  /** Nombre del icono registrado con provideIcons() / Icon name registered with provideIcons() */
16
16
  name: _angular_core.InputSignal<string>;
17
+ /** Los iconos son decorativos por defecto. Para exponer uno al lector de pantalla, usa decorative=false y ariaLabel. */
18
+ decorative: _angular_core.InputSignal<boolean>;
19
+ /** Nombre accesible obligatorio cuando decorative=false. */
20
+ ariaLabel: _angular_core.InputSignal<string>;
17
21
  /**
18
22
  * Grosor del trazo. Default '2' para estética fina y técnica.
19
23
  * Puede sobrescribirse por instancia.
@@ -27,7 +31,7 @@ declare class NeuIconComponent {
27
31
  /** Tamaño resuelto: usa el input `size` o cae al token CSS. / Resolved size: uses the `size` input or falls back to the CSS token. */
28
32
  readonly resolvedSize: _angular_core.Signal<string>;
29
33
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuIconComponent, never>;
30
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuIconComponent, "neu-icon", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
34
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuIconComponent, "neu-icon", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "decorative": { "alias": "decorative"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
31
35
  }
32
36
 
33
37
  export { NeuIconComponent };
@@ -18,6 +18,24 @@ declare class NeuListboxItemDirective {
18
18
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuListboxItemDirective, never>;
19
19
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuListboxItemDirective, "ng-template[neuListboxItem]", never, {}, {}, never, never, true, never>;
20
20
  }
21
+ declare class NeuListboxHeaderDirective {
22
+ readonly templateRef: TemplateRef<void>;
23
+ constructor(templateRef: TemplateRef<void>);
24
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuListboxHeaderDirective, never>;
25
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuListboxHeaderDirective, "ng-template[neuListboxHeader]", never, {}, {}, never, never, true, never>;
26
+ }
27
+ declare class NeuListboxFooterDirective {
28
+ readonly templateRef: TemplateRef<void>;
29
+ constructor(templateRef: TemplateRef<void>);
30
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuListboxFooterDirective, never>;
31
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuListboxFooterDirective, "ng-template[neuListboxFooter]", never, {}, {}, never, never, true, never>;
32
+ }
33
+ declare class NeuListboxEmptyDirective {
34
+ readonly templateRef: TemplateRef<void>;
35
+ constructor(templateRef: TemplateRef<void>);
36
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuListboxEmptyDirective, never>;
37
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuListboxEmptyDirective, "ng-template[neuListboxEmpty]", never, {}, {}, never, never, true, never>;
38
+ }
21
39
  declare class NeuListboxComponent implements ControlValueAccessor {
22
40
  readonly options: _angular_core.InputSignal<NeuListboxOption[]>;
23
41
  readonly label: _angular_core.InputSignal<string>;
@@ -30,6 +48,9 @@ declare class NeuListboxComponent implements ControlValueAccessor {
30
48
  readonly disabled: _angular_core.InputSignal<boolean>;
31
49
  readonly selectionChange: _angular_core.OutputEmitterRef<NeuListboxOption[]>;
32
50
  readonly itemTpl: _angular_core.Signal<NeuListboxItemDirective | undefined>;
51
+ readonly headerTpl: _angular_core.Signal<NeuListboxHeaderDirective | undefined>;
52
+ readonly footerTpl: _angular_core.Signal<NeuListboxFooterDirective | undefined>;
53
+ readonly emptyTpl: _angular_core.Signal<NeuListboxEmptyDirective | undefined>;
33
54
  readonly query: _angular_core.WritableSignal<string>;
34
55
  readonly activeIndex: _angular_core.WritableSignal<number>;
35
56
  readonly values: _angular_core.WritableSignal<string[]>;
@@ -47,8 +68,8 @@ declare class NeuListboxComponent implements ControlValueAccessor {
47
68
  toggleOption(option: NeuListboxOption): void;
48
69
  onKeyDown(event: KeyboardEvent): void;
49
70
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuListboxComponent, never>;
50
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuListboxComponent, "neu-listbox", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, ["itemTpl"], never, true, never>;
71
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuListboxComponent, "neu-listbox", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, ["itemTpl", "headerTpl", "footerTpl", "emptyTpl"], never, true, never>;
51
72
  }
52
73
 
53
- export { NeuListboxComponent, NeuListboxItemDirective };
74
+ export { NeuListboxComponent, NeuListboxEmptyDirective, NeuListboxFooterDirective, NeuListboxHeaderDirective, NeuListboxItemDirective };
54
75
  export type { NeuListboxOption };
@@ -1,4 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
2
3
 
3
4
  interface NeuMenuItem {
4
5
  key: string;
@@ -10,15 +11,34 @@ interface NeuMenuItem {
10
11
  children?: NeuMenuItem[];
11
12
  data?: unknown;
12
13
  }
14
+ /** Custom visual content for each menu item; menu semantics remain owned by the component. */
15
+ declare class NeuMenuItemDirective {
16
+ readonly templateRef: TemplateRef<{
17
+ $implicit: NeuMenuItem;
18
+ }>;
19
+ constructor(templateRef: TemplateRef<{
20
+ $implicit: NeuMenuItem;
21
+ }>);
22
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuMenuItemDirective, never>;
23
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NeuMenuItemDirective, "ng-template[neuMenuItem]", never, {}, {}, never, never, true, never>;
24
+ }
13
25
  declare class NeuMenuComponent {
26
+ readonly itemTpl: _angular_core.Signal<NeuMenuItemDirective | undefined>;
27
+ readonly itemTemplate: _angular_core.InputSignal<TemplateRef<{
28
+ $implicit: NeuMenuItem;
29
+ }> | null>;
30
+ readonly itemTemplateRef: _angular_core.Signal<TemplateRef<{
31
+ $implicit: NeuMenuItem;
32
+ }> | null>;
14
33
  readonly items: _angular_core.InputSignal<NeuMenuItem[]>;
15
34
  readonly ariaLabel: _angular_core.InputSignal<string>;
16
35
  readonly itemClick: _angular_core.OutputEmitterRef<NeuMenuItem>;
17
36
  activate(item: NeuMenuItem): void;
18
37
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuMenuComponent, never>;
19
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuMenuComponent, "neu-menu", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, never, true, never>;
38
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuMenuComponent, "neu-menu", never, { "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, ["itemTpl"], never, true, never>;
20
39
  }
21
40
  declare class NeuMenuButtonComponent {
41
+ readonly itemTpl: _angular_core.Signal<NeuMenuItemDirective | undefined>;
22
42
  readonly items: _angular_core.InputSignal<NeuMenuItem[]>;
23
43
  readonly label: _angular_core.InputSignal<string>;
24
44
  readonly itemClick: _angular_core.OutputEmitterRef<NeuMenuItem>;
@@ -28,7 +48,7 @@ declare class NeuMenuButtonComponent {
28
48
  close(): void;
29
49
  onItemClick(item: NeuMenuItem): void;
30
50
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuMenuButtonComponent, never>;
31
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuMenuButtonComponent, "neu-menu-button", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; "openChange": "openChange"; }, never, ["*"], true, never>;
51
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuMenuButtonComponent, "neu-menu-button", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; "openChange": "openChange"; }, ["itemTpl"], ["*"], true, never>;
32
52
  }
33
53
  declare class NeuMenubarComponent {
34
54
  readonly items: _angular_core.InputSignal<NeuMenuItem[]>;
@@ -45,5 +65,5 @@ declare class NeuTieredMenuComponent {
45
65
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuTieredMenuComponent, "neu-tiered-menu", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, never, true, never>;
46
66
  }
47
67
 
48
- export { NeuMenuButtonComponent, NeuMenuComponent, NeuMenubarComponent, NeuTieredMenuComponent };
68
+ export { NeuMenuButtonComponent, NeuMenuComponent, NeuMenuItemDirective, NeuMenubarComponent, NeuTieredMenuComponent };
49
69
  export type { NeuMenuItem };