valtech-components 2.0.848 → 2.0.850

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.
@@ -0,0 +1,43 @@
1
+ import { ButtonMetadata } from '../../types';
2
+ import { EmptyStateMetadata, EmptyStateVariant } from './types';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * `<val-empty-state>` — molecule declarativo para estados de "no hay datos /
6
+ * hubo error / sin red". Reemplaza el patrón ad-hoc (ion-icon + val-title +
7
+ * val-text + val-button) que cada página venía improvisando.
8
+ *
9
+ * Uso típico:
10
+ *
11
+ * ```html
12
+ * @if (loading()) {
13
+ * <val-skeleton-layout [props]="..." />
14
+ * } @else if (errorState(); as e) {
15
+ * <val-empty-state [props]="e" />
16
+ * } @else if (items().length === 0) {
17
+ * <val-empty-state [props]="emptyProps" />
18
+ * } @else {
19
+ * <!-- contenido normal -->
20
+ * }
21
+ * ```
22
+ *
23
+ * I18n: las cadenas vienen ya traducidas en las props (la lib es agnóstica de
24
+ * namespaces). Para wiring automático desde un error capturado, usar el
25
+ * helper `createErrorStateProps(err, ...)` (`valtech-components`).
26
+ */
27
+ export declare class EmptyStateComponent {
28
+ props: import("@angular/core").InputSignal<EmptyStateMetadata>;
29
+ /** Variante resuelta (default `'empty'`). */
30
+ protected variantClass: import("@angular/core").Signal<EmptyStateVariant>;
31
+ /** Icono final — custom si se pasó, default de la variante si no. */
32
+ protected iconName: import("@angular/core").Signal<string>;
33
+ /** Tamaño en px. Default 64. */
34
+ protected iconSize: import("@angular/core").Signal<number>;
35
+ /**
36
+ * Props del botón CTA. Construidas a partir de `props().action`. El estado
37
+ * `WORKING` se aplica cuando `action.loading === true` (spinner mientras
38
+ * el handler corre).
39
+ */
40
+ protected ctaProps: import("@angular/core").Signal<ButtonMetadata>;
41
+ static ɵfac: i0.ɵɵFactoryDeclaration<EmptyStateComponent, never>;
42
+ static ɵcmp: i0.ɵɵComponentDeclaration<EmptyStateComponent, "val-empty-state", never, { "props": { "alias": "props"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
43
+ }
@@ -0,0 +1,64 @@
1
+ import { EmptyStateMetadata } from './types';
2
+ /**
3
+ * Opciones del helper. Los strings son requeridos para mantener el
4
+ * componente i18n-agnóstico — la página los resuelve (con su namespace) y los
5
+ * pasa ya traducidos. El helper solo decide la VARIANTE y compone los props.
6
+ */
7
+ export interface CreateErrorStateOpts {
8
+ /**
9
+ * Título a mostrar. Convención: la página lo resuelve por escenario:
10
+ * - red caída → `t('offlineTitle')`
11
+ * - error backend → `t('errorTitle')`
12
+ *
13
+ * Si pasás un solo string, se usa en ambas variantes. Si pasás el objeto,
14
+ * el helper elige según `isNetwork` del error interpretado.
15
+ */
16
+ title: string | {
17
+ offline: string;
18
+ error: string;
19
+ };
20
+ /** Descripción a mostrar (típicamente el `message` del backend en español). */
21
+ description?: string | {
22
+ offline: string;
23
+ error: string;
24
+ };
25
+ /** Label del botón CTA (típicamente `t('retry')`). Si se omite, no se muestra botón. */
26
+ retryLabel?: string;
27
+ /** Handler invocado al click de retry. Requerido si `retryLabel` está. */
28
+ onRetry?: () => void | Promise<void>;
29
+ /** `true` mientras el retry está corriendo — el botón pasa a WORKING. */
30
+ retrying?: boolean;
31
+ }
32
+ /**
33
+ * Convierte un error capturado en `EmptyStateMetadata` listo para
34
+ * `<val-empty-state>`. Decide la variante (`offline` vs `error`) según
35
+ * `interpretError(err).isNetwork`.
36
+ *
37
+ * Uso típico en una page:
38
+ *
39
+ * ```ts
40
+ * readonly errorState = computed(() => {
41
+ * const err = this.loadError();
42
+ * if (!err) return null;
43
+ * return createErrorStateProps(err, {
44
+ * title: { offline: this.t('offlineTitle'), error: this.t('errorTitle') },
45
+ * description: { offline: this.t('offlineHint'), error: interpretError(err).message },
46
+ * retryLabel: this.t('retry'),
47
+ * onRetry: () => this.reload(),
48
+ * retrying: this.reloading(),
49
+ * });
50
+ * });
51
+ * ```
52
+ *
53
+ * En el template:
54
+ *
55
+ * ```html
56
+ * @if (errorState(); as e) {
57
+ * <val-empty-state [props]="e" />
58
+ * }
59
+ * ```
60
+ *
61
+ * Para escenarios SIN error (lista vacía), construir `EmptyStateMetadata`
62
+ * manualmente con `variant: 'empty'` — no es lo que este helper resuelve.
63
+ */
64
+ export declare function createErrorStateProps(err: unknown, opts: CreateErrorStateOpts): EmptyStateMetadata;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Variante semántica del empty/error state.
3
+ *
4
+ * - `empty` — la fuente devolvió cero resultados (lista vacía, sin notifs).
5
+ * Icono neutro, sin alarma.
6
+ * - `error` — la fuente falló por un error de la app/servidor (500, parse).
7
+ * Icono de alerta.
8
+ * - `offline` — la fuente falló por red caída / Firestore unreachable.
9
+ * Icono cloud-offline.
10
+ *
11
+ * Cada variante mapea a un icono default si `icon` no se especifica.
12
+ */
13
+ export type EmptyStateVariant = 'empty' | 'error' | 'offline';
14
+ /**
15
+ * Acción CTA opcional del state (típicamente "Reintentar" / "Recargar").
16
+ *
17
+ * Si se omite, el componente no renderiza botón. El `handler` ya viene
18
+ * traducido — el componente NO resuelve i18n internamente.
19
+ */
20
+ export interface EmptyStateAction {
21
+ label: string;
22
+ handler: () => void | Promise<void>;
23
+ /** Si `true`, el botón pasa a estado WORKING (spinner). Útil mientras re-fetcha. */
24
+ loading?: boolean;
25
+ }
26
+ /**
27
+ * Metadata para `<val-empty-state>` — molecule que renderiza un estado
28
+ * declarativo de "no hay datos / hubo error / sin red" con título, descripción
29
+ * opcional y CTA opcional. Reemplaza el patrón ad-hoc (ion-icon + val-title +
30
+ * val-text + val-button) que cada página venía improvisando.
31
+ *
32
+ * I18n: los strings (`title`, `description`, `action.label`) los resuelve la
33
+ * página antes de construir las props. Esto mantiene el componente agnóstico
34
+ * a namespaces y consistente con el resto de la lib (FormMetadata, etc.).
35
+ */
36
+ export interface EmptyStateMetadata {
37
+ /** Título principal. Requerido. */
38
+ title: string;
39
+ /** Descripción opcional (1-2 líneas) debajo del título. */
40
+ description?: string;
41
+ /** Variante semántica. Default `'empty'`. */
42
+ variant?: EmptyStateVariant;
43
+ /**
44
+ * Nombre del icono Ionicons (kebab-case). Si se omite, el componente usa
45
+ * el default de la variante:
46
+ * - empty → `document-outline`
47
+ * - error → `alert-circle-outline`
48
+ * - offline → `cloud-offline-outline`
49
+ *
50
+ * Si pasás un icono custom, importalo + registralo con `addIcons({ ... })`
51
+ * en el componente consumidor (Ionic standalone no auto-registra).
52
+ */
53
+ icon?: string;
54
+ /** Tamaño del icono en píxeles. Default `64`. */
55
+ iconSize?: number;
56
+ /** Acción CTA opcional. Si se omite, no se muestra botón. */
57
+ action?: EmptyStateAction;
58
+ }
@@ -69,6 +69,8 @@ export declare class MfaModalComponent implements OnDestroy {
69
69
  readonly totpQr: import("@angular/core").WritableSignal<QrResult>;
70
70
  /** Códigos de respaldo recién regenerados — se muestran una sola vez. */
71
71
  readonly regeneratedCodes: import("@angular/core").WritableSignal<string[]>;
72
+ /** Marca momentánea cuando el secreto TOTP se acaba de copiar (feedback visual). */
73
+ readonly copiedSecret: import("@angular/core").WritableSignal<boolean>;
72
74
  readonly resendCooldown: import("@angular/core").WritableSignal<number>;
73
75
  readonly pinControl: FormControl<string>;
74
76
  readonly phoneControl: FormControl<string>;
@@ -115,6 +117,8 @@ export declare class MfaModalComponent implements OnDestroy {
115
117
  onDisableSubmit(event: FormSubmit): void;
116
118
  /** Copia una lista de códigos de respaldo al portapapeles. */
117
119
  copyCodes(codes: string[]): Promise<void>;
120
+ /** Copia el secreto TOTP al portapapeles + feedback visual (check) durante 2s. */
121
+ copySecret(secret: string): Promise<void>;
118
122
  /** Etiqueta i18n legible para un método MFA. */
119
123
  methodLabel(method: MFAMethod | null): string;
120
124
  private resetFlow;
package/lib/version.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * Current version of valtech-components.
3
3
  * This is automatically updated during the publish process.
4
4
  */
5
- export declare const VERSION = "2.0.848";
5
+ export declare const VERSION = "2.0.850";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valtech-components",
3
- "version": "2.0.848",
3
+ "version": "2.0.850",
4
4
  "private": false,
5
5
  "bin": {
6
6
  "valtech-firebase-config": "./src/lib/services/firebase/scripts/generate-sw-config.js"
package/public-api.d.ts CHANGED
@@ -174,6 +174,9 @@ export * from './lib/components/molecules/username-input/username-input.componen
174
174
  export * from './lib/components/molecules/username-input/types';
175
175
  export * from './lib/components/molecules/linked-providers/linked-providers.component';
176
176
  export * from './lib/components/molecules/linked-providers/types';
177
+ export * from './lib/components/molecules/empty-state/empty-state.component';
178
+ export * from './lib/components/molecules/empty-state/factory';
179
+ export * from './lib/components/molecules/empty-state/types';
177
180
  export * from './lib/components/molecules/image-crop/image-crop.component';
178
181
  export * from './lib/components/molecules/modal-shell/modal-shell.component';
179
182
  export * from './lib/components/organisms/article/article.component';