@kaufmann-lab/ui 0.1.21 → 0.1.24
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.
- package/fesm2022/kaufmann-lab-ui-business.mjs +2 -2
- package/fesm2022/kaufmann-lab-ui-business.mjs.map +1 -1
- package/fesm2022/kaufmann-lab-ui-core.mjs +2580 -527
- package/fesm2022/kaufmann-lab-ui-core.mjs.map +1 -1
- package/fesm2022/kaufmann-lab-ui-map.mjs +1 -1
- package/fesm2022/kaufmann-lab-ui-map.mjs.map +1 -1
- package/package.json +1 -1
- package/src/tokens/base.css +33 -8
- package/types/kaufmann-lab-ui-core.d.ts +1187 -162
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { AfterContentInit, TemplateRef, Signal, ElementRef, AfterViewInit } from '@angular/core';
|
|
2
|
+
import { AfterContentInit, TemplateRef, Signal, ElementRef, AfterViewInit, OnDestroy } from '@angular/core';
|
|
3
3
|
import { ControlValueAccessor } from '@angular/forms';
|
|
4
4
|
import { SafeResourceUrl } from '@angular/platform-browser';
|
|
5
5
|
|
|
@@ -179,10 +179,10 @@ declare class AdminBadge {
|
|
|
179
179
|
declare class Button {
|
|
180
180
|
readonly variant: _angular_core.InputSignal<"primary" | "secondary" | "ghost" | "outline" | "danger" | "surface">;
|
|
181
181
|
readonly size: _angular_core.InputSignal<"sm" | "md" | "lg">;
|
|
182
|
-
readonly shape: _angular_core.InputSignal<"
|
|
182
|
+
readonly shape: _angular_core.InputSignal<"rect" | "circle">;
|
|
183
183
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
184
184
|
/** Igual al default nativo: hace submit dentro de un `<form>`. */
|
|
185
|
-
readonly type: _angular_core.InputSignal<"button" | "
|
|
185
|
+
readonly type: _angular_core.InputSignal<"button" | "submit" | "reset">;
|
|
186
186
|
/** Ícono líder, renderizado con `kf-icon` antes del label proyectado. */
|
|
187
187
|
readonly icon: _angular_core.InputSignal<IconName | undefined>;
|
|
188
188
|
/** Estira el botón a todo el ancho de su contenedor. */
|
|
@@ -205,7 +205,7 @@ declare class Button {
|
|
|
205
205
|
readonly ariaPressed: _angular_core.InputSignal<boolean | undefined>;
|
|
206
206
|
/** Tipo de elemento emergente que abre el botón (ej. `'dialog'` para un
|
|
207
207
|
* panel de filtros, `'listbox'`) — mismo motivo de reenvío manual. */
|
|
208
|
-
readonly ariaHaspopup: _angular_core.InputSignal<"
|
|
208
|
+
readonly ariaHaspopup: _angular_core.InputSignal<"menu" | "dialog" | "listbox" | "true" | undefined>;
|
|
209
209
|
private readonly nativeButton;
|
|
210
210
|
/** Enfoca el `<button>` interno (mismas opciones que `HTMLElement.focus`). */
|
|
211
211
|
focus(options?: FocusOptions): void;
|
|
@@ -218,6 +218,8 @@ declare class Button {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
type AlertTone = 'info' | 'ok' | 'warn' | 'error';
|
|
221
|
+
/** Forma del aviso: `card` (default, con borde y esquinas) o `bar` (franja compacta de ancho completo). */
|
|
222
|
+
type AlertVariant = 'card' | 'bar';
|
|
221
223
|
/**
|
|
222
224
|
* Banner contextual que vive dentro del flujo: validaciones, avisos de
|
|
223
225
|
* vencimiento, confirmaciones. Persiste hasta que se descarta o hasta que la
|
|
@@ -229,9 +231,21 @@ type AlertTone = 'info' | 'ok' | 'warn' | 'error';
|
|
|
229
231
|
*
|
|
230
232
|
* <kf-alert tone="warn" title="SOAT por vencer">Vence el 15/08.</kf-alert>
|
|
231
233
|
* <kf-alert tone="ok" [(open)]="saved" dismissible>Pago registrado.</kf-alert>
|
|
234
|
+
*
|
|
235
|
+
* `variant="bar"` es una franja compacta de ancho completo, sin tarjeta: sin
|
|
236
|
+
* esquinas ni bordes laterales (solo la línea superior e inferior del tono),
|
|
237
|
+
* ícono, título y mensaje en una sola línea que envuelve si no entra. Mismos
|
|
238
|
+
* tonos y mismo `role` (`alert` para `error`/`warn`, `status` para el resto)
|
|
239
|
+
* que la variante `card`. Pensada para el borde de una página o de un panel
|
|
240
|
+
* (ej. "Estás viendo datos de otro cliente"), donde una tarjeta con margen
|
|
241
|
+
* sobra.
|
|
242
|
+
*
|
|
243
|
+
* <kf-alert variant="bar" tone="warn" title="Modo suplantación">Viendo como Ana Pérez.</kf-alert>
|
|
232
244
|
*/
|
|
233
245
|
declare class Alert {
|
|
234
246
|
readonly tone: _angular_core.InputSignal<AlertTone>;
|
|
247
|
+
/** `card` (default) o `bar` (franja compacta de ancho completo). */
|
|
248
|
+
readonly variant: _angular_core.InputSignal<AlertVariant>;
|
|
235
249
|
/** Línea en negrita arriba del mensaje. Vacío deja solo el contenido proyectado. */
|
|
236
250
|
readonly title: _angular_core.InputSignal<string>;
|
|
237
251
|
readonly dismissible: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
@@ -241,13 +255,13 @@ declare class Alert {
|
|
|
241
255
|
* `alert` interrumpe al lector de pantalla; se reserva para error/warn.
|
|
242
256
|
* Los avisos informativos se anuncian sin cortar lo que se esté leyendo.
|
|
243
257
|
*/
|
|
244
|
-
protected readonly ariaRole: _angular_core.Signal<"
|
|
258
|
+
protected readonly ariaRole: _angular_core.Signal<"alert" | "status">;
|
|
245
259
|
protected readonly toneIcon: _angular_core.Signal<IconName>;
|
|
246
260
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Alert, never>;
|
|
247
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Alert, "kf-alert", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*"], true, never>;
|
|
261
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Alert, "kf-alert", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*"], true, never>;
|
|
248
262
|
}
|
|
249
263
|
|
|
250
|
-
type AlertRowTone = 'warn' | 'error';
|
|
264
|
+
type AlertRowTone = 'warn' | 'error' | 'neutral';
|
|
251
265
|
/**
|
|
252
266
|
* Fila clickeable de una lista de pendientes/alertas: ícono circular con
|
|
253
267
|
* tono semántico, texto de una línea, chevron al final. Pensada para
|
|
@@ -255,14 +269,43 @@ type AlertRowTone = 'warn' | 'error';
|
|
|
255
269
|
* dashboard) — no incluye el contenedor en sí.
|
|
256
270
|
*
|
|
257
271
|
* <kf-alert-row icon="file" tone="warn" text="2 cotizaciones esperan tu aprobación" (rowClick)="onNavigate('cotizaciones')" />
|
|
272
|
+
*
|
|
273
|
+
* Extensiones opcionales (la fila sin ellas se ve y se comporta como siempre):
|
|
274
|
+
* - `tone="neutral"`: ícono gris, para una fila sin urgencia ni alerta.
|
|
275
|
+
* - `value`: cifra alineada a la derecha, antes del chevron (ej. el conteo de
|
|
276
|
+
* pendientes). Admite `'—'` cuando no hay dato; en ese caso conviene pasar
|
|
277
|
+
* `valueLabel` con el texto que debe leer un lector de pantalla
|
|
278
|
+
* («Sin datos»), porque la raya sola no dice nada.
|
|
279
|
+
* - `valueLabel`: texto solo para lectores de pantalla que reemplaza a `value`
|
|
280
|
+
* en el árbol de accesibilidad; visualmente se sigue viendo `value`.
|
|
281
|
+
* - `tag`: etiqueta neutra pequeña junto al texto (ej. «Próximamente»).
|
|
282
|
+
* - `disabled`: la fila no es accionable — no emite `rowClick`, no entra en el
|
|
283
|
+
* orden de tabulación, no cambia al pasar el mouse, su chevron se oculta (conserva el
|
|
284
|
+
* espacio para alinear las cifras con las filas activas) y el
|
|
285
|
+
* texto y la cifra se atenúan (sin bajar el contraste de lectura). Expone
|
|
286
|
+
* `disabled` y `aria-disabled="true"`, así que un lector de pantalla la
|
|
287
|
+
* anuncia como no disponible en vez de omitirla.
|
|
288
|
+
*
|
|
289
|
+
* <kf-alert-row icon="file" tone="neutral" text="Documentos por firmar" tag="Próximamente" value="—" valueLabel="Sin datos todavía" disabled />
|
|
258
290
|
*/
|
|
259
291
|
declare class AlertRow {
|
|
260
292
|
readonly icon: _angular_core.InputSignal<IconName>;
|
|
261
293
|
readonly tone: _angular_core.InputSignal<AlertRowTone>;
|
|
262
294
|
readonly text: _angular_core.InputSignal<string>;
|
|
295
|
+
/** Cifra o texto corto alineado a la derecha (ej. `3`, `'—'`). */
|
|
296
|
+
readonly value: _angular_core.InputSignal<string | number | undefined>;
|
|
297
|
+
/** Texto solo para lectores de pantalla que reemplaza a `value` en el árbol de accesibilidad. */
|
|
298
|
+
readonly valueLabel: _angular_core.InputSignal<string | undefined>;
|
|
299
|
+
/** Etiqueta neutra junto al texto (ej. «Próximamente»). */
|
|
300
|
+
readonly tag: _angular_core.InputSignal<string | undefined>;
|
|
301
|
+
/** La fila no es accionable: sin clic, sin foco ni hover. */
|
|
302
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
263
303
|
readonly rowClick: _angular_core.OutputEmitterRef<void>;
|
|
304
|
+
/** Emite `rowClick` salvo que la fila esté deshabilitada (también ante clics sintéticos). */
|
|
305
|
+
protected activate(): void;
|
|
306
|
+
protected hasValue(): boolean;
|
|
264
307
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AlertRow, never>;
|
|
265
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<AlertRow, "kf-alert-row", never, { "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "text": { "alias": "text"; "required": true; "isSignal": true; }; }, { "rowClick": "rowClick"; }, never, never, true, never>;
|
|
308
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<AlertRow, "kf-alert-row", never, { "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "text": { "alias": "text"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "valueLabel": { "alias": "valueLabel"; "required": false; "isSignal": true; }; "tag": { "alias": "tag"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "rowClick": "rowClick"; }, never, never, true, never>;
|
|
266
309
|
}
|
|
267
310
|
|
|
268
311
|
/**
|
|
@@ -313,7 +356,7 @@ declare class Avatar {
|
|
|
313
356
|
* <kf-badge tone="warn" dot truncate [title]="q.statusLabel">{{ q.statusLabel }}</kf-badge>
|
|
314
357
|
*/
|
|
315
358
|
declare class Badge {
|
|
316
|
-
readonly tone: _angular_core.InputSignal<"
|
|
359
|
+
readonly tone: _angular_core.InputSignal<"info" | "neutral" | "ok" | "warn" | "error" | "service">;
|
|
317
360
|
readonly variant: _angular_core.InputSignal<"soft" | "glass">;
|
|
318
361
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
319
362
|
/** Corta el texto con elipsis al ancho del contenedor. Ver JSDoc de la clase. */
|
|
@@ -546,14 +589,26 @@ declare class Calendar {
|
|
|
546
589
|
* <kf-button>Guardar</kf-button>
|
|
547
590
|
* </div>
|
|
548
591
|
* </kf-card>
|
|
592
|
+
*
|
|
593
|
+
* `loading` (default `false`): cubre el cuerpo con un bloque de carga animado
|
|
594
|
+
* sin sacar el contenido del layout (queda invisible y fuera del foco y de
|
|
595
|
+
* lectores de pantalla), así la card conserva exactamente sus dimensiones. Los
|
|
596
|
+
* slots `[kf-card-media]` y `[kf-card-actions]` también se ocultan. Marca el
|
|
597
|
+
* host con `aria-busy="true"`. Para una forma más fiel (líneas separadas) usa
|
|
598
|
+
* `kf-skeleton` dentro de la card, o la card propia del dominio con su
|
|
599
|
+
* `loading` (`kf-stat-card`, `kf-metric-card`).
|
|
600
|
+
*
|
|
601
|
+
* <kf-card [loading]="isLoading()"><h3>{{ title() }}</h3><p>{{ text() }}</p></kf-card>
|
|
549
602
|
*/
|
|
550
603
|
declare class Card {
|
|
551
604
|
/** Quita la sombra — para cards anidadas dentro de otra superficie ya elevada. */
|
|
552
605
|
readonly flush: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
553
606
|
/** Espacio entre los hijos directos del cuerpo. `md` es el default. */
|
|
554
607
|
readonly gap: _angular_core.InputSignal<"sm" | "md" | "lg" | "xs" | "xl">;
|
|
608
|
+
/** Cubre el cuerpo con un bloque de carga conservando las dimensiones. */
|
|
609
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
555
610
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Card, never>;
|
|
556
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Card, "kf-card", never, { "flush": { "alias": "flush"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; }, {}, never, ["[kf-card-media]", "*", "[kf-card-actions]"], true, never>;
|
|
611
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Card, "kf-card", never, { "flush": { "alias": "flush"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; }, {}, never, ["[kf-card-media]", "*", "[kf-card-actions]"], true, never>;
|
|
557
612
|
}
|
|
558
613
|
|
|
559
614
|
/**
|
|
@@ -675,7 +730,7 @@ declare class Checkbox implements ControlValueAccessor {
|
|
|
675
730
|
* de superficie/borde/texto-muted más cercanos).
|
|
676
731
|
*/
|
|
677
732
|
declare class Chip {
|
|
678
|
-
readonly tone: _angular_core.InputSignal<"
|
|
733
|
+
readonly tone: _angular_core.InputSignal<"neutral" | "ok" | "warn" | "error">;
|
|
679
734
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
680
735
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Chip, never>;
|
|
681
736
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Chip, "kf-chip", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
@@ -769,99 +824,6 @@ declare class ContentSlot {
|
|
|
769
824
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentSlot, "kf-content-slot", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
770
825
|
}
|
|
771
826
|
|
|
772
|
-
/** En qué estado está la sección. */
|
|
773
|
-
type ContentStateKind = 'ready' | 'loading' | 'empty' | 'error';
|
|
774
|
-
/** Cómo se dibuja `loading`. Default `'skeleton'`. */
|
|
775
|
-
type ContentStateLoad = 'skeleton' | 'spinner';
|
|
776
|
-
/**
|
|
777
|
-
* Wrapper de los cuatro estados que toda sección tiene: cargando, con datos,
|
|
778
|
-
* vacía y con error. Un componente en vez de tres `@if` sueltos, porque es
|
|
779
|
-
* siempre el mismo slot el que va rotando entre los cuatro.
|
|
780
|
-
*
|
|
781
|
-
* Con `state="ready"` proyecta el contenido real y desaparece; en los otros
|
|
782
|
-
* tres dibuja el placeholder correspondiente y el contenido no se instancia.
|
|
783
|
-
* No inventa visuales propios: `loading` usa `kf-skeleton` (o `kf-spinner` con
|
|
784
|
-
* `load="spinner"`), y `empty`/`error` usan `kf-empty-state`.
|
|
785
|
-
*
|
|
786
|
-
* Las acciones (reintentar, crear) van en el slot `actions` — se ignoran
|
|
787
|
-
* mientras carga, porque no hay nada que reintentar todavía.
|
|
788
|
-
*
|
|
789
|
-
* <kf-content-state [state]="state()" title="No pudimos cargar tus vehículos"
|
|
790
|
-
* subtitle="Revisá tu conexión e intentá de nuevo.">
|
|
791
|
-
* <kf-button actions (click)="retry()">Reintentar</kf-button>
|
|
792
|
-
* <kf-data-table [columns]="cols" [rows]="rows()" />
|
|
793
|
-
* </kf-content-state>
|
|
794
|
-
*/
|
|
795
|
-
declare class ContentState {
|
|
796
|
-
readonly state: _angular_core.InputSignal<ContentStateKind>;
|
|
797
|
-
/** Forma del estado de carga: silueta (default) o spinner. */
|
|
798
|
-
readonly load: _angular_core.InputSignal<ContentStateLoad>;
|
|
799
|
-
/** Título de `empty`/`error`. Ignorado mientras carga. */
|
|
800
|
-
readonly title: _angular_core.InputSignal<string>;
|
|
801
|
-
readonly subtitle: _angular_core.InputSignal<string>;
|
|
802
|
-
/** Texto al lado del spinner cuando `load="spinner"`. */
|
|
803
|
-
readonly loadingLabel: _angular_core.InputSignal<string>;
|
|
804
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentState, never>;
|
|
805
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentState, "kf-content-state", never, { "state": { "alias": "state"; "required": true; "isSignal": true; }; "load": { "alias": "load"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[actions]"], true, never>;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
type ContentViewerType = 'image' | 'video' | 'pdf';
|
|
809
|
-
/**
|
|
810
|
-
* Visor a pantalla completa para ampliar una pieza de contenido: imagen,
|
|
811
|
-
* video o PDF (`type="pdf"`, renderizado por el visor nativo del navegador).
|
|
812
|
-
* Mismo mecanismo que `kf-modal` (el `<dialog>` nativo resuelve backdrop,
|
|
813
|
-
* atrapado de foco, top-layer y `Escape`), pero sin panel/título/footer:
|
|
814
|
-
* el contenido ocupa toda la pantalla sobre un backdrop oscuro.
|
|
815
|
-
*
|
|
816
|
-
* `src` acepta lo que venga del backend sin que el consumidor tenga que
|
|
817
|
-
* normalizarlo primero: una URL (`http(s)://`), un data URI ya armado
|
|
818
|
-
* (`data:...`), o base64 crudo (se le antepone el prefijo `data:` según
|
|
819
|
-
* `type`, asumiendo JPEG para imagen, MP4 para video y PDF para pdf). Un PDF
|
|
820
|
-
* solo acepta contenido local (`blob:`, data URI o base64), nunca una URL remota.
|
|
821
|
-
*
|
|
822
|
-
* Lo proyectado con el atributo `actions` (p. ej. un botón de descarga) va en
|
|
823
|
-
* la barra superior, junto al título.
|
|
824
|
-
*
|
|
825
|
-
* <kf-content-viewer [(open)]="viewerOpen" [src]="viewerSrc()" alt="Foto del vehículo" />
|
|
826
|
-
* <kf-content-viewer [(open)]="viewerOpen" type="video" [src]="viewerSrc()" title="Inspección" />
|
|
827
|
-
* <kf-content-viewer [(open)]="viewerOpen" type="pdf" [src]="blobUrl()" title="Contrato">
|
|
828
|
-
* <kf-button actions variant="surface" icon="download" (click)="save()">Descargar</kf-button>
|
|
829
|
-
* </kf-content-viewer>
|
|
830
|
-
*/
|
|
831
|
-
declare class ContentViewer {
|
|
832
|
-
readonly type: _angular_core.InputSignal<ContentViewerType>;
|
|
833
|
-
/** URL, data URI, o base64 crudo — ver JSDoc de la clase. */
|
|
834
|
-
readonly src: _angular_core.InputSignal<string | null>;
|
|
835
|
-
/** Texto alternativo cuando `type="image"`. */
|
|
836
|
-
readonly alt: _angular_core.InputSignal<string>;
|
|
837
|
-
readonly title: _angular_core.InputSignal<string>;
|
|
838
|
-
/** Visibilidad, two-way: `[(open)]="viewerOpen"`. */
|
|
839
|
-
readonly open: _angular_core.ModelSignal<boolean>;
|
|
840
|
-
/** Permite cerrar con el botón, `Escape` o clic en el backdrop. */
|
|
841
|
-
readonly dismissible: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
842
|
-
protected readonly titleId: string;
|
|
843
|
-
/** Detecta si `src` ya es una URL o un data URI armado; si no, asume
|
|
844
|
-
* base64 crudo y le antepone el prefijo `data:` correspondiente a `type`
|
|
845
|
-
* — el backend a veces manda una cosa, a veces la otra. */
|
|
846
|
-
protected readonly resolvedSrc: _angular_core.Signal<string | null>;
|
|
847
|
-
protected readonly pdfSrc: _angular_core.Signal<SafeResourceUrl | null>;
|
|
848
|
-
protected readonly fallbackLabel: _angular_core.Signal<string>;
|
|
849
|
-
private readonly dialog;
|
|
850
|
-
private readonly document;
|
|
851
|
-
private readonly sanitizer;
|
|
852
|
-
constructor();
|
|
853
|
-
/** `Escape` dispara `cancel`; cancelarlo lo deja abierto. */
|
|
854
|
-
protected onCancel(event: Event): void;
|
|
855
|
-
/**
|
|
856
|
-
* Clic en el backdrop. Un clic en la zona del backdrop tiene como `target` al
|
|
857
|
-
* propio `<dialog>` (el contenido vive en el panel de adentro), así que basta
|
|
858
|
-
* comparar contra él — no hace falta cortar la propagación en el panel.
|
|
859
|
-
*/
|
|
860
|
-
protected onHostClick(event: MouseEvent): void;
|
|
861
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentViewer, never>;
|
|
862
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentViewer, "kf-content-viewer", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "src": { "alias": "src"; "required": false; "isSignal": true; }; "alt": { "alias": "alt"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[actions]"], true, never>;
|
|
863
|
-
}
|
|
864
|
-
|
|
865
827
|
/**
|
|
866
828
|
* Zona que ocupa la columna en la vista de cards. La vista de tabla ignora
|
|
867
829
|
* esto (salvo `media`, que igual se rinde como thumbnail en vez de imprimir
|
|
@@ -940,7 +902,25 @@ interface DataTableColumn {
|
|
|
940
902
|
/** Destaca el valor (peso y color de tinta) — ej. el monto. En la vista
|
|
941
903
|
* tarjetas, una columna `meta` con `emphasis` va al final de su fila. */
|
|
942
904
|
emphasis?: boolean;
|
|
905
|
+
/** Celda interactiva: su contenido (texto, `cellTemplates` o `render`) se
|
|
906
|
+
* renderiza dentro de un `<button type="button">` real —enfocable con Tab,
|
|
907
|
+
* con foco visible y activable con Enter o Espacio—, tanto en la vista de
|
|
908
|
+
* tabla como en la de tarjetas. Al activarla emite `cellClick`
|
|
909
|
+
* (`{ row, column, index }`) y NO emite `rowClick`. El contenido de un
|
|
910
|
+
* `cellTemplates` en una columna interactiva debe ser fraseo no interactivo
|
|
911
|
+
* (texto, íconos, indicadores): un enlace o botón dentro de otro botón es
|
|
912
|
+
* HTML inválido. El nombre accesible sale del contenido o, si no alcanza
|
|
913
|
+
* (un indicador sin texto), de `cellAriaLabel`. */
|
|
914
|
+
interactive?: boolean;
|
|
915
|
+
}
|
|
916
|
+
/** Payload de `cellClick`: la fila, la columna interactiva y el índice de la fila renderizada. */
|
|
917
|
+
interface DataTableCellClick<T = unknown> {
|
|
918
|
+
row: T;
|
|
919
|
+
column: DataTableColumn;
|
|
920
|
+
index: number;
|
|
943
921
|
}
|
|
922
|
+
/** Tope de filas (o tarjetas) esqueleto: con `loading`, una página de 50 no pinta 50. */
|
|
923
|
+
declare const DATA_TABLE_MAX_SKELETON_ROWS = 12;
|
|
944
924
|
/** Vistas disponibles cuando `cardable` está activo. */
|
|
945
925
|
type DataTableView = 'table' | 'cards';
|
|
946
926
|
/** Opciones de "filas por página" estándar del portal — 10 como default
|
|
@@ -988,12 +968,21 @@ type DataTableSort = `${string}:${'asc' | 'desc'}`;
|
|
|
988
968
|
* <kf-data-table [columns]="columns" [rows]="rows" [cardable]="true" defaultView="cards" />
|
|
989
969
|
*
|
|
990
970
|
* Loading nativo: con `loading` en `true`, la tabla se reemplaza por un
|
|
991
|
-
* placeholder (`kf-skeleton` por celda/card) —
|
|
992
|
-
* `pageSize`, o 5 si no hay paginación activa.
|
|
971
|
+
* placeholder (`kf-skeleton` por celda/card) — `skeletonRows` filas si se
|
|
972
|
+
* pasa; si no, las de `pageSize`, o 5 si no hay paginación activa. Nunca más
|
|
973
|
+
* de 12 (`DATA_TABLE_MAX_SKELETON_ROWS`): con una página de 50 no se pintan
|
|
974
|
+
* 50 placeholders. Ignora `rows()`/el slot
|
|
993
975
|
* `[empty]` mientras dura (no sabemos aún si el resultado real estará
|
|
994
976
|
* vacío), y respeta la vista activa (tabla o cards) para no cambiar el
|
|
995
977
|
* layout de golpe cuando los datos reales lleguen. El toggle tabla/cards y
|
|
996
|
-
* el header de columnas siguen visibles — solo el cuerpo se reemplaza
|
|
978
|
+
* el header de columnas siguen visibles — solo el cuerpo se reemplaza.
|
|
979
|
+
*
|
|
980
|
+
* El placeholder respeta la columna: en la tabla cada celda conserva su
|
|
981
|
+
* `align`, `width`, `minWidth` y `maxWidth` (una columna numérica lleva una
|
|
982
|
+
* barra corta alineada al final, una de acciones un cuadrado chico, el resto
|
|
983
|
+
* barras de anchos distintos) y la fila reserva el alto de una línea de texto.
|
|
984
|
+
* En tarjetas reproduce la estructura según `cardRole`: encabezado (miniatura,
|
|
985
|
+
* título y estado), campos con su rótulo, fila de `meta` y pie de acciones:
|
|
997
986
|
*
|
|
998
987
|
* <kf-data-table [columns]="columns" [rows]="rows()" [loading]="isLoading()">
|
|
999
988
|
* <kf-empty-state empty>No hay resultados para mostrar.</kf-empty-state>
|
|
@@ -1025,7 +1014,8 @@ type DataTableSort = `${string}:${'asc' | 'desc'}`;
|
|
|
1025
1014
|
* el selector, y `pageSizeChange` avisa cuando el usuario lo cambia.
|
|
1026
1015
|
*
|
|
1027
1016
|
* Ordenamiento por columna: cada `DataTableColumn` con `sortable: true`
|
|
1028
|
-
* vuelve su header
|
|
1017
|
+
* vuelve su header un botón (Tab, Enter y Espacio) que expone el estado con
|
|
1018
|
+
* `aria-sort` (`ascending`/`descending`/`none`), con el mismo formato `key:direction` que
|
|
1029
1019
|
* usa `sort` de `kf-quote-picker` (two-way manual, no `model()` — el
|
|
1030
1020
|
* consumidor decide si persiste el valor o lo descarta al desmontar):
|
|
1031
1021
|
*
|
|
@@ -1086,6 +1076,30 @@ type DataTableSort = `${string}:${'asc' | 'desc'}`;
|
|
|
1086
1076
|
* <kf-data-table [columns]="columns" [rows]="quotes" cardable [(view)]="view"
|
|
1087
1077
|
* [showViewToggle]="false" cardMinWidth="300px" [rowClickable]="true"
|
|
1088
1078
|
* (rowClick)="open($event.row)" />
|
|
1079
|
+
*
|
|
1080
|
+
* Celdas interactivas (modo aditivo, ej. una matriz unidad × etapa donde cada
|
|
1081
|
+
* celda de etapa es un indicador de estado): una columna con
|
|
1082
|
+
* `interactive: true` renderiza su contenido dentro de un `<button>` real
|
|
1083
|
+
* —focusable, con foco visible y activación con Enter o Espacio— en la vista
|
|
1084
|
+
* de tabla y en la de tarjetas, y emite `cellClick` con `{ row, column, index }`.
|
|
1085
|
+
* `cellAriaLabel` da el nombre accesible de cada celda cuando el contenido no
|
|
1086
|
+
* lo aporta por sí solo (un indicador sin texto); en tarjetas conviene incluir
|
|
1087
|
+
* el contexto de la fila, porque no hay encabezado de columna que lo dé:
|
|
1088
|
+
*
|
|
1089
|
+
* columns = [
|
|
1090
|
+
* { key: 'unit', label: 'Unidad', cardRole: 'title', sticky: 'left' },
|
|
1091
|
+
* { key: 'stage1', label: 'Recepción', interactive: true, align: 'center' },
|
|
1092
|
+
* { key: 'stage2', label: 'Entrega', interactive: true, align: 'center' },
|
|
1093
|
+
* ];
|
|
1094
|
+
* <kf-data-table [columns]="columns" [rows]="units" cardable [rowKey]="unitId"
|
|
1095
|
+
* [cellTemplates]="{ stage1: stageCell, stage2: stageCell }"
|
|
1096
|
+
* [cellAriaLabel]="stageLabel" (cellClick)="openStage($event.row, $event.column)" />
|
|
1097
|
+
*
|
|
1098
|
+
* Convive con `rowClick`: la fila sigue emitiéndolo desde cualquier punto que
|
|
1099
|
+
* no sea una celda interactiva. En tarjetas, la tarjeta deja de ser un botón
|
|
1100
|
+
* (un botón dentro de un `role="button"` es inválido) salvo que se fuerce con
|
|
1101
|
+
* `[rowClickable]="true"`. `sticky`, `cellTemplates`, `currentRowKey`, la
|
|
1102
|
+
* ordenación y la paginación no cambian.
|
|
1089
1103
|
*/
|
|
1090
1104
|
declare class DataTable<T = unknown> {
|
|
1091
1105
|
readonly columns: _angular_core.InputSignal<DataTableColumn[]>;
|
|
@@ -1093,6 +1107,10 @@ declare class DataTable<T = unknown> {
|
|
|
1093
1107
|
/** Placeholder nativo (`kf-skeleton`) mientras los datos reales cargan —
|
|
1094
1108
|
* ver el doc-comment de la clase para el detalle. */
|
|
1095
1109
|
readonly loading: _angular_core.InputSignal<boolean>;
|
|
1110
|
+
/** Filas (o tarjetas) esqueleto mientras `loading` es `true`. Sin valor: el
|
|
1111
|
+
* `pageSize` con paginación activa, o 5. Máximo
|
|
1112
|
+
* {@link DATA_TABLE_MAX_SKELETON_ROWS}. */
|
|
1113
|
+
readonly skeletonRows: _angular_core.InputSignal<number | undefined>;
|
|
1096
1114
|
private readonly scrollEl;
|
|
1097
1115
|
private readonly destroyRef;
|
|
1098
1116
|
/**
|
|
@@ -1132,20 +1150,45 @@ declare class DataTable<T = unknown> {
|
|
|
1132
1150
|
* real (badges, links, botones) usar `cellTemplates`.
|
|
1133
1151
|
*/
|
|
1134
1152
|
readonly render: _angular_core.InputSignal<((row: T) => string) | undefined>;
|
|
1135
|
-
/** Mapa `columnKey -> TemplateRef` para celdas con contenido custom.
|
|
1153
|
+
/** Mapa `columnKey -> TemplateRef` para celdas con contenido custom. El
|
|
1154
|
+
* contexto trae `$implicit` (la fila), `index` y `column` (la columna), así
|
|
1155
|
+
* que un mismo template puede servir a varias columnas. */
|
|
1136
1156
|
readonly cellTemplates: _angular_core.InputSignal<Record<string, TemplateRef<{
|
|
1137
1157
|
$implicit: T;
|
|
1138
1158
|
index: number;
|
|
1159
|
+
column?: DataTableColumn;
|
|
1139
1160
|
}>> | undefined>;
|
|
1140
1161
|
/** Densidad de fila — ver `DataTableDensity`. */
|
|
1141
1162
|
readonly density: _angular_core.InputSignal<DataTableDensity>;
|
|
1142
1163
|
/** Fuerza si la fila entera dispara `rowClick` en la vista de tabla —
|
|
1143
1164
|
* ver `rowInteractive` para el cálculo automático cuando no se define. */
|
|
1144
1165
|
readonly rowClickable: _angular_core.InputSignal<boolean | null>;
|
|
1166
|
+
/**
|
|
1167
|
+
* Con `false`, las filas interactivas de la vista de tabla dejan de ser
|
|
1168
|
+
* paradas de Tab (sin `tabindex`): útil cuando la fila es clickeable con el
|
|
1169
|
+
* mouse pero la acción accesible por teclado es un enlace o botón real
|
|
1170
|
+
* dentro de una celda — así una página de N filas no suma N paradas de Tab
|
|
1171
|
+
* sin rol. El clic con mouse sigue emitiendo `rowClick`. Default `true`
|
|
1172
|
+
* (comportamiento histórico). No afecta a las tarjetas, que son
|
|
1173
|
+
* `role="button"`.
|
|
1174
|
+
*/
|
|
1175
|
+
readonly rowFocusable: _angular_core.InputSignal<boolean>;
|
|
1145
1176
|
readonly rowClick: _angular_core.OutputEmitterRef<{
|
|
1146
1177
|
row: T;
|
|
1147
1178
|
index: number;
|
|
1148
1179
|
}>;
|
|
1180
|
+
/**
|
|
1181
|
+
* Se emite al activar (clic, Enter o Espacio) una celda de una columna
|
|
1182
|
+
* `interactive`. `index` es el de la fila dentro de las filas mostradas
|
|
1183
|
+
* (misma convención que `rowClick`). No emite `rowClick`.
|
|
1184
|
+
*/
|
|
1185
|
+
readonly cellClick: _angular_core.OutputEmitterRef<DataTableCellClick<T>>;
|
|
1186
|
+
/**
|
|
1187
|
+
* Nombre accesible (`aria-label`) del botón de cada celda interactiva:
|
|
1188
|
+
* `(row, column, index) => string`. Sin esta función, el botón se nombra
|
|
1189
|
+
* por su contenido. Se usa solo en columnas `interactive`.
|
|
1190
|
+
*/
|
|
1191
|
+
readonly cellAriaLabel: _angular_core.InputSignal<((row: T, column: DataTableColumn, index: number) => string) | undefined>;
|
|
1149
1192
|
/** Nombre accesible del contenedor con scroll horizontal (solo se aplica cuando hay overflow). */
|
|
1150
1193
|
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
1151
1194
|
/**
|
|
@@ -1191,10 +1234,22 @@ declare class DataTable<T = unknown> {
|
|
|
1191
1234
|
* (si `pageSizeOptions` está activo), o el `pageSize` del consumidor. */
|
|
1192
1235
|
protected readonly effectivePageSize: _angular_core.Signal<number | null>;
|
|
1193
1236
|
/** Cantidad de filas/cards placeholder mientras `loading` es true — el
|
|
1194
|
-
* `
|
|
1195
|
-
* "adivina" cuántas filas reales
|
|
1196
|
-
* o 5
|
|
1237
|
+
* `skeletonRows` explícito; si no hay, el `pageSize` efectivo con
|
|
1238
|
+
* paginación activa (así el placeholder ya "adivina" cuántas filas reales
|
|
1239
|
+
* van a aparecer, sin salto de layout) o 5 sin paginación. Siempre entre 1 y
|
|
1240
|
+
* {@link DATA_TABLE_MAX_SKELETON_ROWS}: con una página de 50 filas no se
|
|
1241
|
+
* pintan 50 placeholders. */
|
|
1197
1242
|
protected readonly skeletonRowIndexes: _angular_core.Signal<number[]>;
|
|
1243
|
+
/** Las tarjetas esqueleto llevan encabezado cuando la real lo tendría. */
|
|
1244
|
+
protected readonly skeletonCardHeader: _angular_core.Signal<boolean>;
|
|
1245
|
+
/**
|
|
1246
|
+
* Ancho (%) de la barra de una celda esqueleto: no todas iguales — una
|
|
1247
|
+
* columna numérica (alineada al final) es corta, un identificador
|
|
1248
|
+
* (`mono`) mediano, una de acciones (`hideLabel`) un cuadrado chico, y el
|
|
1249
|
+
* resto alterna entre tres anchos según su posición para que la tabla no
|
|
1250
|
+
* parezca un patrón repetido.
|
|
1251
|
+
*/
|
|
1252
|
+
protected skeletonBarWidth(column: DataTableColumn, row: number, index: number): string;
|
|
1198
1253
|
protected readonly totalPages: _angular_core.Signal<number>;
|
|
1199
1254
|
/** Texto informativo del footer de paginación interna ("1–5 de 7
|
|
1200
1255
|
* beneficios") — se recalcula con cada cambio de página/tamaño/dataset,
|
|
@@ -1207,13 +1262,15 @@ declare class DataTable<T = unknown> {
|
|
|
1207
1262
|
* asc → desc → sin orden; clickear otra columna reinicia el ciclo en esa
|
|
1208
1263
|
* columna nueva.
|
|
1209
1264
|
*/
|
|
1210
|
-
readonly sort: _angular_core.InputSignal<`${string}:
|
|
1211
|
-
readonly sortChange: _angular_core.OutputEmitterRef<`${string}:
|
|
1265
|
+
readonly sort: _angular_core.InputSignal<`${string}:desc` | `${string}:asc` | null>;
|
|
1266
|
+
readonly sortChange: _angular_core.OutputEmitterRef<`${string}:desc` | `${string}:asc` | null>;
|
|
1212
1267
|
protected readonly sortedRows: _angular_core.Signal<T[]>;
|
|
1213
1268
|
/** Filas realmente renderizadas: ordenadas y, si `pageSize` está activo,
|
|
1214
1269
|
* recortadas a la página actual. */
|
|
1215
1270
|
protected readonly displayedRows: _angular_core.Signal<T[]>;
|
|
1216
1271
|
protected sortDirectionFor(column: DataTableColumn): 'asc' | 'desc' | null;
|
|
1272
|
+
/** Valor de `aria-sort` del header de una columna ordenable. */
|
|
1273
|
+
protected ariaSortFor(column: DataTableColumn): 'ascending' | 'descending' | 'none';
|
|
1217
1274
|
/** Ciclo asc → desc → sin orden, disparado al clickear un header `sortable`. */
|
|
1218
1275
|
protected toggleSort(column: DataTableColumn): void;
|
|
1219
1276
|
protected goToPage(target: number): void;
|
|
@@ -1278,6 +1335,8 @@ declare class DataTable<T = unknown> {
|
|
|
1278
1335
|
* Con columnas `action`, la interacción la manejan esos botones.
|
|
1279
1336
|
*/
|
|
1280
1337
|
readonly cardInteractive: _angular_core.Signal<boolean>;
|
|
1338
|
+
/** Hay al menos una columna `interactive` (celdas con botón propio). */
|
|
1339
|
+
protected readonly hasInteractiveColumns: _angular_core.Signal<boolean>;
|
|
1281
1340
|
/**
|
|
1282
1341
|
* Mismo criterio que `cardInteractive`, para la vista de tabla: la fila
|
|
1283
1342
|
* entera dispara `rowClick` solo si no hay una columna `action` que ya
|
|
@@ -1287,6 +1346,13 @@ declare class DataTable<T = unknown> {
|
|
|
1287
1346
|
* consumidor lo necesita.
|
|
1288
1347
|
*/
|
|
1289
1348
|
readonly rowInteractive: _angular_core.Signal<boolean>;
|
|
1349
|
+
/**
|
|
1350
|
+
* La fila de la vista de tabla es parada de Tab solo si es interactiva,
|
|
1351
|
+
* `rowFocusable` lo permite y NO hay columnas `interactive`: con botones
|
|
1352
|
+
* propios por celda, la fila además de ellos duplicaría las paradas de Tab
|
|
1353
|
+
* (el clic de la fila sigue emitiendo `rowClick` con el mouse).
|
|
1354
|
+
*/
|
|
1355
|
+
protected readonly rowTabStop: _angular_core.Signal<boolean>;
|
|
1290
1356
|
setView(next: DataTableView): void;
|
|
1291
1357
|
trackRow(row: T, index: number): string | number;
|
|
1292
1358
|
/** Alineada al final: `align: 'end'` o el histórico `right: true`. */
|
|
@@ -1310,6 +1376,10 @@ declare class DataTable<T = unknown> {
|
|
|
1310
1376
|
* `event` es opcional para no romper llamadas programáticas existentes.
|
|
1311
1377
|
*/
|
|
1312
1378
|
onRowClick(row: T, index: number, event?: Event): void;
|
|
1379
|
+
/** Activación de una celda interactiva (clic, o Enter/Espacio sobre su botón). */
|
|
1380
|
+
protected onCellClick(row: T, column: DataTableColumn, index: number): void;
|
|
1381
|
+
/** `aria-label` del botón de una celda interactiva, o `null` si lo da su contenido. */
|
|
1382
|
+
protected cellLabel(row: T, column: DataTableColumn, index: number): string | null;
|
|
1313
1383
|
private originatesInInteractiveControl;
|
|
1314
1384
|
/**
|
|
1315
1385
|
* Ancho real de cada columna `sticky` — se mide después de cada render
|
|
@@ -1321,7 +1391,234 @@ declare class DataTable<T = unknown> {
|
|
|
1321
1391
|
*/
|
|
1322
1392
|
protected measureStickyOffsets(): void;
|
|
1323
1393
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataTable<any>, never>;
|
|
1324
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTable<any>, "kf-data-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "flush": { "alias": "flush"; "required": false; "isSignal": true; }; "cardable": { "alias": "cardable"; "required": false; "isSignal": true; }; "defaultView": { "alias": "defaultView"; "required": false; "isSignal": true; }; "showViewToggle": { "alias": "showViewToggle"; "required": false; "isSignal": true; }; "cardMinWidth": { "alias": "cardMinWidth"; "required": false; "isSignal": true; }; "render": { "alias": "render"; "required": false; "isSignal": true; }; "cellTemplates": { "alias": "cellTemplates"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "rowClickable": { "alias": "rowClickable"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "currentRowKey": { "alias": "currentRowKey"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "page": { "alias": "page"; "required": false; "isSignal": true; }; "keepPageOnRowsChange": { "alias": "keepPageOnRowsChange"; "required": false; "isSignal": true; }; "itemLabel": { "alias": "itemLabel"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "view": { "alias": "view"; "required": false; "isSignal": true; }; }, { "rowClick": "rowClick"; "page": "pageChange"; "pageSizeChange": "pageSizeChange"; "sortChange": "sortChange"; "view": "viewChange"; }, never, ["[empty]", "[footer]"], true, never>;
|
|
1394
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTable<any>, "kf-data-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "skeletonRows": { "alias": "skeletonRows"; "required": false; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "flush": { "alias": "flush"; "required": false; "isSignal": true; }; "cardable": { "alias": "cardable"; "required": false; "isSignal": true; }; "defaultView": { "alias": "defaultView"; "required": false; "isSignal": true; }; "showViewToggle": { "alias": "showViewToggle"; "required": false; "isSignal": true; }; "cardMinWidth": { "alias": "cardMinWidth"; "required": false; "isSignal": true; }; "render": { "alias": "render"; "required": false; "isSignal": true; }; "cellTemplates": { "alias": "cellTemplates"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "rowClickable": { "alias": "rowClickable"; "required": false; "isSignal": true; }; "rowFocusable": { "alias": "rowFocusable"; "required": false; "isSignal": true; }; "cellAriaLabel": { "alias": "cellAriaLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "currentRowKey": { "alias": "currentRowKey"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "page": { "alias": "page"; "required": false; "isSignal": true; }; "keepPageOnRowsChange": { "alias": "keepPageOnRowsChange"; "required": false; "isSignal": true; }; "itemLabel": { "alias": "itemLabel"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "view": { "alias": "view"; "required": false; "isSignal": true; }; }, { "rowClick": "rowClick"; "cellClick": "cellClick"; "page": "pageChange"; "pageSizeChange": "pageSizeChange"; "sortChange": "sortChange"; "view": "viewChange"; }, never, ["[empty]", "[footer]"], true, never>;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
/** Forma de contenido que reproduce el preset. */
|
|
1398
|
+
type SkeletonPresetVariant = 'kpi-grid' | 'card-grid' | 'form' | 'list' | 'table' | 'timeline' | 'detail-header';
|
|
1399
|
+
/** Tope de elementos: un `count` mayor se acota, no tiene sentido pintar más. */
|
|
1400
|
+
declare const SKELETON_PRESET_MAX_COUNT = 12;
|
|
1401
|
+
/**
|
|
1402
|
+
* Esqueletos listos para usar que reproducen la FORMA del contenido real, para
|
|
1403
|
+
* que al llegar los datos nada se mueva. Cada variante se arma con la misma
|
|
1404
|
+
* geometría que su equivalente cargado (mismos cascarones, alturas, radios y
|
|
1405
|
+
* gaps, todo por tokens):
|
|
1406
|
+
*
|
|
1407
|
+
* | `variant` | Equivalente cargado | `count` | `columns` |
|
|
1408
|
+
* | ---------------- | ---------------------------- | -------------- | ------------------ |
|
|
1409
|
+
* | `kpi-grid` | `kf-stat-card` | tarjetas (4) | columnas de la grilla |
|
|
1410
|
+
* | `card-grid` | `kf-card` | tarjetas (6) | columnas de la grilla |
|
|
1411
|
+
* | `form` | `kf-input` con label | campos (4) | `1` o `2` |
|
|
1412
|
+
* | `list` | `kf-document-row` | filas (4) | — |
|
|
1413
|
+
* | `table` | `kf-data-table` | filas (5) | columnas (4) |
|
|
1414
|
+
* | `timeline` | `kf-milestone-timeline` | etapas (4) | — |
|
|
1415
|
+
* | `detail-header` | `kf-page-header` con ícono | — | — |
|
|
1416
|
+
*
|
|
1417
|
+
* Sin `columns`, las grillas (`kpi-grid`, `card-grid`) se reparten solas con un
|
|
1418
|
+
* ancho mínimo por tarjeta. `count` se acota a 12.
|
|
1419
|
+
*
|
|
1420
|
+
* El preset es decorativo (`aria-hidden` por dentro) y marca su contenedor con
|
|
1421
|
+
* `aria-busy="true"`. Con `label` agrega un texto visualmente oculto con
|
|
1422
|
+
* `role="status"` que lo anuncia a lectores de pantalla; dentro de
|
|
1423
|
+
* `kf-content-state` no hace falta (ya lo anuncia él).
|
|
1424
|
+
*
|
|
1425
|
+
* <kf-skeleton-preset variant="kpi-grid" [count]="4" />
|
|
1426
|
+
* <kf-skeleton-preset variant="form" [count]="3" [columns]="2" label="Cargando formulario" />
|
|
1427
|
+
* <kf-content-state [state]="state()" loadingPreset="table">…</kf-content-state>
|
|
1428
|
+
*/
|
|
1429
|
+
declare class SkeletonPreset {
|
|
1430
|
+
readonly variant: _angular_core.InputSignal<SkeletonPresetVariant>;
|
|
1431
|
+
/** Cantidad de elementos. Sin valor, el de la variante. Máximo 12. */
|
|
1432
|
+
readonly count: _angular_core.InputSignal<number | undefined>;
|
|
1433
|
+
/** Columnas: de la grilla (`kpi-grid`, `card-grid`), del formulario (`1`|`2`) o de la tabla. */
|
|
1434
|
+
readonly columns: _angular_core.InputSignal<number | undefined>;
|
|
1435
|
+
/** Texto accesible (visualmente oculto, `role="status"`). Vacío, no se emite. */
|
|
1436
|
+
readonly label: _angular_core.InputSignal<string>;
|
|
1437
|
+
protected readonly total: _angular_core.Signal<number>;
|
|
1438
|
+
protected readonly items: _angular_core.Signal<number[]>;
|
|
1439
|
+
/** Columnas de la tabla sintética (encabezados en blanco: lo real aún no llegó). */
|
|
1440
|
+
protected readonly tableColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1441
|
+
protected readonly formColumns: _angular_core.Signal<2 | 1>;
|
|
1442
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SkeletonPreset, never>;
|
|
1443
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SkeletonPreset, "kf-skeleton-preset", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "count": { "alias": "count"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
/** En qué estado está la sección. */
|
|
1447
|
+
type ContentStateKind = 'ready' | 'loading' | 'empty' | 'error';
|
|
1448
|
+
/** Cómo se dibuja `loading`. Default `'skeleton'`. */
|
|
1449
|
+
type ContentStateLoad = 'skeleton' | 'spinner';
|
|
1450
|
+
/**
|
|
1451
|
+
* Marca el `ng-template` que reemplaza el esqueleto genérico de
|
|
1452
|
+
* `kf-content-state` mientras carga (`state="loading"`, `load="skeleton"`).
|
|
1453
|
+
*
|
|
1454
|
+
* <kf-content-state [state]="state()">
|
|
1455
|
+
* <ng-template kfContentStateLoading><kf-skeleton-preset variant="kpi-grid" /></ng-template>
|
|
1456
|
+
* …
|
|
1457
|
+
* </kf-content-state>
|
|
1458
|
+
*/
|
|
1459
|
+
declare class ContentStateLoading {
|
|
1460
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentStateLoading, never>;
|
|
1461
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ContentStateLoading, "ng-template[kfContentStateLoading]", never, {}, {}, never, never, true, never>;
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Wrapper de los cuatro estados que toda sección tiene: cargando, con datos,
|
|
1465
|
+
* vacía y con error. Un componente en vez de tres `@if` sueltos, porque es
|
|
1466
|
+
* siempre el mismo slot el que va rotando entre los cuatro.
|
|
1467
|
+
*
|
|
1468
|
+
* Con `state="ready"` proyecta el contenido real y desaparece; en los otros
|
|
1469
|
+
* tres dibuja el placeholder correspondiente y el contenido no se instancia.
|
|
1470
|
+
* No inventa visuales propios: `loading` usa `kf-skeleton` (o `kf-spinner` con
|
|
1471
|
+
* `load="spinner"`), y `empty`/`error` usan `kf-empty-state`.
|
|
1472
|
+
*
|
|
1473
|
+
* Las acciones (reintentar, crear) van en el slot `actions` — se ignoran
|
|
1474
|
+
* mientras carga, porque no hay nada que reintentar todavía.
|
|
1475
|
+
*
|
|
1476
|
+
* Anuncios para lectores de pantalla: al cargar con silueta, `loadingLabel`
|
|
1477
|
+
* se anuncia en una región `status` (con `load="spinner"` ya lo anuncia el
|
|
1478
|
+
* propio `kf-spinner`); un error entra como `role="alert"` (interrumpe) y el
|
|
1479
|
+
* estado vacío como `role="status"` (cortés). `icon` dibuja el glifo de
|
|
1480
|
+
* `kf-empty-state` en esos dos estados.
|
|
1481
|
+
*
|
|
1482
|
+
* <kf-content-state [state]="state()" title="No pudimos cargar tus vehículos"
|
|
1483
|
+
* subtitle="Revisá tu conexión e intentá de nuevo.">
|
|
1484
|
+
* <kf-button actions (click)="retry()">Reintentar</kf-button>
|
|
1485
|
+
* <kf-data-table [columns]="cols" [rows]="rows()" />
|
|
1486
|
+
* </kf-content-state>
|
|
1487
|
+
*
|
|
1488
|
+
* Esqueleto de carga: por defecto son tres líneas genéricas. Para que la
|
|
1489
|
+
* carga se parezca a lo que va a aparecer, hay tres vías (de la más corta a la
|
|
1490
|
+
* más libre): `loadingPreset` (una variante de `kf-skeleton-preset`), el input
|
|
1491
|
+
* `loadingTemplate` (un `TemplateRef`) o un `ng-template` marcado con
|
|
1492
|
+
* `kfContentStateLoading` dentro del contenido. Si hay más de una, gana la
|
|
1493
|
+
* plantilla proyectada, luego `loadingTemplate` y por último `loadingPreset`.
|
|
1494
|
+
*
|
|
1495
|
+
* <kf-content-state [state]="state()" loadingPreset="kpi-grid">…</kf-content-state>
|
|
1496
|
+
*
|
|
1497
|
+
* Accesibilidad: en modo skeleton el contenedor lleva `aria-busy="true"` y un
|
|
1498
|
+
* texto visualmente oculto con `role="status"` (`loadingLabel`, "Cargando…" por
|
|
1499
|
+
* defecto) que anuncia el estado una vez. Con `load="spinner"` el texto es el
|
|
1500
|
+
* del propio `kf-spinner`. El contenedor reserva un ancho mínimo, así que el
|
|
1501
|
+
* esqueleto no colapsa a 0 dentro de un padre que se ajusta a su contenido.
|
|
1502
|
+
*/
|
|
1503
|
+
declare class ContentState {
|
|
1504
|
+
readonly state: _angular_core.InputSignal<ContentStateKind>;
|
|
1505
|
+
/** Forma del estado de carga: silueta (default) o spinner. */
|
|
1506
|
+
readonly load: _angular_core.InputSignal<ContentStateLoad>;
|
|
1507
|
+
/** Título de `empty`/`error`. Ignorado mientras carga. */
|
|
1508
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
1509
|
+
readonly subtitle: _angular_core.InputSignal<string>;
|
|
1510
|
+
/** Glifo de `empty`/`error` (el mismo input de `kf-empty-state`). Sin valor, no se dibuja ícono. */
|
|
1511
|
+
readonly icon: _angular_core.InputSignal<IconName | undefined>;
|
|
1512
|
+
/** Texto de carga: visible al lado del spinner con `load="spinner"` y, en modo
|
|
1513
|
+
* skeleton, texto visualmente oculto con `role="status"` para lectores de pantalla. */
|
|
1514
|
+
readonly loadingLabel: _angular_core.InputSignal<string>;
|
|
1515
|
+
/** Plantilla propia del esqueleto (reemplaza las tres líneas genéricas). */
|
|
1516
|
+
readonly loadingTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
1517
|
+
/** Variante de `kf-skeleton-preset` como esqueleto de carga. */
|
|
1518
|
+
readonly loadingPreset: _angular_core.InputSignal<SkeletonPresetVariant | null>;
|
|
1519
|
+
/** `ng-template[kfContentStateLoading]` proyectado como contenido. */
|
|
1520
|
+
protected readonly projectedLoading: _angular_core.Signal<TemplateRef<any> | undefined>;
|
|
1521
|
+
protected readonly customLoading: _angular_core.Signal<TemplateRef<any> | null>;
|
|
1522
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentState, never>;
|
|
1523
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentState, "kf-content-state", never, { "state": { "alias": "state"; "required": true; "isSignal": true; }; "load": { "alias": "load"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; "isSignal": true; }; "loadingTemplate": { "alias": "loadingTemplate"; "required": false; "isSignal": true; }; "loadingPreset": { "alias": "loadingPreset"; "required": false; "isSignal": true; }; }, {}, ["projectedLoading"], ["*", "[actions]"], true, never>;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
type ContentViewerType = 'image' | 'video' | 'pdf';
|
|
1527
|
+
/**
|
|
1528
|
+
* Visor a pantalla completa para ampliar una pieza de contenido: imagen,
|
|
1529
|
+
* video o PDF (`type="pdf"`, renderizado por el visor nativo del navegador).
|
|
1530
|
+
* Mismo mecanismo que `kf-modal` (el `<dialog>` nativo resuelve backdrop,
|
|
1531
|
+
* atrapado de foco, top-layer y `Escape`), pero sin panel/título/footer:
|
|
1532
|
+
* el contenido ocupa toda la pantalla sobre un backdrop oscuro.
|
|
1533
|
+
*
|
|
1534
|
+
* `src` acepta lo que venga del backend sin que el consumidor tenga que
|
|
1535
|
+
* normalizarlo primero: una URL (`http(s)://`), un data URI ya armado
|
|
1536
|
+
* (`data:...`), o base64 crudo (se le antepone el prefijo `data:` según
|
|
1537
|
+
* `type`, asumiendo JPEG para imagen, MP4 para video y PDF para pdf). Un PDF
|
|
1538
|
+
* solo acepta contenido local (`blob:`, data URI o base64), nunca una URL remota.
|
|
1539
|
+
*
|
|
1540
|
+
* Lo proyectado con el atributo `actions` (p. ej. un botón de descarga) va en
|
|
1541
|
+
* la barra superior, junto al título.
|
|
1542
|
+
*
|
|
1543
|
+
* <kf-content-viewer [(open)]="viewerOpen" [src]="viewerSrc()" alt="Foto del vehículo" />
|
|
1544
|
+
* <kf-content-viewer [(open)]="viewerOpen" type="video" [src]="viewerSrc()" title="Inspección" />
|
|
1545
|
+
* <kf-content-viewer [(open)]="viewerOpen" type="pdf" [src]="blobUrl()" title="Contrato">
|
|
1546
|
+
* <kf-button actions variant="surface" icon="download" (click)="save()">Descargar</kf-button>
|
|
1547
|
+
* </kf-content-viewer>
|
|
1548
|
+
*/
|
|
1549
|
+
declare class ContentViewer {
|
|
1550
|
+
readonly type: _angular_core.InputSignal<ContentViewerType>;
|
|
1551
|
+
/** URL, data URI, o base64 crudo — ver JSDoc de la clase. */
|
|
1552
|
+
readonly src: _angular_core.InputSignal<string | null>;
|
|
1553
|
+
/** Texto alternativo cuando `type="image"`. */
|
|
1554
|
+
readonly alt: _angular_core.InputSignal<string>;
|
|
1555
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
1556
|
+
/** Visibilidad, two-way: `[(open)]="viewerOpen"`. */
|
|
1557
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
1558
|
+
/** Permite cerrar con el botón, `Escape` o clic en el backdrop. */
|
|
1559
|
+
readonly dismissible: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1560
|
+
protected readonly titleId: string;
|
|
1561
|
+
/** Detecta si `src` ya es una URL o un data URI armado; si no, asume
|
|
1562
|
+
* base64 crudo y le antepone el prefijo `data:` correspondiente a `type`
|
|
1563
|
+
* — el backend a veces manda una cosa, a veces la otra. */
|
|
1564
|
+
protected readonly resolvedSrc: _angular_core.Signal<string | null>;
|
|
1565
|
+
protected readonly pdfSrc: _angular_core.Signal<SafeResourceUrl | null>;
|
|
1566
|
+
protected readonly fallbackLabel: _angular_core.Signal<string>;
|
|
1567
|
+
private readonly dialog;
|
|
1568
|
+
private readonly document;
|
|
1569
|
+
private readonly sanitizer;
|
|
1570
|
+
constructor();
|
|
1571
|
+
/** `Escape` dispara `cancel`; cancelarlo lo deja abierto. */
|
|
1572
|
+
protected onCancel(event: Event): void;
|
|
1573
|
+
/**
|
|
1574
|
+
* Clic en el backdrop. Un clic en la zona del backdrop tiene como `target` al
|
|
1575
|
+
* propio `<dialog>` (el contenido vive en el panel de adentro), así que basta
|
|
1576
|
+
* comparar contra él — no hace falta cortar la propagación en el panel.
|
|
1577
|
+
*/
|
|
1578
|
+
protected onHostClick(event: MouseEvent): void;
|
|
1579
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentViewer, never>;
|
|
1580
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentViewer, "kf-content-viewer", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "src": { "alias": "src"; "required": false; "isSignal": true; }; "alt": { "alias": "alt"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[actions]"], true, never>;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
/**
|
|
1584
|
+
* Paginador «Anterior / Siguiente» para listas con cursor: no conoce el
|
|
1585
|
+
* número de página, solo si hay una anterior o una siguiente y un resumen ya
|
|
1586
|
+
* armado. Complementa a `kf-pagination`, que exige número de página y total.
|
|
1587
|
+
*
|
|
1588
|
+
* `summary` ("Mostrando 25 de 96") se anuncia en una región `status`. Los
|
|
1589
|
+
* botones usan `aria-disabled` y no `disabled`, para que el foco no se pierda
|
|
1590
|
+
* al llegar a un extremo (un botón `disabled` deja de ser enfocable y el foco
|
|
1591
|
+
* cae al `body`); pulsarlos en ese estado no emite nada.
|
|
1592
|
+
*
|
|
1593
|
+
* Con `pageSizeOptions` agrega el selector "Filas por página"; vacío lo oculta.
|
|
1594
|
+
*
|
|
1595
|
+
* <kf-cursor-pager summary="Mostrando 25 de 96" [hasPrevious]="!!prev()" [hasNext]="!!next()"
|
|
1596
|
+
* [pageSizeOptions]="[25, 50, 100]" [pageSize]="size()"
|
|
1597
|
+
* (previous)="load(prev())" (next)="load(next())" (pageSizeChange)="size.set($event)" />
|
|
1598
|
+
*/
|
|
1599
|
+
declare class CursorPager {
|
|
1600
|
+
/** Texto anunciado y mostrado a la izquierda, p. ej. «Mostrando 25 de 96». */
|
|
1601
|
+
readonly summary: _angular_core.InputSignal<string>;
|
|
1602
|
+
readonly hasPrevious: _angular_core.InputSignal<boolean>;
|
|
1603
|
+
readonly hasNext: _angular_core.InputSignal<boolean>;
|
|
1604
|
+
/** Opciones del selector de filas por página. Vacío oculta el selector. */
|
|
1605
|
+
readonly pageSizeOptions: _angular_core.InputSignal<readonly number[]>;
|
|
1606
|
+
readonly pageSize: _angular_core.InputSignal<number | undefined>;
|
|
1607
|
+
/** Nombre accesible de la navegación. */
|
|
1608
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
1609
|
+
readonly previous: _angular_core.OutputEmitterRef<void>;
|
|
1610
|
+
readonly next: _angular_core.OutputEmitterRef<void>;
|
|
1611
|
+
readonly pageSizeChange: _angular_core.OutputEmitterRef<number>;
|
|
1612
|
+
protected readonly sizeOptions: _angular_core.Signal<{
|
|
1613
|
+
value: string;
|
|
1614
|
+
label: string;
|
|
1615
|
+
}[]>;
|
|
1616
|
+
protected readonly sizeValue: _angular_core.Signal<string>;
|
|
1617
|
+
protected onPrevious(): void;
|
|
1618
|
+
protected onNext(): void;
|
|
1619
|
+
protected onPageSize(value: string): void;
|
|
1620
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<CursorPager, never>;
|
|
1621
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<CursorPager, "kf-cursor-pager", never, { "summary": { "alias": "summary"; "required": false; "isSignal": true; }; "hasPrevious": { "alias": "hasPrevious"; "required": false; "isSignal": true; }; "hasNext": { "alias": "hasNext"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "previous": "previous"; "next": "next"; "pageSizeChange": "pageSizeChange"; }, never, never, true, never>;
|
|
1325
1622
|
}
|
|
1326
1623
|
|
|
1327
1624
|
/**
|
|
@@ -1367,6 +1664,14 @@ type DocumentRowTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';
|
|
|
1367
1664
|
* título, metadata y la acción de descarga al final. Sin `href` rinde
|
|
1368
1665
|
* `pendingLabel` en vez de un link roto. El contenido proyectado cae entre
|
|
1369
1666
|
* la metadata y la acción, como slot para un `kf-badge` de estado.
|
|
1667
|
+
*
|
|
1668
|
+
* `loading` (default `false`): dibuja el esqueleto de la fila — chip, título,
|
|
1669
|
+
* metadata y acción como bloques del alto real de cada texto — con el mismo
|
|
1670
|
+
* cascarón, así que al llegar los datos no hay salto de layout. Pasa los
|
|
1671
|
+
* mismos inputs que usarás cargada (`meta` incluido, para reservar su línea).
|
|
1672
|
+
* Marca el host con `aria-busy="true"` y oculta el contenido proyectado.
|
|
1673
|
+
*
|
|
1674
|
+
* <kf-document-row title="Factura" meta="PDF · 120 KB" [loading]="isLoading()" />
|
|
1370
1675
|
*/
|
|
1371
1676
|
declare class DocumentRow {
|
|
1372
1677
|
readonly icon: _angular_core.InputSignal<IconName>;
|
|
@@ -1382,8 +1687,10 @@ declare class DocumentRow {
|
|
|
1382
1687
|
readonly downloadLabel: _angular_core.InputSignal<string>;
|
|
1383
1688
|
/** Qué se dice cuando no hay `href`. */
|
|
1384
1689
|
readonly pendingLabel: _angular_core.InputSignal<string>;
|
|
1690
|
+
/** Dibuja el esqueleto en lugar del contenido, conservando las dimensiones. */
|
|
1691
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1385
1692
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DocumentRow, never>;
|
|
1386
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DocumentRow, "kf-document-row", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "downloadLabel": { "alias": "downloadLabel"; "required": false; "isSignal": true; }; "pendingLabel": { "alias": "pendingLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1693
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DocumentRow, "kf-document-row", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "downloadLabel": { "alias": "downloadLabel"; "required": false; "isSignal": true; }; "pendingLabel": { "alias": "pendingLabel"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; }, {}, never, ["*", "*"], true, never>;
|
|
1387
1694
|
}
|
|
1388
1695
|
|
|
1389
1696
|
/** Borde de anclaje del panel. `bottom` es una hoja inferior (bottom sheet). */
|
|
@@ -1447,8 +1754,9 @@ type DrawerRole = 'navigation' | 'dialog';
|
|
|
1447
1754
|
* redondeadas, alto máximo 80vh) — pensado para un resumen en mobile.
|
|
1448
1755
|
*
|
|
1449
1756
|
* Escape cierra el panel salvo que un control interno ya haya consumido la
|
|
1450
|
-
* tecla (`event.defaultPrevented
|
|
1451
|
-
* drawer cierra
|
|
1757
|
+
* tecla (`event.defaultPrevented`): un `kf-select`, `kf-multi-select` o
|
|
1758
|
+
* `kf-dropdown` abierto dentro del drawer cierra primero su propio panel y
|
|
1759
|
+
* un segundo Escape cierra el drawer.
|
|
1452
1760
|
*
|
|
1453
1761
|
* Nombres por defecto: con `role="navigation"` el panel se llama "Menú" y
|
|
1454
1762
|
* el cierre "Cerrar menú" (comportamiento histórico). Con `role="dialog"`
|
|
@@ -1456,12 +1764,25 @@ type DrawerRole = 'navigation' | 'dialog';
|
|
|
1456
1764
|
* avisa por consola si no hay `title` ni `ariaLabel`: un diálogo sin nombre
|
|
1457
1765
|
* propio no le dice nada al lector de pantalla.
|
|
1458
1766
|
*
|
|
1459
|
-
*
|
|
1460
|
-
*
|
|
1461
|
-
*
|
|
1462
|
-
*
|
|
1463
|
-
*
|
|
1464
|
-
*
|
|
1767
|
+
* ## Selectores y otros paneles flotantes dentro del drawer
|
|
1768
|
+
*
|
|
1769
|
+
* `kf-select`, `kf-multi-select` y `kf-dropdown` funcionan
|
|
1770
|
+
* dentro de un drawer (incluido el pie `[kf-drawer-footer]`): sus paneles
|
|
1771
|
+
* quedan por encima del drawer, se abren hacia arriba si abajo no hay lugar
|
|
1772
|
+
* y no se cortan con el borde del panel ni con el scroll del cuerpo. Con
|
|
1773
|
+
* `role="dialog"` el contenedor de overlays de CDK se reubica dentro del
|
|
1774
|
+
* panel mientras está abierto: el listbox queda dentro del diálogo
|
|
1775
|
+
* `aria-modal`, no fuera de él, y el atrapado de foco lo incluye. Al cerrar
|
|
1776
|
+
* el drawer vuelve a `<body>`. Escape cierra primero el panel flotante
|
|
1777
|
+
* (devolviendo el foco a su disparador) y el siguiente cierra el drawer.
|
|
1778
|
+
*
|
|
1779
|
+
* <kf-drawer [(open)]="open" role="dialog" side="right" title="Unidad VIN-1003">
|
|
1780
|
+
* ...
|
|
1781
|
+
* <div kf-drawer-footer>
|
|
1782
|
+
* <kf-select label="Saltar a otra unidad" width="full"
|
|
1783
|
+
* [options]="units" [value]="unit()" (valueChange)="unit.set($event)" />
|
|
1784
|
+
* </div>
|
|
1785
|
+
* </kf-drawer>
|
|
1465
1786
|
*
|
|
1466
1787
|
* Al cerrar, el foco vuelve al elemento que lo tenía al abrir solo si sigue
|
|
1467
1788
|
* en el documento (`isConnected`); si fue desmontado mientras el drawer
|
|
@@ -1494,6 +1815,8 @@ declare class Drawer {
|
|
|
1494
1815
|
private readonly panelRef;
|
|
1495
1816
|
private readonly focusTrapFactory;
|
|
1496
1817
|
private readonly document;
|
|
1818
|
+
private readonly overlayContainer;
|
|
1819
|
+
private registeredPanel;
|
|
1497
1820
|
private focusTrap;
|
|
1498
1821
|
private lastFocusedElement;
|
|
1499
1822
|
constructor();
|
|
@@ -1517,6 +1840,19 @@ declare class Drawer {
|
|
|
1517
1840
|
* de anclaje visual del panel.
|
|
1518
1841
|
*
|
|
1519
1842
|
* <kf-dropdown [(open)]="menuOpen"><kf-dropdown-panel>...</kf-dropdown-panel></kf-dropdown>
|
|
1843
|
+
*
|
|
1844
|
+
* Accesibilidad. Disparador: el primer control enfocable del `anchor` (o del
|
|
1845
|
+
* propio host) recibe `aria-haspopup` (`menu` o `dialog`, según el `role` del
|
|
1846
|
+
* panel), `aria-expanded` y, con el panel abierto, `aria-controls`; un atributo
|
|
1847
|
+
* que el consumidor ya declaró nunca se pisa. Foco: el panel vive en un overlay
|
|
1848
|
+
* al final del `body`, así que al abrir el foco pasa al primer elemento
|
|
1849
|
+
* enfocable del panel (`autoFocus`, default `true`; solo si el foco estaba en
|
|
1850
|
+
* el disparador, para no robarlo cuando algo abre el panel por código), y al
|
|
1851
|
+
* cerrar vuelve al disparador si estaba dentro del panel (Escape, elegir una
|
|
1852
|
+
* acción, aplicar). Un clic afuera no devuelve el foco: ya se fue a donde se
|
|
1853
|
+
* hizo clic. Con `role="menu"` las flechas, Home y End recorren los ítems. Tab
|
|
1854
|
+
* desde el último (o Shift+Tab desde el primero) cierra el panel y continúa la
|
|
1855
|
+
* tabulación desde el disparador.
|
|
1520
1856
|
*/
|
|
1521
1857
|
declare class Dropdown {
|
|
1522
1858
|
/** Visibilidad del panel, two-way: `[(open)]="menuOpen"`. */
|
|
@@ -1529,11 +1865,20 @@ declare class Dropdown {
|
|
|
1529
1865
|
* (ej. el avatar de sesión dentro de `PortalHeader`).
|
|
1530
1866
|
*/
|
|
1531
1867
|
readonly anchor: _angular_core.InputSignal<ElementRef<HTMLElement> | undefined>;
|
|
1868
|
+
/**
|
|
1869
|
+
* Mueve el foco al primer elemento enfocable del panel al abrirlo. Poner
|
|
1870
|
+
* `false` si el contenido ya gestiona su propio foco inicial.
|
|
1871
|
+
*/
|
|
1872
|
+
readonly autoFocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1532
1873
|
private readonly panel;
|
|
1533
1874
|
private readonly overlayService;
|
|
1534
1875
|
private readonly host;
|
|
1535
1876
|
private readonly viewContainerRef;
|
|
1536
1877
|
private readonly destroyRef;
|
|
1878
|
+
private readonly injector;
|
|
1879
|
+
private readonly document;
|
|
1880
|
+
/** Atributos ARIA que este componente puso en el disparador (y por tanto retira él). */
|
|
1881
|
+
private readonly ownedTriggerAttributes;
|
|
1537
1882
|
private overlayRef;
|
|
1538
1883
|
/**
|
|
1539
1884
|
* Suscripciones a `outsidePointerEvents()`/`keydownEvents()` del overlay
|
|
@@ -1549,10 +1894,28 @@ declare class Dropdown {
|
|
|
1549
1894
|
* Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo
|
|
1550
1895
|
* ve teclas con el foco DENTRO del panel. Si el foco queda en el botón
|
|
1551
1896
|
* disparador (caso común), `keydownEvents()` nunca dispara — este
|
|
1552
|
-
* listener a nivel de documento cubre ese caso.
|
|
1897
|
+
* listener a nivel de documento cubre ese caso. Va en fase de captura
|
|
1898
|
+
* (ver `listenEscapeCapture`) y consume la tecla solo si había un menú
|
|
1899
|
+
* abierto, así un `kf-drawer`/`kf-modal` contenedor no se cierra con el
|
|
1900
|
+
* mismo Escape. Devuelve si cerró algo.
|
|
1553
1901
|
*/
|
|
1554
|
-
onDocumentEscape():
|
|
1902
|
+
onDocumentEscape(): boolean;
|
|
1555
1903
|
private attach;
|
|
1904
|
+
/** Flechas/Home/End entre ítems (solo `role="menu"`) y salida con Tab en los extremos. */
|
|
1905
|
+
private onPanelKeydown;
|
|
1906
|
+
private focusFirstInPanel;
|
|
1907
|
+
private focusableIn;
|
|
1908
|
+
private isFocusOnTrigger;
|
|
1909
|
+
/**
|
|
1910
|
+
* Control que abre el panel: el propio `anchor`/host si ya es enfocable, o
|
|
1911
|
+
* su primer descendiente enfocable (ej. el `<button>` dentro de `kf-button`).
|
|
1912
|
+
*/
|
|
1913
|
+
private triggerElement;
|
|
1914
|
+
private syncTriggerAria;
|
|
1915
|
+
/** Escribe el atributo solo si no es del consumidor (ausente, o ya puesto por este componente). */
|
|
1916
|
+
private setOwnedAttribute;
|
|
1917
|
+
private removeOwnedAttribute;
|
|
1918
|
+
private releaseTriggerAria;
|
|
1556
1919
|
/**
|
|
1557
1920
|
* El trigger real (el `anchor`, o el propio host si no se pasó ninguno —
|
|
1558
1921
|
* ver comentario de la clase) vive FUERA del overlay a propósito: el
|
|
@@ -1566,7 +1929,7 @@ declare class Dropdown {
|
|
|
1566
1929
|
private detach;
|
|
1567
1930
|
private getOrCreateOverlayRef;
|
|
1568
1931
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Dropdown, never>;
|
|
1569
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Dropdown, "kf-dropdown", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "anchor": { "alias": "anchor"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, ["panel"], ["*"], true, never>;
|
|
1932
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Dropdown, "kf-dropdown", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "anchor": { "alias": "anchor"; "required": false; "isSignal": true; }; "autoFocus": { "alias": "autoFocus"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, ["panel"], ["*"], true, never>;
|
|
1570
1933
|
}
|
|
1571
1934
|
|
|
1572
1935
|
type DropdownItemTone = 'neutral' | 'error';
|
|
@@ -1594,6 +1957,8 @@ declare class DropdownItem {
|
|
|
1594
1957
|
}
|
|
1595
1958
|
|
|
1596
1959
|
type DropdownPanelVariant = 'solid' | 'dark';
|
|
1960
|
+
/** Rol del contenedor del panel: `menu` (ítems de acción) o `dialog` (contenido de formulario o informativo). */
|
|
1961
|
+
type DropdownPanelRole = 'menu' | 'dialog';
|
|
1597
1962
|
/**
|
|
1598
1963
|
* Contenido del panel flotante de un `kf-dropdown`. Es solo una plantilla
|
|
1599
1964
|
* (`<ng-template>`, capturada vía `TemplateRef`) — `Dropdown` la conecta al
|
|
@@ -1609,12 +1974,24 @@ type DropdownPanelVariant = 'solid' | 'dark';
|
|
|
1609
1974
|
* reposiciona el panel según dónde entra en el viewport y puede terminar
|
|
1610
1975
|
* cayendo sobre fondo blanco en vez de sobre el rail oscuro — un color
|
|
1611
1976
|
* sólido se ve intencional sin importar dónde lo posicione el CDK.
|
|
1977
|
+
*
|
|
1978
|
+
* `role`: `'menu'` (default) cuando el contenido son `kf-dropdown-item`;
|
|
1979
|
+
* `'dialog'` cuando lleva campos de formulario, selects, casillas o texto
|
|
1980
|
+
* libre — un `role="menu"` solo admite ítems de menú como hijos. Un panel
|
|
1981
|
+
* `dialog` necesita nombre: pasar `ariaLabel`.
|
|
1982
|
+
*
|
|
1983
|
+
* <kf-dropdown-panel role="dialog" ariaLabel="Filtros">…</kf-dropdown-panel>
|
|
1612
1984
|
*/
|
|
1613
1985
|
declare class DropdownPanel {
|
|
1614
1986
|
readonly variant: _angular_core.InputSignal<DropdownPanelVariant>;
|
|
1987
|
+
readonly role: _angular_core.InputSignal<DropdownPanelRole>;
|
|
1988
|
+
/** Nombre accesible del panel (obligatorio en la práctica con `role="dialog"`). */
|
|
1989
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
1990
|
+
/** `id` del contenedor con el rol; el disparador lo referencia con `aria-controls`. */
|
|
1991
|
+
readonly panelId: string;
|
|
1615
1992
|
readonly templateRef: _angular_core.Signal<TemplateRef<any>>;
|
|
1616
1993
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DropdownPanel, never>;
|
|
1617
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownPanel, "kf-dropdown-panel", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1994
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownPanel, "kf-dropdown-panel", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "role": { "alias": "role"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1618
1995
|
}
|
|
1619
1996
|
|
|
1620
1997
|
/** Tono del estado. `warn`/`info` solo cambian el chip del ícono. */
|
|
@@ -1671,7 +2048,7 @@ declare class EmptyState {
|
|
|
1671
2048
|
/** `neutral` (default): cero resultados. `error`: fallo real de carga. `warn`/`info`: tiñen el chip del ícono. */
|
|
1672
2049
|
readonly tone: _angular_core.InputSignal<EmptyStateTone>;
|
|
1673
2050
|
/** `inline` (default, histórico) o `card` (tarjeta centrada). Ver JSDoc de la clase. */
|
|
1674
|
-
readonly variant: _angular_core.InputSignal<"
|
|
2051
|
+
readonly variant: _angular_core.InputSignal<"card" | "inline">;
|
|
1675
2052
|
/** Título destacado sobre el contenido. Opcional en ambas variantes. */
|
|
1676
2053
|
readonly title: _angular_core.InputSignal<string | undefined>;
|
|
1677
2054
|
protected readonly iconSize: _angular_core.Signal<IconSize>;
|
|
@@ -1781,14 +2158,141 @@ declare class Field {
|
|
|
1781
2158
|
*
|
|
1782
2159
|
* <kf-field-label [for]="inputId">Patente o VIN</kf-field-label>
|
|
1783
2160
|
* <kf-field-label [for]="inputId" required>Correo electrónico</kf-field-label>
|
|
2161
|
+
*
|
|
2162
|
+
* `visuallyHidden` deja el texto solo para lectores de pantalla: el `<label
|
|
2163
|
+
* for>` sigue nombrando el control sin ocupar espacio.
|
|
1784
2164
|
*/
|
|
1785
2165
|
declare class FieldLabel {
|
|
1786
2166
|
/** `id` del control asociado — se refleja como `for` en el `<label>` interno. */
|
|
1787
2167
|
readonly for: _angular_core.InputSignal<string | undefined>;
|
|
1788
2168
|
/** Muestra un asterisco visual indicando que el campo es obligatorio. */
|
|
1789
2169
|
readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2170
|
+
/** Oculta el texto a la vista pero lo conserva como nombre accesible del control. */
|
|
2171
|
+
readonly visuallyHidden: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1790
2172
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldLabel, never>;
|
|
1791
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FieldLabel, "kf-field-label", never, { "for": { "alias": "for"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
2173
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FieldLabel, "kf-field-label", never, { "for": { "alias": "for"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "visuallyHidden": { "alias": "visuallyHidden"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
/** Por qué se descartó un archivo: formato fuera de `accept` o más grande que `maxSize`. */
|
|
2177
|
+
type FileRejectionReason = 'type' | 'size';
|
|
2178
|
+
/** Un archivo descartado y el motivo. */
|
|
2179
|
+
interface FileRejection {
|
|
2180
|
+
file: File;
|
|
2181
|
+
reason: FileRejectionReason;
|
|
2182
|
+
}
|
|
2183
|
+
/** Tamaño en bytes como texto (`5 MB`, `120 KB`), base 1024. */
|
|
2184
|
+
declare function formatFileSize(bytes: number): string;
|
|
2185
|
+
/**
|
|
2186
|
+
* Selector de archivo accesible, con la misma apariencia y contrato de campo
|
|
2187
|
+
* que `kf-input`: label arriba, ayuda y error debajo, `invalid`.
|
|
2188
|
+
*
|
|
2189
|
+
* El control real es un `<input type="file">` nativo, visualmente oculto pero
|
|
2190
|
+
* enfocable: se llega con Tab, se abre con Enter o Espacio y el anillo de foco
|
|
2191
|
+
* se dibuja sobre el botón visible. Su nombre accesible es el `label` (o
|
|
2192
|
+
* `ariaLabel`); la ayuda, el archivo elegido y el error lo describen
|
|
2193
|
+
* (`aria-describedby`).
|
|
2194
|
+
*
|
|
2195
|
+
* **Ayuda antes de elegir.** `hint` es texto libre; si no se pasa, se arma sola
|
|
2196
|
+
* con los formatos de `accept` y el tamaño de `maxSize` (`PDF, JPG · máx. 5 MB`),
|
|
2197
|
+
* para que el usuario sepa qué sirve ANTES de abrir el selector.
|
|
2198
|
+
*
|
|
2199
|
+
* **Validación.** Cada archivo se revisa contra `accept` (extensiones `.pdf`,
|
|
2200
|
+
* tipos `image/png` o comodines `image/*`) y `maxSize` (bytes). Los válidos
|
|
2201
|
+
* quedan elegidos y se emiten en `fileChange` (siempre `File[]`, vacío al
|
|
2202
|
+
* quitar); los descartados se emiten uno a uno en `fileRejected` con su
|
|
2203
|
+
* motivo (`'type'` o `'size'`) y se muestran como error bajo el campo
|
|
2204
|
+
* (`rejectedTypeText` / `rejectedSizeText`); la ayuda sigue visible bajo ese
|
|
2205
|
+
* mensaje, para que se vea qué sí sirve. Un `error` del consumidor tiene
|
|
2206
|
+
* prioridad sobre ese mensaje y reemplaza a la ayuda, igual que `errorMessage`
|
|
2207
|
+
* sobre `hint` en `kf-input`. La validación del navegador no reemplaza la del servidor.
|
|
2208
|
+
*
|
|
2209
|
+
* **Archivo elegido.** Su nombre y tamaño aparecen UNA vez, con un botón para
|
|
2210
|
+
* quitarlo (`removeLabel`, con el nombre del archivo en su `aria-label`); el
|
|
2211
|
+
* nombre del `<input>` nativo queda oculto. Con `multiple` se listan todos y
|
|
2212
|
+
* cada uno se quita por separado. Elegir de nuevo reemplaza la selección.
|
|
2213
|
+
*
|
|
2214
|
+
* `dropzone` agrega arrastrar y soltar sobre el área; el botón y el teclado
|
|
2215
|
+
* siguen siendo la vía principal.
|
|
2216
|
+
*
|
|
2217
|
+
* Es un `ControlValueAccessor`: con `[(ngModel)]`/`formControl` el valor es
|
|
2218
|
+
* `File | null` (o `File[]` con `multiple`); `writeValue(null)` limpia.
|
|
2219
|
+
*
|
|
2220
|
+
* <kf-file-input label="Comprobante" accept=".pdf,.jpg,.png" [maxSize]="5242880"
|
|
2221
|
+
* (fileChange)="onFiles($event)" (fileRejected)="onRejected($event)" />
|
|
2222
|
+
* <kf-file-input label="Fotos" accept="image/*" multiple dropzone formControlName="photos" />
|
|
2223
|
+
* <kf-file-input label="Contrato" error="Adjunta el contrato firmado." formControlName="contract" />
|
|
2224
|
+
*/
|
|
2225
|
+
declare class FileInput implements ControlValueAccessor {
|
|
2226
|
+
private readonly nativeInput;
|
|
2227
|
+
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
2228
|
+
readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2229
|
+
/** Texto de ayuda. Sin valor, se arma con `accept` y `maxSize`. */
|
|
2230
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
2231
|
+
/** Formatos admitidos, como el `accept` nativo: `.pdf,.jpg`, `image/png`, `image/*`. */
|
|
2232
|
+
readonly accept: _angular_core.InputSignal<string | undefined>;
|
|
2233
|
+
/** Tamaño máximo por archivo, en bytes. Sin valor, sin límite. */
|
|
2234
|
+
readonly maxSize: _angular_core.InputSignal<number | undefined>;
|
|
2235
|
+
readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2236
|
+
/** Agrega arrastrar y soltar sobre el área del control. */
|
|
2237
|
+
readonly dropzone: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2238
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2239
|
+
/** Borde rojo y `aria-invalid`. Se activa solo con `error`; úsalo para marcar un error sin mensaje. */
|
|
2240
|
+
readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2241
|
+
/** Mensaje de error del consumidor (`role="alert"`); reemplaza a la ayuda y al motivo de rechazo, como `errorMessage` en `kf-input`. */
|
|
2242
|
+
readonly error: _angular_core.InputSignal<string | undefined>;
|
|
2243
|
+
/** Nombre accesible cuando no hay `label` visible. */
|
|
2244
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
2245
|
+
/** Texto del botón cuando no hay archivo elegido. */
|
|
2246
|
+
readonly buttonLabel: _angular_core.InputSignal<string>;
|
|
2247
|
+
/** Texto del botón con `multiple` o cuando ya hay un archivo (cambiar). */
|
|
2248
|
+
readonly changeLabel: _angular_core.InputSignal<string>;
|
|
2249
|
+
/** Nombre accesible del botón de quitar; se le agrega el nombre del archivo. */
|
|
2250
|
+
readonly removeLabel: _angular_core.InputSignal<string>;
|
|
2251
|
+
/** Texto de arrastrar y soltar (solo con `dropzone`). */
|
|
2252
|
+
readonly dropzoneText: _angular_core.InputSignal<string>;
|
|
2253
|
+
readonly rejectedTypeText: _angular_core.InputSignal<string>;
|
|
2254
|
+
readonly rejectedSizeText: _angular_core.InputSignal<string>;
|
|
2255
|
+
/** Selección vigente (`File[]`, vacío al quitar todo). */
|
|
2256
|
+
readonly fileChange: _angular_core.OutputEmitterRef<File[]>;
|
|
2257
|
+
/** Un archivo descartado y su motivo. */
|
|
2258
|
+
readonly fileRejected: _angular_core.OutputEmitterRef<FileRejection>;
|
|
2259
|
+
protected readonly inputId: string;
|
|
2260
|
+
protected readonly hintId: string;
|
|
2261
|
+
protected readonly errorId: string;
|
|
2262
|
+
protected readonly filesId: string;
|
|
2263
|
+
protected readonly files: _angular_core.WritableSignal<File[]>;
|
|
2264
|
+
protected readonly rejection: _angular_core.WritableSignal<FileRejectionReason | null>;
|
|
2265
|
+
protected readonly dragging: _angular_core.WritableSignal<boolean>;
|
|
2266
|
+
private readonly disabledByForm;
|
|
2267
|
+
protected readonly isDisabled: _angular_core.Signal<boolean>;
|
|
2268
|
+
private onChange;
|
|
2269
|
+
private onTouched;
|
|
2270
|
+
/** Mensaje visible: el del consumidor, o el motivo del último rechazo. */
|
|
2271
|
+
protected readonly message: _angular_core.Signal<string | null>;
|
|
2272
|
+
/** Ayuda efectiva: la del consumidor o la armada con formatos y tamaño. */
|
|
2273
|
+
protected readonly effectiveHint: _angular_core.Signal<string>;
|
|
2274
|
+
protected readonly isInvalid: _angular_core.Signal<boolean>;
|
|
2275
|
+
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
2276
|
+
protected readonly triggerText: _angular_core.Signal<string>;
|
|
2277
|
+
/** Enfoca el `<input>` nativo. */
|
|
2278
|
+
focus(options?: FocusOptions): void;
|
|
2279
|
+
writeValue(value: File | File[] | null): void;
|
|
2280
|
+
registerOnChange(fn: (value: File | File[] | null) => void): void;
|
|
2281
|
+
registerOnTouched(fn: () => void): void;
|
|
2282
|
+
setDisabledState(isDisabled: boolean): void;
|
|
2283
|
+
protected onPick(event: Event): void;
|
|
2284
|
+
protected onDragOver(event: DragEvent): void;
|
|
2285
|
+
protected onDragLeave(): void;
|
|
2286
|
+
protected onDrop(event: DragEvent): void;
|
|
2287
|
+
protected remove(index: number): void;
|
|
2288
|
+
protected formatSize(file: File): string;
|
|
2289
|
+
/** Valida lo recibido, emite los rechazos y reemplaza la selección si hay algo válido. */
|
|
2290
|
+
private receive;
|
|
2291
|
+
private reject;
|
|
2292
|
+
private matchesAccept;
|
|
2293
|
+
private commit;
|
|
2294
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileInput, never>;
|
|
2295
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FileInput, "kf-file-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "dropzone": { "alias": "dropzone"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "buttonLabel": { "alias": "buttonLabel"; "required": false; "isSignal": true; }; "changeLabel": { "alias": "changeLabel"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; "dropzoneText": { "alias": "dropzoneText"; "required": false; "isSignal": true; }; "rejectedTypeText": { "alias": "rejectedTypeText"; "required": false; "isSignal": true; }; "rejectedSizeText": { "alias": "rejectedSizeText"; "required": false; "isSignal": true; }; }, { "fileChange": "fileChange"; "fileRejected": "fileRejected"; }, never, never, true, never>;
|
|
1792
2296
|
}
|
|
1793
2297
|
|
|
1794
2298
|
interface MultiSelectOption {
|
|
@@ -1884,7 +2388,13 @@ declare class MultiSelect {
|
|
|
1884
2388
|
/** Mueve `activeIndex` sobre las opciones YA FILTRADAS visibles. Clamp simple, sin wraparound. */
|
|
1885
2389
|
moveActive(delta: number): void;
|
|
1886
2390
|
toggleActive(): void;
|
|
1887
|
-
|
|
2391
|
+
/**
|
|
2392
|
+
* Escape con el panel abierto, en fase de captura sobre `document` (ver
|
|
2393
|
+
* `listenEscapeCapture`): consume la tecla solo si había un panel que
|
|
2394
|
+
* cerrar, así un `kf-drawer`/`kf-modal` contenedor no se cierra con el
|
|
2395
|
+
* mismo Escape. Devuelve si cerró algo.
|
|
2396
|
+
*/
|
|
2397
|
+
onEscape(): boolean;
|
|
1888
2398
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MultiSelect, never>;
|
|
1889
2399
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MultiSelect, "kf-multi-select", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchThreshold": { "alias": "searchThreshold"; "required": false; "isSignal": true; }; }, { "valuesChange": "valuesChange"; }, never, never, true, never>;
|
|
1890
2400
|
}
|
|
@@ -2035,6 +2545,8 @@ declare class Footer {
|
|
|
2035
2545
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Footer, "kf-footer", never, { "logoSrc": { "alias": "logoSrc"; "required": false; "isSignal": true; }; "logoAlt": { "alias": "logoAlt"; "required": false; "isSignal": true; }; "copyright": { "alias": "copyright"; "required": true; "isSignal": true; }; "links": { "alias": "links"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2036
2546
|
}
|
|
2037
2547
|
|
|
2548
|
+
/** Valor de `min`/`max`/`step`: número, o texto cuando el tipo lo pide (una fecha `'2026-01-31'`, un mes, una hora). */
|
|
2549
|
+
type InputBound = string | number | null | undefined;
|
|
2038
2550
|
/**
|
|
2039
2551
|
* Input de formulario apilado: label arriba (en mayúsculas vía CSS), campo con
|
|
2040
2552
|
* fondo gris que pasa a blanco con anillo de foco azul al enfocar.
|
|
@@ -2098,11 +2610,27 @@ declare class Footer {
|
|
|
2098
2610
|
*
|
|
2099
2611
|
* <kf-input label="RUT" autocomplete="username" name="rut" inputmode="text" formControlName="rut" />
|
|
2100
2612
|
* <kf-input type="password" label="Contraseña" toggleable autocomplete="current-password" name="password" formControlName="password" />
|
|
2613
|
+
*
|
|
2614
|
+
* `min`, `max`, `step` y `maxlength` se reenvían al `<input>` nativo (mismo
|
|
2615
|
+
* motivo: un atributo en el host no llega adentro) y sin valor no se
|
|
2616
|
+
* renderiza ningún atributo. `min`/`max`/`step` aceptan número o texto según
|
|
2617
|
+
* el `type` (`number`, `range`, `date`, `time`, `month`…): con `type="date"` el
|
|
2618
|
+
* límite es una fecha ISO. `maxlength` es un entero positivo y aplica a los
|
|
2619
|
+
* tipos de texto (`text`, `search`, `email`, `tel`, `url`, `password`). El
|
|
2620
|
+
* navegador usa los límites para la validación nativa (`:invalid`,
|
|
2621
|
+
* `validity.rangeUnderflow`) y para el selector de fechas; no reemplazan la
|
|
2622
|
+
* validación del formulario ni el `errorMessage`.
|
|
2623
|
+
*
|
|
2624
|
+
* <kf-input type="date" label="Fecha de entrega" min="2026-01-01" max="2026-12-31" />
|
|
2625
|
+
* <kf-input type="number" label="Cantidad" [min]="1" [max]="20" [step]="1" />
|
|
2626
|
+
* <kf-input label="Placa" [maxlength]="7" />
|
|
2101
2627
|
*/
|
|
2102
2628
|
declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
2103
2629
|
private static nextId;
|
|
2104
2630
|
private readonly nativeInput;
|
|
2105
2631
|
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
2632
|
+
/** Oculta el `label` a la vista y lo deja como nombre accesible (`<label for>`), sin ocultarlo con CSS desde afuera. */
|
|
2633
|
+
readonly hideLabel: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2106
2634
|
/** Marca el label con un asterisco visual y aplica `required` al `<input>`
|
|
2107
2635
|
* nativo — el atributo HTML ya expone el estado obligatorio a lectores de
|
|
2108
2636
|
* pantalla (mapeo implícito a `aria-required`), sin necesidad de un
|
|
@@ -2136,6 +2664,14 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
|
2136
2664
|
/** Sugiere el teclado virtual (`numeric`, `email`, `tel`, etc.) sin cambiar
|
|
2137
2665
|
* el `type`. Sin valor, el atributo no se renderiza. */
|
|
2138
2666
|
readonly inputmode: _angular_core.InputSignal<string | null | undefined>;
|
|
2667
|
+
/** Límite inferior del control (`min` nativo): número, o texto para fechas/horas (`'2026-01-01'`). */
|
|
2668
|
+
readonly min: _angular_core.InputSignalWithTransform<string | number | null, InputBound>;
|
|
2669
|
+
/** Límite superior del control (`max` nativo). Ver `min`. */
|
|
2670
|
+
readonly max: _angular_core.InputSignalWithTransform<string | number | null, InputBound>;
|
|
2671
|
+
/** Paso del control (`step` nativo): número o `'any'`. */
|
|
2672
|
+
readonly step: _angular_core.InputSignalWithTransform<string | number | null, InputBound>;
|
|
2673
|
+
/** Largo máximo del texto (`maxlength` nativo), entero positivo. Solo aplica a tipos de texto. */
|
|
2674
|
+
readonly maxlength: _angular_core.InputSignalWithTransform<number | null, string | number | null | undefined>;
|
|
2139
2675
|
/** Agrega el botón de mostrar/ocultar — sin efecto si `type` no es `"password"`. */
|
|
2140
2676
|
readonly toggleable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2141
2677
|
/** Nombre accesible del `<input>` cuando no hay `label` visible. Ignorado
|
|
@@ -2195,9 +2731,13 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
|
2195
2731
|
*/
|
|
2196
2732
|
protected onTogglePasswordVisibility(): void;
|
|
2197
2733
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Input, never>;
|
|
2198
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Input, "kf-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "inputmode": { "alias": "inputmode"; "required": false; "isSignal": true; }; "toggleable": { "alias": "toggleable"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; }, { "cleared": "cleared"; }, never, never, true, never>;
|
|
2734
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Input, "kf-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "inputmode": { "alias": "inputmode"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "maxlength": { "alias": "maxlength"; "required": false; "isSignal": true; }; "toggleable": { "alias": "toggleable"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; }, { "cleared": "cleared"; }, never, never, true, never>;
|
|
2199
2735
|
}
|
|
2200
2736
|
|
|
2737
|
+
type ResolvedJourneyStep = JourneyStep & {
|
|
2738
|
+
status: JourneyStepStatus;
|
|
2739
|
+
progressValue: number | null;
|
|
2740
|
+
};
|
|
2201
2741
|
type JourneyStepStatus = 'done' | 'current' | 'delayed' | 'pending';
|
|
2202
2742
|
type JourneyStepperSurface = 'dark' | 'card';
|
|
2203
2743
|
/**
|
|
@@ -2211,32 +2751,71 @@ type JourneyStepperSurface = 'dark' | 'card';
|
|
|
2211
2751
|
* Para cuando cada paso comunica su propio estado puntual.
|
|
2212
2752
|
*/
|
|
2213
2753
|
type JourneyStepperColorScheme = 'brand' | 'semantic';
|
|
2754
|
+
/** `'auto'` elige horizontal o vertical según el ancho del propio componente. */
|
|
2755
|
+
type JourneyStepperOrientation = 'horizontal' | 'vertical' | 'auto';
|
|
2214
2756
|
interface JourneyStep {
|
|
2215
2757
|
key: string;
|
|
2216
2758
|
label: string;
|
|
2217
2759
|
icon: IconName;
|
|
2218
|
-
/**
|
|
2760
|
+
/**
|
|
2761
|
+
* Estado explícito del paso. Si AL MENOS un paso lo define, todos los
|
|
2762
|
+
* estados salen de acá (un paso sin `status` queda `pending`), también en
|
|
2763
|
+
* horizontal y permitiendo varios pasos `current` o estados no
|
|
2764
|
+
* consecutivos. Si ningún paso lo define, horizontal lo deriva de
|
|
2765
|
+
* `currentStep`. Con `orientation="vertical"` siempre se usa el explícito.
|
|
2766
|
+
*/
|
|
2219
2767
|
status?: JourneyStepStatus;
|
|
2220
|
-
/** Texto bajo el label
|
|
2768
|
+
/** Texto bajo el label, junto al label en horizontal sin `caption` (compatibilidad). */
|
|
2221
2769
|
date?: string;
|
|
2770
|
+
/**
|
|
2771
|
+
* Texto secundario del paso, distinto de `date` (ej. «16 de 18 completaron»).
|
|
2772
|
+
* Se muestra bajo el label en ambas orientaciones.
|
|
2773
|
+
*/
|
|
2774
|
+
caption?: string;
|
|
2775
|
+
/**
|
|
2776
|
+
* Avance 0-100 del paso, como barra fina bajo el texto. Se acota a [0, 100];
|
|
2777
|
+
* un valor no finito no dibuja la barra. Si el paso tiene `caption`, la
|
|
2778
|
+
* barra es decorativa (`aria-hidden`) y el `caption` debe comunicar el avance;
|
|
2779
|
+
* sin `caption` expone `role="progressbar"` con el `label` como nombre.
|
|
2780
|
+
*/
|
|
2781
|
+
progress?: number;
|
|
2782
|
+
/**
|
|
2783
|
+
* Texto visible del estado (ej. «Completado», «En curso», «Pendiente»), para
|
|
2784
|
+
* que el estado no dependa solo del color y la forma del punto.
|
|
2785
|
+
*/
|
|
2786
|
+
statusLabel?: string;
|
|
2222
2787
|
}
|
|
2223
2788
|
/**
|
|
2224
2789
|
* Progreso de un flujo de N pasos.
|
|
2225
2790
|
*
|
|
2226
|
-
* - `orientation` (`'horizontal'` default | `'vertical'`): horizontal
|
|
2227
|
-
* deriva done/current/pending de `currentStep
|
|
2228
|
-
* `steps[].status` explícito, con `delayed` como
|
|
2791
|
+
* - `orientation` (`'horizontal'` default | `'vertical'` | `'auto'`): horizontal
|
|
2792
|
+
* deriva done/current/pending de `currentStep` (salvo que algún paso defina
|
|
2793
|
+
* `status`); vertical usa `steps[].status` explícito, con `delayed` como
|
|
2794
|
+
* cuarto estado. `'auto'` es horizontal cuando el propio componente mide al
|
|
2795
|
+
* menos `autoBreakpoint` px (820 por defecto) y vertical si no; en vertical,
|
|
2796
|
+
* con `caption`/`progress`/`statusLabel` y desde 520 px de ancho, el texto de
|
|
2797
|
+
* cada paso pasa a filas «etiqueta | estado y conteo | barra». En `'auto'`
|
|
2798
|
+
* los puntos son clickeables solo mientras el layout es horizontal.
|
|
2229
2799
|
* - `surface` (`'dark'` default | `'card'`): fondo sólido oscuro de marca,
|
|
2230
2800
|
* o superficie clara con borde+sombra.
|
|
2231
2801
|
* - `colorScheme` (`'brand'` default | `'semantic'`): ver `JourneyStepperColorScheme`.
|
|
2802
|
+
* - `ariaLabel`: nombre de la lista de pasos (lectores de pantalla).
|
|
2803
|
+
*
|
|
2804
|
+
* Los pasos se exponen como lista (`role="list"`/`listitem`) y el paso con
|
|
2805
|
+
* `status === 'current'` lleva `aria-current="step"`.
|
|
2232
2806
|
*
|
|
2233
2807
|
* <kf-journey-stepper surface="card" [steps]="steps" [currentStep]="4" (stepClick)="onNavigate($event)" />
|
|
2234
2808
|
* <kf-journey-stepper orientation="vertical" [steps]="unitSteps" />
|
|
2235
2809
|
* <kf-journey-stepper orientation="vertical" colorScheme="semantic" [steps]="unitStepsWithDelays" />
|
|
2810
|
+
* <kf-journey-stepper orientation="auto" surface="card" ariaLabel="Avance por etapa" [steps]="stages" />
|
|
2236
2811
|
*/
|
|
2237
2812
|
declare class JourneyStepper {
|
|
2238
2813
|
readonly steps: _angular_core.InputSignal<JourneyStep[]>;
|
|
2239
|
-
readonly orientation: _angular_core.InputSignal<
|
|
2814
|
+
readonly orientation: _angular_core.InputSignal<JourneyStepperOrientation>;
|
|
2815
|
+
/** Ancho mínimo (px) del componente para ser horizontal con `orientation="auto"`. */
|
|
2816
|
+
readonly autoBreakpoint: _angular_core.InputSignal<number>;
|
|
2817
|
+
/** Nombre accesible de la lista de pasos. */
|
|
2818
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
2240
2819
|
readonly surface: _angular_core.InputSignal<JourneyStepperSurface>;
|
|
2241
2820
|
readonly colorScheme: _angular_core.InputSignal<JourneyStepperColorScheme>;
|
|
2242
2821
|
/** Índice del paso actual — solo con `orientation="horizontal"`. */
|
|
@@ -2247,15 +2826,26 @@ declare class JourneyStepper {
|
|
|
2247
2826
|
private readonly destroyRef;
|
|
2248
2827
|
/** `true` cuando el contenido desborda el ancho visible — controla el fade de los bordes. */
|
|
2249
2828
|
protected readonly hasOverflow: _angular_core.WritableSignal<boolean>;
|
|
2829
|
+
/** Ancho medido del componente; `null` hasta la primera medición. */
|
|
2830
|
+
private readonly trackWidth;
|
|
2831
|
+
/**
|
|
2832
|
+
* Orientación efectiva: la de `orientation`, o —con `'auto'`— horizontal si el
|
|
2833
|
+
* componente mide al menos `autoBreakpoint` px. Antes de medir (o con ancho
|
|
2834
|
+
* 0) es vertical, que siempre cabe.
|
|
2835
|
+
*/
|
|
2836
|
+
protected readonly effectiveOrientation: _angular_core.Signal<"horizontal" | "vertical">;
|
|
2837
|
+
protected readonly vertical: _angular_core.Signal<boolean>;
|
|
2250
2838
|
protected readonly clickable: _angular_core.Signal<boolean>;
|
|
2839
|
+
/** `true` si algún paso usa `caption`, `progress` o `statusLabel` (layout enriquecido). */
|
|
2840
|
+
protected readonly rich: _angular_core.Signal<boolean>;
|
|
2251
2841
|
constructor();
|
|
2252
2842
|
private measureOverflow;
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2843
|
+
/** Progreso acotado a [0, 100]; `null` si no hay valor finito. */
|
|
2844
|
+
private static progressOf;
|
|
2845
|
+
protected readonly resolvedSteps: _angular_core.Signal<ResolvedJourneyStep[]>;
|
|
2256
2846
|
protected dotIcon(status: JourneyStepStatus, stepIcon: IconName): IconName;
|
|
2257
2847
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<JourneyStepper, never>;
|
|
2258
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<JourneyStepper, "kf-journey-stepper", never, { "steps": { "alias": "steps"; "required": true; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "surface": { "alias": "surface"; "required": false; "isSignal": true; }; "colorScheme": { "alias": "colorScheme"; "required": false; "isSignal": true; }; "currentStep": { "alias": "currentStep"; "required": false; "isSignal": true; }; }, { "stepClick": "stepClick"; }, never, never, true, never>;
|
|
2848
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<JourneyStepper, "kf-journey-stepper", never, { "steps": { "alias": "steps"; "required": true; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "autoBreakpoint": { "alias": "autoBreakpoint"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "surface": { "alias": "surface"; "required": false; "isSignal": true; }; "colorScheme": { "alias": "colorScheme"; "required": false; "isSignal": true; }; "currentStep": { "alias": "currentStep"; "required": false; "isSignal": true; }; }, { "stepClick": "stepClick"; }, never, never, true, never>;
|
|
2259
2849
|
}
|
|
2260
2850
|
|
|
2261
2851
|
type LinkVariant = 'default' | 'muted';
|
|
@@ -2508,6 +3098,14 @@ declare class ListToolbar {
|
|
|
2508
3098
|
* <kf-metric-card label="Saldo Pendiente" value="$45,000">
|
|
2509
3099
|
* <kf-button actions variant="primary" size="sm">Pagar Ahora</kf-button>
|
|
2510
3100
|
* </kf-metric-card>
|
|
3101
|
+
*
|
|
3102
|
+
* `loading` (default `false`): dibuja el esqueleto de la card — etiqueta,
|
|
3103
|
+
* ícono, valor y `foot` como bloques del alto real de cada línea — dentro del
|
|
3104
|
+
* mismo `kf-card`, y reserva (sin mostrar) el espacio de las acciones, así que
|
|
3105
|
+
* al llegar los datos no hay salto de layout. Pasa los mismos inputs que
|
|
3106
|
+
* usarás cargada. Marca el host con `aria-busy="true"`.
|
|
3107
|
+
*
|
|
3108
|
+
* <kf-metric-card label="Tickets abiertos" value="11" foot="+2 hoy" [loading]="isLoading()" />
|
|
2511
3109
|
*/
|
|
2512
3110
|
declare class MetricCard {
|
|
2513
3111
|
readonly label: _angular_core.InputSignal<string>;
|
|
@@ -2520,8 +3118,132 @@ declare class MetricCard {
|
|
|
2520
3118
|
readonly valueColor: _angular_core.InputSignal<string | undefined>;
|
|
2521
3119
|
/** Badge de esquina opcional, pegado al valor (ej. "+2%"). */
|
|
2522
3120
|
readonly badge: _angular_core.InputSignal<string | undefined>;
|
|
3121
|
+
/** Dibuja el esqueleto en lugar del contenido, conservando las dimensiones. */
|
|
3122
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2523
3123
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MetricCard, never>;
|
|
2524
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MetricCard, "kf-metric-card", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "foot": { "alias": "foot"; "required": false; "isSignal": true; }; "valueColor": { "alias": "valueColor"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; }, {}, never, ["[actions]"], true, never>;
|
|
3124
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MetricCard, "kf-metric-card", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "foot": { "alias": "foot"; "required": false; "isSignal": true; }; "valueColor": { "alias": "valueColor"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; }, {}, never, ["[actions]"], true, never>;
|
|
3125
|
+
}
|
|
3126
|
+
|
|
3127
|
+
/** Estado de avance de una etapa o hito; nunca se comunica solo con color. */
|
|
3128
|
+
type ProgressStatus = 'done' | 'current' | 'pending';
|
|
3129
|
+
declare const PROGRESS_STATUS: {
|
|
3130
|
+
readonly DONE: "done";
|
|
3131
|
+
readonly CURRENT: "current";
|
|
3132
|
+
readonly PENDING: "pending";
|
|
3133
|
+
};
|
|
3134
|
+
/**
|
|
3135
|
+
* Texto por defecto (español) de cada estado: el estado nunca se comunica solo
|
|
3136
|
+
* con color. Los componentes que lo muestran aceptan sus propios textos.
|
|
3137
|
+
*/
|
|
3138
|
+
declare const PROGRESS_STATUS_LABEL: {
|
|
3139
|
+
readonly done: "Completado";
|
|
3140
|
+
readonly current: "En curso";
|
|
3141
|
+
readonly pending: "Pendiente";
|
|
3142
|
+
};
|
|
3143
|
+
|
|
3144
|
+
/**
|
|
3145
|
+
* Hito de una etapa. `date` llega ya formateada; `exception` excluye el hito
|
|
3146
|
+
* del avance (se muestra en un bloque aparte y solo si ocurrió).
|
|
3147
|
+
*/
|
|
3148
|
+
interface MilestoneItem {
|
|
3149
|
+
id: string;
|
|
3150
|
+
label: string;
|
|
3151
|
+
done: boolean;
|
|
3152
|
+
date?: string;
|
|
3153
|
+
exception?: boolean;
|
|
3154
|
+
}
|
|
3155
|
+
/**
|
|
3156
|
+
* Etapa expandible de la línea de tiempo. `date` llega ya formateada y solo
|
|
3157
|
+
* aplica si la etapa está completada. Una etapa sin `items` no es expandible.
|
|
3158
|
+
*/
|
|
3159
|
+
interface MilestoneGroup {
|
|
3160
|
+
id: string;
|
|
3161
|
+
label: string;
|
|
3162
|
+
status: ProgressStatus;
|
|
3163
|
+
icon: IconName;
|
|
3164
|
+
date?: string;
|
|
3165
|
+
items: readonly MilestoneItem[];
|
|
3166
|
+
}
|
|
3167
|
+
/** Textos de `kf-milestone-timeline`; todos tienen valor por defecto en español. */
|
|
3168
|
+
interface MilestoneTimelineLabels {
|
|
3169
|
+
heading: string;
|
|
3170
|
+
expandAll: string;
|
|
3171
|
+
collapseAll: string;
|
|
3172
|
+
statusDone: string;
|
|
3173
|
+
statusPending: string;
|
|
3174
|
+
/** Texto de una etapa en curso; recibe los hitos completados y el total que cuenta en el avance. */
|
|
3175
|
+
currentMeta: (done: number, total: number) => string;
|
|
3176
|
+
/** Insignia del hito destacado como el siguiente a completar. */
|
|
3177
|
+
next: string;
|
|
3178
|
+
exceptionsTitle: string;
|
|
3179
|
+
noExceptions: string;
|
|
3180
|
+
/** Texto solo para lectores de pantalla tras un hito completado. */
|
|
3181
|
+
itemDone: string;
|
|
3182
|
+
/** Texto solo para lectores de pantalla tras un hito pendiente. */
|
|
3183
|
+
itemPending: string;
|
|
3184
|
+
}
|
|
3185
|
+
declare const DEFAULT_MILESTONE_TIMELINE_LABELS: MilestoneTimelineLabels;
|
|
3186
|
+
|
|
3187
|
+
/**
|
|
3188
|
+
* Línea de tiempo de etapas con hitos. Cada etapa es un encabezado expandible
|
|
3189
|
+
* (`aria-expanded`/`aria-controls`) con un panel de hitos y, si la etapa tiene
|
|
3190
|
+
* hitos de excepción, un bloque aparte que no cuenta en el avance. Una etapa
|
|
3191
|
+
* sin hitos es solo informativa (no es un botón).
|
|
3192
|
+
*
|
|
3193
|
+
* El estado nunca se comunica solo con color: cada etapa y cada hito llevan su
|
|
3194
|
+
* estado en texto (visible o solo para lectores de pantalla) y los nodos y
|
|
3195
|
+
* marcas lo dibujan también con la forma. Todos los textos salen de `labels`
|
|
3196
|
+
* (español por defecto) y las fechas llegan ya formateadas.
|
|
3197
|
+
*
|
|
3198
|
+
* El conector entre etapas se deriva del tamaño del nodo
|
|
3199
|
+
* (`--kf-status-node-size`, default `2.125rem`) y de la separación del
|
|
3200
|
+
* encabezado: cambiar el tamaño del nodo mueve la línea con él.
|
|
3201
|
+
*
|
|
3202
|
+
* <kf-milestone-timeline
|
|
3203
|
+
* [groups]="stages()"
|
|
3204
|
+
* [(expandedIds)]="expanded"
|
|
3205
|
+
* nextItemId="stage2-docs"
|
|
3206
|
+
* ariaLabel="Avance de la entrega"
|
|
3207
|
+
* [labels]="{ heading: 'Progress', expandAll: 'Expand all' }"
|
|
3208
|
+
* />
|
|
3209
|
+
*/
|
|
3210
|
+
declare class MilestoneTimeline {
|
|
3211
|
+
private readonly host;
|
|
3212
|
+
private readonly instanceId;
|
|
3213
|
+
readonly groups: _angular_core.InputSignal<readonly MilestoneGroup[]>;
|
|
3214
|
+
/** Ids de las etapas expandidas, two-way: `[(expandedIds)]`. El padre controla el estado inicial. */
|
|
3215
|
+
readonly expandedIds: _angular_core.ModelSignal<readonly string[]>;
|
|
3216
|
+
/** Id del hito que se destaca como el siguiente a completar. */
|
|
3217
|
+
readonly nextItemId: _angular_core.InputSignal<string | undefined>;
|
|
3218
|
+
/** Textos; los que no se pasen usan el español por defecto. */
|
|
3219
|
+
readonly labels: _angular_core.InputSignal<Partial<MilestoneTimelineLabels>>;
|
|
3220
|
+
/** Nombre accesible de la lista de etapas. */
|
|
3221
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
3222
|
+
/** Nivel (2-6) del título "Avance por etapa", para respetar el esquema de títulos de la página. */
|
|
3223
|
+
readonly headingLevel: _angular_core.InputSignal<2 | 3 | 4 | 5 | 6>;
|
|
3224
|
+
protected readonly text: _angular_core.Signal<MilestoneTimelineLabels>;
|
|
3225
|
+
protected readonly rows: _angular_core.Signal<{
|
|
3226
|
+
group: MilestoneGroup;
|
|
3227
|
+
main: MilestoneItem[];
|
|
3228
|
+
exceptions: MilestoneItem[];
|
|
3229
|
+
happened: MilestoneItem[];
|
|
3230
|
+
expandable: boolean;
|
|
3231
|
+
meta: string;
|
|
3232
|
+
}[]>;
|
|
3233
|
+
private readonly expandableIds;
|
|
3234
|
+
protected readonly hasExpandable: _angular_core.Signal<boolean>;
|
|
3235
|
+
protected readonly allExpanded: _angular_core.Signal<boolean>;
|
|
3236
|
+
protected isExpanded(groupId: string): boolean;
|
|
3237
|
+
protected headId(groupId: string): string;
|
|
3238
|
+
protected panelId(groupId: string): string;
|
|
3239
|
+
protected itemStatus(item: MilestoneItem): 'done' | 'pending';
|
|
3240
|
+
protected toggle(groupId: string): void;
|
|
3241
|
+
protected toggleAll(): void;
|
|
3242
|
+
/** Lleva el foco al encabezado de una etapa expandible; devuelve el elemento, o `null` si no existe o no es expandible. */
|
|
3243
|
+
focusGroup(groupId: string): HTMLElement | null;
|
|
3244
|
+
private metaOf;
|
|
3245
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MilestoneTimeline, never>;
|
|
3246
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MilestoneTimeline, "kf-milestone-timeline", never, { "groups": { "alias": "groups"; "required": true; "isSignal": true; }; "expandedIds": { "alias": "expandedIds"; "required": false; "isSignal": true; }; "nextItemId": { "alias": "nextItemId"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; }, { "expandedIds": "expandedIdsChange"; }, never, never, true, never>;
|
|
2525
3247
|
}
|
|
2526
3248
|
|
|
2527
3249
|
/**
|
|
@@ -2918,6 +3640,140 @@ declare class Panel {
|
|
|
2918
3640
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Panel, "kf-panel", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionHref": { "alias": "actionHref"; "required": false; "isSignal": true; }; }, { "actionClick": "actionClick"; }, never, ["*"], true, never>;
|
|
2919
3641
|
}
|
|
2920
3642
|
|
|
3643
|
+
type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
3644
|
+
/**
|
|
3645
|
+
* Popover de contenido enriquecido anclado a un elemento — la contraparte de
|
|
3646
|
+
* `kfTooltip` para cuando el texto plano no alcanza (varias líneas, énfasis,
|
|
3647
|
+
* un desglose, enlaces). Mismo mecanismo de `@angular/cdk/overlay`. El host
|
|
3648
|
+
* sigue siendo el elemento que recibe el foco: la directiva no lo hace
|
|
3649
|
+
* focusable, así que va sobre un `<button>`, un `<a>` o un elemento con
|
|
3650
|
+
* `tabindex="0"`.
|
|
3651
|
+
*
|
|
3652
|
+
* <button [kfPopover]="detail" kfPopoverPlacement="top">Etapa</button>
|
|
3653
|
+
* <ng-template #detail><strong>Recepción</strong><p>Completada el 12/05.</p></ng-template>
|
|
3654
|
+
*
|
|
3655
|
+
* Apertura: puntero (hover, tras `kfPopoverShowDelay` ms; NO se abre con puntero
|
|
3656
|
+
* táctil) y foco de teclado (al instante, solo si el foco es visible: un
|
|
3657
|
+
* clic con el mouse no lo abre). Cierre: Escape (descarta el panel hasta que
|
|
3658
|
+
* el puntero y el foco salgan y vuelvan), salida del puntero tras
|
|
3659
|
+
* `kfPopoverHideDelay` ms, pérdida de foco, scroll de cualquier contenedor y
|
|
3660
|
+
* redimensionado de la ventana. El panel se reposiciona dentro del viewport
|
|
3661
|
+
* (invierte el lado si no cabe).
|
|
3662
|
+
*
|
|
3663
|
+
* Con `kfPopoverInteractive`, el puntero puede entrar al panel sin cerrarlo y
|
|
3664
|
+
* el panel es un `dialog` no modal: Tab desde el anfitrión entra al primer
|
|
3665
|
+
* control del panel y Mayús+Tab desde ese control vuelve al anfitrión. Sin
|
|
3666
|
+
* `kfPopoverInteractive` (default), el panel es un `tooltip` que no captura
|
|
3667
|
+
* el puntero y no debe contener controles.
|
|
3668
|
+
*
|
|
3669
|
+
* Si el anfitrión no es interactivo pero vive dentro de un control (un botón,
|
|
3670
|
+
* un enlace, un elemento con `tabindex`), los eventos de puntero, foco y
|
|
3671
|
+
* teclado se escuchan en ese control y el panel se ancla al anfitrión. Es el
|
|
3672
|
+
* caso de un indicador dentro de una celda interactiva de `kf-data-table`:
|
|
3673
|
+
*
|
|
3674
|
+
* <ng-template #stageCell let-row>
|
|
3675
|
+
* <span [kfPopover]="detail"><kf-status-mark [status]="row.status" /></span>
|
|
3676
|
+
* </ng-template>
|
|
3677
|
+
*
|
|
3678
|
+
* Accesibilidad: mientras está abierto, el elemento que recibe el foco
|
|
3679
|
+
* referencia el panel con `aria-describedby` (se conserva cualquier valor
|
|
3680
|
+
* previo).
|
|
3681
|
+
*/
|
|
3682
|
+
declare class PopoverDirective implements OnDestroy {
|
|
3683
|
+
/** Contenido del popover (un `ng-template`). `null`/`undefined` = no se abre. */
|
|
3684
|
+
readonly kfPopover: _angular_core.InputSignal<TemplateRef<unknown> | null | undefined>;
|
|
3685
|
+
/** Lado preferido; si no cabe en el viewport, se invierte. Default `bottom`. */
|
|
3686
|
+
readonly kfPopoverPlacement: _angular_core.InputSignal<PopoverPlacement>;
|
|
3687
|
+
/** Retardo (ms) antes de abrir con el puntero. El foco de teclado abre sin retardo. */
|
|
3688
|
+
readonly kfPopoverShowDelay: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
3689
|
+
/** Retardo (ms) antes de cerrar al salir el puntero. */
|
|
3690
|
+
readonly kfPopoverHideDelay: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
3691
|
+
/** Desactiva el popover (y lo cierra si estaba abierto). */
|
|
3692
|
+
readonly kfPopoverDisabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3693
|
+
/** Permite que el puntero entre al panel sin cerrarlo y que el teclado llegue a sus controles. */
|
|
3694
|
+
readonly kfPopoverInteractive: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3695
|
+
/** Nombre accesible del panel cuando es `interactive` (rol `dialog`). */
|
|
3696
|
+
readonly kfPopoverLabel: _angular_core.InputSignal<string | null>;
|
|
3697
|
+
/** Emite `true` al abrirse y `false` al cerrarse. */
|
|
3698
|
+
readonly kfPopoverOpenChange: _angular_core.OutputEmitterRef<boolean>;
|
|
3699
|
+
private readonly host;
|
|
3700
|
+
private readonly overlayService;
|
|
3701
|
+
private readonly viewContainerRef;
|
|
3702
|
+
private readonly injector;
|
|
3703
|
+
private readonly document;
|
|
3704
|
+
private readonly destroyRef;
|
|
3705
|
+
private readonly panelId;
|
|
3706
|
+
private readonly openState;
|
|
3707
|
+
/** `true` mientras el panel está abierto. */
|
|
3708
|
+
readonly isOpen: _angular_core.Signal<boolean>;
|
|
3709
|
+
/**
|
|
3710
|
+
* Elemento que recibe los eventos de puntero, foco y teclado: el propio
|
|
3711
|
+
* anfitrión o, si este no es interactivo pero vive dentro de un control
|
|
3712
|
+
* (botón, enlace, `tabindex`), ese control. `aria-describedby` va en él.
|
|
3713
|
+
*/
|
|
3714
|
+
private trigger;
|
|
3715
|
+
private overlayRef;
|
|
3716
|
+
private panelElement;
|
|
3717
|
+
private showTimer;
|
|
3718
|
+
private hideTimer;
|
|
3719
|
+
private openedAt;
|
|
3720
|
+
private teardownGlobalListeners;
|
|
3721
|
+
private destroyed;
|
|
3722
|
+
private pointerOnHost;
|
|
3723
|
+
private pointerOnPanel;
|
|
3724
|
+
private focusOnHost;
|
|
3725
|
+
private focusOnPanel;
|
|
3726
|
+
/** Escape lo descartó: no reabre hasta que puntero y foco hayan salido. */
|
|
3727
|
+
private dismissed;
|
|
3728
|
+
constructor();
|
|
3729
|
+
ngOnDestroy(): void;
|
|
3730
|
+
/** Cierra el panel de inmediato, sin retardo. */
|
|
3731
|
+
close(): void;
|
|
3732
|
+
private readonly onHostPointerEnter;
|
|
3733
|
+
private readonly onHostPointerLeave;
|
|
3734
|
+
private readonly onHostFocusIn;
|
|
3735
|
+
private readonly onHostFocusOut;
|
|
3736
|
+
private readonly onHostKeydown;
|
|
3737
|
+
private get wanted();
|
|
3738
|
+
/** Abre o cierra según los cuatro orígenes (puntero/foco × anfitrión/panel). */
|
|
3739
|
+
private reevaluate;
|
|
3740
|
+
private scheduleOpen;
|
|
3741
|
+
private scheduleClose;
|
|
3742
|
+
private open;
|
|
3743
|
+
private dispose;
|
|
3744
|
+
private onPanelFocusOut;
|
|
3745
|
+
/** Mayús+Tab desde el primer control del panel devuelve el foco al anfitrión. */
|
|
3746
|
+
private readonly onPanelKeydown;
|
|
3747
|
+
private focusHost;
|
|
3748
|
+
/**
|
|
3749
|
+
* Escape, scroll y resize mientras el panel está abierto. En fase de captura
|
|
3750
|
+
* y sobre `document`: `scroll` no burbujea (hay que capturarlo para ver el
|
|
3751
|
+
* de cualquier contenedor) y Escape debe cerrar primero el popover sin
|
|
3752
|
+
* llegar al modal o drawer que lo contenga.
|
|
3753
|
+
*/
|
|
3754
|
+
private listenGlobal;
|
|
3755
|
+
private resolveTrigger;
|
|
3756
|
+
/** Foco de teclado (`:focus-visible`); sin soporte del selector, se asume teclado. */
|
|
3757
|
+
private isKeyboardFocus;
|
|
3758
|
+
private addDescribedBy;
|
|
3759
|
+
private removeDescribedBy;
|
|
3760
|
+
private describedByTokens;
|
|
3761
|
+
private clearShowTimer;
|
|
3762
|
+
private clearHideTimer;
|
|
3763
|
+
private clearTimers;
|
|
3764
|
+
/**
|
|
3765
|
+
* Posiciones en orden de preferencia: el lado pedido (centrado, luego
|
|
3766
|
+
* alineado al inicio y al final del anfitrión), el lado opuesto con las
|
|
3767
|
+
* mismas tres alineaciones y, por último, los dos lados perpendiculares.
|
|
3768
|
+
* Así un anfitrión pegado a una esquina encuentra una posición que cabe
|
|
3769
|
+
* entera en vez de depender solo del empuje al viewport.
|
|
3770
|
+
*/
|
|
3771
|
+
private positionsFor;
|
|
3772
|
+
private positionFor;
|
|
3773
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PopoverDirective, never>;
|
|
3774
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<PopoverDirective, "[kfPopover]", ["kfPopover"], { "kfPopover": { "alias": "kfPopover"; "required": true; "isSignal": true; }; "kfPopoverPlacement": { "alias": "kfPopoverPlacement"; "required": false; "isSignal": true; }; "kfPopoverShowDelay": { "alias": "kfPopoverShowDelay"; "required": false; "isSignal": true; }; "kfPopoverHideDelay": { "alias": "kfPopoverHideDelay"; "required": false; "isSignal": true; }; "kfPopoverDisabled": { "alias": "kfPopoverDisabled"; "required": false; "isSignal": true; }; "kfPopoverInteractive": { "alias": "kfPopoverInteractive"; "required": false; "isSignal": true; }; "kfPopoverLabel": { "alias": "kfPopoverLabel"; "required": false; "isSignal": true; }; }, { "kfPopoverOpenChange": "kfPopoverOpenChange"; }, never, never, true, never>;
|
|
3775
|
+
}
|
|
3776
|
+
|
|
2921
3777
|
/** Un ítem de navegación de la barra de marca. `icon` es opcional y solo se
|
|
2922
3778
|
* usa en el drawer mobile (columna, ver template) — el `<nav>` horizontal de
|
|
2923
3779
|
* escritorio se mantiene solo texto, sin ícono ni chevron. */
|
|
@@ -3052,9 +3908,12 @@ declare class PortalHeader {
|
|
|
3052
3908
|
* que no aplican a un valor de progreso): `neutral` es el color de marca
|
|
3053
3909
|
* por defecto (sin implicar buen/mal estado), `primary` es el color
|
|
3054
3910
|
* primario para un avance de proceso (ej. una carga), y `ok`/`warn`/`error`
|
|
3055
|
-
* sí comunican severidad.
|
|
3911
|
+
* sí comunican severidad. `purple` es el acento morado de marca, igual al tono
|
|
3912
|
+
* `purple` de `kf-stat-card`. La librería no conoce el dominio que produce ese
|
|
3056
3913
|
* valor (SLA, storage, lo que sea) — el consumidor decide qué tone usar. */
|
|
3057
|
-
type ProgressTone = 'neutral' | 'primary' | 'ok' | 'warn' | 'error';
|
|
3914
|
+
type ProgressTone = 'neutral' | 'primary' | 'ok' | 'warn' | 'error' | 'purple';
|
|
3915
|
+
/** Grosor de la pista: `sm` 4px (el histórico), `md` 8px, `lg` 12px. */
|
|
3916
|
+
type ProgressSize = 'sm' | 'md' | 'lg';
|
|
3058
3917
|
/**
|
|
3059
3918
|
* Barra de progreso de un solo valor (0-100%) con color por severidad —
|
|
3060
3919
|
* para un porcentaje simple, a diferencia de `kf-bucket-progress`, que
|
|
@@ -3065,16 +3924,24 @@ type ProgressTone = 'neutral' | 'primary' | 'ok' | 'warn' | 'error';
|
|
|
3065
3924
|
*
|
|
3066
3925
|
* `value` se clampea a [0, 100] — un consumidor que calcule un ratio fuera
|
|
3067
3926
|
* de rango (ej. tiempo transcurrido sobre un SLA ya vencido) no rompe el
|
|
3068
|
-
* ancho de la barra. `
|
|
3927
|
+
* ancho de la barra. `size` cambia el grosor de la pista (`sm` 4px, `md` 8px,
|
|
3928
|
+
* `lg` 12px; sin él, 4px como siempre); el `role="progressbar"` y sus valores
|
|
3929
|
+
* accesibles no cambian. `label` es texto libre opcional sobre la barra (ej.
|
|
3069
3930
|
* "80%"); sin él, no se renderiza ningún texto, solo la barra.
|
|
3070
3931
|
*/
|
|
3071
3932
|
declare class Progress {
|
|
3072
3933
|
readonly value: _angular_core.InputSignal<number>;
|
|
3073
3934
|
readonly tone: _angular_core.InputSignal<ProgressTone>;
|
|
3935
|
+
/** Grosor de la pista. Default `sm` (4px). */
|
|
3936
|
+
readonly size: _angular_core.InputSignal<ProgressSize>;
|
|
3074
3937
|
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
3938
|
+
/** Nombre accesible de la barra (`aria-label`). Sin él, el `progressbar`
|
|
3939
|
+
* queda sin nombre: dalo siempre que el contexto no lo nombre ya (por
|
|
3940
|
+
* ejemplo con un `label` visible asociado). */
|
|
3941
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
3075
3942
|
protected readonly clampedValue: _angular_core.Signal<number>;
|
|
3076
3943
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Progress, never>;
|
|
3077
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Progress, "kf-progress", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
3944
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Progress, "kf-progress", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
3078
3945
|
}
|
|
3079
3946
|
|
|
3080
3947
|
/**
|
|
@@ -3390,10 +4257,27 @@ interface SelectOption {
|
|
|
3390
4257
|
* buscador, si está visible). En el panel, flechas y Home/End mueven el
|
|
3391
4258
|
* foco, Enter/Espacio eligen, Escape cierra y devuelve el foco al trigger,
|
|
3392
4259
|
* y Tab cierra el panel y continúa la tabulación desde el trigger. Las
|
|
3393
|
-
* opciones nunca son paradas de Tab (`tabindex="-1"`).
|
|
4260
|
+
* opciones nunca son paradas de Tab (`tabindex="-1"`). Home/End sobre el
|
|
4261
|
+
* trigger cerrado lo abren en la primera/última opción, y teclear letras
|
|
4262
|
+
* (con el panel abierto o cerrado, sin buscador) salta a la opción cuyo
|
|
4263
|
+
* label empieza con lo tecleado; repetir la misma letra recorre las que
|
|
4264
|
+
* empiezan igual.
|
|
3394
4265
|
*/
|
|
3395
4266
|
declare class Select {
|
|
3396
4267
|
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
4268
|
+
/**
|
|
4269
|
+
* Oculta el `label` a la vista y lo deja como nombre accesible (`<label
|
|
4270
|
+
* for>`): para un control cuyo valor se explica solo (ej. un rango de
|
|
4271
|
+
* fechas), sin tener que ocultar la etiqueta con CSS desde afuera.
|
|
4272
|
+
*/
|
|
4273
|
+
readonly hideLabel: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
4274
|
+
/**
|
|
4275
|
+
* Texto corto visible dentro del trigger, antes del valor (ej. `Rango:
|
|
4276
|
+
* Últimos 30 días`), para un select compacto que no lleva etiqueta
|
|
4277
|
+
* encima. Forma parte del nombre accesible del botón: no combinarlo con
|
|
4278
|
+
* `label`/`ariaLabel`, que reemplazarían ese nombre.
|
|
4279
|
+
*/
|
|
4280
|
+
readonly prefix: _angular_core.InputSignal<string | undefined>;
|
|
3397
4281
|
readonly options: _angular_core.InputSignal<readonly (string | SelectOption)[]>;
|
|
3398
4282
|
readonly value: _angular_core.InputSignal<string | undefined>;
|
|
3399
4283
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
@@ -3402,7 +4286,7 @@ declare class Select {
|
|
|
3402
4286
|
readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3403
4287
|
/** Mensaje de error con `role="alert"`, debajo del trigger. */
|
|
3404
4288
|
readonly errorMessage: _angular_core.InputSignal<string | undefined>;
|
|
3405
|
-
readonly variant: _angular_core.InputSignal<"
|
|
4289
|
+
readonly variant: _angular_core.InputSignal<"field" | "compact">;
|
|
3406
4290
|
/**
|
|
3407
4291
|
* Ancho del control. 'md' (240px) es el default histórico y preserva el
|
|
3408
4292
|
* comportamiento actual sin cambios para consumidores existentes.
|
|
@@ -3465,15 +4349,21 @@ declare class Select {
|
|
|
3465
4349
|
private readonly searchInputRef;
|
|
3466
4350
|
private readonly panelRef;
|
|
3467
4351
|
private readonly document;
|
|
4352
|
+
private typeaheadBuffer;
|
|
4353
|
+
private typeaheadTimer;
|
|
3468
4354
|
private readonly overlay;
|
|
3469
4355
|
constructor();
|
|
3470
4356
|
/**
|
|
3471
|
-
*
|
|
3472
|
-
*
|
|
3473
|
-
*
|
|
3474
|
-
*
|
|
4357
|
+
* Escape con el panel abierto, escuchado en fase de captura sobre
|
|
4358
|
+
* `document` (ver `listenEscapeCapture`). Respaldo de
|
|
4359
|
+
* `overlayRef.keydownEvents()`: ese observable del CDK solo ve teclas
|
|
4360
|
+
* presionadas con el foco DENTRO del pane del overlay; si el foco sigue en
|
|
4361
|
+
* el trigger (o en cualquier otro lado) mientras el panel está abierto,
|
|
4362
|
+
* nunca dispara. Consume la tecla (`preventDefault`) solo si había un
|
|
4363
|
+
* panel que cerrar, así un `kf-drawer`/`kf-modal` que contenga al select
|
|
4364
|
+
* no se cierra con el mismo Escape. Devuelve si cerró algo.
|
|
3475
4365
|
*/
|
|
3476
|
-
onDocumentEscape():
|
|
4366
|
+
onDocumentEscape(): boolean;
|
|
3477
4367
|
toggle(): void;
|
|
3478
4368
|
/** Abre el panel con la opción seleccionada como activa (o la primera). */
|
|
3479
4369
|
open(): void;
|
|
@@ -3484,7 +4374,11 @@ declare class Select {
|
|
|
3484
4374
|
* click afuera no lo restaura: el foco ya se fue a donde se hizo click.
|
|
3485
4375
|
*/
|
|
3486
4376
|
close(restoreFocus?: boolean): void;
|
|
3487
|
-
/**
|
|
4377
|
+
/**
|
|
4378
|
+
* Con el panel cerrado: ArrowDown/ArrowUp lo abren en la opción activa,
|
|
4379
|
+
* Home/End en la primera/última, y una letra lo abre en la opción que
|
|
4380
|
+
* empieza con ella (patrón listbox).
|
|
4381
|
+
*/
|
|
3488
4382
|
onTriggerKeydown(event: KeyboardEvent): void;
|
|
3489
4383
|
/**
|
|
3490
4384
|
* Teclado con el foco en una opción del panel. Las flechas parten SIEMPRE
|
|
@@ -3493,6 +4387,15 @@ declare class Select {
|
|
|
3493
4387
|
* foco en la opción 1 y el mouse sobre la 4, ArrowDown saltaría a la 5.
|
|
3494
4388
|
*/
|
|
3495
4389
|
onOptionKeydown(event: KeyboardEvent, option: SelectOption, index: number): void;
|
|
4390
|
+
/** Un carácter imprimible sin modificadores, y solo cuando no hay buscador (ahí la tecla filtra). */
|
|
4391
|
+
private isTypeaheadKey;
|
|
4392
|
+
/**
|
|
4393
|
+
* Índice de la opción cuyo label empieza con lo tecleado, o -1. Una sola
|
|
4394
|
+
* letra (o la misma repetida) busca desde la opción SIGUIENTE a `from`, para
|
|
4395
|
+
* recorrer las que empiezan igual; un prefijo más largo busca desde `from`
|
|
4396
|
+
* inclusive, para que la opción actual se conserve mientras siga coincidiendo.
|
|
4397
|
+
*/
|
|
4398
|
+
private findTypeaheadMatch;
|
|
3496
4399
|
/** Teclas de salida del buscador: Escape y Tab, igual que desde una opción. */
|
|
3497
4400
|
onSearchKeydown(event: KeyboardEvent): void;
|
|
3498
4401
|
/**
|
|
@@ -3527,7 +4430,7 @@ declare class Select {
|
|
|
3527
4430
|
private scrollActiveIntoView;
|
|
3528
4431
|
selectActive(): void;
|
|
3529
4432
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Select, never>;
|
|
3530
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Select, "kf-select", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchThreshold": { "alias": "searchThreshold"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "panelTitle": { "alias": "panelTitle"; "required": false; "isSignal": true; }; "panelWidth": { "alias": "panelWidth"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
4433
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Select, "kf-select", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchThreshold": { "alias": "searchThreshold"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "panelTitle": { "alias": "panelTitle"; "required": false; "isSignal": true; }; "panelWidth": { "alias": "panelWidth"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
3531
4434
|
}
|
|
3532
4435
|
|
|
3533
4436
|
interface SelectableCardOption {
|
|
@@ -3714,7 +4617,9 @@ declare class Spinner {
|
|
|
3714
4617
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Spinner, "kf-spinner", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "onDark": { "alias": "onDark"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
3715
4618
|
}
|
|
3716
4619
|
|
|
3717
|
-
type StatCardTone = 'primary' | 'success' | 'error' | 'purple';
|
|
4620
|
+
type StatCardTone = 'primary' | 'success' | 'error' | 'purple' | 'warn' | 'info' | 'neutral';
|
|
4621
|
+
/** Densidad de la card: `'compact'` reduce el padding, el ícono y el valor. */
|
|
4622
|
+
type StatCardDensity = 'default' | 'compact';
|
|
3718
4623
|
/**
|
|
3719
4624
|
* Card de estadística horizontal: ícono circular grande a la izquierda,
|
|
3720
4625
|
* valor + label + nota apilados al centro, chevron opcional al final si es
|
|
@@ -3723,6 +4628,43 @@ type StatCardTone = 'primary' | 'success' | 'error' | 'purple';
|
|
|
3723
4628
|
* otorgados", "Cortesías otorgadas"), no una variante de la misma card.
|
|
3724
4629
|
*
|
|
3725
4630
|
* <kf-stat-card icon="gift" tone="purple" value="4" label="Bonos otorgados" note="$15,000.00 en beneficios" (cardClick)="onNavigate('beneficios')" />
|
|
4631
|
+
*
|
|
4632
|
+
* Extensiones opcionales (la card sin ellas se ve y se comporta como siempre):
|
|
4633
|
+
* - `tone`: además de `primary|success|error|purple`, `warn`, `info` y `neutral`.
|
|
4634
|
+
* - `bar` (0-100): barra de progreso accesible (`kf-progress`, `role="progressbar"`
|
|
4635
|
+
* con `aria-valuenow`/`min`/`max` y el `label` como nombre) bajo la nota. Se
|
|
4636
|
+
* acota a [0, 100]; `null`/`undefined` no la dibuja. Es un refuerzo visual:
|
|
4637
|
+
* el valor exacto conviene darlo también en texto (`hint`), porque el relleno
|
|
4638
|
+
* de algunos tonos de `kf-progress` tiene poco contraste con su pista.
|
|
4639
|
+
* - `hint`: texto secundario bajo la barra (ej. "12 de 20 completadas").
|
|
4640
|
+
* - `pressed` (`boolean | null`): con `clickable`, la card es un botón de
|
|
4641
|
+
* alternancia (`aria-pressed`), útil como filtro. `null` (default) = no
|
|
4642
|
+
* aplica y no emite el atributo. Sin `clickable` no tiene efecto.
|
|
4643
|
+
*
|
|
4644
|
+
* <kf-stat-card icon="clock" tone="warn" value="7" label="Por vencer" [bar]="35" hint="7 de 20"
|
|
4645
|
+
* clickable [pressed]="filter() === 'due'" (cardClick)="toggle('due')" />
|
|
4646
|
+
*
|
|
4647
|
+
* `density` (`'default'` | `'compact'`): `'compact'` es la variante para
|
|
4648
|
+
* pantallas angostas — padding de `--kf-space-md`, ícono de 40px y valor de
|
|
4649
|
+
* `--kf-font-size-title-sm`, con el mismo contenido. Si la card mide 210px de
|
|
4650
|
+
* ancho o menos (ej. una grilla 2x2 en teléfono), pasa además a dos filas:
|
|
4651
|
+
* ícono y valor en la primera, y label, nota, barra y `hint` debajo a todo el
|
|
4652
|
+
* ancho; el chevron se oculta. Solo la variante compacta convierte el host en
|
|
4653
|
+
* contenedor de tamaño (`container-type: inline-size`), así que debe tener un
|
|
4654
|
+
* ancho que no dependa de su contenido (celda de grilla, `width` explícito o
|
|
4655
|
+
* hijo de un contenedor en bloque). `'default'` no cambia nada.
|
|
4656
|
+
*
|
|
4657
|
+
* <kf-stat-card density="compact" icon="clock" value="7" label="Por vencer" />
|
|
4658
|
+
*
|
|
4659
|
+
* `loading` (default `false`): mientras es `true` la card dibuja su esqueleto
|
|
4660
|
+
* en vez del contenido, con el MISMO cascarón (borde, padding, ícono de 50px)
|
|
4661
|
+
* y líneas del alto real de cada texto — valor, etiqueta y, si se pasaron,
|
|
4662
|
+
* nota, barra y `hint` —, así que al llegar los datos no hay salto de
|
|
4663
|
+
* layout. Pasa los mismos inputs que usarás cargada para que el esqueleto
|
|
4664
|
+
* reserve las mismas líneas. Marca la card con `aria-busy="true"`, no es
|
|
4665
|
+
* clicable ni expone su texto a lectores de pantalla mientras carga.
|
|
4666
|
+
*
|
|
4667
|
+
* <kf-stat-card icon="clock" value="7" label="Por vencer" note="Esta semana" [loading]="isLoading()" />
|
|
3726
4668
|
*/
|
|
3727
4669
|
declare class StatCard {
|
|
3728
4670
|
readonly icon: _angular_core.InputSignal<IconName>;
|
|
@@ -3730,11 +4672,26 @@ declare class StatCard {
|
|
|
3730
4672
|
readonly value: _angular_core.InputSignal<string | number>;
|
|
3731
4673
|
readonly label: _angular_core.InputSignal<string>;
|
|
3732
4674
|
readonly note: _angular_core.InputSignal<string | undefined>;
|
|
4675
|
+
/** Avance 0-100 (barra de progreso accesible); `null`/`undefined` = sin barra. */
|
|
4676
|
+
readonly bar: _angular_core.InputSignal<number | null | undefined>;
|
|
4677
|
+
/** Texto secundario bajo la barra (o bajo la nota si no hay barra). */
|
|
4678
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
4679
|
+
/**
|
|
4680
|
+
* Estado de alternancia (`aria-pressed`) cuando la card es `clickable`.
|
|
4681
|
+
* `null` (default) = no aplica: el atributo no se emite.
|
|
4682
|
+
*/
|
|
4683
|
+
readonly pressed: _angular_core.InputSignal<boolean | null>;
|
|
4684
|
+
/** `'compact'`: variante para pantallas angostas; `'default'` no cambia la card. */
|
|
4685
|
+
readonly density: _angular_core.InputSignal<StatCardDensity>;
|
|
4686
|
+
/** Dibuja el esqueleto en lugar del contenido, conservando las dimensiones. */
|
|
4687
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3733
4688
|
/** Si se escucha `cardClick`, la card se renderiza como botón clickeable con chevron. */
|
|
3734
4689
|
readonly clickable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3735
4690
|
readonly cardClick: _angular_core.OutputEmitterRef<void>;
|
|
4691
|
+
protected readonly barTone: _angular_core.Signal<ProgressTone>;
|
|
4692
|
+
protected readonly hasBar: _angular_core.Signal<boolean>;
|
|
3736
4693
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatCard, never>;
|
|
3737
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StatCard, "kf-stat-card", never, { "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "note": { "alias": "note"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; }, { "cardClick": "cardClick"; }, never, never, true, never>;
|
|
4694
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StatCard, "kf-stat-card", never, { "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "note": { "alias": "note"; "required": false; "isSignal": true; }; "bar": { "alias": "bar"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "pressed": { "alias": "pressed"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; }, { "cardClick": "cardClick"; }, never, never, true, never>;
|
|
3738
4695
|
}
|
|
3739
4696
|
|
|
3740
4697
|
/** Vocabulario semántico único de tono, compartido con `TextTone`. */
|
|
@@ -3792,6 +4749,57 @@ declare class StatTile {
|
|
|
3792
4749
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StatTile, "kf-stat-tile", never, { "cta": { "alias": "cta"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "note": { "alias": "note"; "required": false; "isSignal": true; }; "notePlaceholder": { "alias": "notePlaceholder"; "required": false; "isSignal": true; }; "valueMissing": { "alias": "valueMissing"; "required": false; "isSignal": true; }; "hasProjectedValue": { "alias": "hasProjectedValue"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionHref": { "alias": "actionHref"; "required": false; "isSignal": true; }; }, { "actionClick": "actionClick"; }, never, ["[valueContent]"], true, never>;
|
|
3793
4750
|
}
|
|
3794
4751
|
|
|
4752
|
+
/**
|
|
4753
|
+
* Marca pequeña de estado para leyendas y listas de hitos: círculo relleno
|
|
4754
|
+
* con check (completado), anillo con punto (en curso) o anillo vacío
|
|
4755
|
+
* (pendiente). La forma comunica el estado y el color solo lo refuerza.
|
|
4756
|
+
* `exception` la pinta con borde discontinuo y tono de aviso.
|
|
4757
|
+
*
|
|
4758
|
+
* Es decorativa por defecto (`aria-hidden`): el texto del estado va en el
|
|
4759
|
+
* contexto que la usa. Para usarla suelta (ej. una leyenda sin texto al lado),
|
|
4760
|
+
* `label` la expone como imagen con ese nombre.
|
|
4761
|
+
*
|
|
4762
|
+
* <kf-status-mark status="done" small />
|
|
4763
|
+
* <kf-status-mark status="current" label="En curso" />
|
|
4764
|
+
*
|
|
4765
|
+
* Tamaño: variables CSS `--kf-status-mark-size` y `--kf-status-mark-size-sm`.
|
|
4766
|
+
*/
|
|
4767
|
+
declare class StatusMark {
|
|
4768
|
+
readonly status: _angular_core.InputSignal<ProgressStatus>;
|
|
4769
|
+
/** Versión reducida, para listas de hitos. */
|
|
4770
|
+
readonly small: _angular_core.InputSignal<boolean>;
|
|
4771
|
+
/** Hito de excepción: borde discontinuo y tono de aviso. */
|
|
4772
|
+
readonly exception: _angular_core.InputSignal<boolean>;
|
|
4773
|
+
/** Nombre accesible; sin él la marca es decorativa. */
|
|
4774
|
+
readonly label: _angular_core.InputSignal<string | null>;
|
|
4775
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatusMark, never>;
|
|
4776
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StatusMark, "kf-status-mark", never, { "status": { "alias": "status"; "required": true; "isSignal": true; }; "small": { "alias": "small"; "required": false; "isSignal": true; }; "exception": { "alias": "exception"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
4777
|
+
}
|
|
4778
|
+
|
|
4779
|
+
/**
|
|
4780
|
+
* Nodo circular de una etapa: ícono de la etapa más una insignia de estado.
|
|
4781
|
+
* La forma comunica el estado (relleno con check, anillo con punto, anillo
|
|
4782
|
+
* vacío) y el color solo lo refuerza.
|
|
4783
|
+
*
|
|
4784
|
+
* Es decorativo por defecto (`aria-hidden`): el texto del estado debe estar en
|
|
4785
|
+
* el contexto que lo usa. Para usarlo suelto, `label` lo expone como imagen
|
|
4786
|
+
* con ese nombre.
|
|
4787
|
+
*
|
|
4788
|
+
* <kf-status-node status="current" icon="truck" />
|
|
4789
|
+
* <kf-status-node status="done" icon="check" size="sm" label="Entrega completada" />
|
|
4790
|
+
*
|
|
4791
|
+
* Tamaño: variables CSS `--kf-status-node-size` y `--kf-status-node-size-sm`.
|
|
4792
|
+
*/
|
|
4793
|
+
declare class StatusNode {
|
|
4794
|
+
readonly status: _angular_core.InputSignal<ProgressStatus>;
|
|
4795
|
+
readonly icon: _angular_core.InputSignal<IconName>;
|
|
4796
|
+
readonly size: _angular_core.InputSignal<"sm" | "md">;
|
|
4797
|
+
/** Nombre accesible; sin él el nodo es decorativo. */
|
|
4798
|
+
readonly label: _angular_core.InputSignal<string | null>;
|
|
4799
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatusNode, never>;
|
|
4800
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StatusNode, "kf-status-node", never, { "status": { "alias": "status"; "required": true; "isSignal": true; }; "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
4801
|
+
}
|
|
4802
|
+
|
|
3795
4803
|
/**
|
|
3796
4804
|
* Pill con borde, en mayúsculas y con letter-spacing, pensada para indicadores
|
|
3797
4805
|
* de estado únicos y prominentes (ej. "ESTADO TÉCNICO"). El fondo es siempre
|
|
@@ -3801,7 +4809,7 @@ declare class StatTile {
|
|
|
3801
4809
|
* <kf-status-pill tone="error" dot>Fuera de servicio</kf-status-pill>
|
|
3802
4810
|
*/
|
|
3803
4811
|
declare class StatusPill {
|
|
3804
|
-
readonly tone: _angular_core.InputSignal<"
|
|
4812
|
+
readonly tone: _angular_core.InputSignal<"ok" | "warn" | "error" | "blue">;
|
|
3805
4813
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3806
4814
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatusPill, never>;
|
|
3807
4815
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StatusPill, "kf-status-pill", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
@@ -4065,7 +5073,12 @@ interface ToastAction {
|
|
|
4065
5073
|
interface ToastOptions {
|
|
4066
5074
|
/** Color tone. Defaults to `'info'`. */
|
|
4067
5075
|
tone?: ToastTone;
|
|
4068
|
-
/**
|
|
5076
|
+
/**
|
|
5077
|
+
* Milliseconds before auto-dismiss. Ignored when `tone` is `'loading'`. When
|
|
5078
|
+
* omitted it depends on the tone (see {@link TOAST_DEFAULT_DURATION_MS}):
|
|
5079
|
+
* `2800` for `success`/`info`, `5000` for `warning`, `8000` for `error`. An
|
|
5080
|
+
* explicit value always wins over the per-tone default.
|
|
5081
|
+
*/
|
|
4069
5082
|
duration?: number;
|
|
4070
5083
|
/** Botón de acción opcional, ej. ir al registro sobre el que avisa el toast. */
|
|
4071
5084
|
action?: ToastAction;
|
|
@@ -4085,6 +5098,13 @@ interface ToastState {
|
|
|
4085
5098
|
leaving: boolean;
|
|
4086
5099
|
action?: ToastAction;
|
|
4087
5100
|
}
|
|
5101
|
+
/**
|
|
5102
|
+
* Auto-dismiss time per tone when the caller doesn't pass `duration`. Errors and
|
|
5103
|
+
* warnings stay longer than confirmations: they carry something to read and
|
|
5104
|
+
* act on, while a success only has to be noticed. `success`/`info` keep the
|
|
5105
|
+
* historical 2800ms. `loading` never auto-dismisses.
|
|
5106
|
+
*/
|
|
5107
|
+
declare const TOAST_DEFAULT_DURATION_MS: Readonly<Record<Exclude<ToastTone, 'loading'>, number>>;
|
|
4088
5108
|
/** What's currently holding the auto-dismiss timer paused. Tracked as a set so hover and
|
|
4089
5109
|
* focus can overlap (e.g. mouse leaves while focus is still on the action button) without
|
|
4090
5110
|
* resuming the timer early. */
|
|
@@ -4093,6 +5113,11 @@ type ToastPauseSource = 'hover' | 'focus';
|
|
|
4093
5113
|
* Shows one toast at a time — a new `show()` call replaces whatever is
|
|
4094
5114
|
* currently up (this mirrors a global status line, not a notification stack).
|
|
4095
5115
|
*
|
|
5116
|
+
* Duration by tone (when `duration` isn't passed): `success`/`info` 2800ms,
|
|
5117
|
+
* `warning` 5000ms, `error` 8000ms (`TOAST_DEFAULT_DURATION_MS`); an explicit
|
|
5118
|
+
* `duration` always wins. The countdown pauses while the pointer or focus is
|
|
5119
|
+
* on the toast. Error toasts also get a larger, always-opaque close button.
|
|
5120
|
+
*
|
|
4096
5121
|
* Angular has no global function that can mount UI on its own, so the
|
|
4097
5122
|
* imperative `showToast(...)` of the reference design system becomes a
|
|
4098
5123
|
* root-provided service holding signal state: `ToastService.show(...)` sets
|
|
@@ -4271,5 +5296,5 @@ declare class ViewToggle {
|
|
|
4271
5296
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ViewToggle, "kf-view-toggle", never, { "view": { "alias": "view"; "required": true; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; "tableLabel": { "alias": "tableLabel"; "required": false; "isSignal": true; }; "cardsLabel": { "alias": "cardsLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "viewChange": "viewChange"; }, never, never, true, never>;
|
|
4272
5297
|
}
|
|
4273
5298
|
|
|
4274
|
-
export { ActionTile, AdminBadge, Alert, AlertRow, Avatar, Badge, Breadcrumb, BucketProgress, Button, Calendar, Card, Carousel, CarouselSlide, Checkbox, Chip, Collapsible, ContactPopover, ContentSlot, ContentState, ContentViewer, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, Divider, DocumentRow, Drawer, Dropdown, DropdownItem, DropdownPanel, EmptyState, EventTimeline, FeatureCard, Field, FieldLabel, Filter, FilterChips, FolderTabs, FolderTabsPanel, Footer, FormatInputDirective, Icon, Input, JourneyStepper, LIST_TOOLBAR_HYSTERESIS, Link, ListToolbar, MetricCard, Modal, MultiSelect, NoteBlock, OptionList, PageHeader, Pagination, Panel, PortalHeader, Progress, PulseDot, RowActions, SectionHeader, SectionNav, SectionNavItem, SectionNavSubsection, Segmented, Select, SelectableCardGroup, SidebarShell, Skeleton, Spinner, StatCard, StatTile, StatusPill, Tabs, Text, Textarea, TileGrid, TimeSlotPicker, ToastHost, ToastService, TooltipDirective, ViewToggle, dataTableViewSignal, resolveListToolbarMode };
|
|
4275
|
-
export type { AlertRowTone, AlertTone, BreadcrumbItem, BucketProgressItem, CalendarDay, ContentStateKind, ContentStateLoad, ContentViewerType, DataTableCardRole, DataTableColumn, DataTableDensity, DataTableSort, DataTableView, DividerOrientation, DocumentRowTone, DrawerRole, DrawerSide, DropdownItemTone, DropdownPanelVariant, EmptyStateTone, EventTimelineItem, EventTimelineTone, FilterChipOption, FilterFieldChange, FilterFieldConfig, FilterFieldType, FilterValue, FolderTabOption, FooterLink, IconName, IconRotation, IconSize, JourneyStep, JourneyStepStatus, JourneyStepperColorScheme, JourneyStepperSurface, LinkVariant, ListToolbarMode, MultiSelectOption, NoteBlockTone, OptionListOption, PageHeaderTitleSize, PaginationItem, PortalHeaderAdminAction, PortalHeaderNavItem, ProgressTone, RowAction, RowActionKind, RowActionsMode, SectionNavSubsectionData, SegmentedOption, SelectOption, SelectableCardOption, SidebarNavItemData, SkeletonVariant, SpinnerSize, StatCardTone, StatTileTone, StatTileVariant, TabOption, TextAs, TextTone, TextVariant, TimeSlot, ToastAction, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, TooltipPosition, ViewToggleOption };
|
|
5299
|
+
export { ActionTile, AdminBadge, Alert, AlertRow, Avatar, Badge, Breadcrumb, BucketProgress, Button, Calendar, Card, Carousel, CarouselSlide, Checkbox, Chip, Collapsible, ContactPopover, ContentSlot, ContentState, ContentStateLoading, ContentViewer, CursorPager, DATA_TABLE_MAX_SKELETON_ROWS, DEFAULT_MILESTONE_TIMELINE_LABELS, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, Divider, DocumentRow, Drawer, Dropdown, DropdownItem, DropdownPanel, EmptyState, EventTimeline, FeatureCard, Field, FieldLabel, FileInput, Filter, FilterChips, FolderTabs, FolderTabsPanel, Footer, FormatInputDirective, Icon, Input, JourneyStepper, LIST_TOOLBAR_HYSTERESIS, Link, ListToolbar, MetricCard, MilestoneTimeline, Modal, MultiSelect, NoteBlock, OptionList, PROGRESS_STATUS, PROGRESS_STATUS_LABEL, PageHeader, Pagination, Panel, PopoverDirective, PortalHeader, Progress, PulseDot, RowActions, SKELETON_PRESET_MAX_COUNT, SectionHeader, SectionNav, SectionNavItem, SectionNavSubsection, Segmented, Select, SelectableCardGroup, SidebarShell, Skeleton, SkeletonPreset, Spinner, StatCard, StatTile, StatusMark, StatusNode, StatusPill, TOAST_DEFAULT_DURATION_MS, Tabs, Text, Textarea, TileGrid, TimeSlotPicker, ToastHost, ToastService, TooltipDirective, ViewToggle, dataTableViewSignal, formatFileSize, resolveListToolbarMode };
|
|
5300
|
+
export type { AlertRowTone, AlertTone, AlertVariant, BreadcrumbItem, BucketProgressItem, CalendarDay, ContentStateKind, ContentStateLoad, ContentViewerType, DataTableCardRole, DataTableCellClick, DataTableColumn, DataTableDensity, DataTableSort, DataTableView, DividerOrientation, DocumentRowTone, DrawerRole, DrawerSide, DropdownItemTone, DropdownPanelRole, DropdownPanelVariant, EmptyStateTone, EventTimelineItem, EventTimelineTone, FileRejection, FileRejectionReason, FilterChipOption, FilterFieldChange, FilterFieldConfig, FilterFieldType, FilterValue, FolderTabOption, FooterLink, IconName, IconRotation, IconSize, InputBound, JourneyStep, JourneyStepStatus, JourneyStepperColorScheme, JourneyStepperOrientation, JourneyStepperSurface, LinkVariant, ListToolbarMode, MilestoneGroup, MilestoneItem, MilestoneTimelineLabels, MultiSelectOption, NoteBlockTone, OptionListOption, PageHeaderTitleSize, PaginationItem, PopoverPlacement, PortalHeaderAdminAction, PortalHeaderNavItem, ProgressSize, ProgressStatus, ProgressTone, RowAction, RowActionKind, RowActionsMode, SectionNavSubsectionData, SegmentedOption, SelectOption, SelectableCardOption, SidebarNavItemData, SkeletonPresetVariant, SkeletonVariant, SpinnerSize, StatCardDensity, StatCardTone, StatTileTone, StatTileVariant, TabOption, TextAs, TextTone, TextVariant, TimeSlot, ToastAction, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, TooltipPosition, ViewToggleOption };
|