valtech-components 2.0.510 → 2.0.511

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 (42) hide show
  1. package/esm2022/lib/components/molecules/refresher/refresher.component.mjs +254 -0
  2. package/esm2022/lib/components/molecules/refresher/types.mjs +15 -0
  3. package/esm2022/lib/components/organisms/infinite-list/infinite-list.component.mjs +618 -0
  4. package/esm2022/lib/components/organisms/infinite-list/types.mjs +15 -0
  5. package/esm2022/lib/components/templates/page-template/page-template.component.mjs +3 -3
  6. package/esm2022/lib/services/pagination/index.mjs +5 -0
  7. package/esm2022/lib/services/pagination/pagination.service.mjs +218 -0
  8. package/esm2022/lib/services/pagination/types.mjs +14 -0
  9. package/esm2022/lib/services/skeleton/config.mjs +79 -0
  10. package/esm2022/lib/services/skeleton/directives/loading.directive.mjs +215 -0
  11. package/esm2022/lib/services/skeleton/index.mjs +16 -0
  12. package/esm2022/lib/services/skeleton/skeleton.service.mjs +198 -0
  13. package/esm2022/lib/services/skeleton/templates/detail-skeleton.component.mjs +223 -0
  14. package/esm2022/lib/services/skeleton/templates/form-skeleton.component.mjs +127 -0
  15. package/esm2022/lib/services/skeleton/templates/grid-skeleton.component.mjs +154 -0
  16. package/esm2022/lib/services/skeleton/templates/list-skeleton.component.mjs +110 -0
  17. package/esm2022/lib/services/skeleton/templates/profile-skeleton.component.mjs +207 -0
  18. package/esm2022/lib/services/skeleton/templates/table-skeleton.component.mjs +116 -0
  19. package/esm2022/lib/services/skeleton/types.mjs +11 -0
  20. package/esm2022/public-api.mjs +12 -1
  21. package/fesm2022/valtech-components.mjs +3467 -950
  22. package/fesm2022/valtech-components.mjs.map +1 -1
  23. package/lib/components/molecules/refresher/refresher.component.d.ts +79 -0
  24. package/lib/components/molecules/refresher/types.d.ts +86 -0
  25. package/lib/components/organisms/infinite-list/infinite-list.component.d.ts +111 -0
  26. package/lib/components/organisms/infinite-list/types.d.ts +197 -0
  27. package/lib/services/pagination/index.d.ts +2 -0
  28. package/lib/services/pagination/pagination.service.d.ts +43 -0
  29. package/lib/services/pagination/types.d.ts +113 -0
  30. package/lib/services/skeleton/config.d.ts +30 -0
  31. package/lib/services/skeleton/directives/loading.directive.d.ts +71 -0
  32. package/lib/services/skeleton/index.d.ts +10 -0
  33. package/lib/services/skeleton/skeleton.service.d.ts +127 -0
  34. package/lib/services/skeleton/templates/detail-skeleton.component.d.ts +18 -0
  35. package/lib/services/skeleton/templates/form-skeleton.component.d.ts +22 -0
  36. package/lib/services/skeleton/templates/grid-skeleton.component.d.ts +18 -0
  37. package/lib/services/skeleton/templates/list-skeleton.component.d.ts +17 -0
  38. package/lib/services/skeleton/templates/profile-skeleton.component.d.ts +20 -0
  39. package/lib/services/skeleton/templates/table-skeleton.component.d.ts +17 -0
  40. package/lib/services/skeleton/types.d.ts +111 -0
  41. package/package.json +1 -1
  42. package/public-api.d.ts +6 -0
@@ -0,0 +1,79 @@
1
+ import { EventEmitter, TemplateRef } from '@angular/core';
2
+ import { IonRefresher } from '@ionic/angular/standalone';
3
+ import { RefresherMetadata, RefresherState, RefreshEvent, RefreshPullEvent } from './types';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Componente de pull-to-refresh para movil y web.
7
+ *
8
+ * @example
9
+ * <!-- Uso basico -->
10
+ * <val-refresher
11
+ * [props]="{
12
+ * color: 'primary',
13
+ * pullingText: 'Arrastra para actualizar',
14
+ * refreshingText: 'Cargando...'
15
+ * }"
16
+ * (refresh)="onRefresh($event)"
17
+ * >
18
+ * <ion-content>
19
+ * <!-- Contenido scrolleable -->
20
+ * </ion-content>
21
+ * </val-refresher>
22
+ *
23
+ * @example
24
+ * <!-- Con indicador personalizado -->
25
+ * <val-refresher [props]="{ color: 'primary' }" (refresh)="onRefresh($event)">
26
+ * <ng-template #pullingIndicator let-progress="progress">
27
+ * <div class="custom-indicator">
28
+ * <ion-icon name="arrow-down" [style.transform]="'rotate(' + progress * 180 + 'deg)'"></ion-icon>
29
+ * </div>
30
+ * </ng-template>
31
+ * <ion-content>...</ion-content>
32
+ * </val-refresher>
33
+ */
34
+ export declare class RefresherComponent {
35
+ ionRefresher: IonRefresher;
36
+ /** Templates personalizados via content projection */
37
+ pullingIndicator?: TemplateRef<{
38
+ progress: number;
39
+ }>;
40
+ refreshingIndicator?: TemplateRef<void>;
41
+ completingIndicator?: TemplateRef<void>;
42
+ /** Configuracion del refresher */
43
+ props: RefresherMetadata;
44
+ /** Evento emitido cuando se activa el refresh */
45
+ refresh: EventEmitter<RefreshEvent>;
46
+ /** Evento de progreso durante el pull */
47
+ pullProgressChange: EventEmitter<RefreshPullEvent>;
48
+ /** Evento de cambio de estado */
49
+ stateChange: EventEmitter<RefresherState>;
50
+ /** Estado actual del refresher */
51
+ readonly state: import("@angular/core").WritableSignal<RefresherState>;
52
+ /** Progreso actual del pull (0-1) */
53
+ readonly pullProgress: import("@angular/core").WritableSignal<number>;
54
+ /** Props combinados con defaults */
55
+ get mergedProps(): RefresherMetadata;
56
+ /** Si hay indicadores personalizados */
57
+ get hasCustomIndicator(): boolean;
58
+ /**
59
+ * Activa programaticamente el refresh.
60
+ */
61
+ triggerRefresh(): void;
62
+ /**
63
+ * Completa la operacion de refresh actual.
64
+ */
65
+ complete(): void;
66
+ /**
67
+ * Cancela la operacion de refresh actual.
68
+ */
69
+ cancel(): void;
70
+ /** Handler para evento ionRefresh */
71
+ onIonRefresh(event: CustomEvent): void;
72
+ /** Handler para evento ionPull */
73
+ onIonPull(event: CustomEvent): void;
74
+ /** Handler para evento ionStart */
75
+ onIonStart(): void;
76
+ private emitRefreshEvent;
77
+ static ɵfac: i0.ɵɵFactoryDeclaration<RefresherComponent, never>;
78
+ static ɵcmp: i0.ɵɵComponentDeclaration<RefresherComponent, "val-refresher", never, { "props": { "alias": "props"; "required": false; }; }, { "refresh": "refresh"; "pullProgressChange": "pullProgressChange"; "stateChange": "stateChange"; }, ["pullingIndicator", "refreshingIndicator", "completingIndicator"], ["*"], true, never>;
79
+ }
@@ -0,0 +1,86 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import { Color } from '@ionic/core';
3
+ /**
4
+ * Estado del componente refresher.
5
+ */
6
+ export type RefresherState = 'idle' | 'pulling' | 'refreshing' | 'completing';
7
+ /**
8
+ * Tipos de spinner disponibles.
9
+ */
10
+ export type RefresherSpinnerType = 'circular' | 'crescent' | 'dots' | 'lines-sharp';
11
+ /**
12
+ * Evento emitido cuando se activa el refresh.
13
+ */
14
+ export interface RefreshEvent {
15
+ /** Llamar cuando la operacion de refresh completa */
16
+ complete: () => void;
17
+ /** Llamar para cancelar el refresh */
18
+ cancel: () => void;
19
+ /** Timestamp cuando inicio el refresh */
20
+ timestamp: Date;
21
+ }
22
+ /**
23
+ * Evento de progreso durante el gesto de pull.
24
+ */
25
+ export interface RefreshPullEvent {
26
+ /** Valor de progreso entre 0 y 1 */
27
+ progress: number;
28
+ /** Si se ha alcanzado el umbral de pull */
29
+ thresholdReached: boolean;
30
+ }
31
+ /**
32
+ * Configuracion de indicador personalizado.
33
+ */
34
+ export interface RefresherIndicatorConfig {
35
+ /** Template personalizado para estado pulling */
36
+ pullingTemplate?: TemplateRef<{
37
+ progress: number;
38
+ }>;
39
+ /** Template personalizado para estado refreshing */
40
+ refreshingTemplate?: TemplateRef<void>;
41
+ /** Template personalizado para estado completing */
42
+ completingTemplate?: TemplateRef<void>;
43
+ }
44
+ /**
45
+ * Metadata para el componente val-refresher.
46
+ */
47
+ export interface RefresherMetadata {
48
+ /** Si el refresher esta deshabilitado */
49
+ disabled?: boolean;
50
+ /** Umbral de pull en pixels (default: 70) */
51
+ pullThreshold?: number;
52
+ /** Distancia maxima de pull en pixels (default: 200) */
53
+ pullMax?: number;
54
+ /** Factor de resistencia del pull (0-1, default: 0.5) */
55
+ pullFactor?: number;
56
+ /** Duracion de snap back en ms (default: 280) */
57
+ snapbackDuration?: number;
58
+ /** Duracion de cierre en ms (default: 280) */
59
+ closeDuration?: number;
60
+ /** Color del spinner */
61
+ color?: Color;
62
+ /** Tipo de spinner */
63
+ spinnerType?: RefresherSpinnerType;
64
+ /** Texto mostrado mientras se arrastra */
65
+ pullingText?: string;
66
+ /** Texto mostrado mientras se actualiza */
67
+ refreshingText?: string;
68
+ /** Configuracion de indicador personalizado */
69
+ indicatorConfig?: RefresherIndicatorConfig;
70
+ /** Habilitar feedback haptico en movil (default: true) */
71
+ hapticFeedback?: boolean;
72
+ /** Modo web - habilita pull-to-refresh en navegadores desktop */
73
+ webMode?: boolean;
74
+ /** Identificador unico */
75
+ token?: string;
76
+ /** Key de traduccion para texto pulling */
77
+ pullingTextKey?: string;
78
+ /** Key de traduccion para texto refreshing */
79
+ refreshingTextKey?: string;
80
+ /** Clase CSS adicional */
81
+ contentClass?: string;
82
+ }
83
+ /**
84
+ * Valores por defecto para el refresher.
85
+ */
86
+ export declare const DEFAULT_REFRESHER_METADATA: Partial<RefresherMetadata>;
@@ -0,0 +1,111 @@
1
+ import { EventEmitter, OnInit, OnDestroy } from '@angular/core';
2
+ import { IonInfiniteScroll } from '@ionic/angular/standalone';
3
+ import { InfiniteListMetadata, InfiniteListState, LoadMoreEvent } from './types';
4
+ import { RefreshEvent, RefresherMetadata } from '../../molecules/refresher/types';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * Componente wrapper para listas con infinite scroll.
8
+ *
9
+ * @example
10
+ * <!-- Uso basico con data source -->
11
+ * <val-infinite-list
12
+ * [props]="{
13
+ * dataSource: { loadFn: loadUsers, trackBy: trackByUserId },
14
+ * itemTemplate: userTemplate,
15
+ * pageSize: 20,
16
+ * threshold: '150px'
17
+ * }"
18
+ * ></val-infinite-list>
19
+ *
20
+ * <ng-template #userTemplate let-user let-index="index">
21
+ * <val-card [props]="{ title: user.name, subtitle: user.email }">
22
+ * <p>{{ user.bio }}</p>
23
+ * </val-card>
24
+ * </ng-template>
25
+ *
26
+ * @example
27
+ * <!-- Con pull-to-refresh y estado vacio personalizado -->
28
+ * <val-infinite-list
29
+ * [props]="{
30
+ * dataSource: { loadFn: loadMessages },
31
+ * itemTemplate: messageTemplate,
32
+ * direction: 'both',
33
+ * enableRefresh: true,
34
+ * emptyState: {
35
+ * icon: 'chatbubbles-outline',
36
+ * title: 'Sin mensajes',
37
+ * message: 'Inicia una conversacion'
38
+ * },
39
+ * skeleton: { template: 'list', count: 5 }
40
+ * }"
41
+ * (refresh)="onRefresh($event)"
42
+ * ></val-infinite-list>
43
+ */
44
+ export declare class InfiniteListComponent<T = unknown> implements OnInit, OnDestroy {
45
+ private readonly skeletonService;
46
+ private readonly cdr;
47
+ infiniteScroll?: IonInfiniteScroll;
48
+ /** Configuracion del componente */
49
+ props: InfiniteListMetadata<T>;
50
+ loadMore: EventEmitter<LoadMoreEvent>;
51
+ refresh: EventEmitter<RefreshEvent>;
52
+ stateChange: EventEmitter<InfiniteListState>;
53
+ itemsChange: EventEmitter<T[]>;
54
+ errorOccurred: EventEmitter<Error>;
55
+ readonly items: import("@angular/core").WritableSignal<T[]>;
56
+ readonly state: import("@angular/core").WritableSignal<InfiniteListState>;
57
+ readonly hasMoreBottom: import("@angular/core").WritableSignal<boolean>;
58
+ readonly hasMoreTop: import("@angular/core").WritableSignal<boolean>;
59
+ readonly error: import("@angular/core").WritableSignal<Error>;
60
+ readonly isInitialLoad: import("@angular/core").WritableSignal<boolean>;
61
+ private currentPage;
62
+ private currentCursor;
63
+ /** Progreso de carga (0-1 si totalCount conocido) */
64
+ readonly loadProgress: import("@angular/core").Signal<number>;
65
+ /** Props combinados con defaults */
66
+ get mergedProps(): InfiniteListMetadata<T>;
67
+ /** Config del refresher */
68
+ get refresherConfig(): RefresherMetadata;
69
+ /** Componente de skeleton a usar */
70
+ get skeletonComponent(): import("@angular/core").Type<unknown>;
71
+ /** Inputs para el skeleton */
72
+ get skeletonInputs(): {
73
+ config: unknown;
74
+ };
75
+ /** Anuncio de estado para lectores de pantalla */
76
+ readonly statusAnnouncement: import("@angular/core").Signal<string>;
77
+ ngOnInit(): void;
78
+ ngOnDestroy(): void;
79
+ /** Funcion de tracking para ngFor */
80
+ trackByFn(index: number, item: T): unknown;
81
+ /** Si debe mostrar el scroll inferior */
82
+ shouldShowBottomScroll(): boolean;
83
+ /** Carga inicial de datos */
84
+ loadInitial(): Promise<void>;
85
+ /** Cargar mas items en la parte inferior */
86
+ loadBottom(): Promise<void>;
87
+ /** Cargar mas items en la parte superior */
88
+ loadTop(): Promise<void>;
89
+ /** Refresh - recargar desde cero */
90
+ refreshList(): Promise<void>;
91
+ /** Reintentar despues de error */
92
+ retry(): Promise<void>;
93
+ /** Reset completo */
94
+ reset(): Promise<void>;
95
+ /** Agregar items al inicio */
96
+ prependItems(newItems: T[]): void;
97
+ /** Agregar items al final */
98
+ appendItems(newItems: T[]): void;
99
+ /** Actualizar un item por indice */
100
+ updateItem(index: number, item: T): void;
101
+ /** Remover un item por indice */
102
+ removeItem(index: number): void;
103
+ /** Handler para evento de infinite scroll */
104
+ onInfiniteScroll(event: CustomEvent): Promise<void>;
105
+ /** Handler para evento de refresh */
106
+ onRefreshTriggered(event: RefreshEvent): Promise<void>;
107
+ private executeLoad;
108
+ private handleError;
109
+ static ɵfac: i0.ɵɵFactoryDeclaration<InfiniteListComponent<any>, never>;
110
+ static ɵcmp: i0.ɵɵComponentDeclaration<InfiniteListComponent<any>, "val-infinite-list", never, { "props": { "alias": "props"; "required": false; }; }, { "loadMore": "loadMore"; "refresh": "refresh"; "stateChange": "stateChange"; "itemsChange": "itemsChange"; "errorOccurred": "errorOccurred"; }, never, never, true, never>;
111
+ }
@@ -0,0 +1,197 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import { Color } from '@ionic/core';
3
+ import { Observable } from 'rxjs';
4
+ import { SkeletonTemplateName, SkeletonTemplateConfig } from '../../../services/skeleton/types';
5
+ import { RefresherMetadata } from '../../molecules/refresher/types';
6
+ /**
7
+ * Direccion de carga de mas items.
8
+ */
9
+ export type LoadDirection = 'bottom' | 'top' | 'both';
10
+ /**
11
+ * Estado de la lista infinita.
12
+ */
13
+ export type InfiniteListState = 'idle' | 'loading' | 'error' | 'complete';
14
+ /**
15
+ * Parametros pasados a la funcion de carga.
16
+ */
17
+ export interface LoadParams {
18
+ /** Direccion de carga */
19
+ direction: 'bottom' | 'top';
20
+ /** Pagina actual (para paginacion basada en offset) */
21
+ page: number;
22
+ /** Items por pagina */
23
+ pageSize: number;
24
+ /** Ultimo item (para paginacion basada en cursor) */
25
+ lastItem?: unknown;
26
+ /** Primer item (para carga top con cursor) */
27
+ firstItem?: unknown;
28
+ /** Cursor personalizado (del LoadResult anterior) */
29
+ cursor?: unknown;
30
+ }
31
+ /**
32
+ * Resultado de la funcion de carga.
33
+ */
34
+ export interface LoadResult<T> {
35
+ /** Items cargados */
36
+ items: T[];
37
+ /** Si hay mas items disponibles */
38
+ hasMore: boolean;
39
+ /** Cursor personalizado para proxima carga (opcional) */
40
+ cursor?: unknown;
41
+ /** Actualizacion de conteo total (opcional) */
42
+ totalCount?: number;
43
+ }
44
+ /**
45
+ * Configuracion del data source.
46
+ */
47
+ export interface InfiniteListDataSource<T> {
48
+ /** Items iniciales (opcional si usa loadFn) */
49
+ items?: T[];
50
+ /** Funcion para cargar mas items */
51
+ loadFn?: (params: LoadParams) => Observable<LoadResult<T>> | Promise<LoadResult<T>>;
52
+ /** Funcion track para ngFor (default: index) */
53
+ trackBy?: (index: number, item: T) => unknown;
54
+ /** Conteo total si se conoce (habilita indicador de progreso) */
55
+ totalCount?: number;
56
+ }
57
+ /**
58
+ * Evento emitido al cargar mas items.
59
+ */
60
+ export interface LoadMoreEvent {
61
+ /** Parametros de carga */
62
+ params: LoadParams;
63
+ /** Llamar cuando la carga completa */
64
+ complete: (result: LoadResult<unknown>) => void;
65
+ /** Llamar cuando la carga falla */
66
+ error: (error: Error) => void;
67
+ }
68
+ /**
69
+ * Configuracion de estado vacio.
70
+ */
71
+ export interface InfiniteListEmptyState {
72
+ /** Nombre del icono */
73
+ icon?: string;
74
+ /** Texto del titulo */
75
+ title?: string;
76
+ /** Texto del mensaje */
77
+ message?: string;
78
+ /** Template personalizado */
79
+ template?: TemplateRef<void>;
80
+ titleKey?: string;
81
+ messageKey?: string;
82
+ contentClass?: string;
83
+ }
84
+ /**
85
+ * Configuracion de estado de error.
86
+ */
87
+ export interface InfiniteListErrorState {
88
+ /** Icono de error */
89
+ icon?: string;
90
+ /** Titulo del error */
91
+ title?: string;
92
+ /** Mensaje del error */
93
+ message?: string;
94
+ /** Mostrar boton de reintentar */
95
+ showRetry?: boolean;
96
+ /** Texto del boton de reintentar */
97
+ retryText?: string;
98
+ /** Template personalizado */
99
+ template?: TemplateRef<{
100
+ error: Error;
101
+ retry: () => void;
102
+ }>;
103
+ titleKey?: string;
104
+ messageKey?: string;
105
+ retryTextKey?: string;
106
+ contentClass?: string;
107
+ }
108
+ /**
109
+ * Configuracion de skeleton para carga.
110
+ */
111
+ export interface InfiniteListSkeletonConfig {
112
+ /** Template de skeleton a usar */
113
+ template?: SkeletonTemplateName | string;
114
+ /** Numero de items skeleton a mostrar */
115
+ count?: number;
116
+ /** Template personalizado */
117
+ customTemplate?: TemplateRef<void>;
118
+ /** Configuracion adicional */
119
+ config?: SkeletonTemplateConfig;
120
+ }
121
+ /**
122
+ * Contexto para el template de items.
123
+ */
124
+ export interface InfiniteListItemContext<T> {
125
+ /** El item actual */
126
+ $implicit: T;
127
+ /** Indice del item */
128
+ index: number;
129
+ /** Si es el primer item */
130
+ first: boolean;
131
+ /** Si es el ultimo item */
132
+ last: boolean;
133
+ /** Items totales */
134
+ count: number;
135
+ }
136
+ /**
137
+ * Metadata para el componente val-infinite-list.
138
+ */
139
+ export interface InfiniteListMetadata<T = unknown> {
140
+ /** Configuracion del data source */
141
+ dataSource: InfiniteListDataSource<T>;
142
+ /** Direccion de carga */
143
+ direction?: LoadDirection;
144
+ /** Items por pagina (default: 20) */
145
+ pageSize?: number;
146
+ /** Distancia del borde para activar carga (default: '100px') */
147
+ threshold?: string;
148
+ /** Tiempo de debounce para eventos de carga en ms (default: 300) */
149
+ debounceTime?: number;
150
+ /** Cargar primera pagina automaticamente al inicializar (default: true) */
151
+ autoLoad?: boolean;
152
+ /** Template para renderizar cada item (requerido) */
153
+ itemTemplate: TemplateRef<InfiniteListItemContext<T>>;
154
+ /** Template para el indicador de carga en bottom */
155
+ loadingTemplate?: TemplateRef<void>;
156
+ /** Template para el indicador de carga en top */
157
+ topLoadingTemplate?: TemplateRef<void>;
158
+ /** Configuracion de estado vacio */
159
+ emptyState?: InfiniteListEmptyState;
160
+ /** Configuracion de estado de error */
161
+ errorState?: InfiniteListErrorState;
162
+ /** Configuracion de skeleton para carga inicial */
163
+ skeleton?: InfiniteListSkeletonConfig;
164
+ /** Tipo de spinner */
165
+ spinnerType?: 'circular' | 'crescent' | 'dots' | 'lines-sharp';
166
+ /** Color del spinner */
167
+ color?: Color;
168
+ /** Usar boton "Cargar mas" en lugar de auto-carga */
169
+ useLoadMoreButton?: boolean;
170
+ /** Texto del boton "Cargar mas" */
171
+ loadMoreText?: string;
172
+ /** Texto cuando no hay mas items */
173
+ noMoreText?: string;
174
+ /** Habilitar pull-to-refresh */
175
+ enableRefresh?: boolean;
176
+ /** Configuracion del refresher */
177
+ refreshConfig?: RefresherMetadata;
178
+ /** Clase CSS para el contenedor */
179
+ cssClass?: string;
180
+ /** Altura maxima (habilita scroll interno) */
181
+ maxHeight?: string;
182
+ /** Mostrar divisores entre items */
183
+ showDividers?: boolean;
184
+ /** ARIA label para la lista */
185
+ ariaLabel?: string;
186
+ /** ARIA description */
187
+ ariaDescription?: string;
188
+ /** Identificador unico */
189
+ token?: string;
190
+ loadMoreTextKey?: string;
191
+ noMoreTextKey?: string;
192
+ contentClass?: string;
193
+ }
194
+ /**
195
+ * Valores por defecto para infinite list.
196
+ */
197
+ export declare const DEFAULT_INFINITE_LIST_METADATA: Partial<InfiniteListMetadata>;
@@ -0,0 +1,2 @@
1
+ export { PaginationStrategy, PaginationState, PaginationLoadParams, PaginationLoadResult, PaginationConfig, PaginationController, createInitialPaginationState, } from './types';
2
+ export { PaginationService } from './pagination.service';
@@ -0,0 +1,43 @@
1
+ import { PaginationConfig, PaginationController } from './types';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Servicio para crear controladores de paginacion reutilizables.
5
+ *
6
+ * @example
7
+ * // En un componente
8
+ * pagination = inject(PaginationService);
9
+ *
10
+ * usersController = this.pagination.createController<User>({
11
+ * strategy: 'offset',
12
+ * pageSize: 20,
13
+ * loadFn: (params) => this.userService.getUsers(params.page, params.pageSize)
14
+ * });
15
+ *
16
+ * // En el template
17
+ * @for (user of usersController.items(); track user.id) {
18
+ * <app-user-card [user]="user"></app-user-card>
19
+ * }
20
+ *
21
+ * @if (usersController.hasMore()) {
22
+ * <ion-button (click)="usersController.loadNext()">Cargar mas</ion-button>
23
+ * }
24
+ */
25
+ export declare class PaginationService {
26
+ /**
27
+ * Crea un controlador de paginacion para una fuente de datos.
28
+ *
29
+ * @param config Configuracion del controlador
30
+ * @returns Controlador de paginacion
31
+ */
32
+ createController<T>(config: PaginationConfig<T>): PaginationController<T>;
33
+ /**
34
+ * Crea un controlador simple para arrays estaticos con paginacion local.
35
+ *
36
+ * @param items Array completo de items
37
+ * @param pageSize Tamano de pagina
38
+ * @returns Controlador de paginacion
39
+ */
40
+ createLocalController<T>(items: T[], pageSize?: number): PaginationController<T>;
41
+ static ɵfac: i0.ɵɵFactoryDeclaration<PaginationService, never>;
42
+ static ɵprov: i0.ɵɵInjectableDeclaration<PaginationService>;
43
+ }
@@ -0,0 +1,113 @@
1
+ import { Signal } from '@angular/core';
2
+ import { Observable } from 'rxjs';
3
+ /**
4
+ * Estrategia de paginacion.
5
+ */
6
+ export type PaginationStrategy = 'offset' | 'cursor' | 'page';
7
+ /**
8
+ * Estado de paginacion.
9
+ */
10
+ export interface PaginationState<T> {
11
+ /** Items actuales */
12
+ items: T[];
13
+ /** Pagina actual (para estrategia offset/page) */
14
+ page: number;
15
+ /** Tamano de pagina */
16
+ pageSize: number;
17
+ /** Conteo total (si se conoce) */
18
+ total?: number;
19
+ /** Cursor para siguiente pagina (para estrategia cursor) */
20
+ nextCursor?: unknown;
21
+ /** Cursor para pagina anterior */
22
+ prevCursor?: unknown;
23
+ /** Si existen mas items */
24
+ hasMore: boolean;
25
+ /** Estado de carga */
26
+ isLoading: boolean;
27
+ /** Estado de error */
28
+ error?: Error;
29
+ }
30
+ /**
31
+ * Parametros para funcion de carga.
32
+ */
33
+ export interface PaginationLoadParams {
34
+ /** Estrategia de paginacion */
35
+ strategy: PaginationStrategy;
36
+ /** Numero de pagina */
37
+ page: number;
38
+ /** Tamano de pagina */
39
+ pageSize: number;
40
+ /** Cursor (para estrategia cursor) */
41
+ cursor?: unknown;
42
+ /** Direccion de carga */
43
+ direction: 'forward' | 'backward';
44
+ }
45
+ /**
46
+ * Resultado de funcion de carga.
47
+ */
48
+ export interface PaginationLoadResult<T> {
49
+ /** Items cargados */
50
+ items: T[];
51
+ /** Si hay mas items */
52
+ hasMore: boolean;
53
+ /** Total de items (opcional) */
54
+ total?: number;
55
+ /** Cursor para siguiente pagina */
56
+ nextCursor?: unknown;
57
+ /** Cursor para pagina anterior */
58
+ prevCursor?: unknown;
59
+ }
60
+ /**
61
+ * Configuracion para crear un controlador de paginacion.
62
+ */
63
+ export interface PaginationConfig<T> {
64
+ /** Estrategia de paginacion */
65
+ strategy: PaginationStrategy;
66
+ /** Tamano de pagina */
67
+ pageSize?: number;
68
+ /** Items iniciales (opcional) */
69
+ initialItems?: T[];
70
+ /** Funcion de carga */
71
+ loadFn: (params: PaginationLoadParams) => Observable<PaginationLoadResult<T>> | Promise<PaginationLoadResult<T>>;
72
+ /** Funcion de tracking para items */
73
+ trackBy?: (item: T) => unknown;
74
+ }
75
+ /**
76
+ * Interface del controlador de paginacion.
77
+ */
78
+ export interface PaginationController<T> {
79
+ /** Estado reactivo como signal */
80
+ state: Signal<PaginationState<T>>;
81
+ /** Signal de items (accessor de conveniencia) */
82
+ items: Signal<T[]>;
83
+ /** Signal de carga */
84
+ isLoading: Signal<boolean>;
85
+ /** Signal de mas items */
86
+ hasMore: Signal<boolean>;
87
+ /** Signal de error */
88
+ error: Signal<Error | null>;
89
+ /** Signal de pagina actual */
90
+ currentPage: Signal<number>;
91
+ /** Signal de total */
92
+ total: Signal<number | undefined>;
93
+ /** Cargar siguiente pagina */
94
+ loadNext(): Promise<void>;
95
+ /** Cargar pagina anterior (si soportado) */
96
+ loadPrevious(): Promise<void>;
97
+ /** Refresh (recargar desde inicio) */
98
+ refresh(): Promise<void>;
99
+ /** Reset a estado inicial */
100
+ reset(): void;
101
+ /** Actualizar un item */
102
+ updateItem(predicate: (item: T) => boolean, updates: Partial<T>): void;
103
+ /** Remover un item */
104
+ removeItem(predicate: (item: T) => boolean): void;
105
+ /** Agregar items al inicio */
106
+ prependItems(items: T[]): void;
107
+ /** Agregar items al final */
108
+ appendItems(items: T[]): void;
109
+ }
110
+ /**
111
+ * Estado inicial para controladores de paginacion.
112
+ */
113
+ export declare function createInitialPaginationState<T>(pageSize: number, initialItems?: T[]): PaginationState<T>;
@@ -0,0 +1,30 @@
1
+ import { EnvironmentProviders } from '@angular/core';
2
+ import { SkeletonConfig } from './types';
3
+ /**
4
+ * Configura el sistema de skeletons para Valtech Components.
5
+ *
6
+ * @param config Configuracion de skeletons
7
+ * @returns Providers para app.config.ts
8
+ *
9
+ * @example
10
+ * // app.config.ts
11
+ * import { provideValtechSkeleton } from 'valtech-components';
12
+ *
13
+ * export const appConfig: ApplicationConfig = {
14
+ * providers: [
15
+ * provideValtechSkeleton({
16
+ * animated: true,
17
+ * defaultDelay: 100,
18
+ * defaultMinTime: 500,
19
+ * templates: [
20
+ * { name: 'custom-card', component: MyCustomCardSkeleton }
21
+ * ]
22
+ * }),
23
+ * ]
24
+ * };
25
+ *
26
+ * @example
27
+ * // Uso minimo - usa configuracion por defecto
28
+ * providers: [provideValtechSkeleton()]
29
+ */
30
+ export declare function provideValtechSkeleton(config?: SkeletonConfig): EnvironmentProviders;