@kaufmann-lab/ui 0.1.22 → 0.1.25

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, booleanAttribute, inject, computed, effect, Component, viewChild, model, output, ElementRef, Injector, signal, afterNextRender, ChangeDetectionStrategy, numberAttribute, contentChildren, DestroyRef, forwardRef, TemplateRef, contentChild, ViewContainerRef, afterRenderEffect, untracked, Directive, HostListener, isDevMode, viewChildren, Input as Input$1, Injectable } from '@angular/core';
2
+ import { input, booleanAttribute, inject, computed, effect, Component, viewChild, model, output, ElementRef, Injector, signal, afterNextRender, ChangeDetectionStrategy, numberAttribute, contentChildren, DestroyRef, forwardRef, TemplateRef, contentChild, ViewContainerRef, untracked, afterRenderEffect, Directive, HostListener, isDevMode, viewChildren, Input as Input$1, Injectable } from '@angular/core';
3
3
  import { DOCUMENT, NgTemplateOutlet } from '@angular/common';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { NG_VALUE_ACCESSOR, FormsModule, NgControl } from '@angular/forms';
@@ -1283,6 +1283,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
1283
1283
  * dashboard) — no incluye el contenedor en sí.
1284
1284
  *
1285
1285
  * <kf-alert-row icon="file" tone="warn" text="2 cotizaciones esperan tu aprobación" (rowClick)="onNavigate('cotizaciones')" />
1286
+ *
1287
+ * Extensiones opcionales (la fila sin ellas se ve y se comporta como siempre):
1288
+ * - `tone="neutral"`: ícono gris, para una fila sin urgencia ni alerta.
1289
+ * - `value`: cifra alineada a la derecha, antes del chevron (ej. el conteo de
1290
+ * pendientes). Admite `'—'` cuando no hay dato; en ese caso conviene pasar
1291
+ * `valueLabel` con el texto que debe leer un lector de pantalla
1292
+ * («Sin datos»), porque la raya sola no dice nada.
1293
+ * - `valueLabel`: texto solo para lectores de pantalla que reemplaza a `value`
1294
+ * en el árbol de accesibilidad; visualmente se sigue viendo `value`.
1295
+ * - `tag`: etiqueta neutra pequeña junto al texto (ej. «Próximamente»).
1296
+ * - `disabled`: la fila no es accionable — no emite `rowClick`, no entra en el
1297
+ * orden de tabulación, no cambia al pasar el mouse, su chevron se oculta (conserva el
1298
+ * espacio para alinear las cifras con las filas activas) y el
1299
+ * texto y la cifra se atenúan (sin bajar el contraste de lectura). Expone
1300
+ * `disabled` y `aria-disabled="true"`, así que un lector de pantalla la
1301
+ * anuncia como no disponible en vez de omitirla.
1302
+ *
1303
+ * <kf-alert-row icon="file" tone="neutral" text="Documentos por firmar" tag="Próximamente" value="—" valueLabel="Sin datos todavía" disabled />
1286
1304
  */
1287
1305
  class AlertRow {
1288
1306
  icon = input.required(/* @ts-ignore */
@@ -1291,14 +1309,35 @@ class AlertRow {
1291
1309
  ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
1292
1310
  text = input.required(/* @ts-ignore */
1293
1311
  ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
1312
+ /** Cifra o texto corto alineado a la derecha (ej. `3`, `'—'`). */
1313
+ value = input(/* @ts-ignore */
1314
+ ...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
1315
+ /** Texto solo para lectores de pantalla que reemplaza a `value` en el árbol de accesibilidad. */
1316
+ valueLabel = input(/* @ts-ignore */
1317
+ ...(ngDevMode ? [undefined, { debugName: "valueLabel" }] : /* istanbul ignore next */ []));
1318
+ /** Etiqueta neutra junto al texto (ej. «Próximamente»). */
1319
+ tag = input(/* @ts-ignore */
1320
+ ...(ngDevMode ? [undefined, { debugName: "tag" }] : /* istanbul ignore next */ []));
1321
+ /** La fila no es accionable: sin clic, sin foco ni hover. */
1322
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1294
1323
  rowClick = output();
1324
+ /** Emite `rowClick` salvo que la fila esté deshabilitada (también ante clics sintéticos). */
1325
+ activate() {
1326
+ if (!this.disabled()) {
1327
+ this.rowClick.emit();
1328
+ }
1329
+ }
1330
+ hasValue() {
1331
+ const value = this.value();
1332
+ return value !== undefined && value !== null && value !== '';
1333
+ }
1295
1334
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: AlertRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
1296
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: AlertRow, isStandalone: true, selector: "kf-alert-row", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { rowClick: "rowClick" }, ngImport: i0, template: "<button type=\"button\" class=\"kf-alert-row\" (click)=\"rowClick.emit()\">\n <span class=\"kf-alert-row__icon\" [class]=\"'kf-alert-row__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n <span class=\"kf-alert-row__text\">{{ text() }}</span>\n <kf-icon class=\"kf-alert-row__chevron\" name=\"chevron-right\" size=\"sm\" />\n</button>\n", styles: [":host{display:block}.kf-alert-row{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-sm) var(--kf-space-sm);border:none;border-radius:var(--kf-radius-sm);background:transparent;font:inherit;text-align:left;cursor:pointer}.kf-alert-row:hover{background:var(--kf-color-surface)}.kf-alert-row:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-alert-row__icon{display:grid;place-items:center;width:36px;height:36px;flex:none;border-radius:var(--kf-radius-pill)}.kf-alert-row__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-alert-row__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-alert-row__text{flex:1 1 auto;font-size:.9rem;font-weight:600;color:var(--kf-color-ink)}.kf-alert-row__chevron{flex:none;color:var(--kf-color-gray-400)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
1335
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: AlertRow, isStandalone: true, selector: "kf-alert-row", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, valueLabel: { classPropertyName: "valueLabel", publicName: "valueLabel", isSignal: true, isRequired: false, transformFunction: null }, tag: { classPropertyName: "tag", publicName: "tag", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowClick: "rowClick" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"kf-alert-row\"\n [class.kf-alert-row--disabled]=\"disabled()\"\n [disabled]=\"disabled()\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n (click)=\"activate()\"\n>\n <span class=\"kf-alert-row__icon\" [class]=\"'kf-alert-row__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n @if (tag()) {\n <span class=\"kf-alert-row__main\">\n <ng-container *ngTemplateOutlet=\"rowText\" />\n <span class=\"kf-alert-row__tag\">{{ tag() }}</span>\n </span>\n } @else {\n <ng-container *ngTemplateOutlet=\"rowText\" />\n }\n @if (hasValue()) {\n @if (valueLabel()) {\n <span class=\"kf-alert-row__value\" aria-hidden=\"true\">{{ value() }}</span>\n <span class=\"kf-sr-only\">{{ valueLabel() }}</span>\n } @else {\n <span class=\"kf-alert-row__value\">{{ value() }}</span>\n }\n }\n <kf-icon class=\"kf-alert-row__chevron\" name=\"chevron-right\" size=\"sm\" />\n</button>\n\n<ng-template #rowText>\n <span class=\"kf-alert-row__text\">{{ text() }}</span>\n</ng-template>\n", styles: [".kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block}.kf-alert-row{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-sm) var(--kf-space-sm);border:none;border-radius:var(--kf-radius-sm);background:transparent;font:inherit;text-align:left;cursor:pointer}.kf-alert-row:hover{background:var(--kf-color-surface)}.kf-alert-row:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-alert-row__icon{display:grid;place-items:center;width:36px;height:36px;flex:none;border-radius:var(--kf-radius-pill)}.kf-alert-row__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-alert-row__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-alert-row__text{flex:1 1 auto;font-size:.9rem;font-weight:600;color:var(--kf-color-ink)}.kf-alert-row__chevron{flex:none;color:var(--kf-color-gray-400)}.kf-alert-row__icon--neutral{background:var(--kf-color-gray-100);color:var(--kf-color-text)}.kf-alert-row__main{flex:1 1 auto;min-width:0;display:flex;flex-wrap:wrap;align-items:center;gap:4px var(--kf-space-sm)}.kf-alert-row__main .kf-alert-row__text{flex:0 1 auto}.kf-alert-row__tag{display:inline-flex;align-items:center;padding:3px 8px;border-radius:var(--kf-radius-pill);background:var(--kf-color-gray-200);color:var(--kf-color-text);font-size:.72rem;font-weight:600;line-height:1;white-space:nowrap}.kf-alert-row__value{flex:none;min-width:2ch;font-family:var(--kf-font-title);font-size:1.15rem;font-weight:700;font-variant-numeric:tabular-nums;text-align:right;color:var(--kf-color-ink)}.kf-alert-row--disabled,.kf-alert-row--disabled:hover{background:transparent;cursor:default}.kf-alert-row--disabled .kf-alert-row__chevron{visibility:hidden}.kf-alert-row--disabled .kf-alert-row__text{font-weight:500;color:var(--kf-color-text)}.kf-alert-row--disabled .kf-alert-row__value{color:var(--kf-color-text)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1297
1336
  }
1298
1337
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: AlertRow, decorators: [{
1299
1338
  type: Component,
1300
- args: [{ selector: 'kf-alert-row', imports: [Icon], template: "<button type=\"button\" class=\"kf-alert-row\" (click)=\"rowClick.emit()\">\n <span class=\"kf-alert-row__icon\" [class]=\"'kf-alert-row__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n <span class=\"kf-alert-row__text\">{{ text() }}</span>\n <kf-icon class=\"kf-alert-row__chevron\" name=\"chevron-right\" size=\"sm\" />\n</button>\n", styles: [":host{display:block}.kf-alert-row{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-sm) var(--kf-space-sm);border:none;border-radius:var(--kf-radius-sm);background:transparent;font:inherit;text-align:left;cursor:pointer}.kf-alert-row:hover{background:var(--kf-color-surface)}.kf-alert-row:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-alert-row__icon{display:grid;place-items:center;width:36px;height:36px;flex:none;border-radius:var(--kf-radius-pill)}.kf-alert-row__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-alert-row__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-alert-row__text{flex:1 1 auto;font-size:.9rem;font-weight:600;color:var(--kf-color-ink)}.kf-alert-row__chevron{flex:none;color:var(--kf-color-gray-400)}\n"] }]
1301
- }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }] } });
1339
+ args: [{ selector: 'kf-alert-row', imports: [Icon, NgTemplateOutlet], template: "<button\n type=\"button\"\n class=\"kf-alert-row\"\n [class.kf-alert-row--disabled]=\"disabled()\"\n [disabled]=\"disabled()\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n (click)=\"activate()\"\n>\n <span class=\"kf-alert-row__icon\" [class]=\"'kf-alert-row__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n @if (tag()) {\n <span class=\"kf-alert-row__main\">\n <ng-container *ngTemplateOutlet=\"rowText\" />\n <span class=\"kf-alert-row__tag\">{{ tag() }}</span>\n </span>\n } @else {\n <ng-container *ngTemplateOutlet=\"rowText\" />\n }\n @if (hasValue()) {\n @if (valueLabel()) {\n <span class=\"kf-alert-row__value\" aria-hidden=\"true\">{{ value() }}</span>\n <span class=\"kf-sr-only\">{{ valueLabel() }}</span>\n } @else {\n <span class=\"kf-alert-row__value\">{{ value() }}</span>\n }\n }\n <kf-icon class=\"kf-alert-row__chevron\" name=\"chevron-right\" size=\"sm\" />\n</button>\n\n<ng-template #rowText>\n <span class=\"kf-alert-row__text\">{{ text() }}</span>\n</ng-template>\n", styles: [".kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block}.kf-alert-row{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-sm) var(--kf-space-sm);border:none;border-radius:var(--kf-radius-sm);background:transparent;font:inherit;text-align:left;cursor:pointer}.kf-alert-row:hover{background:var(--kf-color-surface)}.kf-alert-row:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-alert-row__icon{display:grid;place-items:center;width:36px;height:36px;flex:none;border-radius:var(--kf-radius-pill)}.kf-alert-row__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-alert-row__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-alert-row__text{flex:1 1 auto;font-size:.9rem;font-weight:600;color:var(--kf-color-ink)}.kf-alert-row__chevron{flex:none;color:var(--kf-color-gray-400)}.kf-alert-row__icon--neutral{background:var(--kf-color-gray-100);color:var(--kf-color-text)}.kf-alert-row__main{flex:1 1 auto;min-width:0;display:flex;flex-wrap:wrap;align-items:center;gap:4px var(--kf-space-sm)}.kf-alert-row__main .kf-alert-row__text{flex:0 1 auto}.kf-alert-row__tag{display:inline-flex;align-items:center;padding:3px 8px;border-radius:var(--kf-radius-pill);background:var(--kf-color-gray-200);color:var(--kf-color-text);font-size:.72rem;font-weight:600;line-height:1;white-space:nowrap}.kf-alert-row__value{flex:none;min-width:2ch;font-family:var(--kf-font-title);font-size:1.15rem;font-weight:700;font-variant-numeric:tabular-nums;text-align:right;color:var(--kf-color-ink)}.kf-alert-row--disabled,.kf-alert-row--disabled:hover{background:transparent;cursor:default}.kf-alert-row--disabled .kf-alert-row__chevron{visibility:hidden}.kf-alert-row--disabled .kf-alert-row__text{font-weight:500;color:var(--kf-color-text)}.kf-alert-row--disabled .kf-alert-row__value{color:var(--kf-color-text)}\n"] }]
1340
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], valueLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueLabel", required: false }] }], tag: [{ type: i0.Input, args: [{ isSignal: true, alias: "tag", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }] } });
1302
1341
 
1303
1342
  /**
1304
1343
  * Avatar de usuario: muestra una foto (`src`) o, si no hay foto, las
@@ -1816,7 +1855,7 @@ class Card {
1816
1855
  /** Cubre el cuerpo con un bloque de carga conservando las dimensiones. */
1817
1856
  loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1818
1857
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Card, deps: [], target: i0.ɵɵFactoryTarget.Component });
1819
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: Card, isStandalone: true, selector: "kf-card", inputs: { flush: { classPropertyName: "flush", publicName: "flush", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kf-card--flush": "flush()", "class.kf-card--loading": "loading()", "attr.aria-busy": "loading() ? 'true' : null", "class.kf-card--gap-xs": "gap() === 'xs'", "class.kf-card--gap-sm": "gap() === 'sm'", "class.kf-card--gap-md": "gap() === 'md'", "class.kf-card--gap-lg": "gap() === 'lg'", "class.kf-card--gap-xl": "gap() === 'xl'" } }, ngImport: i0, template: "<ng-content select=\"[kf-card-media]\" />\n<div\n class=\"kf-card__body\"\n [class.kf-card__body--loading]=\"loading()\"\n [class.kf-bone-overlay]=\"loading()\"\n>\n <ng-content />\n</div>\n<ng-content select=\"[kf-card-actions]\" />\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;flex-direction:column;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-xs);overflow:hidden}:host.kf-card--flush{box-shadow:none}.kf-card__body{display:flex;flex-direction:column;gap:var(--kf-space-md);padding:var(--kf-space-md);flex:1 1 auto}:host.kf-card--gap-xs .kf-card__body{gap:var(--kf-space-xs)}:host.kf-card--gap-sm .kf-card__body{gap:var(--kf-space-sm)}:host.kf-card--gap-md .kf-card__body{gap:var(--kf-space-md)}:host.kf-card--gap-lg .kf-card__body{gap:var(--kf-space-lg)}:host.kf-card--gap-xl .kf-card__body{gap:var(--kf-space-xl)}::ng-deep [kf-card-media]{display:block;inline-size:100%;block-size:auto;object-fit:cover}::ng-deep [kf-card-actions]{display:flex;align-items:center;justify-content:flex-end;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-card__body--loading{position:relative;visibility:hidden}.kf-card__body--loading:after{content:\"\";visibility:visible;position:absolute;inset:var(--kf-space-md);border-radius:var(--kf-radius-sm)}:host.kf-card--loading ::ng-deep [kf-card-media],:host.kf-card--loading ::ng-deep [kf-card-actions]{visibility:hidden}\n"] });
1858
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: Card, isStandalone: true, selector: "kf-card", inputs: { flush: { classPropertyName: "flush", publicName: "flush", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kf-card--flush": "flush()", "class.kf-card--loading": "loading()", "attr.aria-busy": "loading() ? 'true' : null", "class.kf-card--gap-xs": "gap() === 'xs'", "class.kf-card--gap-sm": "gap() === 'sm'", "class.kf-card--gap-md": "gap() === 'md'", "class.kf-card--gap-lg": "gap() === 'lg'", "class.kf-card--gap-xl": "gap() === 'xl'" } }, ngImport: i0, template: "<ng-content select=\"[kf-card-media]\" />\n<div\n class=\"kf-card__body\"\n [class.kf-card__body--loading]=\"loading()\"\n [class.kf-bone-overlay]=\"loading()\"\n>\n <ng-content />\n</div>\n<ng-content select=\"[kf-card-actions]\" />\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;flex-direction:column;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-xs);overflow:hidden}:host.kf-card--flush{box-shadow:none}.kf-card__body{display:flex;flex-direction:column;gap:var(--kf-space-md);padding:var(--kf-space-md);flex:1 1 auto}:host.kf-card--gap-xs .kf-card__body{gap:var(--kf-space-xs)}:host.kf-card--gap-sm .kf-card__body{gap:var(--kf-space-sm)}:host.kf-card--gap-md .kf-card__body{gap:var(--kf-space-md)}:host.kf-card--gap-lg .kf-card__body{gap:var(--kf-space-lg)}:host.kf-card--gap-xl .kf-card__body{gap:var(--kf-space-xl)}::ng-deep [kf-card-media]{display:block;inline-size:100%;block-size:auto;object-fit:cover}::ng-deep [kf-card-actions]{display:flex;align-items:center;justify-content:flex-end;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-card__body--loading{position:relative;visibility:hidden}.kf-card__body--loading:after{content:\"\";visibility:visible;position:absolute;inset:var(--kf-space-md);border-radius:var(--kf-radius-sm)}:host.kf-card--loading ::ng-deep [kf-card-media],:host.kf-card--loading ::ng-deep [kf-card-actions]{visibility:hidden}\n"] });
1820
1859
  }
1821
1860
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Card, decorators: [{
1822
1861
  type: Component,
@@ -1829,7 +1868,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
1829
1868
  '[class.kf-card--gap-md]': "gap() === 'md'",
1830
1869
  '[class.kf-card--gap-lg]': "gap() === 'lg'",
1831
1870
  '[class.kf-card--gap-xl]': "gap() === 'xl'",
1832
- }, template: "<ng-content select=\"[kf-card-media]\" />\n<div\n class=\"kf-card__body\"\n [class.kf-card__body--loading]=\"loading()\"\n [class.kf-bone-overlay]=\"loading()\"\n>\n <ng-content />\n</div>\n<ng-content select=\"[kf-card-actions]\" />\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;flex-direction:column;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-xs);overflow:hidden}:host.kf-card--flush{box-shadow:none}.kf-card__body{display:flex;flex-direction:column;gap:var(--kf-space-md);padding:var(--kf-space-md);flex:1 1 auto}:host.kf-card--gap-xs .kf-card__body{gap:var(--kf-space-xs)}:host.kf-card--gap-sm .kf-card__body{gap:var(--kf-space-sm)}:host.kf-card--gap-md .kf-card__body{gap:var(--kf-space-md)}:host.kf-card--gap-lg .kf-card__body{gap:var(--kf-space-lg)}:host.kf-card--gap-xl .kf-card__body{gap:var(--kf-space-xl)}::ng-deep [kf-card-media]{display:block;inline-size:100%;block-size:auto;object-fit:cover}::ng-deep [kf-card-actions]{display:flex;align-items:center;justify-content:flex-end;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-card__body--loading{position:relative;visibility:hidden}.kf-card__body--loading:after{content:\"\";visibility:visible;position:absolute;inset:var(--kf-space-md);border-radius:var(--kf-radius-sm)}:host.kf-card--loading ::ng-deep [kf-card-media],:host.kf-card--loading ::ng-deep [kf-card-actions]{visibility:hidden}\n"] }]
1871
+ }, template: "<ng-content select=\"[kf-card-media]\" />\n<div\n class=\"kf-card__body\"\n [class.kf-card__body--loading]=\"loading()\"\n [class.kf-bone-overlay]=\"loading()\"\n>\n <ng-content />\n</div>\n<ng-content select=\"[kf-card-actions]\" />\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;flex-direction:column;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-xs);overflow:hidden}:host.kf-card--flush{box-shadow:none}.kf-card__body{display:flex;flex-direction:column;gap:var(--kf-space-md);padding:var(--kf-space-md);flex:1 1 auto}:host.kf-card--gap-xs .kf-card__body{gap:var(--kf-space-xs)}:host.kf-card--gap-sm .kf-card__body{gap:var(--kf-space-sm)}:host.kf-card--gap-md .kf-card__body{gap:var(--kf-space-md)}:host.kf-card--gap-lg .kf-card__body{gap:var(--kf-space-lg)}:host.kf-card--gap-xl .kf-card__body{gap:var(--kf-space-xl)}::ng-deep [kf-card-media]{display:block;inline-size:100%;block-size:auto;object-fit:cover}::ng-deep [kf-card-actions]{display:flex;align-items:center;justify-content:flex-end;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-card__body--loading{position:relative;visibility:hidden}.kf-card__body--loading:after{content:\"\";visibility:visible;position:absolute;inset:var(--kf-space-md);border-radius:var(--kf-radius-sm)}:host.kf-card--loading ::ng-deep [kf-card-media],:host.kf-card--loading ::ng-deep [kf-card-actions]{visibility:hidden}\n"] }]
1833
1872
  }], propDecorators: { flush: [{ type: i0.Input, args: [{ isSignal: true, alias: "flush", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
1834
1873
 
1835
1874
  /**
@@ -2004,7 +2043,7 @@ class Checkbox {
2004
2043
  useExisting: forwardRef(() => Checkbox),
2005
2044
  multi: true,
2006
2045
  },
2007
- ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"kf-checkbox__box kf-checkbox-box\"\n [class.kf-checkbox__box--invalid]=\"invalid()\"\n ></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n</label>\n", styles: [".kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-block}.kf-checkbox{display:inline-flex;align-items:center;gap:var(--kf-space-sm);cursor:pointer;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text)}.kf-checkbox--disabled{cursor:not-allowed;color:var(--kf-color-text-muted)}.kf-checkbox input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kf-checkbox__box{display:inline-flex;align-items:center;justify-content:center}.kf-checkbox input:checked+.kf-checkbox__box,.kf-checkbox input:indeterminate+.kf-checkbox__box{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-checkbox input:checked+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border-radius:var(--kf-radius-xs)}.kf-checkbox input:focus-visible+.kf-checkbox__box{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-checkbox__box--invalid{border-color:var(--kf-color-error)}.kf-checkbox--disabled .kf-checkbox__box{opacity:.5}.kf-checkbox__label{-webkit-user-select:none;user-select:none}\n"] });
2046
+ ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"kf-checkbox__box kf-checkbox-box\"\n [class.kf-checkbox__box--invalid]=\"invalid()\"\n ></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n</label>\n", styles: [".kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-block}.kf-checkbox{display:inline-flex;align-items:center;gap:var(--kf-space-sm);cursor:pointer;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text)}.kf-checkbox--disabled{cursor:not-allowed;color:var(--kf-color-text-muted)}.kf-checkbox input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kf-checkbox__box{display:inline-flex;align-items:center;justify-content:center}.kf-checkbox input:checked+.kf-checkbox__box,.kf-checkbox input:indeterminate+.kf-checkbox__box{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-checkbox input:checked+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border-radius:var(--kf-radius-xs)}.kf-checkbox input:focus-visible+.kf-checkbox__box{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-checkbox__box--invalid{border-color:var(--kf-color-error)}.kf-checkbox--disabled .kf-checkbox__box{opacity:.5}.kf-checkbox__label{-webkit-user-select:none;user-select:none}\n"] });
2008
2047
  }
2009
2048
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Checkbox, decorators: [{
2010
2049
  type: Component,
@@ -2014,7 +2053,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
2014
2053
  useExisting: forwardRef(() => Checkbox),
2015
2054
  multi: true,
2016
2055
  },
2017
- ], template: "<label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"kf-checkbox__box kf-checkbox-box\"\n [class.kf-checkbox__box--invalid]=\"invalid()\"\n ></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n</label>\n", styles: [".kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-block}.kf-checkbox{display:inline-flex;align-items:center;gap:var(--kf-space-sm);cursor:pointer;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text)}.kf-checkbox--disabled{cursor:not-allowed;color:var(--kf-color-text-muted)}.kf-checkbox input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kf-checkbox__box{display:inline-flex;align-items:center;justify-content:center}.kf-checkbox input:checked+.kf-checkbox__box,.kf-checkbox input:indeterminate+.kf-checkbox__box{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-checkbox input:checked+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border-radius:var(--kf-radius-xs)}.kf-checkbox input:focus-visible+.kf-checkbox__box{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-checkbox__box--invalid{border-color:var(--kf-color-error)}.kf-checkbox--disabled .kf-checkbox__box{opacity:.5}.kf-checkbox__label{-webkit-user-select:none;user-select:none}\n"] }]
2056
+ ], template: "<label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"kf-checkbox__box kf-checkbox-box\"\n [class.kf-checkbox__box--invalid]=\"invalid()\"\n ></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n</label>\n", styles: [".kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-block}.kf-checkbox{display:inline-flex;align-items:center;gap:var(--kf-space-sm);cursor:pointer;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text)}.kf-checkbox--disabled{cursor:not-allowed;color:var(--kf-color-text-muted)}.kf-checkbox input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kf-checkbox__box{display:inline-flex;align-items:center;justify-content:center}.kf-checkbox input:checked+.kf-checkbox__box,.kf-checkbox input:indeterminate+.kf-checkbox__box{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-checkbox input:checked+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border-radius:var(--kf-radius-xs)}.kf-checkbox input:focus-visible+.kf-checkbox__box{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-checkbox__box--invalid{border-color:var(--kf-color-error)}.kf-checkbox--disabled .kf-checkbox__box{opacity:.5}.kf-checkbox__label{-webkit-user-select:none;user-select:none}\n"] }]
2018
2057
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }], inputRef: [{ type: i0.ViewChild, args: ['inputRef', { isSignal: true }] }] } });
2019
2058
 
2020
2059
  /**
@@ -2122,6 +2161,7 @@ function listenEscapeCapture(doc, onEscape) {
2122
2161
  return () => doc.removeEventListener('keydown', handler, true);
2123
2162
  }
2124
2163
 
2164
+ let nextPanelId = 0;
2125
2165
  /**
2126
2166
  * Contenido del panel flotante de un `kf-dropdown`. Es solo una plantilla
2127
2167
  * (`<ng-template>`, capturada vía `TemplateRef`) — `Dropdown` la conecta al
@@ -2137,20 +2177,35 @@ function listenEscapeCapture(doc, onEscape) {
2137
2177
  * reposiciona el panel según dónde entra en el viewport y puede terminar
2138
2178
  * cayendo sobre fondo blanco en vez de sobre el rail oscuro — un color
2139
2179
  * sólido se ve intencional sin importar dónde lo posicione el CDK.
2180
+ *
2181
+ * `role`: `'menu'` (default) cuando el contenido son `kf-dropdown-item`;
2182
+ * `'dialog'` cuando lleva campos de formulario, selects, casillas o texto
2183
+ * libre — un `role="menu"` solo admite ítems de menú como hijos. Un panel
2184
+ * `dialog` necesita nombre: pasar `ariaLabel`.
2185
+ *
2186
+ * <kf-dropdown-panel role="dialog" ariaLabel="Filtros">…</kf-dropdown-panel>
2140
2187
  */
2141
2188
  class DropdownPanel {
2142
2189
  variant = input('solid', /* @ts-ignore */
2143
2190
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
2191
+ role = input('menu', /* @ts-ignore */
2192
+ ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
2193
+ /** Nombre accesible del panel (obligatorio en la práctica con `role="dialog"`). */
2194
+ ariaLabel = input(/* @ts-ignore */
2195
+ ...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2196
+ /** `id` del contenedor con el rol; el disparador lo referencia con `aria-controls`. */
2197
+ panelId = `kf-dropdown-panel-${nextPanelId++}`;
2144
2198
  templateRef = viewChild.required(TemplateRef, /* @ts-ignore */
2145
2199
  ...(ngDevMode ? [{ debugName: "templateRef" }] : /* istanbul ignore next */ []));
2146
2200
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
2147
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: DropdownPanel, isStandalone: true, selector: "kf-dropdown-panel", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template>\n <div class=\"kf-dropdown-panel\" [class.kf-dropdown-panel--dark]=\"variant() === 'dark'\">\n <div class=\"kf-dropdown-panel__inner\" role=\"menu\">\n <ng-content />\n </div>\n </div>\n</ng-template>\n", styles: [".kf-dropdown-panel{min-width:220px;max-width:min(280px,90vw);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-lg);font-family:var(--kf-font-body);animation:kf-dropdown-panel-enter .14s ease-out}.kf-dropdown-panel--dark{background:var(--kf-color-tertiary-deep);border-color:#ffffff24}.kf-dropdown-panel__inner{padding:var(--kf-space-xs) 0;overflow:hidden;border-radius:inherit}@media(prefers-reduced-motion:reduce){.kf-dropdown-panel{animation:none}}@keyframes kf-dropdown-panel-enter{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] });
2201
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: DropdownPanel, isStandalone: true, selector: "kf-dropdown-panel", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.role": "null" } }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template>\n <div class=\"kf-dropdown-panel\" [class.kf-dropdown-panel--dark]=\"variant() === 'dark'\">\n <div\n class=\"kf-dropdown-panel__inner\"\n tabindex=\"-1\"\n [id]=\"panelId\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n >\n <ng-content />\n </div>\n </div>\n</ng-template>\n", styles: [".kf-dropdown-panel{min-width:220px;max-width:min(280px,90vw);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-lg);font-family:var(--kf-font-body);animation:kf-dropdown-panel-enter .14s ease-out}.kf-dropdown-panel--dark{background:var(--kf-color-tertiary-deep);border-color:#ffffff24}.kf-dropdown-panel__inner{padding:var(--kf-space-xs) 0;overflow:hidden;border-radius:inherit}@media(prefers-reduced-motion:reduce){.kf-dropdown-panel{animation:none}}@keyframes kf-dropdown-panel-enter{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.kf-dropdown-panel__inner:focus{outline:none}\n"] });
2148
2202
  }
2149
2203
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownPanel, decorators: [{
2150
2204
  type: Component,
2151
- args: [{ selector: 'kf-dropdown-panel', template: "<ng-template>\n <div class=\"kf-dropdown-panel\" [class.kf-dropdown-panel--dark]=\"variant() === 'dark'\">\n <div class=\"kf-dropdown-panel__inner\" role=\"menu\">\n <ng-content />\n </div>\n </div>\n</ng-template>\n", styles: [".kf-dropdown-panel{min-width:220px;max-width:min(280px,90vw);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-lg);font-family:var(--kf-font-body);animation:kf-dropdown-panel-enter .14s ease-out}.kf-dropdown-panel--dark{background:var(--kf-color-tertiary-deep);border-color:#ffffff24}.kf-dropdown-panel__inner{padding:var(--kf-space-xs) 0;overflow:hidden;border-radius:inherit}@media(prefers-reduced-motion:reduce){.kf-dropdown-panel{animation:none}}@keyframes kf-dropdown-panel-enter{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
2152
- }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], templateRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
2205
+ args: [{ selector: 'kf-dropdown-panel', host: { '[attr.role]': 'null' }, template: "<ng-template>\n <div class=\"kf-dropdown-panel\" [class.kf-dropdown-panel--dark]=\"variant() === 'dark'\">\n <div\n class=\"kf-dropdown-panel__inner\"\n tabindex=\"-1\"\n [id]=\"panelId\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n >\n <ng-content />\n </div>\n </div>\n</ng-template>\n", styles: [".kf-dropdown-panel{min-width:220px;max-width:min(280px,90vw);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-lg);font-family:var(--kf-font-body);animation:kf-dropdown-panel-enter .14s ease-out}.kf-dropdown-panel--dark{background:var(--kf-color-tertiary-deep);border-color:#ffffff24}.kf-dropdown-panel__inner{padding:var(--kf-space-xs) 0;overflow:hidden;border-radius:inherit}@media(prefers-reduced-motion:reduce){.kf-dropdown-panel{animation:none}}@keyframes kf-dropdown-panel-enter{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.kf-dropdown-panel__inner:focus{outline:none}\n"] }]
2206
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], templateRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
2153
2207
 
2208
+ const FOCUSABLE_SELECTOR$1 = 'button:not([disabled]), a[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
2154
2209
  /**
2155
2210
  * Menú de acciones flotante, conectado a un elemento disparador vía
2156
2211
  * `@angular/cdk/overlay` — la misma pieza que usa Angular Material para
@@ -2164,6 +2219,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
2164
2219
  * de anclaje visual del panel.
2165
2220
  *
2166
2221
  * <kf-dropdown [(open)]="menuOpen"><kf-dropdown-panel>...</kf-dropdown-panel></kf-dropdown>
2222
+ *
2223
+ * Accesibilidad. Disparador: el primer control enfocable del `anchor` (o del
2224
+ * propio host) recibe `aria-haspopup` (`menu` o `dialog`, según el `role` del
2225
+ * panel), `aria-expanded` y, con el panel abierto, `aria-controls`; un atributo
2226
+ * que el consumidor ya declaró nunca se pisa. Foco: el panel vive en un overlay
2227
+ * al final del `body`, así que al abrir el foco pasa al primer elemento
2228
+ * enfocable del panel (`autoFocus`, default `true`; solo si el foco estaba en
2229
+ * el disparador, para no robarlo cuando algo abre el panel por código), y al
2230
+ * cerrar vuelve al disparador si estaba dentro del panel (Escape, elegir una
2231
+ * acción, aplicar). Un clic afuera no devuelve el foco: ya se fue a donde se
2232
+ * hizo clic. Con `role="menu"` las flechas, Home y End recorren los ítems. Tab
2233
+ * desde el último (o Shift+Tab desde el primero) cierra el panel y continúa la
2234
+ * tabulación desde el disparador.
2167
2235
  */
2168
2236
  class Dropdown {
2169
2237
  /** Visibilidad del panel, two-way: `[(open)]="menuOpen"`. */
@@ -2178,12 +2246,21 @@ class Dropdown {
2178
2246
  */
2179
2247
  anchor = input(/* @ts-ignore */
2180
2248
  ...(ngDevMode ? [undefined, { debugName: "anchor" }] : /* istanbul ignore next */ []));
2249
+ /**
2250
+ * Mueve el foco al primer elemento enfocable del panel al abrirlo. Poner
2251
+ * `false` si el contenido ya gestiona su propio foco inicial.
2252
+ */
2253
+ autoFocus = input(true, { ...(ngDevMode ? { debugName: "autoFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2181
2254
  panel = contentChild(DropdownPanel, /* @ts-ignore */
2182
2255
  ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
2183
2256
  overlayService = inject(Overlay);
2184
2257
  host = inject((ElementRef));
2185
2258
  viewContainerRef = inject(ViewContainerRef);
2186
2259
  destroyRef = inject(DestroyRef);
2260
+ injector = inject(Injector);
2261
+ document = inject(DOCUMENT);
2262
+ /** Atributos ARIA que este componente puso en el disparador (y por tanto retira él). */
2263
+ ownedTriggerAttributes = new Map();
2187
2264
  overlayRef = null;
2188
2265
  /**
2189
2266
  * Suscripciones a `outsidePointerEvents()`/`keydownEvents()` del overlay
@@ -2203,11 +2280,17 @@ class Dropdown {
2203
2280
  this.detach();
2204
2281
  }
2205
2282
  });
2206
- const stopEscape = listenEscapeCapture(inject(DOCUMENT), () => this.onDocumentEscape());
2283
+ effect(() => {
2284
+ const open = this.open();
2285
+ const panel = this.panel();
2286
+ untracked(() => this.syncTriggerAria(open, panel));
2287
+ });
2288
+ const stopEscape = listenEscapeCapture(this.document, () => this.onDocumentEscape());
2207
2289
  this.destroyRef.onDestroy(() => {
2208
2290
  stopEscape();
2209
2291
  this.overlaySubscription?.unsubscribe();
2210
2292
  this.overlayRef?.dispose();
2293
+ this.releaseTriggerAria();
2211
2294
  });
2212
2295
  }
2213
2296
  /**
@@ -2244,8 +2327,111 @@ class Dropdown {
2244
2327
  this.overlaySubscription.add(overlayRef.keydownEvents().subscribe((event) => {
2245
2328
  if (event.key === 'Escape') {
2246
2329
  this.open.set(false);
2330
+ return;
2247
2331
  }
2332
+ this.onPanelKeydown(event, overlayRef.overlayElement);
2248
2333
  }));
2334
+ if (this.autoFocus() && this.isFocusOnTrigger()) {
2335
+ afterNextRender(() => this.focusFirstInPanel(overlayRef.overlayElement), {
2336
+ injector: this.injector,
2337
+ });
2338
+ }
2339
+ }
2340
+ /** Flechas/Home/End entre ítems (solo `role="menu"`) y salida con Tab en los extremos. */
2341
+ onPanelKeydown(event, pane) {
2342
+ const focusables = this.focusableIn(pane);
2343
+ const active = this.document.activeElement;
2344
+ const index = active ? focusables.indexOf(active) : -1;
2345
+ if (event.key === 'Tab') {
2346
+ const leaving = event.shiftKey ? index <= 0 : index === focusables.length - 1;
2347
+ if (leaving) {
2348
+ // Sin preventDefault: la tabulación nativa sigue desde el disparador.
2349
+ this.triggerElement()?.focus();
2350
+ this.open.set(false);
2351
+ }
2352
+ return;
2353
+ }
2354
+ if (this.panel()?.role() !== 'menu' || focusables.length === 0) {
2355
+ return;
2356
+ }
2357
+ const last = focusables.length - 1;
2358
+ let target = -1;
2359
+ switch (event.key) {
2360
+ case 'ArrowDown':
2361
+ target = index >= last ? 0 : index + 1;
2362
+ break;
2363
+ case 'ArrowUp':
2364
+ target = index <= 0 ? last : index - 1;
2365
+ break;
2366
+ case 'Home':
2367
+ target = 0;
2368
+ break;
2369
+ case 'End':
2370
+ target = last;
2371
+ break;
2372
+ }
2373
+ if (target >= 0) {
2374
+ event.preventDefault();
2375
+ focusables[target].focus();
2376
+ }
2377
+ }
2378
+ focusFirstInPanel(pane) {
2379
+ const first = this.focusableIn(pane)[0];
2380
+ (first ?? pane.querySelector('.kf-dropdown-panel__inner'))?.focus();
2381
+ }
2382
+ focusableIn(pane) {
2383
+ return Array.from(pane.querySelectorAll(FOCUSABLE_SELECTOR$1)).filter((element) => element.checkVisibility?.() ?? true);
2384
+ }
2385
+ isFocusOnTrigger() {
2386
+ const active = this.document.activeElement;
2387
+ const trigger = this.anchor()?.nativeElement ?? this.host.nativeElement;
2388
+ return !!active && trigger.contains(active);
2389
+ }
2390
+ /**
2391
+ * Control que abre el panel: el propio `anchor`/host si ya es enfocable, o
2392
+ * su primer descendiente enfocable (ej. el `<button>` dentro de `kf-button`).
2393
+ */
2394
+ triggerElement() {
2395
+ const root = this.anchor()?.nativeElement ?? this.host.nativeElement;
2396
+ if (root.matches(FOCUSABLE_SELECTOR$1)) {
2397
+ return root;
2398
+ }
2399
+ return root.querySelector(FOCUSABLE_SELECTOR$1);
2400
+ }
2401
+ syncTriggerAria(open, panel) {
2402
+ const trigger = this.triggerElement();
2403
+ if (!trigger || !panel) {
2404
+ return;
2405
+ }
2406
+ this.setOwnedAttribute(trigger, 'aria-haspopup', panel.role());
2407
+ this.setOwnedAttribute(trigger, 'aria-expanded', String(open));
2408
+ if (open) {
2409
+ this.setOwnedAttribute(trigger, 'aria-controls', panel.panelId);
2410
+ }
2411
+ else {
2412
+ this.removeOwnedAttribute(trigger, 'aria-controls');
2413
+ }
2414
+ }
2415
+ /** Escribe el atributo solo si no es del consumidor (ausente, o ya puesto por este componente). */
2416
+ setOwnedAttribute(element, name, value) {
2417
+ const owned = this.ownedTriggerAttributes.get(element) ?? new Set();
2418
+ if (element.hasAttribute(name) && !owned.has(name)) {
2419
+ return;
2420
+ }
2421
+ element.setAttribute(name, value);
2422
+ owned.add(name);
2423
+ this.ownedTriggerAttributes.set(element, owned);
2424
+ }
2425
+ removeOwnedAttribute(element, name) {
2426
+ if (this.ownedTriggerAttributes.get(element)?.delete(name)) {
2427
+ element.removeAttribute(name);
2428
+ }
2429
+ }
2430
+ releaseTriggerAria() {
2431
+ for (const [element, names] of this.ownedTriggerAttributes) {
2432
+ names.forEach((name) => element.removeAttribute(name));
2433
+ }
2434
+ this.ownedTriggerAttributes.clear();
2249
2435
  }
2250
2436
  /**
2251
2437
  * El trigger real (el `anchor`, o el propio host si no se pasó ninguno —
@@ -2264,6 +2450,14 @@ class Dropdown {
2264
2450
  detach() {
2265
2451
  this.overlaySubscription?.unsubscribe();
2266
2452
  this.overlaySubscription = null;
2453
+ if (this.overlayRef?.hasAttached()) {
2454
+ // Antes de desmontar el panel: si no, el elemento enfocado desaparece y el foco cae al `body`.
2455
+ const pane = this.overlayRef.overlayElement;
2456
+ const active = this.document.activeElement;
2457
+ if (active && pane.contains(active)) {
2458
+ this.triggerElement()?.focus();
2459
+ }
2460
+ }
2267
2461
  this.overlayRef?.detach();
2268
2462
  }
2269
2463
  getOrCreateOverlayRef() {
@@ -2295,12 +2489,12 @@ class Dropdown {
2295
2489
  return this.overlayRef;
2296
2490
  }
2297
2491
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Dropdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
2298
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: Dropdown, isStandalone: true, selector: "kf-dropdown", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, queries: [{ propertyName: "panel", first: true, predicate: DropdownPanel, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{display:inline-block}\n"] });
2492
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.0", type: Dropdown, isStandalone: true, selector: "kf-dropdown", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, queries: [{ propertyName: "panel", first: true, predicate: DropdownPanel, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{display:inline-block}\n"] });
2299
2493
  }
2300
2494
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Dropdown, decorators: [{
2301
2495
  type: Component,
2302
2496
  args: [{ selector: 'kf-dropdown', template: `<ng-content />`, styles: [":host{display:inline-block}\n"] }]
2303
- }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], panel: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownPanel), { isSignal: true }] }] } });
2497
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], panel: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownPanel), { isSignal: true }] }] } });
2304
2498
 
2305
2499
  /**
2306
2500
  * Popover de "Datos de contacto" de una persona (asesor, ejecutivo — nombre
@@ -2355,11 +2549,11 @@ class ContactPopover {
2355
2549
  this.open.set(false);
2356
2550
  }
2357
2551
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ContactPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
2358
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ContactPopover, isStandalone: true, selector: "kf-contact-popover", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, whatsapp: { classPropertyName: "whatsapp", publicName: "whatsapp", isSignal: true, isRequired: false, transformFunction: null }, phone: { classPropertyName: "phone", publicName: "phone", isSignal: true, isRequired: false, transformFunction: null }, email: { classPropertyName: "email", publicName: "email", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<kf-dropdown class=\"kf-contact-popover\" [(open)]=\"open\">\n <button\n type=\"button\"\n class=\"kf-contact-popover__trigger\"\n [attr.aria-expanded]=\"open()\"\n (click)=\"onToggle()\"\n >\n {{ name() }}\n <kf-icon name=\"chevron-down\" size=\"sm\" [rotate]=\"open() ? 180 : 0\" />\n </button>\n <kf-dropdown-panel>\n <div class=\"kf-contact-popover__header\">\n <span class=\"kf-contact-popover__title\">{{ title() }}</span>\n <button\n type=\"button\"\n class=\"kf-contact-popover__close\"\n aria-label=\"Cerrar\"\n (click)=\"onClose()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n </div>\n <hr class=\"kf-contact-popover__hr\" />\n @if (hasContactMethods()) {\n @if (whatsappHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"whatsappHref()!\">\n <kf-icon name=\"message-circle\" size=\"sm\" />\n WhatsApp\n </a>\n }\n @if (phoneHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"phoneHref()!\">\n <kf-icon name=\"phone\" size=\"sm\" />\n Tel\u00E9fono\n </a>\n }\n @if (emailHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"emailHref()!\">\n <kf-icon name=\"mail\" size=\"sm\" />\n Correo\n </a>\n }\n } @else {\n <div class=\"kf-contact-popover__empty\">\n <kf-icon name=\"alert-circle\" size=\"sm\" />\n No registra datos de contacto\n </div>\n }\n </kf-dropdown-panel>\n</kf-dropdown>\n", styles: [":host{display:inline-flex}.kf-contact-popover{display:inline-flex}.kf-contact-popover__trigger{display:inline-flex;align-items:center;gap:4px;border:none;background:none;padding:0;font:inherit;font-weight:600;color:var(--kf-color-primary);cursor:pointer}.kf-contact-popover__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus);border-radius:var(--kf-radius-xs)}.kf-contact-popover__header{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md)}.kf-contact-popover__title{font-size:.8125rem;font-weight:700;color:var(--kf-color-ink)}.kf-contact-popover__close{display:inline-flex;border:none;background:none;padding:0;color:var(--kf-color-text-muted);cursor:pointer}.kf-contact-popover__hr{height:1px;margin:0;border:none;background:var(--kf-color-border)}.kf-contact-popover__link{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none}.kf-contact-popover__link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-contact-popover__link:hover{background:var(--kf-color-surface)}.kf-contact-popover__link:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-contact-popover__empty{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-md);color:var(--kf-color-text-muted);font-size:.875rem}\n"], dependencies: [{ kind: "component", type: Dropdown, selector: "kf-dropdown", inputs: ["open", "anchor"], outputs: ["openChange"] }, { kind: "component", type: DropdownPanel, selector: "kf-dropdown-panel", inputs: ["variant"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
2552
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ContactPopover, isStandalone: true, selector: "kf-contact-popover", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, whatsapp: { classPropertyName: "whatsapp", publicName: "whatsapp", isSignal: true, isRequired: false, transformFunction: null }, phone: { classPropertyName: "phone", publicName: "phone", isSignal: true, isRequired: false, transformFunction: null }, email: { classPropertyName: "email", publicName: "email", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<kf-dropdown class=\"kf-contact-popover\" [(open)]=\"open\">\n <button\n type=\"button\"\n class=\"kf-contact-popover__trigger\"\n [attr.aria-expanded]=\"open()\"\n (click)=\"onToggle()\"\n >\n {{ name() }}\n <kf-icon name=\"chevron-down\" size=\"sm\" [rotate]=\"open() ? 180 : 0\" />\n </button>\n <kf-dropdown-panel role=\"dialog\" [ariaLabel]=\"title()\">\n <div class=\"kf-contact-popover__header\">\n <span class=\"kf-contact-popover__title\">{{ title() }}</span>\n <button\n type=\"button\"\n class=\"kf-contact-popover__close\"\n aria-label=\"Cerrar\"\n (click)=\"onClose()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n </div>\n <hr class=\"kf-contact-popover__hr\" />\n @if (hasContactMethods()) {\n @if (whatsappHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"whatsappHref()!\">\n <kf-icon name=\"message-circle\" size=\"sm\" />\n WhatsApp\n </a>\n }\n @if (phoneHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"phoneHref()!\">\n <kf-icon name=\"phone\" size=\"sm\" />\n Tel\u00E9fono\n </a>\n }\n @if (emailHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"emailHref()!\">\n <kf-icon name=\"mail\" size=\"sm\" />\n Correo\n </a>\n }\n } @else {\n <div class=\"kf-contact-popover__empty\">\n <kf-icon name=\"alert-circle\" size=\"sm\" />\n No registra datos de contacto\n </div>\n }\n </kf-dropdown-panel>\n</kf-dropdown>\n", styles: [":host{display:inline-flex}.kf-contact-popover{display:inline-flex}.kf-contact-popover__trigger{display:inline-flex;align-items:center;gap:4px;border:none;background:none;padding:0;font:inherit;font-weight:600;color:var(--kf-color-primary);cursor:pointer}.kf-contact-popover__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus);border-radius:var(--kf-radius-xs)}.kf-contact-popover__header{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md)}.kf-contact-popover__title{font-size:.8125rem;font-weight:700;color:var(--kf-color-ink)}.kf-contact-popover__close{display:inline-flex;border:none;background:none;padding:0;color:var(--kf-color-text-muted);cursor:pointer}.kf-contact-popover__hr{height:1px;margin:0;border:none;background:var(--kf-color-border)}.kf-contact-popover__link{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none}.kf-contact-popover__link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-contact-popover__link:hover{background:var(--kf-color-surface)}.kf-contact-popover__link:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus-inset)}.kf-contact-popover__empty{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-md);color:var(--kf-color-text-muted);font-size:.875rem}\n"], dependencies: [{ kind: "component", type: Dropdown, selector: "kf-dropdown", inputs: ["open", "anchor", "autoFocus"], outputs: ["openChange"] }, { kind: "component", type: DropdownPanel, selector: "kf-dropdown-panel", inputs: ["variant", "role", "ariaLabel"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
2359
2553
  }
2360
2554
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ContactPopover, decorators: [{
2361
2555
  type: Component,
2362
- args: [{ selector: 'kf-contact-popover', imports: [Dropdown, DropdownPanel, Icon], template: "<kf-dropdown class=\"kf-contact-popover\" [(open)]=\"open\">\n <button\n type=\"button\"\n class=\"kf-contact-popover__trigger\"\n [attr.aria-expanded]=\"open()\"\n (click)=\"onToggle()\"\n >\n {{ name() }}\n <kf-icon name=\"chevron-down\" size=\"sm\" [rotate]=\"open() ? 180 : 0\" />\n </button>\n <kf-dropdown-panel>\n <div class=\"kf-contact-popover__header\">\n <span class=\"kf-contact-popover__title\">{{ title() }}</span>\n <button\n type=\"button\"\n class=\"kf-contact-popover__close\"\n aria-label=\"Cerrar\"\n (click)=\"onClose()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n </div>\n <hr class=\"kf-contact-popover__hr\" />\n @if (hasContactMethods()) {\n @if (whatsappHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"whatsappHref()!\">\n <kf-icon name=\"message-circle\" size=\"sm\" />\n WhatsApp\n </a>\n }\n @if (phoneHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"phoneHref()!\">\n <kf-icon name=\"phone\" size=\"sm\" />\n Tel\u00E9fono\n </a>\n }\n @if (emailHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"emailHref()!\">\n <kf-icon name=\"mail\" size=\"sm\" />\n Correo\n </a>\n }\n } @else {\n <div class=\"kf-contact-popover__empty\">\n <kf-icon name=\"alert-circle\" size=\"sm\" />\n No registra datos de contacto\n </div>\n }\n </kf-dropdown-panel>\n</kf-dropdown>\n", styles: [":host{display:inline-flex}.kf-contact-popover{display:inline-flex}.kf-contact-popover__trigger{display:inline-flex;align-items:center;gap:4px;border:none;background:none;padding:0;font:inherit;font-weight:600;color:var(--kf-color-primary);cursor:pointer}.kf-contact-popover__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus);border-radius:var(--kf-radius-xs)}.kf-contact-popover__header{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md)}.kf-contact-popover__title{font-size:.8125rem;font-weight:700;color:var(--kf-color-ink)}.kf-contact-popover__close{display:inline-flex;border:none;background:none;padding:0;color:var(--kf-color-text-muted);cursor:pointer}.kf-contact-popover__hr{height:1px;margin:0;border:none;background:var(--kf-color-border)}.kf-contact-popover__link{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none}.kf-contact-popover__link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-contact-popover__link:hover{background:var(--kf-color-surface)}.kf-contact-popover__link:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-contact-popover__empty{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-md);color:var(--kf-color-text-muted);font-size:.875rem}\n"] }]
2556
+ args: [{ selector: 'kf-contact-popover', imports: [Dropdown, DropdownPanel, Icon], template: "<kf-dropdown class=\"kf-contact-popover\" [(open)]=\"open\">\n <button\n type=\"button\"\n class=\"kf-contact-popover__trigger\"\n [attr.aria-expanded]=\"open()\"\n (click)=\"onToggle()\"\n >\n {{ name() }}\n <kf-icon name=\"chevron-down\" size=\"sm\" [rotate]=\"open() ? 180 : 0\" />\n </button>\n <kf-dropdown-panel role=\"dialog\" [ariaLabel]=\"title()\">\n <div class=\"kf-contact-popover__header\">\n <span class=\"kf-contact-popover__title\">{{ title() }}</span>\n <button\n type=\"button\"\n class=\"kf-contact-popover__close\"\n aria-label=\"Cerrar\"\n (click)=\"onClose()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n </div>\n <hr class=\"kf-contact-popover__hr\" />\n @if (hasContactMethods()) {\n @if (whatsappHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"whatsappHref()!\">\n <kf-icon name=\"message-circle\" size=\"sm\" />\n WhatsApp\n </a>\n }\n @if (phoneHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"phoneHref()!\">\n <kf-icon name=\"phone\" size=\"sm\" />\n Tel\u00E9fono\n </a>\n }\n @if (emailHref()) {\n <a class=\"kf-contact-popover__link\" [href]=\"emailHref()!\">\n <kf-icon name=\"mail\" size=\"sm\" />\n Correo\n </a>\n }\n } @else {\n <div class=\"kf-contact-popover__empty\">\n <kf-icon name=\"alert-circle\" size=\"sm\" />\n No registra datos de contacto\n </div>\n }\n </kf-dropdown-panel>\n</kf-dropdown>\n", styles: [":host{display:inline-flex}.kf-contact-popover{display:inline-flex}.kf-contact-popover__trigger{display:inline-flex;align-items:center;gap:4px;border:none;background:none;padding:0;font:inherit;font-weight:600;color:var(--kf-color-primary);cursor:pointer}.kf-contact-popover__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus);border-radius:var(--kf-radius-xs)}.kf-contact-popover__header{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md)}.kf-contact-popover__title{font-size:.8125rem;font-weight:700;color:var(--kf-color-ink)}.kf-contact-popover__close{display:inline-flex;border:none;background:none;padding:0;color:var(--kf-color-text-muted);cursor:pointer}.kf-contact-popover__hr{height:1px;margin:0;border:none;background:var(--kf-color-border)}.kf-contact-popover__link{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none}.kf-contact-popover__link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-contact-popover__link:hover{background:var(--kf-color-surface)}.kf-contact-popover__link:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus-inset)}.kf-contact-popover__empty{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-md);color:var(--kf-color-text-muted);font-size:.875rem}\n"] }]
2363
2557
  }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], whatsapp: [{ type: i0.Input, args: [{ isSignal: true, alias: "whatsapp", required: false }] }], phone: [{ type: i0.Input, args: [{ isSignal: true, alias: "phone", required: false }] }], email: [{ type: i0.Input, args: [{ isSignal: true, alias: "email", required: false }] }] } });
2364
2558
 
2365
2559
  /**
@@ -2522,6 +2716,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
2522
2716
  *
2523
2717
  * <kf-field-label [for]="inputId">Patente o VIN</kf-field-label>
2524
2718
  * <kf-field-label [for]="inputId" required>Correo electrónico</kf-field-label>
2719
+ *
2720
+ * `visuallyHidden` deja el texto solo para lectores de pantalla: el `<label
2721
+ * for>` sigue nombrando el control sin ocupar espacio.
2525
2722
  */
2526
2723
  class FieldLabel {
2527
2724
  /** `id` del control asociado — se refleja como `for` en el `<label>` interno. */
@@ -2529,13 +2726,15 @@ class FieldLabel {
2529
2726
  ...(ngDevMode ? [undefined, { debugName: "for" }] : /* istanbul ignore next */ []));
2530
2727
  /** Muestra un asterisco visual indicando que el campo es obligatorio. */
2531
2728
  required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2729
+ /** Oculta el texto a la vista pero lo conserva como nombre accesible del control. */
2730
+ visuallyHidden = input(false, { ...(ngDevMode ? { debugName: "visuallyHidden" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2532
2731
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FieldLabel, deps: [], target: i0.ɵɵFactoryTarget.Component });
2533
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: FieldLabel, isStandalone: true, selector: "kf-field-label", inputs: { for: { classPropertyName: "for", publicName: "for", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<label class=\"kf-field-label\" [for]=\"for()\">\n <ng-content />\n @if (required()) {\n <span class=\"kf-field-label__required\" aria-hidden=\"true\">*</span>\n }\n</label>\n", styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-field-label__required{color:var(--kf-color-error);margin-inline-start:2px}\n"] });
2732
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: FieldLabel, isStandalone: true, selector: "kf-field-label", inputs: { for: { classPropertyName: "for", publicName: "for", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, visuallyHidden: { classPropertyName: "visuallyHidden", publicName: "visuallyHidden", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<label class=\"kf-field-label\" [class.kf-field-label--sr-only]=\"visuallyHidden()\" [for]=\"for()\">\n <ng-content />\n @if (required()) {\n <span class=\"kf-field-label__required\" aria-hidden=\"true\">*</span>\n }\n</label>\n", styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-field-label__required{color:var(--kf-color-error);margin-inline-start:2px}.kf-field-label--sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] });
2534
2733
  }
2535
2734
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FieldLabel, decorators: [{
2536
2735
  type: Component,
2537
- args: [{ selector: 'kf-field-label', template: "<label class=\"kf-field-label\" [for]=\"for()\">\n <ng-content />\n @if (required()) {\n <span class=\"kf-field-label__required\" aria-hidden=\"true\">*</span>\n }\n</label>\n", styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-field-label__required{color:var(--kf-color-error);margin-inline-start:2px}\n"] }]
2538
- }], propDecorators: { for: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }] } });
2736
+ args: [{ selector: 'kf-field-label', template: "<label class=\"kf-field-label\" [class.kf-field-label--sr-only]=\"visuallyHidden()\" [for]=\"for()\">\n <ng-content />\n @if (required()) {\n <span class=\"kf-field-label__required\" aria-hidden=\"true\">*</span>\n }\n</label>\n", styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-field-label__required{color:var(--kf-color-error);margin-inline-start:2px}.kf-field-label--sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
2737
+ }], propDecorators: { for: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], visuallyHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "visuallyHidden", required: false }] }] } });
2539
2738
 
2540
2739
  /**
2541
2740
  * Overlay flotante conectado a un trigger de ancho variable — usado por
@@ -2655,6 +2854,8 @@ let nextId$4 = 0;
2655
2854
  * dejaba el panel de "Filas" visiblemente más ancho que el propio
2656
2855
  * trigger que lo abre. */
2657
2856
  const COMPACT_PANEL_MIN_WIDTH = 72;
2857
+ /** Pausa tras la cual lo tecleado deja de acumularse para la búsqueda por prefijo. */
2858
+ const TYPEAHEAD_RESET_MS = 500;
2658
2859
  /**
2659
2860
  * Dropdown de selección simple con panel propio — NUNCA usa el `<select>`
2660
2861
  * nativo del navegador. Un `<select>` real siempre delega el popup de
@@ -2701,11 +2902,29 @@ const COMPACT_PANEL_MIN_WIDTH = 72;
2701
2902
  * buscador, si está visible). En el panel, flechas y Home/End mueven el
2702
2903
  * foco, Enter/Espacio eligen, Escape cierra y devuelve el foco al trigger,
2703
2904
  * y Tab cierra el panel y continúa la tabulación desde el trigger. Las
2704
- * opciones nunca son paradas de Tab (`tabindex="-1"`).
2905
+ * opciones nunca son paradas de Tab (`tabindex="-1"`). Home/End sobre el
2906
+ * trigger cerrado lo abren en la primera/última opción, y teclear letras
2907
+ * (con el panel abierto o cerrado, sin buscador) salta a la opción cuyo
2908
+ * label empieza con lo tecleado; repetir la misma letra recorre las que
2909
+ * empiezan igual.
2705
2910
  */
2706
2911
  class Select {
2707
2912
  label = input(/* @ts-ignore */
2708
2913
  ...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
2914
+ /**
2915
+ * Oculta el `label` a la vista y lo deja como nombre accesible (`<label
2916
+ * for>`): para un control cuyo valor se explica solo (ej. un rango de
2917
+ * fechas), sin tener que ocultar la etiqueta con CSS desde afuera.
2918
+ */
2919
+ hideLabel = input(false, { ...(ngDevMode ? { debugName: "hideLabel" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2920
+ /**
2921
+ * Texto corto visible dentro del trigger, antes del valor (ej. `Rango:
2922
+ * Últimos 30 días`), para un select compacto que no lleva etiqueta
2923
+ * encima. Forma parte del nombre accesible del botón: no combinarlo con
2924
+ * `label`/`ariaLabel`, que reemplazarían ese nombre.
2925
+ */
2926
+ prefix = input(/* @ts-ignore */
2927
+ ...(ngDevMode ? [undefined, { debugName: "prefix" }] : /* istanbul ignore next */ []));
2709
2928
  options = input.required(/* @ts-ignore */
2710
2929
  ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
2711
2930
  value = input(/* @ts-ignore */
@@ -2817,6 +3036,8 @@ class Select {
2817
3036
  panelRef = viewChild('panel', /* @ts-ignore */
2818
3037
  ...(ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []));
2819
3038
  document = inject(DOCUMENT);
3039
+ typeaheadBuffer = '';
3040
+ typeaheadTimer;
2820
3041
  overlay = new SelectOverlay(inject(Overlay), inject(ViewContainerRef), () => this.triggerRef(), () => (this.variant() === 'compact' ? COMPACT_PANEL_MIN_WIDTH : 0), () => (this.panelWidth() === 'content' ? 'content' : 'match'));
2821
3042
  constructor() {
2822
3043
  effect(() => {
@@ -2852,6 +3073,7 @@ class Select {
2852
3073
  const stopEscape = listenEscapeCapture(this.document, () => this.onDocumentEscape());
2853
3074
  inject(DestroyRef).onDestroy(() => {
2854
3075
  stopEscape();
3076
+ clearTimeout(this.typeaheadTimer);
2855
3077
  this.overlay.dispose();
2856
3078
  });
2857
3079
  }
@@ -2907,13 +3129,41 @@ class Select {
2907
3129
  }
2908
3130
  this.isOpen.set(false);
2909
3131
  }
2910
- /** ArrowDown/ArrowUp con el panel cerrado lo abren (patrón listbox). */
3132
+ /**
3133
+ * Con el panel cerrado: ArrowDown/ArrowUp lo abren en la opción activa,
3134
+ * Home/End en la primera/última, y una letra lo abre en la opción que
3135
+ * empieza con ella (patrón listbox).
3136
+ */
2911
3137
  onTriggerKeydown(event) {
2912
- if (this.isOpen() || (event.key !== 'ArrowDown' && event.key !== 'ArrowUp')) {
3138
+ if (this.isOpen() || this.disabled()) {
2913
3139
  return;
2914
3140
  }
2915
- event.preventDefault();
2916
- this.open();
3141
+ switch (event.key) {
3142
+ case 'ArrowDown':
3143
+ case 'ArrowUp':
3144
+ event.preventDefault();
3145
+ this.open();
3146
+ return;
3147
+ case 'Home':
3148
+ event.preventDefault();
3149
+ this.open();
3150
+ this.activeIndex.set(0);
3151
+ return;
3152
+ case 'End':
3153
+ event.preventDefault();
3154
+ this.open();
3155
+ this.activeIndex.set(this.filteredOptions().length - 1);
3156
+ return;
3157
+ }
3158
+ if (this.isTypeaheadKey(event)) {
3159
+ const selectedIndex = this.filteredOptions().findIndex((option) => option.value === this.value());
3160
+ const match = this.findTypeaheadMatch(event.key, selectedIndex);
3161
+ if (match >= 0) {
3162
+ event.preventDefault();
3163
+ this.open();
3164
+ this.activeIndex.set(match);
3165
+ }
3166
+ }
2917
3167
  }
2918
3168
  /**
2919
3169
  * Teclado con el foco en una opción del panel. Las flechas parten SIEMPRE
@@ -2954,9 +3204,51 @@ class Select {
2954
3204
  this.select(option);
2955
3205
  break;
2956
3206
  default:
3207
+ if (this.isTypeaheadKey(event)) {
3208
+ const match = this.findTypeaheadMatch(event.key, index);
3209
+ if (match >= 0) {
3210
+ event.preventDefault();
3211
+ this.activeIndex.set(match);
3212
+ this.focusOption(match);
3213
+ this.scrollActiveIntoView();
3214
+ }
3215
+ return;
3216
+ }
2957
3217
  this.handleExitKeys(event);
2958
3218
  }
2959
3219
  }
3220
+ /** Un carácter imprimible sin modificadores, y solo cuando no hay buscador (ahí la tecla filtra). */
3221
+ isTypeaheadKey(event) {
3222
+ return (!this.showSearch() &&
3223
+ event.key.length === 1 &&
3224
+ event.key !== ' ' &&
3225
+ !event.ctrlKey &&
3226
+ !event.metaKey &&
3227
+ !event.altKey);
3228
+ }
3229
+ /**
3230
+ * Índice de la opción cuyo label empieza con lo tecleado, o -1. Una sola
3231
+ * letra (o la misma repetida) busca desde la opción SIGUIENTE a `from`, para
3232
+ * recorrer las que empiezan igual; un prefijo más largo busca desde `from`
3233
+ * inclusive, para que la opción actual se conserve mientras siga coincidiendo.
3234
+ */
3235
+ findTypeaheadMatch(char, from) {
3236
+ this.typeaheadBuffer += normalizeForSearch(char);
3237
+ clearTimeout(this.typeaheadTimer);
3238
+ this.typeaheadTimer = setTimeout(() => (this.typeaheadBuffer = ''), TYPEAHEAD_RESET_MS);
3239
+ const options = this.filteredOptions();
3240
+ const buffer = this.typeaheadBuffer;
3241
+ const repeated = [...buffer].every((letter) => letter === buffer[0]);
3242
+ const prefix = repeated ? buffer[0] : buffer;
3243
+ const start = repeated ? from + 1 : Math.max(from, 0);
3244
+ for (let offset = 0; offset < options.length; offset++) {
3245
+ const index = (start + offset) % options.length;
3246
+ if (normalizeForSearch(options[index].label).startsWith(prefix)) {
3247
+ return index;
3248
+ }
3249
+ }
3250
+ return -1;
3251
+ }
2960
3252
  /** Teclas de salida del buscador: Escape y Tab, igual que desde una opción. */
2961
3253
  onSearchKeydown(event) {
2962
3254
  this.handleExitKeys(event);
@@ -3039,7 +3331,7 @@ class Select {
3039
3331
  }
3040
3332
  }
3041
3333
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Select, deps: [], target: i0.ɵɵFactoryTarget.Component });
3042
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Select, isStandalone: true, selector: "kf-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchThreshold: { classPropertyName: "searchThreshold", publicName: "searchThreshold", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, panelTitle: { classPropertyName: "panelTitle", publicName: "panelTitle", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.kf-select--compact": "variant() === 'compact'", "class.kf-select--width-sm": "width() === 'sm'", "class.kf-select--width-lg": "width() === 'lg'", "class.kf-select--width-full": "width() === 'full'" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }, { propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [class.kf-select__trigger--invalid]=\"invalid()\"\n [class.kf-select__trigger--with-icon]=\"!!icon()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n [attr.aria-label]=\"triggerAriaLabel()\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [class.kf-select__trigger--tagged]=\"!!selectedOption()?.tag\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-select__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ triggerText() }}\n </span>\n @if (selectedOption()?.tag; as tag) {\n <kf-badge class=\"kf-select__tag\">{{ tag }}</kf-badge>\n }\n <span\n class=\"kf-select__caret kf-caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n@if (errorMessage(); as message) {\n <span class=\"kf-select__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n}\n<ng-template #panelTemplate>\n <div #panel class=\"kf-select__panel\" [class.kf-select__panel--compact]=\"variant() === 'compact'\">\n @if (panelTitle(); as title) {\n <div class=\"kf-select__panel-title kf-overline-text\" aria-hidden=\"true\">{{ title }}</div>\n }\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-select__search\"\n placeholder=\"Buscar\u2026\"\n aria-label=\"Buscar opci\u00F3n\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"filteredOptions().length ? optionId(activeIndex()) : null\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); selectActive()\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n }\n <ul\n class=\"kf-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"ariaLabel() ? null : triggerId\"\n >\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-select__option\"\n [id]=\"optionId(i)\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n [class.kf-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"-1\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-label]=\"optionAriaLabel(option)\"\n [class.kf-select__option--rich]=\"!!(option.tag || option.detail)\"\n (click)=\"select(option)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown)=\"onOptionKeydown($event, option, i)\"\n >\n @if (option.tag || option.detail) {\n <span class=\"kf-select__option-main\">\n <span class=\"kf-select__option-label\">{{ option.label }}</span>\n @if (option.tag) {\n <kf-badge class=\"kf-select__tag\">{{ option.tag }}</kf-badge>\n }\n </span>\n @if (option.detail) {\n <span class=\"kf-select__option-detail\">{{ option.detail }}</span>\n }\n } @else {\n {{ option.label }}\n }\n </li>\n } @empty {\n <li class=\"kf-select__empty\">\n {{ searchQuery() ? 'Sin resultados' : 'Sin opciones disponibles' }}\n </li>\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}.kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);width:var(--kf-select-width-md);font-family:var(--kf-font-body)}:host(.kf-select--compact){width:max-content;max-width:160px}:host(.kf-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-select--width-full){width:100%}:host(.kf-select--compact) .kf-select__trigger{padding:6px var(--kf-space-sm);font-size:.85rem;gap:var(--kf-space-xs)}:host(.kf-select--compact) .kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select__trigger:focus-visible{outline:none;border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-select__trigger--disabled{opacity:.5;cursor:not-allowed}.kf-select__trigger--invalid{border-color:var(--kf-color-error)}.kf-select__trigger--invalid:focus-visible{border-color:var(--kf-color-error);box-shadow:var(--kf-shadow-focus-error)}.kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__icon{flex:none;color:var(--kf-color-text-muted)}.kf-select__trigger--with-icon .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}:host(.kf-select--compact) .kf-select__trigger--with-icon .kf-select__value{color:var(--kf-color-ink);font-weight:600}.kf-select__trigger--tagged .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}.kf-select__tag{flex:none}.kf-select__trigger .kf-select__tag{margin-block:-2px}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__panel{box-sizing:border-box;font-family:var(--kf-font-body);width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-select__panel-title{padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-xs)}.kf-select__panel--compact .kf-select__panel-title{padding:var(--kf-space-xs) var(--kf-space-sm) 2px}.kf-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-select__list::-webkit-scrollbar{width:6px}.kf-select__list::-webkit-scrollbar-track{background:transparent}.kf-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-select__option{padding:var(--kf-space-sm) var(--kf-space-md);outline:none;color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select__option--rich{display:flex;flex-direction:column;gap:2px}.kf-select__option-main{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-select__option-label,.kf-select__option-detail{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.kf-select__option-detail{font-size:var(--kf-font-size-body-sm);font-weight:400;color:var(--kf-color-text-muted)}.kf-select__panel--compact .kf-select__option{padding:6px var(--kf-space-sm);font-size:.85rem}.kf-select__option:hover{background:var(--kf-color-primary-soft)}.kf-select__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select__option--active{background:var(--kf-color-primary-soft)}.kf-select__option:focus-visible{background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "component", type: Badge, selector: "kf-badge", inputs: ["tone", "variant", "dot", "truncate"] }, { kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
3334
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Select, isStandalone: true, selector: "kf-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchThreshold: { classPropertyName: "searchThreshold", publicName: "searchThreshold", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, panelTitle: { classPropertyName: "panelTitle", publicName: "panelTitle", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.kf-select--compact": "variant() === 'compact'", "class.kf-select--width-sm": "width() === 'sm'", "class.kf-select--width-lg": "width() === 'lg'", "class.kf-select--width-full": "width() === 'full'" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }, { propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\" [visuallyHidden]=\"hideLabel()\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [class.kf-select__trigger--invalid]=\"invalid()\"\n [class.kf-select__trigger--with-icon]=\"!!icon()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n [attr.aria-label]=\"triggerAriaLabel()\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [class.kf-select__trigger--tagged]=\"!!selectedOption()?.tag\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-select__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n @if (prefix(); as prefixText) {\n <span class=\"kf-select__prefix\">{{ prefixText }}</span>\n }\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ triggerText() }}\n </span>\n @if (selectedOption()?.tag; as tag) {\n <kf-badge class=\"kf-select__tag\">{{ tag }}</kf-badge>\n }\n <span\n class=\"kf-select__caret kf-caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n@if (errorMessage(); as message) {\n <span class=\"kf-select__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n}\n<ng-template #panelTemplate>\n <div #panel class=\"kf-select__panel\" [class.kf-select__panel--compact]=\"variant() === 'compact'\">\n @if (panelTitle(); as title) {\n <div class=\"kf-select__panel-title kf-overline-text\" aria-hidden=\"true\">{{ title }}</div>\n }\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-select__search\"\n placeholder=\"Buscar\u2026\"\n aria-label=\"Buscar opci\u00F3n\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"filteredOptions().length ? optionId(activeIndex()) : null\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); selectActive()\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n }\n <ul\n class=\"kf-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"ariaLabel() ? null : triggerId\"\n >\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-select__option\"\n [id]=\"optionId(i)\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n [class.kf-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"-1\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-label]=\"optionAriaLabel(option)\"\n [class.kf-select__option--rich]=\"!!(option.tag || option.detail)\"\n (click)=\"select(option)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown)=\"onOptionKeydown($event, option, i)\"\n >\n @if (option.tag || option.detail) {\n <span class=\"kf-select__option-main\">\n <span class=\"kf-select__option-label\">{{ option.label }}</span>\n @if (option.tag) {\n <kf-badge class=\"kf-select__tag\">{{ option.tag }}</kf-badge>\n }\n </span>\n @if (option.detail) {\n <span class=\"kf-select__option-detail\">{{ option.detail }}</span>\n }\n } @else {\n {{ option.label }}\n }\n </li>\n } @empty {\n <li class=\"kf-select__empty\">\n {{ searchQuery() ? 'Sin resultados' : 'Sin opciones disponibles' }}\n </li>\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}.kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);width:var(--kf-select-width-md);font-family:var(--kf-font-body)}:host(.kf-select--compact){width:max-content;max-width:160px}:host(.kf-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-select--width-full){width:100%}:host(.kf-select--compact) .kf-select__trigger{padding:6px var(--kf-space-sm);font-size:.85rem;gap:var(--kf-space-xs)}:host(.kf-select--compact) .kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);background:var(--kf-color-white);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select__trigger:hover:not(:disabled){border-color:var(--kf-color-text-muted)}.kf-select__trigger:focus-visible{outline:none;border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-select__trigger--disabled{opacity:.5;cursor:not-allowed}.kf-select__trigger--invalid{border-color:var(--kf-color-error)}.kf-select__trigger--invalid:focus-visible{border-color:var(--kf-color-error);box-shadow:var(--kf-shadow-focus-error)}.kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__icon{flex:none;color:var(--kf-color-text-muted)}.kf-select__trigger--with-icon .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}:host(.kf-select--compact) .kf-select__trigger--with-icon .kf-select__value{color:var(--kf-color-ink);font-weight:600}.kf-select__trigger--tagged .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}.kf-select__tag{flex:none}.kf-select__trigger .kf-select__tag{margin-block:-2px}.kf-select__prefix{flex:none;color:var(--kf-color-text-muted);white-space:nowrap}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__panel{box-sizing:border-box;font-family:var(--kf-font-body);width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-select__panel-title{padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-xs)}.kf-select__panel--compact .kf-select__panel-title{padding:var(--kf-space-xs) var(--kf-space-sm) 2px}.kf-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-select__list::-webkit-scrollbar{width:6px}.kf-select__list::-webkit-scrollbar-track{background:transparent}.kf-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-select__option{padding:var(--kf-space-sm) var(--kf-space-md);outline:none;color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select__option--rich{display:flex;flex-direction:column;gap:2px}.kf-select__option-main{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-select__option-label,.kf-select__option-detail{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.kf-select__option-detail{font-size:var(--kf-font-size-body-sm);font-weight:400;color:var(--kf-color-text-muted)}.kf-select__panel--compact .kf-select__option{padding:6px var(--kf-space-sm);font-size:.85rem}.kf-select__option:hover{background:var(--kf-color-primary-soft)}.kf-select__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select__option--active{background:var(--kf-color-primary-soft)}.kf-select__option:focus-visible{background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "component", type: Badge, selector: "kf-badge", inputs: ["tone", "variant", "dot", "truncate"] }, { kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required", "visuallyHidden"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
3043
3335
  }
3044
3336
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Select, decorators: [{
3045
3337
  type: Component,
@@ -3048,8 +3340,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
3048
3340
  '[class.kf-select--width-sm]': "width() === 'sm'",
3049
3341
  '[class.kf-select--width-lg]': "width() === 'lg'",
3050
3342
  '[class.kf-select--width-full]': "width() === 'full'",
3051
- }, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [class.kf-select__trigger--invalid]=\"invalid()\"\n [class.kf-select__trigger--with-icon]=\"!!icon()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n [attr.aria-label]=\"triggerAriaLabel()\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [class.kf-select__trigger--tagged]=\"!!selectedOption()?.tag\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-select__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ triggerText() }}\n </span>\n @if (selectedOption()?.tag; as tag) {\n <kf-badge class=\"kf-select__tag\">{{ tag }}</kf-badge>\n }\n <span\n class=\"kf-select__caret kf-caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n@if (errorMessage(); as message) {\n <span class=\"kf-select__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n}\n<ng-template #panelTemplate>\n <div #panel class=\"kf-select__panel\" [class.kf-select__panel--compact]=\"variant() === 'compact'\">\n @if (panelTitle(); as title) {\n <div class=\"kf-select__panel-title kf-overline-text\" aria-hidden=\"true\">{{ title }}</div>\n }\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-select__search\"\n placeholder=\"Buscar\u2026\"\n aria-label=\"Buscar opci\u00F3n\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"filteredOptions().length ? optionId(activeIndex()) : null\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); selectActive()\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n }\n <ul\n class=\"kf-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"ariaLabel() ? null : triggerId\"\n >\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-select__option\"\n [id]=\"optionId(i)\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n [class.kf-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"-1\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-label]=\"optionAriaLabel(option)\"\n [class.kf-select__option--rich]=\"!!(option.tag || option.detail)\"\n (click)=\"select(option)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown)=\"onOptionKeydown($event, option, i)\"\n >\n @if (option.tag || option.detail) {\n <span class=\"kf-select__option-main\">\n <span class=\"kf-select__option-label\">{{ option.label }}</span>\n @if (option.tag) {\n <kf-badge class=\"kf-select__tag\">{{ option.tag }}</kf-badge>\n }\n </span>\n @if (option.detail) {\n <span class=\"kf-select__option-detail\">{{ option.detail }}</span>\n }\n } @else {\n {{ option.label }}\n }\n </li>\n } @empty {\n <li class=\"kf-select__empty\">\n {{ searchQuery() ? 'Sin resultados' : 'Sin opciones disponibles' }}\n </li>\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}.kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);width:var(--kf-select-width-md);font-family:var(--kf-font-body)}:host(.kf-select--compact){width:max-content;max-width:160px}:host(.kf-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-select--width-full){width:100%}:host(.kf-select--compact) .kf-select__trigger{padding:6px var(--kf-space-sm);font-size:.85rem;gap:var(--kf-space-xs)}:host(.kf-select--compact) .kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select__trigger:focus-visible{outline:none;border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-select__trigger--disabled{opacity:.5;cursor:not-allowed}.kf-select__trigger--invalid{border-color:var(--kf-color-error)}.kf-select__trigger--invalid:focus-visible{border-color:var(--kf-color-error);box-shadow:var(--kf-shadow-focus-error)}.kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__icon{flex:none;color:var(--kf-color-text-muted)}.kf-select__trigger--with-icon .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}:host(.kf-select--compact) .kf-select__trigger--with-icon .kf-select__value{color:var(--kf-color-ink);font-weight:600}.kf-select__trigger--tagged .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}.kf-select__tag{flex:none}.kf-select__trigger .kf-select__tag{margin-block:-2px}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__panel{box-sizing:border-box;font-family:var(--kf-font-body);width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-select__panel-title{padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-xs)}.kf-select__panel--compact .kf-select__panel-title{padding:var(--kf-space-xs) var(--kf-space-sm) 2px}.kf-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-select__list::-webkit-scrollbar{width:6px}.kf-select__list::-webkit-scrollbar-track{background:transparent}.kf-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-select__option{padding:var(--kf-space-sm) var(--kf-space-md);outline:none;color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select__option--rich{display:flex;flex-direction:column;gap:2px}.kf-select__option-main{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-select__option-label,.kf-select__option-detail{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.kf-select__option-detail{font-size:var(--kf-font-size-body-sm);font-weight:400;color:var(--kf-color-text-muted)}.kf-select__panel--compact .kf-select__option{padding:6px var(--kf-space-sm);font-size:.85rem}.kf-select__option:hover{background:var(--kf-color-primary-soft)}.kf-select__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select__option--active{background:var(--kf-color-primary-soft)}.kf-select__option:focus-visible{background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"] }]
3052
- }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchThreshold", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], panelTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelTitle", required: false }] }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panelTemplate: [{ type: i0.ViewChild, args: ['panelTemplate', { isSignal: true }] }], searchInputRef: [{ type: i0.ViewChild, args: ['searchInput', { isSignal: true }] }], panelRef: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }] } });
3343
+ }, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\" [visuallyHidden]=\"hideLabel()\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [class.kf-select__trigger--invalid]=\"invalid()\"\n [class.kf-select__trigger--with-icon]=\"!!icon()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n [attr.aria-label]=\"triggerAriaLabel()\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [class.kf-select__trigger--tagged]=\"!!selectedOption()?.tag\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-select__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n @if (prefix(); as prefixText) {\n <span class=\"kf-select__prefix\">{{ prefixText }}</span>\n }\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ triggerText() }}\n </span>\n @if (selectedOption()?.tag; as tag) {\n <kf-badge class=\"kf-select__tag\">{{ tag }}</kf-badge>\n }\n <span\n class=\"kf-select__caret kf-caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n@if (errorMessage(); as message) {\n <span class=\"kf-select__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n}\n<ng-template #panelTemplate>\n <div #panel class=\"kf-select__panel\" [class.kf-select__panel--compact]=\"variant() === 'compact'\">\n @if (panelTitle(); as title) {\n <div class=\"kf-select__panel-title kf-overline-text\" aria-hidden=\"true\">{{ title }}</div>\n }\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-select__search\"\n placeholder=\"Buscar\u2026\"\n aria-label=\"Buscar opci\u00F3n\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"filteredOptions().length ? optionId(activeIndex()) : null\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); selectActive()\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n }\n <ul\n class=\"kf-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"ariaLabel() ? null : triggerId\"\n >\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-select__option\"\n [id]=\"optionId(i)\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n [class.kf-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"-1\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-label]=\"optionAriaLabel(option)\"\n [class.kf-select__option--rich]=\"!!(option.tag || option.detail)\"\n (click)=\"select(option)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown)=\"onOptionKeydown($event, option, i)\"\n >\n @if (option.tag || option.detail) {\n <span class=\"kf-select__option-main\">\n <span class=\"kf-select__option-label\">{{ option.label }}</span>\n @if (option.tag) {\n <kf-badge class=\"kf-select__tag\">{{ option.tag }}</kf-badge>\n }\n </span>\n @if (option.detail) {\n <span class=\"kf-select__option-detail\">{{ option.detail }}</span>\n }\n } @else {\n {{ option.label }}\n }\n </li>\n } @empty {\n <li class=\"kf-select__empty\">\n {{ searchQuery() ? 'Sin resultados' : 'Sin opciones disponibles' }}\n </li>\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}.kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);width:var(--kf-select-width-md);font-family:var(--kf-font-body)}:host(.kf-select--compact){width:max-content;max-width:160px}:host(.kf-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-select--width-full){width:100%}:host(.kf-select--compact) .kf-select__trigger{padding:6px var(--kf-space-sm);font-size:.85rem;gap:var(--kf-space-xs)}:host(.kf-select--compact) .kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);background:var(--kf-color-white);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-select__trigger:hover:not(:disabled){border-color:var(--kf-color-text-muted)}.kf-select__trigger:focus-visible{outline:none;border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-select__trigger--disabled{opacity:.5;cursor:not-allowed}.kf-select__trigger--invalid{border-color:var(--kf-color-error)}.kf-select__trigger--invalid:focus-visible{border-color:var(--kf-color-error);box-shadow:var(--kf-shadow-focus-error)}.kf-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__icon{flex:none;color:var(--kf-color-text-muted)}.kf-select__trigger--with-icon .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}:host(.kf-select--compact) .kf-select__trigger--with-icon .kf-select__value{color:var(--kf-color-ink);font-weight:600}.kf-select__trigger--tagged .kf-select__value{flex:1 1 auto;min-width:0;text-align:start}.kf-select__tag{flex:none}.kf-select__trigger .kf-select__tag{margin-block:-2px}.kf-select__prefix{flex:none;color:var(--kf-color-text-muted);white-space:nowrap}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__panel{box-sizing:border-box;font-family:var(--kf-font-body);width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-select__panel-title{padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-xs)}.kf-select__panel--compact .kf-select__panel-title{padding:var(--kf-space-xs) var(--kf-space-sm) 2px}.kf-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-select__list::-webkit-scrollbar{width:6px}.kf-select__list::-webkit-scrollbar-track{background:transparent}.kf-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-select__option{padding:var(--kf-space-sm) var(--kf-space-md);outline:none;color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-select__option--rich{display:flex;flex-direction:column;gap:2px}.kf-select__option-main{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-select__option-label,.kf-select__option-detail{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.kf-select__option-detail{font-size:var(--kf-font-size-body-sm);font-weight:400;color:var(--kf-color-text-muted)}.kf-select__panel--compact .kf-select__option{padding:6px var(--kf-space-sm);font-size:.85rem}.kf-select__option:hover{background:var(--kf-color-primary-soft)}.kf-select__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select__option--active{background:var(--kf-color-primary-soft)}.kf-select__option:focus-visible{background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"] }]
3344
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hideLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideLabel", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchThreshold", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], panelTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelTitle", required: false }] }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panelTemplate: [{ type: i0.ViewChild, args: ['panelTemplate', { isSignal: true }] }], searchInputRef: [{ type: i0.ViewChild, args: ['searchInput', { isSignal: true }] }], panelRef: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }] } });
3053
3345
 
3054
3346
  const SIBLINGS = 1;
3055
3347
  /**
@@ -3123,7 +3415,7 @@ class Pagination {
3123
3415
  this.pageChange.emit(clamped);
3124
3416
  }
3125
3417
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Pagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
3126
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Pagination, isStandalone: true, selector: "kf-pagination", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pages: { classPropertyName: "pages", publicName: "pages", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", pageSize: "pageSizeChange" }, ngImport: i0, template: "<div class=\"kf-pagination\">\n <div class=\"kf-pagination__info kf-caption-text\" aria-live=\"polite\">\n <ng-content />\n </div>\n\n <div class=\"kf-pagination__controls\">\n @if (pageSizeOptions().length > 0) {\n <div class=\"kf-pagination__size\">\n <span class=\"kf-pagination__size-label kf-caption-text\">Filas</span>\n <kf-select\n variant=\"compact\"\n ariaLabel=\"Filas por p\u00E1gina\"\n [options]=\"pageSizeSelectOptions()\"\n [value]=\"pageSizeValue()\"\n (valueChange)=\"setPageSize($event)\"\n />\n </div>\n @if (hasNav()) {\n <div class=\"kf-pagination__divider\" aria-hidden=\"true\"></div>\n }\n }\n\n @if (hasNav()) {\n <nav class=\"kf-pagination__nav\" aria-label=\"Paginaci\u00F3n\">\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() <= 1\"\n aria-label=\"P\u00E1gina anterior\"\n (click)=\"goTo(page() - 1)\"\n >\n \u2039\n </button>\n\n @for (item of items(); track $index) {\n @if (item.type === 'page') {\n <button\n type=\"button\"\n class=\"kf-pagination__page\"\n [class.kf-pagination__page--active]=\"item.page === page()\"\n [attr.aria-current]=\"item.page === page() ? 'page' : null\"\n [attr.aria-label]=\"'Ir a la p\u00E1gina ' + item.page\"\n (click)=\"goTo(item.page)\"\n >\n {{ item.page }}\n </button>\n } @else {\n <span class=\"kf-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>\n }\n }\n\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() >= pages()\"\n aria-label=\"P\u00E1gina siguiente\"\n (click)=\"goTo(page() + 1)\"\n >\n \u203A\n </button>\n </nav>\n }\n </div>\n</div>\n", styles: [".kf-caption-text{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}:host{display:block;font-family:var(--kf-font-body)}.kf-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);flex-wrap:wrap}.kf-pagination__info:empty{display:none}.kf-pagination__controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--kf-space-sm) var(--kf-space-md)}.kf-pagination__size{display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-pagination__size-label{white-space:nowrap}.kf-pagination__divider{width:1px;height:1.25rem;background:var(--kf-color-border)}.kf-pagination__nav{display:flex;align-items:center;gap:var(--kf-space-xs)}.kf-pagination__control,.kf-pagination__page{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 var(--kf-space-xs);font:inherit;font-size:.85rem;color:var(--kf-color-text);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);cursor:pointer;transition:background .14s,border-color .14s,color .14s}.kf-pagination__control:hover:not(:disabled),.kf-pagination__page:hover:not(.kf-pagination__page--active){background:var(--kf-color-surface);border-color:var(--kf-color-border-strong)}.kf-pagination__control:focus-visible,.kf-pagination__page:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-pagination__control:disabled{opacity:.5;cursor:not-allowed}.kf-pagination__page--active{color:var(--kf-color-white);background:var(--kf-color-primary);border-color:var(--kf-color-primary);cursor:default}.kf-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--kf-color-text-muted)}@media(max-width:480px){.kf-pagination__controls{width:100%}.kf-pagination__divider{display:none}}\n"], dependencies: [{ kind: "component", type: Select, selector: "kf-select", inputs: ["label", "options", "value", "placeholder", "disabled", "invalid", "errorMessage", "variant", "width", "searchable", "searchThreshold", "ariaLabel", "icon", "panelTitle", "panelWidth"], outputs: ["valueChange"] }] });
3418
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Pagination, isStandalone: true, selector: "kf-pagination", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pages: { classPropertyName: "pages", publicName: "pages", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", pageSize: "pageSizeChange" }, ngImport: i0, template: "<div class=\"kf-pagination\">\n <div class=\"kf-pagination__info kf-caption-text\" aria-live=\"polite\">\n <ng-content />\n </div>\n\n <div class=\"kf-pagination__controls\">\n @if (pageSizeOptions().length > 0) {\n <div class=\"kf-pagination__size\">\n <span class=\"kf-pagination__size-label kf-caption-text\">Filas</span>\n <kf-select\n variant=\"compact\"\n ariaLabel=\"Filas por p\u00E1gina\"\n [options]=\"pageSizeSelectOptions()\"\n [value]=\"pageSizeValue()\"\n (valueChange)=\"setPageSize($event)\"\n />\n </div>\n @if (hasNav()) {\n <div class=\"kf-pagination__divider\" aria-hidden=\"true\"></div>\n }\n }\n\n @if (hasNav()) {\n <nav class=\"kf-pagination__nav\" aria-label=\"Paginaci\u00F3n\">\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() <= 1\"\n aria-label=\"P\u00E1gina anterior\"\n (click)=\"goTo(page() - 1)\"\n >\n \u2039\n </button>\n\n @for (item of items(); track $index) {\n @if (item.type === 'page') {\n <button\n type=\"button\"\n class=\"kf-pagination__page\"\n [class.kf-pagination__page--active]=\"item.page === page()\"\n [attr.aria-current]=\"item.page === page() ? 'page' : null\"\n [attr.aria-label]=\"'Ir a la p\u00E1gina ' + item.page\"\n (click)=\"goTo(item.page)\"\n >\n {{ item.page }}\n </button>\n } @else {\n <span class=\"kf-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>\n }\n }\n\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() >= pages()\"\n aria-label=\"P\u00E1gina siguiente\"\n (click)=\"goTo(page() + 1)\"\n >\n \u203A\n </button>\n </nav>\n }\n </div>\n</div>\n", styles: [".kf-caption-text{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}:host{display:block;font-family:var(--kf-font-body)}.kf-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);flex-wrap:wrap}.kf-pagination__info:empty{display:none}.kf-pagination__controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--kf-space-sm) var(--kf-space-md)}.kf-pagination__size{display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-pagination__size-label{white-space:nowrap}.kf-pagination__divider{width:1px;height:1.25rem;background:var(--kf-color-border)}.kf-pagination__nav{display:flex;align-items:center;gap:var(--kf-space-xs)}.kf-pagination__control,.kf-pagination__page{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 var(--kf-space-xs);font:inherit;font-size:.85rem;color:var(--kf-color-text);background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);cursor:pointer;transition:background .14s,border-color .14s,color .14s}.kf-pagination__control:hover:not(:disabled),.kf-pagination__page:hover:not(.kf-pagination__page--active){background:var(--kf-color-surface);border-color:var(--kf-color-border-strong)}.kf-pagination__control:focus-visible,.kf-pagination__page:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-pagination__control:disabled{opacity:.5;cursor:not-allowed}.kf-pagination__page--active{color:var(--kf-color-white);background:var(--kf-color-primary);border-color:var(--kf-color-primary);cursor:default}.kf-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--kf-color-text-muted)}@media(max-width:480px){.kf-pagination__controls{width:100%}.kf-pagination__divider{display:none}}\n"], dependencies: [{ kind: "component", type: Select, selector: "kf-select", inputs: ["label", "hideLabel", "prefix", "options", "value", "placeholder", "disabled", "invalid", "errorMessage", "variant", "width", "searchable", "searchThreshold", "ariaLabel", "icon", "panelTitle", "panelWidth"], outputs: ["valueChange"] }] });
3127
3419
  }
3128
3420
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Pagination, decorators: [{
3129
3421
  type: Component,
@@ -3312,7 +3604,8 @@ const DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50];
3312
3604
  * el selector, y `pageSizeChange` avisa cuando el usuario lo cambia.
3313
3605
  *
3314
3606
  * Ordenamiento por columna: cada `DataTableColumn` con `sortable: true`
3315
- * vuelve su header clickeable, con el mismo formato `key:direction` que
3607
+ * vuelve su header un botón (Tab, Enter y Espacio) que expone el estado con
3608
+ * `aria-sort` (`ascending`/`descending`/`none`), con el mismo formato `key:direction` que
3316
3609
  * usa `sort` de `kf-quote-picker` (two-way manual, no `model()` — el
3317
3610
  * consumidor decide si persiste el valor o lo descarta al desmontar):
3318
3611
  *
@@ -3544,6 +3837,17 @@ class DataTable {
3544
3837
  * ver `rowInteractive` para el cálculo automático cuando no se define. */
3545
3838
  rowClickable = input(null, /* @ts-ignore */
3546
3839
  ...(ngDevMode ? [{ debugName: "rowClickable" }] : /* istanbul ignore next */ []));
3840
+ /**
3841
+ * Con `false`, las filas interactivas de la vista de tabla dejan de ser
3842
+ * paradas de Tab (sin `tabindex`): útil cuando la fila es clickeable con el
3843
+ * mouse pero la acción accesible por teclado es un enlace o botón real
3844
+ * dentro de una celda — así una página de N filas no suma N paradas de Tab
3845
+ * sin rol. El clic con mouse sigue emitiendo `rowClick`. Default `true`
3846
+ * (comportamiento histórico). No afecta a las tarjetas, que son
3847
+ * `role="button"`.
3848
+ */
3849
+ rowFocusable = input(true, /* @ts-ignore */
3850
+ ...(ngDevMode ? [{ debugName: "rowFocusable" }] : /* istanbul ignore next */ []));
3547
3851
  rowClick = output();
3548
3852
  /**
3549
3853
  * Se emite al activar (clic, Enter o Espacio) una celda de una columna
@@ -3724,6 +4028,11 @@ class DataTable {
3724
4028
  const [key, direction] = sortValue.split(':');
3725
4029
  return key === column.key ? direction : null;
3726
4030
  }
4031
+ /** Valor de `aria-sort` del header de una columna ordenable. */
4032
+ ariaSortFor(column) {
4033
+ const direction = this.sortDirectionFor(column);
4034
+ return direction === 'asc' ? 'ascending' : direction === 'desc' ? 'descending' : 'none';
4035
+ }
3727
4036
  /** Ciclo asc → desc → sin orden, disparado al clickear un header `sortable`. */
3728
4037
  toggleSort(column) {
3729
4038
  if (!column.sortable) {
@@ -3885,6 +4194,14 @@ class DataTable {
3885
4194
  */
3886
4195
  rowInteractive = computed(() => this.rowClickable() ?? this.cardActionColumns().length === 0, /* @ts-ignore */
3887
4196
  ...(ngDevMode ? [{ debugName: "rowInteractive" }] : /* istanbul ignore next */ []));
4197
+ /**
4198
+ * La fila de la vista de tabla es parada de Tab solo si es interactiva,
4199
+ * `rowFocusable` lo permite y NO hay columnas `interactive`: con botones
4200
+ * propios por celda, la fila además de ellos duplicaría las paradas de Tab
4201
+ * (el clic de la fila sigue emitiendo `rowClick` con el mouse).
4202
+ */
4203
+ rowTabStop = computed(() => this.rowInteractive() && this.rowFocusable() && !this.hasInteractiveColumns(), /* @ts-ignore */
4204
+ ...(ngDevMode ? [{ debugName: "rowTabStop" }] : /* istanbul ignore next */ []));
3888
4205
  setView(next) {
3889
4206
  this.view.set(next);
3890
4207
  }
@@ -3987,12 +4304,12 @@ class DataTable {
3987
4304
  this.stickyOffsets.set(offsets);
3988
4305
  }
3989
4306
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DataTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
3990
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DataTable, isStandalone: true, selector: "kf-data-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, skeletonRows: { classPropertyName: "skeletonRows", publicName: "skeletonRows", isSignal: true, isRequired: false, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, flush: { classPropertyName: "flush", publicName: "flush", isSignal: true, isRequired: false, transformFunction: null }, cardable: { classPropertyName: "cardable", publicName: "cardable", isSignal: true, isRequired: false, transformFunction: null }, defaultView: { classPropertyName: "defaultView", publicName: "defaultView", isSignal: true, isRequired: false, transformFunction: null }, showViewToggle: { classPropertyName: "showViewToggle", publicName: "showViewToggle", isSignal: true, isRequired: false, transformFunction: null }, cardMinWidth: { classPropertyName: "cardMinWidth", publicName: "cardMinWidth", isSignal: true, isRequired: false, transformFunction: null }, render: { classPropertyName: "render", publicName: "render", isSignal: true, isRequired: false, transformFunction: null }, cellTemplates: { classPropertyName: "cellTemplates", publicName: "cellTemplates", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, rowClickable: { classPropertyName: "rowClickable", publicName: "rowClickable", isSignal: true, isRequired: false, transformFunction: null }, cellAriaLabel: { classPropertyName: "cellAriaLabel", publicName: "cellAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, currentRowKey: { classPropertyName: "currentRowKey", publicName: "currentRowKey", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, keepPageOnRowsChange: { classPropertyName: "keepPageOnRowsChange", publicName: "keepPageOnRowsChange", isSignal: true, isRequired: false, transformFunction: null }, itemLabel: { classPropertyName: "itemLabel", publicName: "itemLabel", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowClick: "rowClick", cellClick: "cellClick", page: "pageChange", pageSizeChange: "pageSizeChange", sortChange: "sortChange", view: "viewChange" }, viewQueries: [{ propertyName: "scrollEl", first: true, predicate: ["scroll"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"kf-data-table\"\n [class.kf-data-table--flush]=\"flush()\"\n [class.kf-data-table--compact]=\"density() === 'compact'\"\n>\n @if (cardable() && showViewToggle()) {\n <div class=\"kf-data-table__toolbar\">\n <kf-view-toggle [view]=\"activeView()\" (viewChange)=\"setView($event)\" />\n </div>\n }\n\n @if (loading()) {\n @if (cardable() && activeView() === 'cards') {\n <div\n class=\"kf-data-table__cards\"\n aria-busy=\"true\"\n [style.--kf-data-table-card-min]=\"cardMinWidth()\"\n >\n @for (i of skeletonRowIndexes(); track i) {\n <div class=\"kf-data-table__card\" aria-hidden=\"true\">\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn()) {\n <div class=\"kf-data-table__card-media\">\n <span class=\"kf-data-table__sk-media kf-bone-fill\"></span>\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n <span\n class=\"kf-data-table__card-title kf-bone\"\n [class.kf-data-table__card-title--mono]=\"cardTitleColumn()?.mono\"\n style=\"--kf-bone-width: 8rem\"\n >COT-2026-0000</span\n >\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n <span class=\"kf-data-table__sk-pill kf-bone-fill\"></span>\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n >\n <span class=\"kf-data-table__sk-lead kf-bone\" style=\"--kf-bone-width: 90%\"\n >Texto</span\n >\n </div>\n }\n @for (column of cardFieldColumns(); track column.key; let first = $first) {\n <div class=\"kf-data-table__card-field\">\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >{{ column.label }}</span\n >\n @if (first && !skeletonCardHeader()) {\n <kf-skeleton class=\"kf-data-table__sk-value\" width=\"100%\" />\n } @else {\n <span class=\"kf-data-table__sk-value kf-bone\" style=\"--kf-bone-width: 40%\"\n >Valor</span\n >\n }\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 4rem\"\n >{{ column.label }}</span\n >\n <span\n class=\"kf-data-table__card-meta-value kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >Valor</span\n >\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n <span class=\"kf-data-table__sk-action kf-bone-fill\"></span>\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n aria-busy=\"true\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (i of skeletonRowIndexes(); track i) {\n <tr class=\"kf-data-table__row\">\n @for (column of columns(); track column.key; let c = $index) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n <div\n class=\"kf-data-table__sk-cell\"\n [class.kf-data-table__sk-cell--end]=\"isEndAligned(column)\"\n [class.kf-data-table__sk-cell--center]=\"column.align === 'center'\"\n >\n <kf-skeleton\n class=\"kf-data-table__sk-bar\"\n [style.width]=\"skeletonBarWidth(column, i, c)\"\n />\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n } @else if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (activeView() === 'table') {\n <div\n #scroll\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--fade-left]=\"canScrollLeft()\"\n [class.kf-data-table__scroll--fade-right]=\"canScrollRight()\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n [attr.tabindex]=\"hasOverflow() ? 0 : null\"\n [attr.role]=\"hasOverflow() ? 'region' : null\"\n [attr.aria-label]=\"hasOverflow() ? ariaLabel() : null\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--sortable]=\"column.sortable\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [class.kf-data-table__cell--sort-active]=\"sortDirectionFor(column) !== null\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n (click)=\"toggleSort(column)\"\n >\n <span class=\"kf-data-table__th-content\">\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n @if (column.sortable) {\n <kf-icon\n name=\"chevron-down\"\n size=\"sm\"\n [rotate]=\"sortDirectionFor(column) === 'asc' ? 180 : 0\"\n class=\"kf-data-table__sort-icon\"\n [class.kf-data-table__sort-icon--active]=\"sortDirectionFor(column) !== null\"\n />\n }\n </span>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n [class.kf-data-table__row--interactive]=\"rowInteractive()\"\n [class.kf-data-table__row--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.tabindex]=\"rowInteractive() ? 0 : null\"\n (click)=\"onRowClick(row, i, $event)\"\n (keydown.enter)=\"onRowClick(row, i, $event)\"\n (keydown.space)=\"onRowSpace($event, row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--mono]=\"column.mono\"\n [class.kf-data-table__cell--emphasis]=\"column.emphasis\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.truncate) {\n <span class=\"kf-data-table__truncate\" [attr.title]=\"truncateTitle(row, column)\">\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\" [style.--kf-data-table-card-min]=\"cardMinWidth()\">\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [class.kf-data-table__card--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.enter)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.space)=\"cardInteractive() ? onRowSpace($event, row, i) : undefined\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: media }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span\n class=\"kf-data-table__card-title\"\n [class.kf-data-table__card-title--mono]=\"title.mono\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: title, index: i }\"\n />\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n [attr.title]=\"cellValue(row, column) || null\"\n >\n <span class=\"kf-data-table__sr-only\">{{ column.label }}: </span>\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </div>\n }\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span\n class=\"kf-data-table__card-value\"\n [class.kf-data-table__card-value--emphasis]=\"column.emphasis\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-meta-value\">\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (!loading() && rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n @if (effectivePageSize()) {\n <kf-pagination\n [page]=\"page()\"\n [pages]=\"totalPages()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [pageSize]=\"effectivePageSize()\"\n (pageChange)=\"goToPage($event)\"\n (pageSizeChange)=\"setPageSize($event)\"\n >\n {{ paginationSummary() }}\n </kf-pagination>\n }\n <ng-content select=\"[footer]\" />\n </div>\n }\n</div>\n\n<!-- Celda de la vista tabla \u2014 compartida por la celda normal y la `truncate`.\n Una columna `interactive` envuelve su contenido en un bot\u00F3n real. -->\n<ng-template #tableCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una celda de la vista tabla (template del consumidor,\n thumbnail o texto). -->\n<ng-template #tableCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n\n<!-- Zona de la tarjeta: igual que la celda de tabla, con bot\u00F3n si la columna es `interactive`. -->\n<ng-template #cardCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una zona de la tarjeta: template del consumidor o el valor como texto. -->\n<ng-template #cardCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block;font-family:var(--kf-font-body)}.kf-data-table{background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-sm);overflow:hidden}.kf-data-table--flush{border:none;box-shadow:none;border-radius:0}.kf-data-table__toolbar{display:flex;justify-content:flex-end;padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border)}.kf-data-table__scroll{position:relative;overflow-x:auto}.kf-data-table__scroll--weighted{container-type:inline-size}.kf-data-table__scroll:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__scroll:before,.kf-data-table__scroll:after{content:\"\";position:absolute;top:0;bottom:0;width:24px;pointer-events:none;opacity:0;transition:opacity .14s}.kf-data-table__scroll:before{left:0;background:linear-gradient(to right,var(--kf-color-white),transparent)}.kf-data-table__scroll:after{right:0;background:linear-gradient(to left,var(--kf-color-white),transparent)}.kf-data-table__scroll--fade-left:before{opacity:1}.kf-data-table__scroll--fade-right:after{opacity:1}.kf-data-table__table{width:100%;border-collapse:collapse;text-align:left}.kf-data-table__table th,.kf-data-table__table td{padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border);white-space:nowrap}.kf-data-table--compact .kf-data-table__table th,.kf-data-table--compact .kf-data-table__table td{padding:var(--kf-space-xs) var(--kf-space-md)}.kf-data-table__table th{background:var(--kf-color-surface)}.kf-data-table__table td{color:var(--kf-color-text)}.kf-data-table__table tbody tr:last-child td{border-bottom:none}.kf-data-table__row{transition:background .14s}.kf-data-table__row--interactive{cursor:pointer}.kf-data-table__row--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__row--interactive:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__row--current{background:var(--kf-color-primary-soft)}.kf-data-table__cell--right{text-align:right}.kf-data-table__cell--center{text-align:center}.kf-data-table__table .kf-data-table__cell--truncate{max-width:0}.kf-data-table__truncate{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-data-table__table td.kf-data-table__cell--mono{font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm)}.kf-data-table__table td.kf-data-table__cell--emphasis{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.kf-data-table__cell-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);max-width:100%;min-width:32px;min-height:32px;padding:var(--kf-space-xs);border:0;border-radius:var(--kf-radius-xs);background:transparent;color:inherit;font:inherit;text-align:inherit;cursor:pointer}.kf-data-table__cell-button:hover{box-shadow:inset 0 0 0 1px var(--kf-color-border-strong)}.kf-data-table__cell-button:focus-visible{outline:2px solid transparent;outline-offset:-2px;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}@media(max-width:640px),(pointer:coarse){.kf-data-table__cell-button{min-width:44px;min-height:44px}}.kf-data-table__cell--sticky{background:var(--kf-color-white)}.kf-data-table__table th.kf-data-table__cell--sticky{background:var(--kf-color-surface);z-index:2}.kf-data-table__cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.kf-data-table__cell--sortable:hover{color:var(--kf-color-ink)}.kf-data-table__table th.kf-data-table__cell--sort-active{color:var(--kf-color-primary);font-weight:700}.kf-data-table__th-content{display:inline-flex;align-items:center;gap:var(--kf-space-xs)}.kf-data-table__sort-icon{transition:opacity .14s}.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon{opacity:.5}.kf-data-table__sort-icon--active,.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon--active{opacity:1}.kf-data-table__empty{padding:var(--kf-space-md)}.kf-data-table__footer{padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__footer:empty{display:none}.kf-data-table__cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--kf-data-table-card-min, 220px),100%),1fr));grid-auto-rows:1fr;gap:var(--kf-space-md);padding:var(--kf-space-md)}.kf-data-table__card{position:relative;display:flex;flex-direction:column;min-width:0;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);overflow:hidden;transition:border-color .14s,box-shadow .14s,background .14s}.kf-data-table__card--interactive{cursor:pointer}.kf-data-table__card:hover{border-color:var(--kf-color-border-strong);box-shadow:var(--kf-shadow-xs)}.kf-data-table__card--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__card--interactive:focus-visible{outline:2px solid transparent;outline-offset:2px;box-shadow:0 0 0 2px var(--kf-color-primary)}.kf-data-table__card--current{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft)}.kf-data-table__card-header{display:flex;align-items:center;gap:var(--kf-space-sm);min-width:0;padding:var(--kf-space-md) var(--kf-space-md) var(--kf-space-sm)}.kf-data-table__card-media{flex:none}.kf-data-table__card-media img,.kf-data-table__thumb{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs);object-fit:cover;background:var(--kf-color-surface)}.kf-data-table__card-heading{display:flex;flex:1;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-title{flex:0 1 auto;min-width:0;font-family:var(--kf-font-title);font-weight:600;color:var(--kf-color-ink);overflow-wrap:anywhere}.kf-data-table__card-title--mono{flex:none;font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm);white-space:nowrap}.kf-data-table__card-statuses{display:flex;flex:0 1 auto;flex-wrap:nowrap;justify-content:flex-end;gap:var(--kf-space-xs);min-width:0;overflow:hidden}.kf-data-table__card-actions{display:flex;flex-wrap:wrap;gap:var(--kf-space-xs)}.kf-data-table__card-fields{display:flex;flex-direction:column;gap:var(--kf-space-xs);min-width:0;padding:var(--kf-space-md)}.kf-data-table__card-header+.kf-data-table__card-fields{padding-top:0}.kf-data-table__card-lead{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--kf-data-table-card-clamp, 2);line-clamp:var(--kf-data-table-card-clamp, 2);min-width:0;overflow:hidden;overflow-wrap:anywhere;color:var(--kf-color-ink);font-weight:500;line-height:1.35}.kf-data-table__card-field{display:flex;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-label{flex:none}.kf-data-table__card-value{min-width:0;color:var(--kf-color-text);text-align:right;overflow-wrap:anywhere}.kf-data-table__card-value--emphasis,.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__card-meta{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--kf-space-xs) var(--kf-space-md);margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__card-meta-item{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-data-table__card-meta-item--end{margin-left:auto;align-items:flex-end;text-align:right}.kf-data-table__card-meta-value{color:var(--kf-color-text);font-variant-numeric:tabular-nums}.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-size:var(--kf-font-size-body)}.kf-data-table__card-actions{justify-content:flex-end;margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border);background:var(--kf-color-surface)}.kf-data-table__card-meta~.kf-data-table__card-actions{margin-top:0}.kf-data-table__thumb{width:32px;height:32px}@media(prefers-reduced-motion:reduce){.kf-data-table__card,.kf-data-table__row{transition:none}}.kf-data-table__sk-cell{display:flex;align-items:center;justify-content:flex-start;min-height:1lh}.kf-data-table__sk-cell--center{justify-content:center}.kf-data-table__sk-cell--end{justify-content:flex-end}.kf-data-table__sk-bar{flex:none}.kf-data-table__sk-media{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs)}.kf-data-table__sk-pill{display:block;width:4.5rem;height:1.25rem;border-radius:var(--kf-radius-pill)}.kf-data-table__sk-value{flex:none;width:40%}.kf-data-table__sk-lead{line-height:1.35}.kf-data-table__sk-action{display:block;width:5rem;height:2rem;border-radius:var(--kf-radius-sm)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Pagination, selector: "kf-pagination", inputs: ["page", "pages", "pageSizeOptions", "pageSize"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "component", type: Skeleton, selector: "kf-skeleton", inputs: ["variant", "width", "height"] }, { kind: "component", type: ViewToggle, selector: "kf-view-toggle", inputs: ["view", "iconOnly", "tableLabel", "cardsLabel", "ariaLabel"], outputs: ["viewChange"] }] });
4307
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DataTable, isStandalone: true, selector: "kf-data-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, skeletonRows: { classPropertyName: "skeletonRows", publicName: "skeletonRows", isSignal: true, isRequired: false, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, flush: { classPropertyName: "flush", publicName: "flush", isSignal: true, isRequired: false, transformFunction: null }, cardable: { classPropertyName: "cardable", publicName: "cardable", isSignal: true, isRequired: false, transformFunction: null }, defaultView: { classPropertyName: "defaultView", publicName: "defaultView", isSignal: true, isRequired: false, transformFunction: null }, showViewToggle: { classPropertyName: "showViewToggle", publicName: "showViewToggle", isSignal: true, isRequired: false, transformFunction: null }, cardMinWidth: { classPropertyName: "cardMinWidth", publicName: "cardMinWidth", isSignal: true, isRequired: false, transformFunction: null }, render: { classPropertyName: "render", publicName: "render", isSignal: true, isRequired: false, transformFunction: null }, cellTemplates: { classPropertyName: "cellTemplates", publicName: "cellTemplates", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, rowClickable: { classPropertyName: "rowClickable", publicName: "rowClickable", isSignal: true, isRequired: false, transformFunction: null }, rowFocusable: { classPropertyName: "rowFocusable", publicName: "rowFocusable", isSignal: true, isRequired: false, transformFunction: null }, cellAriaLabel: { classPropertyName: "cellAriaLabel", publicName: "cellAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, currentRowKey: { classPropertyName: "currentRowKey", publicName: "currentRowKey", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, keepPageOnRowsChange: { classPropertyName: "keepPageOnRowsChange", publicName: "keepPageOnRowsChange", isSignal: true, isRequired: false, transformFunction: null }, itemLabel: { classPropertyName: "itemLabel", publicName: "itemLabel", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowClick: "rowClick", cellClick: "cellClick", page: "pageChange", pageSizeChange: "pageSizeChange", sortChange: "sortChange", view: "viewChange" }, viewQueries: [{ propertyName: "scrollEl", first: true, predicate: ["scroll"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"kf-data-table\"\n [class.kf-data-table--flush]=\"flush()\"\n [class.kf-data-table--compact]=\"density() === 'compact'\"\n>\n @if (cardable() && showViewToggle()) {\n <div class=\"kf-data-table__toolbar\">\n <kf-view-toggle [view]=\"activeView()\" (viewChange)=\"setView($event)\" />\n </div>\n }\n\n @if (loading()) {\n @if (cardable() && activeView() === 'cards') {\n <div\n class=\"kf-data-table__cards\"\n aria-busy=\"true\"\n [style.--kf-data-table-card-min]=\"cardMinWidth()\"\n >\n @for (i of skeletonRowIndexes(); track i) {\n <div class=\"kf-data-table__card\" aria-hidden=\"true\">\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn()) {\n <div class=\"kf-data-table__card-media\">\n <span class=\"kf-data-table__sk-media kf-bone-fill\"></span>\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n <span\n class=\"kf-data-table__card-title kf-bone\"\n [class.kf-data-table__card-title--mono]=\"cardTitleColumn()?.mono\"\n style=\"--kf-bone-width: 8rem\"\n >COT-2026-0000</span\n >\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n <span class=\"kf-data-table__sk-pill kf-bone-fill\"></span>\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n >\n <span class=\"kf-data-table__sk-lead kf-bone\" style=\"--kf-bone-width: 90%\"\n >Texto</span\n >\n </div>\n }\n @for (column of cardFieldColumns(); track column.key; let first = $first) {\n <div class=\"kf-data-table__card-field\">\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >{{ column.label }}</span\n >\n @if (first && !skeletonCardHeader()) {\n <kf-skeleton class=\"kf-data-table__sk-value\" width=\"100%\" />\n } @else {\n <span class=\"kf-data-table__sk-value kf-bone\" style=\"--kf-bone-width: 40%\"\n >Valor</span\n >\n }\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 4rem\"\n >{{ column.label }}</span\n >\n <span\n class=\"kf-data-table__card-meta-value kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >Valor</span\n >\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n <span class=\"kf-data-table__sk-action kf-bone-fill\"></span>\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n aria-busy=\"true\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (i of skeletonRowIndexes(); track i) {\n <tr class=\"kf-data-table__row\">\n @for (column of columns(); track column.key; let c = $index) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n <div\n class=\"kf-data-table__sk-cell\"\n [class.kf-data-table__sk-cell--end]=\"isEndAligned(column)\"\n [class.kf-data-table__sk-cell--center]=\"column.align === 'center'\"\n >\n <kf-skeleton\n class=\"kf-data-table__sk-bar\"\n [style.width]=\"skeletonBarWidth(column, i, c)\"\n />\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n } @else if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (activeView() === 'table') {\n <div\n #scroll\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--fade-left]=\"canScrollLeft()\"\n [class.kf-data-table__scroll--fade-right]=\"canScrollRight()\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n [attr.tabindex]=\"hasOverflow() ? 0 : null\"\n [attr.role]=\"hasOverflow() ? 'region' : null\"\n [attr.aria-label]=\"hasOverflow() ? ariaLabel() : null\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--sortable]=\"column.sortable\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [class.kf-data-table__cell--sort-active]=\"sortDirectionFor(column) !== null\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n [attr.aria-sort]=\"column.sortable ? ariaSortFor(column) : null\"\n (click)=\"toggleSort(column)\"\n >\n @if (column.sortable) {\n <!-- El clic del bot\u00F3n burbujea al `th`, que ya ordena: un solo manejador para mouse y teclado. -->\n <button type=\"button\" class=\"kf-data-table__sort-button\">\n <span class=\"kf-data-table__th-content\">\n <ng-container\n [ngTemplateOutlet]=\"headerLabel\"\n [ngTemplateOutletContext]=\"{ $implicit: column }\"\n />\n <kf-icon\n name=\"chevron-down\"\n size=\"sm\"\n [rotate]=\"sortDirectionFor(column) === 'asc' ? 180 : 0\"\n class=\"kf-data-table__sort-icon\"\n [class.kf-data-table__sort-icon--active]=\"sortDirectionFor(column) !== null\"\n />\n </span>\n </button>\n } @else {\n <span class=\"kf-data-table__th-content\">\n <ng-container\n [ngTemplateOutlet]=\"headerLabel\"\n [ngTemplateOutletContext]=\"{ $implicit: column }\"\n />\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n [class.kf-data-table__row--interactive]=\"rowInteractive()\"\n [class.kf-data-table__row--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.tabindex]=\"rowTabStop() ? 0 : null\"\n (click)=\"onRowClick(row, i, $event)\"\n (keydown.enter)=\"onRowClick(row, i, $event)\"\n (keydown.space)=\"onRowSpace($event, row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--mono]=\"column.mono\"\n [class.kf-data-table__cell--emphasis]=\"column.emphasis\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.truncate) {\n <span class=\"kf-data-table__truncate\" [attr.title]=\"truncateTitle(row, column)\">\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\" [style.--kf-data-table-card-min]=\"cardMinWidth()\">\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [class.kf-data-table__card--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.enter)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.space)=\"cardInteractive() ? onRowSpace($event, row, i) : undefined\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: media }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span\n class=\"kf-data-table__card-title\"\n [class.kf-data-table__card-title--mono]=\"title.mono\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: title, index: i }\"\n />\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n [attr.title]=\"cellValue(row, column) || null\"\n >\n <span class=\"kf-data-table__sr-only\">{{ column.label }}: </span>\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </div>\n }\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span\n class=\"kf-data-table__card-value\"\n [class.kf-data-table__card-value--emphasis]=\"column.emphasis\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-meta-value\">\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (!loading() && rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n @if (effectivePageSize()) {\n <kf-pagination\n [page]=\"page()\"\n [pages]=\"totalPages()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [pageSize]=\"effectivePageSize()\"\n (pageChange)=\"goToPage($event)\"\n (pageSizeChange)=\"setPageSize($event)\"\n >\n {{ paginationSummary() }}\n </kf-pagination>\n }\n <ng-content select=\"[footer]\" />\n </div>\n }\n</div>\n\n<!-- R\u00F3tulo de una columna: texto visible o solo para lectores con `hideLabel`. -->\n<ng-template #headerLabel let-column>\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n</ng-template>\n\n<!-- Celda de la vista tabla \u2014 compartida por la celda normal y la `truncate`.\n Una columna `interactive` envuelve su contenido en un bot\u00F3n real. -->\n<ng-template #tableCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una celda de la vista tabla (template del consumidor,\n thumbnail o texto). -->\n<ng-template #tableCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n\n<!-- Zona de la tarjeta: igual que la celda de tabla, con bot\u00F3n si la columna es `interactive`. -->\n<ng-template #cardCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una zona de la tarjeta: template del consumidor o el valor como texto. -->\n<ng-template #cardCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block;font-family:var(--kf-font-body)}.kf-data-table{background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-sm);overflow:hidden}.kf-data-table--flush{border:none;box-shadow:none;border-radius:0}.kf-data-table__toolbar{display:flex;justify-content:flex-end;padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border)}.kf-data-table__scroll{position:relative;overflow-x:auto}.kf-data-table__scroll--weighted{container-type:inline-size}.kf-data-table__scroll:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__scroll:before,.kf-data-table__scroll:after{content:\"\";position:absolute;top:0;bottom:0;width:24px;pointer-events:none;opacity:0;transition:opacity .14s}.kf-data-table__scroll:before{left:0;background:linear-gradient(to right,var(--kf-color-white),transparent)}.kf-data-table__scroll:after{right:0;background:linear-gradient(to left,var(--kf-color-white),transparent)}.kf-data-table__scroll--fade-left:before{opacity:1}.kf-data-table__scroll--fade-right:after{opacity:1}.kf-data-table__table{width:100%;border-collapse:collapse;text-align:left}.kf-data-table__table th,.kf-data-table__table td{padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border);white-space:nowrap}.kf-data-table--compact .kf-data-table__table th,.kf-data-table--compact .kf-data-table__table td{padding:var(--kf-space-xs) var(--kf-space-md)}.kf-data-table__table th{background:var(--kf-color-surface)}.kf-data-table__table td{color:var(--kf-color-text)}.kf-data-table__table tbody tr:last-child td{border-bottom:none}.kf-data-table__row{transition:background .14s}.kf-data-table__row--interactive{cursor:pointer}.kf-data-table__row--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__row--interactive:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__row--current{background:var(--kf-color-primary-soft)}.kf-data-table__cell--right{text-align:right}.kf-data-table__cell--center{text-align:center}.kf-data-table__table .kf-data-table__cell--truncate{max-width:0}.kf-data-table__truncate{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-data-table__table td.kf-data-table__cell--mono{font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm)}.kf-data-table__table td.kf-data-table__cell--emphasis{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.kf-data-table__cell-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);max-width:100%;min-width:32px;min-height:32px;padding:var(--kf-space-xs);border:0;border-radius:var(--kf-radius-xs);background:transparent;color:inherit;font:inherit;text-align:inherit;cursor:pointer}.kf-data-table__cell-button:hover{box-shadow:inset 0 0 0 1px var(--kf-color-border-strong)}.kf-data-table__cell-button:focus-visible{outline:2px solid transparent;outline-offset:-2px;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}@media(max-width:640px),(pointer:coarse){.kf-data-table__cell-button{min-width:44px;min-height:44px}}.kf-data-table__cell--sticky{background:var(--kf-color-white)}.kf-data-table__table th.kf-data-table__cell--sticky{background:var(--kf-color-surface);z-index:2}.kf-data-table__cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.kf-data-table__sort-button{display:inline-flex;align-items:center;margin:0;padding:0;font:inherit;letter-spacing:inherit;text-transform:inherit;color:inherit;text-align:inherit;background:none;border:none;border-radius:var(--kf-radius-xs);cursor:pointer}.kf-data-table__sort-button:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-data-table__cell--sortable:hover{color:var(--kf-color-ink)}.kf-data-table__table th.kf-data-table__cell--sort-active{color:var(--kf-color-primary);font-weight:700}.kf-data-table__th-content{display:inline-flex;align-items:center;gap:var(--kf-space-xs)}.kf-data-table__sort-icon{transition:opacity .14s}.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon{opacity:.5}.kf-data-table__sort-icon--active,.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon--active{opacity:1}.kf-data-table__empty{padding:var(--kf-space-md)}.kf-data-table__footer{padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__footer:empty{display:none}.kf-data-table__cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--kf-data-table-card-min, 220px),100%),1fr));grid-auto-rows:1fr;gap:var(--kf-space-md);padding:var(--kf-space-md)}.kf-data-table__card{position:relative;display:flex;flex-direction:column;min-width:0;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);overflow:hidden;transition:border-color .14s,box-shadow .14s,background .14s}.kf-data-table__card--interactive{cursor:pointer}.kf-data-table__card:hover{border-color:var(--kf-color-border-strong);box-shadow:var(--kf-shadow-xs)}.kf-data-table__card--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__card--interactive:focus-visible{outline:2px solid transparent;outline-offset:2px;box-shadow:var(--kf-shadow-focus)}.kf-data-table__card--current{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft)}.kf-data-table__card-header{display:flex;align-items:center;gap:var(--kf-space-sm);min-width:0;padding:var(--kf-space-md) var(--kf-space-md) var(--kf-space-sm)}.kf-data-table__card-media{flex:none}.kf-data-table__card-media img,.kf-data-table__thumb{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs);object-fit:cover;background:var(--kf-color-surface)}.kf-data-table__card-heading{display:flex;flex:1;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-title{flex:0 1 auto;min-width:0;font-family:var(--kf-font-title);font-weight:600;color:var(--kf-color-ink);overflow-wrap:anywhere}.kf-data-table__card-title--mono{flex:none;font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm);white-space:nowrap}.kf-data-table__card-statuses{display:flex;flex:0 1 auto;flex-wrap:nowrap;justify-content:flex-end;gap:var(--kf-space-xs);min-width:0;overflow:hidden}.kf-data-table__card-actions{display:flex;flex-wrap:wrap;gap:var(--kf-space-xs)}.kf-data-table__card-fields{display:flex;flex-direction:column;gap:var(--kf-space-xs);min-width:0;padding:var(--kf-space-md)}.kf-data-table__card-header+.kf-data-table__card-fields{padding-top:0}.kf-data-table__card-lead{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--kf-data-table-card-clamp, 2);line-clamp:var(--kf-data-table-card-clamp, 2);min-width:0;overflow:hidden;overflow-wrap:anywhere;color:var(--kf-color-ink);font-weight:500;line-height:1.35}.kf-data-table__card-field{display:flex;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-label{flex:none}.kf-data-table__card-value{min-width:0;color:var(--kf-color-text);text-align:right;overflow-wrap:anywhere}.kf-data-table__card-value--emphasis,.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__card-meta{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--kf-space-xs) var(--kf-space-md);margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__card-meta-item{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-data-table__card-meta-item--end{margin-left:auto;align-items:flex-end;text-align:right}.kf-data-table__card-meta-value{color:var(--kf-color-text);font-variant-numeric:tabular-nums}.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-size:var(--kf-font-size-body)}.kf-data-table__card-actions{justify-content:flex-end;margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border);background:var(--kf-color-surface)}.kf-data-table__card-meta~.kf-data-table__card-actions{margin-top:0}.kf-data-table__thumb{width:32px;height:32px}@media(prefers-reduced-motion:reduce){.kf-data-table__card,.kf-data-table__row{transition:none}}.kf-data-table__sk-cell{display:flex;align-items:center;justify-content:flex-start;min-height:1lh}.kf-data-table__sk-cell--center{justify-content:center}.kf-data-table__sk-cell--end{justify-content:flex-end}.kf-data-table__sk-bar{flex:none}.kf-data-table__sk-media{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs)}.kf-data-table__sk-pill{display:block;width:4.5rem;height:1.25rem;border-radius:var(--kf-radius-pill)}.kf-data-table__sk-value{flex:none;width:40%}.kf-data-table__sk-lead{line-height:1.35}.kf-data-table__sk-action{display:block;width:5rem;height:2rem;border-radius:var(--kf-radius-sm)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Pagination, selector: "kf-pagination", inputs: ["page", "pages", "pageSizeOptions", "pageSize"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "component", type: Skeleton, selector: "kf-skeleton", inputs: ["variant", "width", "height"] }, { kind: "component", type: ViewToggle, selector: "kf-view-toggle", inputs: ["view", "iconOnly", "tableLabel", "cardsLabel", "ariaLabel"], outputs: ["viewChange"] }] });
3991
4308
  }
3992
4309
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DataTable, decorators: [{
3993
4310
  type: Component,
3994
- args: [{ selector: 'kf-data-table', imports: [Icon, NgTemplateOutlet, Pagination, Skeleton, ViewToggle], template: "<div\n class=\"kf-data-table\"\n [class.kf-data-table--flush]=\"flush()\"\n [class.kf-data-table--compact]=\"density() === 'compact'\"\n>\n @if (cardable() && showViewToggle()) {\n <div class=\"kf-data-table__toolbar\">\n <kf-view-toggle [view]=\"activeView()\" (viewChange)=\"setView($event)\" />\n </div>\n }\n\n @if (loading()) {\n @if (cardable() && activeView() === 'cards') {\n <div\n class=\"kf-data-table__cards\"\n aria-busy=\"true\"\n [style.--kf-data-table-card-min]=\"cardMinWidth()\"\n >\n @for (i of skeletonRowIndexes(); track i) {\n <div class=\"kf-data-table__card\" aria-hidden=\"true\">\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn()) {\n <div class=\"kf-data-table__card-media\">\n <span class=\"kf-data-table__sk-media kf-bone-fill\"></span>\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n <span\n class=\"kf-data-table__card-title kf-bone\"\n [class.kf-data-table__card-title--mono]=\"cardTitleColumn()?.mono\"\n style=\"--kf-bone-width: 8rem\"\n >COT-2026-0000</span\n >\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n <span class=\"kf-data-table__sk-pill kf-bone-fill\"></span>\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n >\n <span class=\"kf-data-table__sk-lead kf-bone\" style=\"--kf-bone-width: 90%\"\n >Texto</span\n >\n </div>\n }\n @for (column of cardFieldColumns(); track column.key; let first = $first) {\n <div class=\"kf-data-table__card-field\">\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >{{ column.label }}</span\n >\n @if (first && !skeletonCardHeader()) {\n <kf-skeleton class=\"kf-data-table__sk-value\" width=\"100%\" />\n } @else {\n <span class=\"kf-data-table__sk-value kf-bone\" style=\"--kf-bone-width: 40%\"\n >Valor</span\n >\n }\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 4rem\"\n >{{ column.label }}</span\n >\n <span\n class=\"kf-data-table__card-meta-value kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >Valor</span\n >\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n <span class=\"kf-data-table__sk-action kf-bone-fill\"></span>\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n aria-busy=\"true\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (i of skeletonRowIndexes(); track i) {\n <tr class=\"kf-data-table__row\">\n @for (column of columns(); track column.key; let c = $index) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n <div\n class=\"kf-data-table__sk-cell\"\n [class.kf-data-table__sk-cell--end]=\"isEndAligned(column)\"\n [class.kf-data-table__sk-cell--center]=\"column.align === 'center'\"\n >\n <kf-skeleton\n class=\"kf-data-table__sk-bar\"\n [style.width]=\"skeletonBarWidth(column, i, c)\"\n />\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n } @else if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (activeView() === 'table') {\n <div\n #scroll\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--fade-left]=\"canScrollLeft()\"\n [class.kf-data-table__scroll--fade-right]=\"canScrollRight()\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n [attr.tabindex]=\"hasOverflow() ? 0 : null\"\n [attr.role]=\"hasOverflow() ? 'region' : null\"\n [attr.aria-label]=\"hasOverflow() ? ariaLabel() : null\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--sortable]=\"column.sortable\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [class.kf-data-table__cell--sort-active]=\"sortDirectionFor(column) !== null\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n (click)=\"toggleSort(column)\"\n >\n <span class=\"kf-data-table__th-content\">\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n @if (column.sortable) {\n <kf-icon\n name=\"chevron-down\"\n size=\"sm\"\n [rotate]=\"sortDirectionFor(column) === 'asc' ? 180 : 0\"\n class=\"kf-data-table__sort-icon\"\n [class.kf-data-table__sort-icon--active]=\"sortDirectionFor(column) !== null\"\n />\n }\n </span>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n [class.kf-data-table__row--interactive]=\"rowInteractive()\"\n [class.kf-data-table__row--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.tabindex]=\"rowInteractive() ? 0 : null\"\n (click)=\"onRowClick(row, i, $event)\"\n (keydown.enter)=\"onRowClick(row, i, $event)\"\n (keydown.space)=\"onRowSpace($event, row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--mono]=\"column.mono\"\n [class.kf-data-table__cell--emphasis]=\"column.emphasis\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.truncate) {\n <span class=\"kf-data-table__truncate\" [attr.title]=\"truncateTitle(row, column)\">\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\" [style.--kf-data-table-card-min]=\"cardMinWidth()\">\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [class.kf-data-table__card--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.enter)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.space)=\"cardInteractive() ? onRowSpace($event, row, i) : undefined\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: media }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span\n class=\"kf-data-table__card-title\"\n [class.kf-data-table__card-title--mono]=\"title.mono\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: title, index: i }\"\n />\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n [attr.title]=\"cellValue(row, column) || null\"\n >\n <span class=\"kf-data-table__sr-only\">{{ column.label }}: </span>\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </div>\n }\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span\n class=\"kf-data-table__card-value\"\n [class.kf-data-table__card-value--emphasis]=\"column.emphasis\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-meta-value\">\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (!loading() && rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n @if (effectivePageSize()) {\n <kf-pagination\n [page]=\"page()\"\n [pages]=\"totalPages()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [pageSize]=\"effectivePageSize()\"\n (pageChange)=\"goToPage($event)\"\n (pageSizeChange)=\"setPageSize($event)\"\n >\n {{ paginationSummary() }}\n </kf-pagination>\n }\n <ng-content select=\"[footer]\" />\n </div>\n }\n</div>\n\n<!-- Celda de la vista tabla \u2014 compartida por la celda normal y la `truncate`.\n Una columna `interactive` envuelve su contenido en un bot\u00F3n real. -->\n<ng-template #tableCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una celda de la vista tabla (template del consumidor,\n thumbnail o texto). -->\n<ng-template #tableCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n\n<!-- Zona de la tarjeta: igual que la celda de tabla, con bot\u00F3n si la columna es `interactive`. -->\n<ng-template #cardCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una zona de la tarjeta: template del consumidor o el valor como texto. -->\n<ng-template #cardCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block;font-family:var(--kf-font-body)}.kf-data-table{background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-sm);overflow:hidden}.kf-data-table--flush{border:none;box-shadow:none;border-radius:0}.kf-data-table__toolbar{display:flex;justify-content:flex-end;padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border)}.kf-data-table__scroll{position:relative;overflow-x:auto}.kf-data-table__scroll--weighted{container-type:inline-size}.kf-data-table__scroll:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__scroll:before,.kf-data-table__scroll:after{content:\"\";position:absolute;top:0;bottom:0;width:24px;pointer-events:none;opacity:0;transition:opacity .14s}.kf-data-table__scroll:before{left:0;background:linear-gradient(to right,var(--kf-color-white),transparent)}.kf-data-table__scroll:after{right:0;background:linear-gradient(to left,var(--kf-color-white),transparent)}.kf-data-table__scroll--fade-left:before{opacity:1}.kf-data-table__scroll--fade-right:after{opacity:1}.kf-data-table__table{width:100%;border-collapse:collapse;text-align:left}.kf-data-table__table th,.kf-data-table__table td{padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border);white-space:nowrap}.kf-data-table--compact .kf-data-table__table th,.kf-data-table--compact .kf-data-table__table td{padding:var(--kf-space-xs) var(--kf-space-md)}.kf-data-table__table th{background:var(--kf-color-surface)}.kf-data-table__table td{color:var(--kf-color-text)}.kf-data-table__table tbody tr:last-child td{border-bottom:none}.kf-data-table__row{transition:background .14s}.kf-data-table__row--interactive{cursor:pointer}.kf-data-table__row--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__row--interactive:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__row--current{background:var(--kf-color-primary-soft)}.kf-data-table__cell--right{text-align:right}.kf-data-table__cell--center{text-align:center}.kf-data-table__table .kf-data-table__cell--truncate{max-width:0}.kf-data-table__truncate{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-data-table__table td.kf-data-table__cell--mono{font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm)}.kf-data-table__table td.kf-data-table__cell--emphasis{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.kf-data-table__cell-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);max-width:100%;min-width:32px;min-height:32px;padding:var(--kf-space-xs);border:0;border-radius:var(--kf-radius-xs);background:transparent;color:inherit;font:inherit;text-align:inherit;cursor:pointer}.kf-data-table__cell-button:hover{box-shadow:inset 0 0 0 1px var(--kf-color-border-strong)}.kf-data-table__cell-button:focus-visible{outline:2px solid transparent;outline-offset:-2px;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}@media(max-width:640px),(pointer:coarse){.kf-data-table__cell-button{min-width:44px;min-height:44px}}.kf-data-table__cell--sticky{background:var(--kf-color-white)}.kf-data-table__table th.kf-data-table__cell--sticky{background:var(--kf-color-surface);z-index:2}.kf-data-table__cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.kf-data-table__cell--sortable:hover{color:var(--kf-color-ink)}.kf-data-table__table th.kf-data-table__cell--sort-active{color:var(--kf-color-primary);font-weight:700}.kf-data-table__th-content{display:inline-flex;align-items:center;gap:var(--kf-space-xs)}.kf-data-table__sort-icon{transition:opacity .14s}.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon{opacity:.5}.kf-data-table__sort-icon--active,.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon--active{opacity:1}.kf-data-table__empty{padding:var(--kf-space-md)}.kf-data-table__footer{padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__footer:empty{display:none}.kf-data-table__cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--kf-data-table-card-min, 220px),100%),1fr));grid-auto-rows:1fr;gap:var(--kf-space-md);padding:var(--kf-space-md)}.kf-data-table__card{position:relative;display:flex;flex-direction:column;min-width:0;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);overflow:hidden;transition:border-color .14s,box-shadow .14s,background .14s}.kf-data-table__card--interactive{cursor:pointer}.kf-data-table__card:hover{border-color:var(--kf-color-border-strong);box-shadow:var(--kf-shadow-xs)}.kf-data-table__card--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__card--interactive:focus-visible{outline:2px solid transparent;outline-offset:2px;box-shadow:0 0 0 2px var(--kf-color-primary)}.kf-data-table__card--current{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft)}.kf-data-table__card-header{display:flex;align-items:center;gap:var(--kf-space-sm);min-width:0;padding:var(--kf-space-md) var(--kf-space-md) var(--kf-space-sm)}.kf-data-table__card-media{flex:none}.kf-data-table__card-media img,.kf-data-table__thumb{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs);object-fit:cover;background:var(--kf-color-surface)}.kf-data-table__card-heading{display:flex;flex:1;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-title{flex:0 1 auto;min-width:0;font-family:var(--kf-font-title);font-weight:600;color:var(--kf-color-ink);overflow-wrap:anywhere}.kf-data-table__card-title--mono{flex:none;font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm);white-space:nowrap}.kf-data-table__card-statuses{display:flex;flex:0 1 auto;flex-wrap:nowrap;justify-content:flex-end;gap:var(--kf-space-xs);min-width:0;overflow:hidden}.kf-data-table__card-actions{display:flex;flex-wrap:wrap;gap:var(--kf-space-xs)}.kf-data-table__card-fields{display:flex;flex-direction:column;gap:var(--kf-space-xs);min-width:0;padding:var(--kf-space-md)}.kf-data-table__card-header+.kf-data-table__card-fields{padding-top:0}.kf-data-table__card-lead{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--kf-data-table-card-clamp, 2);line-clamp:var(--kf-data-table-card-clamp, 2);min-width:0;overflow:hidden;overflow-wrap:anywhere;color:var(--kf-color-ink);font-weight:500;line-height:1.35}.kf-data-table__card-field{display:flex;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-label{flex:none}.kf-data-table__card-value{min-width:0;color:var(--kf-color-text);text-align:right;overflow-wrap:anywhere}.kf-data-table__card-value--emphasis,.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__card-meta{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--kf-space-xs) var(--kf-space-md);margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__card-meta-item{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-data-table__card-meta-item--end{margin-left:auto;align-items:flex-end;text-align:right}.kf-data-table__card-meta-value{color:var(--kf-color-text);font-variant-numeric:tabular-nums}.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-size:var(--kf-font-size-body)}.kf-data-table__card-actions{justify-content:flex-end;margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border);background:var(--kf-color-surface)}.kf-data-table__card-meta~.kf-data-table__card-actions{margin-top:0}.kf-data-table__thumb{width:32px;height:32px}@media(prefers-reduced-motion:reduce){.kf-data-table__card,.kf-data-table__row{transition:none}}.kf-data-table__sk-cell{display:flex;align-items:center;justify-content:flex-start;min-height:1lh}.kf-data-table__sk-cell--center{justify-content:center}.kf-data-table__sk-cell--end{justify-content:flex-end}.kf-data-table__sk-bar{flex:none}.kf-data-table__sk-media{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs)}.kf-data-table__sk-pill{display:block;width:4.5rem;height:1.25rem;border-radius:var(--kf-radius-pill)}.kf-data-table__sk-value{flex:none;width:40%}.kf-data-table__sk-lead{line-height:1.35}.kf-data-table__sk-action{display:block;width:5rem;height:2rem;border-radius:var(--kf-radius-sm)}\n"] }]
3995
- }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], skeletonRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonRows", required: false }] }], scrollEl: [{ type: i0.ViewChild, args: ['scroll', { isSignal: true }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], flush: [{ type: i0.Input, args: [{ isSignal: true, alias: "flush", required: false }] }], cardable: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardable", required: false }] }], defaultView: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultView", required: false }] }], showViewToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showViewToggle", required: false }] }], cardMinWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardMinWidth", required: false }] }], render: [{ type: i0.Input, args: [{ isSignal: true, alias: "render", required: false }] }], cellTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellTemplates", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], rowClickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowClickable", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], cellAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellAriaLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], currentRowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentRowKey", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], keepPageOnRowsChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepPageOnRowsChange", required: false }] }], pageSizeChange: [{ type: i0.Output, args: ["pageSizeChange"] }], itemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemLabel", required: false }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }] } });
4311
+ args: [{ selector: 'kf-data-table', imports: [Icon, NgTemplateOutlet, Pagination, Skeleton, ViewToggle], template: "<div\n class=\"kf-data-table\"\n [class.kf-data-table--flush]=\"flush()\"\n [class.kf-data-table--compact]=\"density() === 'compact'\"\n>\n @if (cardable() && showViewToggle()) {\n <div class=\"kf-data-table__toolbar\">\n <kf-view-toggle [view]=\"activeView()\" (viewChange)=\"setView($event)\" />\n </div>\n }\n\n @if (loading()) {\n @if (cardable() && activeView() === 'cards') {\n <div\n class=\"kf-data-table__cards\"\n aria-busy=\"true\"\n [style.--kf-data-table-card-min]=\"cardMinWidth()\"\n >\n @for (i of skeletonRowIndexes(); track i) {\n <div class=\"kf-data-table__card\" aria-hidden=\"true\">\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn()) {\n <div class=\"kf-data-table__card-media\">\n <span class=\"kf-data-table__sk-media kf-bone-fill\"></span>\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n <span\n class=\"kf-data-table__card-title kf-bone\"\n [class.kf-data-table__card-title--mono]=\"cardTitleColumn()?.mono\"\n style=\"--kf-bone-width: 8rem\"\n >COT-2026-0000</span\n >\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n <span class=\"kf-data-table__sk-pill kf-bone-fill\"></span>\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n >\n <span class=\"kf-data-table__sk-lead kf-bone\" style=\"--kf-bone-width: 90%\"\n >Texto</span\n >\n </div>\n }\n @for (column of cardFieldColumns(); track column.key; let first = $first) {\n <div class=\"kf-data-table__card-field\">\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >{{ column.label }}</span\n >\n @if (first && !skeletonCardHeader()) {\n <kf-skeleton class=\"kf-data-table__sk-value\" width=\"100%\" />\n } @else {\n <span class=\"kf-data-table__sk-value kf-bone\" style=\"--kf-bone-width: 40%\"\n >Valor</span\n >\n }\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span\n class=\"kf-data-table__card-label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 4rem\"\n >{{ column.label }}</span\n >\n <span\n class=\"kf-data-table__card-meta-value kf-bone\"\n style=\"--kf-bone-width: 5rem\"\n >Valor</span\n >\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n <span class=\"kf-data-table__sk-action kf-bone-fill\"></span>\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n aria-busy=\"true\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (i of skeletonRowIndexes(); track i) {\n <tr class=\"kf-data-table__row\">\n @for (column of columns(); track column.key; let c = $index) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n <div\n class=\"kf-data-table__sk-cell\"\n [class.kf-data-table__sk-cell--end]=\"isEndAligned(column)\"\n [class.kf-data-table__sk-cell--center]=\"column.align === 'center'\"\n >\n <kf-skeleton\n class=\"kf-data-table__sk-bar\"\n [style.width]=\"skeletonBarWidth(column, i, c)\"\n />\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n } @else if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (activeView() === 'table') {\n <div\n #scroll\n class=\"kf-data-table__scroll\"\n [class.kf-data-table__scroll--fade-left]=\"canScrollLeft()\"\n [class.kf-data-table__scroll--fade-right]=\"canScrollRight()\"\n [class.kf-data-table__scroll--weighted]=\"weighted()\"\n [attr.tabindex]=\"hasOverflow() ? 0 : null\"\n [attr.role]=\"hasOverflow() ? 'region' : null\"\n [attr.aria-label]=\"hasOverflow() ? ariaLabel() : null\"\n >\n <table class=\"kf-data-table__table\" [class.kf-data-table__table--weighted]=\"weighted()\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th\n class=\"kf-overline-text\"\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--sortable]=\"column.sortable\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [class.kf-data-table__cell--sort-active]=\"sortDirectionFor(column) !== null\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n [attr.aria-sort]=\"column.sortable ? ariaSortFor(column) : null\"\n (click)=\"toggleSort(column)\"\n >\n @if (column.sortable) {\n <!-- El clic del bot\u00F3n burbujea al `th`, que ya ordena: un solo manejador para mouse y teclado. -->\n <button type=\"button\" class=\"kf-data-table__sort-button\">\n <span class=\"kf-data-table__th-content\">\n <ng-container\n [ngTemplateOutlet]=\"headerLabel\"\n [ngTemplateOutletContext]=\"{ $implicit: column }\"\n />\n <kf-icon\n name=\"chevron-down\"\n size=\"sm\"\n [rotate]=\"sortDirectionFor(column) === 'asc' ? 180 : 0\"\n class=\"kf-data-table__sort-icon\"\n [class.kf-data-table__sort-icon--active]=\"sortDirectionFor(column) !== null\"\n />\n </span>\n </button>\n } @else {\n <span class=\"kf-data-table__th-content\">\n <ng-container\n [ngTemplateOutlet]=\"headerLabel\"\n [ngTemplateOutletContext]=\"{ $implicit: column }\"\n />\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n [class.kf-data-table__row--interactive]=\"rowInteractive()\"\n [class.kf-data-table__row--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.tabindex]=\"rowTabStop() ? 0 : null\"\n (click)=\"onRowClick(row, i, $event)\"\n (keydown.enter)=\"onRowClick(row, i, $event)\"\n (keydown.space)=\"onRowSpace($event, row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [attr.data-column-key]=\"column.key\"\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"isEndAligned(column)\"\n [class.kf-data-table__cell--center]=\"column.align === 'center'\"\n [class.kf-data-table__cell--truncate]=\"column.truncate\"\n [class.kf-data-table__cell--mono]=\"column.mono\"\n [class.kf-data-table__cell--emphasis]=\"column.emphasis\"\n [class.kf-data-table__cell--sticky]=\"column.sticky\"\n [style]=\"stickyStyle(column)\"\n [style.min-width]=\"minWidthFor(column)\"\n [style.width]=\"widthFor(column)\"\n [style.max-width]=\"maxWidthFor(column)\"\n >\n @if (column.truncate) {\n <span class=\"kf-data-table__truncate\" [attr.title]=\"truncateTitle(row, column)\">\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\" [style.--kf-data-table-card-min]=\"cardMinWidth()\">\n @for (row of displayedRows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [class.kf-data-table__card--current]=\"isCurrentRow(row, i)\"\n [attr.aria-current]=\"isCurrentRow(row, i) ? 'true' : null\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.enter)=\"cardInteractive() ? onRowClick(row, i, $event) : undefined\"\n (keydown.space)=\"cardInteractive() ? onRowSpace($event, row, i) : undefined\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: media }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span\n class=\"kf-data-table__card-title\"\n [class.kf-data-table__card-title--mono]=\"title.mono\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: title, index: i }\"\n />\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardLeadColumns().length || cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardLeadColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-lead\"\n [style.--kf-data-table-card-clamp]=\"column.cardClamp\"\n [attr.title]=\"cellValue(row, column) || null\"\n >\n <span class=\"kf-data-table__sr-only\">{{ column.label }}: </span>\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </div>\n }\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span\n class=\"kf-data-table__card-value\"\n [class.kf-data-table__card-value--emphasis]=\"column.emphasis\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardMetaColumns().length) {\n <div class=\"kf-data-table__card-meta\">\n @for (column of cardMetaColumns(); track column.key) {\n <div\n class=\"kf-data-table__card-meta-item\"\n [class.kf-data-table__card-meta-item--end]=\"\n isEndAligned(column) || column.emphasis\n \"\n [class.kf-data-table__card-meta-item--emphasis]=\"column.emphasis\"\n [style.flex-basis]=\"column.width\"\n >\n <span class=\"kf-data-table__card-label kf-overline-text\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-meta-value\">\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n <ng-container\n [ngTemplateOutlet]=\"cardCell\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (!loading() && rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n @if (effectivePageSize()) {\n <kf-pagination\n [page]=\"page()\"\n [pages]=\"totalPages()\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n [pageSize]=\"effectivePageSize()\"\n (pageChange)=\"goToPage($event)\"\n (pageSizeChange)=\"setPageSize($event)\"\n >\n {{ paginationSummary() }}\n </kf-pagination>\n }\n <ng-content select=\"[footer]\" />\n </div>\n }\n</div>\n\n<!-- R\u00F3tulo de una columna: texto visible o solo para lectores con `hideLabel`. -->\n<ng-template #headerLabel let-column>\n @if (column.hideLabel) {\n <span class=\"kf-data-table__sr-only\">{{ column.label }}</span>\n } @else {\n {{ column.label }}\n }\n</ng-template>\n\n<!-- Celda de la vista tabla \u2014 compartida por la celda normal y la `truncate`.\n Una columna `interactive` envuelve su contenido en un bot\u00F3n real. -->\n<ng-template #tableCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"tableCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una celda de la vista tabla (template del consumidor,\n thumbnail o texto). -->\n<ng-template #tableCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n\n<!-- Zona de la tarjeta: igual que la celda de tabla, con bot\u00F3n si la columna es `interactive`. -->\n<ng-template #cardCell let-row let-column=\"column\" let-i=\"index\">\n @if (column.interactive) {\n <button\n type=\"button\"\n class=\"kf-data-table__cell-button\"\n [attr.aria-label]=\"cellLabel(row, column, i)\"\n (click)=\"onCellClick(row, column, i)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n </button>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"cardCellContent\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column, index: i }\"\n />\n }\n</ng-template>\n\n<!-- Contenido de una zona de la tarjeta: template del consumidor o el valor como texto. -->\n<ng-template #cardCellContent let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i, column: column }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n</ng-template>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block;font-family:var(--kf-font-body)}.kf-data-table{background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-md);box-shadow:var(--kf-shadow-sm);overflow:hidden}.kf-data-table--flush{border:none;box-shadow:none;border-radius:0}.kf-data-table__toolbar{display:flex;justify-content:flex-end;padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border)}.kf-data-table__scroll{position:relative;overflow-x:auto}.kf-data-table__scroll--weighted{container-type:inline-size}.kf-data-table__scroll:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__scroll:before,.kf-data-table__scroll:after{content:\"\";position:absolute;top:0;bottom:0;width:24px;pointer-events:none;opacity:0;transition:opacity .14s}.kf-data-table__scroll:before{left:0;background:linear-gradient(to right,var(--kf-color-white),transparent)}.kf-data-table__scroll:after{right:0;background:linear-gradient(to left,var(--kf-color-white),transparent)}.kf-data-table__scroll--fade-left:before{opacity:1}.kf-data-table__scroll--fade-right:after{opacity:1}.kf-data-table__table{width:100%;border-collapse:collapse;text-align:left}.kf-data-table__table th,.kf-data-table__table td{padding:var(--kf-space-sm) var(--kf-space-md);border-bottom:1px solid var(--kf-color-border);white-space:nowrap}.kf-data-table--compact .kf-data-table__table th,.kf-data-table--compact .kf-data-table__table td{padding:var(--kf-space-xs) var(--kf-space-md)}.kf-data-table__table th{background:var(--kf-color-surface)}.kf-data-table__table td{color:var(--kf-color-text)}.kf-data-table__table tbody tr:last-child td{border-bottom:none}.kf-data-table__row{transition:background .14s}.kf-data-table__row--interactive{cursor:pointer}.kf-data-table__row--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__row--interactive:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-data-table__row--current{background:var(--kf-color-primary-soft)}.kf-data-table__cell--right{text-align:right}.kf-data-table__cell--center{text-align:center}.kf-data-table__table .kf-data-table__cell--truncate{max-width:0}.kf-data-table__truncate{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-data-table__table td.kf-data-table__cell--mono{font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm)}.kf-data-table__table td.kf-data-table__cell--emphasis{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.kf-data-table__cell-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);max-width:100%;min-width:32px;min-height:32px;padding:var(--kf-space-xs);border:0;border-radius:var(--kf-radius-xs);background:transparent;color:inherit;font:inherit;text-align:inherit;cursor:pointer}.kf-data-table__cell-button:hover{box-shadow:inset 0 0 0 1px var(--kf-color-border-strong)}.kf-data-table__cell-button:focus-visible{outline:2px solid transparent;outline-offset:-2px;box-shadow:inset 0 0 0 2px var(--kf-color-primary)}@media(max-width:640px),(pointer:coarse){.kf-data-table__cell-button{min-width:44px;min-height:44px}}.kf-data-table__cell--sticky{background:var(--kf-color-white)}.kf-data-table__table th.kf-data-table__cell--sticky{background:var(--kf-color-surface);z-index:2}.kf-data-table__cell--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.kf-data-table__sort-button{display:inline-flex;align-items:center;margin:0;padding:0;font:inherit;letter-spacing:inherit;text-transform:inherit;color:inherit;text-align:inherit;background:none;border:none;border-radius:var(--kf-radius-xs);cursor:pointer}.kf-data-table__sort-button:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-data-table__cell--sortable:hover{color:var(--kf-color-ink)}.kf-data-table__table th.kf-data-table__cell--sort-active{color:var(--kf-color-primary);font-weight:700}.kf-data-table__th-content{display:inline-flex;align-items:center;gap:var(--kf-space-xs)}.kf-data-table__sort-icon{transition:opacity .14s}.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon{opacity:.5}.kf-data-table__sort-icon--active,.kf-data-table__cell--sortable:hover .kf-data-table__sort-icon--active{opacity:1}.kf-data-table__empty{padding:var(--kf-space-md)}.kf-data-table__footer{padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__footer:empty{display:none}.kf-data-table__cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--kf-data-table-card-min, 220px),100%),1fr));grid-auto-rows:1fr;gap:var(--kf-space-md);padding:var(--kf-space-md)}.kf-data-table__card{position:relative;display:flex;flex-direction:column;min-width:0;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);overflow:hidden;transition:border-color .14s,box-shadow .14s,background .14s}.kf-data-table__card--interactive{cursor:pointer}.kf-data-table__card:hover{border-color:var(--kf-color-border-strong);box-shadow:var(--kf-shadow-xs)}.kf-data-table__card--interactive:hover{background:var(--kf-color-primary-soft)}.kf-data-table__card--interactive:focus-visible{outline:2px solid transparent;outline-offset:2px;box-shadow:var(--kf-shadow-focus)}.kf-data-table__card--current{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft)}.kf-data-table__card-header{display:flex;align-items:center;gap:var(--kf-space-sm);min-width:0;padding:var(--kf-space-md) var(--kf-space-md) var(--kf-space-sm)}.kf-data-table__card-media{flex:none}.kf-data-table__card-media img,.kf-data-table__thumb{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs);object-fit:cover;background:var(--kf-color-surface)}.kf-data-table__card-heading{display:flex;flex:1;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-title{flex:0 1 auto;min-width:0;font-family:var(--kf-font-title);font-weight:600;color:var(--kf-color-ink);overflow-wrap:anywhere}.kf-data-table__card-title--mono{flex:none;font-family:var(--kf-font-mono);font-size:var(--kf-font-size-body-sm);white-space:nowrap}.kf-data-table__card-statuses{display:flex;flex:0 1 auto;flex-wrap:nowrap;justify-content:flex-end;gap:var(--kf-space-xs);min-width:0;overflow:hidden}.kf-data-table__card-actions{display:flex;flex-wrap:wrap;gap:var(--kf-space-xs)}.kf-data-table__card-fields{display:flex;flex-direction:column;gap:var(--kf-space-xs);min-width:0;padding:var(--kf-space-md)}.kf-data-table__card-header+.kf-data-table__card-fields{padding-top:0}.kf-data-table__card-lead{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--kf-data-table-card-clamp, 2);line-clamp:var(--kf-data-table-card-clamp, 2);min-width:0;overflow:hidden;overflow-wrap:anywhere;color:var(--kf-color-ink);font-weight:500;line-height:1.35}.kf-data-table__card-field{display:flex;justify-content:space-between;gap:var(--kf-space-sm);min-width:0}.kf-data-table__card-label{flex:none}.kf-data-table__card-value{min-width:0;color:var(--kf-color-text);text-align:right;overflow-wrap:anywhere}.kf-data-table__card-value--emphasis,.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-weight:700;color:var(--kf-color-ink);font-variant-numeric:tabular-nums}.kf-data-table__card-meta{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--kf-space-xs) var(--kf-space-md);margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md) var(--kf-space-md);border-top:1px solid var(--kf-color-border)}.kf-data-table__card-meta-item{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-data-table__card-meta-item--end{margin-left:auto;align-items:flex-end;text-align:right}.kf-data-table__card-meta-value{color:var(--kf-color-text);font-variant-numeric:tabular-nums}.kf-data-table__card-meta-item--emphasis .kf-data-table__card-meta-value{font-size:var(--kf-font-size-body)}.kf-data-table__card-actions{justify-content:flex-end;margin-top:auto;padding:var(--kf-space-sm) var(--kf-space-md);border-top:1px solid var(--kf-color-border);background:var(--kf-color-surface)}.kf-data-table__card-meta~.kf-data-table__card-actions{margin-top:0}.kf-data-table__thumb{width:32px;height:32px}@media(prefers-reduced-motion:reduce){.kf-data-table__card,.kf-data-table__row{transition:none}}.kf-data-table__sk-cell{display:flex;align-items:center;justify-content:flex-start;min-height:1lh}.kf-data-table__sk-cell--center{justify-content:center}.kf-data-table__sk-cell--end{justify-content:flex-end}.kf-data-table__sk-bar{flex:none}.kf-data-table__sk-media{display:block;width:48px;height:48px;border-radius:var(--kf-radius-xs)}.kf-data-table__sk-pill{display:block;width:4.5rem;height:1.25rem;border-radius:var(--kf-radius-pill)}.kf-data-table__sk-value{flex:none;width:40%}.kf-data-table__sk-lead{line-height:1.35}.kf-data-table__sk-action{display:block;width:5rem;height:2rem;border-radius:var(--kf-radius-sm)}\n"] }]
4312
+ }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], skeletonRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonRows", required: false }] }], scrollEl: [{ type: i0.ViewChild, args: ['scroll', { isSignal: true }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], flush: [{ type: i0.Input, args: [{ isSignal: true, alias: "flush", required: false }] }], cardable: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardable", required: false }] }], defaultView: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultView", required: false }] }], showViewToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showViewToggle", required: false }] }], cardMinWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardMinWidth", required: false }] }], render: [{ type: i0.Input, args: [{ isSignal: true, alias: "render", required: false }] }], cellTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellTemplates", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], rowClickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowClickable", required: false }] }], rowFocusable: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowFocusable", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], cellAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellAriaLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], currentRowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentRowKey", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], keepPageOnRowsChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepPageOnRowsChange", required: false }] }], pageSizeChange: [{ type: i0.Output, args: ["pageSizeChange"] }], itemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemLabel", required: false }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }] } });
3996
4313
 
3997
4314
  /**
3998
4315
  * Acción de bajo énfasis con apariencia de texto — "¿Olvidaste tu
@@ -4067,7 +4384,7 @@ class DocumentRow {
4067
4384
  /** Dibuja el esqueleto en lugar del contenido, conservando las dimensiones. */
4068
4385
  loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4069
4386
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DocumentRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
4070
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DocumentRow, isStandalone: true, selector: "kf-document-row", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, downloadLabel: { classPropertyName: "downloadLabel", publicName: "downloadLabel", isSignal: true, isRequired: false, transformFunction: null }, pendingLabel: { classPropertyName: "pendingLabel", publicName: "pendingLabel", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "\"kf-document-row--\" + tone()", "class.kf-document-row--loading": "loading()", "attr.aria-busy": "loading() ? 'true' : null" } }, ngImport: i0, template: "@if (loading()) {\n <span class=\"kf-document-row__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n\n <span class=\"kf-document-row__body\" aria-hidden=\"true\">\n <span class=\"kf-document-row__title kf-bone\" style=\"--kf-bone-width: 55%\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text kf-bone\" style=\"--kf-bone-width: 35%\">{{\n line\n }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions kf-document-row__actions--loading\" aria-hidden=\"true\">\n <ng-content />\n <span class=\"kf-document-row__pending kf-caption-text kf-bone\" style=\"--kf-bone-width: 5rem\">{{\n href() ? downloadLabel() : pendingLabel()\n }}</span>\n </span>\n} @else {\n <span class=\"kf-document-row__icon\" aria-hidden=\"true\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n\n <span class=\"kf-document-row__body\">\n <span class=\"kf-document-row__title\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text\">{{ line }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions\">\n <ng-content />\n @if (href(); as url) {\n <kf-link [href]=\"url\">{{ downloadLabel() }}</kf-link>\n } @else {\n <span class=\"kf-document-row__pending kf-caption-text\">{{ pendingLabel() }}</span>\n }\n </span>\n}\n", styles: [".kf-caption-text{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);min-width:0}.kf-document-row__icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:32px;height:32px;border-radius:var(--kf-radius-xs);background:var(--kf-color-gray-200);color:var(--kf-color-text)}:host(.kf-document-row--info) .kf-document-row__icon{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}:host(.kf-document-row--ok) .kf-document-row__icon{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}:host(.kf-document-row--warn) .kf-document-row__icon{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}:host(.kf-document-row--error) .kf-document-row__icon{background:var(--kf-color-error-soft);color:var(--kf-color-error-strong)}.kf-document-row__body{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}.kf-document-row__title{font-family:var(--kf-font-body);font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-ink)}.kf-document-row__meta{overflow-wrap:anywhere}.kf-document-row__actions{display:flex;align-items:center;gap:var(--kf-space-sm);flex:0 0 auto;margin-left:auto}@container (max-width: 420px){:host{flex-wrap:wrap}}.kf-document-row__actions--loading>:not(.kf-bone){visibility:hidden}.kf-document-row__icon.kf-bone-fill{border-radius:var(--kf-radius-xs)}:host(.kf-document-row--loading) .kf-document-row__icon{background:var(--kf-color-border);animation:none}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "component", type: Link, selector: "kf-link", inputs: ["variant", "disabled", "href", "showArrow"] }] });
4387
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DocumentRow, isStandalone: true, selector: "kf-document-row", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, downloadLabel: { classPropertyName: "downloadLabel", publicName: "downloadLabel", isSignal: true, isRequired: false, transformFunction: null }, pendingLabel: { classPropertyName: "pendingLabel", publicName: "pendingLabel", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "\"kf-document-row--\" + tone()", "class.kf-document-row--loading": "loading()", "attr.aria-busy": "loading() ? 'true' : null" } }, ngImport: i0, template: "@if (loading()) {\n <span class=\"kf-document-row__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n\n <span class=\"kf-document-row__body\" aria-hidden=\"true\">\n <span class=\"kf-document-row__title kf-bone\" style=\"--kf-bone-width: 55%\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text kf-bone\" style=\"--kf-bone-width: 35%\">{{\n line\n }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions kf-document-row__actions--loading\" aria-hidden=\"true\">\n <ng-content />\n <span class=\"kf-document-row__pending kf-caption-text kf-bone\" style=\"--kf-bone-width: 5rem\">{{\n href() ? downloadLabel() : pendingLabel()\n }}</span>\n </span>\n} @else {\n <span class=\"kf-document-row__icon\" aria-hidden=\"true\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n\n <span class=\"kf-document-row__body\">\n <span class=\"kf-document-row__title\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text\">{{ line }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions\">\n <ng-content />\n @if (href(); as url) {\n <kf-link [href]=\"url\">{{ downloadLabel() }}</kf-link>\n } @else {\n <span class=\"kf-document-row__pending kf-caption-text\">{{ pendingLabel() }}</span>\n }\n </span>\n}\n", styles: [".kf-caption-text{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);min-width:0}.kf-document-row__icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:32px;height:32px;border-radius:var(--kf-radius-xs);background:var(--kf-color-gray-200);color:var(--kf-color-text)}:host(.kf-document-row--info) .kf-document-row__icon{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}:host(.kf-document-row--ok) .kf-document-row__icon{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}:host(.kf-document-row--warn) .kf-document-row__icon{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}:host(.kf-document-row--error) .kf-document-row__icon{background:var(--kf-color-error-soft);color:var(--kf-color-error-strong)}.kf-document-row__body{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}.kf-document-row__title{font-family:var(--kf-font-body);font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-ink)}.kf-document-row__meta{overflow-wrap:anywhere}.kf-document-row__actions{display:flex;align-items:center;gap:var(--kf-space-sm);flex:0 0 auto;margin-left:auto}@container (max-width: 420px){:host{flex-wrap:wrap}}.kf-document-row__actions--loading>:not(.kf-bone){visibility:hidden}.kf-document-row__icon.kf-bone-fill{border-radius:var(--kf-radius-xs)}:host(.kf-document-row--loading) .kf-document-row__icon{background:var(--kf-color-border);animation:none}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "component", type: Link, selector: "kf-link", inputs: ["variant", "disabled", "href", "showArrow"] }] });
4071
4388
  }
4072
4389
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DocumentRow, decorators: [{
4073
4390
  type: Component,
@@ -4075,7 +4392,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
4075
4392
  '[class]': '"kf-document-row--" + tone()',
4076
4393
  '[class.kf-document-row--loading]': 'loading()',
4077
4394
  '[attr.aria-busy]': "loading() ? 'true' : null",
4078
- }, template: "@if (loading()) {\n <span class=\"kf-document-row__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n\n <span class=\"kf-document-row__body\" aria-hidden=\"true\">\n <span class=\"kf-document-row__title kf-bone\" style=\"--kf-bone-width: 55%\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text kf-bone\" style=\"--kf-bone-width: 35%\">{{\n line\n }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions kf-document-row__actions--loading\" aria-hidden=\"true\">\n <ng-content />\n <span class=\"kf-document-row__pending kf-caption-text kf-bone\" style=\"--kf-bone-width: 5rem\">{{\n href() ? downloadLabel() : pendingLabel()\n }}</span>\n </span>\n} @else {\n <span class=\"kf-document-row__icon\" aria-hidden=\"true\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n\n <span class=\"kf-document-row__body\">\n <span class=\"kf-document-row__title\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text\">{{ line }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions\">\n <ng-content />\n @if (href(); as url) {\n <kf-link [href]=\"url\">{{ downloadLabel() }}</kf-link>\n } @else {\n <span class=\"kf-document-row__pending kf-caption-text\">{{ pendingLabel() }}</span>\n }\n </span>\n}\n", styles: [".kf-caption-text{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);min-width:0}.kf-document-row__icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:32px;height:32px;border-radius:var(--kf-radius-xs);background:var(--kf-color-gray-200);color:var(--kf-color-text)}:host(.kf-document-row--info) .kf-document-row__icon{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}:host(.kf-document-row--ok) .kf-document-row__icon{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}:host(.kf-document-row--warn) .kf-document-row__icon{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}:host(.kf-document-row--error) .kf-document-row__icon{background:var(--kf-color-error-soft);color:var(--kf-color-error-strong)}.kf-document-row__body{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}.kf-document-row__title{font-family:var(--kf-font-body);font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-ink)}.kf-document-row__meta{overflow-wrap:anywhere}.kf-document-row__actions{display:flex;align-items:center;gap:var(--kf-space-sm);flex:0 0 auto;margin-left:auto}@container (max-width: 420px){:host{flex-wrap:wrap}}.kf-document-row__actions--loading>:not(.kf-bone){visibility:hidden}.kf-document-row__icon.kf-bone-fill{border-radius:var(--kf-radius-xs)}:host(.kf-document-row--loading) .kf-document-row__icon{background:var(--kf-color-border);animation:none}\n"] }]
4395
+ }, template: "@if (loading()) {\n <span class=\"kf-document-row__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n\n <span class=\"kf-document-row__body\" aria-hidden=\"true\">\n <span class=\"kf-document-row__title kf-bone\" style=\"--kf-bone-width: 55%\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text kf-bone\" style=\"--kf-bone-width: 35%\">{{\n line\n }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions kf-document-row__actions--loading\" aria-hidden=\"true\">\n <ng-content />\n <span class=\"kf-document-row__pending kf-caption-text kf-bone\" style=\"--kf-bone-width: 5rem\">{{\n href() ? downloadLabel() : pendingLabel()\n }}</span>\n </span>\n} @else {\n <span class=\"kf-document-row__icon\" aria-hidden=\"true\">\n <kf-icon [name]=\"icon()\" size=\"sm\" />\n </span>\n\n <span class=\"kf-document-row__body\">\n <span class=\"kf-document-row__title\">{{ title() }}</span>\n @if (meta(); as line) {\n <span class=\"kf-document-row__meta kf-caption-text\">{{ line }}</span>\n }\n </span>\n\n <span class=\"kf-document-row__actions\">\n <ng-content />\n @if (href(); as url) {\n <kf-link [href]=\"url\">{{ downloadLabel() }}</kf-link>\n } @else {\n <span class=\"kf-document-row__pending kf-caption-text\">{{ pendingLabel() }}</span>\n }\n </span>\n}\n", styles: [".kf-caption-text{font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-body);color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);min-width:0}.kf-document-row__icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:32px;height:32px;border-radius:var(--kf-radius-xs);background:var(--kf-color-gray-200);color:var(--kf-color-text)}:host(.kf-document-row--info) .kf-document-row__icon{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}:host(.kf-document-row--ok) .kf-document-row__icon{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}:host(.kf-document-row--warn) .kf-document-row__icon{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}:host(.kf-document-row--error) .kf-document-row__icon{background:var(--kf-color-error-soft);color:var(--kf-color-error-strong)}.kf-document-row__body{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}.kf-document-row__title{font-family:var(--kf-font-body);font-size:var(--kf-font-size-body);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-ink)}.kf-document-row__meta{overflow-wrap:anywhere}.kf-document-row__actions{display:flex;align-items:center;gap:var(--kf-space-sm);flex:0 0 auto;margin-left:auto}@container (max-width: 420px){:host{flex-wrap:wrap}}.kf-document-row__actions--loading>:not(.kf-bone){visibility:hidden}.kf-document-row__icon.kf-bone-fill{border-radius:var(--kf-radius-xs)}:host(.kf-document-row--loading) .kf-document-row__icon{background:var(--kf-color-border);animation:none}\n"] }]
4079
4396
  }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], downloadLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadLabel", required: false }] }], pendingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pendingLabel", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
4080
4397
 
4081
4398
  /**
@@ -4152,6 +4469,18 @@ const BAR_TONE = {
4152
4469
  * <kf-stat-card icon="clock" tone="warn" value="7" label="Por vencer" [bar]="35" hint="7 de 20"
4153
4470
  * clickable [pressed]="filter() === 'due'" (cardClick)="toggle('due')" />
4154
4471
  *
4472
+ * `density` (`'default'` | `'compact'`): `'compact'` es la variante para
4473
+ * pantallas angostas — padding de `--kf-space-md`, ícono de 40px y valor de
4474
+ * `--kf-font-size-title-sm`, con el mismo contenido. Si la card mide 210px de
4475
+ * ancho o menos (ej. una grilla 2x2 en teléfono), pasa además a dos filas:
4476
+ * ícono y valor en la primera, y label, nota, barra y `hint` debajo a todo el
4477
+ * ancho; el chevron se oculta. Solo la variante compacta convierte el host en
4478
+ * contenedor de tamaño (`container-type: inline-size`), así que debe tener un
4479
+ * ancho que no dependa de su contenido (celda de grilla, `width` explícito o
4480
+ * hijo de un contenedor en bloque). `'default'` no cambia nada.
4481
+ *
4482
+ * <kf-stat-card density="compact" icon="clock" value="7" label="Por vencer" />
4483
+ *
4155
4484
  * `loading` (default `false`): mientras es `true` la card dibuja su esqueleto
4156
4485
  * en vez del contenido, con el MISMO cascarón (borde, padding, ícono de 50px)
4157
4486
  * y líneas del alto real de cada texto — valor, etiqueta y, si se pasaron,
@@ -4185,6 +4514,9 @@ class StatCard {
4185
4514
  */
4186
4515
  pressed = input(null, /* @ts-ignore */
4187
4516
  ...(ngDevMode ? [{ debugName: "pressed" }] : /* istanbul ignore next */ []));
4517
+ /** `'compact'`: variante para pantallas angostas; `'default'` no cambia la card. */
4518
+ density = input('default', /* @ts-ignore */
4519
+ ...(ngDevMode ? [{ debugName: "density" }] : /* istanbul ignore next */ []));
4188
4520
  /** Dibuja el esqueleto en lugar del contenido, conservando las dimensiones. */
4189
4521
  loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4190
4522
  /** Si se escucha `cardClick`, la card se renderiza como botón clickeable con chevron. */
@@ -4198,12 +4530,14 @@ class StatCard {
4198
4530
  }, /* @ts-ignore */
4199
4531
  ...(ngDevMode ? [{ debugName: "hasBar" }] : /* istanbul ignore next */ []));
4200
4532
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: StatCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
4201
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: StatCard, isStandalone: true, selector: "kf-stat-card", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, note: { classPropertyName: "note", publicName: "note", isSignal: true, isRequired: false, transformFunction: null }, bar: { classPropertyName: "bar", publicName: "bar", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, pressed: { classPropertyName: "pressed", publicName: "pressed", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick" }, ngImport: i0, template: "@if (loading()) {\n <div class=\"kf-stat-card\" aria-busy=\"true\">\n <span\n class=\"kf-stat-card__icon kf-stat-card__icon--bone kf-bone-fill\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"kf-stat-card__body\" aria-hidden=\"true\">\n <span class=\"kf-stat-card__value kf-bone\" style=\"--kf-bone-width: 40%\">{{ value() }}</span>\n <span class=\"kf-stat-card__label kf-bone\" style=\"--kf-bone-width: 70%\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note kf-bone\" style=\"--kf-bone-width: 55%\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <span class=\"kf-stat-card__bar\">\n <span class=\"kf-stat-card__bar-bone kf-bone-fill\"></span>\n </span>\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint kf-bone\" style=\"--kf-bone-width: 45%\">{{ hint() }}</span>\n }\n </span>\n </div>\n} @else if (clickable()) {\n <button\n type=\"button\"\n class=\"kf-stat-card kf-stat-card--clickable\"\n [class.kf-stat-card--pressed]=\"pressed() === true\"\n [attr.aria-pressed]=\"pressed()\"\n (click)=\"cardClick.emit()\"\n >\n <ng-container *ngTemplateOutlet=\"content\" />\n <kf-icon class=\"kf-stat-card__chevron\" name=\"chevron-right\" size=\"sm\" />\n </button>\n} @else {\n <div class=\"kf-stat-card\">\n <ng-container *ngTemplateOutlet=\"content\" />\n </div>\n}\n\n<ng-template #content>\n <span class=\"kf-stat-card__icon\" [class]=\"'kf-stat-card__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"md\" />\n </span>\n <span class=\"kf-stat-card__body\">\n <span class=\"kf-stat-card__value\">{{ value() }}</span>\n <span class=\"kf-stat-card__label\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <kf-progress\n class=\"kf-stat-card__bar\"\n [value]=\"bar()!\"\n [tone]=\"barTone()\"\n [ariaLabel]=\"label()\"\n />\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint\">{{ hint() }}</span>\n }\n </span>\n</ng-template>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-stat-card{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-lg);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-md);background:var(--kf-color-white);box-shadow:var(--kf-shadow-sm);font:inherit;text-align:left}.kf-stat-card--clickable{cursor:pointer;transition:box-shadow .14s,transform .14s}.kf-stat-card--clickable:hover{box-shadow:var(--kf-shadow-md);transform:translateY(-2px)}.kf-stat-card--clickable:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-stat-card--pressed{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 1px var(--kf-color-primary)}.kf-stat-card--pressed:focus-visible{box-shadow:inset 0 0 0 1px var(--kf-color-primary),var(--kf-shadow-focus)}.kf-stat-card__icon{display:grid;place-items:center;width:50px;height:50px;flex:none;border-radius:var(--kf-radius-md)}.kf-stat-card__icon--primary{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-stat-card__icon--success{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}.kf-stat-card__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-stat-card__icon--purple{background:var(--kf-color-purple-soft);color:var(--kf-color-purple)}.kf-stat-card__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-stat-card__icon--info{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}.kf-stat-card__icon--neutral{background:var(--kf-color-gray-100);color:var(--kf-color-text)}.kf-stat-card__body{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-stat-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:var(--kf-font-size-title-md);color:var(--kf-color-ink)}.kf-stat-card__label{font-size:.875rem;font-weight:700;color:var(--kf-color-ink)}.kf-stat-card__note{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-stat-card__bar{padding-block-start:var(--kf-space-xs)}.kf-stat-card__hint{font-size:.78rem;color:var(--kf-color-text)}.kf-stat-card__chevron{margin-left:auto;flex:none;color:var(--kf-color-gray-400)}.kf-stat-card__icon--bone{border-radius:var(--kf-radius-md)}.kf-stat-card__bar-bone{display:block;height:4px;border-radius:var(--kf-radius-pill)}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Progress, selector: "kf-progress", inputs: ["value", "tone", "size", "label", "ariaLabel"] }] });
4533
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: StatCard, isStandalone: true, selector: "kf-stat-card", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, note: { classPropertyName: "note", publicName: "note", isSignal: true, isRequired: false, transformFunction: null }, bar: { classPropertyName: "bar", publicName: "bar", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, pressed: { classPropertyName: "pressed", publicName: "pressed", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick" }, host: { properties: { "class.kf-stat-card-host--compact": "density() === 'compact'" } }, ngImport: i0, template: "@if (loading()) {\n <div\n class=\"kf-stat-card\"\n [class.kf-stat-card--compact]=\"density() === 'compact'\"\n aria-busy=\"true\"\n >\n <span\n class=\"kf-stat-card__icon kf-stat-card__icon--bone kf-bone-fill\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"kf-stat-card__body\" aria-hidden=\"true\">\n <span class=\"kf-stat-card__value kf-bone\" style=\"--kf-bone-width: 40%\">{{ value() }}</span>\n <span class=\"kf-stat-card__label kf-bone\" style=\"--kf-bone-width: 70%\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note kf-bone\" style=\"--kf-bone-width: 55%\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <span class=\"kf-stat-card__bar\">\n <span class=\"kf-stat-card__bar-bone kf-bone-fill\"></span>\n </span>\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint kf-bone\" style=\"--kf-bone-width: 45%\">{{ hint() }}</span>\n }\n </span>\n </div>\n} @else if (clickable()) {\n <button\n type=\"button\"\n class=\"kf-stat-card kf-stat-card--clickable\"\n [class.kf-stat-card--compact]=\"density() === 'compact'\"\n [class.kf-stat-card--pressed]=\"pressed() === true\"\n [attr.aria-pressed]=\"pressed()\"\n (click)=\"cardClick.emit()\"\n >\n <ng-container *ngTemplateOutlet=\"content\" />\n <kf-icon class=\"kf-stat-card__chevron\" name=\"chevron-right\" size=\"sm\" />\n </button>\n} @else {\n <div class=\"kf-stat-card\" [class.kf-stat-card--compact]=\"density() === 'compact'\">\n <ng-container *ngTemplateOutlet=\"content\" />\n </div>\n}\n\n<ng-template #content>\n <span class=\"kf-stat-card__icon\" [class]=\"'kf-stat-card__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"md\" />\n </span>\n <span class=\"kf-stat-card__body\">\n <span class=\"kf-stat-card__value\">{{ value() }}</span>\n <span class=\"kf-stat-card__label\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <kf-progress\n class=\"kf-stat-card__bar\"\n [value]=\"bar()!\"\n [tone]=\"barTone()\"\n [ariaLabel]=\"label()\"\n />\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint\">{{ hint() }}</span>\n }\n </span>\n</ng-template>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-stat-card{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-lg);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-md);background:var(--kf-color-white);box-shadow:var(--kf-shadow-sm);font:inherit;text-align:left}.kf-stat-card--clickable{cursor:pointer;transition:box-shadow .14s,transform .14s}.kf-stat-card--clickable:hover{box-shadow:var(--kf-shadow-md);transform:translateY(-2px)}.kf-stat-card--clickable:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-stat-card--pressed{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 1px var(--kf-color-primary)}.kf-stat-card--pressed:focus-visible{box-shadow:inset 0 0 0 1px var(--kf-color-primary),var(--kf-shadow-focus)}.kf-stat-card__icon{display:grid;place-items:center;width:50px;height:50px;flex:none;border-radius:var(--kf-radius-md)}.kf-stat-card__icon--primary{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-stat-card__icon--success{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}.kf-stat-card__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-stat-card__icon--purple{background:var(--kf-color-purple-soft);color:var(--kf-color-purple)}.kf-stat-card__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-stat-card__icon--info{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}.kf-stat-card__icon--neutral{background:var(--kf-color-gray-100);color:var(--kf-color-text)}.kf-stat-card__body{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-stat-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:var(--kf-font-size-title-md);color:var(--kf-color-ink)}.kf-stat-card__label{font-size:.875rem;font-weight:700;color:var(--kf-color-ink)}.kf-stat-card__note{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-stat-card__bar{padding-block-start:var(--kf-space-xs)}.kf-stat-card__hint{font-size:.78rem;color:var(--kf-color-text)}.kf-stat-card__chevron{margin-left:auto;flex:none;color:var(--kf-color-gray-400)}.kf-stat-card__icon--bone{border-radius:var(--kf-radius-md)}.kf-stat-card__bar-bone{display:block;height:4px;border-radius:var(--kf-radius-pill)}.kf-stat-card--compact{gap:var(--kf-space-sm) 12px;padding:var(--kf-space-md)}.kf-stat-card--compact .kf-stat-card__icon{width:40px;height:40px}.kf-stat-card--compact .kf-stat-card__value{font-size:var(--kf-font-size-title-sm)}:host(.kf-stat-card-host--compact){container-type:inline-size}@container (max-width: 210px){.kf-stat-card--compact{display:grid;grid-template-columns:auto minmax(0,1fr);align-content:start;align-items:center;gap:2px 10px;padding:12px}.kf-stat-card--compact .kf-stat-card__body{display:contents}.kf-stat-card--compact .kf-stat-card__icon{grid-row:1;grid-column:1;width:36px;height:36px}.kf-stat-card--compact .kf-stat-card__value{grid-row:1;grid-column:2}.kf-stat-card--compact .kf-stat-card__label,.kf-stat-card--compact .kf-stat-card__note,.kf-stat-card--compact .kf-stat-card__bar,.kf-stat-card--compact .kf-stat-card__hint{grid-column:1 / -1}.kf-stat-card--compact .kf-stat-card__label{margin-top:6px}.kf-stat-card--compact .kf-stat-card__chevron{display:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Progress, selector: "kf-progress", inputs: ["value", "tone", "size", "label", "ariaLabel"] }] });
4202
4534
  }
4203
4535
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: StatCard, decorators: [{
4204
4536
  type: Component,
4205
- args: [{ selector: 'kf-stat-card', imports: [Icon, NgTemplateOutlet, Progress], template: "@if (loading()) {\n <div class=\"kf-stat-card\" aria-busy=\"true\">\n <span\n class=\"kf-stat-card__icon kf-stat-card__icon--bone kf-bone-fill\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"kf-stat-card__body\" aria-hidden=\"true\">\n <span class=\"kf-stat-card__value kf-bone\" style=\"--kf-bone-width: 40%\">{{ value() }}</span>\n <span class=\"kf-stat-card__label kf-bone\" style=\"--kf-bone-width: 70%\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note kf-bone\" style=\"--kf-bone-width: 55%\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <span class=\"kf-stat-card__bar\">\n <span class=\"kf-stat-card__bar-bone kf-bone-fill\"></span>\n </span>\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint kf-bone\" style=\"--kf-bone-width: 45%\">{{ hint() }}</span>\n }\n </span>\n </div>\n} @else if (clickable()) {\n <button\n type=\"button\"\n class=\"kf-stat-card kf-stat-card--clickable\"\n [class.kf-stat-card--pressed]=\"pressed() === true\"\n [attr.aria-pressed]=\"pressed()\"\n (click)=\"cardClick.emit()\"\n >\n <ng-container *ngTemplateOutlet=\"content\" />\n <kf-icon class=\"kf-stat-card__chevron\" name=\"chevron-right\" size=\"sm\" />\n </button>\n} @else {\n <div class=\"kf-stat-card\">\n <ng-container *ngTemplateOutlet=\"content\" />\n </div>\n}\n\n<ng-template #content>\n <span class=\"kf-stat-card__icon\" [class]=\"'kf-stat-card__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"md\" />\n </span>\n <span class=\"kf-stat-card__body\">\n <span class=\"kf-stat-card__value\">{{ value() }}</span>\n <span class=\"kf-stat-card__label\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <kf-progress\n class=\"kf-stat-card__bar\"\n [value]=\"bar()!\"\n [tone]=\"barTone()\"\n [ariaLabel]=\"label()\"\n />\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint\">{{ hint() }}</span>\n }\n </span>\n</ng-template>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-stat-card{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-lg);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-md);background:var(--kf-color-white);box-shadow:var(--kf-shadow-sm);font:inherit;text-align:left}.kf-stat-card--clickable{cursor:pointer;transition:box-shadow .14s,transform .14s}.kf-stat-card--clickable:hover{box-shadow:var(--kf-shadow-md);transform:translateY(-2px)}.kf-stat-card--clickable:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-stat-card--pressed{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 1px var(--kf-color-primary)}.kf-stat-card--pressed:focus-visible{box-shadow:inset 0 0 0 1px var(--kf-color-primary),var(--kf-shadow-focus)}.kf-stat-card__icon{display:grid;place-items:center;width:50px;height:50px;flex:none;border-radius:var(--kf-radius-md)}.kf-stat-card__icon--primary{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-stat-card__icon--success{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}.kf-stat-card__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-stat-card__icon--purple{background:var(--kf-color-purple-soft);color:var(--kf-color-purple)}.kf-stat-card__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-stat-card__icon--info{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}.kf-stat-card__icon--neutral{background:var(--kf-color-gray-100);color:var(--kf-color-text)}.kf-stat-card__body{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-stat-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:var(--kf-font-size-title-md);color:var(--kf-color-ink)}.kf-stat-card__label{font-size:.875rem;font-weight:700;color:var(--kf-color-ink)}.kf-stat-card__note{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-stat-card__bar{padding-block-start:var(--kf-space-xs)}.kf-stat-card__hint{font-size:.78rem;color:var(--kf-color-text)}.kf-stat-card__chevron{margin-left:auto;flex:none;color:var(--kf-color-gray-400)}.kf-stat-card__icon--bone{border-radius:var(--kf-radius-md)}.kf-stat-card__bar-bone{display:block;height:4px;border-radius:var(--kf-radius-pill)}\n"] }]
4206
- }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], note: [{ type: i0.Input, args: [{ isSignal: true, alias: "note", required: false }] }], bar: [{ type: i0.Input, args: [{ isSignal: true, alias: "bar", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], pressed: [{ type: i0.Input, args: [{ isSignal: true, alias: "pressed", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }] } });
4537
+ args: [{ selector: 'kf-stat-card', imports: [Icon, NgTemplateOutlet, Progress], host: {
4538
+ '[class.kf-stat-card-host--compact]': "density() === 'compact'",
4539
+ }, template: "@if (loading()) {\n <div\n class=\"kf-stat-card\"\n [class.kf-stat-card--compact]=\"density() === 'compact'\"\n aria-busy=\"true\"\n >\n <span\n class=\"kf-stat-card__icon kf-stat-card__icon--bone kf-bone-fill\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"kf-stat-card__body\" aria-hidden=\"true\">\n <span class=\"kf-stat-card__value kf-bone\" style=\"--kf-bone-width: 40%\">{{ value() }}</span>\n <span class=\"kf-stat-card__label kf-bone\" style=\"--kf-bone-width: 70%\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note kf-bone\" style=\"--kf-bone-width: 55%\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <span class=\"kf-stat-card__bar\">\n <span class=\"kf-stat-card__bar-bone kf-bone-fill\"></span>\n </span>\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint kf-bone\" style=\"--kf-bone-width: 45%\">{{ hint() }}</span>\n }\n </span>\n </div>\n} @else if (clickable()) {\n <button\n type=\"button\"\n class=\"kf-stat-card kf-stat-card--clickable\"\n [class.kf-stat-card--compact]=\"density() === 'compact'\"\n [class.kf-stat-card--pressed]=\"pressed() === true\"\n [attr.aria-pressed]=\"pressed()\"\n (click)=\"cardClick.emit()\"\n >\n <ng-container *ngTemplateOutlet=\"content\" />\n <kf-icon class=\"kf-stat-card__chevron\" name=\"chevron-right\" size=\"sm\" />\n </button>\n} @else {\n <div class=\"kf-stat-card\" [class.kf-stat-card--compact]=\"density() === 'compact'\">\n <ng-container *ngTemplateOutlet=\"content\" />\n </div>\n}\n\n<ng-template #content>\n <span class=\"kf-stat-card__icon\" [class]=\"'kf-stat-card__icon--' + tone()\">\n <kf-icon [name]=\"icon()\" size=\"md\" />\n </span>\n <span class=\"kf-stat-card__body\">\n <span class=\"kf-stat-card__value\">{{ value() }}</span>\n <span class=\"kf-stat-card__label\">{{ label() }}</span>\n @if (note()) {\n <span class=\"kf-stat-card__note\">{{ note() }}</span>\n }\n @if (hasBar()) {\n <kf-progress\n class=\"kf-stat-card__bar\"\n [value]=\"bar()!\"\n [tone]=\"barTone()\"\n [ariaLabel]=\"label()\"\n />\n }\n @if (hint()) {\n <span class=\"kf-stat-card__hint\">{{ hint() }}</span>\n }\n </span>\n</ng-template>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-stat-card{display:flex;align-items:center;gap:var(--kf-space-md);width:100%;padding:var(--kf-space-lg);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-md);background:var(--kf-color-white);box-shadow:var(--kf-shadow-sm);font:inherit;text-align:left}.kf-stat-card--clickable{cursor:pointer;transition:box-shadow .14s,transform .14s}.kf-stat-card--clickable:hover{box-shadow:var(--kf-shadow-md);transform:translateY(-2px)}.kf-stat-card--clickable:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-stat-card--pressed{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft);box-shadow:inset 0 0 0 1px var(--kf-color-primary)}.kf-stat-card--pressed:focus-visible{box-shadow:inset 0 0 0 1px var(--kf-color-primary),var(--kf-shadow-focus)}.kf-stat-card__icon{display:grid;place-items:center;width:50px;height:50px;flex:none;border-radius:var(--kf-radius-md)}.kf-stat-card__icon--primary{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-stat-card__icon--success{background:var(--kf-color-success-soft);color:var(--kf-color-success-strong)}.kf-stat-card__icon--error{background:var(--kf-color-error-soft);color:var(--kf-color-error)}.kf-stat-card__icon--purple{background:var(--kf-color-purple-soft);color:var(--kf-color-purple)}.kf-stat-card__icon--warn{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong)}.kf-stat-card__icon--info{background:var(--kf-color-info-soft);color:var(--kf-color-info-strong)}.kf-stat-card__icon--neutral{background:var(--kf-color-gray-100);color:var(--kf-color-text)}.kf-stat-card__body{display:flex;flex-direction:column;gap:2px;min-width:0}.kf-stat-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:var(--kf-font-size-title-md);color:var(--kf-color-ink)}.kf-stat-card__label{font-size:.875rem;font-weight:700;color:var(--kf-color-ink)}.kf-stat-card__note{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-stat-card__bar{padding-block-start:var(--kf-space-xs)}.kf-stat-card__hint{font-size:.78rem;color:var(--kf-color-text)}.kf-stat-card__chevron{margin-left:auto;flex:none;color:var(--kf-color-gray-400)}.kf-stat-card__icon--bone{border-radius:var(--kf-radius-md)}.kf-stat-card__bar-bone{display:block;height:4px;border-radius:var(--kf-radius-pill)}.kf-stat-card--compact{gap:var(--kf-space-sm) 12px;padding:var(--kf-space-md)}.kf-stat-card--compact .kf-stat-card__icon{width:40px;height:40px}.kf-stat-card--compact .kf-stat-card__value{font-size:var(--kf-font-size-title-sm)}:host(.kf-stat-card-host--compact){container-type:inline-size}@container (max-width: 210px){.kf-stat-card--compact{display:grid;grid-template-columns:auto minmax(0,1fr);align-content:start;align-items:center;gap:2px 10px;padding:12px}.kf-stat-card--compact .kf-stat-card__body{display:contents}.kf-stat-card--compact .kf-stat-card__icon{grid-row:1;grid-column:1;width:36px;height:36px}.kf-stat-card--compact .kf-stat-card__value{grid-row:1;grid-column:2}.kf-stat-card--compact .kf-stat-card__label,.kf-stat-card--compact .kf-stat-card__note,.kf-stat-card--compact .kf-stat-card__bar,.kf-stat-card--compact .kf-stat-card__hint{grid-column:1 / -1}.kf-stat-card--compact .kf-stat-card__label{margin-top:6px}.kf-stat-card--compact .kf-stat-card__chevron{display:none}}\n"] }]
4540
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], note: [{ type: i0.Input, args: [{ isSignal: true, alias: "note", required: false }] }], bar: [{ type: i0.Input, args: [{ isSignal: true, alias: "bar", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], pressed: [{ type: i0.Input, args: [{ isSignal: true, alias: "pressed", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }] } });
4207
4541
 
4208
4542
  /** Cantidad de elementos por defecto de cada variante (`count` sin valor). */
4209
4543
  const DEFAULT_COUNT = {
@@ -4273,11 +4607,11 @@ class SkeletonPreset {
4273
4607
  formColumns = computed(() => (this.columns() === 2 ? 2 : 1), /* @ts-ignore */
4274
4608
  ...(ngDevMode ? [{ debugName: "formColumns" }] : /* istanbul ignore next */ []));
4275
4609
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SkeletonPreset, deps: [], target: i0.ɵɵFactoryTarget.Component });
4276
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: SkeletonPreset, isStandalone: true, selector: "kf-skeleton-preset", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n [class]=\"'kf-skeleton-preset kf-skeleton-preset--' + variant()\"\n aria-busy=\"true\"\n [style.--kf-skeleton-preset-columns]=\"columns() ?? null\"\n>\n @if (label()) {\n <span class=\"kf-sr-only\" role=\"status\">{{ label() }}</span>\n }\n @switch (variant()) {\n @case ('kpi-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-stat-card [loading]=\"true\" icon=\"bell\" value=\"0\" label=\"Etiqueta\" note=\"Nota\" />\n }\n </div>\n }\n @case ('card-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-card gap=\"sm\" aria-hidden=\"true\">\n <kf-skeleton variant=\"rect\" height=\"7.5rem\" />\n <kf-skeleton width=\"60%\" height=\"1.25rem\" />\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n </kf-card>\n }\n </div>\n }\n @case ('form') {\n <div\n class=\"kf-skeleton-preset__form\"\n [class.kf-skeleton-preset__form--two]=\"formColumns() === 2\"\n aria-hidden=\"true\"\n >\n @for (i of items(); track i) {\n <div class=\"kf-skeleton-preset__field\">\n <span\n class=\"kf-skeleton-preset__label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Etiqueta\n </span>\n <span class=\"kf-skeleton-preset__control\">\n <span class=\"kf-skeleton-preset__value kf-bone\" style=\"--kf-bone-width: 55%\"\n >Valor</span\n >\n </span>\n </div>\n }\n </div>\n }\n @case ('list') {\n <div class=\"kf-skeleton-preset__stack\">\n @for (i of items(); track i) {\n <kf-document-row [loading]=\"true\" title=\"Documento\" meta=\"Archivo \u00B7 120 KB\" />\n }\n </div>\n }\n @case ('table') {\n <kf-data-table\n [columns]=\"tableColumns()\"\n [rows]=\"[]\"\n [loading]=\"true\"\n [skeletonRows]=\"total()\"\n />\n }\n @case ('timeline') {\n <div class=\"kf-skeleton-preset__timeline\" aria-hidden=\"true\">\n <div class=\"kf-skeleton-preset__timeline-toolbar\">\n <span class=\"kf-skeleton-preset__timeline-heading kf-bone\" style=\"--kf-bone-width: 30%\">\n Etapas\n </span>\n <span class=\"kf-skeleton-preset__timeline-toggle kf-bone\" style=\"--kf-bone-width: 7rem\">\n Expandir todo\n </span>\n </div>\n <ol class=\"kf-skeleton-preset__timeline-list\">\n @for (i of items(); track i) {\n <li class=\"kf-skeleton-preset__timeline-group\">\n <span class=\"kf-skeleton-preset__timeline-node kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__timeline-text\">\n <span\n class=\"kf-skeleton-preset__timeline-title kf-bone\"\n style=\"--kf-bone-width: 45%\"\n >\n Etapa\n </span>\n <span\n class=\"kf-skeleton-preset__timeline-meta kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Detalle\n </span>\n </span>\n </li>\n }\n </ol>\n </div>\n }\n @case ('detail-header') {\n <div class=\"kf-skeleton-preset__header\" aria-hidden=\"true\">\n <span class=\"kf-skeleton-preset__header-icon kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__header-heading\">\n <span class=\"kf-skeleton-preset__header-title kf-bone\" style=\"--kf-bone-width: 40%\">\n T\u00EDtulo\n </span>\n <span class=\"kf-skeleton-preset__header-subtitle kf-bone\" style=\"--kf-bone-width: 60%\">\n Subt\u00EDtulo\n </span>\n </span>\n </div>\n }\n }\n</div>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}.kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block;font-family:var(--kf-font-body)}.kf-skeleton-preset__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,15rem),1fr));gap:var(--kf-space-md)}.kf-skeleton-preset__grid--fixed{grid-template-columns:repeat(var(--kf-skeleton-preset-columns),minmax(0,1fr))}.kf-skeleton-preset__stack{display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__form{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--kf-space-md)}.kf-skeleton-preset__form--two{grid-template-columns:repeat(2,minmax(0,1fr))}@media(max-width:640px){.kf-skeleton-preset__form--two{grid-template-columns:minmax(0,1fr)}}.kf-skeleton-preset__field{display:flex;flex-direction:column;gap:var(--kf-space-xs)}.kf-skeleton-preset__control{display:block;padding:var(--kf-space-sm) var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm)}.kf-skeleton-preset__timeline{--_node: var(--kf-status-node-size, 2.125rem);--_gutter: var(--kf-space-sm);--_pad-y: var(--kf-space-sm);--_line: 2px;display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-heading{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-sm);font-weight:var(--kf-font-weight-title)}.kf-skeleton-preset__timeline-toggle{box-sizing:border-box;padding:6px var(--kf-space-sm);border:1px solid transparent;font-size:.85rem;font-weight:600;border-radius:var(--kf-radius-sm)}@media(max-width:640px),(pointer:coarse){.kf-skeleton-preset__timeline-toggle{min-height:44px}}.kf-skeleton-preset__timeline-list{list-style:none;margin:0;padding:0}.kf-skeleton-preset__timeline-group{position:relative;display:flex;align-items:flex-start;gap:var(--kf-space-md);box-sizing:border-box;min-height:2.75rem;padding:var(--_pad-y) var(--_gutter)}.kf-skeleton-preset__timeline-group:not(:last-child):before{content:\"\";position:absolute;inset-inline-start:calc(var(--_gutter) + var(--_node) / 2 - var(--_line) / 2);top:calc(var(--_pad-y) + var(--_node));bottom:calc(var(--kf-space-xs) - var(--_pad-y));width:var(--_line);background:var(--kf-color-border)}.kf-skeleton-preset__timeline-node{flex:none;width:var(--_node);height:var(--_node);border-radius:50%}.kf-skeleton-preset__timeline-text{flex:1;display:flex;flex-direction:column;justify-content:center;gap:2px;min-width:0;min-height:var(--_node)}.kf-skeleton-preset__timeline-title{font-weight:700;font-size:var(--kf-font-size-body)}.kf-skeleton-preset__timeline-meta{font-size:var(--kf-font-size-body-sm)}.kf-skeleton-preset__header{display:flex;align-items:center;gap:var(--kf-space-md);padding-bottom:var(--kf-space-lg);border-bottom:1px solid var(--kf-color-border)}.kf-skeleton-preset__header-icon{flex:none;width:52px;height:52px;border:1px solid transparent;border-radius:var(--kf-radius-md)}.kf-skeleton-preset__header-heading{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;min-width:0}.kf-skeleton-preset__header-title{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-md);font-weight:var(--kf-font-weight-title);line-height:1.2}.kf-skeleton-preset__header-subtitle{font-size:.9375rem}@media(max-width:900px){.kf-skeleton-preset__header-icon{width:40px;height:40px}.kf-skeleton-preset__header-title{font-size:var(--kf-font-size-title-sm)}.kf-skeleton-preset__header-subtitle{font-size:.8125rem}}\n"], dependencies: [{ kind: "component", type: Card, selector: "kf-card", inputs: ["flush", "gap", "loading"] }, { kind: "component", type: DataTable, selector: "kf-data-table", inputs: ["columns", "rows", "loading", "skeletonRows", "rowKey", "flush", "cardable", "defaultView", "showViewToggle", "cardMinWidth", "render", "cellTemplates", "density", "rowClickable", "cellAriaLabel", "ariaLabel", "currentRowKey", "pageSize", "pageSizeOptions", "page", "keepPageOnRowsChange", "itemLabel", "sort", "view"], outputs: ["rowClick", "cellClick", "pageChange", "pageSizeChange", "sortChange", "viewChange"] }, { kind: "component", type: DocumentRow, selector: "kf-document-row", inputs: ["icon", "tone", "title", "meta", "href", "downloadLabel", "pendingLabel", "loading"] }, { kind: "component", type: Skeleton, selector: "kf-skeleton", inputs: ["variant", "width", "height"] }, { kind: "component", type: StatCard, selector: "kf-stat-card", inputs: ["icon", "tone", "value", "label", "note", "bar", "hint", "pressed", "loading", "clickable"], outputs: ["cardClick"] }] });
4610
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: SkeletonPreset, isStandalone: true, selector: "kf-skeleton-preset", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n [class]=\"'kf-skeleton-preset kf-skeleton-preset--' + variant()\"\n aria-busy=\"true\"\n [style.--kf-skeleton-preset-columns]=\"columns() ?? null\"\n>\n @if (label()) {\n <span class=\"kf-sr-only\" role=\"status\">{{ label() }}</span>\n }\n @switch (variant()) {\n @case ('kpi-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-stat-card [loading]=\"true\" icon=\"bell\" value=\"0\" label=\"Etiqueta\" note=\"Nota\" />\n }\n </div>\n }\n @case ('card-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-card gap=\"sm\" aria-hidden=\"true\">\n <kf-skeleton variant=\"rect\" height=\"7.5rem\" />\n <kf-skeleton width=\"60%\" height=\"1.25rem\" />\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n </kf-card>\n }\n </div>\n }\n @case ('form') {\n <div\n class=\"kf-skeleton-preset__form\"\n [class.kf-skeleton-preset__form--two]=\"formColumns() === 2\"\n aria-hidden=\"true\"\n >\n @for (i of items(); track i) {\n <div class=\"kf-skeleton-preset__field\">\n <span\n class=\"kf-skeleton-preset__label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Etiqueta\n </span>\n <span class=\"kf-skeleton-preset__control\">\n <span class=\"kf-skeleton-preset__value kf-bone\" style=\"--kf-bone-width: 55%\"\n >Valor</span\n >\n </span>\n </div>\n }\n </div>\n }\n @case ('list') {\n <div class=\"kf-skeleton-preset__stack\">\n @for (i of items(); track i) {\n <kf-document-row [loading]=\"true\" title=\"Documento\" meta=\"Archivo \u00B7 120 KB\" />\n }\n </div>\n }\n @case ('table') {\n <kf-data-table\n [columns]=\"tableColumns()\"\n [rows]=\"[]\"\n [loading]=\"true\"\n [skeletonRows]=\"total()\"\n />\n }\n @case ('timeline') {\n <div class=\"kf-skeleton-preset__timeline\" aria-hidden=\"true\">\n <div class=\"kf-skeleton-preset__timeline-toolbar\">\n <span class=\"kf-skeleton-preset__timeline-heading kf-bone\" style=\"--kf-bone-width: 30%\">\n Etapas\n </span>\n <span class=\"kf-skeleton-preset__timeline-toggle kf-bone\" style=\"--kf-bone-width: 7rem\">\n Expandir todo\n </span>\n </div>\n <ol class=\"kf-skeleton-preset__timeline-list\">\n @for (i of items(); track i) {\n <li class=\"kf-skeleton-preset__timeline-group\">\n <span class=\"kf-skeleton-preset__timeline-node kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__timeline-text\">\n <span\n class=\"kf-skeleton-preset__timeline-title kf-bone\"\n style=\"--kf-bone-width: 45%\"\n >\n Etapa\n </span>\n <span\n class=\"kf-skeleton-preset__timeline-meta kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Detalle\n </span>\n </span>\n </li>\n }\n </ol>\n </div>\n }\n @case ('detail-header') {\n <div class=\"kf-skeleton-preset__header\" aria-hidden=\"true\">\n <span class=\"kf-skeleton-preset__header-icon kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__header-heading\">\n <span class=\"kf-skeleton-preset__header-title kf-bone\" style=\"--kf-bone-width: 40%\">\n T\u00EDtulo\n </span>\n <span class=\"kf-skeleton-preset__header-subtitle kf-bone\" style=\"--kf-bone-width: 60%\">\n Subt\u00EDtulo\n </span>\n </span>\n </div>\n }\n }\n</div>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}.kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block;font-family:var(--kf-font-body)}.kf-skeleton-preset__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,15rem),1fr));gap:var(--kf-space-md)}.kf-skeleton-preset__grid--fixed{grid-template-columns:repeat(var(--kf-skeleton-preset-columns),minmax(0,1fr))}.kf-skeleton-preset__stack{display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__form{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--kf-space-md)}.kf-skeleton-preset__form--two{grid-template-columns:repeat(2,minmax(0,1fr))}@media(max-width:640px){.kf-skeleton-preset__form--two{grid-template-columns:minmax(0,1fr)}}.kf-skeleton-preset__field{display:flex;flex-direction:column;gap:var(--kf-space-xs)}.kf-skeleton-preset__control{display:block;padding:var(--kf-space-sm) var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm)}.kf-skeleton-preset__timeline{--_node: var(--kf-status-node-size, 2.125rem);--_gutter: var(--kf-space-sm);--_pad-y: var(--kf-space-sm);--_line: 2px;display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-heading{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-sm);font-weight:var(--kf-font-weight-title)}.kf-skeleton-preset__timeline-toggle{box-sizing:border-box;padding:6px var(--kf-space-sm);border:1px solid transparent;font-size:.85rem;font-weight:600;border-radius:var(--kf-radius-sm)}@media(max-width:640px),(pointer:coarse){.kf-skeleton-preset__timeline-toggle{min-height:44px}}.kf-skeleton-preset__timeline-list{list-style:none;margin:0;padding:0}.kf-skeleton-preset__timeline-group{position:relative;display:flex;align-items:flex-start;gap:var(--kf-space-md);box-sizing:border-box;min-height:2.75rem;padding:var(--_pad-y) var(--_gutter)}.kf-skeleton-preset__timeline-group:not(:last-child):before{content:\"\";position:absolute;inset-inline-start:calc(var(--_gutter) + var(--_node) / 2 - var(--_line) / 2);top:calc(var(--_pad-y) + var(--_node));bottom:calc(var(--kf-space-xs) - var(--_pad-y));width:var(--_line);background:var(--kf-color-border)}.kf-skeleton-preset__timeline-node{flex:none;width:var(--_node);height:var(--_node);border-radius:50%}.kf-skeleton-preset__timeline-text{flex:1;display:flex;flex-direction:column;justify-content:center;gap:2px;min-width:0;min-height:var(--_node)}.kf-skeleton-preset__timeline-title{font-weight:700;font-size:var(--kf-font-size-body)}.kf-skeleton-preset__timeline-meta{font-size:var(--kf-font-size-body-sm)}.kf-skeleton-preset__header{display:flex;align-items:center;gap:var(--kf-space-md);padding-bottom:var(--kf-space-lg);border-bottom:1px solid var(--kf-color-border)}.kf-skeleton-preset__header-icon{flex:none;width:52px;height:52px;border:1px solid transparent;border-radius:var(--kf-radius-md)}.kf-skeleton-preset__header-heading{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;min-width:0}.kf-skeleton-preset__header-title{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-md);font-weight:var(--kf-font-weight-title);line-height:1.2}.kf-skeleton-preset__header-subtitle{font-size:.9375rem}@media(max-width:900px){.kf-skeleton-preset__header-icon{width:40px;height:40px}.kf-skeleton-preset__header-title{font-size:var(--kf-font-size-title-sm)}.kf-skeleton-preset__header-subtitle{font-size:.8125rem}}\n"], dependencies: [{ kind: "component", type: Card, selector: "kf-card", inputs: ["flush", "gap", "loading"] }, { kind: "component", type: DataTable, selector: "kf-data-table", inputs: ["columns", "rows", "loading", "skeletonRows", "rowKey", "flush", "cardable", "defaultView", "showViewToggle", "cardMinWidth", "render", "cellTemplates", "density", "rowClickable", "rowFocusable", "cellAriaLabel", "ariaLabel", "currentRowKey", "pageSize", "pageSizeOptions", "page", "keepPageOnRowsChange", "itemLabel", "sort", "view"], outputs: ["rowClick", "cellClick", "pageChange", "pageSizeChange", "sortChange", "viewChange"] }, { kind: "component", type: DocumentRow, selector: "kf-document-row", inputs: ["icon", "tone", "title", "meta", "href", "downloadLabel", "pendingLabel", "loading"] }, { kind: "component", type: Skeleton, selector: "kf-skeleton", inputs: ["variant", "width", "height"] }, { kind: "component", type: StatCard, selector: "kf-stat-card", inputs: ["icon", "tone", "value", "label", "note", "bar", "hint", "pressed", "density", "loading", "clickable"], outputs: ["cardClick"] }] });
4277
4611
  }
4278
4612
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SkeletonPreset, decorators: [{
4279
4613
  type: Component,
4280
- args: [{ selector: 'kf-skeleton-preset', imports: [Card, DataTable, DocumentRow, Skeleton, StatCard], template: "<div\n [class]=\"'kf-skeleton-preset kf-skeleton-preset--' + variant()\"\n aria-busy=\"true\"\n [style.--kf-skeleton-preset-columns]=\"columns() ?? null\"\n>\n @if (label()) {\n <span class=\"kf-sr-only\" role=\"status\">{{ label() }}</span>\n }\n @switch (variant()) {\n @case ('kpi-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-stat-card [loading]=\"true\" icon=\"bell\" value=\"0\" label=\"Etiqueta\" note=\"Nota\" />\n }\n </div>\n }\n @case ('card-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-card gap=\"sm\" aria-hidden=\"true\">\n <kf-skeleton variant=\"rect\" height=\"7.5rem\" />\n <kf-skeleton width=\"60%\" height=\"1.25rem\" />\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n </kf-card>\n }\n </div>\n }\n @case ('form') {\n <div\n class=\"kf-skeleton-preset__form\"\n [class.kf-skeleton-preset__form--two]=\"formColumns() === 2\"\n aria-hidden=\"true\"\n >\n @for (i of items(); track i) {\n <div class=\"kf-skeleton-preset__field\">\n <span\n class=\"kf-skeleton-preset__label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Etiqueta\n </span>\n <span class=\"kf-skeleton-preset__control\">\n <span class=\"kf-skeleton-preset__value kf-bone\" style=\"--kf-bone-width: 55%\"\n >Valor</span\n >\n </span>\n </div>\n }\n </div>\n }\n @case ('list') {\n <div class=\"kf-skeleton-preset__stack\">\n @for (i of items(); track i) {\n <kf-document-row [loading]=\"true\" title=\"Documento\" meta=\"Archivo \u00B7 120 KB\" />\n }\n </div>\n }\n @case ('table') {\n <kf-data-table\n [columns]=\"tableColumns()\"\n [rows]=\"[]\"\n [loading]=\"true\"\n [skeletonRows]=\"total()\"\n />\n }\n @case ('timeline') {\n <div class=\"kf-skeleton-preset__timeline\" aria-hidden=\"true\">\n <div class=\"kf-skeleton-preset__timeline-toolbar\">\n <span class=\"kf-skeleton-preset__timeline-heading kf-bone\" style=\"--kf-bone-width: 30%\">\n Etapas\n </span>\n <span class=\"kf-skeleton-preset__timeline-toggle kf-bone\" style=\"--kf-bone-width: 7rem\">\n Expandir todo\n </span>\n </div>\n <ol class=\"kf-skeleton-preset__timeline-list\">\n @for (i of items(); track i) {\n <li class=\"kf-skeleton-preset__timeline-group\">\n <span class=\"kf-skeleton-preset__timeline-node kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__timeline-text\">\n <span\n class=\"kf-skeleton-preset__timeline-title kf-bone\"\n style=\"--kf-bone-width: 45%\"\n >\n Etapa\n </span>\n <span\n class=\"kf-skeleton-preset__timeline-meta kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Detalle\n </span>\n </span>\n </li>\n }\n </ol>\n </div>\n }\n @case ('detail-header') {\n <div class=\"kf-skeleton-preset__header\" aria-hidden=\"true\">\n <span class=\"kf-skeleton-preset__header-icon kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__header-heading\">\n <span class=\"kf-skeleton-preset__header-title kf-bone\" style=\"--kf-bone-width: 40%\">\n T\u00EDtulo\n </span>\n <span class=\"kf-skeleton-preset__header-subtitle kf-bone\" style=\"--kf-bone-width: 60%\">\n Subt\u00EDtulo\n </span>\n </span>\n </div>\n }\n }\n</div>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}.kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block;font-family:var(--kf-font-body)}.kf-skeleton-preset__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,15rem),1fr));gap:var(--kf-space-md)}.kf-skeleton-preset__grid--fixed{grid-template-columns:repeat(var(--kf-skeleton-preset-columns),minmax(0,1fr))}.kf-skeleton-preset__stack{display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__form{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--kf-space-md)}.kf-skeleton-preset__form--two{grid-template-columns:repeat(2,minmax(0,1fr))}@media(max-width:640px){.kf-skeleton-preset__form--two{grid-template-columns:minmax(0,1fr)}}.kf-skeleton-preset__field{display:flex;flex-direction:column;gap:var(--kf-space-xs)}.kf-skeleton-preset__control{display:block;padding:var(--kf-space-sm) var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm)}.kf-skeleton-preset__timeline{--_node: var(--kf-status-node-size, 2.125rem);--_gutter: var(--kf-space-sm);--_pad-y: var(--kf-space-sm);--_line: 2px;display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-heading{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-sm);font-weight:var(--kf-font-weight-title)}.kf-skeleton-preset__timeline-toggle{box-sizing:border-box;padding:6px var(--kf-space-sm);border:1px solid transparent;font-size:.85rem;font-weight:600;border-radius:var(--kf-radius-sm)}@media(max-width:640px),(pointer:coarse){.kf-skeleton-preset__timeline-toggle{min-height:44px}}.kf-skeleton-preset__timeline-list{list-style:none;margin:0;padding:0}.kf-skeleton-preset__timeline-group{position:relative;display:flex;align-items:flex-start;gap:var(--kf-space-md);box-sizing:border-box;min-height:2.75rem;padding:var(--_pad-y) var(--_gutter)}.kf-skeleton-preset__timeline-group:not(:last-child):before{content:\"\";position:absolute;inset-inline-start:calc(var(--_gutter) + var(--_node) / 2 - var(--_line) / 2);top:calc(var(--_pad-y) + var(--_node));bottom:calc(var(--kf-space-xs) - var(--_pad-y));width:var(--_line);background:var(--kf-color-border)}.kf-skeleton-preset__timeline-node{flex:none;width:var(--_node);height:var(--_node);border-radius:50%}.kf-skeleton-preset__timeline-text{flex:1;display:flex;flex-direction:column;justify-content:center;gap:2px;min-width:0;min-height:var(--_node)}.kf-skeleton-preset__timeline-title{font-weight:700;font-size:var(--kf-font-size-body)}.kf-skeleton-preset__timeline-meta{font-size:var(--kf-font-size-body-sm)}.kf-skeleton-preset__header{display:flex;align-items:center;gap:var(--kf-space-md);padding-bottom:var(--kf-space-lg);border-bottom:1px solid var(--kf-color-border)}.kf-skeleton-preset__header-icon{flex:none;width:52px;height:52px;border:1px solid transparent;border-radius:var(--kf-radius-md)}.kf-skeleton-preset__header-heading{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;min-width:0}.kf-skeleton-preset__header-title{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-md);font-weight:var(--kf-font-weight-title);line-height:1.2}.kf-skeleton-preset__header-subtitle{font-size:.9375rem}@media(max-width:900px){.kf-skeleton-preset__header-icon{width:40px;height:40px}.kf-skeleton-preset__header-title{font-size:var(--kf-font-size-title-sm)}.kf-skeleton-preset__header-subtitle{font-size:.8125rem}}\n"] }]
4614
+ args: [{ selector: 'kf-skeleton-preset', imports: [Card, DataTable, DocumentRow, Skeleton, StatCard], template: "<div\n [class]=\"'kf-skeleton-preset kf-skeleton-preset--' + variant()\"\n aria-busy=\"true\"\n [style.--kf-skeleton-preset-columns]=\"columns() ?? null\"\n>\n @if (label()) {\n <span class=\"kf-sr-only\" role=\"status\">{{ label() }}</span>\n }\n @switch (variant()) {\n @case ('kpi-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-stat-card [loading]=\"true\" icon=\"bell\" value=\"0\" label=\"Etiqueta\" note=\"Nota\" />\n }\n </div>\n }\n @case ('card-grid') {\n <div class=\"kf-skeleton-preset__grid\" [class.kf-skeleton-preset__grid--fixed]=\"!!columns()\">\n @for (i of items(); track i) {\n <kf-card gap=\"sm\" aria-hidden=\"true\">\n <kf-skeleton variant=\"rect\" height=\"7.5rem\" />\n <kf-skeleton width=\"60%\" height=\"1.25rem\" />\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n </kf-card>\n }\n </div>\n }\n @case ('form') {\n <div\n class=\"kf-skeleton-preset__form\"\n [class.kf-skeleton-preset__form--two]=\"formColumns() === 2\"\n aria-hidden=\"true\"\n >\n @for (i of items(); track i) {\n <div class=\"kf-skeleton-preset__field\">\n <span\n class=\"kf-skeleton-preset__label kf-overline-text kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Etiqueta\n </span>\n <span class=\"kf-skeleton-preset__control\">\n <span class=\"kf-skeleton-preset__value kf-bone\" style=\"--kf-bone-width: 55%\"\n >Valor</span\n >\n </span>\n </div>\n }\n </div>\n }\n @case ('list') {\n <div class=\"kf-skeleton-preset__stack\">\n @for (i of items(); track i) {\n <kf-document-row [loading]=\"true\" title=\"Documento\" meta=\"Archivo \u00B7 120 KB\" />\n }\n </div>\n }\n @case ('table') {\n <kf-data-table\n [columns]=\"tableColumns()\"\n [rows]=\"[]\"\n [loading]=\"true\"\n [skeletonRows]=\"total()\"\n />\n }\n @case ('timeline') {\n <div class=\"kf-skeleton-preset__timeline\" aria-hidden=\"true\">\n <div class=\"kf-skeleton-preset__timeline-toolbar\">\n <span class=\"kf-skeleton-preset__timeline-heading kf-bone\" style=\"--kf-bone-width: 30%\">\n Etapas\n </span>\n <span class=\"kf-skeleton-preset__timeline-toggle kf-bone\" style=\"--kf-bone-width: 7rem\">\n Expandir todo\n </span>\n </div>\n <ol class=\"kf-skeleton-preset__timeline-list\">\n @for (i of items(); track i) {\n <li class=\"kf-skeleton-preset__timeline-group\">\n <span class=\"kf-skeleton-preset__timeline-node kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__timeline-text\">\n <span\n class=\"kf-skeleton-preset__timeline-title kf-bone\"\n style=\"--kf-bone-width: 45%\"\n >\n Etapa\n </span>\n <span\n class=\"kf-skeleton-preset__timeline-meta kf-bone\"\n style=\"--kf-bone-width: 30%\"\n >\n Detalle\n </span>\n </span>\n </li>\n }\n </ol>\n </div>\n }\n @case ('detail-header') {\n <div class=\"kf-skeleton-preset__header\" aria-hidden=\"true\">\n <span class=\"kf-skeleton-preset__header-icon kf-bone-fill\"></span>\n <span class=\"kf-skeleton-preset__header-heading\">\n <span class=\"kf-skeleton-preset__header-title kf-bone\" style=\"--kf-bone-width: 40%\">\n T\u00EDtulo\n </span>\n <span class=\"kf-skeleton-preset__header-subtitle kf-bone\" style=\"--kf-bone-width: 60%\">\n Subt\u00EDtulo\n </span>\n </span>\n </div>\n }\n }\n</div>\n", styles: [".kf-overline-text{font-family:var(--kf-font-title);font-size:var(--kf-font-size-caption);font-weight:var(--kf-font-weight-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}.kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block;font-family:var(--kf-font-body)}.kf-skeleton-preset__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,15rem),1fr));gap:var(--kf-space-md)}.kf-skeleton-preset__grid--fixed{grid-template-columns:repeat(var(--kf-skeleton-preset-columns),minmax(0,1fr))}.kf-skeleton-preset__stack{display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__form{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--kf-space-md)}.kf-skeleton-preset__form--two{grid-template-columns:repeat(2,minmax(0,1fr))}@media(max-width:640px){.kf-skeleton-preset__form--two{grid-template-columns:minmax(0,1fr)}}.kf-skeleton-preset__field{display:flex;flex-direction:column;gap:var(--kf-space-xs)}.kf-skeleton-preset__control{display:block;padding:var(--kf-space-sm) var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm)}.kf-skeleton-preset__timeline{--_node: var(--kf-status-node-size, 2.125rem);--_gutter: var(--kf-space-sm);--_pad-y: var(--kf-space-sm);--_line: 2px;display:flex;flex-direction:column;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm)}.kf-skeleton-preset__timeline-heading{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-sm);font-weight:var(--kf-font-weight-title)}.kf-skeleton-preset__timeline-toggle{box-sizing:border-box;padding:6px var(--kf-space-sm);border:1px solid transparent;font-size:.85rem;font-weight:600;border-radius:var(--kf-radius-sm)}@media(max-width:640px),(pointer:coarse){.kf-skeleton-preset__timeline-toggle{min-height:44px}}.kf-skeleton-preset__timeline-list{list-style:none;margin:0;padding:0}.kf-skeleton-preset__timeline-group{position:relative;display:flex;align-items:flex-start;gap:var(--kf-space-md);box-sizing:border-box;min-height:2.75rem;padding:var(--_pad-y) var(--_gutter)}.kf-skeleton-preset__timeline-group:not(:last-child):before{content:\"\";position:absolute;inset-inline-start:calc(var(--_gutter) + var(--_node) / 2 - var(--_line) / 2);top:calc(var(--_pad-y) + var(--_node));bottom:calc(var(--kf-space-xs) - var(--_pad-y));width:var(--_line);background:var(--kf-color-border)}.kf-skeleton-preset__timeline-node{flex:none;width:var(--_node);height:var(--_node);border-radius:50%}.kf-skeleton-preset__timeline-text{flex:1;display:flex;flex-direction:column;justify-content:center;gap:2px;min-width:0;min-height:var(--_node)}.kf-skeleton-preset__timeline-title{font-weight:700;font-size:var(--kf-font-size-body)}.kf-skeleton-preset__timeline-meta{font-size:var(--kf-font-size-body-sm)}.kf-skeleton-preset__header{display:flex;align-items:center;gap:var(--kf-space-md);padding-bottom:var(--kf-space-lg);border-bottom:1px solid var(--kf-color-border)}.kf-skeleton-preset__header-icon{flex:none;width:52px;height:52px;border:1px solid transparent;border-radius:var(--kf-radius-md)}.kf-skeleton-preset__header-heading{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;min-width:0}.kf-skeleton-preset__header-title{font-family:var(--kf-font-title);font-size:var(--kf-font-size-title-md);font-weight:var(--kf-font-weight-title);line-height:1.2}.kf-skeleton-preset__header-subtitle{font-size:.9375rem}@media(max-width:900px){.kf-skeleton-preset__header-icon{width:40px;height:40px}.kf-skeleton-preset__header-title{font-size:var(--kf-font-size-title-sm)}.kf-skeleton-preset__header-subtitle{font-size:.8125rem}}\n"] }]
4281
4615
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
4282
4616
 
4283
4617
  /**
@@ -4310,6 +4644,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
4310
4644
  * Las acciones (reintentar, crear) van en el slot `actions` — se ignoran
4311
4645
  * mientras carga, porque no hay nada que reintentar todavía.
4312
4646
  *
4647
+ * Anuncios para lectores de pantalla: al cargar con silueta, `loadingLabel`
4648
+ * se anuncia en una región `status` (con `load="spinner"` ya lo anuncia el
4649
+ * propio `kf-spinner`); un error entra como `role="alert"` (interrumpe) y el
4650
+ * estado vacío como `role="status"` (cortés). `icon` dibuja el glifo de
4651
+ * `kf-empty-state` en esos dos estados.
4652
+ *
4313
4653
  * <kf-content-state [state]="state()" title="No pudimos cargar tus vehículos"
4314
4654
  * subtitle="Revisá tu conexión e intentá de nuevo.">
4315
4655
  * <kf-button actions (click)="retry()">Reintentar</kf-button>
@@ -4342,8 +4682,11 @@ class ContentState {
4342
4682
  ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
4343
4683
  subtitle = input('', /* @ts-ignore */
4344
4684
  ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
4345
- /** Texto de carga: al lado del spinner con `load="spinner"` y, en modo skeleton,
4346
- * texto visualmente oculto con `role="status"` para lectores de pantalla. */
4685
+ /** Glifo de `empty`/`error` (el mismo input de `kf-empty-state`). Sin valor, no se dibuja ícono. */
4686
+ icon = input(/* @ts-ignore */
4687
+ ...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
4688
+ /** Texto de carga: visible al lado del spinner con `load="spinner"` y, en modo
4689
+ * skeleton, texto visualmente oculto con `role="status"` para lectores de pantalla. */
4347
4690
  loadingLabel = input('Cargando…', /* @ts-ignore */
4348
4691
  ...(ngDevMode ? [{ debugName: "loadingLabel" }] : /* istanbul ignore next */ []));
4349
4692
  /** Plantilla propia del esqueleto (reemplaza las tres líneas genéricas). */
@@ -4357,12 +4700,12 @@ class ContentState {
4357
4700
  customLoading = computed(() => this.projectedLoading() ?? this.loadingTemplate(), /* @ts-ignore */
4358
4701
  ...(ngDevMode ? [{ debugName: "customLoading" }] : /* istanbul ignore next */ []));
4359
4702
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ContentState, deps: [], target: i0.ɵɵFactoryTarget.Component });
4360
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ContentState, isStandalone: true, selector: "kf-content-state", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, load: { classPropertyName: "load", publicName: "load", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, loadingLabel: { classPropertyName: "loadingLabel", publicName: "loadingLabel", isSignal: true, isRequired: false, transformFunction: null }, loadingTemplate: { classPropertyName: "loadingTemplate", publicName: "loadingTemplate", isSignal: true, isRequired: false, transformFunction: null }, loadingPreset: { classPropertyName: "loadingPreset", publicName: "loadingPreset", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "projectedLoading", first: true, predicate: ContentStateLoading, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "@switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n <span class=\"kf-sr-only\" role=\"status\">{{ loadingLabel() }}</span>\n @if (customLoading(); as template) {\n <ng-container [ngTemplateOutlet]=\"template\" />\n } @else if (loadingPreset(); as preset) {\n <kf-skeleton-preset [variant]=\"preset\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n }\n </div>\n }\n @default {\n <kf-empty-state [tone]=\"state() === 'error' ? 'error' : 'neutral'\">\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n}\n", styles: [".kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block;font-family:var(--kf-font-body)}.kf-content-state__loading{display:flex;flex-direction:column;gap:var(--kf-space-sm);min-width:min(12rem,100vw);box-sizing:border-box}.kf-content-state__title{margin:0;font-family:var(--kf-font-title);font-weight:700;color:var(--kf-color-ink)}.kf-content-state__subtitle{margin:0;color:var(--kf-color-text-muted)}.kf-content-state__actions:empty{display:none}.kf-content-state__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm)}\n"], dependencies: [{ kind: "component", type: EmptyState, selector: "kf-empty-state", inputs: ["icon", "tone", "variant", "title"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Skeleton, selector: "kf-skeleton", inputs: ["variant", "width", "height"] }, { kind: "component", type: SkeletonPreset, selector: "kf-skeleton-preset", inputs: ["variant", "count", "columns", "label"] }, { kind: "component", type: Spinner, selector: "kf-spinner", inputs: ["size", "label", "onDark"] }] });
4703
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ContentState, isStandalone: true, selector: "kf-content-state", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, load: { classPropertyName: "load", publicName: "load", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, loadingLabel: { classPropertyName: "loadingLabel", publicName: "loadingLabel", isSignal: true, isRequired: false, transformFunction: null }, loadingTemplate: { classPropertyName: "loadingTemplate", publicName: "loadingTemplate", isSignal: true, isRequired: false, transformFunction: null }, loadingPreset: { classPropertyName: "loadingPreset", publicName: "loadingPreset", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "projectedLoading", first: true, predicate: ContentStateLoading, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "@switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n @if (load() === 'skeleton') {\n <!-- Fuera del contenedor `aria-busy`: una regi\u00F3n viva ocupada no anuncia nada. -->\n <span class=\"kf-sr-only\" role=\"status\">{{ loadingLabel() }}</span>\n }\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n @if (customLoading(); as template) {\n <ng-container [ngTemplateOutlet]=\"template\" />\n } @else if (loadingPreset(); as preset) {\n <kf-skeleton-preset [variant]=\"preset\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n }\n </div>\n }\n @default {\n <kf-empty-state\n [tone]=\"state() === 'error' ? 'error' : 'neutral'\"\n [icon]=\"icon()\"\n [attr.role]=\"state() === 'error' ? 'alert' : 'status'\"\n >\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n}\n", styles: [".kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{position:relative;display:block;font-family:var(--kf-font-body)}.kf-content-state__loading{display:flex;flex-direction:column;gap:var(--kf-space-sm);min-width:min(12rem,100vw);box-sizing:border-box}.kf-content-state__title{margin:0;font-family:var(--kf-font-title);font-weight:700;color:var(--kf-color-ink)}.kf-content-state__subtitle{margin:0;color:var(--kf-color-text-muted)}.kf-content-state__actions:empty{display:none}.kf-content-state__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm)}\n"], dependencies: [{ kind: "component", type: EmptyState, selector: "kf-empty-state", inputs: ["icon", "tone", "variant", "title"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Skeleton, selector: "kf-skeleton", inputs: ["variant", "width", "height"] }, { kind: "component", type: SkeletonPreset, selector: "kf-skeleton-preset", inputs: ["variant", "count", "columns", "label"] }, { kind: "component", type: Spinner, selector: "kf-spinner", inputs: ["size", "label", "onDark"] }] });
4361
4704
  }
4362
4705
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ContentState, decorators: [{
4363
4706
  type: Component,
4364
- args: [{ selector: 'kf-content-state', imports: [EmptyState, NgTemplateOutlet, Skeleton, SkeletonPreset, Spinner], template: "@switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n <span class=\"kf-sr-only\" role=\"status\">{{ loadingLabel() }}</span>\n @if (customLoading(); as template) {\n <ng-container [ngTemplateOutlet]=\"template\" />\n } @else if (loadingPreset(); as preset) {\n <kf-skeleton-preset [variant]=\"preset\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n }\n </div>\n }\n @default {\n <kf-empty-state [tone]=\"state() === 'error' ? 'error' : 'neutral'\">\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n}\n", styles: [".kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{display:block;font-family:var(--kf-font-body)}.kf-content-state__loading{display:flex;flex-direction:column;gap:var(--kf-space-sm);min-width:min(12rem,100vw);box-sizing:border-box}.kf-content-state__title{margin:0;font-family:var(--kf-font-title);font-weight:700;color:var(--kf-color-ink)}.kf-content-state__subtitle{margin:0;color:var(--kf-color-text-muted)}.kf-content-state__actions:empty{display:none}.kf-content-state__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm)}\n"] }]
4365
- }], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: true }] }], load: [{ type: i0.Input, args: [{ isSignal: true, alias: "load", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], loadingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingLabel", required: false }] }], loadingTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingTemplate", required: false }] }], loadingPreset: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingPreset", required: false }] }], projectedLoading: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ContentStateLoading), { ...{
4707
+ args: [{ selector: 'kf-content-state', imports: [EmptyState, NgTemplateOutlet, Skeleton, SkeletonPreset, Spinner], template: "@switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n @if (load() === 'skeleton') {\n <!-- Fuera del contenedor `aria-busy`: una regi\u00F3n viva ocupada no anuncia nada. -->\n <span class=\"kf-sr-only\" role=\"status\">{{ loadingLabel() }}</span>\n }\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n @if (customLoading(); as template) {\n <ng-container [ngTemplateOutlet]=\"template\" />\n } @else if (loadingPreset(); as preset) {\n <kf-skeleton-preset [variant]=\"preset\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n }\n </div>\n }\n @default {\n <kf-empty-state\n [tone]=\"state() === 'error' ? 'error' : 'neutral'\"\n [icon]=\"icon()\"\n [attr.role]=\"state() === 'error' ? 'alert' : 'status'\"\n >\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n}\n", styles: [".kf-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}:host{position:relative;display:block;font-family:var(--kf-font-body)}.kf-content-state__loading{display:flex;flex-direction:column;gap:var(--kf-space-sm);min-width:min(12rem,100vw);box-sizing:border-box}.kf-content-state__title{margin:0;font-family:var(--kf-font-title);font-weight:700;color:var(--kf-color-ink)}.kf-content-state__subtitle{margin:0;color:var(--kf-color-text-muted)}.kf-content-state__actions:empty{display:none}.kf-content-state__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm)}\n"] }]
4708
+ }], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: true }] }], load: [{ type: i0.Input, args: [{ isSignal: true, alias: "load", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], loadingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingLabel", required: false }] }], loadingTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingTemplate", required: false }] }], loadingPreset: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingPreset", required: false }] }], projectedLoading: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ContentStateLoading), { ...{
4366
4709
  read: TemplateRef,
4367
4710
  }, isSignal: true }] }] } });
4368
4711
 
@@ -4496,6 +4839,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
4496
4839
  args: ['click', ['$event']]
4497
4840
  }] } });
4498
4841
 
4842
+ /**
4843
+ * Paginador «Anterior / Siguiente» para listas con cursor: no conoce el
4844
+ * número de página, solo si hay una anterior o una siguiente y un resumen ya
4845
+ * armado. Complementa a `kf-pagination`, que exige número de página y total.
4846
+ *
4847
+ * `summary` ("Mostrando 25 de 96") se anuncia en una región `status`. Los
4848
+ * botones usan `aria-disabled` y no `disabled`, para que el foco no se pierda
4849
+ * al llegar a un extremo (un botón `disabled` deja de ser enfocable y el foco
4850
+ * cae al `body`); pulsarlos en ese estado no emite nada.
4851
+ *
4852
+ * Con `pageSizeOptions` agrega el selector "Filas por página"; vacío lo oculta.
4853
+ *
4854
+ * <kf-cursor-pager summary="Mostrando 25 de 96" [hasPrevious]="!!prev()" [hasNext]="!!next()"
4855
+ * [pageSizeOptions]="[25, 50, 100]" [pageSize]="size()"
4856
+ * (previous)="load(prev())" (next)="load(next())" (pageSizeChange)="size.set($event)" />
4857
+ */
4858
+ class CursorPager {
4859
+ /** Texto anunciado y mostrado a la izquierda, p. ej. «Mostrando 25 de 96». */
4860
+ summary = input('', /* @ts-ignore */
4861
+ ...(ngDevMode ? [{ debugName: "summary" }] : /* istanbul ignore next */ []));
4862
+ hasPrevious = input(false, /* @ts-ignore */
4863
+ ...(ngDevMode ? [{ debugName: "hasPrevious" }] : /* istanbul ignore next */ []));
4864
+ hasNext = input(false, /* @ts-ignore */
4865
+ ...(ngDevMode ? [{ debugName: "hasNext" }] : /* istanbul ignore next */ []));
4866
+ /** Opciones del selector de filas por página. Vacío oculta el selector. */
4867
+ pageSizeOptions = input([], /* @ts-ignore */
4868
+ ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
4869
+ pageSize = input(/* @ts-ignore */
4870
+ ...(ngDevMode ? [undefined, { debugName: "pageSize" }] : /* istanbul ignore next */ []));
4871
+ /** Nombre accesible de la navegación. */
4872
+ ariaLabel = input('Paginación', /* @ts-ignore */
4873
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
4874
+ previous = output();
4875
+ next = output();
4876
+ pageSizeChange = output();
4877
+ sizeOptions = computed(() => this.pageSizeOptions().map((size) => ({ value: String(size), label: String(size) })), /* @ts-ignore */
4878
+ ...(ngDevMode ? [{ debugName: "sizeOptions" }] : /* istanbul ignore next */ []));
4879
+ sizeValue = computed(() => String(this.pageSize() ?? ''), /* @ts-ignore */
4880
+ ...(ngDevMode ? [{ debugName: "sizeValue" }] : /* istanbul ignore next */ []));
4881
+ onPrevious() {
4882
+ if (this.hasPrevious()) {
4883
+ this.previous.emit();
4884
+ }
4885
+ }
4886
+ onNext() {
4887
+ if (this.hasNext()) {
4888
+ this.next.emit();
4889
+ }
4890
+ }
4891
+ onPageSize(value) {
4892
+ const size = Number(value);
4893
+ if (Number.isFinite(size) && size !== this.pageSize()) {
4894
+ this.pageSizeChange.emit(size);
4895
+ }
4896
+ }
4897
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CursorPager, deps: [], target: i0.ɵɵFactoryTarget.Component });
4898
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: CursorPager, isStandalone: true, selector: "kf-cursor-pager", inputs: { summary: { classPropertyName: "summary", publicName: "summary", isSignal: true, isRequired: false, transformFunction: null }, hasPrevious: { classPropertyName: "hasPrevious", publicName: "hasPrevious", isSignal: true, isRequired: false, transformFunction: null }, hasNext: { classPropertyName: "hasNext", publicName: "hasNext", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { previous: "previous", next: "next", pageSizeChange: "pageSizeChange" }, ngImport: i0, template: "<div class=\"kf-cursor-pager\">\n <div class=\"kf-cursor-pager__summary\" role=\"status\" aria-live=\"polite\">{{ summary() }}</div>\n\n <div class=\"kf-cursor-pager__controls\">\n @if (sizeOptions().length > 0) {\n <div class=\"kf-cursor-pager__size\">\n <span class=\"kf-cursor-pager__size-label\" aria-hidden=\"true\">Filas</span>\n <kf-select\n variant=\"compact\"\n label=\"Filas por p\u00E1gina\"\n hideLabel\n [options]=\"sizeOptions()\"\n [value]=\"sizeValue()\"\n (valueChange)=\"onPageSize($event)\"\n />\n </div>\n <span class=\"kf-cursor-pager__divider\" aria-hidden=\"true\"></span>\n }\n\n <nav class=\"kf-cursor-pager__nav\" [attr.aria-label]=\"ariaLabel()\">\n <button\n type=\"button\"\n class=\"kf-cursor-pager__button\"\n [attr.aria-disabled]=\"!hasPrevious()\"\n (click)=\"onPrevious()\"\n >\n <kf-icon name=\"chevron-left\" size=\"sm\" />\n Anterior\n </button>\n <button\n type=\"button\"\n class=\"kf-cursor-pager__button kf-cursor-pager__button--next\"\n [attr.aria-disabled]=\"!hasNext()\"\n (click)=\"onNext()\"\n >\n Siguiente\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </button>\n </nav>\n </div>\n</div>\n", styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-cursor-pager{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--kf-space-md)}.kf-cursor-pager__summary{font-size:var(--kf-font-size-body-sm);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-text)}.kf-cursor-pager__summary:empty{display:none}.kf-cursor-pager__controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--kf-space-sm) var(--kf-space-md)}.kf-cursor-pager__size{display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-cursor-pager__size-label{font-size:var(--kf-font-size-body-sm);color:var(--kf-color-text);white-space:nowrap}.kf-cursor-pager__divider{width:1px;height:1.25rem;background:var(--kf-color-border)}.kf-cursor-pager__nav{display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-cursor-pager__button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);min-height:32px;padding:0 var(--kf-space-sm);font:inherit;font-size:var(--kf-font-size-body-sm);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-text);background:transparent;border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-sm);cursor:pointer}.kf-cursor-pager__button:hover:not([aria-disabled=true]){background:var(--kf-color-white);border-color:var(--kf-color-text-muted)}.kf-cursor-pager__button:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-cursor-pager__button[aria-disabled=true]{opacity:.5;cursor:not-allowed}@media(max-width:599.98px){.kf-cursor-pager__controls{width:100%}.kf-cursor-pager__divider{display:none}.kf-cursor-pager__nav{width:100%}.kf-cursor-pager__button{flex:1 1 0;min-height:36px}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "component", type: Select, selector: "kf-select", inputs: ["label", "hideLabel", "prefix", "options", "value", "placeholder", "disabled", "invalid", "errorMessage", "variant", "width", "searchable", "searchThreshold", "ariaLabel", "icon", "panelTitle", "panelWidth"], outputs: ["valueChange"] }] });
4899
+ }
4900
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CursorPager, decorators: [{
4901
+ type: Component,
4902
+ args: [{ selector: 'kf-cursor-pager', imports: [Icon, Select], template: "<div class=\"kf-cursor-pager\">\n <div class=\"kf-cursor-pager__summary\" role=\"status\" aria-live=\"polite\">{{ summary() }}</div>\n\n <div class=\"kf-cursor-pager__controls\">\n @if (sizeOptions().length > 0) {\n <div class=\"kf-cursor-pager__size\">\n <span class=\"kf-cursor-pager__size-label\" aria-hidden=\"true\">Filas</span>\n <kf-select\n variant=\"compact\"\n label=\"Filas por p\u00E1gina\"\n hideLabel\n [options]=\"sizeOptions()\"\n [value]=\"sizeValue()\"\n (valueChange)=\"onPageSize($event)\"\n />\n </div>\n <span class=\"kf-cursor-pager__divider\" aria-hidden=\"true\"></span>\n }\n\n <nav class=\"kf-cursor-pager__nav\" [attr.aria-label]=\"ariaLabel()\">\n <button\n type=\"button\"\n class=\"kf-cursor-pager__button\"\n [attr.aria-disabled]=\"!hasPrevious()\"\n (click)=\"onPrevious()\"\n >\n <kf-icon name=\"chevron-left\" size=\"sm\" />\n Anterior\n </button>\n <button\n type=\"button\"\n class=\"kf-cursor-pager__button kf-cursor-pager__button--next\"\n [attr.aria-disabled]=\"!hasNext()\"\n (click)=\"onNext()\"\n >\n Siguiente\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </button>\n </nav>\n </div>\n</div>\n", styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-cursor-pager{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--kf-space-md)}.kf-cursor-pager__summary{font-size:var(--kf-font-size-body-sm);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-text)}.kf-cursor-pager__summary:empty{display:none}.kf-cursor-pager__controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--kf-space-sm) var(--kf-space-md)}.kf-cursor-pager__size{display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-cursor-pager__size-label{font-size:var(--kf-font-size-body-sm);color:var(--kf-color-text);white-space:nowrap}.kf-cursor-pager__divider{width:1px;height:1.25rem;background:var(--kf-color-border)}.kf-cursor-pager__nav{display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-cursor-pager__button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);min-height:32px;padding:0 var(--kf-space-sm);font:inherit;font-size:var(--kf-font-size-body-sm);font-weight:var(--kf-font-weight-medium);color:var(--kf-color-text);background:transparent;border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-sm);cursor:pointer}.kf-cursor-pager__button:hover:not([aria-disabled=true]){background:var(--kf-color-white);border-color:var(--kf-color-text-muted)}.kf-cursor-pager__button:focus-visible{outline:2px solid transparent;box-shadow:var(--kf-shadow-focus)}.kf-cursor-pager__button[aria-disabled=true]{opacity:.5;cursor:not-allowed}@media(max-width:599.98px){.kf-cursor-pager__controls{width:100%}.kf-cursor-pager__divider{display:none}.kf-cursor-pager__nav{width:100%}.kf-cursor-pager__button{flex:1 1 0;min-height:36px}}\n"] }]
4903
+ }], propDecorators: { summary: [{ type: i0.Input, args: [{ isSignal: true, alias: "summary", required: false }] }], hasPrevious: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasPrevious", required: false }] }], hasNext: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasNext", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], previous: [{ type: i0.Output, args: ["previous"] }], next: [{ type: i0.Output, args: ["next"] }], pageSizeChange: [{ type: i0.Output, args: ["pageSizeChange"] }] } });
4904
+
4499
4905
  /**
4500
4906
  * Signal con la vista de `kf-data-table` ('table' | 'cards') derivada de un
4501
4907
  * breakpoint — mismo criterio que cualquier tabla con muchas columnas: bajo
@@ -4886,11 +5292,11 @@ class DropdownItem {
4886
5292
  */
4887
5293
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4888
5294
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
4889
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DropdownItem, isStandalone: true, selector: "kf-dropdown-item", inputs: { tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"kf-dropdown-item\"\n [class.kf-dropdown-item--error]=\"tone() === 'error'\"\n [disabled]=\"disabled()\"\n role=\"menuitem\"\n>\n @if (icon()) {\n <kf-icon [name]=\"icon()!\" size=\"sm\" />\n }\n <span class=\"kf-dropdown-item__label\"><ng-content /></span>\n</button>\n", styles: [":host{display:block}.kf-dropdown-item{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);border:none;background:transparent;font:inherit;text-align:left;color:var(--kf-color-text);cursor:pointer}.kf-dropdown-item kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-dropdown-item__label{flex:1 1 auto}.kf-dropdown-item:hover{background:var(--kf-color-surface)}.kf-dropdown-item:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-dropdown-item:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.kf-dropdown-item--error{color:var(--kf-color-error-strong)}.kf-dropdown-item--error kf-icon{color:var(--kf-color-error-strong)}.kf-dropdown-item--error:hover{background:var(--kf-color-error-soft)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item{color:#ffffffd9}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item kf-icon{color:#ffffff8c}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item:hover{background:#ffffff14}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error kf-icon{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error:hover{background:#bc454529}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
5295
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DropdownItem, isStandalone: true, selector: "kf-dropdown-item", inputs: { tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"kf-dropdown-item\"\n [class.kf-dropdown-item--error]=\"tone() === 'error'\"\n [disabled]=\"disabled()\"\n role=\"menuitem\"\n>\n @if (icon()) {\n <kf-icon [name]=\"icon()!\" size=\"sm\" />\n }\n <span class=\"kf-dropdown-item__label\"><ng-content /></span>\n</button>\n", styles: [":host{display:block}.kf-dropdown-item{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);border:none;background:transparent;font:inherit;text-align:left;color:var(--kf-color-text);cursor:pointer}.kf-dropdown-item kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-dropdown-item__label{flex:1 1 auto}.kf-dropdown-item:hover{background:var(--kf-color-surface)}.kf-dropdown-item:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus-inset)}.kf-dropdown-item:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.kf-dropdown-item--error{color:var(--kf-color-error-strong)}.kf-dropdown-item--error kf-icon{color:var(--kf-color-error-strong)}.kf-dropdown-item--error:hover{background:var(--kf-color-error-soft)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item{color:#ffffffd9}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item kf-icon{color:#ffffff8c}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item:hover{background:#ffffff14}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error kf-icon{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error:hover{background:#bc454529}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
4890
5296
  }
4891
5297
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DropdownItem, decorators: [{
4892
5298
  type: Component,
4893
- args: [{ selector: 'kf-dropdown-item', imports: [Icon], template: "<button\n type=\"button\"\n class=\"kf-dropdown-item\"\n [class.kf-dropdown-item--error]=\"tone() === 'error'\"\n [disabled]=\"disabled()\"\n role=\"menuitem\"\n>\n @if (icon()) {\n <kf-icon [name]=\"icon()!\" size=\"sm\" />\n }\n <span class=\"kf-dropdown-item__label\"><ng-content /></span>\n</button>\n", styles: [":host{display:block}.kf-dropdown-item{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);border:none;background:transparent;font:inherit;text-align:left;color:var(--kf-color-text);cursor:pointer}.kf-dropdown-item kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-dropdown-item__label{flex:1 1 auto}.kf-dropdown-item:hover{background:var(--kf-color-surface)}.kf-dropdown-item:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-dropdown-item:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.kf-dropdown-item--error{color:var(--kf-color-error-strong)}.kf-dropdown-item--error kf-icon{color:var(--kf-color-error-strong)}.kf-dropdown-item--error:hover{background:var(--kf-color-error-soft)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item{color:#ffffffd9}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item kf-icon{color:#ffffff8c}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item:hover{background:#ffffff14}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error kf-icon{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error:hover{background:#bc454529}\n"] }]
5299
+ args: [{ selector: 'kf-dropdown-item', imports: [Icon], template: "<button\n type=\"button\"\n class=\"kf-dropdown-item\"\n [class.kf-dropdown-item--error]=\"tone() === 'error'\"\n [disabled]=\"disabled()\"\n role=\"menuitem\"\n>\n @if (icon()) {\n <kf-icon [name]=\"icon()!\" size=\"sm\" />\n }\n <span class=\"kf-dropdown-item__label\"><ng-content /></span>\n</button>\n", styles: [":host{display:block}.kf-dropdown-item{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);border:none;background:transparent;font:inherit;text-align:left;color:var(--kf-color-text);cursor:pointer}.kf-dropdown-item kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-dropdown-item__label{flex:1 1 auto}.kf-dropdown-item:hover{background:var(--kf-color-surface)}.kf-dropdown-item:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus-inset)}.kf-dropdown-item:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.kf-dropdown-item--error{color:var(--kf-color-error-strong)}.kf-dropdown-item--error kf-icon{color:var(--kf-color-error-strong)}.kf-dropdown-item--error:hover{background:var(--kf-color-error-soft)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item{color:#ffffffd9}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item kf-icon{color:#ffffff8c}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item:hover{background:#ffffff14}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error kf-icon{color:var(--kf-color-error)}:host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error:hover{background:#bc454529}\n"] }]
4894
5300
  }], propDecorators: { tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
4895
5301
 
4896
5302
  /**
@@ -5288,7 +5694,7 @@ class FileInput {
5288
5694
  useExisting: forwardRef(() => FileInput),
5289
5695
  multi: true,
5290
5696
  },
5291
- ], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<div\n class=\"kf-file-input__area\"\n [class.kf-file-input__area--dropzone]=\"dropzone()\"\n [class.kf-file-input__area--dragging]=\"dragging()\"\n [class.kf-file-input__area--invalid]=\"isInvalid()\"\n [class.kf-file-input__area--disabled]=\"isDisabled()\"\n (dragover)=\"dropzone() ? onDragOver($event) : null\"\n (dragleave)=\"dropzone() ? onDragLeave() : null\"\n (drop)=\"dropzone() ? onDrop($event) : null\"\n>\n <input\n #nativeInput\n type=\"file\"\n class=\"kf-file-input__native\"\n [id]=\"inputId\"\n [attr.accept]=\"accept() || null\"\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required() && !files().length\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"isInvalid() ? true : null\"\n [attr.aria-label]=\"label() ? null : ariaLabel() || null\"\n (change)=\"onPick($event)\"\n />\n <label class=\"kf-file-input__button\" [for]=\"inputId\" aria-hidden=\"true\">\n <kf-icon name=\"upload-cloud\" size=\"sm\" />\n {{ triggerText() }}\n </label>\n @if (dropzone()) {\n <span class=\"kf-file-input__drop-text\" aria-hidden=\"true\">{{ dropzoneText() }}</span>\n }\n</div>\n@if (files().length) {\n <ul class=\"kf-file-input__files\" [id]=\"filesId\">\n @for (file of files(); track $index) {\n <li class=\"kf-file-input__file\">\n <kf-icon class=\"kf-file-input__file-icon\" name=\"file\" size=\"sm\" />\n <span class=\"kf-file-input__file-name\">{{ file.name }}</span>\n <span class=\"kf-file-input__file-size\">{{ formatSize(file) }}</span>\n <button\n type=\"button\"\n class=\"kf-file-input__remove\"\n [attr.aria-label]=\"removeLabel() + ' ' + file.name\"\n [disabled]=\"isDisabled()\"\n (click)=\"remove($index)\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n </li>\n }\n </ul>\n}\n@if (message(); as text) {\n <span class=\"kf-file-input__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ text }}</span>\n}\n@if (effectiveHint() && !error()) {\n <span class=\"kf-file-input__hint kf-field-hint\" [id]=\"hintId\">{{ effectiveHint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-file-input__area{position:relative;display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-file-input__native{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}.kf-file-input__native:disabled{cursor:not-allowed}.kf-file-input__button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);min-height:2.25rem;padding:var(--kf-space-sm) var(--kf-space-md);box-sizing:border-box;border:1px solid var(--kf-color-primary);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-primary-active);font:inherit;font-weight:600;pointer-events:none;transition:background .14s,box-shadow .14s}.kf-file-input__area:hover .kf-file-input__native:not(:disabled)+.kf-file-input__button{background:var(--kf-color-primary-soft)}.kf-file-input__native:focus-visible+.kf-file-input__button{box-shadow:var(--kf-shadow-focus);outline:2px solid transparent}.kf-file-input__area--invalid .kf-file-input__button{border-color:var(--kf-color-error);color:var(--kf-color-error-strong)}.kf-file-input__area--invalid .kf-file-input__native:focus-visible+.kf-file-input__button{box-shadow:var(--kf-shadow-focus-error)}.kf-file-input__area--disabled{opacity:.5}.kf-file-input__area--dropzone{flex-direction:column;justify-content:center;gap:var(--kf-space-xs);padding:var(--kf-space-lg) var(--kf-space-md);border:1px dashed var(--kf-color-border-strong);border-radius:var(--kf-radius-sm);background:var(--kf-color-surface);transition:background .14s,border-color .14s}.kf-file-input__area--dragging{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft)}.kf-file-input__area--dropzone.kf-file-input__area--invalid{border-color:var(--kf-color-error)}.kf-file-input__drop-text{font-size:.875rem;color:var(--kf-color-text);pointer-events:none}.kf-file-input__files{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--kf-space-xs)}.kf-file-input__file{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-xs) var(--kf-space-sm);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);min-width:0}.kf-file-input__file-icon{flex:none;color:var(--kf-color-text-muted)}.kf-file-input__file-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--kf-color-ink);font-weight:600}.kf-file-input__file-size{flex:none;font-size:.75rem;color:var(--kf-color-text)}.kf-file-input__remove{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;padding:0;border:none;border-radius:var(--kf-radius-xs);background:transparent;color:var(--kf-color-text);cursor:pointer}.kf-file-input__remove:hover:not(:disabled){background:var(--kf-color-surface);color:var(--kf-color-ink)}.kf-file-input__remove:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-file-input__hint{color:var(--kf-color-text)}@media(pointer:coarse),(max-width:760px){.kf-file-input__button{min-height:44px}.kf-file-input__remove{min-width:44px;min-height:44px}}\n"], dependencies: [{ kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5697
+ ], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<div\n class=\"kf-file-input__area\"\n [class.kf-file-input__area--dropzone]=\"dropzone()\"\n [class.kf-file-input__area--dragging]=\"dragging()\"\n [class.kf-file-input__area--invalid]=\"isInvalid()\"\n [class.kf-file-input__area--disabled]=\"isDisabled()\"\n (dragover)=\"dropzone() ? onDragOver($event) : null\"\n (dragleave)=\"dropzone() ? onDragLeave() : null\"\n (drop)=\"dropzone() ? onDrop($event) : null\"\n>\n <input\n #nativeInput\n type=\"file\"\n class=\"kf-file-input__native\"\n [id]=\"inputId\"\n [attr.accept]=\"accept() || null\"\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required() && !files().length\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"isInvalid() ? true : null\"\n [attr.aria-label]=\"label() ? null : ariaLabel() || null\"\n (change)=\"onPick($event)\"\n />\n <label class=\"kf-file-input__button\" [for]=\"inputId\" aria-hidden=\"true\">\n <kf-icon name=\"upload-cloud\" size=\"sm\" />\n {{ triggerText() }}\n </label>\n @if (dropzone()) {\n <span class=\"kf-file-input__drop-text\" aria-hidden=\"true\">{{ dropzoneText() }}</span>\n }\n</div>\n@if (files().length) {\n <ul class=\"kf-file-input__files\" [id]=\"filesId\">\n @for (file of files(); track $index) {\n <li class=\"kf-file-input__file\">\n <kf-icon class=\"kf-file-input__file-icon\" name=\"file\" size=\"sm\" />\n <span class=\"kf-file-input__file-name\">{{ file.name }}</span>\n <span class=\"kf-file-input__file-size\">{{ formatSize(file) }}</span>\n <button\n type=\"button\"\n class=\"kf-file-input__remove\"\n [attr.aria-label]=\"removeLabel() + ' ' + file.name\"\n [disabled]=\"isDisabled()\"\n (click)=\"remove($index)\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n </li>\n }\n </ul>\n}\n@if (message(); as text) {\n <span class=\"kf-file-input__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ text }}</span>\n}\n@if (effectiveHint() && !error()) {\n <span class=\"kf-file-input__hint kf-field-hint\" [id]=\"hintId\">{{ effectiveHint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-file-input__area{position:relative;display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-file-input__native{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}.kf-file-input__native:disabled{cursor:not-allowed}.kf-file-input__button{display:inline-flex;align-items:center;justify-content:center;gap:var(--kf-space-xs);min-height:2.25rem;padding:var(--kf-space-sm) var(--kf-space-md);box-sizing:border-box;border:1px solid var(--kf-color-primary);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-primary-active);font:inherit;font-weight:600;pointer-events:none;transition:background .14s,box-shadow .14s}.kf-file-input__area:hover .kf-file-input__native:not(:disabled)+.kf-file-input__button{background:var(--kf-color-primary-soft)}.kf-file-input__native:focus-visible+.kf-file-input__button{box-shadow:var(--kf-shadow-focus);outline:2px solid transparent}.kf-file-input__area--invalid .kf-file-input__button{border-color:var(--kf-color-error);color:var(--kf-color-error-strong)}.kf-file-input__area--invalid .kf-file-input__native:focus-visible+.kf-file-input__button{box-shadow:var(--kf-shadow-focus-error)}.kf-file-input__area--disabled{opacity:.5}.kf-file-input__area--dropzone{flex-direction:column;justify-content:center;gap:var(--kf-space-xs);padding:var(--kf-space-lg) var(--kf-space-md);border:1px dashed var(--kf-color-border-strong);border-radius:var(--kf-radius-sm);background:var(--kf-color-surface);transition:background .14s,border-color .14s}.kf-file-input__area--dragging{border-color:var(--kf-color-primary);background:var(--kf-color-primary-soft)}.kf-file-input__area--dropzone.kf-file-input__area--invalid{border-color:var(--kf-color-error)}.kf-file-input__drop-text{font-size:.875rem;color:var(--kf-color-text);pointer-events:none}.kf-file-input__files{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--kf-space-xs)}.kf-file-input__file{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-xs) var(--kf-space-sm);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);min-width:0}.kf-file-input__file-icon{flex:none;color:var(--kf-color-text-muted)}.kf-file-input__file-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--kf-color-ink);font-weight:600}.kf-file-input__file-size{flex:none;font-size:.75rem;color:var(--kf-color-text)}.kf-file-input__remove{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;padding:0;border:none;border-radius:var(--kf-radius-xs);background:transparent;color:var(--kf-color-text);cursor:pointer}.kf-file-input__remove:hover:not(:disabled){background:var(--kf-color-surface);color:var(--kf-color-ink)}.kf-file-input__remove:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-file-input__hint{color:var(--kf-color-text)}@media(pointer:coarse),(max-width:760px){.kf-file-input__button{min-height:44px}.kf-file-input__remove{min-width:44px;min-height:44px}}\n"], dependencies: [{ kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required", "visuallyHidden"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5292
5698
  }
5293
5699
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FileInput, decorators: [{
5294
5700
  type: Component,
@@ -5394,6 +5800,8 @@ class Input {
5394
5800
  ...(ngDevMode ? [{ debugName: "nativeInput" }] : /* istanbul ignore next */ []));
5395
5801
  label = input(/* @ts-ignore */
5396
5802
  ...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
5803
+ /** Oculta el `label` a la vista y lo deja como nombre accesible (`<label for>`), sin ocultarlo con CSS desde afuera. */
5804
+ hideLabel = input(false, { ...(ngDevMode ? { debugName: "hideLabel" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
5397
5805
  /** Marca el label con un asterisco visual y aplica `required` al `<input>`
5398
5806
  * nativo — el atributo HTML ya expone el estado obligatorio a lectores de
5399
5807
  * pantalla (mapeo implícito a `aria-required`), sin necesidad de un
@@ -5553,13 +5961,13 @@ class Input {
5553
5961
  this.passwordVisible.update((visible) => !visible);
5554
5962
  }
5555
5963
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Input, deps: [], target: i0.ɵɵFactoryTarget.Component });
5556
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Input, isStandalone: true, selector: "kf-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, inputmode: { classPropertyName: "inputmode", publicName: "inputmode", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, toggleable: { classPropertyName: "toggleable", publicName: "toggleable", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cleared: "cleared" }, providers: [
5964
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Input, isStandalone: true, selector: "kf-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, inputmode: { classPropertyName: "inputmode", publicName: "inputmode", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, toggleable: { classPropertyName: "toggleable", publicName: "toggleable", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cleared: "cleared" }, providers: [
5557
5965
  {
5558
5966
  provide: NG_VALUE_ACCESSOR,
5559
5967
  useExisting: forwardRef(() => Input),
5560
5968
  multi: true,
5561
5969
  },
5562
- ], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--readonly]=\"readonly()\"\n [class.kf-input__field--focused]=\"focused()\"\n [class.kf-input__field--invalid]=\"invalid()\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-input__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.name]=\"name() || null\"\n [attr.inputmode]=\"inputmode() || null\"\n [attr.min]=\"min()\"\n [attr.max]=\"max()\"\n [attr.step]=\"step()\"\n [attr.maxlength]=\"maxlength()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [attr.aria-label]=\"label() ? null : ariaLabel() || null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kf-input__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onClear()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n }\n @if (showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"kf-input__toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Ocultar contrase\u00F1a' : 'Mostrar contrase\u00F1a'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"onTogglePasswordVisibility()\"\n >\n <kf-icon [name]=\"passwordVisible() ? 'eye-off' : 'eye'\" size=\"sm\" />\n </button>\n } @else if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n</div>\n@if (errorMessage(); as message) {\n <span class=\"kf-input__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-input__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-input__field{display:flex;align-items:center;gap:var(--kf-space-sm);padding:0 var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-input__field--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-input__field--invalid{border-color:var(--kf-color-error)}.kf-input__field--invalid.kf-input__field--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-input__field--disabled{opacity:.5}.kf-input__field--readonly{background:var(--kf-color-gray-100)}.kf-input__control:read-only{cursor:default}.kf-input__icon{color:var(--kf-color-text-muted)}.kf-input__field--invalid .kf-input__icon{color:var(--kf-color-error)}.kf-input__control{flex:1;min-width:0;border:none;outline:none;background:transparent;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) 0}.kf-input__control::placeholder{color:var(--kf-color-text-muted)}.kf-input__control:disabled{cursor:not-allowed}.kf-input__suffix{flex:none;color:var(--kf-color-text-muted);font-size:.875rem}.kf-input__control::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}.kf-input__clear,.kf-input__toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:var(--kf-space-xs);margin:0 calc(var(--kf-space-xs) * -1);color:var(--kf-color-text-muted);cursor:pointer;border-radius:var(--kf-radius-xs);transition:color .14s}.kf-input__clear:hover,.kf-input__toggle:hover{color:var(--kf-color-text)}.kf-input__clear:focus-visible,.kf-input__toggle:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5970
+ ], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\" [visuallyHidden]=\"hideLabel()\">{{\n label()\n }}</kf-field-label>\n}\n<div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--readonly]=\"readonly()\"\n [class.kf-input__field--focused]=\"focused()\"\n [class.kf-input__field--invalid]=\"invalid()\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-input__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.name]=\"name() || null\"\n [attr.inputmode]=\"inputmode() || null\"\n [attr.min]=\"min()\"\n [attr.max]=\"max()\"\n [attr.step]=\"step()\"\n [attr.maxlength]=\"maxlength()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [attr.aria-label]=\"label() ? null : ariaLabel() || null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kf-input__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onClear()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n }\n @if (showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"kf-input__toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Ocultar contrase\u00F1a' : 'Mostrar contrase\u00F1a'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"onTogglePasswordVisibility()\"\n >\n <kf-icon [name]=\"passwordVisible() ? 'eye-off' : 'eye'\" size=\"sm\" />\n </button>\n } @else if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n</div>\n@if (errorMessage(); as message) {\n <span class=\"kf-input__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-input__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-input__field{display:flex;align-items:center;gap:var(--kf-space-sm);padding:0 var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-input__field--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-input__field--invalid{border-color:var(--kf-color-error)}.kf-input__field--invalid.kf-input__field--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-input__field--disabled{opacity:.5}.kf-input__field--readonly{background:var(--kf-color-gray-100)}.kf-input__control:read-only{cursor:default}.kf-input__icon{color:var(--kf-color-text-muted)}.kf-input__field--invalid .kf-input__icon{color:var(--kf-color-error)}.kf-input__control{flex:1;min-width:0;border:none;outline:none;background:transparent;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) 0}.kf-input__control::placeholder{color:var(--kf-color-text-muted)}.kf-input__control:disabled{cursor:not-allowed}.kf-input__suffix{flex:none;color:var(--kf-color-text-muted);font-size:.875rem}.kf-input__control::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}.kf-input__clear,.kf-input__toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:var(--kf-space-xs);margin:0 calc(var(--kf-space-xs) * -1);color:var(--kf-color-text-muted);cursor:pointer;border-radius:var(--kf-radius-xs);transition:color .14s}.kf-input__clear:hover,.kf-input__toggle:hover{color:var(--kf-color-text)}.kf-input__clear:focus-visible,.kf-input__toggle:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required", "visuallyHidden"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5563
5971
  }
5564
5972
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Input, decorators: [{
5565
5973
  type: Component,
@@ -5569,8 +5977,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
5569
5977
  useExisting: forwardRef(() => Input),
5570
5978
  multi: true,
5571
5979
  },
5572
- ], template: "@if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--readonly]=\"readonly()\"\n [class.kf-input__field--focused]=\"focused()\"\n [class.kf-input__field--invalid]=\"invalid()\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-input__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.name]=\"name() || null\"\n [attr.inputmode]=\"inputmode() || null\"\n [attr.min]=\"min()\"\n [attr.max]=\"max()\"\n [attr.step]=\"step()\"\n [attr.maxlength]=\"maxlength()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [attr.aria-label]=\"label() ? null : ariaLabel() || null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kf-input__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onClear()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n }\n @if (showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"kf-input__toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Ocultar contrase\u00F1a' : 'Mostrar contrase\u00F1a'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"onTogglePasswordVisibility()\"\n >\n <kf-icon [name]=\"passwordVisible() ? 'eye-off' : 'eye'\" size=\"sm\" />\n </button>\n } @else if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n</div>\n@if (errorMessage(); as message) {\n <span class=\"kf-input__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-input__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-input__field{display:flex;align-items:center;gap:var(--kf-space-sm);padding:0 var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-input__field--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-input__field--invalid{border-color:var(--kf-color-error)}.kf-input__field--invalid.kf-input__field--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-input__field--disabled{opacity:.5}.kf-input__field--readonly{background:var(--kf-color-gray-100)}.kf-input__control:read-only{cursor:default}.kf-input__icon{color:var(--kf-color-text-muted)}.kf-input__field--invalid .kf-input__icon{color:var(--kf-color-error)}.kf-input__control{flex:1;min-width:0;border:none;outline:none;background:transparent;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) 0}.kf-input__control::placeholder{color:var(--kf-color-text-muted)}.kf-input__control:disabled{cursor:not-allowed}.kf-input__suffix{flex:none;color:var(--kf-color-text-muted);font-size:.875rem}.kf-input__control::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}.kf-input__clear,.kf-input__toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:var(--kf-space-xs);margin:0 calc(var(--kf-space-xs) * -1);color:var(--kf-color-text-muted);cursor:pointer;border-radius:var(--kf-radius-xs);transition:color .14s}.kf-input__clear:hover,.kf-input__toggle:hover{color:var(--kf-color-text)}.kf-input__clear:focus-visible,.kf-input__toggle:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}\n"] }]
5573
- }], propDecorators: { nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], inputmode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputmode", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], toggleable: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleable", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], cleared: [{ type: i0.Output, args: ["cleared"] }] } });
5980
+ ], template: "@if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\" [visuallyHidden]=\"hideLabel()\">{{\n label()\n }}</kf-field-label>\n}\n<div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--readonly]=\"readonly()\"\n [class.kf-input__field--focused]=\"focused()\"\n [class.kf-input__field--invalid]=\"invalid()\"\n>\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-input__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [attr.autocomplete]=\"autocomplete() || null\"\n [attr.name]=\"name() || null\"\n [attr.inputmode]=\"inputmode() || null\"\n [attr.min]=\"min()\"\n [attr.max]=\"max()\"\n [attr.step]=\"step()\"\n [attr.maxlength]=\"maxlength()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [attr.aria-label]=\"label() ? null : ariaLabel() || null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"kf-input__clear\"\n [attr.aria-label]=\"clearLabel()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onClear()\"\n >\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n }\n @if (showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"kf-input__toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Ocultar contrase\u00F1a' : 'Mostrar contrase\u00F1a'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"onTogglePasswordVisibility()\"\n >\n <kf-icon [name]=\"passwordVisible() ? 'eye-off' : 'eye'\" size=\"sm\" />\n </button>\n } @else if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n</div>\n@if (errorMessage(); as message) {\n <span class=\"kf-input__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-input__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-input__field{display:flex;align-items:center;gap:var(--kf-space-sm);padding:0 var(--kf-space-sm);background:var(--kf-color-surface);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-input__field--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus)}.kf-input__field--invalid{border-color:var(--kf-color-error)}.kf-input__field--invalid.kf-input__field--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-input__field--disabled{opacity:.5}.kf-input__field--readonly{background:var(--kf-color-gray-100)}.kf-input__control:read-only{cursor:default}.kf-input__icon{color:var(--kf-color-text-muted)}.kf-input__field--invalid .kf-input__icon{color:var(--kf-color-error)}.kf-input__control{flex:1;min-width:0;border:none;outline:none;background:transparent;font:inherit;color:var(--kf-color-text);padding:var(--kf-space-sm) 0}.kf-input__control::placeholder{color:var(--kf-color-text-muted)}.kf-input__control:disabled{cursor:not-allowed}.kf-input__suffix{flex:none;color:var(--kf-color-text-muted);font-size:.875rem}.kf-input__control::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}.kf-input__clear,.kf-input__toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:var(--kf-space-xs);margin:0 calc(var(--kf-space-xs) * -1);color:var(--kf-color-text-muted);cursor:pointer;border-radius:var(--kf-radius-xs);transition:color .14s}.kf-input__clear:hover,.kf-input__toggle:hover{color:var(--kf-color-text)}.kf-input__clear:focus-visible,.kf-input__toggle:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}\n"] }]
5981
+ }], propDecorators: { nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hideLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideLabel", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], inputmode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputmode", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], toggleable: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleable", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], cleared: [{ type: i0.Output, args: ["cleared"] }] } });
5574
5982
 
5575
5983
  let nextId$1 = 0;
5576
5984
  /**
@@ -5763,7 +6171,7 @@ class MultiSelect {
5763
6171
  return true;
5764
6172
  }
5765
6173
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MultiSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
5766
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: MultiSelect, isStandalone: true, selector: "kf-multi-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchThreshold: { classPropertyName: "searchThreshold", publicName: "searchThreshold", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valuesChange: "valuesChange" }, host: { properties: { "class.kf-multi-select--width-sm": "width() === 'sm'", "class.kf-multi-select--width-lg": "width() === 'lg'", "class.kf-multi-select--width-full": "width() === 'full'" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }, { propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n>\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret kf-caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n<ng-template #panelTemplate>\n <div class=\"kf-multi-select__panel\">\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-multi-select__search\"\n placeholder=\"Buscar\u2026\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); toggleActive()\"\n />\n }\n <ul\n class=\"kf-multi-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n [class.kf-multi-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n @if (options().length > 0) {\n <li class=\"kf-multi-select__empty\">Sin resultados</li>\n } @else {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);font:inherit;width:var(--kf-select-width-md)}:host(.kf-multi-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-multi-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-multi-select--width-full){width:100%}.kf-multi-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-multi-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-multi-select__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-multi-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:left}.kf-multi-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-multi-select__count{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 5px;border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.72rem;font-weight:700}.kf-multi-select__panel{box-sizing:border-box;width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-multi-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-multi-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-multi-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-multi-select__list::-webkit-scrollbar{width:6px}.kf-multi-select__list::-webkit-scrollbar-track{background:transparent}.kf-multi-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-multi-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-multi-select__option{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-multi-select__option:hover{background:var(--kf-color-primary-soft)}.kf-multi-select__option--selected{color:var(--kf-color-primary);font-weight:600}.kf-multi-select__option--active{background:var(--kf-color-primary-soft)}.kf-multi-select__checkbox{display:inline-flex}.kf-multi-select__checkbox--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--checked:after{content:\"\";position:absolute;left:4px;top:1px;width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg)}.kf-multi-select__checkbox--indeterminate{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--indeterminate:after{content:\"\";position:absolute;left:3px;top:6px;width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }] });
6174
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: MultiSelect, isStandalone: true, selector: "kf-multi-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchThreshold: { classPropertyName: "searchThreshold", publicName: "searchThreshold", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valuesChange: "valuesChange" }, host: { properties: { "class.kf-multi-select--width-sm": "width() === 'sm'", "class.kf-multi-select--width-lg": "width() === 'lg'", "class.kf-multi-select--width-full": "width() === 'full'" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panelTemplate", first: true, predicate: ["panelTemplate"], descendants: true, isSignal: true }, { propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n>\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret kf-caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n<ng-template #panelTemplate>\n <div class=\"kf-multi-select__panel\">\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-multi-select__search\"\n placeholder=\"Buscar\u2026\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); toggleActive()\"\n />\n }\n <ul\n class=\"kf-multi-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n [class.kf-multi-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n @if (options().length > 0) {\n <li class=\"kf-multi-select__empty\">Sin resultados</li>\n } @else {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);font:inherit;width:var(--kf-select-width-md)}:host(.kf-multi-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-multi-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-multi-select--width-full){width:100%}.kf-multi-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-multi-select__trigger:hover:not(:disabled){border-color:var(--kf-color-text-muted)}.kf-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-multi-select__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-multi-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:left}.kf-multi-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-multi-select__count{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 5px;border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.72rem;font-weight:700}.kf-multi-select__panel{box-sizing:border-box;width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-multi-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-multi-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-multi-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-multi-select__list::-webkit-scrollbar{width:6px}.kf-multi-select__list::-webkit-scrollbar-track{background:transparent}.kf-multi-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-multi-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-multi-select__option{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-multi-select__option:hover{background:var(--kf-color-primary-soft)}.kf-multi-select__option--selected{color:var(--kf-color-primary);font-weight:600}.kf-multi-select__option--active{background:var(--kf-color-primary-soft)}.kf-multi-select__checkbox{display:inline-flex}.kf-multi-select__checkbox--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--checked:after{content:\"\";position:absolute;left:4px;top:1px;width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg)}.kf-multi-select__checkbox--indeterminate{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--indeterminate:after{content:\"\";position:absolute;left:3px;top:6px;width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required", "visuallyHidden"] }] });
5767
6175
  }
5768
6176
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MultiSelect, decorators: [{
5769
6177
  type: Component,
@@ -5771,7 +6179,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
5771
6179
  '[class.kf-multi-select--width-sm]': "width() === 'sm'",
5772
6180
  '[class.kf-multi-select--width-lg]': "width() === 'lg'",
5773
6181
  '[class.kf-multi-select--width-full]': "width() === 'full'",
5774
- }, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n>\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret kf-caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n<ng-template #panelTemplate>\n <div class=\"kf-multi-select__panel\">\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-multi-select__search\"\n placeholder=\"Buscar\u2026\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); toggleActive()\"\n />\n }\n <ul\n class=\"kf-multi-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n [class.kf-multi-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n @if (options().length > 0) {\n <li class=\"kf-multi-select__empty\">Sin resultados</li>\n } @else {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-strong);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);font:inherit;width:var(--kf-select-width-md)}:host(.kf-multi-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-multi-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-multi-select--width-full){width:100%}.kf-multi-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-multi-select__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-multi-select__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-multi-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:left}.kf-multi-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-multi-select__count{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 5px;border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.72rem;font-weight:700}.kf-multi-select__panel{box-sizing:border-box;width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-multi-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-multi-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-multi-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-multi-select__list::-webkit-scrollbar{width:6px}.kf-multi-select__list::-webkit-scrollbar-track{background:transparent}.kf-multi-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-multi-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-multi-select__option{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-multi-select__option:hover{background:var(--kf-color-primary-soft)}.kf-multi-select__option--selected{color:var(--kf-color-primary);font-weight:600}.kf-multi-select__option--active{background:var(--kf-color-primary-soft)}.kf-multi-select__checkbox{display:inline-flex}.kf-multi-select__checkbox--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--checked:after{content:\"\";position:absolute;left:4px;top:1px;width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg)}.kf-multi-select__checkbox--indeterminate{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--indeterminate:after{content:\"\";position:absolute;left:3px;top:6px;width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"] }]
6182
+ }, template: "@if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n}\n<button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n>\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret kf-caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n [class.kf-caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n</button>\n<ng-template #panelTemplate>\n <div class=\"kf-multi-select__panel\">\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-multi-select__search\"\n placeholder=\"Buscar\u2026\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); toggleActive()\"\n />\n }\n <ul\n class=\"kf-multi-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n [class.kf-multi-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n >\n <span\n class=\"kf-multi-select__checkbox kf-checkbox-box\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n @if (options().length > 0) {\n <li class=\"kf-multi-select__empty\">Sin resultados</li>\n } @else {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n }\n </ul>\n </div>\n</ng-template>\n", styles: [".kf-caret{flex-shrink:0;width:8px;height:8px;border-right:2px solid var(--kf-color-text-muted);border-bottom:2px solid var(--kf-color-text-muted);transform:rotate(45deg);transition:transform .14s;margin-top:-4px}.kf-caret--open{transform:rotate(-135deg);margin-top:4px}.kf-checkbox-box{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--kf-space-md);height:var(--kf-space-md);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-xs);background:var(--kf-color-white);transition:background .14s,border-color .14s;position:relative}.kf-checkbox-box--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}:host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);font:inherit;width:var(--kf-select-width-md)}:host(.kf-multi-select--width-sm){width:var(--kf-select-width-sm)}:host(.kf-multi-select--width-lg){width:var(--kf-select-width-lg)}:host(.kf-multi-select--width-full){width:100%}.kf-multi-select__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-sm);width:100%;font:inherit;font-family:var(--kf-font-body);padding:var(--kf-space-sm) var(--kf-space-md);border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);background:var(--kf-color-white);color:var(--kf-color-text);cursor:pointer;transition:border-color .14s,box-shadow .14s}.kf-multi-select__trigger:hover:not(:disabled){border-color:var(--kf-color-text-muted)}.kf-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-multi-select__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-multi-select__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:left}.kf-multi-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-multi-select__count{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 5px;border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.72rem;font-weight:700}.kf-multi-select__panel{box-sizing:border-box;width:100%;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md);overflow:hidden}.kf-multi-select__search{box-sizing:border-box;width:100%;font:inherit;font-family:var(--kf-font-body);color:var(--kf-color-text);padding:var(--kf-space-sm) var(--kf-space-md);border:none;border-bottom:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm) var(--kf-radius-sm) 0 0;outline:none}.kf-multi-select__search:focus-visible{box-shadow:inset 0 0 0 2px var(--kf-color-primary)}.kf-multi-select__list{box-sizing:border-box;width:100%;margin:0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-multi-select__list::-webkit-scrollbar{width:6px}.kf-multi-select__list::-webkit-scrollbar-track{background:transparent}.kf-multi-select__list::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-multi-select__list::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-multi-select__option{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kf-multi-select__option:hover{background:var(--kf-color-primary-soft)}.kf-multi-select__option--selected{color:var(--kf-color-primary);font-weight:600}.kf-multi-select__option--active{background:var(--kf-color-primary-soft)}.kf-multi-select__checkbox{display:inline-flex}.kf-multi-select__checkbox--checked{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--checked:after{content:\"\";position:absolute;left:4px;top:1px;width:var(--kf-checkbox-mark-width);height:var(--kf-checkbox-mark-height);border:var(--kf-checkbox-mark-border);border-width:var(--kf-checkbox-mark-border-width);transform:rotate(45deg)}.kf-multi-select__checkbox--indeterminate{background:var(--kf-color-primary);border-color:var(--kf-color-primary)}.kf-multi-select__checkbox--indeterminate:after{content:\"\";position:absolute;left:3px;top:6px;width:var(--kf-checkbox-dash-width);height:var(--kf-checkbox-dash-height);background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{text-align:center;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text-muted)}\n"] }]
5775
6183
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], values: [{ type: i0.Input, args: [{ isSignal: true, alias: "values", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchThreshold", required: false }] }], valuesChange: [{ type: i0.Output, args: ["valuesChange"] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panelTemplate: [{ type: i0.ViewChild, args: ['panelTemplate', { isSignal: true }] }], searchInputRef: [{ type: i0.ViewChild, args: ['searchInput', { isSignal: true }] }] } });
5776
6184
 
5777
6185
  const DEFAULT_FIELD_WIDTH = '240px';
@@ -5837,7 +6245,7 @@ class Filter {
5837
6245
  this.fieldChange.emit({ key, value });
5838
6246
  }
5839
6247
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Filter, deps: [], target: i0.ɵɵFactoryTarget.Component });
5840
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Filter, isStandalone: true, selector: "kf-filter", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, mobileTitle: { classPropertyName: "mobileTitle", publicName: "mobileTitle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldChange: "fieldChange" }, ngImport: i0, template: "<ng-template #fieldsTpl let-stacked=\"stacked\">\n @for (field of fields(); track field.key) {\n @switch (field.type) {\n @case ('select') {\n <kf-select\n [label]=\"field.label ?? ''\"\n [options]=\"optionsFor(field.key)\"\n [value]=\"singleValueFor(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [style.width]=\"stacked ? '100%' : fieldWidth(field)\"\n (valueChange)=\"onFieldChange(field.key, $event)\"\n />\n }\n @case ('multi-select') {\n <kf-multi-select\n [label]=\"field.label ?? ''\"\n [options]=\"multiOptionsFor(field.key)\"\n [values]=\"multiValueFor(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [style.width]=\"stacked ? '100%' : fieldWidth(field)\"\n (valuesChange)=\"onFieldChange(field.key, $event)\"\n />\n }\n @case ('search') {\n <kf-input\n [label]=\"field.label ?? ''\"\n [icon]=\"field.icon ?? 'search'\"\n [placeholder]=\"field.placeholder ?? ''\"\n [style.width]=\"stacked ? '100%' : fieldWidth(field)\"\n [ngModel]=\"singleValueFor(field.key)\"\n (ngModelChange)=\"onFieldChange(field.key, $event)\"\n />\n }\n }\n @if (!stacked && field.showDivider) {\n <kf-divider orientation=\"vertical\" />\n }\n }\n</ng-template>\n\n<div class=\"kf-filter kf-filter--row\">\n <ng-container [ngTemplateOutlet]=\"fieldsTpl\" [ngTemplateOutletContext]=\"{ stacked: false }\" />\n</div>\n\n<kf-collapsible class=\"kf-filter__collapsible\" [title]=\"mobileTitle()\">\n <div class=\"kf-filter kf-filter--stack\">\n <ng-container [ngTemplateOutlet]=\"fieldsTpl\" [ngTemplateOutletContext]=\"{ stacked: true }\" />\n </div>\n</kf-collapsible>\n", styles: ["@charset \"UTF-8\";:host{display:block}.kf-filter--row{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--kf-space-md)}.kf-filter--stack{display:flex;flex-direction:column;gap:var(--kf-space-md)}.kf-filter__collapsible{display:none}@media(max-width:768px){.kf-filter--row{display:none}.kf-filter__collapsible{display:block}}\n"], dependencies: [{ kind: "component", type: Collapsible, selector: "kf-collapsible", inputs: ["title", "expanded"], outputs: ["expandedChange"] }, { kind: "component", type: Divider, selector: "kf-divider", inputs: ["orientation"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Input, selector: "kf-input", inputs: ["label", "required", "icon", "suffix", "hint", "invalid", "errorMessage", "disabled", "readonly", "type", "placeholder", "autocomplete", "name", "inputmode", "min", "max", "step", "maxlength", "toggleable", "ariaLabel", "clearable", "clearLabel"], outputs: ["cleared"] }, { kind: "component", type: MultiSelect, selector: "kf-multi-select", inputs: ["label", "options", "values", "placeholder", "disabled", "width", "searchable", "searchThreshold"], outputs: ["valuesChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Select, selector: "kf-select", inputs: ["label", "options", "value", "placeholder", "disabled", "invalid", "errorMessage", "variant", "width", "searchable", "searchThreshold", "ariaLabel", "icon", "panelTitle", "panelWidth"], outputs: ["valueChange"] }] });
6248
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Filter, isStandalone: true, selector: "kf-filter", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, mobileTitle: { classPropertyName: "mobileTitle", publicName: "mobileTitle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldChange: "fieldChange" }, ngImport: i0, template: "<ng-template #fieldsTpl let-stacked=\"stacked\">\n @for (field of fields(); track field.key) {\n @switch (field.type) {\n @case ('select') {\n <kf-select\n [label]=\"field.label ?? ''\"\n [options]=\"optionsFor(field.key)\"\n [value]=\"singleValueFor(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [style.width]=\"stacked ? '100%' : fieldWidth(field)\"\n (valueChange)=\"onFieldChange(field.key, $event)\"\n />\n }\n @case ('multi-select') {\n <kf-multi-select\n [label]=\"field.label ?? ''\"\n [options]=\"multiOptionsFor(field.key)\"\n [values]=\"multiValueFor(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [style.width]=\"stacked ? '100%' : fieldWidth(field)\"\n (valuesChange)=\"onFieldChange(field.key, $event)\"\n />\n }\n @case ('search') {\n <kf-input\n [label]=\"field.label ?? ''\"\n [icon]=\"field.icon ?? 'search'\"\n [placeholder]=\"field.placeholder ?? ''\"\n [style.width]=\"stacked ? '100%' : fieldWidth(field)\"\n [ngModel]=\"singleValueFor(field.key)\"\n (ngModelChange)=\"onFieldChange(field.key, $event)\"\n />\n }\n }\n @if (!stacked && field.showDivider) {\n <kf-divider orientation=\"vertical\" />\n }\n }\n</ng-template>\n\n<div class=\"kf-filter kf-filter--row\">\n <ng-container [ngTemplateOutlet]=\"fieldsTpl\" [ngTemplateOutletContext]=\"{ stacked: false }\" />\n</div>\n\n<kf-collapsible class=\"kf-filter__collapsible\" [title]=\"mobileTitle()\">\n <div class=\"kf-filter kf-filter--stack\">\n <ng-container [ngTemplateOutlet]=\"fieldsTpl\" [ngTemplateOutletContext]=\"{ stacked: true }\" />\n </div>\n</kf-collapsible>\n", styles: ["@charset \"UTF-8\";:host{display:block}.kf-filter--row{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--kf-space-md)}.kf-filter--stack{display:flex;flex-direction:column;gap:var(--kf-space-md)}.kf-filter__collapsible{display:none}@media(max-width:768px){.kf-filter--row{display:none}.kf-filter__collapsible{display:block}}\n"], dependencies: [{ kind: "component", type: Collapsible, selector: "kf-collapsible", inputs: ["title", "expanded"], outputs: ["expandedChange"] }, { kind: "component", type: Divider, selector: "kf-divider", inputs: ["orientation"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Input, selector: "kf-input", inputs: ["label", "hideLabel", "required", "icon", "suffix", "hint", "invalid", "errorMessage", "disabled", "readonly", "type", "placeholder", "autocomplete", "name", "inputmode", "min", "max", "step", "maxlength", "toggleable", "ariaLabel", "clearable", "clearLabel"], outputs: ["cleared"] }, { kind: "component", type: MultiSelect, selector: "kf-multi-select", inputs: ["label", "options", "values", "placeholder", "disabled", "width", "searchable", "searchThreshold"], outputs: ["valuesChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Select, selector: "kf-select", inputs: ["label", "hideLabel", "prefix", "options", "value", "placeholder", "disabled", "invalid", "errorMessage", "variant", "width", "searchable", "searchThreshold", "ariaLabel", "icon", "panelTitle", "panelWidth"], outputs: ["valueChange"] }] });
5841
6249
  }
5842
6250
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Filter, decorators: [{
5843
6251
  type: Component,
@@ -5945,25 +6353,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
5945
6353
  args: [{ selector: 'kf-footer', template: "<div class=\"kf-footer__wrap\">\n @if (logoSrc()) {\n <img class=\"kf-footer__logo\" [src]=\"logoSrc()\" [alt]=\"logoAlt()\" />\n }\n <span class=\"kf-footer__copyright\">{{ copyright() }}</span>\n @if (links().length) {\n <nav class=\"kf-footer__links\">\n @for (link of links(); track link.label) {\n <a [href]=\"link.href || '#'\">{{ link.label }}</a>\n }\n </nav>\n }\n</div>\n", styles: [":host{display:block;margin-top:auto;background:var(--kf-color-tertiary-deep)}.kf-footer__wrap{max-width:var(--kf-footer-max-width, none);margin:0 auto;display:flex;align-items:center;flex-wrap:wrap;gap:var(--kf-space-lg);min-height:4.5rem;padding:var(--kf-space-md) var(--kf-space-lg)}.kf-footer__logo{height:1.375rem;opacity:.9}.kf-footer__copyright{font-size:.8125rem;color:#ffffff8c;font-family:var(--kf-font-body)}.kf-footer__links{margin-left:auto;display:flex;flex-wrap:wrap;gap:var(--kf-space-lg)}.kf-footer__links a{font-size:.8125rem;color:#ffffffa8;text-decoration:none;font-family:var(--kf-font-body)}.kf-footer__links a:hover{color:#fff}@media(max-width:640px){.kf-footer__wrap{flex-direction:column;align-items:flex-start}.kf-footer__links{margin-left:0}}\n"] }]
5946
6354
  }], propDecorators: { logoSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoSrc", required: false }] }], logoAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoAlt", required: false }] }], copyright: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyright", required: true }] }], links: [{ type: i0.Input, args: [{ isSignal: true, alias: "links", required: false }] }] } });
5947
6355
 
6356
+ /** Ancho por defecto desde el cual `orientation="auto"` elige horizontal. */
6357
+ const AUTO_BREAKPOINT_PX = 820;
5948
6358
  /**
5949
6359
  * Progreso de un flujo de N pasos.
5950
6360
  *
5951
- * - `orientation` (`'horizontal'` default | `'vertical'`): horizontal
5952
- * deriva done/current/pending de `currentStep`; vertical usa
5953
- * `steps[].status` explícito, con `delayed` como cuarto estado.
6361
+ * - `orientation` (`'horizontal'` default | `'vertical'` | `'auto'`): horizontal
6362
+ * deriva done/current/pending de `currentStep` (salvo que algún paso defina
6363
+ * `status`); vertical usa `steps[].status` explícito, con `delayed` como
6364
+ * cuarto estado. `'auto'` es horizontal cuando el propio componente mide al
6365
+ * menos `autoBreakpoint` px (820 por defecto) y vertical si no; en vertical,
6366
+ * con `caption`/`progress`/`statusLabel` y desde 520 px de ancho, el texto de
6367
+ * cada paso pasa a filas «etiqueta | estado y conteo | barra». En `'auto'`
6368
+ * los puntos son clickeables solo mientras el layout es horizontal.
5954
6369
  * - `surface` (`'dark'` default | `'card'`): fondo sólido oscuro de marca,
5955
6370
  * o superficie clara con borde+sombra.
5956
6371
  * - `colorScheme` (`'brand'` default | `'semantic'`): ver `JourneyStepperColorScheme`.
6372
+ * - `ariaLabel`: nombre de la lista de pasos (lectores de pantalla).
6373
+ *
6374
+ * Los pasos se exponen como lista (`role="list"`/`listitem`) y el paso con
6375
+ * `status === 'current'` lleva `aria-current="step"`.
5957
6376
  *
5958
6377
  * <kf-journey-stepper surface="card" [steps]="steps" [currentStep]="4" (stepClick)="onNavigate($event)" />
5959
6378
  * <kf-journey-stepper orientation="vertical" [steps]="unitSteps" />
5960
6379
  * <kf-journey-stepper orientation="vertical" colorScheme="semantic" [steps]="unitStepsWithDelays" />
6380
+ * <kf-journey-stepper orientation="auto" surface="card" ariaLabel="Avance por etapa" [steps]="stages" />
5961
6381
  */
5962
6382
  class JourneyStepper {
5963
6383
  steps = input.required(/* @ts-ignore */
5964
6384
  ...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
5965
6385
  orientation = input('horizontal', /* @ts-ignore */
5966
6386
  ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
6387
+ /** Ancho mínimo (px) del componente para ser horizontal con `orientation="auto"`. */
6388
+ autoBreakpoint = input(AUTO_BREAKPOINT_PX, /* @ts-ignore */
6389
+ ...(ngDevMode ? [{ debugName: "autoBreakpoint" }] : /* istanbul ignore next */ []));
6390
+ /** Nombre accesible de la lista de pasos. */
6391
+ ariaLabel = input(/* @ts-ignore */
6392
+ ...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
5967
6393
  surface = input('dark', /* @ts-ignore */
5968
6394
  ...(ngDevMode ? [{ debugName: "surface" }] : /* istanbul ignore next */ []));
5969
6395
  colorScheme = input('brand', /* @ts-ignore */
@@ -5979,12 +6405,34 @@ class JourneyStepper {
5979
6405
  /** `true` cuando el contenido desborda el ancho visible — controla el fade de los bordes. */
5980
6406
  hasOverflow = signal(false, /* @ts-ignore */
5981
6407
  ...(ngDevMode ? [{ debugName: "hasOverflow" }] : /* istanbul ignore next */ []));
5982
- clickable = computed(() => this.orientation() === 'horizontal', /* @ts-ignore */
6408
+ /** Ancho medido del componente; `null` hasta la primera medición. */
6409
+ trackWidth = signal(null, /* @ts-ignore */
6410
+ ...(ngDevMode ? [{ debugName: "trackWidth" }] : /* istanbul ignore next */ []));
6411
+ /**
6412
+ * Orientación efectiva: la de `orientation`, o —con `'auto'`— horizontal si el
6413
+ * componente mide al menos `autoBreakpoint` px. Antes de medir (o con ancho
6414
+ * 0) es vertical, que siempre cabe.
6415
+ */
6416
+ effectiveOrientation = computed(() => {
6417
+ const orientation = this.orientation();
6418
+ if (orientation !== 'auto') {
6419
+ return orientation;
6420
+ }
6421
+ const width = this.trackWidth();
6422
+ return width !== null && width >= this.autoBreakpoint() ? 'horizontal' : 'vertical';
6423
+ }, /* @ts-ignore */
6424
+ ...(ngDevMode ? [{ debugName: "effectiveOrientation" }] : /* istanbul ignore next */ []));
6425
+ vertical = computed(() => this.effectiveOrientation() === 'vertical', /* @ts-ignore */
6426
+ ...(ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []));
6427
+ clickable = computed(() => this.effectiveOrientation() === 'horizontal', /* @ts-ignore */
5983
6428
  ...(ngDevMode ? [{ debugName: "clickable" }] : /* istanbul ignore next */ []));
6429
+ /** `true` si algún paso usa `caption`, `progress` o `statusLabel` (layout enriquecido). */
6430
+ rich = computed(() => this.steps().some((step) => !!step.caption || !!step.statusLabel || JourneyStepper.progressOf(step.progress) !== null), /* @ts-ignore */
6431
+ ...(ngDevMode ? [{ debugName: "rich" }] : /* istanbul ignore next */ []));
5984
6432
  constructor() {
5985
6433
  afterRenderEffect(() => {
5986
6434
  this.steps();
5987
- this.orientation();
6435
+ this.effectiveOrientation();
5988
6436
  this.measureOverflow();
5989
6437
  });
5990
6438
  afterNextRender(() => {
@@ -5996,15 +6444,28 @@ class JourneyStepper {
5996
6444
  measureOverflow() {
5997
6445
  const el = this.track().nativeElement;
5998
6446
  this.hasOverflow.set(el.scrollWidth > el.clientWidth);
6447
+ this.trackWidth.set(el.clientWidth);
6448
+ }
6449
+ /** Progreso acotado a [0, 100]; `null` si no hay valor finito. */
6450
+ static progressOf(value) {
6451
+ return value === undefined || !Number.isFinite(value)
6452
+ ? null
6453
+ : Math.min(100, Math.max(0, value));
5999
6454
  }
6000
6455
  resolvedSteps = computed(() => {
6001
- if (this.orientation() === 'vertical') {
6002
- return this.steps().map((step) => ({ ...step, status: step.status ?? 'pending' }));
6003
- }
6456
+ const steps = this.steps();
6457
+ const explicit = this.orientation() === 'vertical' || steps.some((step) => step.status);
6004
6458
  const current = this.currentStep();
6005
- return this.steps().map((step, index) => ({
6459
+ return steps.map((step, index) => ({
6006
6460
  ...step,
6007
- status: index < current ? 'done' : index === current ? 'current' : 'pending',
6461
+ status: explicit
6462
+ ? (step.status ?? 'pending')
6463
+ : index < current
6464
+ ? 'done'
6465
+ : index === current
6466
+ ? 'current'
6467
+ : 'pending',
6468
+ progressValue: JourneyStepper.progressOf(step.progress),
6008
6469
  }));
6009
6470
  }, /* @ts-ignore */
6010
6471
  ...(ngDevMode ? [{ debugName: "resolvedSteps" }] : /* istanbul ignore next */ []));
@@ -6018,12 +6479,12 @@ class JourneyStepper {
6018
6479
  return stepIcon;
6019
6480
  }
6020
6481
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: JourneyStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
6021
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: JourneyStepper, isStandalone: true, selector: "kf-journey-stepper", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, surface: { classPropertyName: "surface", publicName: "surface", isSignal: true, isRequired: false, transformFunction: null }, colorScheme: { classPropertyName: "colorScheme", publicName: "colorScheme", isSignal: true, isRequired: false, transformFunction: null }, currentStep: { classPropertyName: "currentStep", publicName: "currentStep", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stepClick: "stepClick" }, viewQueries: [{ propertyName: "track", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #track\n class=\"kf-journey-stepper\"\n [class.kf-journey-stepper--vertical]=\"orientation() === 'vertical'\"\n [class.kf-journey-stepper--card]=\"surface() === 'card'\"\n [class.kf-journey-stepper--semantic]=\"colorScheme() === 'semantic'\"\n [class.kf-journey-stepper--overflowing]=\"hasOverflow()\"\n>\n @for (step of resolvedSteps(); track step.key; let last = $last) {\n <div class=\"kf-journey-stepper__step\" [class]=\"'kf-journey-stepper__step--' + step.status\">\n @if (clickable()) {\n <button type=\"button\" class=\"kf-journey-stepper__dot\" (click)=\"stepClick.emit(step.key)\">\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </button>\n } @else {\n <span class=\"kf-journey-stepper__dot\">\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </span>\n }\n\n <div class=\"kf-journey-stepper__text\">\n <span class=\"kf-journey-stepper__label\">{{ step.label }}</span>\n @if (step.date) {\n <span class=\"kf-journey-stepper__date\">{{ step.date }}</span>\n }\n </div>\n </div>\n\n @if (!last && orientation() === 'horizontal') {\n <span\n class=\"kf-journey-stepper__line\"\n [class.kf-journey-stepper__line--done]=\"step.status === 'done'\"\n ></span>\n }\n }\n</div>\n", styles: [":host{display:block;min-width:0}.kf-journey-stepper--overflowing:not(.kf-journey-stepper--vertical){-webkit-mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%);mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%)}.kf-journey-stepper{display:flex;align-items:center;overflow-x:auto;padding-bottom:var(--kf-space-xs);font-family:var(--kf-font-body);scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-journey-stepper::-webkit-scrollbar{height:6px}.kf-journey-stepper::-webkit-scrollbar-track{background:transparent}.kf-journey-stepper::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-journey-stepper::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-journey-stepper:not(.kf-journey-stepper--card){scrollbar-color:rgba(255,255,255,.3) transparent}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb{background-color:#ffffff4d}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb:hover{background-color:#ffffff73}.kf-journey-stepper--vertical{flex-direction:column;align-items:stretch;overflow-x:visible}.kf-journey-stepper__step{display:flex;align-items:center;flex-direction:column;gap:var(--kf-space-sm);flex:none}.kf-journey-stepper--vertical .kf-journey-stepper__step{flex-direction:row;align-items:flex-start;position:relative;padding-bottom:var(--kf-space-lg)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child{padding-bottom:0}.kf-journey-stepper--vertical .kf-journey-stepper__step:before{content:\"\";position:absolute;left:13px;top:28px;bottom:0;width:2px;background:var(--kf-color-gray-200)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child:before{display:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done:before{background:var(--kf-color-primary)}.kf-journey-stepper--semantic .kf-journey-stepper__step--done:before{background:var(--kf-color-success)}.kf-journey-stepper__dot{width:36px;height:36px;border-radius:var(--kf-radius-pill);display:grid;place-items:center;flex:none;z-index:1;border:2px solid transparent;background:transparent;cursor:default;font:inherit}.kf-journey-stepper--vertical .kf-journey-stepper__dot{width:28px;height:28px;border:none}button.kf-journey-stepper__dot{cursor:pointer}.kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:#ffffff14;color:#ffffff80;border-color:#ffffff24}.kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);border-color:var(--kf-color-primary)}.kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-white);color:var(--kf-color-primary);border-color:var(--kf-color-white);box-shadow:0 0 0 4px #ffffff29}.kf-journey-stepper__label{font-size:.72rem;font-weight:700;color:#ffffff8c;white-space:nowrap}.kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-white)}.kf-journey-stepper__line{flex:1;height:2px;background:#ffffff24;margin:0 var(--kf-space-xs);margin-bottom:20px;min-width:24px}.kf-journey-stepper__line--done{background:var(--kf-color-primary)}.kf-journey-stepper--card .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-surface);color:var(--kf-color-gray-400);border-color:var(--kf-color-border)}.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:var(--kf-color-primary);box-shadow:0 0 0 4px var(--kf-color-primary-soft)}.kf-journey-stepper--card .kf-journey-stepper__label{color:var(--kf-color-text-muted)}.kf-journey-stepper--card .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--card .kf-journey-stepper__line{background:var(--kf-color-border)}.kf-journey-stepper--vertical .kf-journey-stepper__text{display:flex;flex-direction:column;gap:2px;padding-top:3px}.kf-journey-stepper--vertical .kf-journey-stepper__label{font-size:.875rem;font-weight:700;color:var(--kf-color-gray-500);white-space:normal}.kf-journey-stepper--vertical .kf-journey-stepper__date{font-size:.78rem;color:var(--kf-color-gray-500)}.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--current .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-primary-soft)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-primary);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-success);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-warning-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-error-soft);color:var(--kf-color-error);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-error-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__date{color:var(--kf-color-gray-500)}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-warning-strong);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__date{color:var(--kf-color-error);font-weight:600}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
6482
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: JourneyStepper, isStandalone: true, selector: "kf-journey-stepper", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, autoBreakpoint: { classPropertyName: "autoBreakpoint", publicName: "autoBreakpoint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, surface: { classPropertyName: "surface", publicName: "surface", isSignal: true, isRequired: false, transformFunction: null }, colorScheme: { classPropertyName: "colorScheme", publicName: "colorScheme", isSignal: true, isRequired: false, transformFunction: null }, currentStep: { classPropertyName: "currentStep", publicName: "currentStep", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stepClick: "stepClick" }, viewQueries: [{ propertyName: "track", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #track\n class=\"kf-journey-stepper\"\n role=\"list\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [class.kf-journey-stepper--vertical]=\"vertical()\"\n [class.kf-journey-stepper--auto]=\"orientation() === 'auto'\"\n [class.kf-journey-stepper--rich]=\"rich()\"\n [class.kf-journey-stepper--card]=\"surface() === 'card'\"\n [class.kf-journey-stepper--semantic]=\"colorScheme() === 'semantic'\"\n [class.kf-journey-stepper--overflowing]=\"hasOverflow()\"\n>\n @for (step of resolvedSteps(); track step.key; let last = $last) {\n <div\n class=\"kf-journey-stepper__step\"\n role=\"listitem\"\n [class]=\"'kf-journey-stepper__step--' + step.status\"\n [attr.aria-current]=\"step.status === 'current' ? 'step' : null\"\n >\n @if (clickable()) {\n <button\n type=\"button\"\n class=\"kf-journey-stepper__dot\"\n [attr.aria-label]=\"step.label\"\n (click)=\"stepClick.emit(step.key)\"\n >\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </button>\n } @else {\n <span class=\"kf-journey-stepper__dot\">\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </span>\n }\n\n <div class=\"kf-journey-stepper__text\">\n <span class=\"kf-journey-stepper__label\">{{ step.label }}</span>\n @if (step.date) {\n <span class=\"kf-journey-stepper__date\">{{ step.date }}</span>\n }\n @if (step.statusLabel || step.caption) {\n <span class=\"kf-journey-stepper__meta\">\n @if (step.statusLabel) {\n <span class=\"kf-journey-stepper__status\">{{ step.statusLabel }}</span>\n }\n @if (step.statusLabel && step.caption) {\n <span class=\"kf-journey-stepper__sep\" aria-hidden=\"true\">\u00B7</span>\n }\n @if (step.caption) {\n <span class=\"kf-journey-stepper__caption\">{{ step.caption }}</span>\n }\n </span>\n }\n @if (step.progressValue !== null) {\n @if (step.caption) {\n <span class=\"kf-journey-stepper__progress\" aria-hidden=\"true\">\n <span [style.width.%]=\"step.progressValue\"></span>\n </span>\n } @else {\n <span\n class=\"kf-journey-stepper__progress\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-valuenow]=\"step.progressValue\"\n [attr.aria-label]=\"step.label\"\n >\n <span [style.width.%]=\"step.progressValue\"></span>\n </span>\n }\n }\n </div>\n </div>\n\n @if (!last && !vertical()) {\n <span\n class=\"kf-journey-stepper__line\"\n aria-hidden=\"true\"\n [class.kf-journey-stepper__line--done]=\"step.status === 'done'\"\n ></span>\n }\n }\n</div>\n", styles: [":host{display:block;min-width:0}.kf-journey-stepper--overflowing:not(.kf-journey-stepper--vertical){-webkit-mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%);mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%)}.kf-journey-stepper{display:flex;align-items:center;overflow-x:auto;padding-bottom:var(--kf-space-xs);font-family:var(--kf-font-body);scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-journey-stepper::-webkit-scrollbar{height:6px}.kf-journey-stepper::-webkit-scrollbar-track{background:transparent}.kf-journey-stepper::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-journey-stepper::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-journey-stepper:not(.kf-journey-stepper--card){scrollbar-color:rgba(255,255,255,.3) transparent}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb{background-color:#ffffff4d}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb:hover{background-color:#ffffff73}.kf-journey-stepper--vertical{flex-direction:column;align-items:stretch;overflow-x:visible}.kf-journey-stepper__step{display:flex;align-items:center;flex-direction:column;gap:var(--kf-space-sm);flex:none}.kf-journey-stepper--vertical .kf-journey-stepper__step{flex-direction:row;align-items:flex-start;position:relative;padding-bottom:var(--kf-space-lg)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child{padding-bottom:0}.kf-journey-stepper--vertical .kf-journey-stepper__step:before{content:\"\";position:absolute;left:13px;top:28px;bottom:0;width:2px;background:var(--kf-color-gray-200)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child:before{display:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done:before{background:var(--kf-color-primary)}.kf-journey-stepper--semantic .kf-journey-stepper__step--done:before{background:var(--kf-color-success)}.kf-journey-stepper__dot{width:36px;height:36px;border-radius:var(--kf-radius-pill);display:grid;place-items:center;flex:none;z-index:1;border:2px solid transparent;background:transparent;cursor:default;font:inherit}.kf-journey-stepper--vertical .kf-journey-stepper__dot{width:28px;height:28px;border:none}button.kf-journey-stepper__dot{cursor:pointer}.kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:#ffffff14;color:#ffffff80;border-color:#ffffff24}.kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);border-color:var(--kf-color-primary)}.kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-white);color:var(--kf-color-primary);border-color:var(--kf-color-white);box-shadow:0 0 0 4px #ffffff29}.kf-journey-stepper__label{font-size:.72rem;font-weight:700;color:#ffffff8c;white-space:nowrap}.kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-white)}.kf-journey-stepper__line{flex:1;height:2px;background:#ffffff24;margin:0 var(--kf-space-xs);margin-bottom:20px;min-width:24px}.kf-journey-stepper__line--done{background:var(--kf-color-primary)}.kf-journey-stepper--card .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-surface);color:var(--kf-color-gray-400);border-color:var(--kf-color-border)}.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:var(--kf-color-primary);box-shadow:0 0 0 4px var(--kf-color-primary-soft)}.kf-journey-stepper--card .kf-journey-stepper__label{color:var(--kf-color-text-muted)}.kf-journey-stepper--card .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--card .kf-journey-stepper__line{background:var(--kf-color-border)}.kf-journey-stepper--vertical .kf-journey-stepper__text{display:flex;flex-direction:column;gap:2px;padding-top:3px}.kf-journey-stepper--vertical .kf-journey-stepper__label{font-size:.875rem;font-weight:700;color:var(--kf-color-gray-500);white-space:normal}.kf-journey-stepper--vertical .kf-journey-stepper__date{font-size:.78rem;color:var(--kf-color-gray-500)}.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--current .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-primary-soft)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-primary);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-success);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-warning-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-error-soft);color:var(--kf-color-error);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-error-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__date{color:var(--kf-color-gray-500)}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-warning-strong);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__date{color:var(--kf-color-error);font-weight:600}button.kf-journey-stepper__dot:focus-visible{outline:2px solid var(--kf-color-white);outline-offset:2px}.kf-journey-stepper--card button.kf-journey-stepper__dot:focus-visible{outline-color:var(--kf-color-primary)}.kf-journey-stepper--auto{container-type:inline-size}.kf-journey-stepper__meta{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 6px;font-size:.78rem;line-height:1.35}.kf-journey-stepper__status{font-weight:700}.kf-journey-stepper__progress{display:block;height:4px;width:100%;max-width:200px;margin-top:4px;border-radius:var(--kf-radius-pill);background:var(--kf-color-gray-200);overflow:hidden}.kf-journey-stepper__progress>span{display:block;height:100%;border-radius:inherit;background:var(--kf-color-primary)}.kf-journey-stepper--card .kf-journey-stepper__meta,.kf-journey-stepper--vertical .kf-journey-stepper__meta{color:var(--kf-color-text)}.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__status,.kf-journey-stepper--vertical .kf-journey-stepper__step--current .kf-journey-stepper__status{color:var(--kf-color-primary-active)}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__meta{color:#ffffffc7}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__step--current .kf-journey-stepper__status{color:var(--kf-color-white)}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__progress{background:#ffffff2e}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__progress>span{background:var(--kf-color-white)}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical){align-items:flex-start}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__step{width:92px;text-align:center}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__line{margin:17px var(--kf-space-xs) 0}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__text{display:flex;flex-direction:column;align-items:center;gap:2px;width:100%}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__label{white-space:normal}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__meta{flex-direction:column;align-items:center;gap:1px}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__sep{display:none}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__progress{width:80%}.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__label{color:var(--kf-color-text)}.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__dot{color:var(--kf-color-text);box-shadow:inset 0 0 0 2px var(--kf-color-border)}.kf-journey-stepper--rich.kf-journey-stepper--card:not(.kf-journey-stepper--vertical) .kf-journey-stepper__step--pending .kf-journey-stepper__label,.kf-journey-stepper--rich.kf-journey-stepper--card:not(.kf-journey-stepper--vertical) .kf-journey-stepper__step--pending .kf-journey-stepper__dot{color:var(--kf-color-text)}@container (min-width: 520px){.kf-journey-stepper--auto.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__text{flex:1 1 auto;min-width:0;display:grid;grid-template-columns:minmax(120px,160px) minmax(200px,max-content) minmax(56px,1fr);align-items:center;column-gap:var(--kf-space-md);min-height:28px;padding-top:0}.kf-journey-stepper--auto.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__progress{margin-top:0;max-width:none}}\n"], dependencies: [{ kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }] });
6022
6483
  }
6023
6484
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: JourneyStepper, decorators: [{
6024
6485
  type: Component,
6025
- args: [{ selector: 'kf-journey-stepper', imports: [Icon], template: "<div\n #track\n class=\"kf-journey-stepper\"\n [class.kf-journey-stepper--vertical]=\"orientation() === 'vertical'\"\n [class.kf-journey-stepper--card]=\"surface() === 'card'\"\n [class.kf-journey-stepper--semantic]=\"colorScheme() === 'semantic'\"\n [class.kf-journey-stepper--overflowing]=\"hasOverflow()\"\n>\n @for (step of resolvedSteps(); track step.key; let last = $last) {\n <div class=\"kf-journey-stepper__step\" [class]=\"'kf-journey-stepper__step--' + step.status\">\n @if (clickable()) {\n <button type=\"button\" class=\"kf-journey-stepper__dot\" (click)=\"stepClick.emit(step.key)\">\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </button>\n } @else {\n <span class=\"kf-journey-stepper__dot\">\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </span>\n }\n\n <div class=\"kf-journey-stepper__text\">\n <span class=\"kf-journey-stepper__label\">{{ step.label }}</span>\n @if (step.date) {\n <span class=\"kf-journey-stepper__date\">{{ step.date }}</span>\n }\n </div>\n </div>\n\n @if (!last && orientation() === 'horizontal') {\n <span\n class=\"kf-journey-stepper__line\"\n [class.kf-journey-stepper__line--done]=\"step.status === 'done'\"\n ></span>\n }\n }\n</div>\n", styles: [":host{display:block;min-width:0}.kf-journey-stepper--overflowing:not(.kf-journey-stepper--vertical){-webkit-mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%);mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%)}.kf-journey-stepper{display:flex;align-items:center;overflow-x:auto;padding-bottom:var(--kf-space-xs);font-family:var(--kf-font-body);scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-journey-stepper::-webkit-scrollbar{height:6px}.kf-journey-stepper::-webkit-scrollbar-track{background:transparent}.kf-journey-stepper::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-journey-stepper::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-journey-stepper:not(.kf-journey-stepper--card){scrollbar-color:rgba(255,255,255,.3) transparent}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb{background-color:#ffffff4d}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb:hover{background-color:#ffffff73}.kf-journey-stepper--vertical{flex-direction:column;align-items:stretch;overflow-x:visible}.kf-journey-stepper__step{display:flex;align-items:center;flex-direction:column;gap:var(--kf-space-sm);flex:none}.kf-journey-stepper--vertical .kf-journey-stepper__step{flex-direction:row;align-items:flex-start;position:relative;padding-bottom:var(--kf-space-lg)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child{padding-bottom:0}.kf-journey-stepper--vertical .kf-journey-stepper__step:before{content:\"\";position:absolute;left:13px;top:28px;bottom:0;width:2px;background:var(--kf-color-gray-200)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child:before{display:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done:before{background:var(--kf-color-primary)}.kf-journey-stepper--semantic .kf-journey-stepper__step--done:before{background:var(--kf-color-success)}.kf-journey-stepper__dot{width:36px;height:36px;border-radius:var(--kf-radius-pill);display:grid;place-items:center;flex:none;z-index:1;border:2px solid transparent;background:transparent;cursor:default;font:inherit}.kf-journey-stepper--vertical .kf-journey-stepper__dot{width:28px;height:28px;border:none}button.kf-journey-stepper__dot{cursor:pointer}.kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:#ffffff14;color:#ffffff80;border-color:#ffffff24}.kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);border-color:var(--kf-color-primary)}.kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-white);color:var(--kf-color-primary);border-color:var(--kf-color-white);box-shadow:0 0 0 4px #ffffff29}.kf-journey-stepper__label{font-size:.72rem;font-weight:700;color:#ffffff8c;white-space:nowrap}.kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-white)}.kf-journey-stepper__line{flex:1;height:2px;background:#ffffff24;margin:0 var(--kf-space-xs);margin-bottom:20px;min-width:24px}.kf-journey-stepper__line--done{background:var(--kf-color-primary)}.kf-journey-stepper--card .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-surface);color:var(--kf-color-gray-400);border-color:var(--kf-color-border)}.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:var(--kf-color-primary);box-shadow:0 0 0 4px var(--kf-color-primary-soft)}.kf-journey-stepper--card .kf-journey-stepper__label{color:var(--kf-color-text-muted)}.kf-journey-stepper--card .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--card .kf-journey-stepper__line{background:var(--kf-color-border)}.kf-journey-stepper--vertical .kf-journey-stepper__text{display:flex;flex-direction:column;gap:2px;padding-top:3px}.kf-journey-stepper--vertical .kf-journey-stepper__label{font-size:.875rem;font-weight:700;color:var(--kf-color-gray-500);white-space:normal}.kf-journey-stepper--vertical .kf-journey-stepper__date{font-size:.78rem;color:var(--kf-color-gray-500)}.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--current .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-primary-soft)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-primary);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-success);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-warning-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-error-soft);color:var(--kf-color-error);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-error-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__date{color:var(--kf-color-gray-500)}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-warning-strong);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__date{color:var(--kf-color-error);font-weight:600}\n"] }]
6026
- }], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], surface: [{ type: i0.Input, args: [{ isSignal: true, alias: "surface", required: false }] }], colorScheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorScheme", required: false }] }], currentStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentStep", required: false }] }], stepClick: [{ type: i0.Output, args: ["stepClick"] }], track: [{ type: i0.ViewChild, args: ['track', { isSignal: true }] }] } });
6486
+ args: [{ selector: 'kf-journey-stepper', imports: [Icon], template: "<div\n #track\n class=\"kf-journey-stepper\"\n role=\"list\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [class.kf-journey-stepper--vertical]=\"vertical()\"\n [class.kf-journey-stepper--auto]=\"orientation() === 'auto'\"\n [class.kf-journey-stepper--rich]=\"rich()\"\n [class.kf-journey-stepper--card]=\"surface() === 'card'\"\n [class.kf-journey-stepper--semantic]=\"colorScheme() === 'semantic'\"\n [class.kf-journey-stepper--overflowing]=\"hasOverflow()\"\n>\n @for (step of resolvedSteps(); track step.key; let last = $last) {\n <div\n class=\"kf-journey-stepper__step\"\n role=\"listitem\"\n [class]=\"'kf-journey-stepper__step--' + step.status\"\n [attr.aria-current]=\"step.status === 'current' ? 'step' : null\"\n >\n @if (clickable()) {\n <button\n type=\"button\"\n class=\"kf-journey-stepper__dot\"\n [attr.aria-label]=\"step.label\"\n (click)=\"stepClick.emit(step.key)\"\n >\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </button>\n } @else {\n <span class=\"kf-journey-stepper__dot\">\n <kf-icon [name]=\"dotIcon(step.status, step.icon)\" size=\"sm\" />\n </span>\n }\n\n <div class=\"kf-journey-stepper__text\">\n <span class=\"kf-journey-stepper__label\">{{ step.label }}</span>\n @if (step.date) {\n <span class=\"kf-journey-stepper__date\">{{ step.date }}</span>\n }\n @if (step.statusLabel || step.caption) {\n <span class=\"kf-journey-stepper__meta\">\n @if (step.statusLabel) {\n <span class=\"kf-journey-stepper__status\">{{ step.statusLabel }}</span>\n }\n @if (step.statusLabel && step.caption) {\n <span class=\"kf-journey-stepper__sep\" aria-hidden=\"true\">\u00B7</span>\n }\n @if (step.caption) {\n <span class=\"kf-journey-stepper__caption\">{{ step.caption }}</span>\n }\n </span>\n }\n @if (step.progressValue !== null) {\n @if (step.caption) {\n <span class=\"kf-journey-stepper__progress\" aria-hidden=\"true\">\n <span [style.width.%]=\"step.progressValue\"></span>\n </span>\n } @else {\n <span\n class=\"kf-journey-stepper__progress\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-valuenow]=\"step.progressValue\"\n [attr.aria-label]=\"step.label\"\n >\n <span [style.width.%]=\"step.progressValue\"></span>\n </span>\n }\n }\n </div>\n </div>\n\n @if (!last && !vertical()) {\n <span\n class=\"kf-journey-stepper__line\"\n aria-hidden=\"true\"\n [class.kf-journey-stepper__line--done]=\"step.status === 'done'\"\n ></span>\n }\n }\n</div>\n", styles: [":host{display:block;min-width:0}.kf-journey-stepper--overflowing:not(.kf-journey-stepper--vertical){-webkit-mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%);mask-image:linear-gradient(to right,transparent 0,black 24px,black calc(100% - 24px),transparent 100%)}.kf-journey-stepper{display:flex;align-items:center;overflow-x:auto;padding-bottom:var(--kf-space-xs);font-family:var(--kf-font-body);scrollbar-width:thin;scrollbar-color:var(--kf-color-gray-400) transparent}.kf-journey-stepper::-webkit-scrollbar{height:6px}.kf-journey-stepper::-webkit-scrollbar-track{background:transparent}.kf-journey-stepper::-webkit-scrollbar-thumb{background-color:var(--kf-color-gray-400);border-radius:var(--kf-radius-pill)}.kf-journey-stepper::-webkit-scrollbar-thumb:hover{background-color:var(--kf-color-gray-500)}.kf-journey-stepper:not(.kf-journey-stepper--card){scrollbar-color:rgba(255,255,255,.3) transparent}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb{background-color:#ffffff4d}.kf-journey-stepper:not(.kf-journey-stepper--card)::-webkit-scrollbar-thumb:hover{background-color:#ffffff73}.kf-journey-stepper--vertical{flex-direction:column;align-items:stretch;overflow-x:visible}.kf-journey-stepper__step{display:flex;align-items:center;flex-direction:column;gap:var(--kf-space-sm);flex:none}.kf-journey-stepper--vertical .kf-journey-stepper__step{flex-direction:row;align-items:flex-start;position:relative;padding-bottom:var(--kf-space-lg)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child{padding-bottom:0}.kf-journey-stepper--vertical .kf-journey-stepper__step:before{content:\"\";position:absolute;left:13px;top:28px;bottom:0;width:2px;background:var(--kf-color-gray-200)}.kf-journey-stepper--vertical .kf-journey-stepper__step:last-child:before{display:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done:before{background:var(--kf-color-primary)}.kf-journey-stepper--semantic .kf-journey-stepper__step--done:before{background:var(--kf-color-success)}.kf-journey-stepper__dot{width:36px;height:36px;border-radius:var(--kf-radius-pill);display:grid;place-items:center;flex:none;z-index:1;border:2px solid transparent;background:transparent;cursor:default;font:inherit}.kf-journey-stepper--vertical .kf-journey-stepper__dot{width:28px;height:28px;border:none}button.kf-journey-stepper__dot{cursor:pointer}.kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:#ffffff14;color:#ffffff80;border-color:#ffffff24}.kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);border-color:var(--kf-color-primary)}.kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-white);color:var(--kf-color-primary);border-color:var(--kf-color-white);box-shadow:0 0 0 4px #ffffff29}.kf-journey-stepper__label{font-size:.72rem;font-weight:700;color:#ffffff8c;white-space:nowrap}.kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-white)}.kf-journey-stepper__line{flex:1;height:2px;background:#ffffff24;margin:0 var(--kf-space-xs);margin-bottom:20px;min-width:24px}.kf-journey-stepper__line--done{background:var(--kf-color-primary)}.kf-journey-stepper--card .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-surface);color:var(--kf-color-gray-400);border-color:var(--kf-color-border)}.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:var(--kf-color-primary);box-shadow:0 0 0 4px var(--kf-color-primary-soft)}.kf-journey-stepper--card .kf-journey-stepper__label{color:var(--kf-color-text-muted)}.kf-journey-stepper--card .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--card .kf-journey-stepper__line{background:var(--kf-color-border)}.kf-journey-stepper--vertical .kf-journey-stepper__text{display:flex;flex-direction:column;gap:2px;padding-top:3px}.kf-journey-stepper--vertical .kf-journey-stepper__label{font-size:.875rem;font-weight:700;color:var(--kf-color-gray-500);white-space:normal}.kf-journey-stepper--vertical .kf-journey-stepper__date{font-size:.78rem;color:var(--kf-color-gray-500)}.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--current .kf-journey-stepper__label,.kf-journey-stepper--vertical .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-primary);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-primary-soft)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-gray-100);color:var(--kf-color-gray-400)}.kf-journey-stepper--vertical:not(.kf-journey-stepper--semantic) .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-primary);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--done .kf-journey-stepper__dot{background:var(--kf-color-success);color:var(--kf-color-white);box-shadow:none}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__dot{background:var(--kf-color-warning-soft);color:var(--kf-color-warning-strong);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-warning-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__dot{background:var(--kf-color-error-soft);color:var(--kf-color-error);border-color:transparent;box-shadow:0 0 0 3px var(--kf-color-error-soft)}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__label{color:var(--kf-color-ink)}.kf-journey-stepper--vertical .kf-journey-stepper__step--done .kf-journey-stepper__date{color:var(--kf-color-gray-500)}.kf-journey-stepper--semantic .kf-journey-stepper__step--current .kf-journey-stepper__date{color:var(--kf-color-warning-strong);font-weight:600}.kf-journey-stepper--semantic .kf-journey-stepper__step--delayed .kf-journey-stepper__date{color:var(--kf-color-error);font-weight:600}button.kf-journey-stepper__dot:focus-visible{outline:2px solid var(--kf-color-white);outline-offset:2px}.kf-journey-stepper--card button.kf-journey-stepper__dot:focus-visible{outline-color:var(--kf-color-primary)}.kf-journey-stepper--auto{container-type:inline-size}.kf-journey-stepper__meta{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 6px;font-size:.78rem;line-height:1.35}.kf-journey-stepper__status{font-weight:700}.kf-journey-stepper__progress{display:block;height:4px;width:100%;max-width:200px;margin-top:4px;border-radius:var(--kf-radius-pill);background:var(--kf-color-gray-200);overflow:hidden}.kf-journey-stepper__progress>span{display:block;height:100%;border-radius:inherit;background:var(--kf-color-primary)}.kf-journey-stepper--card .kf-journey-stepper__meta,.kf-journey-stepper--vertical .kf-journey-stepper__meta{color:var(--kf-color-text)}.kf-journey-stepper--card .kf-journey-stepper__step--current .kf-journey-stepper__status,.kf-journey-stepper--vertical .kf-journey-stepper__step--current .kf-journey-stepper__status{color:var(--kf-color-primary-active)}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__meta{color:#ffffffc7}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__step--current .kf-journey-stepper__status{color:var(--kf-color-white)}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__progress{background:#ffffff2e}.kf-journey-stepper:not(.kf-journey-stepper--card):not(.kf-journey-stepper--vertical) .kf-journey-stepper__progress>span{background:var(--kf-color-white)}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical){align-items:flex-start}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__step{width:92px;text-align:center}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__line{margin:17px var(--kf-space-xs) 0}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__text{display:flex;flex-direction:column;align-items:center;gap:2px;width:100%}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__label{white-space:normal}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__meta{flex-direction:column;align-items:center;gap:1px}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__sep{display:none}.kf-journey-stepper--rich:not(.kf-journey-stepper--vertical) .kf-journey-stepper__progress{width:80%}.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__label{color:var(--kf-color-text)}.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__step--pending .kf-journey-stepper__dot{color:var(--kf-color-text);box-shadow:inset 0 0 0 2px var(--kf-color-border)}.kf-journey-stepper--rich.kf-journey-stepper--card:not(.kf-journey-stepper--vertical) .kf-journey-stepper__step--pending .kf-journey-stepper__label,.kf-journey-stepper--rich.kf-journey-stepper--card:not(.kf-journey-stepper--vertical) .kf-journey-stepper__step--pending .kf-journey-stepper__dot{color:var(--kf-color-text)}@container (min-width: 520px){.kf-journey-stepper--auto.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__text{flex:1 1 auto;min-width:0;display:grid;grid-template-columns:minmax(120px,160px) minmax(200px,max-content) minmax(56px,1fr);align-items:center;column-gap:var(--kf-space-md);min-height:28px;padding-top:0}.kf-journey-stepper--auto.kf-journey-stepper--rich.kf-journey-stepper--vertical .kf-journey-stepper__progress{margin-top:0;max-width:none}}\n"] }]
6487
+ }], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], autoBreakpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoBreakpoint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], surface: [{ type: i0.Input, args: [{ isSignal: true, alias: "surface", required: false }] }], colorScheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorScheme", required: false }] }], currentStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentStep", required: false }] }], stepClick: [{ type: i0.Output, args: ["stepClick"] }], track: [{ type: i0.ViewChild, args: ['track', { isSignal: true }] }] } });
6027
6488
 
6028
6489
  /**
6029
6490
  * Margen de histéresis (px) para SUBIR de modo. Bajar es inmediato (si no
@@ -6478,13 +6939,13 @@ class MetricCard {
6478
6939
  /** Dibuja el esqueleto en lugar del contenido, conservando las dimensiones. */
6479
6940
  loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
6480
6941
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MetricCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
6481
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: MetricCard, isStandalone: true, selector: "kf-metric-card", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, foot: { classPropertyName: "foot", publicName: "foot", isSignal: true, isRequired: false, transformFunction: null }, valueColor: { classPropertyName: "valueColor", publicName: "valueColor", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-busy": "loading() ? 'true' : null" } }, ngImport: i0, template: "<kf-card>\n <div class=\"kf-metric-card__head\">\n @if (loading()) {\n <span\n class=\"kf-metric-card__label-bone kf-bone\"\n style=\"--kf-bone-width: 45%\"\n aria-hidden=\"true\"\n >\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n </span>\n @if (icon()) {\n <span class=\"kf-metric-card__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n }\n } @else {\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n @if (loading()) {\n <div class=\"kf-metric-card__value kf-bone\" style=\"--kf-bone-width: 50%\" aria-hidden=\"true\">\n {{ value() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">\n <kf-text as=\"span\" variant=\"overline-strong\" tone=\"ok\">{{ badge() }}</kf-text>\n </span>\n }\n }\n </div>\n @if (foot()) {\n @if (loading()) {\n <div class=\"kf-metric-card__foot kf-bone\" style=\"--kf-bone-width: 60%\" aria-hidden=\"true\">\n {{ foot() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n }\n <div class=\"kf-metric-card__actions\" [class.kf-metric-card__actions--loading]=\"loading()\">\n <ng-content select=\"[actions]\" />\n </div>\n</kf-card>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-metric-card__head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--kf-space-xs)}.kf-metric-card__icon{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border-radius:var(--kf-radius-sm);background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-metric-card__value-row{display:flex;align-items:center;gap:var(--kf-space-xs)}.kf-metric-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:1.6rem;line-height:1.1;color:var(--kf-color-ink)}.kf-metric-card__unit{font-size:.85rem;font-weight:500;color:var(--kf-color-text-muted);margin-left:var(--kf-space-xs)}.kf-metric-card__badge{padding:2px var(--kf-space-xs);border-radius:var(--kf-radius-pill);background:var(--kf-color-success-soft)}.kf-metric-card__foot{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-metric-card__actions:empty{display:none}.kf-metric-card__actions{display:flex;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm);margin-top:auto}.kf-metric-card__actions--loading{visibility:hidden}\n"], dependencies: [{ kind: "component", type: Card, selector: "kf-card", inputs: ["flush", "gap", "loading"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "component", type: Text, selector: "kf-text", inputs: ["as", "variant", "tone"] }] });
6942
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: MetricCard, isStandalone: true, selector: "kf-metric-card", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, foot: { classPropertyName: "foot", publicName: "foot", isSignal: true, isRequired: false, transformFunction: null }, valueColor: { classPropertyName: "valueColor", publicName: "valueColor", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-busy": "loading() ? 'true' : null" } }, ngImport: i0, template: "<kf-card>\n <div class=\"kf-metric-card__head\">\n @if (loading()) {\n <span\n class=\"kf-metric-card__label-bone kf-bone\"\n style=\"--kf-bone-width: 45%\"\n aria-hidden=\"true\"\n >\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n </span>\n @if (icon()) {\n <span class=\"kf-metric-card__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n }\n } @else {\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n @if (loading()) {\n <div class=\"kf-metric-card__value kf-bone\" style=\"--kf-bone-width: 50%\" aria-hidden=\"true\">\n {{ value() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">\n <kf-text as=\"span\" variant=\"overline-strong\" tone=\"ok\">{{ badge() }}</kf-text>\n </span>\n }\n }\n </div>\n @if (foot()) {\n @if (loading()) {\n <div class=\"kf-metric-card__foot kf-bone\" style=\"--kf-bone-width: 60%\" aria-hidden=\"true\">\n {{ foot() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n }\n <div class=\"kf-metric-card__actions\" [class.kf-metric-card__actions--loading]=\"loading()\">\n <ng-content select=\"[actions]\" />\n </div>\n</kf-card>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-metric-card__head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--kf-space-xs)}.kf-metric-card__icon{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border-radius:var(--kf-radius-sm);background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-metric-card__value-row{display:flex;align-items:center;gap:var(--kf-space-xs)}.kf-metric-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:1.6rem;line-height:1.1;color:var(--kf-color-ink)}.kf-metric-card__unit{font-size:.85rem;font-weight:500;color:var(--kf-color-text-muted);margin-left:var(--kf-space-xs)}.kf-metric-card__badge{padding:2px var(--kf-space-xs);border-radius:var(--kf-radius-pill);background:var(--kf-color-success-soft)}.kf-metric-card__foot{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-metric-card__actions:empty{display:none}.kf-metric-card__actions{display:flex;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm);margin-top:auto}.kf-metric-card__actions--loading{visibility:hidden}\n"], dependencies: [{ kind: "component", type: Card, selector: "kf-card", inputs: ["flush", "gap", "loading"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "component", type: Text, selector: "kf-text", inputs: ["as", "variant", "tone"] }] });
6482
6943
  }
6483
6944
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MetricCard, decorators: [{
6484
6945
  type: Component,
6485
6946
  args: [{ selector: 'kf-metric-card', imports: [Card, Icon, Text], host: {
6486
6947
  '[attr.aria-busy]': "loading() ? 'true' : null",
6487
- }, template: "<kf-card>\n <div class=\"kf-metric-card__head\">\n @if (loading()) {\n <span\n class=\"kf-metric-card__label-bone kf-bone\"\n style=\"--kf-bone-width: 45%\"\n aria-hidden=\"true\"\n >\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n </span>\n @if (icon()) {\n <span class=\"kf-metric-card__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n }\n } @else {\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n @if (loading()) {\n <div class=\"kf-metric-card__value kf-bone\" style=\"--kf-bone-width: 50%\" aria-hidden=\"true\">\n {{ value() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">\n <kf-text as=\"span\" variant=\"overline-strong\" tone=\"ok\">{{ badge() }}</kf-text>\n </span>\n }\n }\n </div>\n @if (foot()) {\n @if (loading()) {\n <div class=\"kf-metric-card__foot kf-bone\" style=\"--kf-bone-width: 60%\" aria-hidden=\"true\">\n {{ foot() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n }\n <div class=\"kf-metric-card__actions\" [class.kf-metric-card__actions--loading]=\"loading()\">\n <ng-content select=\"[actions]\" />\n </div>\n</kf-card>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-metric-card__head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--kf-space-xs)}.kf-metric-card__icon{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border-radius:var(--kf-radius-sm);background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-metric-card__value-row{display:flex;align-items:center;gap:var(--kf-space-xs)}.kf-metric-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:1.6rem;line-height:1.1;color:var(--kf-color-ink)}.kf-metric-card__unit{font-size:.85rem;font-weight:500;color:var(--kf-color-text-muted);margin-left:var(--kf-space-xs)}.kf-metric-card__badge{padding:2px var(--kf-space-xs);border-radius:var(--kf-radius-pill);background:var(--kf-color-success-soft)}.kf-metric-card__foot{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-metric-card__actions:empty{display:none}.kf-metric-card__actions{display:flex;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm);margin-top:auto}.kf-metric-card__actions--loading{visibility:hidden}\n"] }]
6948
+ }, template: "<kf-card>\n <div class=\"kf-metric-card__head\">\n @if (loading()) {\n <span\n class=\"kf-metric-card__label-bone kf-bone\"\n style=\"--kf-bone-width: 45%\"\n aria-hidden=\"true\"\n >\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n </span>\n @if (icon()) {\n <span class=\"kf-metric-card__icon kf-bone-fill\" aria-hidden=\"true\"></span>\n }\n } @else {\n <kf-text as=\"span\" variant=\"overline-strong\">{{ label() }}</kf-text>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n @if (loading()) {\n <div class=\"kf-metric-card__value kf-bone\" style=\"--kf-bone-width: 50%\" aria-hidden=\"true\">\n {{ value() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">\n <kf-text as=\"span\" variant=\"overline-strong\" tone=\"ok\">{{ badge() }}</kf-text>\n </span>\n }\n }\n </div>\n @if (foot()) {\n @if (loading()) {\n <div class=\"kf-metric-card__foot kf-bone\" style=\"--kf-bone-width: 60%\" aria-hidden=\"true\">\n {{ foot() }}\n </div>\n } @else {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n }\n <div class=\"kf-metric-card__actions\" [class.kf-metric-card__actions--loading]=\"loading()\">\n <ng-content select=\"[actions]\" />\n </div>\n</kf-card>\n", styles: [".kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{background:linear-gradient(90deg,var(--kf-color-border) 25%,var(--kf-color-surface) 37%,var(--kf-color-border) 63%);background-size:400% 100%;animation:kf-bone-shimmer 1.4s ease infinite}.kf-bone{display:block;box-sizing:border-box;width:var(--kf-bone-width, 60%);max-width:100%;overflow:hidden;white-space:nowrap;border-radius:var(--kf-radius-xs);-webkit-user-select:none;user-select:none;pointer-events:none}.kf-bone.kf-bone{color:transparent!important}.kf-bone>*{visibility:hidden}@keyframes kf-bone-shimmer{0%{background-position:100% 0}to{background-position:0 0}}@media(prefers-reduced-motion:reduce){.kf-bone.kf-bone,.kf-bone-fill.kf-bone-fill,.kf-bone-overlay.kf-bone-overlay:after{animation:none;background:var(--kf-color-border)}}:host{display:block}.kf-metric-card__head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--kf-space-xs)}.kf-metric-card__icon{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border-radius:var(--kf-radius-sm);background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-metric-card__value-row{display:flex;align-items:center;gap:var(--kf-space-xs)}.kf-metric-card__value{font-family:var(--kf-font-title);font-weight:700;font-size:1.6rem;line-height:1.1;color:var(--kf-color-ink)}.kf-metric-card__unit{font-size:.85rem;font-weight:500;color:var(--kf-color-text-muted);margin-left:var(--kf-space-xs)}.kf-metric-card__badge{padding:2px var(--kf-space-xs);border-radius:var(--kf-radius-pill);background:var(--kf-color-success-soft)}.kf-metric-card__foot{font-size:.78rem;color:var(--kf-color-text-muted)}.kf-metric-card__actions:empty{display:none}.kf-metric-card__actions{display:flex;gap:var(--kf-space-sm);margin-top:var(--kf-space-sm);margin-top:auto}.kf-metric-card__actions--loading{visibility:hidden}\n"] }]
6488
6949
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], foot: [{ type: i0.Input, args: [{ isSignal: true, alias: "foot", required: false }] }], valueColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueColor", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
6489
6950
 
6490
6951
  const PROGRESS_STATUS = {
@@ -7705,6 +8166,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
7705
8166
  * userInitials="TS"
7706
8167
  * userName="Tomás Soto"
7707
8168
  * [showCart]="true"
8169
+ * [cartCount]="3"
7708
8170
  * (cartClick)="onCartClick()"
7709
8171
  * >
7710
8172
  * <kf-drawer-session
@@ -7743,8 +8205,23 @@ class PortalHeader {
7743
8205
  userName = input('', /* @ts-ignore */
7744
8206
  ...(ngDevMode ? [{ debugName: "userName" }] : /* istanbul ignore next */ []));
7745
8207
  showCart = input(false, { ...(ngDevMode ? { debugName: "showCart" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8208
+ /** Cantidad de ítems en el carrito. Con 0 (default) no se muestra el
8209
+ * contador; sobre 99 se muestra "99+". */
8210
+ cartCount = input(0, { ...(ngDevMode ? { debugName: "cartCount" } : /* istanbul ignore next */ {}), transform: numberAttribute });
7746
8211
  sessionClick = output();
7747
8212
  cartClick = output();
8213
+ cartCountLabel = computed(() => {
8214
+ const count = this.cartCount();
8215
+ return count > 99 ? '99+' : String(count);
8216
+ }, /* @ts-ignore */
8217
+ ...(ngDevMode ? [{ debugName: "cartCountLabel" }] : /* istanbul ignore next */ []));
8218
+ cartAriaLabel = computed(() => {
8219
+ const count = this.cartCount();
8220
+ if (count <= 0)
8221
+ return 'Carrito de compras';
8222
+ return `Carrito de compras, ${count} ${count === 1 ? 'elemento' : 'elementos'}`;
8223
+ }, /* @ts-ignore */
8224
+ ...(ngDevMode ? [{ debugName: "cartAriaLabel" }] : /* istanbul ignore next */ []));
7748
8225
  /** Visibilidad del drawer de navegación mobile (bajo los 768px). Se pasa a
7749
8226
  * `kf-drawer` como `[(open)]` — `PortalHeader` ya no implementa overlay,
7750
8227
  * `Escape` ni atrapado de foco por su cuenta, eso vive en `Drawer`. */
@@ -7804,12 +8281,12 @@ class PortalHeader {
7804
8281
  }, /* @ts-ignore */
7805
8282
  ...(ngDevMode ? [{ debugName: "thumbStyle" }] : /* istanbul ignore next */ []));
7806
8283
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PortalHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
7807
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: PortalHeader, isStandalone: true, selector: "kf-portal-header", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: false, transformFunction: null }, logoSrc: { classPropertyName: "logoSrc", publicName: "logoSrc", isSignal: true, isRequired: false, transformFunction: null }, logoAlt: { classPropertyName: "logoAlt", publicName: "logoAlt", isSignal: true, isRequired: false, transformFunction: null }, isAdmin: { classPropertyName: "isAdmin", publicName: "isAdmin", isSignal: true, isRequired: false, transformFunction: null }, adminActions: { classPropertyName: "adminActions", publicName: "adminActions", isSignal: true, isRequired: false, transformFunction: null }, navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, userInitials: { classPropertyName: "userInitials", publicName: "userInitials", isSignal: true, isRequired: true, transformFunction: null }, tagline: { classPropertyName: "tagline", publicName: "tagline", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, showCart: { classPropertyName: "showCart", publicName: "showCart", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sessionClick: "sessionClick", cartClick: "cartClick" }, host: { listeners: { "window:resize": "onWindowResize()" } }, viewQueries: [{ propertyName: "sessionButtonRef", first: true, predicate: ["sessionButton"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "navItemAnchors", predicate: ["navItemAnchor"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <div class=\"kf-portal-header__admin-inner\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n </div>\n}\n<div class=\"kf-portal-header__brand-bar\">\n <div class=\"kf-portal-header__brand-inner\">\n <div class=\"kf-portal-header__top-row\">\n <div class=\"kf-portal-header__logo-group\">\n @if (logoSrc()) {\n <img class=\"kf-portal-header__logo-img\" [src]=\"logoSrc()\" [alt]=\"logoAlt() || brand()\" />\n } @else {\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n }\n @if (tagline()) {\n <span class=\"kf-portal-header__logo-sep\" aria-hidden=\"true\"></span>\n <span class=\"kf-portal-header__logo-tag\">{{ tagline() }}</span>\n }\n </div>\n\n <div class=\"kf-portal-header__actions\">\n @if (showCart()) {\n <button\n type=\"button\"\n class=\"kf-portal-header__cart\"\n aria-label=\"Carrito de compras\"\n (click)=\"cartClick.emit()\"\n >\n <kf-icon name=\"cart\" size=\"md\" />\n </button>\n }\n\n <button\n #sessionButton\n type=\"button\"\n class=\"kf-portal-header__session\"\n [class.kf-portal-header__session--expanded]=\"userName()\"\n (click)=\"sessionClick.emit()\"\n >\n @if (userName()) {\n <kf-avatar [initials]=\"userInitials()\" />\n <span class=\"kf-portal-header__session-who\">\n <span class=\"kf-portal-header__session-greeting\">Hola</span>\n <span class=\"kf-portal-header__session-name\">{{ userName() }}</span>\n </span>\n <kf-icon name=\"chevron-down\" size=\"sm\" class=\"kf-portal-header__session-chevron\" />\n } @else {\n <kf-avatar [initials]=\"userInitials()\" pill />\n }\n </button>\n\n <button\n type=\"button\"\n class=\"kf-portal-header__menu-toggle\"\n [attr.aria-expanded]=\"mobileMenuOpen()\"\n aria-label=\"Abrir men\u00FA de navegaci\u00F3n\"\n (click)=\"mobileMenuOpen.set(!mobileMenuOpen())\"\n >\n <kf-icon [name]=\"mobileMenuOpen() ? 'x' : 'menu'\" size=\"md\" />\n </button>\n </div>\n </div>\n\n <nav class=\"kf-portal-header__nav\">\n <span class=\"kf-portal-header__nav-thumb\" [style]=\"thumbStyle()\" aria-hidden=\"true\"></span>\n @for (item of navItems(); track item.label) {\n <a\n #navItemAnchor\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n </div>\n</div>\n\n<kf-drawer [(open)]=\"mobileMenuOpen\" ariaLabel=\"Men\u00FA de navegaci\u00F3n\">\n <div kf-drawer-header>\n <ng-content select=\"[kf-portal-header-extra]\" />\n </div>\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__mobile-nav-item\"\n [class.kf-portal-header__mobile-nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n (click)=\"mobileMenuOpen.set(false)\"\n >\n @if (item.icon) {\n <kf-icon [name]=\"item.icon\" size=\"sm\" />\n }\n <span class=\"kf-portal-header__mobile-nav-item-label\">{{ item.label }}</span>\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n <div kf-drawer-footer>\n <ng-content select=\"[kf-portal-header-footer]\" />\n </div>\n</kf-drawer>\n", styles: [":host{display:block;position:sticky;top:0;z-index:30;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{padding-block:var(--kf-space-xs);background:var(--kf-color-tertiary-deep)}.kf-portal-header__admin-inner{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__admin-actions{display:flex;gap:var(--kf-space-md)}.kf-portal-header__admin-action{font-size:.8125rem;font-weight:600;color:#ffffffd9;text-decoration:none}.kf-portal-header__admin-action:hover{color:var(--kf-color-white)}.kf-portal-header__brand-bar{background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.kf-portal-header__brand-inner{display:flex;flex-direction:column;max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__top-row{display:flex;align-items:center;gap:var(--kf-space-lg);min-height:60px;padding-block:var(--kf-space-sm) 4px}.kf-portal-header__logo-group{display:flex;align-items:center;gap:var(--kf-space-md);flex:1 1 auto;min-width:0}.kf-portal-header__logo{font-family:var(--kf-font-title);font-size:1.25rem;font-weight:700;letter-spacing:.02em;color:var(--kf-color-white);text-transform:uppercase}.kf-portal-header__logo-img{height:28px;width:auto;display:block}.kf-portal-header__logo-sep{flex:none;width:1px;height:30px;background:#fff3}.kf-portal-header__logo-tag{font-family:var(--kf-font-title);font-weight:400;font-size:1.1875rem;color:#ffffffc7}.kf-portal-header__actions{margin-left:auto;display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-portal-header__cart{flex:none;width:46px;height:46px;border-radius:var(--kf-radius-pill);border:1px solid rgba(255,255,255,.18);background:transparent;color:var(--kf-color-white);display:grid;place-items:center;cursor:pointer}.kf-portal-header__cart:hover{background:#ffffff1a;border-color:#ffffff4d}.kf-portal-header__nav{display:flex;align-items:center;gap:2px;padding:4px;margin-bottom:var(--kf-space-sm);background:#ffffff14;border-radius:var(--kf-radius-pill);width:fit-content;max-width:100%;position:relative}.kf-portal-header__nav-thumb{position:absolute;top:4px;bottom:4px;left:0;background:var(--kf-color-white);border-radius:var(--kf-radius-pill);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1),opacity .15s linear;pointer-events:none}.kf-portal-header__nav-item{position:relative;padding:var(--kf-space-sm) var(--kf-space-md);border-radius:var(--kf-radius-pill);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;white-space:nowrap;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active){color:var(--kf-color-white);background:#ffffff14}.kf-portal-header__nav-item--active{color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}.kf-portal-header__session--expanded{display:flex;align-items:center;gap:var(--kf-space-sm);padding:7px 12px 7px 8px;background:var(--kf-color-primary);border-radius:var(--kf-radius-pill)}.kf-portal-header__session--expanded:hover{background:var(--kf-color-primary-active)}.kf-portal-header__session-who{display:flex;flex-direction:column;line-height:1.2;color:var(--kf-color-white)}.kf-portal-header__session-greeting{font-size:.65625rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#ffffffb3}.kf-portal-header__session-name{font-size:.875rem;font-weight:700;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-portal-header__session-chevron{color:#ffffffd9}.kf-portal-header__menu-toggle{display:none;flex:none;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-white);cursor:pointer}.kf-portal-header__menu-toggle:hover{background:#ffffff1a}.kf-portal-header__mobile-nav-item{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-xs);color:var(--kf-color-text);font-size:.9375rem;font-weight:600;text-decoration:none;border-radius:var(--kf-radius-sm)}.kf-portal-header__mobile-nav-item:hover{background:var(--kf-color-surface)}.kf-portal-header__mobile-nav-item--active{color:var(--kf-color-primary-active);background:var(--kf-color-primary-soft)}.kf-portal-header__mobile-nav-item-label{flex:1 1 auto}.kf-portal-header__mobile-nav-item kf-icon:last-child{color:#171d2559}@media(max-width:768px){.kf-portal-header__nav,.kf-portal-header__session{display:none}.kf-portal-header__menu-toggle{display:inline-flex}}\n"], dependencies: [{ kind: "component", type: AdminBadge, selector: "kf-admin-badge", inputs: ["inline"] }, { kind: "component", type: Avatar, selector: "kf-avatar", inputs: ["initials", "src", "round", "pill"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "component", type: Drawer, selector: "kf-drawer", inputs: ["open", "side", "role", "ariaLabel", "title", "closeLabel"], outputs: ["openChange"] }] });
8284
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: PortalHeader, isStandalone: true, selector: "kf-portal-header", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: false, transformFunction: null }, logoSrc: { classPropertyName: "logoSrc", publicName: "logoSrc", isSignal: true, isRequired: false, transformFunction: null }, logoAlt: { classPropertyName: "logoAlt", publicName: "logoAlt", isSignal: true, isRequired: false, transformFunction: null }, isAdmin: { classPropertyName: "isAdmin", publicName: "isAdmin", isSignal: true, isRequired: false, transformFunction: null }, adminActions: { classPropertyName: "adminActions", publicName: "adminActions", isSignal: true, isRequired: false, transformFunction: null }, navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, userInitials: { classPropertyName: "userInitials", publicName: "userInitials", isSignal: true, isRequired: true, transformFunction: null }, tagline: { classPropertyName: "tagline", publicName: "tagline", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, showCart: { classPropertyName: "showCart", publicName: "showCart", isSignal: true, isRequired: false, transformFunction: null }, cartCount: { classPropertyName: "cartCount", publicName: "cartCount", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sessionClick: "sessionClick", cartClick: "cartClick" }, host: { listeners: { "window:resize": "onWindowResize()" } }, viewQueries: [{ propertyName: "sessionButtonRef", first: true, predicate: ["sessionButton"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "navItemAnchors", predicate: ["navItemAnchor"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <div class=\"kf-portal-header__admin-inner\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n </div>\n}\n<div class=\"kf-portal-header__brand-bar\">\n <div class=\"kf-portal-header__brand-inner\">\n <div class=\"kf-portal-header__top-row\">\n <div class=\"kf-portal-header__logo-group\">\n @if (logoSrc()) {\n <img class=\"kf-portal-header__logo-img\" [src]=\"logoSrc()\" [alt]=\"logoAlt() || brand()\" />\n } @else {\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n }\n @if (tagline()) {\n <span class=\"kf-portal-header__logo-sep\" aria-hidden=\"true\"></span>\n <span class=\"kf-portal-header__logo-tag\">{{ tagline() }}</span>\n }\n </div>\n\n <div class=\"kf-portal-header__actions\">\n @if (showCart()) {\n <button\n type=\"button\"\n class=\"kf-portal-header__cart\"\n [attr.aria-label]=\"cartAriaLabel()\"\n (click)=\"cartClick.emit()\"\n >\n <kf-icon name=\"cart\" size=\"md\" />\n @if (cartCount() > 0) {\n <span class=\"kf-portal-header__cart-count\" aria-hidden=\"true\">{{\n cartCountLabel()\n }}</span>\n }\n </button>\n }\n\n <button\n #sessionButton\n type=\"button\"\n class=\"kf-portal-header__session\"\n [class.kf-portal-header__session--expanded]=\"userName()\"\n (click)=\"sessionClick.emit()\"\n >\n @if (userName()) {\n <kf-avatar [initials]=\"userInitials()\" />\n <span class=\"kf-portal-header__session-who\">\n <span class=\"kf-portal-header__session-greeting\">Hola</span>\n <span class=\"kf-portal-header__session-name\">{{ userName() }}</span>\n </span>\n <kf-icon name=\"chevron-down\" size=\"sm\" class=\"kf-portal-header__session-chevron\" />\n } @else {\n <kf-avatar [initials]=\"userInitials()\" pill />\n }\n </button>\n\n <button\n type=\"button\"\n class=\"kf-portal-header__menu-toggle\"\n [attr.aria-expanded]=\"mobileMenuOpen()\"\n aria-label=\"Abrir men\u00FA de navegaci\u00F3n\"\n (click)=\"mobileMenuOpen.set(!mobileMenuOpen())\"\n >\n <kf-icon [name]=\"mobileMenuOpen() ? 'x' : 'menu'\" size=\"md\" />\n </button>\n </div>\n </div>\n\n <nav class=\"kf-portal-header__nav\">\n <span class=\"kf-portal-header__nav-thumb\" [style]=\"thumbStyle()\" aria-hidden=\"true\"></span>\n @for (item of navItems(); track item.label) {\n <a\n #navItemAnchor\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n </div>\n</div>\n\n<kf-drawer [(open)]=\"mobileMenuOpen\" ariaLabel=\"Men\u00FA de navegaci\u00F3n\">\n <div kf-drawer-header>\n <ng-content select=\"[kf-portal-header-extra]\" />\n </div>\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__mobile-nav-item\"\n [class.kf-portal-header__mobile-nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n (click)=\"mobileMenuOpen.set(false)\"\n >\n @if (item.icon) {\n <kf-icon [name]=\"item.icon\" size=\"sm\" />\n }\n <span class=\"kf-portal-header__mobile-nav-item-label\">{{ item.label }}</span>\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n <div kf-drawer-footer>\n <ng-content select=\"[kf-portal-header-footer]\" />\n </div>\n</kf-drawer>\n", styles: [":host{display:block;position:sticky;top:0;z-index:30;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{padding-block:var(--kf-space-xs);background:var(--kf-color-tertiary-deep)}.kf-portal-header__admin-inner{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__admin-actions{display:flex;gap:var(--kf-space-md)}.kf-portal-header__admin-action{font-size:.8125rem;font-weight:600;color:#ffffffd9;text-decoration:none}.kf-portal-header__admin-action:hover{color:var(--kf-color-white)}.kf-portal-header__brand-bar{background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.kf-portal-header__brand-inner{display:flex;flex-direction:column;max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__top-row{display:flex;align-items:center;gap:var(--kf-space-lg);min-height:60px;padding-block:var(--kf-space-sm) 4px}.kf-portal-header__logo-group{display:flex;align-items:center;gap:var(--kf-space-md);flex:1 1 auto;min-width:0}.kf-portal-header__logo{font-family:var(--kf-font-title);font-size:1.25rem;font-weight:700;letter-spacing:.02em;color:var(--kf-color-white);text-transform:uppercase}.kf-portal-header__logo-img{height:28px;width:auto;display:block}.kf-portal-header__logo-sep{flex:none;width:1px;height:30px;background:#fff3}.kf-portal-header__logo-tag{font-family:var(--kf-font-title);font-weight:400;font-size:1.1875rem;color:#ffffffc7}.kf-portal-header__actions{margin-left:auto;display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-portal-header__cart{position:relative;flex:none;width:46px;height:46px;border-radius:var(--kf-radius-pill);border:1px solid rgba(255,255,255,.18);background:transparent;color:var(--kf-color-white);display:grid;place-items:center;cursor:pointer}.kf-portal-header__cart-count{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 5px;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;border:2px solid var(--kf-color-tertiary-deep);border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.6875rem;font-weight:700;line-height:1;pointer-events:none}.kf-portal-header__cart:hover{background:#ffffff1a;border-color:#ffffff4d}.kf-portal-header__nav{display:flex;align-items:center;gap:2px;padding:4px;margin-bottom:var(--kf-space-sm);background:#ffffff14;border-radius:var(--kf-radius-pill);width:fit-content;max-width:100%;position:relative}.kf-portal-header__nav-thumb{position:absolute;top:4px;bottom:4px;left:0;background:var(--kf-color-white);border-radius:var(--kf-radius-pill);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1),opacity .15s linear;pointer-events:none}.kf-portal-header__nav-item{position:relative;padding:var(--kf-space-sm) var(--kf-space-md);border-radius:var(--kf-radius-pill);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;white-space:nowrap;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active){color:var(--kf-color-white);background:#ffffff14}.kf-portal-header__nav-item--active{color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}.kf-portal-header__session--expanded{display:flex;align-items:center;gap:var(--kf-space-sm);padding:7px 12px 7px 8px;background:var(--kf-color-primary);border-radius:var(--kf-radius-pill)}.kf-portal-header__session--expanded:hover{background:var(--kf-color-primary-active)}.kf-portal-header__session-who{display:flex;flex-direction:column;line-height:1.2;color:var(--kf-color-white)}.kf-portal-header__session-greeting{font-size:.65625rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#ffffffb3}.kf-portal-header__session-name{font-size:.875rem;font-weight:700;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-portal-header__session-chevron{color:#ffffffd9}.kf-portal-header__menu-toggle{display:none;flex:none;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-white);cursor:pointer}.kf-portal-header__menu-toggle:hover{background:#ffffff1a}.kf-portal-header__mobile-nav-item{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-xs);color:var(--kf-color-text);font-size:.9375rem;font-weight:600;text-decoration:none;border-radius:var(--kf-radius-sm)}.kf-portal-header__mobile-nav-item:hover{background:var(--kf-color-surface)}.kf-portal-header__mobile-nav-item--active{color:var(--kf-color-primary-active);background:var(--kf-color-primary-soft)}.kf-portal-header__mobile-nav-item-label{flex:1 1 auto}.kf-portal-header__mobile-nav-item kf-icon:last-child{color:#171d2559}@media(max-width:768px){.kf-portal-header__nav,.kf-portal-header__session{display:none}.kf-portal-header__menu-toggle{display:inline-flex}}\n"], dependencies: [{ kind: "component", type: AdminBadge, selector: "kf-admin-badge", inputs: ["inline"] }, { kind: "component", type: Avatar, selector: "kf-avatar", inputs: ["initials", "src", "round", "pill"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "component", type: Drawer, selector: "kf-drawer", inputs: ["open", "side", "role", "ariaLabel", "title", "closeLabel"], outputs: ["openChange"] }] });
7808
8285
  }
7809
8286
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PortalHeader, decorators: [{
7810
8287
  type: Component,
7811
- args: [{ selector: 'kf-portal-header', imports: [AdminBadge, Avatar, Icon, Drawer], template: "@if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <div class=\"kf-portal-header__admin-inner\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n </div>\n}\n<div class=\"kf-portal-header__brand-bar\">\n <div class=\"kf-portal-header__brand-inner\">\n <div class=\"kf-portal-header__top-row\">\n <div class=\"kf-portal-header__logo-group\">\n @if (logoSrc()) {\n <img class=\"kf-portal-header__logo-img\" [src]=\"logoSrc()\" [alt]=\"logoAlt() || brand()\" />\n } @else {\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n }\n @if (tagline()) {\n <span class=\"kf-portal-header__logo-sep\" aria-hidden=\"true\"></span>\n <span class=\"kf-portal-header__logo-tag\">{{ tagline() }}</span>\n }\n </div>\n\n <div class=\"kf-portal-header__actions\">\n @if (showCart()) {\n <button\n type=\"button\"\n class=\"kf-portal-header__cart\"\n aria-label=\"Carrito de compras\"\n (click)=\"cartClick.emit()\"\n >\n <kf-icon name=\"cart\" size=\"md\" />\n </button>\n }\n\n <button\n #sessionButton\n type=\"button\"\n class=\"kf-portal-header__session\"\n [class.kf-portal-header__session--expanded]=\"userName()\"\n (click)=\"sessionClick.emit()\"\n >\n @if (userName()) {\n <kf-avatar [initials]=\"userInitials()\" />\n <span class=\"kf-portal-header__session-who\">\n <span class=\"kf-portal-header__session-greeting\">Hola</span>\n <span class=\"kf-portal-header__session-name\">{{ userName() }}</span>\n </span>\n <kf-icon name=\"chevron-down\" size=\"sm\" class=\"kf-portal-header__session-chevron\" />\n } @else {\n <kf-avatar [initials]=\"userInitials()\" pill />\n }\n </button>\n\n <button\n type=\"button\"\n class=\"kf-portal-header__menu-toggle\"\n [attr.aria-expanded]=\"mobileMenuOpen()\"\n aria-label=\"Abrir men\u00FA de navegaci\u00F3n\"\n (click)=\"mobileMenuOpen.set(!mobileMenuOpen())\"\n >\n <kf-icon [name]=\"mobileMenuOpen() ? 'x' : 'menu'\" size=\"md\" />\n </button>\n </div>\n </div>\n\n <nav class=\"kf-portal-header__nav\">\n <span class=\"kf-portal-header__nav-thumb\" [style]=\"thumbStyle()\" aria-hidden=\"true\"></span>\n @for (item of navItems(); track item.label) {\n <a\n #navItemAnchor\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n </div>\n</div>\n\n<kf-drawer [(open)]=\"mobileMenuOpen\" ariaLabel=\"Men\u00FA de navegaci\u00F3n\">\n <div kf-drawer-header>\n <ng-content select=\"[kf-portal-header-extra]\" />\n </div>\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__mobile-nav-item\"\n [class.kf-portal-header__mobile-nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n (click)=\"mobileMenuOpen.set(false)\"\n >\n @if (item.icon) {\n <kf-icon [name]=\"item.icon\" size=\"sm\" />\n }\n <span class=\"kf-portal-header__mobile-nav-item-label\">{{ item.label }}</span>\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n <div kf-drawer-footer>\n <ng-content select=\"[kf-portal-header-footer]\" />\n </div>\n</kf-drawer>\n", styles: [":host{display:block;position:sticky;top:0;z-index:30;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{padding-block:var(--kf-space-xs);background:var(--kf-color-tertiary-deep)}.kf-portal-header__admin-inner{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__admin-actions{display:flex;gap:var(--kf-space-md)}.kf-portal-header__admin-action{font-size:.8125rem;font-weight:600;color:#ffffffd9;text-decoration:none}.kf-portal-header__admin-action:hover{color:var(--kf-color-white)}.kf-portal-header__brand-bar{background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.kf-portal-header__brand-inner{display:flex;flex-direction:column;max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__top-row{display:flex;align-items:center;gap:var(--kf-space-lg);min-height:60px;padding-block:var(--kf-space-sm) 4px}.kf-portal-header__logo-group{display:flex;align-items:center;gap:var(--kf-space-md);flex:1 1 auto;min-width:0}.kf-portal-header__logo{font-family:var(--kf-font-title);font-size:1.25rem;font-weight:700;letter-spacing:.02em;color:var(--kf-color-white);text-transform:uppercase}.kf-portal-header__logo-img{height:28px;width:auto;display:block}.kf-portal-header__logo-sep{flex:none;width:1px;height:30px;background:#fff3}.kf-portal-header__logo-tag{font-family:var(--kf-font-title);font-weight:400;font-size:1.1875rem;color:#ffffffc7}.kf-portal-header__actions{margin-left:auto;display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-portal-header__cart{flex:none;width:46px;height:46px;border-radius:var(--kf-radius-pill);border:1px solid rgba(255,255,255,.18);background:transparent;color:var(--kf-color-white);display:grid;place-items:center;cursor:pointer}.kf-portal-header__cart:hover{background:#ffffff1a;border-color:#ffffff4d}.kf-portal-header__nav{display:flex;align-items:center;gap:2px;padding:4px;margin-bottom:var(--kf-space-sm);background:#ffffff14;border-radius:var(--kf-radius-pill);width:fit-content;max-width:100%;position:relative}.kf-portal-header__nav-thumb{position:absolute;top:4px;bottom:4px;left:0;background:var(--kf-color-white);border-radius:var(--kf-radius-pill);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1),opacity .15s linear;pointer-events:none}.kf-portal-header__nav-item{position:relative;padding:var(--kf-space-sm) var(--kf-space-md);border-radius:var(--kf-radius-pill);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;white-space:nowrap;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active){color:var(--kf-color-white);background:#ffffff14}.kf-portal-header__nav-item--active{color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}.kf-portal-header__session--expanded{display:flex;align-items:center;gap:var(--kf-space-sm);padding:7px 12px 7px 8px;background:var(--kf-color-primary);border-radius:var(--kf-radius-pill)}.kf-portal-header__session--expanded:hover{background:var(--kf-color-primary-active)}.kf-portal-header__session-who{display:flex;flex-direction:column;line-height:1.2;color:var(--kf-color-white)}.kf-portal-header__session-greeting{font-size:.65625rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#ffffffb3}.kf-portal-header__session-name{font-size:.875rem;font-weight:700;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-portal-header__session-chevron{color:#ffffffd9}.kf-portal-header__menu-toggle{display:none;flex:none;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-white);cursor:pointer}.kf-portal-header__menu-toggle:hover{background:#ffffff1a}.kf-portal-header__mobile-nav-item{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-xs);color:var(--kf-color-text);font-size:.9375rem;font-weight:600;text-decoration:none;border-radius:var(--kf-radius-sm)}.kf-portal-header__mobile-nav-item:hover{background:var(--kf-color-surface)}.kf-portal-header__mobile-nav-item--active{color:var(--kf-color-primary-active);background:var(--kf-color-primary-soft)}.kf-portal-header__mobile-nav-item-label{flex:1 1 auto}.kf-portal-header__mobile-nav-item kf-icon:last-child{color:#171d2559}@media(max-width:768px){.kf-portal-header__nav,.kf-portal-header__session{display:none}.kf-portal-header__menu-toggle{display:inline-flex}}\n"] }]
7812
- }], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: false }] }], logoSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoSrc", required: false }] }], logoAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoAlt", required: false }] }], isAdmin: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAdmin", required: false }] }], adminActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "adminActions", required: false }] }], navItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "navItems", required: false }] }], userInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "userInitials", required: true }] }], tagline: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagline", required: false }] }], userName: [{ type: i0.Input, args: [{ isSignal: true, alias: "userName", required: false }] }], showCart: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCart", required: false }] }], sessionClick: [{ type: i0.Output, args: ["sessionClick"] }], cartClick: [{ type: i0.Output, args: ["cartClick"] }], sessionButtonRef: [{ type: i0.ViewChild, args: ['sessionButton', { ...{ read: ElementRef }, isSignal: true }] }], navItemAnchors: [{ type: i0.ViewChildren, args: ['navItemAnchor', { isSignal: true }] }], onWindowResize: [{
8288
+ args: [{ selector: 'kf-portal-header', imports: [AdminBadge, Avatar, Icon, Drawer], template: "@if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <div class=\"kf-portal-header__admin-inner\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n </div>\n}\n<div class=\"kf-portal-header__brand-bar\">\n <div class=\"kf-portal-header__brand-inner\">\n <div class=\"kf-portal-header__top-row\">\n <div class=\"kf-portal-header__logo-group\">\n @if (logoSrc()) {\n <img class=\"kf-portal-header__logo-img\" [src]=\"logoSrc()\" [alt]=\"logoAlt() || brand()\" />\n } @else {\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n }\n @if (tagline()) {\n <span class=\"kf-portal-header__logo-sep\" aria-hidden=\"true\"></span>\n <span class=\"kf-portal-header__logo-tag\">{{ tagline() }}</span>\n }\n </div>\n\n <div class=\"kf-portal-header__actions\">\n @if (showCart()) {\n <button\n type=\"button\"\n class=\"kf-portal-header__cart\"\n [attr.aria-label]=\"cartAriaLabel()\"\n (click)=\"cartClick.emit()\"\n >\n <kf-icon name=\"cart\" size=\"md\" />\n @if (cartCount() > 0) {\n <span class=\"kf-portal-header__cart-count\" aria-hidden=\"true\">{{\n cartCountLabel()\n }}</span>\n }\n </button>\n }\n\n <button\n #sessionButton\n type=\"button\"\n class=\"kf-portal-header__session\"\n [class.kf-portal-header__session--expanded]=\"userName()\"\n (click)=\"sessionClick.emit()\"\n >\n @if (userName()) {\n <kf-avatar [initials]=\"userInitials()\" />\n <span class=\"kf-portal-header__session-who\">\n <span class=\"kf-portal-header__session-greeting\">Hola</span>\n <span class=\"kf-portal-header__session-name\">{{ userName() }}</span>\n </span>\n <kf-icon name=\"chevron-down\" size=\"sm\" class=\"kf-portal-header__session-chevron\" />\n } @else {\n <kf-avatar [initials]=\"userInitials()\" pill />\n }\n </button>\n\n <button\n type=\"button\"\n class=\"kf-portal-header__menu-toggle\"\n [attr.aria-expanded]=\"mobileMenuOpen()\"\n aria-label=\"Abrir men\u00FA de navegaci\u00F3n\"\n (click)=\"mobileMenuOpen.set(!mobileMenuOpen())\"\n >\n <kf-icon [name]=\"mobileMenuOpen() ? 'x' : 'menu'\" size=\"md\" />\n </button>\n </div>\n </div>\n\n <nav class=\"kf-portal-header__nav\">\n <span class=\"kf-portal-header__nav-thumb\" [style]=\"thumbStyle()\" aria-hidden=\"true\"></span>\n @for (item of navItems(); track item.label) {\n <a\n #navItemAnchor\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n </div>\n</div>\n\n<kf-drawer [(open)]=\"mobileMenuOpen\" ariaLabel=\"Men\u00FA de navegaci\u00F3n\">\n <div kf-drawer-header>\n <ng-content select=\"[kf-portal-header-extra]\" />\n </div>\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__mobile-nav-item\"\n [class.kf-portal-header__mobile-nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n (click)=\"mobileMenuOpen.set(false)\"\n >\n @if (item.icon) {\n <kf-icon [name]=\"item.icon\" size=\"sm\" />\n }\n <span class=\"kf-portal-header__mobile-nav-item-label\">{{ item.label }}</span>\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n <div kf-drawer-footer>\n <ng-content select=\"[kf-portal-header-footer]\" />\n </div>\n</kf-drawer>\n", styles: [":host{display:block;position:sticky;top:0;z-index:30;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{padding-block:var(--kf-space-xs);background:var(--kf-color-tertiary-deep)}.kf-portal-header__admin-inner{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__admin-actions{display:flex;gap:var(--kf-space-md)}.kf-portal-header__admin-action{font-size:.8125rem;font-weight:600;color:#ffffffd9;text-decoration:none}.kf-portal-header__admin-action:hover{color:var(--kf-color-white)}.kf-portal-header__brand-bar{background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.kf-portal-header__brand-inner{display:flex;flex-direction:column;max-width:var(--kf-header-max-width, none);margin:0 auto;padding:0 var(--kf-space-lg)}.kf-portal-header__top-row{display:flex;align-items:center;gap:var(--kf-space-lg);min-height:60px;padding-block:var(--kf-space-sm) 4px}.kf-portal-header__logo-group{display:flex;align-items:center;gap:var(--kf-space-md);flex:1 1 auto;min-width:0}.kf-portal-header__logo{font-family:var(--kf-font-title);font-size:1.25rem;font-weight:700;letter-spacing:.02em;color:var(--kf-color-white);text-transform:uppercase}.kf-portal-header__logo-img{height:28px;width:auto;display:block}.kf-portal-header__logo-sep{flex:none;width:1px;height:30px;background:#fff3}.kf-portal-header__logo-tag{font-family:var(--kf-font-title);font-weight:400;font-size:1.1875rem;color:#ffffffc7}.kf-portal-header__actions{margin-left:auto;display:flex;align-items:center;gap:var(--kf-space-sm)}.kf-portal-header__cart{position:relative;flex:none;width:46px;height:46px;border-radius:var(--kf-radius-pill);border:1px solid rgba(255,255,255,.18);background:transparent;color:var(--kf-color-white);display:grid;place-items:center;cursor:pointer}.kf-portal-header__cart-count{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 5px;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;border:2px solid var(--kf-color-tertiary-deep);border-radius:var(--kf-radius-pill);background:var(--kf-color-primary);color:var(--kf-color-white);font-size:.6875rem;font-weight:700;line-height:1;pointer-events:none}.kf-portal-header__cart:hover{background:#ffffff1a;border-color:#ffffff4d}.kf-portal-header__nav{display:flex;align-items:center;gap:2px;padding:4px;margin-bottom:var(--kf-space-sm);background:#ffffff14;border-radius:var(--kf-radius-pill);width:fit-content;max-width:100%;position:relative}.kf-portal-header__nav-thumb{position:absolute;top:4px;bottom:4px;left:0;background:var(--kf-color-white);border-radius:var(--kf-radius-pill);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1),opacity .15s linear;pointer-events:none}.kf-portal-header__nav-item{position:relative;padding:var(--kf-space-sm) var(--kf-space-md);border-radius:var(--kf-radius-pill);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;white-space:nowrap;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active){color:var(--kf-color-white);background:#ffffff14}.kf-portal-header__nav-item--active{color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}.kf-portal-header__session--expanded{display:flex;align-items:center;gap:var(--kf-space-sm);padding:7px 12px 7px 8px;background:var(--kf-color-primary);border-radius:var(--kf-radius-pill)}.kf-portal-header__session--expanded:hover{background:var(--kf-color-primary-active)}.kf-portal-header__session-who{display:flex;flex-direction:column;line-height:1.2;color:var(--kf-color-white)}.kf-portal-header__session-greeting{font-size:.65625rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#ffffffb3}.kf-portal-header__session-name{font-size:.875rem;font-weight:700;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-portal-header__session-chevron{color:#ffffffd9}.kf-portal-header__menu-toggle{display:none;flex:none;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-white);cursor:pointer}.kf-portal-header__menu-toggle:hover{background:#ffffff1a}.kf-portal-header__mobile-nav-item{display:flex;align-items:center;gap:var(--kf-space-sm);padding:var(--kf-space-sm) var(--kf-space-xs);color:var(--kf-color-text);font-size:.9375rem;font-weight:600;text-decoration:none;border-radius:var(--kf-radius-sm)}.kf-portal-header__mobile-nav-item:hover{background:var(--kf-color-surface)}.kf-portal-header__mobile-nav-item--active{color:var(--kf-color-primary-active);background:var(--kf-color-primary-soft)}.kf-portal-header__mobile-nav-item-label{flex:1 1 auto}.kf-portal-header__mobile-nav-item kf-icon:last-child{color:#171d2559}@media(max-width:768px){.kf-portal-header__nav,.kf-portal-header__session{display:none}.kf-portal-header__menu-toggle{display:inline-flex}}\n"] }]
8289
+ }], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: false }] }], logoSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoSrc", required: false }] }], logoAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoAlt", required: false }] }], isAdmin: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAdmin", required: false }] }], adminActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "adminActions", required: false }] }], navItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "navItems", required: false }] }], userInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "userInitials", required: true }] }], tagline: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagline", required: false }] }], userName: [{ type: i0.Input, args: [{ isSignal: true, alias: "userName", required: false }] }], showCart: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCart", required: false }] }], cartCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "cartCount", required: false }] }], sessionClick: [{ type: i0.Output, args: ["sessionClick"] }], cartClick: [{ type: i0.Output, args: ["cartClick"] }], sessionButtonRef: [{ type: i0.ViewChild, args: ['sessionButton', { ...{ read: ElementRef }, isSignal: true }] }], navItemAnchors: [{ type: i0.ViewChildren, args: ['navItemAnchor', { isSignal: true }] }], onWindowResize: [{
7813
8290
  type: HostListener,
7814
8291
  args: ['window:resize']
7815
8292
  }] } });
@@ -8065,11 +8542,11 @@ class RowActions {
8065
8542
  this.menuOpen.set(false);
8066
8543
  }
8067
8544
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: RowActions, deps: [], target: i0.ɵɵFactoryTarget.Component });
8068
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: RowActions, isStandalone: true, selector: "kf-row-actions", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: true, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, inlineLimit: { classPropertyName: "inlineLimit", publicName: "inlineLimit", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (effectiveMode() === 'inline') {\n <div class=\"kf-row-actions kf-row-actions--inline\">\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a\n class=\"kf-row-actions__icon-btn\"\n [href]=\"action.href\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </a>\n } @else {\n <span\n class=\"kf-row-actions__icon-btn kf-row-actions__icon-btn--disabled\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </span>\n }\n } @else {\n <button\n type=\"button\"\n class=\"kf-row-actions__icon-btn\"\n [disabled]=\"action.disabled ?? false\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n (click)=\"action.onClick?.()\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </button>\n }\n }\n </div>\n} @else {\n <kf-dropdown class=\"kf-row-actions\" [(open)]=\"menuOpen\">\n <button\n type=\"button\"\n class=\"kf-row-actions__trigger\"\n [class.kf-row-actions__trigger--open]=\"menuOpen()\"\n [attr.aria-expanded]=\"menuOpen()\"\n aria-label=\"M\u00E1s acciones\"\n (click)=\"onToggleMenu()\"\n >\n <kf-icon name=\"more-vertical\" size=\"md\" />\n </button>\n <kf-dropdown-panel>\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a class=\"kf-row-actions__menu-link\" [href]=\"action.href\" (click)=\"onMenuLinkClick()\">\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </a>\n } @else {\n <span class=\"kf-row-actions__menu-link kf-row-actions__menu-link--disabled\">\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </span>\n }\n } @else {\n <kf-dropdown-item\n [icon]=\"action.icon\"\n [disabled]=\"action.disabled ?? false\"\n (click)=\"onButtonAction(action)\"\n >\n {{ action.label }}\n </kf-dropdown-item>\n }\n }\n </kf-dropdown-panel>\n </kf-dropdown>\n}\n", styles: [":host{display:inline-flex}.kf-row-actions{display:inline-flex}.kf-row-actions--inline{align-items:center;gap:2px}.kf-row-actions__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,color .14s}.kf-row-actions__icon-btn:hover{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-row-actions__icon-btn:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__icon-btn--disabled,.kf-row-actions__icon-btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.kf-row-actions__trigger{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-pill);background:var(--kf-color-white);color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,border-color .14s,color .14s}.kf-row-actions__trigger:hover{border-color:var(--kf-color-border-strong)}.kf-row-actions__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__trigger--open{background:var(--kf-color-primary-soft);border-color:var(--kf-color-primary);color:var(--kf-color-primary)}.kf-row-actions__menu-link{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none;cursor:pointer}.kf-row-actions__menu-link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-row-actions__menu-link-label{flex:1 1 auto}.kf-row-actions__menu-link:hover{background:var(--kf-color-surface)}.kf-row-actions__menu-link:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-row-actions__menu-link--disabled{opacity:.55;cursor:not-allowed;pointer-events:none}\n"], dependencies: [{ kind: "component", type: Dropdown, selector: "kf-dropdown", inputs: ["open", "anchor"], outputs: ["openChange"] }, { kind: "component", type: DropdownPanel, selector: "kf-dropdown-panel", inputs: ["variant"] }, { kind: "component", type: DropdownItem, selector: "kf-dropdown-item", inputs: ["tone", "icon", "disabled"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "directive", type: TooltipDirective, selector: "[kfTooltip]", inputs: ["kfTooltip", "kfTooltipPosition"] }] });
8545
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: RowActions, isStandalone: true, selector: "kf-row-actions", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: true, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, inlineLimit: { classPropertyName: "inlineLimit", publicName: "inlineLimit", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (effectiveMode() === 'inline') {\n <div class=\"kf-row-actions kf-row-actions--inline\">\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a\n class=\"kf-row-actions__icon-btn\"\n [href]=\"action.href\"\n [attr.aria-label]=\"action.label\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </a>\n } @else {\n <span\n class=\"kf-row-actions__icon-btn kf-row-actions__icon-btn--disabled\"\n role=\"link\"\n aria-disabled=\"true\"\n [attr.aria-label]=\"action.label\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </span>\n }\n } @else {\n <button\n type=\"button\"\n class=\"kf-row-actions__icon-btn\"\n [disabled]=\"action.disabled ?? false\"\n [attr.aria-label]=\"action.label\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n (click)=\"action.onClick?.()\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </button>\n }\n }\n </div>\n} @else {\n <kf-dropdown class=\"kf-row-actions\" [(open)]=\"menuOpen\">\n <button\n type=\"button\"\n class=\"kf-row-actions__trigger\"\n [class.kf-row-actions__trigger--open]=\"menuOpen()\"\n [attr.aria-expanded]=\"menuOpen()\"\n aria-label=\"M\u00E1s acciones\"\n (click)=\"onToggleMenu()\"\n >\n <kf-icon name=\"more-vertical\" size=\"md\" />\n </button>\n <kf-dropdown-panel>\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a\n class=\"kf-row-actions__menu-link\"\n role=\"menuitem\"\n [href]=\"action.href\"\n (click)=\"onMenuLinkClick()\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </a>\n } @else {\n <span\n class=\"kf-row-actions__menu-link kf-row-actions__menu-link--disabled\"\n role=\"menuitem\"\n aria-disabled=\"true\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </span>\n }\n } @else {\n <kf-dropdown-item\n [icon]=\"action.icon\"\n [disabled]=\"action.disabled ?? false\"\n (click)=\"onButtonAction(action)\"\n >\n {{ action.label }}\n </kf-dropdown-item>\n }\n }\n </kf-dropdown-panel>\n </kf-dropdown>\n}\n", styles: [":host{display:inline-flex}.kf-row-actions{display:inline-flex}.kf-row-actions--inline{align-items:center;gap:2px}.kf-row-actions__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,color .14s}.kf-row-actions__icon-btn:hover{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-row-actions__icon-btn:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__icon-btn--disabled,.kf-row-actions__icon-btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.kf-row-actions__trigger{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-pill);background:var(--kf-color-white);color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,border-color .14s,color .14s}.kf-row-actions__trigger:hover{border-color:var(--kf-color-border-strong)}.kf-row-actions__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__trigger--open{background:var(--kf-color-primary-soft);border-color:var(--kf-color-primary);color:var(--kf-color-primary)}.kf-row-actions__menu-link{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none;cursor:pointer}.kf-row-actions__menu-link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-row-actions__menu-link-label{flex:1 1 auto}.kf-row-actions__menu-link:hover{background:var(--kf-color-surface)}.kf-row-actions__menu-link:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus-inset)}.kf-row-actions__menu-link--disabled{opacity:.55;cursor:not-allowed;pointer-events:none}\n"], dependencies: [{ kind: "component", type: Dropdown, selector: "kf-dropdown", inputs: ["open", "anchor", "autoFocus"], outputs: ["openChange"] }, { kind: "component", type: DropdownPanel, selector: "kf-dropdown-panel", inputs: ["variant", "role", "ariaLabel"] }, { kind: "component", type: DropdownItem, selector: "kf-dropdown-item", inputs: ["tone", "icon", "disabled"] }, { kind: "component", type: Icon, selector: "kf-icon", inputs: ["name", "size", "rotate", "filled"] }, { kind: "directive", type: TooltipDirective, selector: "[kfTooltip]", inputs: ["kfTooltip", "kfTooltipPosition"] }] });
8069
8546
  }
8070
8547
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: RowActions, decorators: [{
8071
8548
  type: Component,
8072
- args: [{ selector: 'kf-row-actions', imports: [Dropdown, DropdownPanel, DropdownItem, Icon, TooltipDirective], template: "@if (effectiveMode() === 'inline') {\n <div class=\"kf-row-actions kf-row-actions--inline\">\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a\n class=\"kf-row-actions__icon-btn\"\n [href]=\"action.href\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </a>\n } @else {\n <span\n class=\"kf-row-actions__icon-btn kf-row-actions__icon-btn--disabled\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </span>\n }\n } @else {\n <button\n type=\"button\"\n class=\"kf-row-actions__icon-btn\"\n [disabled]=\"action.disabled ?? false\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n (click)=\"action.onClick?.()\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </button>\n }\n }\n </div>\n} @else {\n <kf-dropdown class=\"kf-row-actions\" [(open)]=\"menuOpen\">\n <button\n type=\"button\"\n class=\"kf-row-actions__trigger\"\n [class.kf-row-actions__trigger--open]=\"menuOpen()\"\n [attr.aria-expanded]=\"menuOpen()\"\n aria-label=\"M\u00E1s acciones\"\n (click)=\"onToggleMenu()\"\n >\n <kf-icon name=\"more-vertical\" size=\"md\" />\n </button>\n <kf-dropdown-panel>\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a class=\"kf-row-actions__menu-link\" [href]=\"action.href\" (click)=\"onMenuLinkClick()\">\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </a>\n } @else {\n <span class=\"kf-row-actions__menu-link kf-row-actions__menu-link--disabled\">\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </span>\n }\n } @else {\n <kf-dropdown-item\n [icon]=\"action.icon\"\n [disabled]=\"action.disabled ?? false\"\n (click)=\"onButtonAction(action)\"\n >\n {{ action.label }}\n </kf-dropdown-item>\n }\n }\n </kf-dropdown-panel>\n </kf-dropdown>\n}\n", styles: [":host{display:inline-flex}.kf-row-actions{display:inline-flex}.kf-row-actions--inline{align-items:center;gap:2px}.kf-row-actions__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,color .14s}.kf-row-actions__icon-btn:hover{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-row-actions__icon-btn:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__icon-btn--disabled,.kf-row-actions__icon-btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.kf-row-actions__trigger{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-pill);background:var(--kf-color-white);color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,border-color .14s,color .14s}.kf-row-actions__trigger:hover{border-color:var(--kf-color-border-strong)}.kf-row-actions__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__trigger--open{background:var(--kf-color-primary-soft);border-color:var(--kf-color-primary);color:var(--kf-color-primary)}.kf-row-actions__menu-link{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none;cursor:pointer}.kf-row-actions__menu-link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-row-actions__menu-link-label{flex:1 1 auto}.kf-row-actions__menu-link:hover{background:var(--kf-color-surface)}.kf-row-actions__menu-link:focus-visible{outline:none;box-shadow:inset var(--kf-shadow-focus)}.kf-row-actions__menu-link--disabled{opacity:.55;cursor:not-allowed;pointer-events:none}\n"] }]
8549
+ args: [{ selector: 'kf-row-actions', imports: [Dropdown, DropdownPanel, DropdownItem, Icon, TooltipDirective], template: "@if (effectiveMode() === 'inline') {\n <div class=\"kf-row-actions kf-row-actions--inline\">\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a\n class=\"kf-row-actions__icon-btn\"\n [href]=\"action.href\"\n [attr.aria-label]=\"action.label\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </a>\n } @else {\n <span\n class=\"kf-row-actions__icon-btn kf-row-actions__icon-btn--disabled\"\n role=\"link\"\n aria-disabled=\"true\"\n [attr.aria-label]=\"action.label\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </span>\n }\n } @else {\n <button\n type=\"button\"\n class=\"kf-row-actions__icon-btn\"\n [disabled]=\"action.disabled ?? false\"\n [attr.aria-label]=\"action.label\"\n [kfTooltip]=\"action.label\"\n kfTooltipPosition=\"top\"\n (click)=\"action.onClick?.()\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n </button>\n }\n }\n </div>\n} @else {\n <kf-dropdown class=\"kf-row-actions\" [(open)]=\"menuOpen\">\n <button\n type=\"button\"\n class=\"kf-row-actions__trigger\"\n [class.kf-row-actions__trigger--open]=\"menuOpen()\"\n [attr.aria-expanded]=\"menuOpen()\"\n aria-label=\"M\u00E1s acciones\"\n (click)=\"onToggleMenu()\"\n >\n <kf-icon name=\"more-vertical\" size=\"md\" />\n </button>\n <kf-dropdown-panel>\n @for (action of actions(); track action.label) {\n @if (action.kind === 'link') {\n @if (action.href && !action.disabled) {\n <a\n class=\"kf-row-actions__menu-link\"\n role=\"menuitem\"\n [href]=\"action.href\"\n (click)=\"onMenuLinkClick()\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </a>\n } @else {\n <span\n class=\"kf-row-actions__menu-link kf-row-actions__menu-link--disabled\"\n role=\"menuitem\"\n aria-disabled=\"true\"\n >\n <kf-icon [name]=\"action.icon\" size=\"sm\" />\n <span class=\"kf-row-actions__menu-link-label\">{{ action.label }}</span>\n </span>\n }\n } @else {\n <kf-dropdown-item\n [icon]=\"action.icon\"\n [disabled]=\"action.disabled ?? false\"\n (click)=\"onButtonAction(action)\"\n >\n {{ action.label }}\n </kf-dropdown-item>\n }\n }\n </kf-dropdown-panel>\n </kf-dropdown>\n}\n", styles: [":host{display:inline-flex}.kf-row-actions{display:inline-flex}.kf-row-actions--inline{align-items:center;gap:2px}.kf-row-actions__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:var(--kf-radius-sm);background:transparent;color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,color .14s}.kf-row-actions__icon-btn:hover{background:var(--kf-color-primary-soft);color:var(--kf-color-primary)}.kf-row-actions__icon-btn:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__icon-btn--disabled,.kf-row-actions__icon-btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.kf-row-actions__trigger{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-pill);background:var(--kf-color-white);color:var(--kf-color-text-muted);cursor:pointer;transition:background-color .14s,border-color .14s,color .14s}.kf-row-actions__trigger:hover{border-color:var(--kf-color-border-strong)}.kf-row-actions__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-row-actions__trigger--open{background:var(--kf-color-primary-soft);border-color:var(--kf-color-primary);color:var(--kf-color-primary)}.kf-row-actions__menu-link{display:flex;align-items:center;gap:var(--kf-space-sm);width:100%;padding:var(--kf-space-sm) var(--kf-space-md);color:var(--kf-color-text);text-decoration:none;cursor:pointer}.kf-row-actions__menu-link kf-icon{flex:none;color:var(--kf-color-text-muted)}.kf-row-actions__menu-link-label{flex:1 1 auto}.kf-row-actions__menu-link:hover{background:var(--kf-color-surface)}.kf-row-actions__menu-link:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus-inset)}.kf-row-actions__menu-link--disabled{opacity:.55;cursor:not-allowed;pointer-events:none}\n"] }]
8073
8550
  }], propDecorators: { actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: true }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], inlineLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineLimit", required: false }] }] } });
8074
8551
 
8075
8552
  /**
@@ -8810,7 +9287,7 @@ class Textarea {
8810
9287
  useExisting: forwardRef(() => Textarea),
8811
9288
  multi: true,
8812
9289
  },
8813
- ], viewQueries: [{ propertyName: "nativeTextarea", first: true, predicate: ["nativeTextarea"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"textareaId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<textarea\n #nativeTextarea\n [id]=\"textareaId\"\n class=\"kf-textarea__control\"\n [class.kf-textarea__control--focused]=\"focused()\"\n [class.kf-textarea__control--invalid]=\"invalid()\"\n [class.kf-textarea__control--readonly]=\"readonly()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeTextarea.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n></textarea>\n@if (errorMessage(); as message) {\n <span class=\"kf-textarea__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-textarea__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-textarea__control{resize:none;width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-surface);color:var(--kf-color-text);font:inherit;padding:var(--kf-space-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-textarea__control::placeholder{color:var(--kf-color-text-muted)}.kf-textarea__control--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus);outline:none}.kf-textarea__control--invalid{border-color:var(--kf-color-error)}.kf-textarea__control--invalid.kf-textarea__control--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-textarea__control:disabled{opacity:.5;cursor:not-allowed}.kf-textarea__control--readonly{background:var(--kf-color-gray-100);cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9290
+ ], viewQueries: [{ propertyName: "nativeTextarea", first: true, predicate: ["nativeTextarea"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <kf-field-label [for]=\"textareaId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<textarea\n #nativeTextarea\n [id]=\"textareaId\"\n class=\"kf-textarea__control\"\n [class.kf-textarea__control--focused]=\"focused()\"\n [class.kf-textarea__control--invalid]=\"invalid()\"\n [class.kf-textarea__control--readonly]=\"readonly()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeTextarea.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n></textarea>\n@if (errorMessage(); as message) {\n <span class=\"kf-textarea__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-textarea__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-textarea__control{resize:none;width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);background:var(--kf-color-surface);color:var(--kf-color-text);font:inherit;padding:var(--kf-space-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-textarea__control::placeholder{color:var(--kf-color-text-muted)}.kf-textarea__control--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus);outline:none}.kf-textarea__control--invalid{border-color:var(--kf-color-error)}.kf-textarea__control--invalid.kf-textarea__control--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-textarea__control:disabled{opacity:.5;cursor:not-allowed}.kf-textarea__control--readonly{background:var(--kf-color-gray-100);cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for", "required", "visuallyHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8814
9291
  }
8815
9292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Textarea, decorators: [{
8816
9293
  type: Component,
@@ -8820,7 +9297,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
8820
9297
  useExisting: forwardRef(() => Textarea),
8821
9298
  multi: true,
8822
9299
  },
8823
- ], template: "@if (label()) {\n <kf-field-label [for]=\"textareaId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<textarea\n #nativeTextarea\n [id]=\"textareaId\"\n class=\"kf-textarea__control\"\n [class.kf-textarea__control--focused]=\"focused()\"\n [class.kf-textarea__control--invalid]=\"invalid()\"\n [class.kf-textarea__control--readonly]=\"readonly()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeTextarea.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n></textarea>\n@if (errorMessage(); as message) {\n <span class=\"kf-textarea__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-textarea__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-textarea__control{resize:none;width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);background:var(--kf-color-surface);color:var(--kf-color-text);font:inherit;padding:var(--kf-space-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-textarea__control::placeholder{color:var(--kf-color-text-muted)}.kf-textarea__control--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus);outline:none}.kf-textarea__control--invalid{border-color:var(--kf-color-error)}.kf-textarea__control--invalid.kf-textarea__control--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-textarea__control:disabled{opacity:.5;cursor:not-allowed}.kf-textarea__control--readonly{background:var(--kf-color-gray-100);cursor:default}\n"] }]
9300
+ ], template: "@if (label()) {\n <kf-field-label [for]=\"textareaId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n}\n<textarea\n #nativeTextarea\n [id]=\"textareaId\"\n class=\"kf-textarea__control\"\n [class.kf-textarea__control--focused]=\"focused()\"\n [class.kf-textarea__control--invalid]=\"invalid()\"\n [class.kf-textarea__control--readonly]=\"readonly()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeTextarea.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n></textarea>\n@if (errorMessage(); as message) {\n <span class=\"kf-textarea__error kf-field-error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n} @else if (hint()) {\n <span class=\"kf-textarea__hint kf-field-hint\" [id]=\"hintId\">{{ hint() }}</span>\n}\n", styles: [".kf-field-hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-field-error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}:host{display:flex;flex-direction:column;gap:var(--kf-space-xs);font-family:var(--kf-font-body)}.kf-textarea__control{resize:none;width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--kf-color-border-control);border-radius:var(--kf-radius-sm);background:var(--kf-color-surface);color:var(--kf-color-text);font:inherit;padding:var(--kf-space-sm);transition:background .14s,border-color .14s,box-shadow .14s}.kf-textarea__control::placeholder{color:var(--kf-color-text-muted)}.kf-textarea__control--focused{background:var(--kf-color-white);border-color:var(--kf-color-primary);box-shadow:var(--kf-shadow-focus);outline:none}.kf-textarea__control--invalid{border-color:var(--kf-color-error)}.kf-textarea__control--invalid.kf-textarea__control--focused{box-shadow:var(--kf-shadow-focus-error)}.kf-textarea__control:disabled{opacity:.5;cursor:not-allowed}.kf-textarea__control--readonly{background:var(--kf-color-gray-100);cursor:default}\n"] }]
8824
9301
  }], propDecorators: { nativeTextarea: [{ type: i0.ViewChild, args: ['nativeTextarea', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], minRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRows", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }] } });
8825
9302
 
8826
9303
  /**
@@ -9243,5 +9720,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
9243
9720
  * Generated bundle index. Do not edit.
9244
9721
  */
9245
9722
 
9246
- export { ActionTile, AdminBadge, Alert, AlertRow, Avatar, Badge, Breadcrumb, BucketProgress, Button, Calendar, Card, Carousel, CarouselSlide, Checkbox, Chip, Collapsible, ContactPopover, ContentSlot, ContentState, ContentStateLoading, ContentViewer, 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 };
9723
+ 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 };
9247
9724
  //# sourceMappingURL=kaufmann-lab-ui-core.mjs.map