@neural-ui/core 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +12 -6
  2. package/fesm2022/neural-ui-core-accordion.mjs +8 -6
  3. package/fesm2022/neural-ui-core-accordion.mjs.map +1 -1
  4. package/fesm2022/neural-ui-core-autocomplete.mjs +121 -29
  5. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
  6. package/fesm2022/neural-ui-core-badge.mjs +2 -2
  7. package/fesm2022/neural-ui-core-badge.mjs.map +1 -1
  8. package/fesm2022/neural-ui-core-button.mjs +2 -2
  9. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  10. package/fesm2022/neural-ui-core-chip.mjs +2 -2
  11. package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
  12. package/fesm2022/neural-ui-core-color-picker.mjs +3 -9
  13. package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -1
  14. package/fesm2022/neural-ui-core-filter-bar.mjs +2 -2
  15. package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -1
  16. package/fesm2022/neural-ui-core-modal.mjs +81 -31
  17. package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
  18. package/fesm2022/neural-ui-core-multiselect.mjs +258 -99
  19. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  20. package/fesm2022/neural-ui-core-nav.mjs +4 -6
  21. package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
  22. package/fesm2022/neural-ui-core-select.mjs +247 -94
  23. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  24. package/fesm2022/neural-ui-core-sidebar.mjs +3 -2
  25. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  26. package/fesm2022/neural-ui-core-slider.mjs +2 -2
  27. package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
  28. package/fesm2022/neural-ui-core-split-button.mjs +2 -2
  29. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  30. package/fesm2022/neural-ui-core-table.mjs +168 -21
  31. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  32. package/fesm2022/neural-ui-core-tabs.mjs +11 -4
  33. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
  34. package/fesm2022/neural-ui-core-toolbar.mjs +2 -2
  35. package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -1
  36. package/fesm2022/neural-ui-core-url-state.mjs +90 -10
  37. package/fesm2022/neural-ui-core-url-state.mjs.map +1 -1
  38. package/fesm2022/neural-ui-core-virtual-list.mjs +52 -22
  39. package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
  40. package/package.json +1 -1
  41. package/styles/_tokens.scss +8 -8
  42. package/types/neural-ui-core-autocomplete.d.ts +10 -1
  43. package/types/neural-ui-core-color-picker.d.ts +0 -1
  44. package/types/neural-ui-core-modal.d.ts +22 -16
  45. package/types/neural-ui-core-multiselect.d.ts +12 -1
  46. package/types/neural-ui-core-select.d.ts +12 -1
  47. package/types/neural-ui-core-sidebar.d.ts +1 -0
  48. package/types/neural-ui-core-table.d.ts +23 -3
  49. package/types/neural-ui-core-tabs.d.ts +1 -0
  50. package/types/neural-ui-core-url-state.d.ts +9 -0
  51. package/types/neural-ui-core-virtual-list.d.ts +17 -1
@@ -7,9 +7,9 @@
7
7
  // ------------------------------------------------
8
8
  // Brand — Neural-Blue (inspirado en Apple HIG)
9
9
  // ------------------------------------------------
10
- --neu-primary: #007aff;
11
- --neu-primary-dark: #005fcc;
12
- --neu-primary-light: #339dff;
10
+ --neu-primary: #005fcc;
11
+ --neu-primary-dark: #004799;
12
+ --neu-primary-light: #2d7fff;
13
13
  --neu-primary-50: #eff6ff;
14
14
  --neu-primary-100: #dbeafe;
15
15
  --neu-primary-fg: #ffffff;
@@ -39,8 +39,8 @@
39
39
  // Tipografía (Slate scale)
40
40
  // ------------------------------------------------
41
41
  --neu-text: #0f172a; // Slate-900
42
- --neu-text-muted: #64748b; // Slate-500
43
- --neu-text-disabled: #94a3b8; // Slate-400
42
+ --neu-text-muted: #475569; // Slate-600
43
+ --neu-text-disabled: #64748b; // Slate-500
44
44
  --neu-text-inverse: #ffffff;
45
45
  --neu-knob-display-color: var(--neu-text);
46
46
  --neu-knob-label-color: var(--neu-text-muted);
@@ -60,7 +60,7 @@
60
60
  // ------------------------------------------------
61
61
  // Estados semánticos
62
62
  // ------------------------------------------------
63
- --neu-success: #10b981;
63
+ --neu-success: #15803d;
64
64
  --neu-success-bg: #d1fae5;
65
65
  --neu-success-text: #065f46;
66
66
 
@@ -68,11 +68,11 @@
68
68
  --neu-warning-bg: #fef3c7;
69
69
  --neu-warning-text: #92400e;
70
70
 
71
- --neu-error: #ef4444;
71
+ --neu-error: #dc2626;
72
72
  --neu-error-bg: #fee2e2;
73
73
  --neu-error-text: #991b1b;
74
74
 
75
- --neu-info: #007aff;
75
+ --neu-info: #005fcc;
76
76
  --neu-info-bg: #eff6ff;
77
77
  --neu-info-text: #1d4ed8;
78
78
 
@@ -35,6 +35,10 @@ declare class NeuAutocompleteComponent implements ControlValueAccessor {
35
35
  readonly floatingLabel: _angular_core.InputSignal<boolean>;
36
36
  /** Tamaño del campo: 'sm' = 36px | 'md' = 48px | 'lg' = 56px / Field size */
37
37
  readonly size: _angular_core.InputSignal<"sm" | "md" | "lg">;
38
+ /** Habilita scroll virtual para listas largas / Enables virtual scrolling for large result lists */
39
+ readonly virtualScroll: _angular_core.InputSignal<boolean>;
40
+ /** Número de resultados visibles en el viewport virtual / Number of visible results in the virtual viewport */
41
+ readonly virtualScrollVisibleItems: _angular_core.InputSignal<number>;
38
42
  /** Emitido al seleccionar una opción / Emitted when an option is selected */
39
43
  readonly optionSelected: _angular_core.OutputEmitterRef<NeuAutocompleteOption>;
40
44
  /** Emitido al cambiar el texto del input / Emitted on query change */
@@ -46,6 +50,7 @@ declare class NeuAutocompleteComponent implements ControlValueAccessor {
46
50
  readonly _activeIndex: _angular_core.WritableSignal<number>;
47
51
  readonly _cvaDisabled: _angular_core.WritableSignal<boolean>;
48
52
  readonly _focused: _angular_core.WritableSignal<boolean>;
53
+ private readonly _viewport;
49
54
  private _onChange;
50
55
  private _onTouched;
51
56
  readonly _filtered: _angular_core.Signal<NeuAutocompleteOption[]>;
@@ -53,6 +58,9 @@ declare class NeuAutocompleteComponent implements ControlValueAccessor {
53
58
  readonly hasError: _angular_core.Signal<boolean>;
54
59
  readonly describedBy: _angular_core.Signal<string | null>;
55
60
  readonly resultsAnnouncement: _angular_core.Signal<string>;
61
+ readonly virtualScrollItemSize: _angular_core.Signal<36 | 52 | 40>;
62
+ readonly virtualViewportHeight: _angular_core.Signal<string>;
63
+ readonly trackByOption: (index: number, option: NeuAutocompleteOption) => {};
56
64
  _optionId(i: number): string;
57
65
  private readonly _el;
58
66
  onDocClick(e: MouseEvent): void;
@@ -63,12 +71,13 @@ declare class NeuAutocompleteComponent implements ControlValueAccessor {
63
71
  private _moveActiveIndex;
64
72
  selectOption(opt: NeuAutocompleteOption): void;
65
73
  clear(): void;
74
+ private _scrollActiveOptionIntoView;
66
75
  writeValue(val: unknown): void;
67
76
  registerOnChange(fn: (v: unknown) => void): void;
68
77
  registerOnTouched(fn: () => void): void;
69
78
  setDisabledState(d: boolean): void;
70
79
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuAutocompleteComponent, never>;
71
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuAutocompleteComponent, "neu-autocomplete", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "optionSelected": "optionSelected"; "queryChange": "queryChange"; }, never, never, true, never>;
80
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuAutocompleteComponent, "neu-autocomplete", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "virtualScrollVisibleItems": { "alias": "virtualScrollVisibleItems"; "required": false; "isSignal": true; }; }, { "optionSelected": "optionSelected"; "queryChange": "queryChange"; }, never, never, true, never>;
72
81
  }
73
82
 
74
83
  export { NeuAutocompleteComponent };
@@ -29,7 +29,6 @@ declare class NeuColorPickerComponent implements ControlValueAccessor {
29
29
  private _onChange;
30
30
  private _onTouched;
31
31
  private readonly _el;
32
- constructor();
33
32
  _outsideClick(e: MouseEvent): void;
34
33
  readonly _hexValue: _angular_core.Signal<string>;
35
34
  readonly _textValue: _angular_core.Signal<string>;
@@ -3,22 +3,6 @@ import { Type } from '@angular/core';
3
3
  import { DialogRef } from '@angular/cdk/dialog';
4
4
 
5
5
  type NeuDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
6
- /** Datos que se inyectan en el componente del diálogo / Data injected into the dialog component */
7
- interface NeuDialogData<T = unknown> {
8
- title?: string;
9
- data?: T;
10
- }
11
- declare class NeuDialogService {
12
- private readonly dialog;
13
- open<T = unknown, R = unknown>(component: Type<unknown>, config?: {
14
- title?: string;
15
- data?: T;
16
- size?: NeuDialogSize;
17
- disableClose?: boolean;
18
- }): DialogRef<R>;
19
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuDialogService, never>;
20
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<NeuDialogService>;
21
- }
22
6
  /**
23
7
  * NeuDialogComponent — Diálogo accesible con header, body y footer. / Accessible dialog with header, body and footer.
24
8
  * Úsalo directamente como componente declarativo pasando `open` como signal. / Use it directly as a declarative component passing `open` as a signal.
@@ -44,11 +28,33 @@ declare class NeuDialogComponent {
44
28
  disableClose: _angular_core.InputSignal<boolean>;
45
29
  /** Emite cuando el usuario cierra el diálogo. / Emits when the user closes the dialog. */
46
30
  closed: _angular_core.OutputEmitterRef<void>;
31
+ private readonly panelRef;
47
32
  /** @internal — ID único para aria-labelledby / Unique ID for aria-labelledby */
48
33
  readonly _uid: string;
34
+ constructor();
35
+ onPanelKeydown(event: KeyboardEvent): void;
36
+ private focusInitialElement;
37
+ private getFocusableElements;
49
38
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuDialogComponent, never>;
50
39
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuDialogComponent, "neu-dialog", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "disableClose": { "alias": "disableClose"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, never, ["*", "[neu-dialog-footer]"], true, never>;
51
40
  }
52
41
 
42
+ /** Datos que se inyectan en el componente del diálogo / Data injected into the dialog component */
43
+ interface NeuDialogData<T = unknown> {
44
+ title?: string;
45
+ data?: T;
46
+ }
47
+ declare class NeuDialogService {
48
+ private readonly dialog;
49
+ open<T = unknown, R = unknown>(component: Type<unknown>, config?: {
50
+ title?: string;
51
+ data?: T;
52
+ size?: NeuDialogSize;
53
+ disableClose?: boolean;
54
+ }): DialogRef<R>;
55
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuDialogService, never>;
56
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<NeuDialogService>;
57
+ }
58
+
53
59
  export { NeuDialogComponent, NeuDialogService };
54
60
  export type { NeuDialogData, NeuDialogSize };
@@ -40,7 +40,9 @@ declare class NeuMultiselectComponent implements ControlValueAccessor {
40
40
  private readonly _urlState;
41
41
  private readonly _mobileViewportMax;
42
42
  private readonly _viewportMargin;
43
+ private readonly _panelMaxHeight;
43
44
  private readonly _urlParamSignals;
45
+ private readonly _viewport;
44
46
  private _getUrlParamSignal;
45
47
  constructor();
46
48
  /** @internal */
@@ -74,6 +76,10 @@ declare class NeuMultiselectComponent implements ControlValueAccessor {
74
76
  clearAllLabel: _angular_core.InputSignal<string>;
75
77
  /** Muestra un botón × en el trigger para limpiar la selección de una vez / Shows a × button in the trigger to clear the selection at once */
76
78
  clearable: _angular_core.InputSignal<boolean>;
79
+ /** Habilita scroll virtual para listas largas / Enables virtual scrolling for large option lists */
80
+ virtualScroll: _angular_core.InputSignal<boolean>;
81
+ /** Número de opciones visibles en el viewport virtual / Number of visible options in the virtual viewport */
82
+ virtualScrollVisibleItems: _angular_core.InputSignal<number>;
77
83
  /** Aria-label del botón clear que aparece en el trigger / Aria-label for the clear button shown in the trigger */
78
84
  clearAriaLabel: _angular_core.InputSignal<string>;
79
85
  /**
@@ -104,6 +110,9 @@ declare class NeuMultiselectComponent implements ControlValueAccessor {
104
110
  readonly describedBy: Signal<string | null>;
105
111
  readonly filteredOptions: Signal<NeuSelectOption[]>;
106
112
  readonly resultsAnnouncement: Signal<string>;
113
+ readonly virtualScrollItemSize: Signal<36 | 52 | 44>;
114
+ readonly virtualViewportHeight: Signal<string>;
115
+ readonly trackByOptionValue: (_index: number, option: NeuSelectOption) => string;
107
116
  private _onChange;
108
117
  private _onTouched;
109
118
  writeValue(value: string[] | null): void;
@@ -130,9 +139,11 @@ declare class NeuMultiselectComponent implements ControlValueAccessor {
130
139
  onWindowResize(): void;
131
140
  onWindowScroll(): void;
132
141
  private syncPanelPosition;
142
+ private focusFirstOption;
143
+ private focusOption;
133
144
  private resetPanelPosition;
134
145
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuMultiselectComponent, never>;
135
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuMultiselectComponent, "neu-multiselect", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "noResultsMessage": { "alias": "noResultsMessage"; "required": false; "isSignal": true; }; "clearAllLabel": { "alias": "clearAllLabel"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearAriaLabel": { "alias": "clearAriaLabel"; "required": false; "isSignal": true; }; "urlParam": { "alias": "urlParam"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, ["itemTpl"], never, true, never>;
146
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuMultiselectComponent, "neu-multiselect", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "noResultsMessage": { "alias": "noResultsMessage"; "required": false; "isSignal": true; }; "clearAllLabel": { "alias": "clearAllLabel"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "virtualScrollVisibleItems": { "alias": "virtualScrollVisibleItems"; "required": false; "isSignal": true; }; "clearAriaLabel": { "alias": "clearAriaLabel"; "required": false; "isSignal": true; }; "urlParam": { "alias": "urlParam"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, ["itemTpl"], never, true, never>;
136
147
  }
137
148
 
138
149
  export { NeuMultiselectComponent, NeuMultiselectItemDirective };
@@ -75,7 +75,9 @@ declare class NeuSelectComponent implements ControlValueAccessor {
75
75
  private readonly _urlState;
76
76
  private readonly _mobileViewportMax;
77
77
  private readonly _viewportMargin;
78
+ private readonly _panelMaxHeight;
78
79
  private readonly _urlParamSignals;
80
+ private readonly _viewport;
79
81
  private _getUrlParamSignal;
80
82
  constructor();
81
83
  /** @internal — ID \u00fanico para asociar label con trigger */
@@ -107,6 +109,10 @@ declare class NeuSelectComponent implements ControlValueAccessor {
107
109
  searchPlaceholder: _angular_core.InputSignal<string>;
108
110
  /** Muestra un botón para limpiar la selección / Shows a button to clear the selection */
109
111
  clearable: _angular_core.InputSignal<boolean>;
112
+ /** Habilita scroll virtual para listas largas / Enables virtual scrolling for large option lists */
113
+ virtualScroll: _angular_core.InputSignal<boolean>;
114
+ /** Número de opciones visibles en el viewport virtual / Number of visible options in the virtual viewport */
115
+ virtualScrollVisibleItems: _angular_core.InputSignal<number>;
110
116
  /** Texto cuando no hay opciones tras filtrar / Text when no options remain after filtering */
111
117
  noResultsMessage: _angular_core.InputSignal<string>;
112
118
  /** Aria-label del botón de limpiar / Aria-label for the clear button */
@@ -139,6 +145,9 @@ declare class NeuSelectComponent implements ControlValueAccessor {
139
145
  readonly selectedLabel: Signal<string | null>;
140
146
  readonly _selectedOption: Signal<NeuSelectOption | null>;
141
147
  readonly resultsAnnouncement: Signal<string>;
148
+ readonly virtualScrollItemSize: Signal<36 | 52 | 44>;
149
+ readonly virtualViewportHeight: Signal<string>;
150
+ readonly trackByOptionValue: (_index: number, option: NeuSelectOption) => string;
142
151
  private _onChange;
143
152
  private _onTouched;
144
153
  writeValue(val: string | null): void;
@@ -161,9 +170,11 @@ declare class NeuSelectComponent implements ControlValueAccessor {
161
170
  onWindowResize(): void;
162
171
  onWindowScroll(): void;
163
172
  private syncPanelPosition;
173
+ private focusFirstOption;
174
+ private focusOption;
164
175
  private resetPanelPosition;
165
176
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuSelectComponent, never>;
166
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuSelectComponent, "neu-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "noResultsMessage": { "alias": "noResultsMessage"; "required": false; "isSignal": true; }; "clearAriaLabel": { "alias": "clearAriaLabel"; "required": false; "isSignal": true; }; "urlParam": { "alias": "urlParam"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, ["itemTpl", "selectedItemTpl"], never, true, never>;
177
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuSelectComponent, "neu-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "virtualScrollVisibleItems": { "alias": "virtualScrollVisibleItems"; "required": false; "isSignal": true; }; "noResultsMessage": { "alias": "noResultsMessage"; "required": false; "isSignal": true; }; "clearAriaLabel": { "alias": "clearAriaLabel"; "required": false; "isSignal": true; }; "urlParam": { "alias": "urlParam"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, ["itemTpl", "selectedItemTpl"], never, true, never>;
167
178
  }
168
179
 
169
180
  export { NeuSelectComponent, NeuSelectItemDirective, NeuSelectSelectedDirective };
@@ -23,6 +23,7 @@ import * as _angular_core from '@angular/core';
23
23
  declare class NeuSidebarComponent {
24
24
  private readonly document;
25
25
  private readonly urlState;
26
+ private readonly openParam;
26
27
  /** Posición del sidebar: izquierda o derecha de la pantalla / Sidebar position: left or right of the screen */
27
28
  side: _angular_core.InputSignal<"left" | "right">;
28
29
  /** QueryParam que controla el estado. Default: 'menu' (?menu=open) / QueryParam that controls the state. Default: 'menu' (?menu=open) */
@@ -110,10 +110,14 @@ declare class NeuTableComponent {
110
110
  private readonly _destroyRef;
111
111
  private readonly _urlState;
112
112
  private readonly _platformId;
113
+ private readonly _scrollContainer;
114
+ private readonly _virtualOverscan;
113
115
  readonly expandTemplate: Signal<NeuTableExpandDirective | undefined>;
114
116
  readonly columns: _angular_core.InputSignal<NeuTableColumn<Record<string, unknown>>[]>;
115
117
  readonly data: _angular_core.InputSignal<object[]>;
116
118
  readonly pageSize: _angular_core.InputSignal<number>;
119
+ /** Controla si la paginación está activa. Si es false, se muestran todos los datos y se ocultan los controles de paginación y pageSize. */
120
+ readonly pagination: _angular_core.InputSignal<boolean>;
117
121
  readonly loading: _angular_core.InputSignal<boolean>;
118
122
  readonly title: _angular_core.InputSignal<string>;
119
123
  readonly emptyMessage: _angular_core.InputSignal<string>;
@@ -151,7 +155,12 @@ declare class NeuTableComponent {
151
155
  readonly exportFileName: _angular_core.InputSignal<string>;
152
156
  readonly pageSizeOptions: _angular_core.InputSignal<number[]>;
153
157
  readonly stickyHeader: _angular_core.InputSignal<boolean>;
158
+ readonly virtualScroll: _angular_core.InputSignal<boolean>;
159
+ readonly virtualScrollVisibleItems: _angular_core.InputSignal<number>;
154
160
  readonly rowKey: _angular_core.InputSignal<string>;
161
+ readonly bordered: _angular_core.InputSignal<boolean>;
162
+ readonly roundedBorders: _angular_core.InputSignal<boolean>;
163
+ readonly stripedRows: _angular_core.InputSignal<boolean>;
155
164
  readonly density: _angular_core.InputSignal<"compact" | "normal" | "relaxed">;
156
165
  readonly showRowNumbers: _angular_core.InputSignal<boolean>;
157
166
  readonly rowClass: _angular_core.InputSignal<((row: Row) => string) | undefined>;
@@ -213,6 +222,7 @@ declare class NeuTableComponent {
213
222
  * Converts filterOptions from string[] to NeuSelectOption[] with a leading "All" option. */
214
223
  _filterOpts(col: NeuTableColumn): NeuSelectOption[];
215
224
  readonly _pageSizeOptions: Signal<NeuSelectOption[]>;
225
+ private readonly _virtualScrollTop;
216
226
  constructor();
217
227
  private readonly _confirmPending;
218
228
  private readonly _rows;
@@ -222,11 +232,18 @@ declare class NeuTableComponent {
222
232
  readonly effectivePageSize: Signal<number>;
223
233
  readonly totalPages: Signal<number>;
224
234
  readonly paginatedData: Signal<Row[]>;
235
+ readonly _virtualRowHeight: Signal<34 | 64 | 48>;
236
+ readonly _virtualHeaderHeight: Signal<number>;
237
+ readonly _virtualScrollActive: Signal<boolean>;
238
+ readonly virtualContainerMaxHeight: Signal<string>;
239
+ readonly _virtualStartIndex: Signal<number>;
240
+ readonly _virtualEndIndex: Signal<number>;
241
+ readonly visiblePageRows: Signal<Row[]>;
242
+ readonly _virtualTopSpacerHeight: Signal<number>;
243
+ readonly _virtualBottomSpacerHeight: Signal<number>;
225
244
  readonly pageNumbers: Signal<number[]>;
226
245
  readonly paginationInfo: Signal<string>;
227
246
  readonly totalColspan: Signal<number>;
228
- /** Calcula el offset izquierdo acumulado para columnas frozen-left múltiples.
229
- * Calculates cumulative left offset for multiple frozen-left columns. */
230
247
  readonly _frozenLeftOffsets: Signal<Map<string, number>>;
231
248
  readonly _lastFrozenLeftKey: Signal<string | null>;
232
249
  readonly _firstFrozenRightKey: Signal<string>;
@@ -270,7 +287,10 @@ declare class NeuTableComponent {
270
287
  exportJson(): void;
271
288
  private _getExportColumns;
272
289
  private _downloadBlob;
290
+ onTableScroll(event: Event): void;
273
291
  getRowKey(row: Row): unknown;
292
+ visibleRowNumber(rowIdx: number): number;
293
+ private resetVirtualScrollPosition;
274
294
  getRowClass(row: Row): string;
275
295
  getCellValue(row: Row, col: NeuTableColumn): string;
276
296
  getSortPriority(key: string): number;
@@ -278,7 +298,7 @@ declare class NeuTableComponent {
278
298
  getColumnFilterValue(key: string): unknown;
279
299
  private _emitServerState;
280
300
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuTableComponent, never>;
281
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuTableComponent, "neu-table", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "skeletonRows": { "alias": "skeletonRows"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "exactMatchable": { "alias": "exactMatchable"; "required": false; "isSignal": true; }; "exactMatchLabel": { "alias": "exactMatchLabel"; "required": false; "isSignal": true; }; "searchAriaLabel": { "alias": "searchAriaLabel"; "required": false; "isSignal": true; }; "clearSearchAriaLabel": { "alias": "clearSearchAriaLabel"; "required": false; "isSignal": true; }; "clearFilterLabel": { "alias": "clearFilterLabel"; "required": false; "isSignal": true; }; "previousPageAriaLabel": { "alias": "previousPageAriaLabel"; "required": false; "isSignal": true; }; "nextPageAriaLabel": { "alias": "nextPageAriaLabel"; "required": false; "isSignal": true; }; "pageSizeLabel": { "alias": "pageSizeLabel"; "required": false; "isSignal": true; }; "pageSizeAriaLabel": { "alias": "pageSizeAriaLabel"; "required": false; "isSignal": true; }; "paginationAriaLabel": { "alias": "paginationAriaLabel"; "required": false; "isSignal": true; }; "exportCsvTitle": { "alias": "exportCsvTitle"; "required": false; "isSignal": true; }; "exportJsonTitle": { "alias": "exportJsonTitle"; "required": false; "isSignal": true; }; "clearSelectionLabel": { "alias": "clearSelectionLabel"; "required": false; "isSignal": true; }; "selectionSummaryLabel": { "alias": "selectionSummaryLabel"; "required": false; "isSignal": true; }; "tableAriaLabel": { "alias": "tableAriaLabel"; "required": false; "isSignal": true; }; "selectAllAriaLabel": { "alias": "selectAllAriaLabel"; "required": false; "isSignal": true; }; "selectRowAriaLabel": { "alias": "selectRowAriaLabel"; "required": false; "isSignal": true; }; "expandRowAriaLabel": { "alias": "expandRowAriaLabel"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "filterAriaPrefix": { "alias": "filterAriaPrefix"; "required": false; "isSignal": true; }; "allFilterOptionLabel": { "alias": "allFilterOptionLabel"; "required": false; "isSignal": true; }; "ofLabel": { "alias": "ofLabel"; "required": false; "isSignal": true; }; "resultLabelSingular": { "alias": "resultLabelSingular"; "required": false; "isSignal": true; }; "resultLabelPlural": { "alias": "resultLabelPlural"; "required": false; "isSignal": true; }; "sortable": { "alias": "sortable"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "expandable": { "alias": "expandable"; "required": false; "isSignal": true; }; "exportable": { "alias": "exportable"; "required": false; "isSignal": true; }; "exportFileName": { "alias": "exportFileName"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "stickyHeader": { "alias": "stickyHeader"; "required": false; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "showRowNumbers": { "alias": "showRowNumbers"; "required": false; "isSignal": true; }; "rowClass": { "alias": "rowClass"; "required": false; "isSignal": true; }; "footerRow": { "alias": "footerRow"; "required": false; "isSignal": true; }; "emptyStateTemplate": { "alias": "emptyStateTemplate"; "required": false; "isSignal": true; }; "serverSide": { "alias": "serverSide"; "required": false; "isSignal": true; }; "totalItems": { "alias": "totalItems"; "required": false; "isSignal": true; }; "multiSort": { "alias": "multiSort"; "required": false; "isSignal": true; }; "exportFormats": { "alias": "exportFormats"; "required": false; "isSignal": true; }; "exportColumns": { "alias": "exportColumns"; "required": false; "isSignal": true; }; "pageParam": { "alias": "pageParam"; "required": false; "isSignal": true; }; "searchParam": { "alias": "searchParam"; "required": false; "isSignal": true; }; "sortParam": { "alias": "sortParam"; "required": false; "isSignal": true; }; "sortDirParam": { "alias": "sortDirParam"; "required": false; "isSignal": true; }; "multiSortParam": { "alias": "multiSortParam"; "required": false; "isSignal": true; }; "useUrlState": { "alias": "useUrlState"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "rowClick": "rowClick"; "rowDblClick": "rowDblClick"; "actionClick": "actionClick"; "serverStateChange": "serverStateChange"; "searchChange": "searchChange"; }, ["expandTemplate"], never, true, never>;
301
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuTableComponent, "neu-table", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pagination": { "alias": "pagination"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "skeletonRows": { "alias": "skeletonRows"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "exactMatchable": { "alias": "exactMatchable"; "required": false; "isSignal": true; }; "exactMatchLabel": { "alias": "exactMatchLabel"; "required": false; "isSignal": true; }; "searchAriaLabel": { "alias": "searchAriaLabel"; "required": false; "isSignal": true; }; "clearSearchAriaLabel": { "alias": "clearSearchAriaLabel"; "required": false; "isSignal": true; }; "clearFilterLabel": { "alias": "clearFilterLabel"; "required": false; "isSignal": true; }; "previousPageAriaLabel": { "alias": "previousPageAriaLabel"; "required": false; "isSignal": true; }; "nextPageAriaLabel": { "alias": "nextPageAriaLabel"; "required": false; "isSignal": true; }; "pageSizeLabel": { "alias": "pageSizeLabel"; "required": false; "isSignal": true; }; "pageSizeAriaLabel": { "alias": "pageSizeAriaLabel"; "required": false; "isSignal": true; }; "paginationAriaLabel": { "alias": "paginationAriaLabel"; "required": false; "isSignal": true; }; "exportCsvTitle": { "alias": "exportCsvTitle"; "required": false; "isSignal": true; }; "exportJsonTitle": { "alias": "exportJsonTitle"; "required": false; "isSignal": true; }; "clearSelectionLabel": { "alias": "clearSelectionLabel"; "required": false; "isSignal": true; }; "selectionSummaryLabel": { "alias": "selectionSummaryLabel"; "required": false; "isSignal": true; }; "tableAriaLabel": { "alias": "tableAriaLabel"; "required": false; "isSignal": true; }; "selectAllAriaLabel": { "alias": "selectAllAriaLabel"; "required": false; "isSignal": true; }; "selectRowAriaLabel": { "alias": "selectRowAriaLabel"; "required": false; "isSignal": true; }; "expandRowAriaLabel": { "alias": "expandRowAriaLabel"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "filterAriaPrefix": { "alias": "filterAriaPrefix"; "required": false; "isSignal": true; }; "allFilterOptionLabel": { "alias": "allFilterOptionLabel"; "required": false; "isSignal": true; }; "ofLabel": { "alias": "ofLabel"; "required": false; "isSignal": true; }; "resultLabelSingular": { "alias": "resultLabelSingular"; "required": false; "isSignal": true; }; "resultLabelPlural": { "alias": "resultLabelPlural"; "required": false; "isSignal": true; }; "sortable": { "alias": "sortable"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "expandable": { "alias": "expandable"; "required": false; "isSignal": true; }; "exportable": { "alias": "exportable"; "required": false; "isSignal": true; }; "exportFileName": { "alias": "exportFileName"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "stickyHeader": { "alias": "stickyHeader"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "virtualScrollVisibleItems": { "alias": "virtualScrollVisibleItems"; "required": false; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "roundedBorders": { "alias": "roundedBorders"; "required": false; "isSignal": true; }; "stripedRows": { "alias": "stripedRows"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "showRowNumbers": { "alias": "showRowNumbers"; "required": false; "isSignal": true; }; "rowClass": { "alias": "rowClass"; "required": false; "isSignal": true; }; "footerRow": { "alias": "footerRow"; "required": false; "isSignal": true; }; "emptyStateTemplate": { "alias": "emptyStateTemplate"; "required": false; "isSignal": true; }; "serverSide": { "alias": "serverSide"; "required": false; "isSignal": true; }; "totalItems": { "alias": "totalItems"; "required": false; "isSignal": true; }; "multiSort": { "alias": "multiSort"; "required": false; "isSignal": true; }; "exportFormats": { "alias": "exportFormats"; "required": false; "isSignal": true; }; "exportColumns": { "alias": "exportColumns"; "required": false; "isSignal": true; }; "pageParam": { "alias": "pageParam"; "required": false; "isSignal": true; }; "searchParam": { "alias": "searchParam"; "required": false; "isSignal": true; }; "sortParam": { "alias": "sortParam"; "required": false; "isSignal": true; }; "sortDirParam": { "alias": "sortDirParam"; "required": false; "isSignal": true; }; "multiSortParam": { "alias": "multiSortParam"; "required": false; "isSignal": true; }; "useUrlState": { "alias": "useUrlState"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "rowClick": "rowClick"; "rowDblClick": "rowDblClick"; "actionClick": "actionClick"; "serverStateChange": "serverStateChange"; "searchChange": "searchChange"; }, ["expandTemplate"], never, true, never>;
282
302
  }
283
303
 
284
304
  export { NeuTableComponent, NeuTableExpandDirective };
@@ -33,6 +33,7 @@ declare class NeuTabsComponent implements AfterViewInit, OnDestroy {
33
33
  private _dragStartX;
34
34
  private _dragStartScrollLeft;
35
35
  private _suppressNextClick;
36
+ private readonly _optimisticActiveTabId;
36
37
  readonly isDraggingNav: _angular_core.WritableSignal<boolean>;
37
38
  private _getUrlParamSignal;
38
39
  private _readUrlParam;
@@ -17,6 +17,11 @@ import { Params, Router } from '@angular/router';
17
17
  declare class NeuUrlStateService {
18
18
  private readonly injector;
19
19
  private readonly router;
20
+ private _pendingParams;
21
+ private _pendingReplaceUrl;
22
+ private _batchScheduled;
23
+ private readonly _pendingParamsState;
24
+ private readonly _routerParams;
20
25
  /**
21
26
  * Signal con el mapa completo de queryParams actual.
22
27
  * Se actualiza automáticamente en cada NavigationEnd.
@@ -40,6 +45,10 @@ declare class NeuUrlStateService {
40
45
  * Pasar false para acciones que el usuario debe poder deshacer con Atrás.
41
46
  */
42
47
  setParam(key: string, value: string | null, replaceUrl?: boolean): void;
48
+ private _schedulePendingNavigation;
49
+ private _consumePendingNavigation;
50
+ private _resetPendingNavigation;
51
+ private _finalizePendingNavigation;
43
52
  /**
44
53
  * Actualiza múltiples queryParams en una sola navegación.
45
54
  *
@@ -1,6 +1,22 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { AfterViewInit, TemplateRef } from '@angular/core';
3
3
 
4
+ declare class NeuVirtualListRowComponent {
5
+ readonly item: _angular_core.InputSignal<unknown>;
6
+ readonly index: _angular_core.InputSignal<number>;
7
+ readonly itemSize: _angular_core.InputSignal<number>;
8
+ readonly label: _angular_core.InputSignal<string>;
9
+ readonly template: _angular_core.InputSignal<TemplateRef<{
10
+ $implicit: unknown;
11
+ index: number;
12
+ }> | null>;
13
+ readonly context: _angular_core.Signal<{
14
+ $implicit: unknown;
15
+ index: number;
16
+ }>;
17
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuVirtualListRowComponent, never>;
18
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuVirtualListRowComponent, "neu-virtual-list-row", never, { "item": { "alias": "item"; "required": true; "isSignal": true; }; "index": { "alias": "index"; "required": true; "isSignal": true; }; "itemSize": { "alias": "itemSize"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "template": { "alias": "template"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
19
+ }
4
20
  /**
5
21
  * NeuralUI VirtualList
6
22
  *
@@ -57,4 +73,4 @@ declare class NeuVirtualListComponent<T = unknown> implements AfterViewInit {
57
73
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuVirtualListComponent<any>, "neu-virtual-list", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "itemSize": { "alias": "itemSize"; "required": false; "isSignal": true; }; "visibleRows": { "alias": "visibleRows"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "trackBy": { "alias": "trackBy"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, ["itemTemplate"], never, true, never>;
58
74
  }
59
75
 
60
- export { NeuVirtualListComponent };
76
+ export { NeuVirtualListComponent, NeuVirtualListRowComponent };