@kaufmann-lab/ui 0.1.25 → 0.1.26

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.25",
3
+ "version": "0.1.26",
4
4
  "description": "Shared Angular component library for the Kaufmann frontends",
5
5
  "license": "MIT",
6
6
  "author": "Kaufmann Lab",
@@ -17,6 +17,11 @@
17
17
  "tslib": "^2.3.0"
18
18
  },
19
19
  "sideEffects": false,
20
+ "files": [
21
+ "fesm2022",
22
+ "types",
23
+ "src/tokens"
24
+ ],
20
25
  "module": "fesm2022/kaufmann-lab-ui.mjs",
21
26
  "typings": "types/kaufmann-lab-ui.d.ts",
22
27
  "exports": {
@@ -156,6 +156,12 @@
156
156
  --kf-font-size-title-sm: 1.125rem;
157
157
  --kf-font-size-body: 1rem;
158
158
  --kf-font-size-body-sm: 0.875rem;
159
+ /*
160
+ * Tamaño de etiqueta/valor en filas y paneles densos (13px): queda entre
161
+ * `body-sm` (14px) y `caption` (12px). Es solo el token; varios CSS de la
162
+ * librería todavía escriben `0.8125rem` suelto y se migran por separado.
163
+ */
164
+ --kf-font-size-label: 0.8125rem;
159
165
  --kf-font-size-caption: 0.75rem;
160
166
 
161
167
  /*
@@ -214,6 +220,13 @@
214
220
  */
215
221
  --kf-shadow-focus-error: 0 0 0 2px var(--kf-color-white), 0 0 0 4px var(--kf-color-error);
216
222
 
223
+ /*
224
+ * Anillo de selección de `kf-stat-tile interactive` en estado `pressed`:
225
+ * 1px de marca por fuera del borde (que también pasa a marca). Un tema o
226
+ * una pantalla lo puede redefinir sin tocar el componente.
227
+ */
228
+ --kf-stat-tile-ring: 0 0 0 1px var(--kf-color-primary);
229
+
217
230
  /*
218
231
  * ---------- Anchos de controles de formulario ----------
219
232
  * Usados por `width` de `kf-select`/`kf-multi-select`. `md` (240px) es
@@ -223,6 +236,8 @@
223
236
  --kf-select-width-sm: 160px;
224
237
  --kf-select-width-md: 240px;
225
238
  --kf-select-width-lg: 320px;
239
+ /* Techo de `kf-select width="fit"`: más allá de este ancho trunca con elipsis. */
240
+ --kf-select-fit-max-width: 20rem;
226
241
 
227
242
  /*
228
243
  * ---------- Geometría del checkbox ----------
@@ -1438,7 +1438,7 @@ declare class SkeletonPreset {
1438
1438
  protected readonly items: _angular_core.Signal<number[]>;
1439
1439
  /** Columnas de la tabla sintética (encabezados en blanco: lo real aún no llegó). */
1440
1440
  protected readonly tableColumns: _angular_core.Signal<DataTableColumn[]>;
1441
- protected readonly formColumns: _angular_core.Signal<2 | 1>;
1441
+ protected readonly formColumns: _angular_core.Signal<1 | 2>;
1442
1442
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SkeletonPreset, never>;
1443
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
1444
  }
@@ -3246,6 +3246,8 @@ declare class MilestoneTimeline {
3246
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>;
3247
3247
  }
3248
3248
 
3249
+ /** Anchos con nombre de `size`: 480 / 640 / 880 / 1120 px. */
3250
+ type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
3249
3251
  /**
3250
3252
  * Diálogo centrado sobre un backdrop: confirmaciones destructivas, formularios
3251
3253
  * cortos, decisiones que bloquean el flujo.
@@ -3284,6 +3286,22 @@ declare class MilestoneTimeline {
3284
3286
  * <kf-link footer class="kf-modal__footer-start" disabled>Ver documento</kf-link>
3285
3287
  * <kf-button footer (click)="open.set(false)">Cerrar</kf-button>
3286
3288
  *
3289
+ * ## Ancho: `size` y `width`
3290
+ * `size` (`'sm'` 480px, `'md'` 640px, `'lg'` 880px, `'xl'` 1120px) elige un
3291
+ * ancho con nombre; sin `size` ni `width` el ancho es el histórico de 480px.
3292
+ * `width` sigue aceptando cualquier valor CSS y, si se pasa, manda sobre
3293
+ * `size`. En pantallas angostas el panel nunca supera el ancho del viewport.
3294
+ *
3295
+ * <kf-modal [(open)]="open" title="Nuevo ticket" size="xl">…</kf-modal>
3296
+ *
3297
+ * ## Separadores: `dividers`
3298
+ * Con `dividers` el encabezado y el footer quedan separados del cuerpo por
3299
+ * una línea (`--kf-color-border`); el del footer solo aparece si hay
3300
+ * acciones. Sirve cuando el cuerpo se desplaza (`maxHeight`) y su contenido
3301
+ * no debe cortarse contra los botones. Sin `dividers` no cambia nada.
3302
+ *
3303
+ * <kf-modal [(open)]="open" title="Nuevo ticket" size="lg" dividers maxHeight="85vh">…</kf-modal>
3304
+ *
3287
3305
  * ## Modal de listado (alto acotado, filtros fijos)
3288
3306
  * Para un diálogo con mucho contenido (ej. elegir un ítem entre cientos):
3289
3307
  * - `maxHeight` (ej. `"85vh"`) acota el panel; solo `.kf-modal__body` se
@@ -3316,6 +3334,10 @@ declare class Modal {
3316
3334
  * más, ej. `width="720px"` — sigue topeado por `100vw` en pantallas
3317
3335
  * angostas, mismo `min()` de siempre. */
3318
3336
  readonly width: _angular_core.InputSignal<string | null>;
3337
+ /** Ancho con nombre sobre `--kf-modal-width`; `width` lo pisa si ambos están. */
3338
+ readonly size: _angular_core.InputSignal<ModalSize | null>;
3339
+ /** Línea bajo el encabezado y sobre el footer (si tiene acciones). */
3340
+ readonly dividers: _angular_core.InputSignalWithTransform<boolean, unknown>;
3319
3341
  /** Alto máximo del panel (ej. `"85vh"`); con valor, solo el cuerpo se
3320
3342
  * desplaza. Sin valor (default) el panel crece con su contenido. */
3321
3343
  readonly maxHeight: _angular_core.InputSignal<string | null>;
@@ -3349,7 +3371,7 @@ declare class Modal {
3349
3371
  */
3350
3372
  protected onHostClick(event: MouseEvent): void;
3351
3373
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<Modal, never>;
3352
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<Modal, "kf-modal", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "fullscreenOnMobile": { "alias": "fullscreenOnMobile"; "required": false; "isSignal": true; }; "initialFocus": { "alias": "initialFocus"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[kf-modal-meta]", "[kf-modal-toolbar]", "*", "[footer]"], true, never>;
3374
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<Modal, "kf-modal", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "dividers": { "alias": "dividers"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "fullscreenOnMobile": { "alias": "fullscreenOnMobile"; "required": false; "isSignal": true; }; "initialFocus": { "alias": "initialFocus"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[kf-modal-meta]", "[kf-modal-toolbar]", "*", "[footer]"], true, never>;
3353
3375
  }
3354
3376
 
3355
3377
  /** Color de la franja izquierda y del fondo. */
@@ -3450,7 +3472,7 @@ declare class OptionList {
3450
3472
  }
3451
3473
 
3452
3474
  type TextAs = 'h1' | 'h2' | 'h3' | 'p' | 'span';
3453
- type TextVariant = 'title-xxl' | 'title-xl' | 'title-lg' | 'title-md' | 'title-sm' | 'body' | 'body-muted' | 'caption' | 'overline' | 'overline-strong';
3475
+ type TextVariant = 'title-xxl' | 'title-xl' | 'title-lg' | 'title-md' | 'title-sm' | 'body' | 'body-muted' | 'body-sm' | 'body-sm-muted' | 'caption' | 'overline' | 'overline-strong';
3454
3476
  type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';
3455
3477
  /**
3456
3478
  * Tipografía unificada — separa la etiqueta semántica (`as`, qué es el
@@ -3471,6 +3493,12 @@ type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';
3471
3493
  * títulos protagonistas de pantalla completa (ej. bienvenida del home vía
3472
3494
  * `kf-page-header[size=xl|xxl]`) — ver tokens/base.css.
3473
3495
  *
3496
+ * `body-sm`/`body-sm-muted` son el paso intermedio entre `body` (1rem) y
3497
+ * `caption` (0.75rem): 0.875rem (`--kf-font-size-body-sm`), para texto de
3498
+ * apoyo en filas y paneles densos. Mismo criterio de color que `body`/
3499
+ * `body-muted`: `body-sm` hereda el color de texto y `body-sm-muted` usa el
3500
+ * atenuado.
3501
+ *
3474
3502
  * `overline`/`overline-strong` son para el patrón "texto chico en mayúsculas
3475
3503
  * junto a un dato" (ej. el label "RUC" de `kf-company-selector`, el badge de
3476
3504
  * `kf-admin-badge`) — antes de estas variantes, ese patrón se reimplementaba
@@ -3482,6 +3510,7 @@ type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';
3482
3510
  *
3483
3511
  * <kf-text as="h1" variant="title-lg">Bienvenido de nuevo</kf-text>
3484
3512
  * <kf-text as="p" variant="body-muted">Ingresá con tu cuenta corporativa.</kf-text>
3513
+ * <kf-text as="span" variant="body-sm">Última actualización hace 5 min</kf-text>
3485
3514
  * <kf-text as="span" variant="caption" tone="error">Campo obligatorio</kf-text>
3486
3515
  * <kf-text as="span" variant="overline">RUC</kf-text>
3487
3516
  * <kf-text as="span" variant="overline-strong" tone="warn">Vista administrador</kf-text>
@@ -4258,6 +4287,28 @@ interface SelectOption {
4258
4287
  * panelTitle="Ordenar por" panelWidth="content"
4259
4288
  * [options]="sortOptions" [value]="sort()" (valueChange)="sort.set($event)" />
4260
4289
  *
4290
+ * `width="fit"` ajusta el ancho al contenido: mide la opción más larga (y el
4291
+ * placeholder) con la tipografía real y no cambia al elegir otra, hasta un
4292
+ * tope de `--kf-select-fit-max-width` (20rem por defecto; lo que no entra se
4293
+ * trunca con elipsis). Pensado para selects en barras de herramientas o
4294
+ * encabezados donde un ancho fijo deja espacio vacío. La medición se hace
4295
+ * con una pasada invisible de todas las opciones, así que conviene para
4296
+ * listas cortas o medianas; con cientos de opciones usar un ancho fijo. Si
4297
+ * alguna opción trae `tag`, también se reserva el hueco del tag más ancho,
4298
+ * por lo que elegir una opción con tag tampoco cambia el ancho. Conviene
4299
+ * combinarlo con `panelWidth="content"`: con el default (`"trigger"`) el panel
4300
+ * mide lo mismo que el trigger y las opciones, que suman su propio padding
4301
+ * (y su tag, si lo traen), pueden quedar truncadas.
4302
+ *
4303
+ * <kf-select width="fit" label="División" hideLabel [options]="divisions" [value]="division()" (valueChange)="..." />
4304
+ *
4305
+ * `size="sm"` fija la altura del trigger en 32px (`--kf-select-min-height`)
4306
+ * para filas de filtros densas, sin tocar el padding horizontal ni el
4307
+ * `variant`. El default (`'md'`) no cambia nada. Para otra altura puntual,
4308
+ * declarar `--kf-select-min-height` en el propio `kf-select`.
4309
+ *
4310
+ * <kf-select size="sm" width="fit" [options]="ranges" [value]="range()" (valueChange)="..." />
4311
+ *
4261
4312
  * Teclado (patrón listbox de WAI-ARIA): ArrowDown/ArrowUp sobre el trigger
4262
4313
  * cerrado lo abren; al abrir, el foco pasa a la opción seleccionada (o al
4263
4314
  * buscador, si está visible). En el panel, flechas y Home/End mueven el
@@ -4298,8 +4349,14 @@ declare class Select {
4298
4349
  * comportamiento actual sin cambios para consumidores existentes.
4299
4350
  * 'full' ocupa el 100% del contenedor — para selects dentro de layouts
4300
4351
  * flex/grid donde el ancho fijo no encaja (ej. un footer de sidebar).
4352
+ * 'fit' mide el contenido (opción más larga) con un tope.
4301
4353
  */
4302
- readonly width: _angular_core.InputSignal<"sm" | "md" | "lg" | "full">;
4354
+ readonly width: _angular_core.InputSignal<"sm" | "md" | "lg" | "full" | "fit">;
4355
+ /**
4356
+ * Altura del trigger. 'md' (default) conserva la altura histórica; 'sm'
4357
+ * la fija en 32px para barras de filtros densas.
4358
+ */
4359
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
4303
4360
  /**
4304
4361
  * Tri-state: si el consumidor no lo especifica (`undefined`), el buscador
4305
4362
  * se activa solo cuando `options().length` supera `searchThreshold()`. Si
@@ -4347,6 +4404,14 @@ declare class Select {
4347
4404
  * nombre accesible, así que con label visible no se emite.
4348
4405
  */
4349
4406
  readonly triggerAriaLabel: _angular_core.Signal<string | null>;
4407
+ /**
4408
+ * Textos que `width="fit"` mide para dimensionar el trigger: el de cada
4409
+ * opción tal como se vería en el trigger (`shortLabel` o `label`) y el
4410
+ * placeholder. Sin repetidos.
4411
+ */
4412
+ protected readonly fitTexts: _angular_core.Signal<string[]>;
4413
+ /** Tags distintos de las opciones, para reservar el hueco del más ancho con `width="fit"`. */
4414
+ protected readonly fitTags: _angular_core.Signal<string[]>;
4350
4415
  readonly showSearch: _angular_core.Signal<boolean>;
4351
4416
  /** Opciones visibles tras aplicar el filtro de búsqueda (case/acento-insensitive). */
4352
4417
  readonly filteredOptions: _angular_core.Signal<SelectOption[]>;
@@ -4436,7 +4501,7 @@ declare class Select {
4436
4501
  private scrollActiveIntoView;
4437
4502
  selectActive(): void;
4438
4503
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<Select, never>;
4439
- 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>;
4504
+ 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; }; "size": { "alias": "size"; "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>;
4440
4505
  }
4441
4506
 
4442
4507
  interface SelectableCardOption {
@@ -4718,6 +4783,24 @@ type StatTileVariant = 'inline' | 'card';
4718
4783
  * <kf-stat-tile label="Estado" hasProjectedValue>
4719
4784
  * <kf-badge valueContent [tone]="stateTone()">{{ stateLabel() }}</kf-badge>
4720
4785
  * </kf-stat-tile>
4786
+ *
4787
+ * `interactive` convierte el tile en un botón (`role="button"`, enfocable,
4788
+ * Enter y Espacio) que emite `tileClick`: para un KPI que filtra o despliega
4789
+ * algo. El click sobre un control proyectado dentro del tile (link, botón,
4790
+ * campo) no emite `tileClick`; el de texto común sí. `pressed`
4791
+ * (`aria-pressed`) lo vuelve un botón de alternancia, útil como filtro; `expanded` (`aria-expanded`) indica que controla un panel
4792
+ * desplegable. Ambos son `boolean | null`: `null` (default) no emite el
4793
+ * atributo. El estado `pressed` se marca con un borde y el anillo
4794
+ * `--kf-stat-tile-ring`; el foco de teclado usa `--kf-shadow-focus`. Sin
4795
+ * `interactive` el tile se comporta exactamente como antes (los demás inputs
4796
+ * se ignoran), y con `cta` tampoco aplica: ya contiene su propio link.
4797
+ *
4798
+ * Distinto de `kf-stat-card` (`clickable` + `pressed`): esa card tiene el
4799
+ * ícono circular a la izquierda y un chevron; el tile conserva label arriba,
4800
+ * ícono a la derecha, valor y nota, y suma `expanded`.
4801
+ *
4802
+ * <kf-stat-tile interactive label="En ruta" value="12" icon="truck"
4803
+ * [pressed]="filter() === 'route'" (tileClick)="toggleFilter('route')" />
4721
4804
  */
4722
4805
  declare class StatTile {
4723
4806
  readonly cta: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -4747,12 +4830,37 @@ declare class StatTile {
4747
4830
  * que `actionClick` de `kf-panel`, sin depender de `@angular/router`.
4748
4831
  */
4749
4832
  readonly actionClick: _angular_core.OutputEmitterRef<MouseEvent>;
4833
+ /** Convierte el tile en un botón; ver la descripción de la clase. */
4834
+ readonly interactive: _angular_core.InputSignalWithTransform<boolean, unknown>;
4835
+ /** Estado de alternancia (`aria-pressed`); `null` = no aplica. */
4836
+ readonly pressed: _angular_core.InputSignal<boolean | null>;
4837
+ /** El tile controla un panel (`aria-expanded`); `null` = no aplica. */
4838
+ readonly expanded: _angular_core.InputSignal<boolean | null>;
4839
+ /** Activación del tile interactivo: click, Enter o Espacio. */
4840
+ readonly tileClick: _angular_core.OutputEmitterRef<void>;
4841
+ /** La variante CTA ya tiene su propio link: no puede ser además un botón. */
4842
+ protected readonly isInteractive: _angular_core.Signal<boolean>;
4750
4843
  /** Texto real de la nota. `null` significa "no reservar la línea": pasa
4751
4844
  * solo cuando el consumidor no declaró ni nota ni placeholder. */
4752
4845
  protected readonly noteText: _angular_core.Signal<string | null>;
4846
+ protected onActivate(event: MouseEvent): void;
4847
+ /**
4848
+ * Un control proyectado dentro del tile (link, botón, campo…) tiene su
4849
+ * propia acción: su click no debe contar como activar el tile. El texto o
4850
+ * los spans comunes sí activan, por eso se busca el control con `closest`
4851
+ * y no se compara `target` con `currentTarget`.
4852
+ */
4853
+ private isFromProjectedControl;
4854
+ /**
4855
+ * Teclado de un botón nativo: Enter activa al presionar y Espacio al soltar
4856
+ * (en `keydown` solo se frena el scroll de la página). Solo cuenta cuando el
4857
+ * foco está en el propio tile, no en contenido proyectado dentro de él.
4858
+ */
4859
+ protected onKeydown(event: KeyboardEvent): void;
4860
+ protected onKeyup(event: KeyboardEvent): void;
4753
4861
  protected readonly noteIsPlaceholder: _angular_core.Signal<boolean>;
4754
4862
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatTile, never>;
4755
- 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>;
4863
+ 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; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "pressed": { "alias": "pressed"; "required": false; "isSignal": true; }; "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; }, { "actionClick": "actionClick"; "tileClick": "tileClick"; }, never, ["[valueContent]"], true, never>;
4756
4864
  }
4757
4865
 
4758
4866
  /**
@@ -4821,6 +4929,61 @@ declare class StatusPill {
4821
4929
  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>;
4822
4930
  }
4823
4931
 
4932
+ type SwitchSize = 'sm' | 'md';
4933
+ /**
4934
+ * Interruptor de activar/desactivar con efecto inmediato (preferencias,
4935
+ * ajustes). Para elegir opciones dentro de un formulario que se envía al
4936
+ * final, usar `kf-checkbox`.
4937
+ *
4938
+ * Es un `<button role="switch" aria-checked>`: el lector de pantalla anuncia
4939
+ * el estado con el propio rol, por eso no hay texto extra de "activado". Enter
4940
+ * y Espacio lo alternan como en cualquier botón.
4941
+ *
4942
+ * `label` es obligatorio: da el nombre accesible aunque no se vea. Con
4943
+ * `hideLabel` se oculta el texto y pasa a `aria-label`, para un interruptor
4944
+ * cuyo contexto ya lo explica la fila que lo contiene.
4945
+ *
4946
+ * `checked` es two-way (`model`). Implementa `ControlValueAccessor`, así que
4947
+ * también funciona con `formControlName`/`ngModel`; en ese modo `writeValue`
4948
+ * escribe en el mismo `checked`. `disabled` del input y el del formulario se
4949
+ * combinan: basta con que uno esté activo.
4950
+ *
4951
+ * `writeValue` (el formulario escribiendo el valor por código, ej.
4952
+ * `setValue`/`reset`) también emite `checkedChange`, porque escribe en el
4953
+ * `model`. Combinar `[(checked)]` con `formControlName`/`ngModel` en el mismo
4954
+ * switch hace que el valor llegue dos veces al consumidor: usar una sola de
4955
+ * las dos vías, o ignorar en el handler el eco que no cambia el valor.
4956
+ *
4957
+ * El color sale de roles (`--kf-color-primary` encendido,
4958
+ * `--kf-color-border-control` apagado) y el foco de `--kf-shadow-focus`; no
4959
+ * recibe colores.
4960
+ *
4961
+ * <kf-switch label="Fijar indicadores" [(checked)]="pinned" />
4962
+ * <kf-switch label="Mapa junto a la tabla" hideLabel size="sm" formControlName="splitMap" />
4963
+ */
4964
+ declare class Switch implements ControlValueAccessor {
4965
+ /** Nombre accesible y texto visible (salvo con `hideLabel`). */
4966
+ readonly label: _angular_core.InputSignal<string>;
4967
+ /** Oculta el texto y lo deja como `aria-label`. */
4968
+ readonly hideLabel: _angular_core.InputSignalWithTransform<boolean, unknown>;
4969
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
4970
+ readonly size: _angular_core.InputSignal<SwitchSize>;
4971
+ /** Estado encendido, two-way: `[(checked)]="pinned"`. */
4972
+ readonly checked: _angular_core.ModelSignal<boolean>;
4973
+ private readonly disabledByForm;
4974
+ protected readonly isDisabled: _angular_core.Signal<boolean>;
4975
+ private onChangeFn;
4976
+ private onTouchedFn;
4977
+ protected toggle(): void;
4978
+ protected onBlur(): void;
4979
+ writeValue(value: boolean | null): void;
4980
+ registerOnChange(fn: (value: boolean) => void): void;
4981
+ registerOnTouched(fn: () => void): void;
4982
+ setDisabledState(isDisabled: boolean): void;
4983
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<Switch, never>;
4984
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<Switch, "kf-switch", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; }, never, never, true, never>;
4985
+ }
4986
+
4824
4987
  interface TabOption {
4825
4988
  value: string;
4826
4989
  label: string;
@@ -5302,5 +5465,5 @@ declare class ViewToggle {
5302
5465
  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>;
5303
5466
  }
5304
5467
 
5305
- 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 };
5306
- 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 };
5468
+ 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, Switch, TOAST_DEFAULT_DURATION_MS, Tabs, Text, Textarea, TileGrid, TimeSlotPicker, ToastHost, ToastService, TooltipDirective, ViewToggle, dataTableViewSignal, formatFileSize, resolveListToolbarMode };
5469
+ 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, ModalSize, 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, SwitchSize, TabOption, TextAs, TextTone, TextVariant, TimeSlot, ToastAction, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, TooltipPosition, ViewToggleOption };