@kaufmann-lab/ui 0.1.18 → 0.1.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaufmann-lab/ui",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "Shared Angular component library for the Kaufmann frontends",
5
5
  "license": "MIT",
6
6
  "author": "Kaufmann Lab",
@@ -8,6 +8,18 @@ interface CompanySelectorMeta {
8
8
  label: string;
9
9
  value: string;
10
10
  }
11
+ /**
12
+ * Empresa elegible. `value` es el identificador único (ej. número de
13
+ * cuenta) — dos empresas con el mismo `label` se seleccionan por separado.
14
+ * `tag` se muestra como badge junto al nombre (ej. 'Personal' | 'Empresa')
15
+ * y `detail` como línea secundaria en el panel (ej. 'RUC 20434860808').
16
+ */
17
+ interface CompanySelectorOption {
18
+ value: string;
19
+ label: string;
20
+ tag?: string;
21
+ detail?: string;
22
+ }
11
23
  /**
12
24
  * Conmutador de empresa activa con metadatos clave (página 32) — encabeza
13
25
  * la pantalla de inicio del portal. Compone `kf-select` para el propio
@@ -25,10 +37,22 @@ interface CompanySelectorMeta {
25
37
  * { label: 'Sucursal', value: 'Sucursal Norte' },
26
38
  * ]"
27
39
  * />
40
+ *
41
+ * Con opciones en forma de objeto, `value`/`valueChange` usan el `value` de
42
+ * la opción, no su nombre:
43
+ *
44
+ * <kf-company-selector
45
+ * [companies]="[
46
+ * { value: '1002099', label: 'DIANA CAROLINA PINZÓN MALDONADO', tag: 'Personal', detail: 'DNI 46594489' },
47
+ * { value: '1004410', label: 'TRANSPORTES VIRGEN DE LA AGRICULTURA', tag: 'Empresa', detail: 'RUC 20434860808' },
48
+ * ]"
49
+ * [value]="activeAccount()"
50
+ * (valueChange)="activeAccount.set($event)"
51
+ * />
28
52
  */
29
53
  declare class CompanySelector {
30
54
  readonly label: _angular_core.InputSignal<string>;
31
- readonly companies: _angular_core.InputSignal<string[]>;
55
+ readonly companies: _angular_core.InputSignal<readonly (string | CompanySelectorOption)[]>;
32
56
  readonly value: _angular_core.InputSignal<string | undefined>;
33
57
  readonly meta: _angular_core.InputSignal<CompanySelectorMeta[]>;
34
58
  readonly valueChange: _angular_core.OutputEmitterRef<string>;
@@ -247,6 +271,15 @@ declare class QuotePicker<T = unknown> {
247
271
  * <kf-button actions icon="calendar">Reservar hora</kf-button>
248
272
  * <kf-button actions variant="outline" icon="list">Ver agenda</kf-button>
249
273
  * </kf-reserve-block>
274
+ *
275
+ * Para apps con router: escuchar `actionClick` y llamar
276
+ * `event.preventDefault()` antes de `router.navigateByUrl(...)`. El
277
+ * `actionHref` se mantiene igual para que click-medio, "abrir en pestaña
278
+ * nueva" y el hover de la barra de estado sigan funcionando.
279
+ *
280
+ * <kf-reserve-block title="¿Necesitas mantención?" actionLabel="Agenda tu reserva aquí"
281
+ * actionHref="/taller/agendar"
282
+ * (actionClick)="$event.preventDefault(); router.navigateByUrl('/taller/agendar')" />
250
283
  */
251
284
  declare class ReserveBlock {
252
285
  readonly emptyLabel: _angular_core.InputSignal<string>;
@@ -256,8 +289,14 @@ declare class ReserveBlock {
256
289
  readonly actionHref: _angular_core.InputSignal<string | undefined>;
257
290
  /** La invitación se estira para llenar la tarjeta (ej. junto a "Total de vehículos"). */
258
291
  readonly grow: _angular_core.InputSignalWithTransform<boolean, unknown>;
292
+ /**
293
+ * Click en el link de la invitación. Incluye el `MouseEvent` para que un
294
+ * consumidor con router pueda cortar la navegación nativa — mismo patrón
295
+ * que `itemClick` de `kf-breadcrumb`, sin depender de `@angular/router`.
296
+ */
297
+ readonly actionClick: _angular_core.OutputEmitterRef<MouseEvent>;
259
298
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ReserveBlock, never>;
260
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<ReserveBlock, "kf-reserve-block", never, { "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionHref": { "alias": "actionHref"; "required": false; "isSignal": true; }; "grow": { "alias": "grow"; "required": false; "isSignal": true; }; }, {}, never, ["[actions]"], true, never>;
299
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ReserveBlock, "kf-reserve-block", never, { "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionHref": { "alias": "actionHref"; "required": false; "isSignal": true; }; "grow": { "alias": "grow"; "required": false; "isSignal": true; }; }, { "actionClick": "actionClick"; }, never, ["[actions]"], true, never>;
261
300
  }
262
301
 
263
302
  /**
@@ -295,4 +334,4 @@ declare class VehicleHeader {
295
334
  }
296
335
 
297
336
  export { CompanySelector, QuotePicker, ReserveBlock, VehicleHeader };
298
- export type { CompanySelectorMeta, QuotePickerChip, QuotePickerSortOption, VehicleHeaderStatus };
337
+ export type { CompanySelectorMeta, CompanySelectorOption, QuotePickerChip, QuotePickerSortOption, VehicleHeaderStatus };
@@ -383,6 +383,102 @@ declare class BucketProgress {
383
383
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<BucketProgress, "kf-bucket-progress", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "summary": { "alias": "summary"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
384
384
  }
385
385
 
386
+ /** Una celda ya resuelta de la grilla del mes. */
387
+ interface CalendarDay {
388
+ /** ISO date, `YYYY-MM-DD`. */
389
+ iso: string;
390
+ day: number;
391
+ inMonth: boolean;
392
+ selectable: boolean;
393
+ selected: boolean;
394
+ marked: boolean;
395
+ today: boolean;
396
+ ariaLabel: string;
397
+ }
398
+ /**
399
+ * Selector de fecha de un solo mes, con grilla semanal que parte en lunes.
400
+ *
401
+ * Las fechas viajan como strings ISO (`YYYY-MM-DD`, y `YYYY-MM` para el mes
402
+ * visible) y se calculan en UTC, así la zona horaria del navegador nunca
403
+ * corre una fecha un día.
404
+ *
405
+ * `availableDates` en `null` deja seleccionable toda fecha dentro de
406
+ * `min`/`max`; un arreglo deja seleccionables SOLO esas fechas (el resto se
407
+ * rinde deshabilitado). `markedDates` es independiente: agrega un punto
408
+ * marcador sin afectar si la fecha se puede elegir.
409
+ *
410
+ * Patrón WAI-ARIA `grid` con roving tabindex: las flechas mueven por
411
+ * día/semana, Home/End van al inicio/fin de la semana y PageUp/PageDown
412
+ * cambian de mes; el foco cruza los límites del mes.
413
+ *
414
+ * <kf-calendar
415
+ * [(value)]="date"
416
+ * [(month)]="month"
417
+ * [min]="today"
418
+ * [availableDates]="freeDates()"
419
+ * [markedDates]="eventDates()"
420
+ * [loading]="loadingAvailability()"
421
+ * >
422
+ * <p footer>Leyenda</p>
423
+ * </kf-calendar>
424
+ */
425
+ declare class Calendar {
426
+ private static nextId;
427
+ /** Fecha seleccionada, ISO `YYYY-MM-DD`. */
428
+ readonly value: _angular_core.ModelSignal<string | null>;
429
+ /** Mes visible, `YYYY-MM`. En `null` se deriva de `value` y, si no hay, de hoy. */
430
+ readonly month: _angular_core.ModelSignal<string | null>;
431
+ /** Fecha mínima seleccionable (inclusive), ISO. */
432
+ readonly min: _angular_core.InputSignal<string | null>;
433
+ /** Fecha máxima seleccionable (inclusive), ISO. */
434
+ readonly max: _angular_core.InputSignal<string | null>;
435
+ /** `null`: toda fecha dentro de `min`/`max` es seleccionable. Arreglo: solo esas fechas. */
436
+ readonly availableDates: _angular_core.InputSignal<readonly string[] | null>;
437
+ /** Fechas con punto marcador, independiente de si son seleccionables. */
438
+ readonly markedDates: _angular_core.InputSignal<readonly string[]>;
439
+ /** Reemplaza el "hoy" local (tests/SSR), ISO. */
440
+ readonly today: _angular_core.InputSignal<string | null>;
441
+ /** Atenúa la grilla y bloquea la selección mientras carga la disponibilidad. */
442
+ readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
443
+ readonly ariaLabel: _angular_core.InputSignal<string>;
444
+ /** Los 12 nombres de mes, partiendo en enero. */
445
+ readonly monthNames: _angular_core.InputSignal<readonly string[]>;
446
+ /** Las 7 iniciales visibles de los días, partiendo en lunes. */
447
+ readonly weekdayLabels: _angular_core.InputSignal<readonly string[]>;
448
+ /** Los 7 nombres completos de los días, partiendo en lunes — se usan en los nombres accesibles. */
449
+ readonly weekdayNames: _angular_core.InputSignal<readonly string[]>;
450
+ /** Se agrega al nombre accesible de una fecha marcada. */
451
+ readonly markedLabel: _angular_core.InputSignal<string>;
452
+ readonly previousMonthLabel: _angular_core.InputSignal<string>;
453
+ readonly nextMonthLabel: _angular_core.InputSignal<string>;
454
+ private readonly host;
455
+ private readonly injector;
456
+ private readonly focusedDate;
457
+ protected readonly titleId: string;
458
+ protected readonly todayIso: _angular_core.Signal<string>;
459
+ protected readonly displayedMonth: _angular_core.Signal<string>;
460
+ protected readonly title: _angular_core.Signal<string>;
461
+ private readonly minMonth;
462
+ private readonly maxMonth;
463
+ protected readonly canGoPrevious: _angular_core.Signal<boolean>;
464
+ protected readonly canGoNext: _angular_core.Signal<boolean>;
465
+ private readonly availableSet;
466
+ private readonly markedSet;
467
+ protected readonly weeks: _angular_core.Signal<CalendarDay[][]>;
468
+ /** La única celda con `tabindex="0"` (roving tabindex). */
469
+ protected readonly activeDate: _angular_core.Signal<string>;
470
+ previousMonth(): void;
471
+ nextMonth(): void;
472
+ protected selectDay(day: CalendarDay): void;
473
+ protected onDayFocus(iso: string): void;
474
+ protected onDayKeydown(event: KeyboardEvent, iso: string): void;
475
+ private focusDay;
476
+ private isMonthNavigable;
477
+ private buildDay;
478
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<Calendar, never>;
479
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<Calendar, "kf-calendar", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "month": { "alias": "month"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "availableDates": { "alias": "availableDates"; "required": false; "isSignal": true; }; "markedDates": { "alias": "markedDates"; "required": false; "isSignal": true; }; "today": { "alias": "today"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "monthNames": { "alias": "monthNames"; "required": false; "isSignal": true; }; "weekdayLabels": { "alias": "weekdayLabels"; "required": false; "isSignal": true; }; "weekdayNames": { "alias": "weekdayNames"; "required": false; "isSignal": true; }; "markedLabel": { "alias": "markedLabel"; "required": false; "isSignal": true; }; "previousMonthLabel": { "alias": "previousMonthLabel"; "required": false; "isSignal": true; }; "nextMonthLabel": { "alias": "nextMonthLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "month": "monthChange"; }, never, ["[footer]"], true, never>;
480
+ }
481
+
386
482
  /**
387
483
  * Contenedor base con esquinas redondeadas y sombra sutil — la base visual
388
484
  * de paneles, tarjetas de métrica, tablas y bloques de contenido de todo el
@@ -1670,6 +1766,9 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
1670
1766
  readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
1671
1767
  readonly type: _angular_core.InputSignal<string>;
1672
1768
  readonly placeholder: _angular_core.InputSignal<string>;
1769
+ /** Teclado virtual sugerido en mobile (ej. `"numeric"` para montos o
1770
+ * kilometraje) — sin valor, el navegador decide según `type`. */
1771
+ readonly inputmode: _angular_core.InputSignal<string | undefined>;
1673
1772
  /** Agrega el botón de mostrar/ocultar — sin efecto si `type` no es `"password"`. */
1674
1773
  readonly toggleable: _angular_core.InputSignalWithTransform<boolean, unknown>;
1675
1774
  protected readonly inputId: string;
@@ -1708,7 +1807,7 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
1708
1807
  */
1709
1808
  protected onTogglePasswordVisibility(): void;
1710
1809
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<Input, never>;
1711
- 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; }; "toggleable": { "alias": "toggleable"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1810
+ 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; }; "inputmode": { "alias": "inputmode"; "required": false; "isSignal": true; }; "toggleable": { "alias": "toggleable"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1712
1811
  }
1713
1812
 
1714
1813
  type JourneyStepStatus = 'done' | 'current' | 'delayed' | 'pending';
@@ -2087,6 +2186,16 @@ declare class Pagination {
2087
2186
  * <kf-action-tile-row icon="download" title="Pagos" description="Revisa tu estado de cuenta y realiza pagos." />
2088
2187
  * </kf-panel>
2089
2188
  *
2189
+ * Para apps con router: escuchar `actionClick` y llamar
2190
+ * `event.preventDefault()` antes de `router.navigateByUrl(...)`. El
2191
+ * `actionHref` se mantiene igual para que click-medio, "abrir en pestaña
2192
+ * nueva" y el hover de la barra de estado sigan funcionando.
2193
+ *
2194
+ * <kf-panel title="Mis documentos por pagar" actionLabel="Ir a pagos" actionHref="/pagos"
2195
+ * (actionClick)="$event.preventDefault(); router.navigateByUrl('/pagos')">
2196
+ * …
2197
+ * </kf-panel>
2198
+ *
2090
2199
  * El host y el `kf-card` interno son flex column con `flex:1` de punta a
2091
2200
  * punta — si un grid/flex externo estira `kf-panel` a la altura de un
2092
2201
  * hermano más alto, el contenido proyectado hereda esa altura en vez de
@@ -2098,8 +2207,14 @@ declare class Panel {
2098
2207
  readonly title: _angular_core.InputSignal<string>;
2099
2208
  readonly actionLabel: _angular_core.InputSignal<string | undefined>;
2100
2209
  readonly actionHref: _angular_core.InputSignal<string | undefined>;
2210
+ /**
2211
+ * Click en el link de acción. Incluye el `MouseEvent` para que un
2212
+ * consumidor con router pueda cortar la navegación nativa — mismo patrón
2213
+ * que `itemClick` de `kf-breadcrumb`, sin depender de `@angular/router`.
2214
+ */
2215
+ readonly actionClick: _angular_core.OutputEmitterRef<MouseEvent>;
2101
2216
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<Panel, never>;
2102
- 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; }; }, {}, never, ["*"], true, never>;
2217
+ 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>;
2103
2218
  }
2104
2219
 
2105
2220
  /** Un ítem de navegación de la barra de marca. `icon` es opcional y solo se
@@ -2234,10 +2349,11 @@ declare class PortalHeader {
2234
2349
 
2235
2350
  /** Mismo vocabulario que `Badge.tone`/`TextTone` (menos `info`/`service`,
2236
2351
  * que no aplican a un valor de progreso): `neutral` es el color de marca
2237
- * por defecto (sin implicar buen/mal estado), `ok`/`warn`/`error` sí
2238
- * comunican severidad. La librería no conoce el dominio que produce ese
2352
+ * por defecto (sin implicar buen/mal estado), `primary` es el color
2353
+ * primario para un avance de proceso (ej. una carga), y `ok`/`warn`/`error`
2354
+ * sí comunican severidad. La librería no conoce el dominio que produce ese
2239
2355
  * valor (SLA, storage, lo que sea) — el consumidor decide qué tone usar. */
2240
- type ProgressTone = 'neutral' | 'ok' | 'warn' | 'error';
2356
+ type ProgressTone = 'neutral' | 'primary' | 'ok' | 'warn' | 'error';
2241
2357
  /**
2242
2358
  * Barra de progreso de un solo valor (0-100%) con color por severidad —
2243
2359
  * para un porcentaje simple, a diferencia de `kf-bucket-progress`, que
@@ -2512,10 +2628,16 @@ declare class Segmented {
2512
2628
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<Segmented, "kf-segmented", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
2513
2629
  }
2514
2630
 
2515
- /** Normalized shape used internally once `options` (string[] or object[]) is resolved. */
2631
+ /**
2632
+ * Opción en forma de objeto. `tag` se muestra como `kf-badge` a la derecha
2633
+ * del label (en el panel y en el trigger) y `detail` como línea secundaria
2634
+ * atenuada debajo, solo en el panel. Ambos entran en la búsqueda.
2635
+ */
2516
2636
  interface SelectOption {
2517
2637
  value: string;
2518
2638
  label: string;
2639
+ tag?: string;
2640
+ detail?: string;
2519
2641
  }
2520
2642
  /**
2521
2643
  * Dropdown de selección simple con panel propio — NUNCA usa el `<select>`
@@ -2528,6 +2650,7 @@ interface SelectOption {
2528
2650
  *
2529
2651
  * <kf-select label="Sede" [options]="['Lima', 'Arequipa', 'Trujillo']" placeholder="Selecciona…" />
2530
2652
  * <kf-select [options]="[{ value: 'pe', label: 'Perú' }]" (valueChange)="onCountry($event)" />
2653
+ * <kf-select [options]="[{ value: '1002099', label: 'BBVA', tag: 'Empresa', detail: 'RUC 20100130204' }]" />
2531
2654
  *
2532
2655
  * `variant="compact"` cambia el ancho de `240px` fijo a intrínseco con un
2533
2656
  * techo de `160px` (se ajusta al contenido de la opción seleccionada hasta
@@ -2547,7 +2670,7 @@ interface SelectOption {
2547
2670
  */
2548
2671
  declare class Select {
2549
2672
  readonly label: _angular_core.InputSignal<string | undefined>;
2550
- readonly options: _angular_core.InputSignal<string[] | SelectOption[]>;
2673
+ readonly options: _angular_core.InputSignal<readonly (string | SelectOption)[]>;
2551
2674
  readonly value: _angular_core.InputSignal<string | undefined>;
2552
2675
  readonly placeholder: _angular_core.InputSignal<string>;
2553
2676
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -2579,7 +2702,7 @@ declare class Select {
2579
2702
  readonly isOpen: _angular_core.WritableSignal<boolean>;
2580
2703
  readonly searchQuery: _angular_core.WritableSignal<string>;
2581
2704
  readonly activeIndex: _angular_core.WritableSignal<number>;
2582
- /** Resolves the union (`string[] | { value; label }[]`) into a single shape for the template. */
2705
+ /** Resolves `string | SelectOption` entries into a single shape for the template. */
2583
2706
  readonly normalizedOptions: _angular_core.Signal<SelectOption[]>;
2584
2707
  readonly selectedOption: _angular_core.Signal<SelectOption | undefined>;
2585
2708
  readonly showSearch: _angular_core.Signal<boolean>;
@@ -2598,6 +2721,8 @@ declare class Select {
2598
2721
  */
2599
2722
  onDocumentEscape(): void;
2600
2723
  toggle(): void;
2724
+ /** Nombre accesible explícito solo para opciones con `tag`/`detail`, para separar las partes al leerlas. */
2725
+ optionAriaLabel(option: SelectOption): string | null;
2601
2726
  select(option: SelectOption): void;
2602
2727
  onSearchInput(event: Event): void;
2603
2728
  /**
@@ -2860,12 +2985,18 @@ declare class StatTile {
2860
2985
  readonly description: _angular_core.InputSignal<string | undefined>;
2861
2986
  readonly actionLabel: _angular_core.InputSignal<string | undefined>;
2862
2987
  readonly actionHref: _angular_core.InputSignal<string | undefined>;
2988
+ /**
2989
+ * Click en el link de la variante CTA. Incluye el `MouseEvent` para que un
2990
+ * consumidor con router pueda cortar la navegación nativa — mismo patrón
2991
+ * que `actionClick` de `kf-panel`, sin depender de `@angular/router`.
2992
+ */
2993
+ readonly actionClick: _angular_core.OutputEmitterRef<MouseEvent>;
2863
2994
  /** Texto real de la nota. `null` significa "no reservar la línea": pasa
2864
2995
  * solo cuando el consumidor no declaró ni nota ni placeholder. */
2865
2996
  protected readonly noteText: _angular_core.Signal<string | null>;
2866
2997
  protected readonly noteIsPlaceholder: _angular_core.Signal<boolean>;
2867
2998
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatTile, never>;
2868
- 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; }; }, {}, never, ["[valueContent]"], true, never>;
2999
+ 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>;
2869
3000
  }
2870
3001
 
2871
3002
  /**
@@ -3073,6 +3204,55 @@ declare class TileGrid {
3073
3204
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<TileGrid, "kf-tile-grid", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
3074
3205
  }
3075
3206
 
3207
+ interface TimeSlot {
3208
+ value: string;
3209
+ /** Texto visible; por defecto, `value`. */
3210
+ label?: string;
3211
+ disabled?: boolean;
3212
+ /** Los horarios con el mismo `group` se rinden juntos bajo esa etiqueta, en orden de aparición. */
3213
+ group?: string;
3214
+ }
3215
+ /**
3216
+ * Grilla de horarios seleccionables con semántica de radiogroup: un solo tab
3217
+ * stop, las flechas mueven y seleccionan (saltando los deshabilitados) y
3218
+ * Home/End van al primer/último horario habilitado.
3219
+ *
3220
+ * Si algún horario declara `group`, se rinde un subgrupo con etiqueta por
3221
+ * cada grupo distinto; si no, una sola grilla plana.
3222
+ *
3223
+ * <kf-time-slot-picker
3224
+ * ariaLabel="Horario"
3225
+ * [slots]="[{ value: '09:00', group: 'Mañana' }, { value: '15:30', group: 'Tarde', disabled: true }]"
3226
+ * [(value)]="time"
3227
+ * [loading]="loadingSlots()"
3228
+ * />
3229
+ */
3230
+ declare class TimeSlotPicker {
3231
+ private static nextId;
3232
+ readonly slots: _angular_core.InputSignal<readonly TimeSlot[]>;
3233
+ readonly value: _angular_core.ModelSignal<string | null>;
3234
+ readonly ariaLabel: _angular_core.InputSignal<string>;
3235
+ /** Muestra chips de carga en lugar de los horarios. */
3236
+ readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
3237
+ readonly emptyLabel: _angular_core.InputSignal<string>;
3238
+ private readonly host;
3239
+ private readonly idPrefix;
3240
+ protected readonly skeletons: number[];
3241
+ protected readonly groups: _angular_core.Signal<{
3242
+ id: string;
3243
+ label: string | null;
3244
+ slots: readonly TimeSlot[];
3245
+ }[]>;
3246
+ /** Valores habilitados en orden visual — la secuencia de navegación por teclado. */
3247
+ private readonly enabledValues;
3248
+ /** El único chip con `tabindex="0"` (roving tabindex). */
3249
+ protected readonly tabStop: _angular_core.Signal<string>;
3250
+ protected select(slot: TimeSlot): void;
3251
+ protected onKeydown(event: KeyboardEvent, current: string): void;
3252
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TimeSlotPicker, never>;
3253
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TimeSlotPicker, "kf-time-slot-picker", never, { "slots": { "alias": "slots"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": true; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
3254
+ }
3255
+
3076
3256
  /**
3077
3257
  * Visual tone of a toast. Maps to the state tokens in
3078
3258
  * projects/ui/src/tokens/base.css. `loading` has no auto-dismiss and shows an
@@ -3284,5 +3464,5 @@ declare class ViewToggle {
3284
3464
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<ViewToggle, "kf-view-toggle", never, { "view": { "alias": "view"; "required": true; "isSignal": true; }; }, { "viewChange": "viewChange"; }, never, never, true, never>;
3285
3465
  }
3286
3466
 
3287
- export { ActionTile, AdminBadge, Alert, AlertRow, Avatar, Badge, Breadcrumb, BucketProgress, Button, 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, Link, MetricCard, Modal, MultiSelect, NoteBlock, PageHeader, Pagination, Panel, PortalHeader, Progress, PulseDot, RowActions, SectionHeader, SectionNav, SectionNavItem, SectionNavSubsection, Segmented, Select, SelectableCardGroup, SidebarShell, Skeleton, Spinner, StatCard, StatTile, StatusPill, Tabs, Text, Textarea, TileGrid, ToastHost, ToastService, TooltipDirective, ViewToggle, dataTableViewSignal };
3288
- export type { AlertRowTone, AlertTone, BreadcrumbItem, BucketProgressItem, ContentStateKind, ContentStateLoad, ContentViewerType, DataTableCardRole, DataTableColumn, DataTableDensity, DataTableSort, DataTableView, DividerOrientation, DocumentRowTone, DrawerSide, DropdownItemTone, DropdownPanelVariant, EventTimelineItem, EventTimelineTone, FilterFieldChange, FilterFieldConfig, FilterFieldType, FilterValue, FolderTabOption, FooterLink, IconName, IconRotation, IconSize, JourneyStep, JourneyStepStatus, JourneyStepperColorScheme, JourneyStepperSurface, LinkVariant, MultiSelectOption, NoteBlockTone, PageHeaderTitleSize, PaginationItem, PortalHeaderAdminAction, PortalHeaderNavItem, ProgressTone, RowAction, RowActionKind, RowActionsMode, SectionNavSubsectionData, SegmentedOption, SelectableCardOption, SidebarNavItemData, SkeletonVariant, SpinnerSize, StatCardTone, StatTileTone, StatTileVariant, TabOption, TextAs, TextTone, TextVariant, ToastAction, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, TooltipPosition, ViewToggleOption };
3467
+ 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, Link, MetricCard, Modal, MultiSelect, NoteBlock, 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 };
3468
+ export type { AlertRowTone, AlertTone, BreadcrumbItem, BucketProgressItem, CalendarDay, ContentStateKind, ContentStateLoad, ContentViewerType, DataTableCardRole, DataTableColumn, DataTableDensity, DataTableSort, DataTableView, DividerOrientation, DocumentRowTone, DrawerSide, DropdownItemTone, DropdownPanelVariant, EventTimelineItem, EventTimelineTone, FilterFieldChange, FilterFieldConfig, FilterFieldType, FilterValue, FolderTabOption, FooterLink, IconName, IconRotation, IconSize, JourneyStep, JourneyStepStatus, JourneyStepperColorScheme, JourneyStepperSurface, LinkVariant, MultiSelectOption, NoteBlockTone, 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 };
Binary file