@neural-ui/core 1.3.2 → 1.5.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 (103) hide show
  1. package/README.md +14 -7
  2. package/calendar/package.json +4 -0
  3. package/fesm2022/neural-ui-core-accordion.mjs +8 -6
  4. package/fesm2022/neural-ui-core-accordion.mjs.map +1 -1
  5. package/fesm2022/neural-ui-core-autocomplete.mjs +121 -29
  6. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
  7. package/fesm2022/neural-ui-core-badge.mjs +2 -2
  8. package/fesm2022/neural-ui-core-badge.mjs.map +1 -1
  9. package/fesm2022/neural-ui-core-block-ui.mjs +2 -2
  10. package/fesm2022/neural-ui-core-button.mjs +2 -2
  11. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  12. package/fesm2022/neural-ui-core-calendar.mjs +551 -0
  13. package/fesm2022/neural-ui-core-calendar.mjs.map +1 -0
  14. package/fesm2022/neural-ui-core-chip.mjs +2 -2
  15. package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
  16. package/fesm2022/neural-ui-core-color-picker.mjs +3 -9
  17. package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -1
  18. package/fesm2022/neural-ui-core-confirm-dialog.mjs +2 -2
  19. package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -1
  20. package/fesm2022/neural-ui-core-dashboard-grid.mjs +2 -2
  21. package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
  22. package/fesm2022/neural-ui-core-date-input.mjs +2 -2
  23. package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
  24. package/fesm2022/neural-ui-core-filter-bar.mjs +2 -2
  25. package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -1
  26. package/fesm2022/neural-ui-core-image-gallery.mjs +224 -0
  27. package/fesm2022/neural-ui-core-image-gallery.mjs.map +1 -0
  28. package/fesm2022/neural-ui-core-input.mjs +2 -2
  29. package/fesm2022/neural-ui-core-kanban.mjs +270 -0
  30. package/fesm2022/neural-ui-core-kanban.mjs.map +1 -0
  31. package/fesm2022/neural-ui-core-meter-group.mjs +2 -2
  32. package/fesm2022/neural-ui-core-modal.mjs +81 -31
  33. package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
  34. package/fesm2022/neural-ui-core-multiselect.mjs +269 -99
  35. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  36. package/fesm2022/neural-ui-core-nav.mjs +4 -6
  37. package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
  38. package/fesm2022/neural-ui-core-number-input.mjs +2 -2
  39. package/fesm2022/neural-ui-core-pagination.mjs +2 -2
  40. package/fesm2022/neural-ui-core-pagination.mjs.map +1 -1
  41. package/fesm2022/neural-ui-core-progress-bar.mjs +2 -2
  42. package/fesm2022/neural-ui-core-scheduler-gantt.mjs +289 -0
  43. package/fesm2022/neural-ui-core-scheduler-gantt.mjs.map +1 -0
  44. package/fesm2022/neural-ui-core-select.mjs +276 -101
  45. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  46. package/fesm2022/neural-ui-core-sidebar.mjs +3 -2
  47. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  48. package/fesm2022/neural-ui-core-slider.mjs +2 -2
  49. package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
  50. package/fesm2022/neural-ui-core-split-button.mjs +2 -2
  51. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  52. package/fesm2022/neural-ui-core-stepper.mjs +2 -2
  53. package/fesm2022/neural-ui-core-stepper.mjs.map +1 -1
  54. package/fesm2022/neural-ui-core-table.mjs +435 -34
  55. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  56. package/fesm2022/neural-ui-core-tabs.mjs +11 -4
  57. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
  58. package/fesm2022/neural-ui-core-textarea.mjs +2 -2
  59. package/fesm2022/neural-ui-core-timeline-grid.mjs +215 -0
  60. package/fesm2022/neural-ui-core-timeline-grid.mjs.map +1 -0
  61. package/fesm2022/neural-ui-core-toggle-button-group.mjs +2 -2
  62. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
  63. package/fesm2022/neural-ui-core-toolbar.mjs +2 -2
  64. package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -1
  65. package/fesm2022/neural-ui-core-tree-table.mjs +262 -0
  66. package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -0
  67. package/fesm2022/neural-ui-core-tree.mjs +413 -0
  68. package/fesm2022/neural-ui-core-tree.mjs.map +1 -0
  69. package/fesm2022/neural-ui-core-uploader.mjs +624 -0
  70. package/fesm2022/neural-ui-core-uploader.mjs.map +1 -0
  71. package/fesm2022/neural-ui-core-url-state.mjs +90 -10
  72. package/fesm2022/neural-ui-core-url-state.mjs.map +1 -1
  73. package/fesm2022/neural-ui-core-virtual-list.mjs +53 -23
  74. package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
  75. package/fesm2022/neural-ui-core.mjs +3 -1
  76. package/fesm2022/neural-ui-core.mjs.map +1 -1
  77. package/image-gallery/package.json +4 -0
  78. package/kanban/package.json +4 -0
  79. package/package.json +34 -2
  80. package/scheduler-gantt/package.json +4 -0
  81. package/styles/_tokens.scss +13 -4
  82. package/timeline-grid/package.json +4 -0
  83. package/tree/package.json +4 -0
  84. package/tree-table/package.json +4 -0
  85. package/types/neural-ui-core-autocomplete.d.ts +10 -1
  86. package/types/neural-ui-core-calendar.d.ts +79 -0
  87. package/types/neural-ui-core-color-picker.d.ts +0 -1
  88. package/types/neural-ui-core-image-gallery.d.ts +26 -0
  89. package/types/neural-ui-core-kanban.d.ts +52 -0
  90. package/types/neural-ui-core-modal.d.ts +22 -16
  91. package/types/neural-ui-core-multiselect.d.ts +13 -1
  92. package/types/neural-ui-core-scheduler-gantt.d.ts +68 -0
  93. package/types/neural-ui-core-select.d.ts +14 -1
  94. package/types/neural-ui-core-sidebar.d.ts +1 -0
  95. package/types/neural-ui-core-table.d.ts +66 -4
  96. package/types/neural-ui-core-tabs.d.ts +1 -0
  97. package/types/neural-ui-core-timeline-grid.d.ts +55 -0
  98. package/types/neural-ui-core-tree-table.d.ts +72 -0
  99. package/types/neural-ui-core-tree.d.ts +52 -0
  100. package/types/neural-ui-core-uploader.d.ts +98 -0
  101. package/types/neural-ui-core-url-state.d.ts +9 -0
  102. package/types/neural-ui-core-virtual-list.d.ts +17 -1
  103. package/uploader/package.json +4 -0
@@ -28,6 +28,7 @@ class NeuTabsComponent {
28
28
  _dragStartX = 0;
29
29
  _dragStartScrollLeft = 0;
30
30
  _suppressNextClick = false;
31
+ _optimisticActiveTabId = signal(null, ...(ngDevMode ? [{ debugName: "_optimisticActiveTabId" }] : /* istanbul ignore next */ []));
31
32
  isDraggingNav = signal(false, ...(ngDevMode ? [{ debugName: "isDraggingNav" }] : /* istanbul ignore next */ []));
32
33
  _getUrlParamSignal(key) {
33
34
  let paramSignal = this._urlParamSignals.get(key);
@@ -59,12 +60,17 @@ class NeuTabsComponent {
59
60
  tabChange = output();
60
61
  /** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */
61
62
  activeTabId = computed(() => {
63
+ const tabList = this.tabs();
62
64
  const fromUrl = this._readUrlParam(this.tabParam());
63
- const available = this.tabs().find((t) => t.id === fromUrl && !t.disabled);
65
+ const available = tabList.find((t) => t.id === fromUrl && !t.disabled);
64
66
  if (available)
65
67
  return available.id;
68
+ const optimistic = this._optimisticActiveTabId();
69
+ const optimisticAvailable = tabList.find((t) => t.id === optimistic && !t.disabled);
70
+ if (optimisticAvailable)
71
+ return optimisticAvailable.id;
66
72
  // Fallback: primera pestaña no deshabilitada
67
- return this.tabs().find((t) => !t.disabled)?.id ?? '';
73
+ return tabList.find((t) => !t.disabled)?.id ?? '';
68
74
  }, ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
69
75
  /** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */
70
76
  _indicatorLeft = signal('0px', ...(ngDevMode ? [{ debugName: "_indicatorLeft" }] : /* istanbul ignore next */ []));
@@ -113,6 +119,7 @@ class NeuTabsComponent {
113
119
  selectTab(tab) {
114
120
  if (tab.disabled)
115
121
  return;
122
+ this._optimisticActiveTabId.set(tab.id);
116
123
  this.urlState.setParam(this.tabParam(), tab.id);
117
124
  this.tabChange.emit(tab.id);
118
125
  requestAnimationFrame(() => this._updateIndicator());
@@ -226,7 +233,7 @@ class NeuTabsComponent {
226
233
  <ng-content />
227
234
  </div>
228
235
  </div>
229
- `, isInline: true, styles: [".neu-tabs{display:flex;flex-direction:column}.neu-tabs__nav{position:relative;display:flex;border-bottom:1.5px solid var(--neu-border);overflow-x:auto;cursor:grab;touch-action:pan-x;scrollbar-width:none}.neu-tabs__nav::-webkit-scrollbar{display:none}.neu-tabs__nav--dragging{cursor:grabbing;-webkit-user-select:none;user-select:none}.neu-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:var(--neu-space-2);padding:var(--neu-space-3) var(--neu-space-5);background:transparent;border:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--neu-transition),background-color var(--neu-transition);outline:none}.neu-tabs__tab:hover:not(:disabled){color:var(--neu-text);background:var(--neu-surface-2)}.neu-tabs__tab:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px;border-radius:var(--neu-radius-sm) var(--neu-radius-sm) 0 0}.neu-tabs__tab--active{color:var(--neu-primary);font-weight:600}.neu-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.neu-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--neu-radius-full);background:var(--neu-primary-100);color:var(--neu-primary);font-size:10px;font-weight:700;line-height:1}.neu-tabs__indicator{position:absolute;bottom:-1.5px;height:2.5px;background:var(--neu-primary);border-radius:var(--neu-radius-full) var(--neu-radius-full) 0 0;transition:left var(--neu-transition-slow),width var(--neu-transition-slow);pointer-events:none}.neu-tabs__panels{flex:1}.neu-tab-panel{padding-top:1.5rem;animation:neu-tab-fade .18s ease}@keyframes neu-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
236
+ `, isInline: true, styles: [".neu-tabs{display:flex;flex-direction:column}.neu-tabs__nav{position:relative;display:flex;border-bottom:1.5px solid var(--neu-border);overflow-x:auto;cursor:grab;touch-action:pan-x;scrollbar-width:none}.neu-tabs__nav::-webkit-scrollbar{display:none}.neu-tabs__nav--dragging{cursor:grabbing;-webkit-user-select:none;user-select:none}.neu-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:var(--neu-space-2);padding:var(--neu-space-3) var(--neu-space-5);background:transparent;border:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;color:color-mix(in srgb,var(--neu-text) 72%,var(--neu-surface) 28%);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--neu-transition),background-color var(--neu-transition);outline:none}.neu-tabs__tab:hover:not(:disabled){color:var(--neu-text);background:var(--neu-surface-2)}.neu-tabs__tab:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px;border-radius:var(--neu-radius-sm) var(--neu-radius-sm) 0 0}.neu-tabs__tab--active{color:var(--neu-primary-dark, var(--neu-primary));font-weight:600}.neu-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.neu-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--neu-radius-full);background:var(--neu-primary-100);color:var(--neu-primary-dark, var(--neu-primary));font-size:10px;font-weight:700;line-height:1}.neu-tabs__indicator{position:absolute;bottom:-1.5px;height:2.5px;background:var(--neu-primary);border-radius:var(--neu-radius-full) var(--neu-radius-full) 0 0;transition:left var(--neu-transition-slow),width var(--neu-transition-slow);pointer-events:none}.neu-tabs__panels{flex:1}.neu-tab-panel{padding-top:1.5rem;animation:neu-tab-fade .18s ease}@keyframes neu-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
230
237
  }
231
238
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTabsComponent, decorators: [{
232
239
  type: Component,
@@ -277,7 +284,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
277
284
  <ng-content />
278
285
  </div>
279
286
  </div>
280
- `, styles: [".neu-tabs{display:flex;flex-direction:column}.neu-tabs__nav{position:relative;display:flex;border-bottom:1.5px solid var(--neu-border);overflow-x:auto;cursor:grab;touch-action:pan-x;scrollbar-width:none}.neu-tabs__nav::-webkit-scrollbar{display:none}.neu-tabs__nav--dragging{cursor:grabbing;-webkit-user-select:none;user-select:none}.neu-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:var(--neu-space-2);padding:var(--neu-space-3) var(--neu-space-5);background:transparent;border:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--neu-transition),background-color var(--neu-transition);outline:none}.neu-tabs__tab:hover:not(:disabled){color:var(--neu-text);background:var(--neu-surface-2)}.neu-tabs__tab:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px;border-radius:var(--neu-radius-sm) var(--neu-radius-sm) 0 0}.neu-tabs__tab--active{color:var(--neu-primary);font-weight:600}.neu-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.neu-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--neu-radius-full);background:var(--neu-primary-100);color:var(--neu-primary);font-size:10px;font-weight:700;line-height:1}.neu-tabs__indicator{position:absolute;bottom:-1.5px;height:2.5px;background:var(--neu-primary);border-radius:var(--neu-radius-full) var(--neu-radius-full) 0 0;transition:left var(--neu-transition-slow),width var(--neu-transition-slow);pointer-events:none}.neu-tabs__panels{flex:1}.neu-tab-panel{padding-top:1.5rem;animation:neu-tab-fade .18s ease}@keyframes neu-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
287
+ `, styles: [".neu-tabs{display:flex;flex-direction:column}.neu-tabs__nav{position:relative;display:flex;border-bottom:1.5px solid var(--neu-border);overflow-x:auto;cursor:grab;touch-action:pan-x;scrollbar-width:none}.neu-tabs__nav::-webkit-scrollbar{display:none}.neu-tabs__nav--dragging{cursor:grabbing;-webkit-user-select:none;user-select:none}.neu-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:var(--neu-space-2);padding:var(--neu-space-3) var(--neu-space-5);background:transparent;border:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;color:color-mix(in srgb,var(--neu-text) 72%,var(--neu-surface) 28%);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--neu-transition),background-color var(--neu-transition);outline:none}.neu-tabs__tab:hover:not(:disabled){color:var(--neu-text);background:var(--neu-surface-2)}.neu-tabs__tab:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px;border-radius:var(--neu-radius-sm) var(--neu-radius-sm) 0 0}.neu-tabs__tab--active{color:var(--neu-primary-dark, var(--neu-primary));font-weight:600}.neu-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.neu-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--neu-radius-full);background:var(--neu-primary-100);color:var(--neu-primary-dark, var(--neu-primary));font-size:10px;font-weight:700;line-height:1}.neu-tabs__indicator{position:absolute;bottom:-1.5px;height:2.5px;background:var(--neu-primary);border-radius:var(--neu-radius-full) var(--neu-radius-full) 0 0;transition:left var(--neu-transition-slow),width var(--neu-transition-slow);pointer-events:none}.neu-tabs__panels{flex:1}.neu-tab-panel{padding-top:1.5rem;animation:neu-tab-fade .18s ease}@keyframes neu-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
281
288
  }], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: false }] }], tabParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabParam", required: false }] }], flush: [{ type: i0.Input, args: [{ isSignal: true, alias: "flush", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }] } });
282
289
  // ----------------------------------------------------------------
283
290
  // NeuTabPanelComponent — panel individual (usa DI para el contexto)
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-tabs.mjs","sources":["../../../../projects/ui-core/tabs/neu-tabs.component.ts","../../../../projects/ui-core/tabs/neural-ui-core-tabs.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InjectionToken,\n OnDestroy,\n Signal,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\n\n// ----------------------------------------------------------------\n// Token de contexto — permite a NeuTabPanelComponent inyectar\n// la instancia padre sin pasar signals manualmente.\n// ----------------------------------------------------------------\nexport const NEU_TABS_CONTEXT = new InjectionToken<NeuTabsComponent>('NeuTabsContext');\n\nexport interface NeuTab {\n /** ID único de la pestaña — se usa como valor en la URL / Unique tab ID — used as the URL value */\n id: string;\n /** Etiqueta visible / Visible label */\n label: string;\n /** Badge opcional junto al label / Optional badge next to the label */\n badge?: string;\n /** Deshabilita la pestaña sin ocultarla / Disables the tab without hiding it */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Tabs Component\n *\n * Sistema de pestañas con estado sincronizado a la URL via NeuUrlStateService. / Tab system with state synchronized to the URL via NeuUrlStateService.\n * El panel activo se determina por ?{tabParam}={tabId}. / The active panel is determined by ?{tabParam}={tabId}.\n *\n * Uso:\n * <neu-tabs [tabs]=\"tabs\" tabParam=\"tab\">\n * <neu-tab-panel tabId=\"preview\">...</neu-tab-panel>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n * </neu-tabs>\n */\n@Component({\n selector: 'neu-tabs',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }],\n template: `\n <!-- Barra de pestañas -->\n <div class=\"neu-tabs\" [class.neu-tabs--flush]=\"flush()\">\n <div\n class=\"neu-tabs__nav\"\n role=\"tablist\"\n [attr.aria-label]=\"ariaLabel()\"\n [class.neu-tabs__nav--dragging]=\"isDraggingNav()\"\n #navRef\n (pointerdown)=\"startNavDrag($event)\"\n (pointermove)=\"moveNavDrag($event)\"\n (pointerup)=\"endNavDrag($event)\"\n (pointercancel)=\"endNavDrag($event)\"\n >\n @for (tab of tabs(); track tab.id) {\n <button\n class=\"neu-tabs__tab\"\n [class.neu-tabs__tab--active]=\"activeTabId() === tab.id\"\n [class.neu-tabs__tab--disabled]=\"tab.disabled\"\n role=\"tab\"\n [id]=\"'neu-tab-' + tab.id\"\n [attr.aria-selected]=\"activeTabId() === tab.id\"\n [attr.aria-controls]=\"'neu-tabpanel-' + tab.id\"\n [attr.tabindex]=\"activeTabId() === tab.id ? '0' : '-1'\"\n [disabled]=\"tab.disabled\"\n type=\"button\"\n (click)=\"handleTabClick($event, tab)\"\n (keydown.arrowRight)=\"focusTab($any($event), 1)\"\n (keydown.arrowLeft)=\"focusTab($any($event), -1)\"\n (keydown.home)=\"focusTab($any($event), 'first')\"\n (keydown.end)=\"focusTab($any($event), 'last')\"\n >\n {{ tab.label }}\n @if (tab.badge) {\n <span class=\"neu-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n </button>\n }\n <!-- Indicador deslizante -->\n <span class=\"neu-tabs__indicator\" [style]=\"indicatorStyle()\"></span>\n </div>\n\n <!-- Paneles (proyectados desde NeuTabPanelComponent) -->\n <div class=\"neu-tabs__panels\">\n <ng-content />\n </div>\n </div>\n `,\n styleUrl: './neu-tabs.component.scss',\n})\nexport class NeuTabsComponent implements AfterViewInit, OnDestroy {\n private readonly urlState = inject(NeuUrlStateService);\n private readonly elRef = inject(ElementRef);\n private resizeObserver?: ResizeObserver;\n private readonly _urlParamSignals = new Map<string, Signal<string | null>>();\n private _dragPointerId: number | null = null;\n private _dragStartX = 0;\n private _dragStartScrollLeft = 0;\n private _suppressNextClick = false;\n readonly isDraggingNav = signal(false);\n\n private _getUrlParamSignal(key: string): Signal<string | null> {\n let paramSignal = this._urlParamSignals.get(key);\n if (!paramSignal) {\n paramSignal = this.urlState.getParam(key);\n this._urlParamSignals.set(key, paramSignal);\n }\n return paramSignal;\n }\n\n private _readUrlParam(key: string): string | null {\n return this._getUrlParamSignal(key)();\n }\n\n constructor() {\n // Actualizar indicador cuando activeTabId cambie — debe estar en el constructor (injection context)\n effect(() => {\n this.activeTabId(); // dependencia reactiva\n requestAnimationFrame(() => this._updateIndicator());\n });\n }\n\n /** Definición de pestañas / Tab definitions */\n tabs = input<NeuTab[]>([]);\n\n /** QueryParam que almacena la pestaña activa / QueryParam that stores the active tab */\n tabParam = input<string>('tab');\n\n /** Si true, elimina el padding interno de los paneles / If true, removes the internal padding from panels */\n flush = input<boolean>(false);\n\n /** Etiqueta accesible del rol tablist / Accessible label for the tablist role */\n ariaLabel = input<string>('Pestañas de contenido');\n\n /** Emite al cambiar de pestaña / Emits when the tab changes */\n tabChange = output<string>();\n\n /** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */\n readonly activeTabId = computed(() => {\n const fromUrl = this._readUrlParam(this.tabParam());\n const available = this.tabs().find((t) => t.id === fromUrl && !t.disabled);\n if (available) return available.id;\n // Fallback: primera pestaña no deshabilitada\n return this.tabs().find((t) => !t.disabled)?.id ?? '';\n });\n\n /** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */\n private readonly _indicatorLeft = signal('0px');\n private readonly _indicatorWidth = signal('0px');\n\n readonly indicatorStyle = computed(\n () => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`,\n );\n\n ngAfterViewInit(): void {\n this._updateIndicator();\n // Actualizar cuando cambie el tamaño del nav (p.ej. resize de ventana)\n const nav = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (nav && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this.resizeObserver.observe(nav);\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n }\n\n private _updateIndicator(): void {\n const nav: HTMLElement | null = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (!nav) return;\n const tabEls = nav.querySelectorAll<HTMLElement>('.neu-tabs__tab');\n const idx = this.tabs().findIndex((t) => t.id === this.activeTabId());\n const tabEl = tabEls[idx];\n if (tabEl) {\n this._indicatorLeft.set(tabEl.offsetLeft + 'px');\n this._indicatorWidth.set(tabEl.offsetWidth + 'px');\n if (typeof tabEl.scrollIntoView === 'function') {\n tabEl.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'nearest',\n });\n }\n }\n }\n\n handleTabClick(event: Event, tab: NeuTab): void {\n if (this._suppressNextClick) {\n event.preventDefault();\n event.stopPropagation();\n this._suppressNextClick = false;\n return;\n }\n this.selectTab(tab);\n }\n\n selectTab(tab: NeuTab): void {\n if (tab.disabled) return;\n this.urlState.setParam(this.tabParam(), tab.id);\n this.tabChange.emit(tab.id);\n requestAnimationFrame(() => this._updateIndicator());\n }\n\n startNavDrag(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n const target = event.target as HTMLElement | null;\n if (!target?.closest('.neu-tabs__nav')) return;\n if (target.closest('.neu-tabs__tab')) return;\n\n const nav = event.currentTarget as HTMLElement;\n this._dragPointerId = event.pointerId;\n this._dragStartX = event.clientX;\n this._dragStartScrollLeft = nav.scrollLeft;\n this.isDraggingNav.set(false);\n nav.setPointerCapture(event.pointerId);\n }\n\n moveNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n const deltaX = event.clientX - this._dragStartX;\n if (!this.isDraggingNav() && Math.abs(deltaX) > 6) {\n this.isDraggingNav.set(true);\n this._suppressNextClick = true;\n }\n if (!this.isDraggingNav()) return;\n\n nav.scrollLeft = this._dragStartScrollLeft - deltaX;\n event.preventDefault();\n }\n\n endNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n if (nav.hasPointerCapture(event.pointerId)) {\n nav.releasePointerCapture(event.pointerId);\n }\n this._dragPointerId = null;\n if (this.isDraggingNav()) {\n requestAnimationFrame(() => this.isDraggingNav.set(false));\n }\n }\n\n /** Mueve el foco entre tabs con flechas (roving tabindex — WAI-ARIA Tabs Pattern) / Moves focus between tabs with arrows (roving tabindex — WAI-ARIA Tabs Pattern) */\n focusTab(event: Event, dir: 1 | -1 | 'first' | 'last'): void {\n event.preventDefault();\n const enabledTabs = this.tabs().filter((t) => !t.disabled);\n const currentIdx = enabledTabs.findIndex((t) => t.id === this.activeTabId());\n let nextIdx: number;\n if (dir === 'first') {\n nextIdx = 0;\n } else if (dir === 'last') {\n nextIdx = enabledTabs.length - 1;\n } else {\n nextIdx = (currentIdx + dir + enabledTabs.length) % enabledTabs.length;\n }\n const next = enabledTabs[nextIdx];\n this.selectTab(next);\n const btn = (this.elRef.nativeElement as HTMLElement).querySelector(\n `#neu-tab-${next.id}`,\n ) as HTMLElement | null;\n btn?.focus();\n }\n}\n\n// ----------------------------------------------------------------\n// NeuTabPanelComponent — panel individual (usa DI para el contexto)\n// ----------------------------------------------------------------\n\n/**\n * NeuralUI Tab Panel\n *\n * Panel de contenido asociado a una pestaña de NeuTabsComponent. / Content panel associated with a NeuTabsComponent tab.\n * Solo se renderiza (no oculta con CSS) cuando la pestaña está activa. / Only rendered (not hidden with CSS) when the tab is active.\n *\n * Uso: hijo directo de <neu-tabs>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n */\n@Component({\n selector: 'neu-tab-panel',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (isActive()) {\n <div\n class=\"neu-tab-panel\"\n role=\"tabpanel\"\n [id]=\"'neu-tabpanel-' + tabId()\"\n [attr.aria-labelledby]=\"'neu-tab-' + tabId()\"\n >\n <ng-content />\n </div>\n }\n `,\n})\nexport class NeuTabPanelComponent {\n private readonly tabs = inject(NEU_TABS_CONTEXT, { optional: true });\n\n /** ID que debe coincidir con NeuTab.id del padre / ID that must match the parent NeuTab.id */\n tabId = input.required<string>();\n\n readonly isActive = computed(() => this.tabs?.activeTabId() === this.tabId());\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-tabs.mjs","sources":["../../../../projects/ui-core/tabs/neu-tabs.component.ts","../../../../projects/ui-core/tabs/neural-ui-core-tabs.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InjectionToken,\n OnDestroy,\n Signal,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\n\n// ----------------------------------------------------------------\n// Token de contexto — permite a NeuTabPanelComponent inyectar\n// la instancia padre sin pasar signals manualmente.\n// ----------------------------------------------------------------\nexport const NEU_TABS_CONTEXT = new InjectionToken<NeuTabsComponent>('NeuTabsContext');\n\nexport interface NeuTab {\n /** ID único de la pestaña — se usa como valor en la URL / Unique tab ID — used as the URL value */\n id: string;\n /** Etiqueta visible / Visible label */\n label: string;\n /** Badge opcional junto al label / Optional badge next to the label */\n badge?: string;\n /** Deshabilita la pestaña sin ocultarla / Disables the tab without hiding it */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Tabs Component\n *\n * Sistema de pestañas con estado sincronizado a la URL via NeuUrlStateService. / Tab system with state synchronized to the URL via NeuUrlStateService.\n * El panel activo se determina por ?{tabParam}={tabId}. / The active panel is determined by ?{tabParam}={tabId}.\n *\n * Uso:\n * <neu-tabs [tabs]=\"tabs\" tabParam=\"tab\">\n * <neu-tab-panel tabId=\"preview\">...</neu-tab-panel>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n * </neu-tabs>\n */\n@Component({\n selector: 'neu-tabs',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }],\n template: `\n <!-- Barra de pestañas -->\n <div class=\"neu-tabs\" [class.neu-tabs--flush]=\"flush()\">\n <div\n class=\"neu-tabs__nav\"\n role=\"tablist\"\n [attr.aria-label]=\"ariaLabel()\"\n [class.neu-tabs__nav--dragging]=\"isDraggingNav()\"\n #navRef\n (pointerdown)=\"startNavDrag($event)\"\n (pointermove)=\"moveNavDrag($event)\"\n (pointerup)=\"endNavDrag($event)\"\n (pointercancel)=\"endNavDrag($event)\"\n >\n @for (tab of tabs(); track tab.id) {\n <button\n class=\"neu-tabs__tab\"\n [class.neu-tabs__tab--active]=\"activeTabId() === tab.id\"\n [class.neu-tabs__tab--disabled]=\"tab.disabled\"\n role=\"tab\"\n [id]=\"'neu-tab-' + tab.id\"\n [attr.aria-selected]=\"activeTabId() === tab.id\"\n [attr.aria-controls]=\"'neu-tabpanel-' + tab.id\"\n [attr.tabindex]=\"activeTabId() === tab.id ? '0' : '-1'\"\n [disabled]=\"tab.disabled\"\n type=\"button\"\n (click)=\"handleTabClick($event, tab)\"\n (keydown.arrowRight)=\"focusTab($any($event), 1)\"\n (keydown.arrowLeft)=\"focusTab($any($event), -1)\"\n (keydown.home)=\"focusTab($any($event), 'first')\"\n (keydown.end)=\"focusTab($any($event), 'last')\"\n >\n {{ tab.label }}\n @if (tab.badge) {\n <span class=\"neu-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n </button>\n }\n <!-- Indicador deslizante -->\n <span class=\"neu-tabs__indicator\" [style]=\"indicatorStyle()\"></span>\n </div>\n\n <!-- Paneles (proyectados desde NeuTabPanelComponent) -->\n <div class=\"neu-tabs__panels\">\n <ng-content />\n </div>\n </div>\n `,\n styleUrl: './neu-tabs.component.scss',\n})\nexport class NeuTabsComponent implements AfterViewInit, OnDestroy {\n private readonly urlState = inject(NeuUrlStateService);\n private readonly elRef = inject(ElementRef);\n private resizeObserver?: ResizeObserver;\n private readonly _urlParamSignals = new Map<string, Signal<string | null>>();\n private _dragPointerId: number | null = null;\n private _dragStartX = 0;\n private _dragStartScrollLeft = 0;\n private _suppressNextClick = false;\n private readonly _optimisticActiveTabId = signal<string | null>(null);\n readonly isDraggingNav = signal(false);\n\n private _getUrlParamSignal(key: string): Signal<string | null> {\n let paramSignal = this._urlParamSignals.get(key);\n if (!paramSignal) {\n paramSignal = this.urlState.getParam(key);\n this._urlParamSignals.set(key, paramSignal);\n }\n return paramSignal;\n }\n\n private _readUrlParam(key: string): string | null {\n return this._getUrlParamSignal(key)();\n }\n\n constructor() {\n // Actualizar indicador cuando activeTabId cambie — debe estar en el constructor (injection context)\n effect(() => {\n this.activeTabId(); // dependencia reactiva\n requestAnimationFrame(() => this._updateIndicator());\n });\n }\n\n /** Definición de pestañas / Tab definitions */\n tabs = input<NeuTab[]>([]);\n\n /** QueryParam que almacena la pestaña activa / QueryParam that stores the active tab */\n tabParam = input<string>('tab');\n\n /** Si true, elimina el padding interno de los paneles / If true, removes the internal padding from panels */\n flush = input<boolean>(false);\n\n /** Etiqueta accesible del rol tablist / Accessible label for the tablist role */\n ariaLabel = input<string>('Pestañas de contenido');\n\n /** Emite al cambiar de pestaña / Emits when the tab changes */\n tabChange = output<string>();\n\n /** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */\n readonly activeTabId = computed(() => {\n const tabList = this.tabs();\n const fromUrl = this._readUrlParam(this.tabParam());\n const available = tabList.find((t) => t.id === fromUrl && !t.disabled);\n if (available) return available.id;\n\n const optimistic = this._optimisticActiveTabId();\n const optimisticAvailable = tabList.find((t) => t.id === optimistic && !t.disabled);\n if (optimisticAvailable) return optimisticAvailable.id;\n\n // Fallback: primera pestaña no deshabilitada\n return tabList.find((t) => !t.disabled)?.id ?? '';\n });\n\n /** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */\n private readonly _indicatorLeft = signal('0px');\n private readonly _indicatorWidth = signal('0px');\n\n readonly indicatorStyle = computed(\n () => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`,\n );\n\n ngAfterViewInit(): void {\n this._updateIndicator();\n // Actualizar cuando cambie el tamaño del nav (p.ej. resize de ventana)\n const nav = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (nav && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this.resizeObserver.observe(nav);\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n }\n\n private _updateIndicator(): void {\n const nav: HTMLElement | null = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (!nav) return;\n const tabEls = nav.querySelectorAll<HTMLElement>('.neu-tabs__tab');\n const idx = this.tabs().findIndex((t) => t.id === this.activeTabId());\n const tabEl = tabEls[idx];\n if (tabEl) {\n this._indicatorLeft.set(tabEl.offsetLeft + 'px');\n this._indicatorWidth.set(tabEl.offsetWidth + 'px');\n if (typeof tabEl.scrollIntoView === 'function') {\n tabEl.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'nearest',\n });\n }\n }\n }\n\n handleTabClick(event: Event, tab: NeuTab): void {\n if (this._suppressNextClick) {\n event.preventDefault();\n event.stopPropagation();\n this._suppressNextClick = false;\n return;\n }\n this.selectTab(tab);\n }\n\n selectTab(tab: NeuTab): void {\n if (tab.disabled) return;\n this._optimisticActiveTabId.set(tab.id);\n this.urlState.setParam(this.tabParam(), tab.id);\n this.tabChange.emit(tab.id);\n requestAnimationFrame(() => this._updateIndicator());\n }\n\n startNavDrag(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n const target = event.target as HTMLElement | null;\n if (!target?.closest('.neu-tabs__nav')) return;\n if (target.closest('.neu-tabs__tab')) return;\n\n const nav = event.currentTarget as HTMLElement;\n this._dragPointerId = event.pointerId;\n this._dragStartX = event.clientX;\n this._dragStartScrollLeft = nav.scrollLeft;\n this.isDraggingNav.set(false);\n nav.setPointerCapture(event.pointerId);\n }\n\n moveNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n const deltaX = event.clientX - this._dragStartX;\n if (!this.isDraggingNav() && Math.abs(deltaX) > 6) {\n this.isDraggingNav.set(true);\n this._suppressNextClick = true;\n }\n if (!this.isDraggingNav()) return;\n\n nav.scrollLeft = this._dragStartScrollLeft - deltaX;\n event.preventDefault();\n }\n\n endNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n if (nav.hasPointerCapture(event.pointerId)) {\n nav.releasePointerCapture(event.pointerId);\n }\n this._dragPointerId = null;\n if (this.isDraggingNav()) {\n requestAnimationFrame(() => this.isDraggingNav.set(false));\n }\n }\n\n /** Mueve el foco entre tabs con flechas (roving tabindex — WAI-ARIA Tabs Pattern) / Moves focus between tabs with arrows (roving tabindex — WAI-ARIA Tabs Pattern) */\n focusTab(event: Event, dir: 1 | -1 | 'first' | 'last'): void {\n event.preventDefault();\n const enabledTabs = this.tabs().filter((t) => !t.disabled);\n const currentIdx = enabledTabs.findIndex((t) => t.id === this.activeTabId());\n let nextIdx: number;\n if (dir === 'first') {\n nextIdx = 0;\n } else if (dir === 'last') {\n nextIdx = enabledTabs.length - 1;\n } else {\n nextIdx = (currentIdx + dir + enabledTabs.length) % enabledTabs.length;\n }\n const next = enabledTabs[nextIdx];\n this.selectTab(next);\n const btn = (this.elRef.nativeElement as HTMLElement).querySelector(\n `#neu-tab-${next.id}`,\n ) as HTMLElement | null;\n btn?.focus();\n }\n}\n\n// ----------------------------------------------------------------\n// NeuTabPanelComponent — panel individual (usa DI para el contexto)\n// ----------------------------------------------------------------\n\n/**\n * NeuralUI Tab Panel\n *\n * Panel de contenido asociado a una pestaña de NeuTabsComponent. / Content panel associated with a NeuTabsComponent tab.\n * Solo se renderiza (no oculta con CSS) cuando la pestaña está activa. / Only rendered (not hidden with CSS) when the tab is active.\n *\n * Uso: hijo directo de <neu-tabs>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n */\n@Component({\n selector: 'neu-tab-panel',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (isActive()) {\n <div\n class=\"neu-tab-panel\"\n role=\"tabpanel\"\n [id]=\"'neu-tabpanel-' + tabId()\"\n [attr.aria-labelledby]=\"'neu-tab-' + tabId()\"\n >\n <ng-content />\n </div>\n }\n `,\n})\nexport class NeuTabPanelComponent {\n private readonly tabs = inject(NEU_TABS_CONTEXT, { optional: true });\n\n /** ID que debe coincidir con NeuTab.id del padre / ID that must match the parent NeuTab.id */\n tabId = input.required<string>();\n\n readonly isActive = computed(() => this.tabs?.activeTabId() === this.tabId());\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -126,7 +126,7 @@ class NeuTextareaComponent {
126
126
  }}</span>
127
127
  }
128
128
  </div>
129
- `, isInline: true, styles: [".neu-textarea-host{display:block;width:100%}.neu-textarea__wrapper{position:relative;width:100%}.neu-textarea__wrapper--disabled{opacity:.5;pointer-events:none}.neu-textarea__field{width:100%;min-height:80px;padding:1.25rem var(--neu-space-4) var(--neu-space-3);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);outline:none;resize:var(--_neu-textarea-resize, vertical);transition:border-color var(--neu-transition),box-shadow var(--neu-transition);line-height:1.5;box-sizing:border-box}.neu-textarea__field::placeholder{color:transparent}.neu-textarea__wrapper--error .neu-textarea__field{border-color:var(--neu-error)}.neu-textarea__wrapper--focused .neu-textarea__field{border-color:var(--neu-border-focus);box-shadow:var(--neu-focus-ring)}.neu-textarea__wrapper--disabled .neu-textarea__field{background:var(--neu-surface-2);cursor:not-allowed}.neu-textarea__field[style*=height]{resize:none;overflow:hidden}.neu-textarea__label{position:absolute;top:.9rem;left:var(--neu-space-4);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-8));transition:top var(--neu-transition),transform var(--neu-transition),color var(--neu-transition),font-size var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-textarea__wrapper--focused .neu-textarea__label,.neu-textarea__wrapper--has-value .neu-textarea__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-4) - 4px);color:var(--neu-primary)}.neu-textarea__wrapper--focused.neu-textarea__wrapper--error .neu-textarea__label,.neu-textarea__wrapper--error .neu-textarea__label{color:var(--neu-error)}.neu-textarea__wrapper--disabled .neu-textarea__label{background:var(--neu-surface-2)}.neu-textarea__hint{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-textarea__error{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text)}.neu-textarea-host--sm .neu-textarea__field{min-height:60px;padding:.7rem var(--neu-space-3) var(--neu-space-2)}.neu-textarea-host--sm .neu-textarea__label{top:.6rem}.neu-textarea-host--lg .neu-textarea__field{min-height:100px;font-size:var(--neu-text-base);padding:1.5rem var(--neu-space-5) var(--neu-space-4)}.neu-textarea-host--lg .neu-textarea__label{top:1.2rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
129
+ `, isInline: true, styles: [".neu-textarea-host{display:block;width:100%}.neu-textarea-host--sm .neu-textarea__field{min-height:60px;padding:.7rem var(--neu-space-3) var(--neu-space-2)}.neu-textarea-host--sm .neu-textarea__label{top:.6rem}.neu-textarea-host--lg .neu-textarea__field{min-height:100px;font-size:var(--neu-text-base);padding:1.5rem var(--neu-space-5) var(--neu-space-4)}.neu-textarea-host--lg .neu-textarea__label{top:1.2rem}.neu-textarea__wrapper{position:relative;width:100%}.neu-textarea__wrapper--disabled{opacity:.5;pointer-events:none}.neu-textarea__field{width:100%;min-height:80px;padding:1.25rem var(--neu-space-4) var(--neu-space-3);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);outline:none;resize:var(--_neu-textarea-resize, vertical);transition:border-color var(--neu-transition),box-shadow var(--neu-transition);line-height:1.5;box-sizing:border-box}.neu-textarea__field::placeholder{color:transparent}.neu-textarea__wrapper--error .neu-textarea__field{border-color:var(--neu-error)}.neu-textarea__wrapper--focused .neu-textarea__field{border-color:var(--neu-border-focus);box-shadow:var(--neu-focus-ring)}.neu-textarea__wrapper--disabled .neu-textarea__field{background:var(--neu-surface-2);cursor:not-allowed}.neu-textarea__field[style*=height]{resize:none;overflow:hidden}.neu-textarea__label{position:absolute;top:.9rem;left:var(--neu-space-4);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-8));transition:top var(--neu-transition),transform var(--neu-transition),color var(--neu-transition),font-size var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-textarea__wrapper--focused .neu-textarea__label,.neu-textarea__wrapper--has-value .neu-textarea__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-4) - 4px);color:var(--neu-primary)}.neu-textarea__wrapper--focused.neu-textarea__wrapper--error .neu-textarea__label,.neu-textarea__wrapper--error .neu-textarea__label{color:var(--neu-error)}.neu-textarea__wrapper--disabled .neu-textarea__label{background:var(--neu-surface-2)}.neu-textarea__hint{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-textarea__error{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
130
130
  }
131
131
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTextareaComponent, decorators: [{
132
132
  type: Component,
@@ -177,7 +177,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
177
177
  }}</span>
178
178
  }
179
179
  </div>
180
- `, styles: [".neu-textarea-host{display:block;width:100%}.neu-textarea__wrapper{position:relative;width:100%}.neu-textarea__wrapper--disabled{opacity:.5;pointer-events:none}.neu-textarea__field{width:100%;min-height:80px;padding:1.25rem var(--neu-space-4) var(--neu-space-3);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);outline:none;resize:var(--_neu-textarea-resize, vertical);transition:border-color var(--neu-transition),box-shadow var(--neu-transition);line-height:1.5;box-sizing:border-box}.neu-textarea__field::placeholder{color:transparent}.neu-textarea__wrapper--error .neu-textarea__field{border-color:var(--neu-error)}.neu-textarea__wrapper--focused .neu-textarea__field{border-color:var(--neu-border-focus);box-shadow:var(--neu-focus-ring)}.neu-textarea__wrapper--disabled .neu-textarea__field{background:var(--neu-surface-2);cursor:not-allowed}.neu-textarea__field[style*=height]{resize:none;overflow:hidden}.neu-textarea__label{position:absolute;top:.9rem;left:var(--neu-space-4);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-8));transition:top var(--neu-transition),transform var(--neu-transition),color var(--neu-transition),font-size var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-textarea__wrapper--focused .neu-textarea__label,.neu-textarea__wrapper--has-value .neu-textarea__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-4) - 4px);color:var(--neu-primary)}.neu-textarea__wrapper--focused.neu-textarea__wrapper--error .neu-textarea__label,.neu-textarea__wrapper--error .neu-textarea__label{color:var(--neu-error)}.neu-textarea__wrapper--disabled .neu-textarea__label{background:var(--neu-surface-2)}.neu-textarea__hint{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-textarea__error{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text)}.neu-textarea-host--sm .neu-textarea__field{min-height:60px;padding:.7rem var(--neu-space-3) var(--neu-space-2)}.neu-textarea-host--sm .neu-textarea__label{top:.6rem}.neu-textarea-host--lg .neu-textarea__field{min-height:100px;font-size:var(--neu-text-base);padding:1.5rem var(--neu-space-5) var(--neu-space-4)}.neu-textarea-host--lg .neu-textarea__label{top:1.2rem}\n"] }]
180
+ `, styles: [".neu-textarea-host{display:block;width:100%}.neu-textarea-host--sm .neu-textarea__field{min-height:60px;padding:.7rem var(--neu-space-3) var(--neu-space-2)}.neu-textarea-host--sm .neu-textarea__label{top:.6rem}.neu-textarea-host--lg .neu-textarea__field{min-height:100px;font-size:var(--neu-text-base);padding:1.5rem var(--neu-space-5) var(--neu-space-4)}.neu-textarea-host--lg .neu-textarea__label{top:1.2rem}.neu-textarea__wrapper{position:relative;width:100%}.neu-textarea__wrapper--disabled{opacity:.5;pointer-events:none}.neu-textarea__field{width:100%;min-height:80px;padding:1.25rem var(--neu-space-4) var(--neu-space-3);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);outline:none;resize:var(--_neu-textarea-resize, vertical);transition:border-color var(--neu-transition),box-shadow var(--neu-transition);line-height:1.5;box-sizing:border-box}.neu-textarea__field::placeholder{color:transparent}.neu-textarea__wrapper--error .neu-textarea__field{border-color:var(--neu-error)}.neu-textarea__wrapper--focused .neu-textarea__field{border-color:var(--neu-border-focus);box-shadow:var(--neu-focus-ring)}.neu-textarea__wrapper--disabled .neu-textarea__field{background:var(--neu-surface-2);cursor:not-allowed}.neu-textarea__field[style*=height]{resize:none;overflow:hidden}.neu-textarea__label{position:absolute;top:.9rem;left:var(--neu-space-4);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-8));transition:top var(--neu-transition),transform var(--neu-transition),color var(--neu-transition),font-size var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-textarea__wrapper--focused .neu-textarea__label,.neu-textarea__wrapper--has-value .neu-textarea__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-4) - 4px);color:var(--neu-primary)}.neu-textarea__wrapper--focused.neu-textarea__wrapper--error .neu-textarea__label,.neu-textarea__wrapper--error .neu-textarea__label{color:var(--neu-error)}.neu-textarea__wrapper--disabled .neu-textarea__label{background:var(--neu-surface-2)}.neu-textarea__hint{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-textarea__error{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text)}\n"] }]
181
181
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], autoResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoResize", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], _textareaRef: [{ type: i0.ViewChild, args: ['textareaRef', { isSignal: true }] }] } });
182
182
 
183
183
  /**
@@ -0,0 +1,215 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, output, computed, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
3
+
4
+ class NeuTimelineGridComponent {
5
+ columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
6
+ rows = input([], ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
7
+ compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
8
+ stickyLabels = input(true, ...(ngDevMode ? [{ debugName: "stickyLabels" }] : /* istanbul ignore next */ []));
9
+ minColumnWidth = input('112px', ...(ngDevMode ? [{ debugName: "minColumnWidth" }] : /* istanbul ignore next */ []));
10
+ selectedItemId = input(null, ...(ngDevMode ? [{ debugName: "selectedItemId" }] : /* istanbul ignore next */ []));
11
+ selectedSlot = input(null, ...(ngDevMode ? [{ debugName: "selectedSlot" }] : /* istanbul ignore next */ []));
12
+ itemClick = output();
13
+ slotClick = output();
14
+ _columnIndexMap = computed(() => {
15
+ const indexMap = new Map();
16
+ this.columns().forEach((column, index) => indexMap.set(column.id, index + 1));
17
+ return indexMap;
18
+ }, ...(ngDevMode ? [{ debugName: "_columnIndexMap" }] : /* istanbul ignore next */ []));
19
+ gridTemplateColumns = computed(() => `repeat(${Math.max(this.columns().length, 1)}, minmax(var(--neu-timeline-grid-min-column-width), 1fr))`, ...(ngDevMode ? [{ debugName: "gridTemplateColumns" }] : /* istanbul ignore next */ []));
20
+ validItems(row) {
21
+ const indexMap = this._columnIndexMap();
22
+ return row.items.filter((item) => indexMap.has(item.start));
23
+ }
24
+ itemGridColumn(item) {
25
+ const start = this._columnIndexMap().get(item.start) ?? 1;
26
+ const span = Math.max(1, item.span ?? 1);
27
+ return `${start} / span ${span}`;
28
+ }
29
+ slotGridColumn(columnId) {
30
+ const start = this._columnIndexMap().get(columnId) ?? 1;
31
+ return `${start} / span 1`;
32
+ }
33
+ itemClass(item) {
34
+ const selectedClass = this.isItemSelected(item.id) ? ' neu-timeline-grid__item--selected' : '';
35
+ return `neu-timeline-grid__item neu-timeline-grid__item--${item.variant ?? 'default'}${selectedClass}`;
36
+ }
37
+ itemAriaLabel(row, item) {
38
+ return `${row.label}: ${item.title}`;
39
+ }
40
+ slotAriaLabel(row, column) {
41
+ return `${row.label}: ${column.label}`;
42
+ }
43
+ slotKey(rowId, columnId) {
44
+ return `${rowId}:${columnId}`;
45
+ }
46
+ isItemSelected(itemId) {
47
+ return this.selectedItemId() === itemId;
48
+ }
49
+ isSlotSelected(rowId, columnId) {
50
+ const selectedSlot = this.selectedSlot();
51
+ return selectedSlot?.rowId === rowId && selectedSlot?.columnId === columnId;
52
+ }
53
+ onSlotClick(rowId, columnId) {
54
+ this.slotClick.emit({ rowId, columnId });
55
+ }
56
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTimelineGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
57
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuTimelineGridComponent, isStandalone: true, selector: "neu-timeline-grid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, stickyLabels: { classPropertyName: "stickyLabels", publicName: "stickyLabels", isSignal: true, isRequired: false, transformFunction: null }, minColumnWidth: { classPropertyName: "minColumnWidth", publicName: "minColumnWidth", isSignal: true, isRequired: false, transformFunction: null }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: true, isRequired: false, transformFunction: null }, selectedSlot: { classPropertyName: "selectedSlot", publicName: "selectedSlot", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick", slotClick: "slotClick" }, host: { properties: { "class.neu-timeline-grid--compact": "compact()", "class.neu-timeline-grid--sticky-labels": "stickyLabels()", "style.--neu-timeline-grid-min-column-width": "minColumnWidth()" } }, ngImport: i0, template: `
58
+ <div class="neu-timeline-grid">
59
+ <div class="neu-timeline-grid__header">
60
+ <div class="neu-timeline-grid__corner" aria-hidden="true"></div>
61
+ <div
62
+ class="neu-timeline-grid__header-track"
63
+ [style.gridTemplateColumns]="gridTemplateColumns()"
64
+ >
65
+ @for (column of columns(); track column.id) {
66
+ <div class="neu-timeline-grid__column">
67
+ <span class="neu-timeline-grid__column-label">{{ column.label }}</span>
68
+ @if (column.description) {
69
+ <span class="neu-timeline-grid__column-desc">{{ column.description }}</span>
70
+ }
71
+ </div>
72
+ }
73
+ </div>
74
+ </div>
75
+
76
+ <div class="neu-timeline-grid__body">
77
+ @for (row of rows(); track row.id) {
78
+ <section class="neu-timeline-grid__row" [attr.aria-label]="row.label">
79
+ <div class="neu-timeline-grid__row-label">
80
+ <strong>{{ row.label }}</strong>
81
+ @if (row.description) {
82
+ <span>{{ row.description }}</span>
83
+ }
84
+ </div>
85
+
86
+ <div
87
+ class="neu-timeline-grid__track"
88
+ [style.gridTemplateColumns]="gridTemplateColumns()"
89
+ >
90
+ @for (column of columns(); track column.id) {
91
+ <button
92
+ type="button"
93
+ class="neu-timeline-grid__slot neu-timeline-grid__slot-button"
94
+ [class.neu-timeline-grid__slot--selected]="isSlotSelected(row.id, column.id)"
95
+ [style.gridColumn]="slotGridColumn(column.id)"
96
+ [attr.aria-label]="slotAriaLabel(row, column)"
97
+ [attr.aria-pressed]="isSlotSelected(row.id, column.id)"
98
+ [attr.data-slot-key]="slotKey(row.id, column.id)"
99
+ (click)="onSlotClick(row.id, column.id)"
100
+ ></button>
101
+ }
102
+
103
+ @for (item of validItems(row); track item.id) {
104
+ <button
105
+ type="button"
106
+ class="neu-timeline-grid__item"
107
+ [class]="itemClass(item)"
108
+ [style.gridColumn]="itemGridColumn(item)"
109
+ [attr.aria-label]="itemAriaLabel(row, item)"
110
+ [attr.aria-pressed]="isItemSelected(item.id)"
111
+ [attr.data-item-id]="item.id"
112
+ (click)="itemClick.emit(item)"
113
+ >
114
+ <span class="neu-timeline-grid__item-title">{{ item.title }}</span>
115
+ @if (item.subtitle) {
116
+ <span class="neu-timeline-grid__item-subtitle">{{ item.subtitle }}</span>
117
+ }
118
+ @if (item.meta) {
119
+ <span class="neu-timeline-grid__item-meta">{{ item.meta }}</span>
120
+ }
121
+ </button>
122
+ }
123
+ </div>
124
+ </section>
125
+ }
126
+ </div>
127
+ </div>
128
+ `, isInline: true, styles: ["neu-timeline-grid{min-width:0}.neu-timeline-grid{display:grid;gap:var(--neu-space-4);width:100%;overflow-x:auto;color:var(--neu-text)}.neu-timeline-grid--compact .neu-timeline-grid__track,.neu-timeline-grid--compact .neu-timeline-grid__slot{min-height:60px}.neu-timeline-grid--compact .neu-timeline-grid__item{margin:8px 0;padding:8px 10px}.neu-timeline-grid--sticky-labels .neu-timeline-grid__row-label,.neu-timeline-grid--sticky-labels .neu-timeline-grid__corner{position:sticky;left:0;z-index:2;background:var(--neu-surface)}.neu-timeline-grid__header,.neu-timeline-grid__row{display:grid;grid-template-columns:minmax(180px,220px) minmax(0,1fr);gap:var(--neu-space-4);min-width:max-content}.neu-timeline-grid__corner,.neu-timeline-grid__row-label{padding:var(--neu-space-3) 0}.neu-timeline-grid__header-track,.neu-timeline-grid__track{display:grid;position:relative;gap:var(--neu-space-3)}.neu-timeline-grid__column{display:flex;flex-direction:column;gap:2px;min-width:0;padding:0 var(--neu-space-2)}.neu-timeline-grid__column-label{font-size:var(--neu-text-sm);font-weight:700}.neu-timeline-grid__column-desc,.neu-timeline-grid__row-label span,.neu-timeline-grid__item-subtitle,.neu-timeline-grid__item-meta{font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-timeline-grid__body{display:grid;gap:var(--neu-space-3)}.neu-timeline-grid__row-label{display:flex;flex-direction:column;gap:4px}.neu-timeline-grid__row-label strong{font-size:var(--neu-text-sm)}.neu-timeline-grid__track{align-items:stretch;min-height:76px}.neu-timeline-grid__slot,.neu-timeline-grid__item{grid-row:1}.neu-timeline-grid__slot{min-height:76px;border-radius:0;border:0;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 18%,transparent),color-mix(in srgb,var(--neu-surface) 96%,transparent));box-shadow:inset 1px 0 color-mix(in srgb,var(--neu-border) 16%,transparent),inset 0 1px #ffffff04}.neu-timeline-grid__slot-button{appearance:none;display:block;width:100%;min-width:100%;justify-self:stretch;align-self:stretch;box-sizing:border-box;padding:0;cursor:pointer}.neu-timeline-grid__slot-button:hover{background:linear-gradient(180deg,color-mix(in srgb,var(--neu-primary) 7%,var(--neu-surface-2)),color-mix(in srgb,var(--neu-primary) 4%,var(--neu-surface)));box-shadow:inset 1px 0 color-mix(in srgb,var(--neu-primary) 22%,transparent),inset 0 1px #ffffff08}.neu-timeline-grid__slot--selected{border-radius:var(--neu-radius-md);background:color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface-2));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 42%,var(--neu-border)),inset 0 1px #ffffff08}.neu-timeline-grid__item{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px;min-width:0;margin:10px 0;padding:10px 12px;border:1px solid transparent;border-radius:var(--neu-radius-lg);text-align:left;background:var(--neu-surface);box-shadow:var(--neu-shadow-sm);color:var(--neu-text)}.neu-timeline-grid__item-title{font-size:var(--neu-text-sm);font-weight:700}.neu-timeline-grid__item--selected{outline:2px solid color-mix(in srgb,var(--neu-primary) 48%,transparent);outline-offset:1px}.neu-timeline-grid__item--default{border-color:var(--neu-border)}.neu-timeline-grid__item--info{border-color:color-mix(in srgb,var(--neu-primary) 36%,var(--neu-border));background:color-mix(in srgb,var(--neu-primary) 8%,var(--neu-surface))}.neu-timeline-grid__item--success{border-color:color-mix(in srgb,var(--neu-success) 36%,var(--neu-border));background:color-mix(in srgb,var(--neu-success) 9%,var(--neu-surface))}.neu-timeline-grid__item--warning{border-color:color-mix(in srgb,var(--neu-warning) 40%,var(--neu-border));background:color-mix(in srgb,var(--neu-warning) 11%,var(--neu-surface))}.neu-timeline-grid__item--danger{border-color:color-mix(in srgb,var(--neu-error) 38%,var(--neu-border));background:color-mix(in srgb,var(--neu-error) 10%,var(--neu-surface))}@media(max-width:720px){.neu-timeline-grid__header,.neu-timeline-grid__row{grid-template-columns:minmax(140px,180px) minmax(0,1fr);gap:var(--neu-space-3)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
129
+ }
130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTimelineGridComponent, decorators: [{
131
+ type: Component,
132
+ args: [{ selector: 'neu-timeline-grid', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
133
+ '[class.neu-timeline-grid--compact]': 'compact()',
134
+ '[class.neu-timeline-grid--sticky-labels]': 'stickyLabels()',
135
+ '[style.--neu-timeline-grid-min-column-width]': 'minColumnWidth()',
136
+ }, template: `
137
+ <div class="neu-timeline-grid">
138
+ <div class="neu-timeline-grid__header">
139
+ <div class="neu-timeline-grid__corner" aria-hidden="true"></div>
140
+ <div
141
+ class="neu-timeline-grid__header-track"
142
+ [style.gridTemplateColumns]="gridTemplateColumns()"
143
+ >
144
+ @for (column of columns(); track column.id) {
145
+ <div class="neu-timeline-grid__column">
146
+ <span class="neu-timeline-grid__column-label">{{ column.label }}</span>
147
+ @if (column.description) {
148
+ <span class="neu-timeline-grid__column-desc">{{ column.description }}</span>
149
+ }
150
+ </div>
151
+ }
152
+ </div>
153
+ </div>
154
+
155
+ <div class="neu-timeline-grid__body">
156
+ @for (row of rows(); track row.id) {
157
+ <section class="neu-timeline-grid__row" [attr.aria-label]="row.label">
158
+ <div class="neu-timeline-grid__row-label">
159
+ <strong>{{ row.label }}</strong>
160
+ @if (row.description) {
161
+ <span>{{ row.description }}</span>
162
+ }
163
+ </div>
164
+
165
+ <div
166
+ class="neu-timeline-grid__track"
167
+ [style.gridTemplateColumns]="gridTemplateColumns()"
168
+ >
169
+ @for (column of columns(); track column.id) {
170
+ <button
171
+ type="button"
172
+ class="neu-timeline-grid__slot neu-timeline-grid__slot-button"
173
+ [class.neu-timeline-grid__slot--selected]="isSlotSelected(row.id, column.id)"
174
+ [style.gridColumn]="slotGridColumn(column.id)"
175
+ [attr.aria-label]="slotAriaLabel(row, column)"
176
+ [attr.aria-pressed]="isSlotSelected(row.id, column.id)"
177
+ [attr.data-slot-key]="slotKey(row.id, column.id)"
178
+ (click)="onSlotClick(row.id, column.id)"
179
+ ></button>
180
+ }
181
+
182
+ @for (item of validItems(row); track item.id) {
183
+ <button
184
+ type="button"
185
+ class="neu-timeline-grid__item"
186
+ [class]="itemClass(item)"
187
+ [style.gridColumn]="itemGridColumn(item)"
188
+ [attr.aria-label]="itemAriaLabel(row, item)"
189
+ [attr.aria-pressed]="isItemSelected(item.id)"
190
+ [attr.data-item-id]="item.id"
191
+ (click)="itemClick.emit(item)"
192
+ >
193
+ <span class="neu-timeline-grid__item-title">{{ item.title }}</span>
194
+ @if (item.subtitle) {
195
+ <span class="neu-timeline-grid__item-subtitle">{{ item.subtitle }}</span>
196
+ }
197
+ @if (item.meta) {
198
+ <span class="neu-timeline-grid__item-meta">{{ item.meta }}</span>
199
+ }
200
+ </button>
201
+ }
202
+ </div>
203
+ </section>
204
+ }
205
+ </div>
206
+ </div>
207
+ `, styles: ["neu-timeline-grid{min-width:0}.neu-timeline-grid{display:grid;gap:var(--neu-space-4);width:100%;overflow-x:auto;color:var(--neu-text)}.neu-timeline-grid--compact .neu-timeline-grid__track,.neu-timeline-grid--compact .neu-timeline-grid__slot{min-height:60px}.neu-timeline-grid--compact .neu-timeline-grid__item{margin:8px 0;padding:8px 10px}.neu-timeline-grid--sticky-labels .neu-timeline-grid__row-label,.neu-timeline-grid--sticky-labels .neu-timeline-grid__corner{position:sticky;left:0;z-index:2;background:var(--neu-surface)}.neu-timeline-grid__header,.neu-timeline-grid__row{display:grid;grid-template-columns:minmax(180px,220px) minmax(0,1fr);gap:var(--neu-space-4);min-width:max-content}.neu-timeline-grid__corner,.neu-timeline-grid__row-label{padding:var(--neu-space-3) 0}.neu-timeline-grid__header-track,.neu-timeline-grid__track{display:grid;position:relative;gap:var(--neu-space-3)}.neu-timeline-grid__column{display:flex;flex-direction:column;gap:2px;min-width:0;padding:0 var(--neu-space-2)}.neu-timeline-grid__column-label{font-size:var(--neu-text-sm);font-weight:700}.neu-timeline-grid__column-desc,.neu-timeline-grid__row-label span,.neu-timeline-grid__item-subtitle,.neu-timeline-grid__item-meta{font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-timeline-grid__body{display:grid;gap:var(--neu-space-3)}.neu-timeline-grid__row-label{display:flex;flex-direction:column;gap:4px}.neu-timeline-grid__row-label strong{font-size:var(--neu-text-sm)}.neu-timeline-grid__track{align-items:stretch;min-height:76px}.neu-timeline-grid__slot,.neu-timeline-grid__item{grid-row:1}.neu-timeline-grid__slot{min-height:76px;border-radius:0;border:0;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 18%,transparent),color-mix(in srgb,var(--neu-surface) 96%,transparent));box-shadow:inset 1px 0 color-mix(in srgb,var(--neu-border) 16%,transparent),inset 0 1px #ffffff04}.neu-timeline-grid__slot-button{appearance:none;display:block;width:100%;min-width:100%;justify-self:stretch;align-self:stretch;box-sizing:border-box;padding:0;cursor:pointer}.neu-timeline-grid__slot-button:hover{background:linear-gradient(180deg,color-mix(in srgb,var(--neu-primary) 7%,var(--neu-surface-2)),color-mix(in srgb,var(--neu-primary) 4%,var(--neu-surface)));box-shadow:inset 1px 0 color-mix(in srgb,var(--neu-primary) 22%,transparent),inset 0 1px #ffffff08}.neu-timeline-grid__slot--selected{border-radius:var(--neu-radius-md);background:color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface-2));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 42%,var(--neu-border)),inset 0 1px #ffffff08}.neu-timeline-grid__item{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px;min-width:0;margin:10px 0;padding:10px 12px;border:1px solid transparent;border-radius:var(--neu-radius-lg);text-align:left;background:var(--neu-surface);box-shadow:var(--neu-shadow-sm);color:var(--neu-text)}.neu-timeline-grid__item-title{font-size:var(--neu-text-sm);font-weight:700}.neu-timeline-grid__item--selected{outline:2px solid color-mix(in srgb,var(--neu-primary) 48%,transparent);outline-offset:1px}.neu-timeline-grid__item--default{border-color:var(--neu-border)}.neu-timeline-grid__item--info{border-color:color-mix(in srgb,var(--neu-primary) 36%,var(--neu-border));background:color-mix(in srgb,var(--neu-primary) 8%,var(--neu-surface))}.neu-timeline-grid__item--success{border-color:color-mix(in srgb,var(--neu-success) 36%,var(--neu-border));background:color-mix(in srgb,var(--neu-success) 9%,var(--neu-surface))}.neu-timeline-grid__item--warning{border-color:color-mix(in srgb,var(--neu-warning) 40%,var(--neu-border));background:color-mix(in srgb,var(--neu-warning) 11%,var(--neu-surface))}.neu-timeline-grid__item--danger{border-color:color-mix(in srgb,var(--neu-error) 38%,var(--neu-border));background:color-mix(in srgb,var(--neu-error) 10%,var(--neu-surface))}@media(max-width:720px){.neu-timeline-grid__header,.neu-timeline-grid__row{grid-template-columns:minmax(140px,180px) minmax(0,1fr);gap:var(--neu-space-3)}}\n"] }]
208
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], stickyLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyLabels", required: false }] }], minColumnWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minColumnWidth", required: false }] }], selectedItemId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemId", required: false }] }], selectedSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedSlot", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], slotClick: [{ type: i0.Output, args: ["slotClick"] }] } });
209
+
210
+ /**
211
+ * Generated bundle index. Do not edit.
212
+ */
213
+
214
+ export { NeuTimelineGridComponent };
215
+ //# sourceMappingURL=neural-ui-core-timeline-grid.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neural-ui-core-timeline-grid.mjs","sources":["../../../../projects/ui-core/timeline-grid/neu-timeline-grid.component.ts","../../../../projects/ui-core/timeline-grid/neural-ui-core-timeline-grid.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n output,\n ViewEncapsulation,\n} from '@angular/core';\n\nexport type NeuTimelineGridItemVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface NeuTimelineGridColumn {\n id: string;\n label: string;\n description?: string;\n}\n\nexport interface NeuTimelineGridItem {\n id: string;\n title: string;\n start: string;\n span?: number;\n subtitle?: string;\n meta?: string;\n variant?: NeuTimelineGridItemVariant;\n}\n\nexport interface NeuTimelineGridRow {\n id: string;\n label: string;\n description?: string;\n items: NeuTimelineGridItem[];\n}\n\nexport interface NeuTimelineGridSlotSelection {\n rowId: string;\n columnId: string;\n}\n\n@Component({\n selector: 'neu-timeline-grid',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-timeline-grid--compact]': 'compact()',\n '[class.neu-timeline-grid--sticky-labels]': 'stickyLabels()',\n '[style.--neu-timeline-grid-min-column-width]': 'minColumnWidth()',\n },\n template: `\n <div class=\"neu-timeline-grid\">\n <div class=\"neu-timeline-grid__header\">\n <div class=\"neu-timeline-grid__corner\" aria-hidden=\"true\"></div>\n <div\n class=\"neu-timeline-grid__header-track\"\n [style.gridTemplateColumns]=\"gridTemplateColumns()\"\n >\n @for (column of columns(); track column.id) {\n <div class=\"neu-timeline-grid__column\">\n <span class=\"neu-timeline-grid__column-label\">{{ column.label }}</span>\n @if (column.description) {\n <span class=\"neu-timeline-grid__column-desc\">{{ column.description }}</span>\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"neu-timeline-grid__body\">\n @for (row of rows(); track row.id) {\n <section class=\"neu-timeline-grid__row\" [attr.aria-label]=\"row.label\">\n <div class=\"neu-timeline-grid__row-label\">\n <strong>{{ row.label }}</strong>\n @if (row.description) {\n <span>{{ row.description }}</span>\n }\n </div>\n\n <div\n class=\"neu-timeline-grid__track\"\n [style.gridTemplateColumns]=\"gridTemplateColumns()\"\n >\n @for (column of columns(); track column.id) {\n <button\n type=\"button\"\n class=\"neu-timeline-grid__slot neu-timeline-grid__slot-button\"\n [class.neu-timeline-grid__slot--selected]=\"isSlotSelected(row.id, column.id)\"\n [style.gridColumn]=\"slotGridColumn(column.id)\"\n [attr.aria-label]=\"slotAriaLabel(row, column)\"\n [attr.aria-pressed]=\"isSlotSelected(row.id, column.id)\"\n [attr.data-slot-key]=\"slotKey(row.id, column.id)\"\n (click)=\"onSlotClick(row.id, column.id)\"\n ></button>\n }\n\n @for (item of validItems(row); track item.id) {\n <button\n type=\"button\"\n class=\"neu-timeline-grid__item\"\n [class]=\"itemClass(item)\"\n [style.gridColumn]=\"itemGridColumn(item)\"\n [attr.aria-label]=\"itemAriaLabel(row, item)\"\n [attr.aria-pressed]=\"isItemSelected(item.id)\"\n [attr.data-item-id]=\"item.id\"\n (click)=\"itemClick.emit(item)\"\n >\n <span class=\"neu-timeline-grid__item-title\">{{ item.title }}</span>\n @if (item.subtitle) {\n <span class=\"neu-timeline-grid__item-subtitle\">{{ item.subtitle }}</span>\n }\n @if (item.meta) {\n <span class=\"neu-timeline-grid__item-meta\">{{ item.meta }}</span>\n }\n </button>\n }\n </div>\n </section>\n }\n </div>\n </div>\n `,\n styleUrl: './neu-timeline-grid.component.scss',\n})\nexport class NeuTimelineGridComponent {\n readonly columns = input<NeuTimelineGridColumn[]>([]);\n readonly rows = input<NeuTimelineGridRow[]>([]);\n readonly compact = input<boolean>(false);\n readonly stickyLabels = input<boolean>(true);\n readonly minColumnWidth = input<string>('112px');\n readonly selectedItemId = input<string | null>(null);\n readonly selectedSlot = input<NeuTimelineGridSlotSelection | null>(null);\n\n readonly itemClick = output<NeuTimelineGridItem>();\n readonly slotClick = output<NeuTimelineGridSlotSelection>();\n\n readonly _columnIndexMap = computed(() => {\n const indexMap = new Map<string, number>();\n this.columns().forEach((column, index) => indexMap.set(column.id, index + 1));\n return indexMap;\n });\n\n readonly gridTemplateColumns = computed(\n () =>\n `repeat(${Math.max(this.columns().length, 1)}, minmax(var(--neu-timeline-grid-min-column-width), 1fr))`,\n );\n\n validItems(row: NeuTimelineGridRow): NeuTimelineGridItem[] {\n const indexMap = this._columnIndexMap();\n return row.items.filter((item) => indexMap.has(item.start));\n }\n\n itemGridColumn(item: NeuTimelineGridItem): string {\n const start = this._columnIndexMap().get(item.start) ?? 1;\n const span = Math.max(1, item.span ?? 1);\n return `${start} / span ${span}`;\n }\n\n slotGridColumn(columnId: string): string {\n const start = this._columnIndexMap().get(columnId) ?? 1;\n return `${start} / span 1`;\n }\n\n itemClass(item: NeuTimelineGridItem): string {\n const selectedClass = this.isItemSelected(item.id) ? ' neu-timeline-grid__item--selected' : '';\n return `neu-timeline-grid__item neu-timeline-grid__item--${item.variant ?? 'default'}${selectedClass}`;\n }\n\n itemAriaLabel(row: NeuTimelineGridRow, item: NeuTimelineGridItem): string {\n return `${row.label}: ${item.title}`;\n }\n\n slotAriaLabel(row: NeuTimelineGridRow, column: NeuTimelineGridColumn): string {\n return `${row.label}: ${column.label}`;\n }\n\n slotKey(rowId: string, columnId: string): string {\n return `${rowId}:${columnId}`;\n }\n\n isItemSelected(itemId: string): boolean {\n return this.selectedItemId() === itemId;\n }\n\n isSlotSelected(rowId: string, columnId: string): boolean {\n const selectedSlot = this.selectedSlot();\n return selectedSlot?.rowId === rowId && selectedSlot?.columnId === columnId;\n }\n\n onSlotClick(rowId: string, columnId: string): void {\n this.slotClick.emit({ rowId, columnId });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -116,7 +116,7 @@ class NeuToggleButtonGroupComponent {
116
116
  </button>
117
117
  }
118
118
  </div>
119
- `, isInline: true, styles: [".neu-toggle-group-host{display:inline-block}.neu-toggle-group{display:inline-flex;border:1px solid var(--neu-border);border-radius:var(--neu-radius);overflow:hidden;background:var(--neu-surface)}.neu-toggle-group__btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:none;border-right:1px solid var(--neu-border);background:transparent;color:var(--neu-text-muted);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;line-height:1;white-space:nowrap;cursor:pointer;padding:.5rem var(--neu-space-4);transition:background-color .15s ease,color .15s ease,border-color .15s ease;outline:none;-webkit-user-select:none;user-select:none}.neu-toggle-group__btn:last-child{border-right:none}.neu-toggle-group__btn:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-toggle-group__btn:focus-visible{position:relative;z-index:1;box-shadow:inset 0 0 0 2px var(--neu-primary)}.neu-toggle-group__btn--active{background:var(--neu-primary);color:var(--neu-primary-fg);border-right-color:var(--neu-primary-dark)}.neu-toggle-group__btn--active:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-primary-dark);color:var(--neu-primary-fg)}.neu-toggle-group__btn--active+.neu-toggle-group__btn{border-left-color:var(--neu-primary-dark)}.neu-toggle-group__btn--disabled{opacity:.45;cursor:not-allowed}.neu-toggle-group--disabled{opacity:.6;pointer-events:none}.neu-toggle-group--sm .neu-toggle-group__btn{font-size:var(--neu-text-xs);padding:.375rem var(--neu-space-3)}.neu-toggle-group--md .neu-toggle-group__btn{font-size:var(--neu-text-sm);padding:.5rem var(--neu-space-4)}.neu-toggle-group--lg .neu-toggle-group__btn{font-size:var(--neu-text-base);padding:.625rem var(--neu-space-5)}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
119
+ `, isInline: true, styles: [".neu-toggle-group-host{display:inline-block}.neu-toggle-group{display:inline-flex;border:1px solid var(--neu-border);border-radius:var(--neu-radius);overflow:hidden;background:var(--neu-surface)}.neu-toggle-group__btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:none;border-right:1px solid var(--neu-border);background:transparent;color:var(--neu-text-muted);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;line-height:1;white-space:nowrap;cursor:pointer;padding:.5rem var(--neu-space-4);transition:background-color .15s ease,color .15s ease,border-color .15s ease;outline:none;-webkit-user-select:none;user-select:none}.neu-toggle-group__btn:last-child{border-right:none}.neu-toggle-group__btn:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-toggle-group__btn:focus-visible{position:relative;z-index:1;box-shadow:inset 0 0 0 2px var(--neu-primary)}.neu-toggle-group__btn--active{background:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-primary-solid-fg, var(--neu-primary-fg));border-right-color:var(--neu-primary-solid-hover, var(--neu-primary-dark))}.neu-toggle-group__btn--active:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-primary-solid-hover, var(--neu-primary-dark));color:var(--neu-primary-solid-fg, var(--neu-primary-fg))}.neu-toggle-group__btn--active+.neu-toggle-group__btn{border-left-color:var(--neu-primary-solid-hover, var(--neu-primary-dark))}.neu-toggle-group__btn--disabled{opacity:.45;cursor:not-allowed}.neu-toggle-group--disabled{opacity:.6;pointer-events:none}.neu-toggle-group--sm .neu-toggle-group__btn{font-size:var(--neu-text-xs);padding:.375rem var(--neu-space-3)}.neu-toggle-group--md .neu-toggle-group__btn{font-size:var(--neu-text-sm);padding:.5rem var(--neu-space-4)}.neu-toggle-group--lg .neu-toggle-group__btn{font-size:var(--neu-text-base);padding:.625rem var(--neu-space-5)}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
120
120
  }
121
121
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuToggleButtonGroupComponent, decorators: [{
122
122
  type: Component,
@@ -151,7 +151,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
151
151
  </button>
152
152
  }
153
153
  </div>
154
- `, styles: [".neu-toggle-group-host{display:inline-block}.neu-toggle-group{display:inline-flex;border:1px solid var(--neu-border);border-radius:var(--neu-radius);overflow:hidden;background:var(--neu-surface)}.neu-toggle-group__btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:none;border-right:1px solid var(--neu-border);background:transparent;color:var(--neu-text-muted);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;line-height:1;white-space:nowrap;cursor:pointer;padding:.5rem var(--neu-space-4);transition:background-color .15s ease,color .15s ease,border-color .15s ease;outline:none;-webkit-user-select:none;user-select:none}.neu-toggle-group__btn:last-child{border-right:none}.neu-toggle-group__btn:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-toggle-group__btn:focus-visible{position:relative;z-index:1;box-shadow:inset 0 0 0 2px var(--neu-primary)}.neu-toggle-group__btn--active{background:var(--neu-primary);color:var(--neu-primary-fg);border-right-color:var(--neu-primary-dark)}.neu-toggle-group__btn--active:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-primary-dark);color:var(--neu-primary-fg)}.neu-toggle-group__btn--active+.neu-toggle-group__btn{border-left-color:var(--neu-primary-dark)}.neu-toggle-group__btn--disabled{opacity:.45;cursor:not-allowed}.neu-toggle-group--disabled{opacity:.6;pointer-events:none}.neu-toggle-group--sm .neu-toggle-group__btn{font-size:var(--neu-text-xs);padding:.375rem var(--neu-space-3)}.neu-toggle-group--md .neu-toggle-group__btn{font-size:var(--neu-text-sm);padding:.5rem var(--neu-space-4)}.neu-toggle-group--lg .neu-toggle-group__btn{font-size:var(--neu-text-base);padding:.625rem var(--neu-space-5)}\n"] }]
154
+ `, styles: [".neu-toggle-group-host{display:inline-block}.neu-toggle-group{display:inline-flex;border:1px solid var(--neu-border);border-radius:var(--neu-radius);overflow:hidden;background:var(--neu-surface)}.neu-toggle-group__btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:none;border-right:1px solid var(--neu-border);background:transparent;color:var(--neu-text-muted);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;line-height:1;white-space:nowrap;cursor:pointer;padding:.5rem var(--neu-space-4);transition:background-color .15s ease,color .15s ease,border-color .15s ease;outline:none;-webkit-user-select:none;user-select:none}.neu-toggle-group__btn:last-child{border-right:none}.neu-toggle-group__btn:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-toggle-group__btn:focus-visible{position:relative;z-index:1;box-shadow:inset 0 0 0 2px var(--neu-primary)}.neu-toggle-group__btn--active{background:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-primary-solid-fg, var(--neu-primary-fg));border-right-color:var(--neu-primary-solid-hover, var(--neu-primary-dark))}.neu-toggle-group__btn--active:hover:not(:disabled):not(.neu-toggle-group__btn--disabled){background:var(--neu-primary-solid-hover, var(--neu-primary-dark));color:var(--neu-primary-solid-fg, var(--neu-primary-fg))}.neu-toggle-group__btn--active+.neu-toggle-group__btn{border-left-color:var(--neu-primary-solid-hover, var(--neu-primary-dark))}.neu-toggle-group__btn--disabled{opacity:.45;cursor:not-allowed}.neu-toggle-group--disabled{opacity:.6;pointer-events:none}.neu-toggle-group--sm .neu-toggle-group__btn{font-size:var(--neu-text-xs);padding:.375rem var(--neu-space-3)}.neu-toggle-group--md .neu-toggle-group__btn{font-size:var(--neu-text-sm);padding:.5rem var(--neu-space-4)}.neu-toggle-group--lg .neu-toggle-group__btn{font-size:var(--neu-text-base);padding:.625rem var(--neu-space-5)}\n"] }]
155
155
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], neuChange: [{ type: i0.Output, args: ["neuChange"] }] } });
156
156
 
157
157
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-toggle-button-group.mjs","sources":["../../../../projects/ui-core/toggle-button-group/neu-toggle-button-group.component.ts","../../../../projects/ui-core/toggle-button-group/neural-ui-core-toggle-button-group.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n forwardRef,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { NeuButtonSize } from '@neural-ui/core/button';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nexport interface NeuToggleOption<T = unknown> {\n /** Texto visible del botón / Visible button text */\n label: string;\n /** Valor asociado a esta opción / Value associated with this option */\n value: T;\n /** Nombre de icono Lucide (opcional) / Lucide icon name (optional) */\n icon?: string;\n /** Deshabilita solo esta opción / Disables this option only */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI ToggleButtonGroup Component\n *\n * Grupo de botones de selección (single o múltiple). / Selection button group (single or multiple).\n * Selector segmentado para selección única o múltiple. / Segmented selector for single or multiple selection.\n *\n * Uso (single):\n * <neu-toggle-button-group [options]=\"opts\" [formControl]=\"valueCtrl\" />\n *\n * Uso (múltiple):\n * <neu-toggle-button-group [options]=\"opts\" [multiple]=\"true\" [formControl]=\"valuesCtrl\" />\n */\n@Component({\n selector: 'neu-toggle-button-group',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuToggleButtonGroupComponent),\n multi: true,\n },\n ],\n host: { class: 'neu-toggle-group-host' },\n template: `\n <div\n class=\"neu-toggle-group\"\n [class]=\"groupClasses()\"\n role=\"group\"\n [attr.aria-disabled]=\"_isDisabled() || null\"\n >\n @for (opt of options(); track opt.value) {\n <button\n type=\"button\"\n class=\"neu-toggle-group__btn\"\n [class.neu-toggle-group__btn--active]=\"isSelected(opt.value)\"\n [class.neu-toggle-group__btn--disabled]=\"opt.disabled || _isDisabled()\"\n [attr.aria-pressed]=\"isSelected(opt.value)\"\n [disabled]=\"opt.disabled || _isDisabled() ? '' : null\"\n (click)=\"toggle(opt)\"\n (blur)=\"onBlur()\"\n >\n @if (opt.icon) {\n <neu-icon [name]=\"opt.icon\" size=\"16px\" strokeWidth=\"2\" />\n }\n {{ opt.label }}\n </button>\n }\n </div>\n `,\n styleUrl: './neu-toggle-button-group.component.scss',\n})\nexport class NeuToggleButtonGroupComponent<T = unknown> implements ControlValueAccessor {\n /** Lista de opciones del grupo / Group option list */\n options = input<NeuToggleOption<T>[]>([]);\n\n /**\n * Permite seleccionar múltiples opciones.\n * - false (por defecto): valor es `T | null`\n * - true: valor es `T[]`\n */\n multiple = input<boolean>(false);\n\n /** Tamaño visual / Visual size */\n size = input<NeuButtonSize>('md');\n\n /** Deshabilita todo el grupo / Disables the entire group */\n disabled = input<boolean>(false);\n\n /** Emite el nuevo valor al cambiar (útil sin formControl) / Emits the new value on change (useful without formControl) */\n neuChange = output<T | T[] | null>();\n\n readonly _value = signal<T | T[] | null>(null);\n readonly _isDisabled = signal(false);\n\n readonly groupClasses = computed(() => ({\n 'neu-toggle-group': true,\n [`neu-toggle-group--${this.size()}`]: true,\n 'neu-toggle-group--disabled': this._isDisabled(),\n }));\n\n isSelected(value: T): boolean {\n const v = this._value();\n if (this.multiple()) {\n return Array.isArray(v) && (v as T[]).includes(value);\n }\n return v === value;\n }\n\n toggle(opt: NeuToggleOption<T>): void {\n if (opt.disabled || this._isDisabled()) return;\n\n let next: T | T[] | null;\n\n if (this.multiple()) {\n const current: T[] = Array.isArray(this._value()) ? (this._value() as T[]) : [];\n const idx = current.indexOf(opt.value);\n next = idx >= 0 ? current.filter((_, i) => i !== idx) : [...current, opt.value];\n } else {\n next = this._value() === opt.value ? null : opt.value;\n }\n\n this._value.set(next);\n this._onChange(next);\n this._onTouched();\n this.neuChange.emit(next);\n }\n\n onBlur(): void {\n this._onTouched();\n }\n\n // ---- CVA ----\n\n private _onChange: (v: unknown) => void = () => {};\n private _onTouched: () => void = () => {};\n\n writeValue(val: T | T[] | null): void {\n if (val === null || val === undefined) {\n this._value.set(this.multiple() ? ([] as T[]) : null);\n } else {\n this._value.set(val);\n }\n }\n\n registerOnChange(fn: (v: unknown) => 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._isDisabled.set(isDisabled);\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-toggle-button-group.mjs","sources":["../../../../projects/ui-core/toggle-button-group/neu-toggle-button-group.component.ts","../../../../projects/ui-core/toggle-button-group/neural-ui-core-toggle-button-group.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n forwardRef,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { NeuButtonSize } from '@neural-ui/core/button';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nexport interface NeuToggleOption<T = unknown> {\n /** Texto visible del botón / Visible button text */\n label: string;\n /** Valor asociado a esta opción / Value associated with this option */\n value: T;\n /** Nombre de icono Lucide (opcional) / Lucide icon name (optional) */\n icon?: string;\n /** Deshabilita solo esta opción / Disables this option only */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI ToggleButtonGroup Component\n *\n * Grupo de botones de selección (single o múltiple). / Selection button group (single or multiple).\n * Selector segmentado para selección única o múltiple. / Segmented selector for single or multiple selection.\n *\n * Uso (single):\n * <neu-toggle-button-group [options]=\"opts\" [formControl]=\"valueCtrl\" />\n *\n * Uso (múltiple):\n * <neu-toggle-button-group [options]=\"opts\" [multiple]=\"true\" [formControl]=\"valuesCtrl\" />\n */\n@Component({\n selector: 'neu-toggle-button-group',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuToggleButtonGroupComponent),\n multi: true,\n },\n ],\n host: { class: 'neu-toggle-group-host' },\n template: `\n <div\n class=\"neu-toggle-group\"\n [class]=\"groupClasses()\"\n role=\"group\"\n [attr.aria-disabled]=\"_isDisabled() || null\"\n >\n @for (opt of options(); track opt.value) {\n <button\n type=\"button\"\n class=\"neu-toggle-group__btn\"\n [class.neu-toggle-group__btn--active]=\"isSelected(opt.value)\"\n [class.neu-toggle-group__btn--disabled]=\"opt.disabled || _isDisabled()\"\n [attr.aria-pressed]=\"isSelected(opt.value)\"\n [disabled]=\"opt.disabled || _isDisabled() ? '' : null\"\n (click)=\"toggle(opt)\"\n (blur)=\"onBlur()\"\n >\n @if (opt.icon) {\n <neu-icon [name]=\"opt.icon\" size=\"16px\" strokeWidth=\"2\" />\n }\n {{ opt.label }}\n </button>\n }\n </div>\n `,\n styleUrl: './neu-toggle-button-group.component.scss',\n})\nexport class NeuToggleButtonGroupComponent<T = unknown> implements ControlValueAccessor {\n /** Lista de opciones del grupo / Group option list */\n options = input<NeuToggleOption<T>[]>([]);\n\n /**\n * Permite seleccionar múltiples opciones.\n * - false (por defecto): valor es `T | null`\n * - true: valor es `T[]`\n */\n multiple = input<boolean>(false);\n\n /** Tamaño visual / Visual size */\n size = input<NeuButtonSize>('md');\n\n /** Deshabilita todo el grupo / Disables the entire group */\n disabled = input<boolean>(false);\n\n /** Emite el nuevo valor al cambiar (útil sin formControl) / Emits the new value on change (useful without formControl) */\n neuChange = output<T | T[] | null>();\n\n readonly _value = signal<T | T[] | null>(null);\n readonly _isDisabled = signal(false);\n\n readonly groupClasses = computed(() => ({\n 'neu-toggle-group': true,\n [`neu-toggle-group--${this.size()}`]: true,\n 'neu-toggle-group--disabled': this._isDisabled(),\n }));\n\n isSelected(value: T): boolean {\n const v = this._value();\n if (this.multiple()) {\n return Array.isArray(v) && (v as T[]).includes(value);\n }\n return v === value;\n }\n\n toggle(opt: NeuToggleOption<T>): void {\n if (opt.disabled || this._isDisabled()) return;\n\n let next: T | T[] | null;\n\n if (this.multiple()) {\n const current: T[] = Array.isArray(this._value()) ? (this._value() as T[]) : [];\n const idx = current.indexOf(opt.value);\n next = idx >= 0 ? current.filter((_, i) => i !== idx) : [...current, opt.value];\n } else {\n next = this._value() === opt.value ? null : opt.value;\n }\n\n this._value.set(next);\n this._onChange(next);\n this._onTouched();\n this.neuChange.emit(next);\n }\n\n onBlur(): void {\n this._onTouched();\n }\n\n // ---- CVA ----\n\n private _onChange: (v: unknown) => void = () => {};\n private _onTouched: () => void = () => {};\n\n writeValue(val: T | T[] | null): void {\n if (val === null || val === undefined) {\n this._value.set(this.multiple() ? ([] as T[]) : null);\n } else {\n this._value.set(val);\n }\n }\n\n registerOnChange(fn: (v: unknown) => 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._isDisabled.set(isDisabled);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -41,7 +41,7 @@ class NeuToolbarComponent {
41
41
  <ng-content select="[neu-toolbar-end]" />
42
42
  </div>
43
43
  <ng-content />
44
- `, isInline: true, styles: ["@charset \"UTF-8\";.neu-toolbar{display:flex;align-items:center;width:100%;gap:8px;background:var(--neu-toolbar-bg, var(--neu-surface-1, #ffffff));color:var(--neu-toolbar-color, var(--neu-text-primary, #111))}.neu-toolbar--sm{padding:6px 12px;min-height:40px}.neu-toolbar--md{padding:8px 16px;min-height:52px}.neu-toolbar--lg{padding:12px 20px;min-height:64px}.neu-toolbar--primary{background:var(--neu-toolbar-primary-bg, var(--neu-color-primary, #0ea5e9));color:var(--neu-toolbar-primary-color, #fff)}.neu-toolbar--none{background:transparent}.neu-toolbar--shadow{box-shadow:0 1px 4px #0000001a}.neu-toolbar--bordered{border-bottom:1px solid var(--neu-border-color, #e5e7eb)}.neu-toolbar__section{display:flex;align-items:center;gap:8px}.neu-toolbar__section--start{flex:0 0 auto;margin-right:auto}.neu-toolbar__section--center{flex:0 1 auto;justify-content:center}.neu-toolbar__section--end{flex:0 0 auto;margin-left:auto}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
44
+ `, isInline: true, styles: ["@charset \"UTF-8\";.neu-toolbar{display:flex;align-items:center;width:100%;gap:8px;background:var(--neu-toolbar-bg, var(--neu-surface-1, #ffffff));color:var(--neu-toolbar-color, var(--neu-text-primary, #111))}.neu-toolbar--sm{padding:6px 12px;min-height:40px}.neu-toolbar--md{padding:8px 16px;min-height:52px}.neu-toolbar--lg{padding:12px 20px;min-height:64px}.neu-toolbar--primary{background:var(--neu-toolbar-primary-bg, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-toolbar-primary-color, #fff)}.neu-toolbar--primary .neu-button--ghost{color:#ffffffeb}.neu-toolbar--primary .neu-button--ghost:hover:not(:disabled):not(.neu-button--disabled){background:#ffffff1f;color:#fff}.neu-toolbar--none{background:transparent}.neu-toolbar--shadow{box-shadow:0 1px 4px #0000001a}.neu-toolbar--bordered{border-bottom:1px solid var(--neu-border-color, #e5e7eb)}.neu-toolbar__section{display:flex;align-items:center;gap:8px}.neu-toolbar__section--start{flex:0 0 auto;margin-right:auto}.neu-toolbar__section--center{flex:0 1 auto;justify-content:center}.neu-toolbar__section--end{flex:0 0 auto;margin-left:auto}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
45
45
  }
46
46
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuToolbarComponent, decorators: [{
47
47
  type: Component,
@@ -56,7 +56,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
56
56
  <ng-content select="[neu-toolbar-end]" />
57
57
  </div>
58
58
  <ng-content />
59
- `, styles: ["@charset \"UTF-8\";.neu-toolbar{display:flex;align-items:center;width:100%;gap:8px;background:var(--neu-toolbar-bg, var(--neu-surface-1, #ffffff));color:var(--neu-toolbar-color, var(--neu-text-primary, #111))}.neu-toolbar--sm{padding:6px 12px;min-height:40px}.neu-toolbar--md{padding:8px 16px;min-height:52px}.neu-toolbar--lg{padding:12px 20px;min-height:64px}.neu-toolbar--primary{background:var(--neu-toolbar-primary-bg, var(--neu-color-primary, #0ea5e9));color:var(--neu-toolbar-primary-color, #fff)}.neu-toolbar--none{background:transparent}.neu-toolbar--shadow{box-shadow:0 1px 4px #0000001a}.neu-toolbar--bordered{border-bottom:1px solid var(--neu-border-color, #e5e7eb)}.neu-toolbar__section{display:flex;align-items:center;gap:8px}.neu-toolbar__section--start{flex:0 0 auto;margin-right:auto}.neu-toolbar__section--center{flex:0 1 auto;justify-content:center}.neu-toolbar__section--end{flex:0 0 auto;margin-left:auto}\n"] }]
59
+ `, styles: ["@charset \"UTF-8\";.neu-toolbar{display:flex;align-items:center;width:100%;gap:8px;background:var(--neu-toolbar-bg, var(--neu-surface-1, #ffffff));color:var(--neu-toolbar-color, var(--neu-text-primary, #111))}.neu-toolbar--sm{padding:6px 12px;min-height:40px}.neu-toolbar--md{padding:8px 16px;min-height:52px}.neu-toolbar--lg{padding:12px 20px;min-height:64px}.neu-toolbar--primary{background:var(--neu-toolbar-primary-bg, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-toolbar-primary-color, #fff)}.neu-toolbar--primary .neu-button--ghost{color:#ffffffeb}.neu-toolbar--primary .neu-button--ghost:hover:not(:disabled):not(.neu-button--disabled){background:#ffffff1f;color:#fff}.neu-toolbar--none{background:transparent}.neu-toolbar--shadow{box-shadow:0 1px 4px #0000001a}.neu-toolbar--bordered{border-bottom:1px solid var(--neu-border-color, #e5e7eb)}.neu-toolbar__section{display:flex;align-items:center;gap:8px}.neu-toolbar__section--start{flex:0 0 auto;margin-right:auto}.neu-toolbar__section--center{flex:0 1 auto;justify-content:center}.neu-toolbar__section--end{flex:0 0 auto;margin-left:auto}\n"] }]
60
60
  }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shadow: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], surface: [{ type: i0.Input, args: [{ isSignal: true, alias: "surface", required: false }] }] } });
61
61
 
62
62
  /**