@neural-ui/core 1.4.0 → 1.5.1

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 (80) hide show
  1. package/README.md +2 -1
  2. package/calendar/package.json +4 -0
  3. package/fesm2022/neural-ui-core-autocomplete.mjs +2 -2
  4. package/fesm2022/neural-ui-core-block-ui.mjs +2 -2
  5. package/fesm2022/neural-ui-core-button.mjs +2 -2
  6. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  7. package/fesm2022/neural-ui-core-calendar.mjs +551 -0
  8. package/fesm2022/neural-ui-core-calendar.mjs.map +1 -0
  9. package/fesm2022/neural-ui-core-chip.mjs +2 -2
  10. package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
  11. package/fesm2022/neural-ui-core-confirm-dialog.mjs +2 -2
  12. package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -1
  13. package/fesm2022/neural-ui-core-dashboard-grid.mjs +2 -2
  14. package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
  15. package/fesm2022/neural-ui-core-date-input.mjs +2 -2
  16. package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
  17. package/fesm2022/neural-ui-core-image-gallery.mjs +224 -0
  18. package/fesm2022/neural-ui-core-image-gallery.mjs.map +1 -0
  19. package/fesm2022/neural-ui-core-input.mjs +2 -2
  20. package/fesm2022/neural-ui-core-kanban.mjs +270 -0
  21. package/fesm2022/neural-ui-core-kanban.mjs.map +1 -0
  22. package/fesm2022/neural-ui-core-meter-group.mjs +2 -2
  23. package/fesm2022/neural-ui-core-multiselect.mjs +13 -2
  24. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  25. package/fesm2022/neural-ui-core-nav.mjs +2 -2
  26. package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
  27. package/fesm2022/neural-ui-core-number-input.mjs +2 -2
  28. package/fesm2022/neural-ui-core-pagination.mjs +2 -2
  29. package/fesm2022/neural-ui-core-pagination.mjs.map +1 -1
  30. package/fesm2022/neural-ui-core-progress-bar.mjs +2 -2
  31. package/fesm2022/neural-ui-core-scheduler-gantt.mjs +289 -0
  32. package/fesm2022/neural-ui-core-scheduler-gantt.mjs.map +1 -0
  33. package/fesm2022/neural-ui-core-select.mjs +31 -9
  34. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  35. package/fesm2022/neural-ui-core-sidebar.mjs +103 -7
  36. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  37. package/fesm2022/neural-ui-core-slider.mjs +2 -2
  38. package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
  39. package/fesm2022/neural-ui-core-split-button.mjs +2 -2
  40. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  41. package/fesm2022/neural-ui-core-stepper.mjs +2 -2
  42. package/fesm2022/neural-ui-core-stepper.mjs.map +1 -1
  43. package/fesm2022/neural-ui-core-table.mjs +273 -19
  44. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  45. package/fesm2022/neural-ui-core-textarea.mjs +2 -2
  46. package/fesm2022/neural-ui-core-timeline-grid.mjs +215 -0
  47. package/fesm2022/neural-ui-core-timeline-grid.mjs.map +1 -0
  48. package/fesm2022/neural-ui-core-toggle-button-group.mjs +2 -2
  49. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
  50. package/fesm2022/neural-ui-core-tree-table.mjs +262 -0
  51. package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -0
  52. package/fesm2022/neural-ui-core-tree.mjs +413 -0
  53. package/fesm2022/neural-ui-core-tree.mjs.map +1 -0
  54. package/fesm2022/neural-ui-core-uploader.mjs +624 -0
  55. package/fesm2022/neural-ui-core-uploader.mjs.map +1 -0
  56. package/fesm2022/neural-ui-core-virtual-list.mjs +2 -2
  57. package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
  58. package/fesm2022/neural-ui-core.mjs +3 -1
  59. package/fesm2022/neural-ui-core.mjs.map +1 -1
  60. package/image-gallery/package.json +4 -0
  61. package/kanban/package.json +4 -0
  62. package/package.json +34 -2
  63. package/scheduler-gantt/package.json +4 -0
  64. package/styles/_tokens.scss +13 -4
  65. package/timeline-grid/package.json +4 -0
  66. package/tree/package.json +4 -0
  67. package/tree-table/package.json +4 -0
  68. package/types/neural-ui-core-calendar.d.ts +79 -0
  69. package/types/neural-ui-core-image-gallery.d.ts +26 -0
  70. package/types/neural-ui-core-kanban.d.ts +52 -0
  71. package/types/neural-ui-core-multiselect.d.ts +1 -0
  72. package/types/neural-ui-core-scheduler-gantt.d.ts +68 -0
  73. package/types/neural-ui-core-select.d.ts +2 -0
  74. package/types/neural-ui-core-sidebar.d.ts +18 -1
  75. package/types/neural-ui-core-table.d.ts +44 -2
  76. package/types/neural-ui-core-timeline-grid.d.ts +55 -0
  77. package/types/neural-ui-core-tree-table.d.ts +72 -0
  78. package/types/neural-ui-core-tree.d.ts +52 -0
  79. package/types/neural-ui-core-uploader.d.ts +98 -0
  80. package/uploader/package.json +4 -0
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, computed, input, output, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
2
+ import { inject, ElementRef, computed, input, output, effect, HostListener, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
3
3
  import { DOCUMENT } from '@angular/common';
4
4
  import { NeuUrlStateService } from '@neural-ui/core/url-state';
5
5
  import { NeuIconComponent } from '@neural-ui/core/icon';
@@ -48,8 +48,10 @@ function unlockDocumentScroll(document) {
48
48
  */
49
49
  class NeuSidebarComponent {
50
50
  document = inject(DOCUMENT);
51
+ elementRef = inject(ElementRef);
51
52
  urlState = inject(NeuUrlStateService);
52
53
  openParam = computed(() => this.urlState.getParam(this.urlParam()), ...(ngDevMode ? [{ debugName: "openParam" }] : /* istanbul ignore next */ []));
54
+ previousActiveElement = null;
53
55
  /** Posición del sidebar: izquierda o derecha de la pantalla / Sidebar position: left or right of the screen */
54
56
  side = input('left', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
55
57
  /** QueryParam que controla el estado. Default: 'menu' (?menu=open) / QueryParam that controls the state. Default: 'menu' (?menu=open) */
@@ -68,8 +70,15 @@ class NeuSidebarComponent {
68
70
  ariaLabel = input('Menú de navegación', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
69
71
  /** Etiqueta accesible para el botón cerrar / Accessible label for the close button */
70
72
  closeLabel = input('Cerrar menú de navegación', ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
73
+ /**
74
+ * Modo colapsado: el sidebar muestra solo iconos (icon-only en desktop).
75
+ * Útil para sidebars persistentes en modo compact / Collapsed mode: sidebar shows only icons.
76
+ */
77
+ collapsed = input(false, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
71
78
  /** Emite cuando el usuario cierra el sidebar (overlay click o botón) / Emits when the user closes the sidebar (overlay click or button) */
72
79
  closeRequested = output();
80
+ /** Emite cuando el estado collapsed cambia / Emits when collapsed state changes */
81
+ collapsedChange = output();
73
82
  /** Signal reactivo: true si el sidebar debe mostrarse / Reactive signal: true if the sidebar should be shown */
74
83
  isOpen = computed(() => {
75
84
  if (this.persistent())
@@ -87,6 +96,27 @@ class NeuSidebarComponent {
87
96
  unlockDocumentScroll(this.document);
88
97
  });
89
98
  });
99
+ // Focus management: save previous element and move focus to sidebar when opening in drawer mode
100
+ effect(() => {
101
+ const isOpenNow = this.isOpen();
102
+ const isPersistent = this.persistent();
103
+ if (isPersistent) {
104
+ return;
105
+ }
106
+ if (isOpenNow) {
107
+ // Save the current active element
108
+ this.previousActiveElement = this.document.activeElement;
109
+ // Move focus to first focusable element inside the sidebar
110
+ this.focusFirstElement();
111
+ }
112
+ else if (this.previousActiveElement && this.previousActiveElement.focus) {
113
+ // Restore focus to the element that had it before opening
114
+ setTimeout(() => {
115
+ this.previousActiveElement?.focus();
116
+ this.previousActiveElement = null;
117
+ }, 0);
118
+ }
119
+ });
90
120
  }
91
121
  /** Abre el sidebar — añade ?{urlParam}=open a la URL / Opens the sidebar — adds ?{urlParam}=open to the URL */
92
122
  open(replaceUrl = false) {
@@ -97,8 +127,67 @@ class NeuSidebarComponent {
97
127
  this.urlState.setParam(this.urlParam(), null, true);
98
128
  this.closeRequested.emit();
99
129
  }
130
+ /** Alterna el estado collapsed / Toggles collapsed state */
131
+ toggleCollapsed() {
132
+ const newState = !this.collapsed();
133
+ this.collapsedChange.emit(newState);
134
+ }
135
+ /** Obtiene los elementos focusables dentro del sidebar / Gets focusable elements inside sidebar */
136
+ getFocusableElements() {
137
+ const focusableSelectors = [
138
+ 'button',
139
+ 'a[href]',
140
+ 'input:not([disabled])',
141
+ 'select:not([disabled])',
142
+ 'textarea:not([disabled])',
143
+ '[tabindex]:not([tabindex="-1"])',
144
+ ].join(',');
145
+ const aside = this.elementRef.nativeElement.querySelector('aside.neu-sidebar');
146
+ if (!aside) {
147
+ return [];
148
+ }
149
+ return Array.from(aside.querySelectorAll(focusableSelectors));
150
+ }
151
+ /** Mueve el foco al primer elemento focusable / Moves focus to first focusable element */
152
+ focusFirstElement() {
153
+ setTimeout(() => {
154
+ const focusable = this.getFocusableElements();
155
+ if (focusable.length > 0) {
156
+ focusable[0].focus();
157
+ }
158
+ }, 0);
159
+ }
160
+ /** Focus trap: cicla entre elementos focusables con Tab/Shift+Tab / Focus trap cycling */
161
+ onKeyDown(event) {
162
+ if (!this.isOpen() || this.persistent()) {
163
+ return;
164
+ }
165
+ if (event.key !== 'Tab') {
166
+ return;
167
+ }
168
+ const focusable = this.getFocusableElements();
169
+ if (focusable.length === 0) {
170
+ return;
171
+ }
172
+ const activeElement = this.document.activeElement;
173
+ const currentIndex = focusable.indexOf(activeElement);
174
+ if (event.shiftKey) {
175
+ // Shift+Tab — go to previous
176
+ if (currentIndex <= 0) {
177
+ event.preventDefault();
178
+ focusable[focusable.length - 1].focus();
179
+ }
180
+ }
181
+ else {
182
+ // Tab — go to next
183
+ if (currentIndex >= focusable.length - 1) {
184
+ event.preventDefault();
185
+ focusable[0].focus();
186
+ }
187
+ }
188
+ }
100
189
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
101
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuSidebarComponent, isStandalone: true, selector: "neu-sidebar", inputs: { side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, urlParam: { classPropertyName: "urlParam", publicName: "urlParam", isSignal: true, isRequired: false, transformFunction: null }, persistent: { classPropertyName: "persistent", publicName: "persistent", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequested: "closeRequested" }, ngImport: i0, template: `
190
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuSidebarComponent, isStandalone: true, selector: "neu-sidebar", inputs: { side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, urlParam: { classPropertyName: "urlParam", publicName: "urlParam", isSignal: true, isRequired: false, transformFunction: null }, persistent: { classPropertyName: "persistent", publicName: "persistent", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequested: "closeRequested", collapsedChange: "collapsedChange" }, host: { listeners: { "keydown": "onKeyDown($event)" } }, ngImport: i0, template: `
102
191
  <!-- Overlay de fondo — solo visible en modo overlay -->
103
192
  @if (!persistent()) {
104
193
  <div
@@ -114,8 +203,10 @@ class NeuSidebarComponent {
114
203
  class="neu-sidebar"
115
204
  [class.neu-sidebar--open]="isOpen()"
116
205
  [class.neu-sidebar--persistent]="persistent()"
206
+ [class.neu-sidebar--collapsed]="collapsed()"
117
207
  [class.neu-sidebar--right]="side() === 'right'"
118
- role="navigation"
208
+ [attr.role]="persistent() ? 'navigation' : 'dialog'"
209
+ [attr.aria-modal]="!persistent()"
119
210
  [attr.aria-label]="ariaLabel()"
120
211
  [attr.aria-hidden]="!isOpen() && !persistent()"
121
212
  [attr.inert]="!isOpen() && !persistent() ? '' : null"
@@ -149,7 +240,7 @@ class NeuSidebarComponent {
149
240
  <ng-content select="[neu-sidebar-footer]" />
150
241
  </div>
151
242
  </aside>
152
- `, isInline: true, styles: [".neu-sidebar__overlay{position:fixed;inset:0;background:var(--neu-overlay-bg-soft);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:var(--neu-z-overlay);opacity:0;pointer-events:none;transition:opacity var(--neu-transition-slow)}.neu-sidebar__overlay--visible{opacity:1;pointer-events:all}.neu-sidebar{position:fixed;top:0;left:0;height:100dvh;width:100%;background:var(--neu-sidebar-bg, var(--neu-surface));border-right:1px solid var(--neu-border);z-index:var(--neu-z-sidebar);display:flex;flex-direction:column;transform:translate(-100%);transition:transform var(--neu-transition-slow),box-shadow var(--neu-transition-slow);overflow:hidden}@media(min-width:400px){.neu-sidebar{width:var(--neu-sidebar-width, 260px)}}.neu-sidebar--open:not(.neu-sidebar--persistent):not(.neu-sidebar--right){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--right{left:auto;right:0;border-right:none;border-left:1px solid var(--neu-border);transform:translate(100%)}.neu-sidebar--right.neu-sidebar--open:not(.neu-sidebar--persistent){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--persistent{position:sticky;top:var(--neu-header-height);height:calc(100dvh - var(--neu-header-height));transform:none;box-shadow:none;border-right:1px solid var(--neu-border);flex-shrink:0;z-index:var(--neu-z-base)}.neu-sidebar__header{display:flex;align-items:center;justify-content:space-between;padding:0 var(--neu-space-5);min-height:var(--neu-header-height, 64px);border-bottom:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__title{font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:700;letter-spacing:-.01em;color:var(--neu-text)}.neu-sidebar__close{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--neu-radius);color:var(--neu-text-muted);cursor:pointer;flex-shrink:0;transition:background-color var(--neu-transition),color var(--neu-transition),border-color var(--neu-transition)}.neu-sidebar__close:hover{background:var(--neu-surface-2);color:var(--neu-text);border-color:var(--neu-border)}.neu-sidebar__close:focus-visible{outline:none;box-shadow:var(--neu-focus-ring-strong)}.neu-sidebar__content{flex:1;overflow-y:auto;overflow-x:hidden;padding:var(--neu-space-3) 0;scrollbar-width:thin;scrollbar-color:var(--neu-surface-3) transparent}.neu-sidebar__content::-webkit-scrollbar{width:4px}.neu-sidebar__content::-webkit-scrollbar-track{background:transparent}.neu-sidebar__content::-webkit-scrollbar-thumb{background:var(--neu-surface-3);border-radius:var(--neu-radius-full)}.neu-sidebar__footer{padding:var(--neu-space-4) var(--neu-space-5);border-top:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__footer:empty{display:none}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
243
+ `, isInline: true, styles: [".neu-sidebar__overlay{position:fixed;inset:0;background:var(--neu-overlay-bg-soft);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:var(--neu-z-overlay);opacity:0;pointer-events:none;transition:opacity var(--neu-transition-slow)}.neu-sidebar__overlay--visible{opacity:1;pointer-events:all}.neu-sidebar{position:fixed;top:0;left:0;height:100dvh;width:100%;background:var(--neu-sidebar-bg, var(--neu-surface));border-right:1px solid var(--neu-border);z-index:var(--neu-z-sidebar);display:flex;flex-direction:column;transform:translate(-100%);transition:transform var(--neu-transition-slow),box-shadow var(--neu-transition-slow);overflow:hidden}@media(min-width:400px){.neu-sidebar{width:var(--neu-sidebar-width, 260px)}}.neu-sidebar--open:not(.neu-sidebar--persistent):not(.neu-sidebar--right){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--right{left:auto;right:0;border-right:none;border-left:1px solid var(--neu-border);transform:translate(100%)}.neu-sidebar--right.neu-sidebar--open:not(.neu-sidebar--persistent){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--persistent{position:sticky;top:var(--neu-header-height);height:calc(100dvh - var(--neu-header-height));transform:none;box-shadow:none;border-right:1px solid var(--neu-border);flex-shrink:0;z-index:var(--neu-z-base)}.neu-sidebar__header{display:flex;align-items:center;justify-content:space-between;padding:0 var(--neu-space-5);min-height:var(--neu-header-height, 64px);border-bottom:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__title{font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:700;letter-spacing:-.01em;color:var(--neu-text)}.neu-sidebar__close{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--neu-radius);color:var(--neu-text-muted);cursor:pointer;flex-shrink:0;transition:background-color var(--neu-transition),color var(--neu-transition),border-color var(--neu-transition)}.neu-sidebar__close:hover{background:var(--neu-surface-2);color:var(--neu-text);border-color:var(--neu-border)}.neu-sidebar__close:focus-visible{outline:none;box-shadow:var(--neu-focus-ring-strong)}.neu-sidebar__content{flex:1;overflow-y:auto;overflow-x:hidden;padding:var(--neu-space-3) 0;scrollbar-width:thin;scrollbar-color:var(--neu-surface-3) transparent}.neu-sidebar__content::-webkit-scrollbar{width:4px}.neu-sidebar__content::-webkit-scrollbar-track{background:transparent}.neu-sidebar__content::-webkit-scrollbar-thumb{background:var(--neu-surface-3);border-radius:var(--neu-radius-full)}.neu-sidebar__footer{padding:var(--neu-space-4) var(--neu-space-5);border-top:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__footer:empty{display:none}.neu-sidebar--collapsed{width:var(--neu-sidebar-collapsed-width, 60px)!important}.neu-sidebar--collapsed .neu-sidebar__header{flex-direction:column;justify-content:center;padding:0;min-height:var(--neu-header-height, 64px)}.neu-sidebar--collapsed .neu-sidebar__header .neu-sidebar__title{display:none}.neu-sidebar--collapsed .neu-sidebar__content{padding:var(--neu-space-2) 0}.neu-sidebar--collapsed a span:not([neu-sidebar-header]),.neu-sidebar--collapsed button span:not([neu-sidebar-header]){max-width:0;overflow:hidden;opacity:0;transition:max-width var(--neu-transition),opacity var(--neu-transition)}.neu-sidebar--collapsed .neu-sidebar__footer{padding:var(--neu-space-2) var(--neu-space-3);min-height:auto}.neu-sidebar--collapsed .neu-sidebar__footer span{display:none}.neu-sidebar--collapsed .neu-sidebar__close{width:40px;height:40px}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
153
244
  }
154
245
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuSidebarComponent, decorators: [{
155
246
  type: Component,
@@ -169,8 +260,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
169
260
  class="neu-sidebar"
170
261
  [class.neu-sidebar--open]="isOpen()"
171
262
  [class.neu-sidebar--persistent]="persistent()"
263
+ [class.neu-sidebar--collapsed]="collapsed()"
172
264
  [class.neu-sidebar--right]="side() === 'right'"
173
- role="navigation"
265
+ [attr.role]="persistent() ? 'navigation' : 'dialog'"
266
+ [attr.aria-modal]="!persistent()"
174
267
  [attr.aria-label]="ariaLabel()"
175
268
  [attr.aria-hidden]="!isOpen() && !persistent()"
176
269
  [attr.inert]="!isOpen() && !persistent() ? '' : null"
@@ -204,8 +297,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
204
297
  <ng-content select="[neu-sidebar-footer]" />
205
298
  </div>
206
299
  </aside>
207
- `, styles: [".neu-sidebar__overlay{position:fixed;inset:0;background:var(--neu-overlay-bg-soft);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:var(--neu-z-overlay);opacity:0;pointer-events:none;transition:opacity var(--neu-transition-slow)}.neu-sidebar__overlay--visible{opacity:1;pointer-events:all}.neu-sidebar{position:fixed;top:0;left:0;height:100dvh;width:100%;background:var(--neu-sidebar-bg, var(--neu-surface));border-right:1px solid var(--neu-border);z-index:var(--neu-z-sidebar);display:flex;flex-direction:column;transform:translate(-100%);transition:transform var(--neu-transition-slow),box-shadow var(--neu-transition-slow);overflow:hidden}@media(min-width:400px){.neu-sidebar{width:var(--neu-sidebar-width, 260px)}}.neu-sidebar--open:not(.neu-sidebar--persistent):not(.neu-sidebar--right){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--right{left:auto;right:0;border-right:none;border-left:1px solid var(--neu-border);transform:translate(100%)}.neu-sidebar--right.neu-sidebar--open:not(.neu-sidebar--persistent){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--persistent{position:sticky;top:var(--neu-header-height);height:calc(100dvh - var(--neu-header-height));transform:none;box-shadow:none;border-right:1px solid var(--neu-border);flex-shrink:0;z-index:var(--neu-z-base)}.neu-sidebar__header{display:flex;align-items:center;justify-content:space-between;padding:0 var(--neu-space-5);min-height:var(--neu-header-height, 64px);border-bottom:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__title{font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:700;letter-spacing:-.01em;color:var(--neu-text)}.neu-sidebar__close{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--neu-radius);color:var(--neu-text-muted);cursor:pointer;flex-shrink:0;transition:background-color var(--neu-transition),color var(--neu-transition),border-color var(--neu-transition)}.neu-sidebar__close:hover{background:var(--neu-surface-2);color:var(--neu-text);border-color:var(--neu-border)}.neu-sidebar__close:focus-visible{outline:none;box-shadow:var(--neu-focus-ring-strong)}.neu-sidebar__content{flex:1;overflow-y:auto;overflow-x:hidden;padding:var(--neu-space-3) 0;scrollbar-width:thin;scrollbar-color:var(--neu-surface-3) transparent}.neu-sidebar__content::-webkit-scrollbar{width:4px}.neu-sidebar__content::-webkit-scrollbar-track{background:transparent}.neu-sidebar__content::-webkit-scrollbar-thumb{background:var(--neu-surface-3);border-radius:var(--neu-radius-full)}.neu-sidebar__footer{padding:var(--neu-space-4) var(--neu-space-5);border-top:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__footer:empty{display:none}\n"] }]
208
- }], ctorParameters: () => [], propDecorators: { side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], urlParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "urlParam", required: false }] }], persistent: [{ type: i0.Input, args: [{ isSignal: true, alias: "persistent", required: false }] }], hideHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideHeader", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }] } });
300
+ `, styles: [".neu-sidebar__overlay{position:fixed;inset:0;background:var(--neu-overlay-bg-soft);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:var(--neu-z-overlay);opacity:0;pointer-events:none;transition:opacity var(--neu-transition-slow)}.neu-sidebar__overlay--visible{opacity:1;pointer-events:all}.neu-sidebar{position:fixed;top:0;left:0;height:100dvh;width:100%;background:var(--neu-sidebar-bg, var(--neu-surface));border-right:1px solid var(--neu-border);z-index:var(--neu-z-sidebar);display:flex;flex-direction:column;transform:translate(-100%);transition:transform var(--neu-transition-slow),box-shadow var(--neu-transition-slow);overflow:hidden}@media(min-width:400px){.neu-sidebar{width:var(--neu-sidebar-width, 260px)}}.neu-sidebar--open:not(.neu-sidebar--persistent):not(.neu-sidebar--right){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--right{left:auto;right:0;border-right:none;border-left:1px solid var(--neu-border);transform:translate(100%)}.neu-sidebar--right.neu-sidebar--open:not(.neu-sidebar--persistent){transform:translate(0);box-shadow:var(--neu-shadow-lg)}.neu-sidebar--persistent{position:sticky;top:var(--neu-header-height);height:calc(100dvh - var(--neu-header-height));transform:none;box-shadow:none;border-right:1px solid var(--neu-border);flex-shrink:0;z-index:var(--neu-z-base)}.neu-sidebar__header{display:flex;align-items:center;justify-content:space-between;padding:0 var(--neu-space-5);min-height:var(--neu-header-height, 64px);border-bottom:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__title{font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:700;letter-spacing:-.01em;color:var(--neu-text)}.neu-sidebar__close{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--neu-radius);color:var(--neu-text-muted);cursor:pointer;flex-shrink:0;transition:background-color var(--neu-transition),color var(--neu-transition),border-color var(--neu-transition)}.neu-sidebar__close:hover{background:var(--neu-surface-2);color:var(--neu-text);border-color:var(--neu-border)}.neu-sidebar__close:focus-visible{outline:none;box-shadow:var(--neu-focus-ring-strong)}.neu-sidebar__content{flex:1;overflow-y:auto;overflow-x:hidden;padding:var(--neu-space-3) 0;scrollbar-width:thin;scrollbar-color:var(--neu-surface-3) transparent}.neu-sidebar__content::-webkit-scrollbar{width:4px}.neu-sidebar__content::-webkit-scrollbar-track{background:transparent}.neu-sidebar__content::-webkit-scrollbar-thumb{background:var(--neu-surface-3);border-radius:var(--neu-radius-full)}.neu-sidebar__footer{padding:var(--neu-space-4) var(--neu-space-5);border-top:1px solid var(--neu-border);flex-shrink:0}.neu-sidebar__footer:empty{display:none}.neu-sidebar--collapsed{width:var(--neu-sidebar-collapsed-width, 60px)!important}.neu-sidebar--collapsed .neu-sidebar__header{flex-direction:column;justify-content:center;padding:0;min-height:var(--neu-header-height, 64px)}.neu-sidebar--collapsed .neu-sidebar__header .neu-sidebar__title{display:none}.neu-sidebar--collapsed .neu-sidebar__content{padding:var(--neu-space-2) 0}.neu-sidebar--collapsed a span:not([neu-sidebar-header]),.neu-sidebar--collapsed button span:not([neu-sidebar-header]){max-width:0;overflow:hidden;opacity:0;transition:max-width var(--neu-transition),opacity var(--neu-transition)}.neu-sidebar--collapsed .neu-sidebar__footer{padding:var(--neu-space-2) var(--neu-space-3);min-height:auto}.neu-sidebar--collapsed .neu-sidebar__footer span{display:none}.neu-sidebar--collapsed .neu-sidebar__close{width:40px;height:40px}\n"] }]
301
+ }], ctorParameters: () => [], propDecorators: { side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], urlParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "urlParam", required: false }] }], persistent: [{ type: i0.Input, args: [{ isSignal: true, alias: "persistent", required: false }] }], hideHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideHeader", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }], collapsedChange: [{ type: i0.Output, args: ["collapsedChange"] }], onKeyDown: [{
302
+ type: HostListener,
303
+ args: ['keydown', ['$event']]
304
+ }] } });
209
305
 
210
306
  /**
211
307
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-sidebar.mjs","sources":["../../../../projects/ui-core/sidebar/neu-sidebar.component.ts","../../../../projects/ui-core/sidebar/neural-ui-core-sidebar.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nlet overlayScrollLockCount = 0;\nlet previousHtmlOverflow = '';\nlet previousBodyOverflow = '';\n\nfunction lockDocumentScroll(document: Document): void {\n if (overlayScrollLockCount === 0) {\n previousHtmlOverflow = document.documentElement.style.overflow;\n previousBodyOverflow = document.body.style.overflow;\n document.documentElement.style.overflow = 'hidden';\n document.body.style.overflow = 'hidden';\n }\n\n overlayScrollLockCount += 1;\n}\n\nfunction unlockDocumentScroll(document: Document): void {\n if (overlayScrollLockCount === 0) {\n return;\n }\n\n overlayScrollLockCount -= 1;\n\n if (overlayScrollLockCount === 0) {\n document.documentElement.style.overflow = previousHtmlOverflow;\n document.body.style.overflow = previousBodyOverflow;\n }\n}\n\n/**\n * NeuralUI Sidebar Component\n *\n * El estado abierto/cerrado se gestiona automáticamente desde la URL / The open/closed state is automatically managed from the URL\n * via NeuUrlStateService (?menu=open por defecto). / via NeuUrlStateService (?menu=open by default).\n *\n * Modos:\n * - overlay (default): panel flotante sobre el contenido con backdrop / floating panel above content with backdrop\n * - persistent: sidebar fijo integrado en el layout (desktop) / fixed sidebar integrated in the layout (desktop)\n *\n * Uso:\n * <neu-sidebar urlParam=\"menu\" [persistent]=\"isDesktop()\">\n * <span neu-sidebar-header>Mi App</span>\n * <nav>...</nav>\n * <div neu-sidebar-footer>...</div>\n * </neu-sidebar>\n *\n * Abrir desde cualquier parte: / Open from anywhere:\n * inject(NeuUrlStateService).setParam('menu', 'open', false);\n */\n@Component({\n selector: 'neu-sidebar',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- Overlay de fondo — solo visible en modo overlay -->\n @if (!persistent()) {\n <div\n class=\"neu-sidebar__overlay\"\n [class.neu-sidebar__overlay--visible]=\"isOpen()\"\n (click)=\"close()\"\n aria-hidden=\"true\"\n ></div>\n }\n\n <!-- Panel lateral -->\n <aside\n class=\"neu-sidebar\"\n [class.neu-sidebar--open]=\"isOpen()\"\n [class.neu-sidebar--persistent]=\"persistent()\"\n [class.neu-sidebar--right]=\"side() === 'right'\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"!isOpen() && !persistent()\"\n [attr.inert]=\"!isOpen() && !persistent() ? '' : null\"\n >\n <!-- Cabecera -->\n @if (!hideHeader()) {\n <div class=\"neu-sidebar__header\">\n <div class=\"neu-sidebar__title\">\n <ng-content select=\"[neu-sidebar-header]\" />\n </div>\n @if (!persistent()) {\n <button\n class=\"neu-sidebar__close\"\n (click)=\"close()\"\n [attr.aria-label]=\"closeLabel()\"\n type=\"button\"\n >\n <neu-icon name=\"lucideX\" size=\"18px\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n }\n\n <!-- Contenido -->\n <div class=\"neu-sidebar__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n <div class=\"neu-sidebar__footer\">\n <ng-content select=\"[neu-sidebar-footer]\" />\n </div>\n </aside>\n `,\n styleUrl: './neu-sidebar.component.scss',\n})\nexport class NeuSidebarComponent {\n private readonly document = inject(DOCUMENT);\n private readonly urlState = inject(NeuUrlStateService);\n private readonly openParam = computed(() => this.urlState.getParam(this.urlParam()));\n\n /** Posición del sidebar: izquierda o derecha de la pantalla / Sidebar position: left or right of the screen */\n side = input<'left' | 'right'>('left');\n\n /** QueryParam que controla el estado. Default: 'menu' (?menu=open) / QueryParam that controls the state. Default: 'menu' (?menu=open) */\n urlParam = input<string>('menu');\n\n /**\n * Modo persistente: el sidebar está siempre visible como parte del layout.\n * Usar en desktop (≥768px). El overlay y el toggle por URL no aplican.\n */\n persistent = input<boolean>(false);\n\n /**\n * Ocultar la cabecera del sidebar. Útil cuando el header ya está en el layout\n * principal y el sidebar persistente no necesita su propio header.\n */\n hideHeader = input<boolean>(false);\n\n /** Etiqueta accesible para el <aside> / Accessible label for the <aside> */\n ariaLabel = input<string>('Menú de navegación');\n\n /** Etiqueta accesible para el botón cerrar / Accessible label for the close button */\n closeLabel = input<string>('Cerrar menú de navegación');\n\n /** Emite cuando el usuario cierra el sidebar (overlay click o botón) / Emits when the user closes the sidebar (overlay click or button) */\n closeRequested = output<void>();\n\n /** Signal reactivo: true si el sidebar debe mostrarse / Reactive signal: true if the sidebar should be shown */\n readonly isOpen = computed(() => {\n if (this.persistent()) return true;\n return this.openParam()() === 'open';\n });\n\n constructor() {\n effect((onCleanup) => {\n const shouldLockScroll = !this.persistent() && this.isOpen();\n\n if (!shouldLockScroll) {\n return;\n }\n\n lockDocumentScroll(this.document);\n\n onCleanup(() => {\n unlockDocumentScroll(this.document);\n });\n });\n }\n\n /** Abre el sidebar — añade ?{urlParam}=open a la URL / Opens the sidebar — adds ?{urlParam}=open to the URL */\n open(replaceUrl = false): void {\n this.urlState.setParam(this.urlParam(), 'open', replaceUrl);\n }\n\n /** Cierra el sidebar — elimina el parámetro de la URL / Closes the sidebar — removes the URL parameter */\n close(): void {\n this.urlState.setParam(this.urlParam(), null, true);\n this.closeRequested.emit();\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-sidebar.mjs","sources":["../../../../projects/ui-core/sidebar/neu-sidebar.component.ts","../../../../projects/ui-core/sidebar/neural-ui-core-sidebar.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n ElementRef,\n HostListener,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nlet overlayScrollLockCount = 0;\nlet previousHtmlOverflow = '';\nlet previousBodyOverflow = '';\n\nfunction lockDocumentScroll(document: Document): void {\n if (overlayScrollLockCount === 0) {\n previousHtmlOverflow = document.documentElement.style.overflow;\n previousBodyOverflow = document.body.style.overflow;\n document.documentElement.style.overflow = 'hidden';\n document.body.style.overflow = 'hidden';\n }\n\n overlayScrollLockCount += 1;\n}\n\nfunction unlockDocumentScroll(document: Document): void {\n if (overlayScrollLockCount === 0) {\n return;\n }\n\n overlayScrollLockCount -= 1;\n\n if (overlayScrollLockCount === 0) {\n document.documentElement.style.overflow = previousHtmlOverflow;\n document.body.style.overflow = previousBodyOverflow;\n }\n}\n\n/**\n * NeuralUI Sidebar Component\n *\n * El estado abierto/cerrado se gestiona automáticamente desde la URL / The open/closed state is automatically managed from the URL\n * via NeuUrlStateService (?menu=open por defecto). / via NeuUrlStateService (?menu=open by default).\n *\n * Modos:\n * - overlay (default): panel flotante sobre el contenido con backdrop / floating panel above content with backdrop\n * - persistent: sidebar fijo integrado en el layout (desktop) / fixed sidebar integrated in the layout (desktop)\n *\n * Uso:\n * <neu-sidebar urlParam=\"menu\" [persistent]=\"isDesktop()\">\n * <span neu-sidebar-header>Mi App</span>\n * <nav>...</nav>\n * <div neu-sidebar-footer>...</div>\n * </neu-sidebar>\n *\n * Abrir desde cualquier parte: / Open from anywhere:\n * inject(NeuUrlStateService).setParam('menu', 'open', false);\n */\n@Component({\n selector: 'neu-sidebar',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- Overlay de fondo — solo visible en modo overlay -->\n @if (!persistent()) {\n <div\n class=\"neu-sidebar__overlay\"\n [class.neu-sidebar__overlay--visible]=\"isOpen()\"\n (click)=\"close()\"\n aria-hidden=\"true\"\n ></div>\n }\n\n <!-- Panel lateral -->\n <aside\n class=\"neu-sidebar\"\n [class.neu-sidebar--open]=\"isOpen()\"\n [class.neu-sidebar--persistent]=\"persistent()\"\n [class.neu-sidebar--collapsed]=\"collapsed()\"\n [class.neu-sidebar--right]=\"side() === 'right'\"\n [attr.role]=\"persistent() ? 'navigation' : 'dialog'\"\n [attr.aria-modal]=\"!persistent()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"!isOpen() && !persistent()\"\n [attr.inert]=\"!isOpen() && !persistent() ? '' : null\"\n >\n <!-- Cabecera -->\n @if (!hideHeader()) {\n <div class=\"neu-sidebar__header\">\n <div class=\"neu-sidebar__title\">\n <ng-content select=\"[neu-sidebar-header]\" />\n </div>\n @if (!persistent()) {\n <button\n class=\"neu-sidebar__close\"\n (click)=\"close()\"\n [attr.aria-label]=\"closeLabel()\"\n type=\"button\"\n >\n <neu-icon name=\"lucideX\" size=\"18px\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n }\n\n <!-- Contenido -->\n <div class=\"neu-sidebar__content\">\n <ng-content />\n </div>\n\n <!-- Footer -->\n <div class=\"neu-sidebar__footer\">\n <ng-content select=\"[neu-sidebar-footer]\" />\n </div>\n </aside>\n `,\n styleUrl: './neu-sidebar.component.scss',\n})\nexport class NeuSidebarComponent {\n private readonly document = inject(DOCUMENT);\n private readonly elementRef = inject(ElementRef);\n private readonly urlState = inject(NeuUrlStateService);\n private readonly openParam = computed(() => this.urlState.getParam(this.urlParam()));\n private previousActiveElement: HTMLElement | null = null;\n\n /** Posición del sidebar: izquierda o derecha de la pantalla / Sidebar position: left or right of the screen */\n side = input<'left' | 'right'>('left');\n\n /** QueryParam que controla el estado. Default: 'menu' (?menu=open) / QueryParam that controls the state. Default: 'menu' (?menu=open) */\n urlParam = input<string>('menu');\n\n /**\n * Modo persistente: el sidebar está siempre visible como parte del layout.\n * Usar en desktop (≥768px). El overlay y el toggle por URL no aplican.\n */\n persistent = input<boolean>(false);\n\n /**\n * Ocultar la cabecera del sidebar. Útil cuando el header ya está en el layout\n * principal y el sidebar persistente no necesita su propio header.\n */\n hideHeader = input<boolean>(false);\n\n /** Etiqueta accesible para el <aside> / Accessible label for the <aside> */\n ariaLabel = input<string>('Menú de navegación');\n\n /** Etiqueta accesible para el botón cerrar / Accessible label for the close button */\n closeLabel = input<string>('Cerrar menú de navegación');\n\n /**\n * Modo colapsado: el sidebar muestra solo iconos (icon-only en desktop).\n * Útil para sidebars persistentes en modo compact / Collapsed mode: sidebar shows only icons.\n */\n collapsed = input<boolean>(false);\n\n /** Emite cuando el usuario cierra el sidebar (overlay click o botón) / Emits when the user closes the sidebar (overlay click or button) */\n closeRequested = output<void>();\n\n /** Emite cuando el estado collapsed cambia / Emits when collapsed state changes */\n collapsedChange = output<boolean>();\n\n /** Signal reactivo: true si el sidebar debe mostrarse / Reactive signal: true if the sidebar should be shown */\n readonly isOpen = computed(() => {\n if (this.persistent()) return true;\n return this.openParam()() === 'open';\n });\n\n constructor() {\n effect((onCleanup) => {\n const shouldLockScroll = !this.persistent() && this.isOpen();\n\n if (!shouldLockScroll) {\n return;\n }\n\n lockDocumentScroll(this.document);\n\n onCleanup(() => {\n unlockDocumentScroll(this.document);\n });\n });\n\n // Focus management: save previous element and move focus to sidebar when opening in drawer mode\n effect(() => {\n const isOpenNow = this.isOpen();\n const isPersistent = this.persistent();\n\n if (isPersistent) {\n return;\n }\n\n if (isOpenNow) {\n // Save the current active element\n this.previousActiveElement = this.document.activeElement as HTMLElement;\n\n // Move focus to first focusable element inside the sidebar\n this.focusFirstElement();\n } else if (this.previousActiveElement && this.previousActiveElement.focus) {\n // Restore focus to the element that had it before opening\n setTimeout(() => {\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n }, 0);\n }\n });\n }\n\n /** Abre el sidebar — añade ?{urlParam}=open a la URL / Opens the sidebar — adds ?{urlParam}=open to the URL */\n open(replaceUrl = false): void {\n this.urlState.setParam(this.urlParam(), 'open', replaceUrl);\n }\n\n /** Cierra el sidebar — elimina el parámetro de la URL / Closes the sidebar — removes the URL parameter */\n close(): void {\n this.urlState.setParam(this.urlParam(), null, true);\n this.closeRequested.emit();\n }\n\n /** Alterna el estado collapsed / Toggles collapsed state */\n toggleCollapsed(): void {\n const newState = !this.collapsed();\n this.collapsedChange.emit(newState);\n }\n\n /** Obtiene los elementos focusables dentro del sidebar / Gets focusable elements inside sidebar */\n private getFocusableElements(): HTMLElement[] {\n const focusableSelectors = [\n 'button',\n 'a[href]',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n ].join(',');\n\n const aside = this.elementRef.nativeElement.querySelector('aside.neu-sidebar');\n if (!aside) {\n return [];\n }\n\n return Array.from(aside.querySelectorAll(focusableSelectors)) as HTMLElement[];\n }\n\n /** Mueve el foco al primer elemento focusable / Moves focus to first focusable element */\n private focusFirstElement(): void {\n setTimeout(() => {\n const focusable = this.getFocusableElements();\n if (focusable.length > 0) {\n focusable[0].focus();\n }\n }, 0);\n }\n\n /** Focus trap: cicla entre elementos focusables con Tab/Shift+Tab / Focus trap cycling */\n @HostListener('keydown', ['$event'])\n onKeyDown(event: KeyboardEvent): void {\n if (!this.isOpen() || this.persistent()) {\n return;\n }\n\n if (event.key !== 'Tab') {\n return;\n }\n\n const focusable = this.getFocusableElements();\n if (focusable.length === 0) {\n return;\n }\n\n const activeElement = this.document.activeElement as HTMLElement;\n const currentIndex = focusable.indexOf(activeElement);\n\n if (event.shiftKey) {\n // Shift+Tab — go to previous\n if (currentIndex <= 0) {\n event.preventDefault();\n focusable[focusable.length - 1].focus();\n }\n } else {\n // Tab — go to next\n if (currentIndex >= focusable.length - 1) {\n event.preventDefault();\n focusable[0].focus();\n }\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -88,7 +88,7 @@ class NeuSliderComponent {
88
88
  </div>
89
89
  }
90
90
  </div>
91
- `, isInline: true, styles: [".neu-slider{display:flex;flex-direction:column;gap:8px;width:100%;font-family:var(--neu-font-sans)}.neu-slider--disabled{pointer-events:none}.neu-slider--disabled .neu-slider__label,.neu-slider--disabled .neu-slider__value,.neu-slider--disabled .neu-slider__ticks{color:var(--neu-text-disabled)}.neu-slider--disabled .neu-slider__track-wrap{opacity:.45}.neu-slider__header{display:flex;align-items:center;justify-content:space-between;gap:8px}.neu-slider__label{font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted)}.neu-slider__value{font-size:var(--neu-text-xs);font-weight:600;color:var(--neu-primary);min-width:32px;text-align:right}.neu-slider__track-wrap{position:relative;height:18px;display:flex;align-items:center}.neu-slider__track{position:absolute;left:0;right:0;height:4px;background:var(--neu-surface-3);border-radius:var(--neu-radius-full);pointer-events:none}.neu-slider__fill{height:100%;background:var(--neu-primary);border-radius:var(--neu-radius-full);transition:width .05s linear}.neu-slider__input{position:relative;width:100%;height:18px;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none;outline:none;z-index:1}.neu-slider__input::-webkit-slider-runnable-track{background:transparent;height:4px}.neu-slider__input::-moz-range-track{background:transparent;height:4px}.neu-slider__input::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;transition:box-shadow .15s;cursor:pointer;margin-top:-7px}.neu-slider__input::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;cursor:pointer}.neu-slider__input:hover::-webkit-slider-thumb,.neu-slider__input:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--neu-primary-100)}.neu-slider__input:focus-visible{outline:none}.neu-slider__ticks{display:flex;justify-content:space-between;font-size:var(--neu-text-xs);color:var(--neu-text-disabled)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
91
+ `, isInline: true, styles: [".neu-slider{display:flex;flex-direction:column;gap:8px;width:100%;font-family:var(--neu-font-sans)}.neu-slider--disabled{pointer-events:none}.neu-slider--disabled .neu-slider__label,.neu-slider--disabled .neu-slider__value,.neu-slider--disabled .neu-slider__ticks{color:var(--neu-text-disabled)}.neu-slider--disabled .neu-slider__track-wrap{opacity:.45}.neu-slider__header{display:flex;align-items:center;justify-content:space-between;gap:8px}.neu-slider__label{font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted)}.neu-slider__value{font-size:var(--neu-text-xs);font-weight:600;color:var(--neu-primary-dark, var(--neu-primary));min-width:32px;text-align:right}.neu-slider__track-wrap{position:relative;height:18px;display:flex;align-items:center}.neu-slider__track{position:absolute;left:0;right:0;height:4px;background:var(--neu-surface-3);border-radius:var(--neu-radius-full);pointer-events:none}.neu-slider__fill{height:100%;background:var(--neu-primary);border-radius:var(--neu-radius-full);transition:width .05s linear}.neu-slider__input{position:relative;width:100%;height:18px;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none;outline:none;z-index:1}.neu-slider__input::-webkit-slider-runnable-track{background:transparent;height:4px}.neu-slider__input::-moz-range-track{background:transparent;height:4px}.neu-slider__input::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;transition:box-shadow .15s;cursor:pointer;margin-top:-7px}.neu-slider__input::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;cursor:pointer}.neu-slider__input:hover::-webkit-slider-thumb,.neu-slider__input:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--neu-primary-100)}.neu-slider__input:focus-visible{outline:none}.neu-slider__ticks{display:flex;justify-content:space-between;font-size:var(--neu-text-xs);color:var(--neu-text-disabled)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
92
92
  }
93
93
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuSliderComponent, decorators: [{
94
94
  type: Component,
@@ -135,7 +135,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
135
135
  </div>
136
136
  }
137
137
  </div>
138
- `, styles: [".neu-slider{display:flex;flex-direction:column;gap:8px;width:100%;font-family:var(--neu-font-sans)}.neu-slider--disabled{pointer-events:none}.neu-slider--disabled .neu-slider__label,.neu-slider--disabled .neu-slider__value,.neu-slider--disabled .neu-slider__ticks{color:var(--neu-text-disabled)}.neu-slider--disabled .neu-slider__track-wrap{opacity:.45}.neu-slider__header{display:flex;align-items:center;justify-content:space-between;gap:8px}.neu-slider__label{font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted)}.neu-slider__value{font-size:var(--neu-text-xs);font-weight:600;color:var(--neu-primary);min-width:32px;text-align:right}.neu-slider__track-wrap{position:relative;height:18px;display:flex;align-items:center}.neu-slider__track{position:absolute;left:0;right:0;height:4px;background:var(--neu-surface-3);border-radius:var(--neu-radius-full);pointer-events:none}.neu-slider__fill{height:100%;background:var(--neu-primary);border-radius:var(--neu-radius-full);transition:width .05s linear}.neu-slider__input{position:relative;width:100%;height:18px;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none;outline:none;z-index:1}.neu-slider__input::-webkit-slider-runnable-track{background:transparent;height:4px}.neu-slider__input::-moz-range-track{background:transparent;height:4px}.neu-slider__input::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;transition:box-shadow .15s;cursor:pointer;margin-top:-7px}.neu-slider__input::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;cursor:pointer}.neu-slider__input:hover::-webkit-slider-thumb,.neu-slider__input:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--neu-primary-100)}.neu-slider__input:focus-visible{outline:none}.neu-slider__ticks{display:flex;justify-content:space-between;font-size:var(--neu-text-xs);color:var(--neu-text-disabled)}\n"] }]
138
+ `, styles: [".neu-slider{display:flex;flex-direction:column;gap:8px;width:100%;font-family:var(--neu-font-sans)}.neu-slider--disabled{pointer-events:none}.neu-slider--disabled .neu-slider__label,.neu-slider--disabled .neu-slider__value,.neu-slider--disabled .neu-slider__ticks{color:var(--neu-text-disabled)}.neu-slider--disabled .neu-slider__track-wrap{opacity:.45}.neu-slider__header{display:flex;align-items:center;justify-content:space-between;gap:8px}.neu-slider__label{font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted)}.neu-slider__value{font-size:var(--neu-text-xs);font-weight:600;color:var(--neu-primary-dark, var(--neu-primary));min-width:32px;text-align:right}.neu-slider__track-wrap{position:relative;height:18px;display:flex;align-items:center}.neu-slider__track{position:absolute;left:0;right:0;height:4px;background:var(--neu-surface-3);border-radius:var(--neu-radius-full);pointer-events:none}.neu-slider__fill{height:100%;background:var(--neu-primary);border-radius:var(--neu-radius-full);transition:width .05s linear}.neu-slider__input{position:relative;width:100%;height:18px;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none;outline:none;z-index:1}.neu-slider__input::-webkit-slider-runnable-track{background:transparent;height:4px}.neu-slider__input::-moz-range-track{background:transparent;height:4px}.neu-slider__input::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;transition:box-shadow .15s;cursor:pointer;margin-top:-7px}.neu-slider__input::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--neu-surface);border:2.5px solid var(--neu-primary);box-shadow:0 1px 4px #00000026;cursor:pointer}.neu-slider__input:hover::-webkit-slider-thumb,.neu-slider__input:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--neu-primary-100)}.neu-slider__input:focus-visible{outline:none}.neu-slider__ticks{display:flex;justify-content:space-between;font-size:var(--neu-text-xs);color:var(--neu-text-disabled)}\n"] }]
139
139
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], showTicks: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTicks", required: false }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
140
140
 
141
141
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-slider.mjs","sources":["../../../../projects/ui-core/slider/neu-slider.component.ts","../../../../projects/ui-core/slider/neural-ui-core-slider.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n output,\n} from '@angular/core';\n\n/**\n * NeuralUI Slider Component\n *\n * Control deslizante accesible que envuelve el <input type=\"range\">\n * nativo con estilos personalizados y tooltips de valor.\n *\n * Uso:\n * <neu-slider [value]=\"volume\" (valueChange)=\"volume = $event\" />\n * <neu-slider [value]=\"50\" [min]=\"0\" [max]=\"100\" [step]=\"5\" [showValue]=\"true\" />\n */\n@Component({\n selector: 'neu-slider',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"neu-slider\" [class.neu-slider--disabled]=\"disabled()\">\n @if (label()) {\n <div class=\"neu-slider__header\">\n <label class=\"neu-slider__label\" [for]=\"sliderId\">{{ label() }}</label>\n @if (showValue()) {\n <span class=\"neu-slider__value\">{{ value() }}{{ unit() }}</span>\n }\n </div>\n } @else if (showValue()) {\n <div class=\"neu-slider__header\">\n <span></span>\n <span class=\"neu-slider__value\">{{ value() }}{{ unit() }}</span>\n </div>\n }\n <div class=\"neu-slider__track-wrap\">\n <div class=\"neu-slider__track\">\n <div class=\"neu-slider__fill\" [style.width.%]=\"fillPercent()\"></div>\n </div>\n <input\n class=\"neu-slider__input\"\n type=\"range\"\n [id]=\"sliderId\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label() || 'Slider'\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n (input)=\"onInput($event)\"\n />\n </div>\n @if (showTicks()) {\n <div class=\"neu-slider__ticks\">\n <span>{{ min() }}{{ unit() }}</span>\n <span>{{ (max() - min()) / 2 + min() }}{{ unit() }}</span>\n <span>{{ max() }}{{ unit() }}</span>\n </div>\n }\n </div>\n `,\n styleUrl: './neu-slider.component.scss',\n})\nexport class NeuSliderComponent {\n private static _idCounter = 0;\n protected readonly sliderId = `neu-slider-${++NeuSliderComponent._idCounter}`;\n\n /** Valor actual / Current value */\n value = input<number>(0);\n\n /** Valor mínimo / Minimum value */\n min = input<number>(0);\n\n /** Valor máximo / Maximum value */\n max = input<number>(100);\n\n /** Paso / Step */\n step = input<number>(1);\n\n /** Etiqueta / Label */\n label = input<string>('');\n\n /** Muestra el valor numerico / Shows the numeric value */\n showValue = input<boolean>(true);\n\n /** Muestra min/mid/max bajo la barra / Shows min/mid/max below the bar */\n showTicks = input<boolean>(false);\n\n /** Unidad a mostrar junto al valor / Unit to display next to the value */\n unit = input<string>('');\n\n /** Deshabilitado / Disabled */\n disabled = input<boolean>(false);\n\n /** Emite al mover el slider / Emits when the slider moves */\n valueChange = output<number>();\n\n readonly fillPercent = computed(() => {\n const range = this.max() - this.min();\n if (range === 0) return 0;\n return ((this.value() - this.min()) / range) * 100;\n });\n\n onInput(event: Event): void {\n const val = Number((event.target as HTMLInputElement).value);\n this.valueChange.emit(val);\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-slider.mjs","sources":["../../../../projects/ui-core/slider/neu-slider.component.ts","../../../../projects/ui-core/slider/neural-ui-core-slider.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n output,\n} from '@angular/core';\n\n/**\n * NeuralUI Slider Component\n *\n * Control deslizante accesible que envuelve el <input type=\"range\">\n * nativo con estilos personalizados y tooltips de valor.\n *\n * Uso:\n * <neu-slider [value]=\"volume\" (valueChange)=\"volume = $event\" />\n * <neu-slider [value]=\"50\" [min]=\"0\" [max]=\"100\" [step]=\"5\" [showValue]=\"true\" />\n */\n@Component({\n selector: 'neu-slider',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"neu-slider\" [class.neu-slider--disabled]=\"disabled()\">\n @if (label()) {\n <div class=\"neu-slider__header\">\n <label class=\"neu-slider__label\" [for]=\"sliderId\">{{ label() }}</label>\n @if (showValue()) {\n <span class=\"neu-slider__value\">{{ value() }}{{ unit() }}</span>\n }\n </div>\n } @else if (showValue()) {\n <div class=\"neu-slider__header\">\n <span></span>\n <span class=\"neu-slider__value\">{{ value() }}{{ unit() }}</span>\n </div>\n }\n <div class=\"neu-slider__track-wrap\">\n <div class=\"neu-slider__track\">\n <div class=\"neu-slider__fill\" [style.width.%]=\"fillPercent()\"></div>\n </div>\n <input\n class=\"neu-slider__input\"\n type=\"range\"\n [id]=\"sliderId\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"label() || 'Slider'\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n (input)=\"onInput($event)\"\n />\n </div>\n @if (showTicks()) {\n <div class=\"neu-slider__ticks\">\n <span>{{ min() }}{{ unit() }}</span>\n <span>{{ (max() - min()) / 2 + min() }}{{ unit() }}</span>\n <span>{{ max() }}{{ unit() }}</span>\n </div>\n }\n </div>\n `,\n styleUrl: './neu-slider.component.scss',\n})\nexport class NeuSliderComponent {\n private static _idCounter = 0;\n protected readonly sliderId = `neu-slider-${++NeuSliderComponent._idCounter}`;\n\n /** Valor actual / Current value */\n value = input<number>(0);\n\n /** Valor mínimo / Minimum value */\n min = input<number>(0);\n\n /** Valor máximo / Maximum value */\n max = input<number>(100);\n\n /** Paso / Step */\n step = input<number>(1);\n\n /** Etiqueta / Label */\n label = input<string>('');\n\n /** Muestra el valor numerico / Shows the numeric value */\n showValue = input<boolean>(true);\n\n /** Muestra min/mid/max bajo la barra / Shows min/mid/max below the bar */\n showTicks = input<boolean>(false);\n\n /** Unidad a mostrar junto al valor / Unit to display next to the value */\n unit = input<string>('');\n\n /** Deshabilitado / Disabled */\n disabled = input<boolean>(false);\n\n /** Emite al mover el slider / Emits when the slider moves */\n valueChange = output<number>();\n\n readonly fillPercent = computed(() => {\n const range = this.max() - this.min();\n if (range === 0) return 0;\n return ((this.value() - this.min()) / range) * 100;\n });\n\n onInput(event: Event): void {\n const val = Number((event.target as HTMLInputElement).value);\n this.valueChange.emit(val);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;AASA;;;;;;;;;AASG;MAoDU,kBAAkB,CAAA;AACrB,IAAA,OAAO,UAAU,GAAG,CAAC;AACV,IAAA,QAAQ,GAAG,CAAA,WAAA,EAAc,EAAE,kBAAkB,CAAC,UAAU,EAAE;;AAG7E,IAAA,KAAK,GAAG,KAAK,CAAS,CAAC,4EAAC;;AAGxB,IAAA,GAAG,GAAG,KAAK,CAAS,CAAC,0EAAC;;AAGtB,IAAA,GAAG,GAAG,KAAK,CAAS,GAAG,0EAAC;;AAGxB,IAAA,IAAI,GAAG,KAAK,CAAS,CAAC,2EAAC;;AAGvB,IAAA,KAAK,GAAG,KAAK,CAAS,EAAE,4EAAC;;AAGzB,IAAA,SAAS,GAAG,KAAK,CAAU,IAAI,gFAAC;;AAGhC,IAAA,SAAS,GAAG,KAAK,CAAU,KAAK,gFAAC;;AAGjC,IAAA,IAAI,GAAG,KAAK,CAAS,EAAE,2EAAC;;AAGxB,IAAA,QAAQ,GAAG,KAAK,CAAU,KAAK,+EAAC;;IAGhC,WAAW,GAAG,MAAM,EAAU;AAErB,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE;QACrC,IAAI,KAAK,KAAK,CAAC;AAAE,YAAA,OAAO,CAAC;AACzB,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG;AACpD,IAAA,CAAC,kFAAC;AAEF,IAAA,OAAO,CAAC,KAAY,EAAA;QAClB,MAAM,GAAG,GAAG,MAAM,CAAE,KAAK,CAAC,MAA2B,CAAC,KAAK,CAAC;AAC5D,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;IAC5B;uGA3CW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA9CnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,+lEAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAGU,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAnD9B,SAAS;+BACE,YAAY,EAAA,OAAA,EACb,EAAE,EAAA,aAAA,EACI,iBAAiB,CAAC,IAAI,EAAA,eAAA,EACpB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,+lEAAA,CAAA,EAAA;;;ACnEH;;AAEG;;;;"}
@@ -148,7 +148,7 @@ class NeuSplitButtonComponent {
148
148
  </div>
149
149
  }
150
150
  </div>
151
- `, isInline: true, styles: [".neu-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:1px solid transparent;border-radius:var(--neu-radius);font-family:var(--neu-font-sans);font-weight:500;line-height:1;cursor:pointer;text-decoration:none;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background-color var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition),box-shadow var(--neu-transition),opacity var(--neu-transition);outline:none}.neu-button:focus-visible{box-shadow:var(--neu-focus-ring-strong)}.neu-button--sm{padding:var(--neu-space-2) var(--neu-space-3);font-size:var(--neu-text-sm);border-radius:var(--neu-radius-sm)}.neu-button--md{padding:var(--neu-space-2) var(--neu-space-5);font-size:var(--neu-text-base)}@media(min-width:400px){.neu-button--md{padding:.625rem var(--neu-space-6)}}.neu-button--lg{padding:var(--neu-space-3) var(--neu-space-8);font-size:var(--neu-text-lg)}.neu-button--full-width{width:100%}.neu-button--primary{background:var(--neu-primary);color:var(--neu-primary-fg);border-color:var(--neu-primary)}.neu-button--primary:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-dark);border-color:var(--neu-primary-dark);box-shadow:var(--neu-shadow-glow)}.neu-button--primary:active:not(:disabled){background:var(--neu-primary-dark);transform:translateY(1px)}.neu-button--secondary{background:#475569;color:#fff;border-color:#475569}.neu-button--secondary:hover:not(:disabled):not(.neu-button--disabled){background:#334155;border-color:#334155}.neu-button--outline{background:transparent;color:var(--neu-primary-dark, var(--neu-primary));border-color:var(--neu-primary)}.neu-button--outline:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-50);border-color:var(--neu-primary-dark, var(--neu-primary))}.neu-button--ghost{background:transparent;color:var(--neu-text-muted);border-color:transparent}.neu-button--ghost:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-button--danger{background:var(--neu-error);color:var(--neu-primary-fg);border-color:var(--neu-error)}.neu-button--danger:hover:not(:disabled):not(.neu-button--disabled){background:#dc2626;border-color:#dc2626}.neu-button--disabled,.neu-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.neu-button--loading{cursor:wait;pointer-events:none}.neu-button--icon-only.neu-button--sm{width:30px;height:30px;padding:0}.neu-button--icon-only.neu-button--md{width:38px;height:38px;padding:0}.neu-button--icon-only.neu-button--lg{width:46px;height:46px;padding:0}.neu-button__spinner{display:inline-flex;flex-shrink:0;width:1em;height:1em}.neu-button__spinner svg{width:100%;height:100%;animation:neu-spin .8s linear infinite}@keyframes neu-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.neu-split-button-host{display:inline-block}.neu-split-button{display:inline-flex;align-items:stretch}.neu-split-button--disabled{opacity:.6;pointer-events:none}.neu-split-button .neu-split-button__main{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right:none!important;flex:1}.neu-split-button .neu-split-button__chevron{border-top-left-radius:0!important;border-bottom-left-radius:0!important;padding-inline:10px!important;min-width:auto}.neu-split-button .neu-split-button__chevron svg{width:14px;height:14px;display:block}.neu-split-button__divider{width:1px;background:var(--neu-split-button-primary-divider);align-self:stretch;flex-shrink:0}.neu-button--secondary .neu-split-button__divider,.neu-button--ghost .neu-split-button__divider,.neu-button--outline .neu-split-button__divider{background:var(--neu-border)}.neu-split-button__dropdown{position:absolute;top:calc(100% + 6px);right:0;z-index:200;min-width:180px;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);box-shadow:var(--neu-shadow-lg);padding:var(--neu-space-1) 0;animation:neu-split-btn-in .1s ease}@keyframes neu-split-btn-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-split-button{position:relative}.neu-split-button__dropdown-item{display:flex;align-items:center;width:100%;padding:9px var(--neu-space-4);border:none;background:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);cursor:pointer;text-align:left;transition:background var(--neu-transition)}.neu-split-button__dropdown-item:hover:not(:disabled):not(.neu-split-button__dropdown-item--disabled){background:var(--neu-surface-2)}.neu-split-button__dropdown-item--disabled,.neu-split-button__dropdown-item:disabled{color:var(--neu-text-disabled);cursor:not-allowed}.neu-split-button__dropdown-sep{height:1px;background:var(--neu-border);margin:var(--neu-space-1) 0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
151
+ `, isInline: true, styles: [".neu-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:1px solid transparent;border-radius:var(--neu-radius);font-family:var(--neu-font-sans);font-weight:500;line-height:1;cursor:pointer;text-decoration:none;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background-color var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition),box-shadow var(--neu-transition),opacity var(--neu-transition);outline:none}.neu-button:focus-visible{box-shadow:var(--neu-focus-ring-strong)}.neu-button--sm{padding:var(--neu-space-2) var(--neu-space-3);font-size:var(--neu-text-sm);border-radius:var(--neu-radius-sm)}.neu-button--md{padding:var(--neu-space-2) var(--neu-space-5);font-size:var(--neu-text-base)}@media(min-width:400px){.neu-button--md{padding:.625rem var(--neu-space-6)}}.neu-button--lg{padding:var(--neu-space-3) var(--neu-space-8);font-size:var(--neu-text-lg)}.neu-button--full-width{width:100%}.neu-button--primary{background:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-primary-solid-fg, var(--neu-primary-fg));border-color:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)))}.neu-button--primary:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-solid-hover, var(--neu-primary-dark));border-color:var(--neu-primary-solid-hover, var(--neu-primary-dark));box-shadow:var(--neu-shadow-glow)}.neu-button--primary:active:not(:disabled){background:var(--neu-primary-solid-hover, var(--neu-primary-dark));transform:translateY(1px)}.neu-button--secondary{background:#475569;color:#fff;border-color:#475569}.neu-button--secondary:hover:not(:disabled):not(.neu-button--disabled){background:#334155;border-color:#334155}.neu-button--outline{background:transparent;color:var(--neu-primary-dark, var(--neu-primary));border-color:var(--neu-primary)}.neu-button--outline:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-50);border-color:var(--neu-primary-dark, var(--neu-primary))}.neu-button--ghost{background:transparent;color:var(--neu-text-muted);border-color:transparent}.neu-button--ghost:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-button--danger{background:var(--neu-error);color:var(--neu-primary-fg);border-color:var(--neu-error)}.neu-button--danger:hover:not(:disabled):not(.neu-button--disabled){background:#dc2626;border-color:#dc2626}.neu-button--disabled,.neu-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.neu-button--loading{cursor:wait;pointer-events:none}.neu-button--icon-only.neu-button--sm{width:30px;height:30px;padding:0}.neu-button--icon-only.neu-button--md{width:38px;height:38px;padding:0}.neu-button--icon-only.neu-button--lg{width:46px;height:46px;padding:0}.neu-button__spinner{display:inline-flex;flex-shrink:0;width:1em;height:1em}.neu-button__spinner svg{width:100%;height:100%;animation:neu-spin .8s linear infinite}@keyframes neu-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.neu-split-button-host{display:inline-block}.neu-split-button{display:inline-flex;align-items:stretch}.neu-split-button--disabled{opacity:.6;pointer-events:none}.neu-split-button .neu-split-button__main{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right:none!important;flex:1}.neu-split-button .neu-split-button__chevron{border-top-left-radius:0!important;border-bottom-left-radius:0!important;padding-inline:10px!important;min-width:auto}.neu-split-button .neu-split-button__chevron svg{width:14px;height:14px;display:block}.neu-split-button__divider{width:1px;background:var(--neu-split-button-primary-divider);align-self:stretch;flex-shrink:0}.neu-button--secondary .neu-split-button__divider,.neu-button--ghost .neu-split-button__divider,.neu-button--outline .neu-split-button__divider{background:var(--neu-border)}.neu-split-button__dropdown{position:absolute;top:calc(100% + 6px);right:0;z-index:200;min-width:180px;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);box-shadow:var(--neu-shadow-lg);padding:var(--neu-space-1) 0;animation:neu-split-btn-in .1s ease}@keyframes neu-split-btn-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-split-button{position:relative}.neu-split-button__dropdown-item{display:flex;align-items:center;width:100%;padding:9px var(--neu-space-4);border:none;background:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);cursor:pointer;text-align:left;transition:background var(--neu-transition)}.neu-split-button__dropdown-item:hover:not(:disabled):not(.neu-split-button__dropdown-item--disabled){background:var(--neu-surface-2)}.neu-split-button__dropdown-item--disabled,.neu-split-button__dropdown-item:disabled{color:var(--neu-text-disabled);cursor:not-allowed}.neu-split-button__dropdown-sep{height:1px;background:var(--neu-border);margin:var(--neu-space-1) 0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
152
152
  }
153
153
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuSplitButtonComponent, decorators: [{
154
154
  type: Component,
@@ -241,7 +241,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
241
241
  </div>
242
242
  }
243
243
  </div>
244
- `, styles: [".neu-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:1px solid transparent;border-radius:var(--neu-radius);font-family:var(--neu-font-sans);font-weight:500;line-height:1;cursor:pointer;text-decoration:none;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background-color var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition),box-shadow var(--neu-transition),opacity var(--neu-transition);outline:none}.neu-button:focus-visible{box-shadow:var(--neu-focus-ring-strong)}.neu-button--sm{padding:var(--neu-space-2) var(--neu-space-3);font-size:var(--neu-text-sm);border-radius:var(--neu-radius-sm)}.neu-button--md{padding:var(--neu-space-2) var(--neu-space-5);font-size:var(--neu-text-base)}@media(min-width:400px){.neu-button--md{padding:.625rem var(--neu-space-6)}}.neu-button--lg{padding:var(--neu-space-3) var(--neu-space-8);font-size:var(--neu-text-lg)}.neu-button--full-width{width:100%}.neu-button--primary{background:var(--neu-primary);color:var(--neu-primary-fg);border-color:var(--neu-primary)}.neu-button--primary:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-dark);border-color:var(--neu-primary-dark);box-shadow:var(--neu-shadow-glow)}.neu-button--primary:active:not(:disabled){background:var(--neu-primary-dark);transform:translateY(1px)}.neu-button--secondary{background:#475569;color:#fff;border-color:#475569}.neu-button--secondary:hover:not(:disabled):not(.neu-button--disabled){background:#334155;border-color:#334155}.neu-button--outline{background:transparent;color:var(--neu-primary-dark, var(--neu-primary));border-color:var(--neu-primary)}.neu-button--outline:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-50);border-color:var(--neu-primary-dark, var(--neu-primary))}.neu-button--ghost{background:transparent;color:var(--neu-text-muted);border-color:transparent}.neu-button--ghost:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-button--danger{background:var(--neu-error);color:var(--neu-primary-fg);border-color:var(--neu-error)}.neu-button--danger:hover:not(:disabled):not(.neu-button--disabled){background:#dc2626;border-color:#dc2626}.neu-button--disabled,.neu-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.neu-button--loading{cursor:wait;pointer-events:none}.neu-button--icon-only.neu-button--sm{width:30px;height:30px;padding:0}.neu-button--icon-only.neu-button--md{width:38px;height:38px;padding:0}.neu-button--icon-only.neu-button--lg{width:46px;height:46px;padding:0}.neu-button__spinner{display:inline-flex;flex-shrink:0;width:1em;height:1em}.neu-button__spinner svg{width:100%;height:100%;animation:neu-spin .8s linear infinite}@keyframes neu-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.neu-split-button-host{display:inline-block}.neu-split-button{display:inline-flex;align-items:stretch}.neu-split-button--disabled{opacity:.6;pointer-events:none}.neu-split-button .neu-split-button__main{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right:none!important;flex:1}.neu-split-button .neu-split-button__chevron{border-top-left-radius:0!important;border-bottom-left-radius:0!important;padding-inline:10px!important;min-width:auto}.neu-split-button .neu-split-button__chevron svg{width:14px;height:14px;display:block}.neu-split-button__divider{width:1px;background:var(--neu-split-button-primary-divider);align-self:stretch;flex-shrink:0}.neu-button--secondary .neu-split-button__divider,.neu-button--ghost .neu-split-button__divider,.neu-button--outline .neu-split-button__divider{background:var(--neu-border)}.neu-split-button__dropdown{position:absolute;top:calc(100% + 6px);right:0;z-index:200;min-width:180px;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);box-shadow:var(--neu-shadow-lg);padding:var(--neu-space-1) 0;animation:neu-split-btn-in .1s ease}@keyframes neu-split-btn-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-split-button{position:relative}.neu-split-button__dropdown-item{display:flex;align-items:center;width:100%;padding:9px var(--neu-space-4);border:none;background:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);cursor:pointer;text-align:left;transition:background var(--neu-transition)}.neu-split-button__dropdown-item:hover:not(:disabled):not(.neu-split-button__dropdown-item--disabled){background:var(--neu-surface-2)}.neu-split-button__dropdown-item--disabled,.neu-split-button__dropdown-item:disabled{color:var(--neu-text-disabled);cursor:not-allowed}.neu-split-button__dropdown-sep{height:1px;background:var(--neu-border);margin:var(--neu-space-1) 0}\n"] }]
244
+ `, styles: [".neu-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--neu-space-2);border:1px solid transparent;border-radius:var(--neu-radius);font-family:var(--neu-font-sans);font-weight:500;line-height:1;cursor:pointer;text-decoration:none;white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background-color var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition),box-shadow var(--neu-transition),opacity var(--neu-transition);outline:none}.neu-button:focus-visible{box-shadow:var(--neu-focus-ring-strong)}.neu-button--sm{padding:var(--neu-space-2) var(--neu-space-3);font-size:var(--neu-text-sm);border-radius:var(--neu-radius-sm)}.neu-button--md{padding:var(--neu-space-2) var(--neu-space-5);font-size:var(--neu-text-base)}@media(min-width:400px){.neu-button--md{padding:.625rem var(--neu-space-6)}}.neu-button--lg{padding:var(--neu-space-3) var(--neu-space-8);font-size:var(--neu-text-lg)}.neu-button--full-width{width:100%}.neu-button--primary{background:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-primary-solid-fg, var(--neu-primary-fg));border-color:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)))}.neu-button--primary:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-solid-hover, var(--neu-primary-dark));border-color:var(--neu-primary-solid-hover, var(--neu-primary-dark));box-shadow:var(--neu-shadow-glow)}.neu-button--primary:active:not(:disabled){background:var(--neu-primary-solid-hover, var(--neu-primary-dark));transform:translateY(1px)}.neu-button--secondary{background:#475569;color:#fff;border-color:#475569}.neu-button--secondary:hover:not(:disabled):not(.neu-button--disabled){background:#334155;border-color:#334155}.neu-button--outline{background:transparent;color:var(--neu-primary-dark, var(--neu-primary));border-color:var(--neu-primary)}.neu-button--outline:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-primary-50);border-color:var(--neu-primary-dark, var(--neu-primary))}.neu-button--ghost{background:transparent;color:var(--neu-text-muted);border-color:transparent}.neu-button--ghost:hover:not(:disabled):not(.neu-button--disabled){background:var(--neu-surface-2);color:var(--neu-text)}.neu-button--danger{background:var(--neu-error);color:var(--neu-primary-fg);border-color:var(--neu-error)}.neu-button--danger:hover:not(:disabled):not(.neu-button--disabled){background:#dc2626;border-color:#dc2626}.neu-button--disabled,.neu-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.neu-button--loading{cursor:wait;pointer-events:none}.neu-button--icon-only.neu-button--sm{width:30px;height:30px;padding:0}.neu-button--icon-only.neu-button--md{width:38px;height:38px;padding:0}.neu-button--icon-only.neu-button--lg{width:46px;height:46px;padding:0}.neu-button__spinner{display:inline-flex;flex-shrink:0;width:1em;height:1em}.neu-button__spinner svg{width:100%;height:100%;animation:neu-spin .8s linear infinite}@keyframes neu-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.neu-split-button-host{display:inline-block}.neu-split-button{display:inline-flex;align-items:stretch}.neu-split-button--disabled{opacity:.6;pointer-events:none}.neu-split-button .neu-split-button__main{border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right:none!important;flex:1}.neu-split-button .neu-split-button__chevron{border-top-left-radius:0!important;border-bottom-left-radius:0!important;padding-inline:10px!important;min-width:auto}.neu-split-button .neu-split-button__chevron svg{width:14px;height:14px;display:block}.neu-split-button__divider{width:1px;background:var(--neu-split-button-primary-divider);align-self:stretch;flex-shrink:0}.neu-button--secondary .neu-split-button__divider,.neu-button--ghost .neu-split-button__divider,.neu-button--outline .neu-split-button__divider{background:var(--neu-border)}.neu-split-button__dropdown{position:absolute;top:calc(100% + 6px);right:0;z-index:200;min-width:180px;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);box-shadow:var(--neu-shadow-lg);padding:var(--neu-space-1) 0;animation:neu-split-btn-in .1s ease}@keyframes neu-split-btn-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-split-button{position:relative}.neu-split-button__dropdown-item{display:flex;align-items:center;width:100%;padding:9px var(--neu-space-4);border:none;background:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);cursor:pointer;text-align:left;transition:background var(--neu-transition)}.neu-split-button__dropdown-item:hover:not(:disabled):not(.neu-split-button__dropdown-item--disabled){background:var(--neu-surface-2)}.neu-split-button__dropdown-item--disabled,.neu-split-button__dropdown-item:disabled{color:var(--neu-text-disabled);cursor:not-allowed}.neu-split-button__dropdown-sep{height:1px;background:var(--neu-border);margin:var(--neu-space-1) 0}\n"] }]
245
245
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], moreActionsAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "moreActionsAriaLabel", required: false }] }], actionsAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsAriaLabel", required: false }] }], primaryClick: [{ type: i0.Output, args: ["primaryClick"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
246
246
 
247
247
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-split-button.mjs","sources":["../../../../projects/ui-core/split-button/neu-split-button.component.ts","../../../../projects/ui-core/split-button/neural-ui-core-split-button.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuButtonVariant, NeuButtonSize } from '@neural-ui/core/button';\n\nexport interface NeuSplitButtonAction {\n /** Identificador único de la acción / Unique action identifier */\n id: string;\n /** Texto visible / Visible text */\n label: string;\n /** Icono opcional (SVG string o nombre) / Optional icon (SVG string or name) */\n icon?: string;\n /** Deshabilita esta acción individualmente / Disables this action individually */\n disabled?: boolean;\n /** Separador visual encima de este item / Visual separator above this item */\n divider?: boolean;\n}\n\n/**\n * NeuralUI SplitButton Component\n *\n * Botón principal con un dropdown de acciones adicionales. / Primary button with a dropdown of additional actions.\n *\n * Uso:\n * <neu-split-button\n * label=\"Guardar\"\n * [actions]=\"actions\"\n * (primaryClick)=\"save()\"\n * (actionClick)=\"onAction($event)\"\n * />\n */\n@Component({\n selector: 'neu-split-button',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'neu-split-button-host',\n '(document:click)': 'onDocumentClick($event)',\n '(keydown.escape)': 'closeDropdown()',\n },\n template: `\n <div class=\"neu-split-button\" [class.neu-split-button--disabled]=\"isDisabled()\">\n <!-- Botón principal -->\n <button\n class=\"neu-split-button__main\"\n [class]=\"mainClasses()\"\n type=\"button\"\n [disabled]=\"isDisabled() || null\"\n [attr.aria-disabled]=\"isDisabled()\"\n [attr.aria-busy]=\"loading()\"\n (click)=\"onPrimaryClick($event)\"\n >\n @if (loading()) {\n <span class=\"neu-button__spinner\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.416\"\n stroke-dashoffset=\"10\"\n />\n </svg>\n </span>\n }\n {{ label() }}\n </button>\n\n <!-- Separador -->\n <span class=\"neu-split-button__divider\" aria-hidden=\"true\"></span>\n\n <!-- Chevron trigger -->\n <button\n class=\"neu-split-button__chevron\"\n [class]=\"chevronClasses()\"\n type=\"button\"\n [disabled]=\"isDisabled() || null\"\n [attr.aria-haspopup]=\"'menu'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-label]=\"moreActionsAriaLabel()\"\n (click)=\"toggleDropdown($event)\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n\n <!-- Dropdown de acciones -->\n @if (isOpen()) {\n <div\n class=\"neu-split-button__dropdown\"\n role=\"menu\"\n [attr.aria-label]=\"actionsAriaLabel()\"\n (click)=\"$event.stopPropagation()\"\n >\n @for (action of actions(); track action.id) {\n @if (action.divider) {\n <div class=\"neu-split-button__dropdown-sep\" role=\"separator\" aria-hidden=\"true\"></div>\n }\n <button\n class=\"neu-split-button__dropdown-item\"\n [class.neu-split-button__dropdown-item--disabled]=\"action.disabled\"\n type=\"button\"\n role=\"menuitem\"\n [disabled]=\"action.disabled || null\"\n [attr.aria-disabled]=\"action.disabled ? 'true' : null\"\n (click)=\"onActionClick(action)\"\n >\n {{ action.label }}\n </button>\n }\n </div>\n }\n </div>\n `,\n styleUrl: './neu-split-button.component.scss',\n})\nexport class NeuSplitButtonComponent {\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** Texto del botón principal / Primary button text */\n label = input<string>('');\n\n /** Variante visual / Visual variant */\n variant = input<NeuButtonVariant>('primary');\n\n /** Tamaño / Size */\n size = input<NeuButtonSize>('md');\n\n /** Deshabilita todo el componente / Disables the entire component */\n disabled = input<boolean>(false);\n\n /** Muestra spinner en el botón principal / Shows spinner on the primary button */\n loading = input<boolean>(false);\n\n /** Acciones del dropdown / Dropdown actions */\n actions = input<NeuSplitButtonAction[]>([]);\n\n /** Aria-label del botón de desplegable / Aria-label for the dropdown button */\n moreActionsAriaLabel = input<string>('Más opciones');\n\n /** Aria-label del menú desplegable / Aria-label for the dropdown menu */\n actionsAriaLabel = input<string>('Acciones');\n\n /** Emite al hacer click en el botón principal / Emits on primary button click */\n primaryClick = output<MouseEvent>();\n\n /** Emite al seleccionar una acción del dropdown / Emits when a dropdown action is selected */\n actionClick = output<NeuSplitButtonAction>();\n\n readonly isOpen = signal(false);\n\n readonly isDisabled = computed(() => this.disabled() || this.loading());\n\n readonly mainClasses = computed(\n () =>\n `neu-button neu-button--${this.variant()} neu-button--${this.size()}${this.loading() ? ' neu-button--loading' : ''}`,\n );\n\n readonly chevronClasses = computed(\n () => `neu-button neu-button--${this.variant()} neu-button--${this.size()}`,\n );\n\n toggleDropdown(event: MouseEvent): void {\n event.stopPropagation();\n this.isOpen.update((v) => !v);\n }\n\n closeDropdown(): void {\n this.isOpen.set(false);\n }\n\n onDocumentClick(event: MouseEvent): void {\n if (!this.el.nativeElement.contains(event.target as Node)) this.closeDropdown();\n }\n\n onPrimaryClick(event: MouseEvent): void {\n if (this.isDisabled()) return;\n this.primaryClick.emit(event);\n }\n\n onActionClick(action: NeuSplitButtonAction): void {\n if (action.disabled) return;\n this.closeDropdown();\n this.actionClick.emit(action);\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-split-button.mjs","sources":["../../../../projects/ui-core/split-button/neu-split-button.component.ts","../../../../projects/ui-core/split-button/neural-ui-core-split-button.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuButtonVariant, NeuButtonSize } from '@neural-ui/core/button';\n\nexport interface NeuSplitButtonAction {\n /** Identificador único de la acción / Unique action identifier */\n id: string;\n /** Texto visible / Visible text */\n label: string;\n /** Icono opcional (SVG string o nombre) / Optional icon (SVG string or name) */\n icon?: string;\n /** Deshabilita esta acción individualmente / Disables this action individually */\n disabled?: boolean;\n /** Separador visual encima de este item / Visual separator above this item */\n divider?: boolean;\n}\n\n/**\n * NeuralUI SplitButton Component\n *\n * Botón principal con un dropdown de acciones adicionales. / Primary button with a dropdown of additional actions.\n *\n * Uso:\n * <neu-split-button\n * label=\"Guardar\"\n * [actions]=\"actions\"\n * (primaryClick)=\"save()\"\n * (actionClick)=\"onAction($event)\"\n * />\n */\n@Component({\n selector: 'neu-split-button',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'neu-split-button-host',\n '(document:click)': 'onDocumentClick($event)',\n '(keydown.escape)': 'closeDropdown()',\n },\n template: `\n <div class=\"neu-split-button\" [class.neu-split-button--disabled]=\"isDisabled()\">\n <!-- Botón principal -->\n <button\n class=\"neu-split-button__main\"\n [class]=\"mainClasses()\"\n type=\"button\"\n [disabled]=\"isDisabled() || null\"\n [attr.aria-disabled]=\"isDisabled()\"\n [attr.aria-busy]=\"loading()\"\n (click)=\"onPrimaryClick($event)\"\n >\n @if (loading()) {\n <span class=\"neu-button__spinner\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.416\"\n stroke-dashoffset=\"10\"\n />\n </svg>\n </span>\n }\n {{ label() }}\n </button>\n\n <!-- Separador -->\n <span class=\"neu-split-button__divider\" aria-hidden=\"true\"></span>\n\n <!-- Chevron trigger -->\n <button\n class=\"neu-split-button__chevron\"\n [class]=\"chevronClasses()\"\n type=\"button\"\n [disabled]=\"isDisabled() || null\"\n [attr.aria-haspopup]=\"'menu'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-label]=\"moreActionsAriaLabel()\"\n (click)=\"toggleDropdown($event)\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n\n <!-- Dropdown de acciones -->\n @if (isOpen()) {\n <div\n class=\"neu-split-button__dropdown\"\n role=\"menu\"\n [attr.aria-label]=\"actionsAriaLabel()\"\n (click)=\"$event.stopPropagation()\"\n >\n @for (action of actions(); track action.id) {\n @if (action.divider) {\n <div class=\"neu-split-button__dropdown-sep\" role=\"separator\" aria-hidden=\"true\"></div>\n }\n <button\n class=\"neu-split-button__dropdown-item\"\n [class.neu-split-button__dropdown-item--disabled]=\"action.disabled\"\n type=\"button\"\n role=\"menuitem\"\n [disabled]=\"action.disabled || null\"\n [attr.aria-disabled]=\"action.disabled ? 'true' : null\"\n (click)=\"onActionClick(action)\"\n >\n {{ action.label }}\n </button>\n }\n </div>\n }\n </div>\n `,\n styleUrl: './neu-split-button.component.scss',\n})\nexport class NeuSplitButtonComponent {\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** Texto del botón principal / Primary button text */\n label = input<string>('');\n\n /** Variante visual / Visual variant */\n variant = input<NeuButtonVariant>('primary');\n\n /** Tamaño / Size */\n size = input<NeuButtonSize>('md');\n\n /** Deshabilita todo el componente / Disables the entire component */\n disabled = input<boolean>(false);\n\n /** Muestra spinner en el botón principal / Shows spinner on the primary button */\n loading = input<boolean>(false);\n\n /** Acciones del dropdown / Dropdown actions */\n actions = input<NeuSplitButtonAction[]>([]);\n\n /** Aria-label del botón de desplegable / Aria-label for the dropdown button */\n moreActionsAriaLabel = input<string>('Más opciones');\n\n /** Aria-label del menú desplegable / Aria-label for the dropdown menu */\n actionsAriaLabel = input<string>('Acciones');\n\n /** Emite al hacer click en el botón principal / Emits on primary button click */\n primaryClick = output<MouseEvent>();\n\n /** Emite al seleccionar una acción del dropdown / Emits when a dropdown action is selected */\n actionClick = output<NeuSplitButtonAction>();\n\n readonly isOpen = signal(false);\n\n readonly isDisabled = computed(() => this.disabled() || this.loading());\n\n readonly mainClasses = computed(\n () =>\n `neu-button neu-button--${this.variant()} neu-button--${this.size()}${this.loading() ? ' neu-button--loading' : ''}`,\n );\n\n readonly chevronClasses = computed(\n () => `neu-button neu-button--${this.variant()} neu-button--${this.size()}`,\n );\n\n toggleDropdown(event: MouseEvent): void {\n event.stopPropagation();\n this.isOpen.update((v) => !v);\n }\n\n closeDropdown(): void {\n this.isOpen.set(false);\n }\n\n onDocumentClick(event: MouseEvent): void {\n if (!this.el.nativeElement.contains(event.target as Node)) this.closeDropdown();\n }\n\n onPrimaryClick(event: MouseEvent): void {\n if (this.isDisabled()) return;\n this.primaryClick.emit(event);\n }\n\n onActionClick(action: NeuSplitButtonAction): void {\n if (action.disabled) return;\n this.closeDropdown();\n this.actionClick.emit(action);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -128,7 +128,7 @@ class NeuStepperComponent {
128
128
  <ng-content />
129
129
  </div>
130
130
  </div>
131
- `, isInline: true, styles: [".neu-stepper{--neu-stepper-indicator-size: 32px;--neu-stepper-indicator-radius: calc(var(--neu-stepper-indicator-size) / 2);--neu-stepper-connector-gap: 8px;display:flex;flex-direction:column;gap:var(--neu-space-6);font-family:var(--neu-font-sans)}.neu-stepper__header{display:flex;align-items:flex-start;gap:0;overflow-x:auto;scrollbar-width:thin;padding-bottom:var(--neu-space-2)}.neu-stepper__step{position:relative;display:flex;flex-direction:column;align-items:center;flex:1 0 8.5rem;min-width:8.5rem}.neu-stepper__step-btn{display:flex;flex-direction:column;align-items:center;width:100%;gap:var(--neu-space-3);background:none;border:none;padding:0 var(--neu-space-2);cursor:pointer;min-width:0;outline:none;position:relative;z-index:1}.neu-stepper__step-btn:focus-visible .neu-stepper__indicator{box-shadow:0 0 0 3px var(--neu-primary-100)}.neu-stepper__step-btn:disabled{cursor:not-allowed}.neu-stepper__indicator{width:var(--neu-stepper-indicator-size);height:var(--neu-stepper-indicator-size);border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:.8125rem;font-weight:700;background:var(--neu-surface-2);border:2px solid var(--neu-border);color:var(--neu-text-disabled);transition:background var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition)}.neu-stepper__step--active .neu-stepper__indicator{background:var(--neu-primary);border-color:var(--neu-primary);color:var(--neu-primary-fg)}.neu-stepper__step--completed .neu-stepper__indicator{background:var(--neu-success);border-color:var(--neu-success);color:var(--neu-primary-fg)}.neu-stepper__step-info{display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;width:100%;gap:2px}.neu-stepper__step-label{display:block;font-size:var(--neu-text-sm);font-weight:600;color:var(--neu-text-muted);transition:color var(--neu-transition);line-height:1.25;overflow-wrap:anywhere}.neu-stepper__step--active .neu-stepper__step-label{color:var(--neu-text)}.neu-stepper__step--completed .neu-stepper__step-label{color:var(--neu-text-muted)}.neu-stepper__step-desc{display:block;max-width:100%;font-size:var(--neu-text-xs);color:var(--neu-text-disabled);margin-top:1px;line-height:1.35;overflow-wrap:anywhere}.neu-stepper__connector{position:absolute;top:calc(var(--neu-stepper-indicator-radius) - 1px);left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2);height:2px;background:var(--neu-border);transition:background var(--neu-transition);z-index:0}.neu-stepper__connector--done{background:var(--neu-success)}.neu-stepper__content{min-height:80px}@media(max-width:767px){.neu-stepper__header{align-items:flex-start;gap:var(--neu-space-2);scroll-snap-type:x proximity}.neu-stepper__step{flex:0 0 auto;min-width:3.5rem}.neu-stepper__step-btn{padding-inline:0}.neu-stepper__connector{left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2)}.neu-stepper__step-info{display:none}}\n"], dependencies: [{ kind: "directive", type: NeuTooltipDirective, selector: "[neuTooltip]", inputs: ["neuTooltip", "neuTooltipPosition", "neuTooltipDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
131
+ `, isInline: true, styles: [".neu-stepper{--neu-stepper-indicator-size: 32px;--neu-stepper-indicator-radius: calc(var(--neu-stepper-indicator-size) / 2);--neu-stepper-connector-gap: 8px;display:flex;flex-direction:column;gap:var(--neu-space-6);font-family:var(--neu-font-sans)}.neu-stepper__header{display:flex;align-items:flex-start;gap:0;overflow-x:auto;scrollbar-width:thin;padding-bottom:var(--neu-space-2)}.neu-stepper__step{position:relative;display:flex;flex-direction:column;align-items:center;flex:1 0 8.5rem;min-width:8.5rem}.neu-stepper__step-btn{display:flex;flex-direction:column;align-items:center;width:100%;gap:var(--neu-space-3);background:none;border:none;padding:0 var(--neu-space-2);cursor:pointer;min-width:0;outline:none;position:relative;z-index:1}.neu-stepper__step-btn:focus-visible .neu-stepper__indicator{box-shadow:0 0 0 3px var(--neu-primary-100)}.neu-stepper__step-btn:disabled{cursor:not-allowed}.neu-stepper__indicator{width:var(--neu-stepper-indicator-size);height:var(--neu-stepper-indicator-size);border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:.8125rem;font-weight:700;background:var(--neu-surface-2);border:2px solid var(--neu-border);color:var(--neu-text-disabled);transition:background var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition)}.neu-stepper__step--active .neu-stepper__indicator{background:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));border-color:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-primary-solid-fg, var(--neu-primary-fg))}.neu-stepper__step--completed .neu-stepper__indicator{background:var(--neu-success);border-color:var(--neu-success);color:var(--neu-primary-fg)}.neu-stepper__step-info{display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;width:100%;gap:2px}.neu-stepper__step-label{display:block;font-size:var(--neu-text-sm);font-weight:600;color:var(--neu-text-muted);transition:color var(--neu-transition);line-height:1.25;overflow-wrap:anywhere}.neu-stepper__step--active .neu-stepper__step-label{color:var(--neu-text)}.neu-stepper__step--completed .neu-stepper__step-label{color:var(--neu-text-muted)}.neu-stepper__step-desc{display:block;max-width:100%;font-size:var(--neu-text-xs);color:var(--neu-text-disabled);margin-top:1px;line-height:1.35;overflow-wrap:anywhere}.neu-stepper__connector{position:absolute;top:calc(var(--neu-stepper-indicator-radius) - 1px);left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2);height:2px;background:var(--neu-border);transition:background var(--neu-transition);z-index:0}.neu-stepper__connector--done{background:var(--neu-success)}.neu-stepper__content{min-height:80px}@media(max-width:767px){.neu-stepper__header{align-items:flex-start;gap:var(--neu-space-2);scroll-snap-type:x proximity}.neu-stepper__step{flex:0 0 auto;min-width:3.5rem}.neu-stepper__step-btn{padding-inline:0}.neu-stepper__connector{left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2)}.neu-stepper__step-info{display:none}}\n"], dependencies: [{ kind: "directive", type: NeuTooltipDirective, selector: "[neuTooltip]", inputs: ["neuTooltip", "neuTooltipPosition", "neuTooltipDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
132
132
  }
133
133
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuStepperComponent, decorators: [{
134
134
  type: Component,
@@ -193,7 +193,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
193
193
  <ng-content />
194
194
  </div>
195
195
  </div>
196
- `, styles: [".neu-stepper{--neu-stepper-indicator-size: 32px;--neu-stepper-indicator-radius: calc(var(--neu-stepper-indicator-size) / 2);--neu-stepper-connector-gap: 8px;display:flex;flex-direction:column;gap:var(--neu-space-6);font-family:var(--neu-font-sans)}.neu-stepper__header{display:flex;align-items:flex-start;gap:0;overflow-x:auto;scrollbar-width:thin;padding-bottom:var(--neu-space-2)}.neu-stepper__step{position:relative;display:flex;flex-direction:column;align-items:center;flex:1 0 8.5rem;min-width:8.5rem}.neu-stepper__step-btn{display:flex;flex-direction:column;align-items:center;width:100%;gap:var(--neu-space-3);background:none;border:none;padding:0 var(--neu-space-2);cursor:pointer;min-width:0;outline:none;position:relative;z-index:1}.neu-stepper__step-btn:focus-visible .neu-stepper__indicator{box-shadow:0 0 0 3px var(--neu-primary-100)}.neu-stepper__step-btn:disabled{cursor:not-allowed}.neu-stepper__indicator{width:var(--neu-stepper-indicator-size);height:var(--neu-stepper-indicator-size);border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:.8125rem;font-weight:700;background:var(--neu-surface-2);border:2px solid var(--neu-border);color:var(--neu-text-disabled);transition:background var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition)}.neu-stepper__step--active .neu-stepper__indicator{background:var(--neu-primary);border-color:var(--neu-primary);color:var(--neu-primary-fg)}.neu-stepper__step--completed .neu-stepper__indicator{background:var(--neu-success);border-color:var(--neu-success);color:var(--neu-primary-fg)}.neu-stepper__step-info{display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;width:100%;gap:2px}.neu-stepper__step-label{display:block;font-size:var(--neu-text-sm);font-weight:600;color:var(--neu-text-muted);transition:color var(--neu-transition);line-height:1.25;overflow-wrap:anywhere}.neu-stepper__step--active .neu-stepper__step-label{color:var(--neu-text)}.neu-stepper__step--completed .neu-stepper__step-label{color:var(--neu-text-muted)}.neu-stepper__step-desc{display:block;max-width:100%;font-size:var(--neu-text-xs);color:var(--neu-text-disabled);margin-top:1px;line-height:1.35;overflow-wrap:anywhere}.neu-stepper__connector{position:absolute;top:calc(var(--neu-stepper-indicator-radius) - 1px);left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2);height:2px;background:var(--neu-border);transition:background var(--neu-transition);z-index:0}.neu-stepper__connector--done{background:var(--neu-success)}.neu-stepper__content{min-height:80px}@media(max-width:767px){.neu-stepper__header{align-items:flex-start;gap:var(--neu-space-2);scroll-snap-type:x proximity}.neu-stepper__step{flex:0 0 auto;min-width:3.5rem}.neu-stepper__step-btn{padding-inline:0}.neu-stepper__connector{left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2)}.neu-stepper__step-info{display:none}}\n"] }]
196
+ `, styles: [".neu-stepper{--neu-stepper-indicator-size: 32px;--neu-stepper-indicator-radius: calc(var(--neu-stepper-indicator-size) / 2);--neu-stepper-connector-gap: 8px;display:flex;flex-direction:column;gap:var(--neu-space-6);font-family:var(--neu-font-sans)}.neu-stepper__header{display:flex;align-items:flex-start;gap:0;overflow-x:auto;scrollbar-width:thin;padding-bottom:var(--neu-space-2)}.neu-stepper__step{position:relative;display:flex;flex-direction:column;align-items:center;flex:1 0 8.5rem;min-width:8.5rem}.neu-stepper__step-btn{display:flex;flex-direction:column;align-items:center;width:100%;gap:var(--neu-space-3);background:none;border:none;padding:0 var(--neu-space-2);cursor:pointer;min-width:0;outline:none;position:relative;z-index:1}.neu-stepper__step-btn:focus-visible .neu-stepper__indicator{box-shadow:0 0 0 3px var(--neu-primary-100)}.neu-stepper__step-btn:disabled{cursor:not-allowed}.neu-stepper__indicator{width:var(--neu-stepper-indicator-size);height:var(--neu-stepper-indicator-size);border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:.8125rem;font-weight:700;background:var(--neu-surface-2);border:2px solid var(--neu-border);color:var(--neu-text-disabled);transition:background var(--neu-transition),border-color var(--neu-transition),color var(--neu-transition)}.neu-stepper__step--active .neu-stepper__indicator{background:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));border-color:var(--neu-primary-solid, var(--neu-primary-dark, var(--neu-primary)));color:var(--neu-primary-solid-fg, var(--neu-primary-fg))}.neu-stepper__step--completed .neu-stepper__indicator{background:var(--neu-success);border-color:var(--neu-success);color:var(--neu-primary-fg)}.neu-stepper__step-info{display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;width:100%;gap:2px}.neu-stepper__step-label{display:block;font-size:var(--neu-text-sm);font-weight:600;color:var(--neu-text-muted);transition:color var(--neu-transition);line-height:1.25;overflow-wrap:anywhere}.neu-stepper__step--active .neu-stepper__step-label{color:var(--neu-text)}.neu-stepper__step--completed .neu-stepper__step-label{color:var(--neu-text-muted)}.neu-stepper__step-desc{display:block;max-width:100%;font-size:var(--neu-text-xs);color:var(--neu-text-disabled);margin-top:1px;line-height:1.35;overflow-wrap:anywhere}.neu-stepper__connector{position:absolute;top:calc(var(--neu-stepper-indicator-radius) - 1px);left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2);height:2px;background:var(--neu-border);transition:background var(--neu-transition);z-index:0}.neu-stepper__connector--done{background:var(--neu-success)}.neu-stepper__content{min-height:80px}@media(max-width:767px){.neu-stepper__header{align-items:flex-start;gap:var(--neu-space-2);scroll-snap-type:x proximity}.neu-stepper__step{flex:0 0 auto;min-width:3.5rem}.neu-stepper__step-btn{padding-inline:0}.neu-stepper__connector{left:calc(50% + var(--neu-stepper-indicator-radius) + var(--neu-stepper-connector-gap));width:calc(100% - var(--neu-stepper-indicator-size) - var(--neu-stepper-connector-gap) * 2)}.neu-stepper__step-info{display:none}}\n"] }]
197
197
  }], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: false }] }], activeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStep", required: false }] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }] } });
198
198
 
199
199
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-stepper.mjs","sources":["../../../../projects/ui-core/stepper/neu-stepper.component.ts","../../../../projects/ui-core/stepper/neural-ui-core-stepper.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ViewEncapsulation,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuTooltipDirective } from '@neural-ui/core/tooltip';\n\nexport interface NeuStepperStep {\n /** Etiqueta del paso / Step label */\n label: string;\n /** Descripción corta opcional / Optional short description */\n description?: string;\n /** Marca el paso como completado externamente / Marks the step as completed externally */\n completed?: boolean;\n /** Desactiva el paso / Disables the step */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Stepper Component\n *\n * Wizard paso a paso con estado de completado, lineal u opcional.\n * Expone métodos next() / prev() y emite stepChange.\n *\n * Uso:\n * <neu-stepper [steps]=\"steps\" [activeStep]=\"step\" (stepChange)=\"step = $event\">\n * <ng-template neuStepContent>Contenido paso 1</ng-template>\n * <ng-template neuStepContent>Contenido paso 2</ng-template>\n * </neu-stepper>\n */\n@Component({\n selector: 'neu-stepper',\n imports: [NeuTooltipDirective],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- Cabecera de pasos -->\n <div class=\"neu-stepper\">\n <div class=\"neu-stepper__header\">\n @for (step of steps(); track step.label; let i = $index; let last = $last) {\n <div\n class=\"neu-stepper__step\"\n [class.neu-stepper__step--active]=\"i === activeStep()\"\n [class.neu-stepper__step--completed]=\"isCompleted(i)\"\n [class.neu-stepper__step--disabled]=\"step.disabled\"\n >\n @if (!last) {\n <div\n class=\"neu-stepper__connector\"\n [class.neu-stepper__connector--done]=\"isCompleted(i) || i < activeStep()\"\n ></div>\n }\n <button\n class=\"neu-stepper__step-btn\"\n type=\"button\"\n [disabled]=\"step.disabled\"\n [attr.aria-label]=\"stepAriaLabel(step)\"\n [neuTooltip]=\"stepTooltip(step)\"\n [neuTooltipDisabled]=\"!isCompact()\"\n neuTooltipPosition=\"bottom\"\n (click)=\"goTo(i)\"\n >\n <span class=\"neu-stepper__indicator\">\n @if (isCompleted(i)) {\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n } @else {\n {{ i + 1 }}\n }\n </span>\n <span class=\"neu-stepper__step-info\">\n <span class=\"neu-stepper__step-label\">{{ step.label }}</span>\n @if (step.description) {\n <span class=\"neu-stepper__step-desc\">{{ step.description }}</span>\n }\n </span>\n </button>\n </div>\n }\n </div>\n\n <!-- Panel de contenido -->\n <div class=\"neu-stepper__content\">\n <ng-content />\n </div>\n </div>\n `,\n styleUrl: './neu-stepper.component.scss',\n})\nexport class NeuStepperComponent {\n private readonly _destroyRef = inject(DestroyRef);\n\n /** Pasos del wizard / Wizard steps */\n steps = input<NeuStepperStep[]>([]);\n\n /** Índice del paso activo (0-based) / Active step index (0-based) */\n activeStep = input<number>(0);\n\n /** Si true, solo permite ir hacia adelante secuencialmente / If true, only allows moving forward sequentially */\n linear = input<boolean>(false);\n\n /** Emite el nuevo índice al cambiar / Emits the new index on change */\n stepChange = output<number>();\n\n /** Set de pasos completados / Set of completed steps */\n private readonly _completed = signal<Set<number>>(new Set());\n readonly isCompact = signal(typeof window !== 'undefined' ? window.innerWidth <= 767 : false);\n\n readonly isCompleted = (i: number) =>\n this._completed().has(i) || (this.steps()[i]?.completed ?? false) || i < this.activeStep();\n\n readonly stepTooltip = (step: NeuStepperStep) =>\n step.description ? `${step.label} - ${step.description}` : step.label;\n\n readonly stepAriaLabel = (step: NeuStepperStep) => this.stepTooltip(step);\n\n constructor() {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n const mediaQuery = window.matchMedia('(max-width: 767px)');\n const updateCompact = (event?: MediaQueryListEvent) => {\n this.isCompact.set(event?.matches ?? mediaQuery.matches);\n };\n\n updateCompact();\n mediaQuery.addEventListener('change', updateCompact);\n this._destroyRef.onDestroy(() => mediaQuery.removeEventListener('change', updateCompact));\n }\n\n goTo(i: number): void {\n const step = this.steps()[i];\n if (step?.disabled) return;\n if (this.linear() && i > this.activeStep() + 1 && !this.isCompleted(this.activeStep())) return;\n this.stepChange.emit(i);\n }\n\n /** Marca el paso actual como completado y avanza al siguiente / Marks the current step as completed and advances to the next */\n next(): void {\n const current = this.activeStep();\n const updated = new Set(this._completed());\n updated.add(current);\n this._completed.set(updated);\n if (current < this.steps().length - 1) {\n this.stepChange.emit(current + 1);\n }\n }\n\n prev(): void {\n const current = this.activeStep();\n if (current > 0) {\n this.stepChange.emit(current - 1);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAuBA;;;;;;;;;;;AAWG;MAsEU,mBAAmB,CAAA;AACb,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;AAGjD,IAAA,KAAK,GAAG,KAAK,CAAmB,EAAE,4EAAC;;AAGnC,IAAA,UAAU,GAAG,KAAK,CAAS,CAAC,iFAAC;;AAG7B,IAAA,MAAM,GAAG,KAAK,CAAU,KAAK,6EAAC;;IAG9B,UAAU,GAAG,MAAM,EAAU;;AAGZ,IAAA,UAAU,GAAG,MAAM,CAAc,IAAI,GAAG,EAAE,iFAAC;IACnD,SAAS,GAAG,MAAM,CAAC,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,CAAC,UAAU,IAAI,GAAG,GAAG,KAAK,gFAAC;AAEpF,IAAA,WAAW,GAAG,CAAC,CAAS,KAC/B,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE;IAEnF,WAAW,GAAG,CAAC,IAAoB,KAC1C,IAAI,CAAC,WAAW,GAAG,CAAA,EAAG,IAAI,CAAC,KAAK,CAAA,GAAA,EAAM,IAAI,CAAC,WAAW,CAAA,CAAE,GAAG,IAAI,CAAC,KAAK;AAE9D,IAAA,aAAa,GAAG,CAAC,IAAoB,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AAEzE,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE;YAC5E;QACF;QAEA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC;AAC1D,QAAA,MAAM,aAAa,GAAG,CAAC,KAA2B,KAAI;AACpD,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC;AAC1D,QAAA,CAAC;AAED,QAAA,aAAa,EAAE;AACf,QAAA,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC;AACpD,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC3F;AAEA,IAAA,IAAI,CAAC,CAAS,EAAA;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5B,IAAI,IAAI,EAAE,QAAQ;YAAE;QACpB,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAAE;AACxF,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB;;IAGA,IAAI,GAAA;AACF,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;QACjC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;AAC1C,QAAA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AACpB,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;QAC5B,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;YACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACnC;IACF;IAEA,IAAI,GAAA;AACF,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;AACjC,QAAA,IAAI,OAAO,GAAG,CAAC,EAAE;YACf,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACnC;IACF;uGAjEW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,4mGAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAhES,mBAAmB,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,oBAAA,EAAA,oBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAmElB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBArE/B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,EAAA,OAAA,EACd,CAAC,mBAAmB,CAAC,EAAA,aAAA,EACf,iBAAiB,CAAC,IAAI,EAAA,eAAA,EACpB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,4mGAAA,CAAA,EAAA;;;ACrGH;;AAEG;;;;"}
1
+ {"version":3,"file":"neural-ui-core-stepper.mjs","sources":["../../../../projects/ui-core/stepper/neu-stepper.component.ts","../../../../projects/ui-core/stepper/neural-ui-core-stepper.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ViewEncapsulation,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuTooltipDirective } from '@neural-ui/core/tooltip';\n\nexport interface NeuStepperStep {\n /** Etiqueta del paso / Step label */\n label: string;\n /** Descripción corta opcional / Optional short description */\n description?: string;\n /** Marca el paso como completado externamente / Marks the step as completed externally */\n completed?: boolean;\n /** Desactiva el paso / Disables the step */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Stepper Component\n *\n * Wizard paso a paso con estado de completado, lineal u opcional.\n * Expone métodos next() / prev() y emite stepChange.\n *\n * Uso:\n * <neu-stepper [steps]=\"steps\" [activeStep]=\"step\" (stepChange)=\"step = $event\">\n * <ng-template neuStepContent>Contenido paso 1</ng-template>\n * <ng-template neuStepContent>Contenido paso 2</ng-template>\n * </neu-stepper>\n */\n@Component({\n selector: 'neu-stepper',\n imports: [NeuTooltipDirective],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- Cabecera de pasos -->\n <div class=\"neu-stepper\">\n <div class=\"neu-stepper__header\">\n @for (step of steps(); track step.label; let i = $index; let last = $last) {\n <div\n class=\"neu-stepper__step\"\n [class.neu-stepper__step--active]=\"i === activeStep()\"\n [class.neu-stepper__step--completed]=\"isCompleted(i)\"\n [class.neu-stepper__step--disabled]=\"step.disabled\"\n >\n @if (!last) {\n <div\n class=\"neu-stepper__connector\"\n [class.neu-stepper__connector--done]=\"isCompleted(i) || i < activeStep()\"\n ></div>\n }\n <button\n class=\"neu-stepper__step-btn\"\n type=\"button\"\n [disabled]=\"step.disabled\"\n [attr.aria-label]=\"stepAriaLabel(step)\"\n [neuTooltip]=\"stepTooltip(step)\"\n [neuTooltipDisabled]=\"!isCompact()\"\n neuTooltipPosition=\"bottom\"\n (click)=\"goTo(i)\"\n >\n <span class=\"neu-stepper__indicator\">\n @if (isCompleted(i)) {\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n } @else {\n {{ i + 1 }}\n }\n </span>\n <span class=\"neu-stepper__step-info\">\n <span class=\"neu-stepper__step-label\">{{ step.label }}</span>\n @if (step.description) {\n <span class=\"neu-stepper__step-desc\">{{ step.description }}</span>\n }\n </span>\n </button>\n </div>\n }\n </div>\n\n <!-- Panel de contenido -->\n <div class=\"neu-stepper__content\">\n <ng-content />\n </div>\n </div>\n `,\n styleUrl: './neu-stepper.component.scss',\n})\nexport class NeuStepperComponent {\n private readonly _destroyRef = inject(DestroyRef);\n\n /** Pasos del wizard / Wizard steps */\n steps = input<NeuStepperStep[]>([]);\n\n /** Índice del paso activo (0-based) / Active step index (0-based) */\n activeStep = input<number>(0);\n\n /** Si true, solo permite ir hacia adelante secuencialmente / If true, only allows moving forward sequentially */\n linear = input<boolean>(false);\n\n /** Emite el nuevo índice al cambiar / Emits the new index on change */\n stepChange = output<number>();\n\n /** Set de pasos completados / Set of completed steps */\n private readonly _completed = signal<Set<number>>(new Set());\n readonly isCompact = signal(typeof window !== 'undefined' ? window.innerWidth <= 767 : false);\n\n readonly isCompleted = (i: number) =>\n this._completed().has(i) || (this.steps()[i]?.completed ?? false) || i < this.activeStep();\n\n readonly stepTooltip = (step: NeuStepperStep) =>\n step.description ? `${step.label} - ${step.description}` : step.label;\n\n readonly stepAriaLabel = (step: NeuStepperStep) => this.stepTooltip(step);\n\n constructor() {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n\n const mediaQuery = window.matchMedia('(max-width: 767px)');\n const updateCompact = (event?: MediaQueryListEvent) => {\n this.isCompact.set(event?.matches ?? mediaQuery.matches);\n };\n\n updateCompact();\n mediaQuery.addEventListener('change', updateCompact);\n this._destroyRef.onDestroy(() => mediaQuery.removeEventListener('change', updateCompact));\n }\n\n goTo(i: number): void {\n const step = this.steps()[i];\n if (step?.disabled) return;\n if (this.linear() && i > this.activeStep() + 1 && !this.isCompleted(this.activeStep())) return;\n this.stepChange.emit(i);\n }\n\n /** Marca el paso actual como completado y avanza al siguiente / Marks the current step as completed and advances to the next */\n next(): void {\n const current = this.activeStep();\n const updated = new Set(this._completed());\n updated.add(current);\n this._completed.set(updated);\n if (current < this.steps().length - 1) {\n this.stepChange.emit(current + 1);\n }\n }\n\n prev(): void {\n const current = this.activeStep();\n if (current > 0) {\n this.stepChange.emit(current - 1);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}