@kaufmann-lab/ui 0.1.0 → 0.1.1

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.
@@ -1152,9 +1152,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
1152
1152
  * forms) queda en su valor por defecto — igual que `disabled` combina el
1153
1153
  * input signal con `setDisabledState` en el resto de la librería.
1154
1154
  *
1155
+ * `invalid` pinta el recuadro en rojo y setea `aria-invalid` en el `<input>`
1156
+ * nativo — mismo mecanismo que `Input.invalid`, para el caso típico de un
1157
+ * checkbox obligatorio (ej. "Acepto términos y condiciones") sin marcar.
1158
+ *
1155
1159
  * <kf-checkbox label="Aceptar términos" [(checked)]="accepted" />
1156
1160
  * <kf-checkbox label="Seleccionar todo" [indeterminate]="isPartial()" />
1157
1161
  * <kf-checkbox label="Notificaciones" formControlName="notifications" />
1162
+ * <kf-checkbox label="Acepto los términos y condiciones" [invalid]="submitted() && !accepted()" />
1158
1163
  */
1159
1164
  class Checkbox {
1160
1165
  label = input(/* @ts-ignore */
@@ -1162,6 +1167,8 @@ class Checkbox {
1162
1167
  checked = input(false, { ...(ngDevMode ? { debugName: "checked" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1163
1168
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1164
1169
  indeterminate = input(false, { ...(ngDevMode ? { debugName: "indeterminate" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1170
+ /** Recuadro en rojo + aria-invalid — ej. checkbox obligatorio sin marcar. */
1171
+ invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1165
1172
  checkedChange = output();
1166
1173
  inputRef = viewChild.required('inputRef', /* @ts-ignore */
1167
1174
  ...(ngDevMode ? [{ debugName: "inputRef" }] : /* istanbul ignore next */ []));
@@ -1197,7 +1204,7 @@ class Checkbox {
1197
1204
  this.inputRef().nativeElement.disabled = isDisabled;
1198
1205
  }
1199
1206
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Checkbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
1200
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Checkbox, isStandalone: true, selector: "kf-checkbox", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange" }, providers: [
1207
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: Checkbox, isStandalone: true, selector: "kf-checkbox", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange" }, providers: [
1201
1208
  {
1202
1209
  provide: NG_VALUE_ACCESSOR,
1203
1210
  useExisting: forwardRef(() => Checkbox),
@@ -1210,15 +1217,16 @@ class Checkbox {
1210
1217
  type="checkbox"
1211
1218
  [checked]="checked()"
1212
1219
  [disabled]="disabled()"
1220
+ [attr.aria-invalid]="invalid() ? true : null"
1213
1221
  (change)="onChange($event)"
1214
1222
  (blur)="onTouched()"
1215
1223
  />
1216
- <span class="kf-checkbox__box"></span>
1224
+ <span class="kf-checkbox__box" [class.kf-checkbox__box--invalid]="invalid()"></span>
1217
1225
  @if (label()) {
1218
1226
  <span class="kf-checkbox__label">{{ label() }}</span>
1219
1227
  }
1220
1228
  </label>
1221
- `, isInline: true, styles: [":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;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}.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:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:8px;height:2px;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--disabled .kf-checkbox__box{opacity:.5}.kf-checkbox__label{-webkit-user-select:none;user-select:none}\n"] });
1229
+ `, isInline: true, styles: [":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;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}.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:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:8px;height:2px;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"] });
1222
1230
  }
1223
1231
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Checkbox, decorators: [{
1224
1232
  type: Component,
@@ -1229,10 +1237,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
1229
1237
  type="checkbox"
1230
1238
  [checked]="checked()"
1231
1239
  [disabled]="disabled()"
1240
+ [attr.aria-invalid]="invalid() ? true : null"
1232
1241
  (change)="onChange($event)"
1233
1242
  (blur)="onTouched()"
1234
1243
  />
1235
- <span class="kf-checkbox__box"></span>
1244
+ <span class="kf-checkbox__box" [class.kf-checkbox__box--invalid]="invalid()"></span>
1236
1245
  @if (label()) {
1237
1246
  <span class="kf-checkbox__label">{{ label() }}</span>
1238
1247
  }
@@ -1243,8 +1252,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
1243
1252
  useExisting: forwardRef(() => Checkbox),
1244
1253
  multi: true,
1245
1254
  },
1246
- ], styles: [":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;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}.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:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:8px;height:2px;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--disabled .kf-checkbox__box{opacity:.5}.kf-checkbox__label{-webkit-user-select:none;user-select:none}\n"] }]
1247
- }], 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 }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }], inputRef: [{ type: i0.ViewChild, args: ['inputRef', { isSignal: true }] }] } });
1255
+ ], styles: [":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;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}.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:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;transform:rotate(45deg) translate(-1px,-1px)}.kf-checkbox input:indeterminate+.kf-checkbox__box:after{content:\"\";width:8px;height:2px;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"] }]
1256
+ }], 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 }] }] } });
1248
1257
 
1249
1258
  /**
1250
1259
  * Chip de fondo suave con un punto líder que indica estado. Pensado
@@ -1307,19 +1316,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
1307
1316
  * No reemplaza al `<label>` nativo — lo envuelve, para no perder la
1308
1317
  * asociación de accesibilidad `for`/`id` con el control real.
1309
1318
  *
1319
+ * `required` agrega un asterisco visual en el tono de error, separado del
1320
+ * texto por un espacio y marcado `aria-hidden` — el estado obligatorio real
1321
+ * para lectores de pantalla lo comunica el propio control (`aria-required`
1322
+ * / `required` en el `<input>`/`<select>` asociado), no este label.
1323
+ *
1310
1324
  * <kf-field-label [for]="inputId">Patente o VIN</kf-field-label>
1325
+ * <kf-field-label [for]="inputId" required>Correo electrónico</kf-field-label>
1311
1326
  */
1312
1327
  class FieldLabel {
1313
1328
  /** `id` del control asociado — se refleja como `for` en el `<label>` interno. */
1314
1329
  for = input(/* @ts-ignore */
1315
1330
  ...(ngDevMode ? [undefined, { debugName: "for" }] : /* istanbul ignore next */ []));
1331
+ /** Muestra un asterisco visual indicando que el campo es obligatorio. */
1332
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1316
1333
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FieldLabel, deps: [], target: i0.ɵɵFactoryTarget.Component });
1317
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.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 } }, ngImport: i0, template: ` <label class="kf-field-label" [for]="for()"><ng-content /></label> `, isInline: true, styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:.75rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}\n"] });
1334
+ 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: `
1335
+ <label class="kf-field-label" [for]="for()">
1336
+ <ng-content />
1337
+ @if (required()) {
1338
+ <span class="kf-field-label__required" aria-hidden="true">*</span>
1339
+ }
1340
+ </label>
1341
+ `, isInline: true, styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:.75rem;font-weight:600;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"] });
1318
1342
  }
1319
1343
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: FieldLabel, decorators: [{
1320
1344
  type: Component,
1321
- args: [{ selector: 'kf-field-label', template: ` <label class="kf-field-label" [for]="for()"><ng-content /></label> `, styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:.75rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--kf-color-text-muted)}\n"] }]
1322
- }], propDecorators: { for: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }] } });
1345
+ args: [{ selector: 'kf-field-label', template: `
1346
+ <label class="kf-field-label" [for]="for()">
1347
+ <ng-content />
1348
+ @if (required()) {
1349
+ <span class="kf-field-label__required" aria-hidden="true">*</span>
1350
+ }
1351
+ </label>
1352
+ `, styles: [":host{display:contents}.kf-field-label{font-family:var(--kf-font-title);font-size:.75rem;font-weight:600;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"] }]
1353
+ }], propDecorators: { for: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }] } });
1323
1354
 
1324
1355
  let nextId$2 = 0;
1325
1356
  /**
@@ -1432,7 +1463,7 @@ class Select {
1432
1463
  }
1433
1464
  </ul>
1434
1465
  }
1435
- `, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font-family:var(--kf-font-body)}.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__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__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-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select__option{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-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__empty{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"] }] });
1466
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font-family:var(--kf-font-body)}.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__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select__value--placeholder{color:var(--kf-color-text-muted)}.kf-select__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-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select__option{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-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__empty{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"] }] });
1436
1467
  }
1437
1468
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Select, decorators: [{
1438
1469
  type: Component,
@@ -2678,10 +2709,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
2678
2709
  * <kf-input label="Placa" icon="car" placeholder="ABC-123" hint="Formato: 3 letras + 3 números" />
2679
2710
  * <input kf-input formControlName="email" type="email" />
2680
2711
  *
2681
- * Nota sobre "icon": todavía no existe un componente Icon / sprite SVG en esta
2682
- * librería. El prop se acepta igual para no romper el contrato de la spec,
2683
- * pero por ahora solo reserva el espacio visual (placeholder vacío) — no
2684
- * renderiza ningún glyph real.
2712
+ * `invalid` + `errorMessage` cubren el estado de error: con `invalid` el
2713
+ * borde pasa a rojo (`--kf-color-error`) y se setea `aria-invalid="true"` en
2714
+ * el `<input>` nativo; `errorMessage` reemplaza el `hint` neutro por un
2715
+ * mensaje en rojo con `role="alert"`, para que un lector de pantalla lo
2716
+ * anuncie apenas aparece (a diferencia de `hint`, que es solo informativo y
2717
+ * nunca interrumpe). Si se pasan ambos, `errorMessage` tiene prioridad
2718
+ * visual sobre `hint` — no tiene sentido mostrar los dos a la vez.
2719
+ *
2720
+ * <kf-input label="Correo" formControlName="email"
2721
+ * [invalid]="email.invalid && email.touched"
2722
+ * [errorMessage]="email.touched && email.hasError('required') ? 'Ingresa tu correo.' : undefined" />
2685
2723
  */
2686
2724
  class Input {
2687
2725
  static nextId = 0;
@@ -2689,13 +2727,20 @@ class Input {
2689
2727
  ...(ngDevMode ? [{ debugName: "nativeInput" }] : /* istanbul ignore next */ []));
2690
2728
  label = input(/* @ts-ignore */
2691
2729
  ...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
2692
- /** Nombre de ícono líder. Ver nota de clase: sin componente Icon todavía. */
2730
+ /** Marca el label con un asterisco visual — no aplica `required` al `<input>` nativo por sí solo. */
2731
+ required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2732
+ /** Ícono líder, renderizado vía `kf-icon`. */
2693
2733
  icon = input(/* @ts-ignore */
2694
2734
  ...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
2695
2735
  suffix = input(/* @ts-ignore */
2696
2736
  ...(ngDevMode ? [undefined, { debugName: "suffix" }] : /* istanbul ignore next */ []));
2697
2737
  hint = input(/* @ts-ignore */
2698
2738
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
2739
+ /** Borde y aria-invalid en rojo. Ver `errorMessage` para el mensaje asociado. */
2740
+ invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2741
+ /** Mensaje de error con `role="alert"` — reemplaza a `hint` mientras esté presente. */
2742
+ errorMessage = input(/* @ts-ignore */
2743
+ ...(ngDevMode ? [undefined, { debugName: "errorMessage" }] : /* istanbul ignore next */ []));
2699
2744
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2700
2745
  type = input('text', /* @ts-ignore */
2701
2746
  ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
@@ -2703,6 +2748,7 @@ class Input {
2703
2748
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
2704
2749
  inputId = `kf-input-${Input.nextId++}`;
2705
2750
  hintId = `${this.inputId}-hint`;
2751
+ errorId = `${this.inputId}-error`;
2706
2752
  value = signal('', /* @ts-ignore */
2707
2753
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2708
2754
  focused = signal(false, /* @ts-ignore */
@@ -2753,7 +2799,7 @@ class Input {
2753
2799
  this.onTouched();
2754
2800
  }
2755
2801
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Input, deps: [], target: i0.ɵɵFactoryTarget.Component });
2756
- 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 }, 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 }, disabled: { classPropertyName: "disabled", publicName: "disabled", 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 } }, providers: [
2802
+ 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 }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
2757
2803
  {
2758
2804
  provide: NG_VALUE_ACCESSOR,
2759
2805
  useExisting: forwardRef(() => Input),
@@ -2761,17 +2807,16 @@ class Input {
2761
2807
  },
2762
2808
  ], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
2763
2809
  @if (label()) {
2764
- <kf-field-label [for]="inputId">{{ label() }}</kf-field-label>
2810
+ <kf-field-label [for]="inputId" [required]="required()">{{ label() }}</kf-field-label>
2765
2811
  }
2766
2812
  <div
2767
2813
  class="kf-input__field"
2768
2814
  [class.kf-input__field--disabled]="isDisabled()"
2769
2815
  [class.kf-input__field--focused]="focused()"
2816
+ [class.kf-input__field--invalid]="invalid()"
2770
2817
  >
2771
- @if (icon()) {
2772
- <!-- Pendiente: falta componente Icon / sprite SVG. Se reserva el
2773
- espacio pero no se renderiza ningún glyph todavía. -->
2774
- <span class="kf-input__icon" aria-hidden="true"></span>
2818
+ @if (icon(); as iconName) {
2819
+ <kf-icon class="kf-input__icon" [name]="iconName" size="sm" />
2775
2820
  }
2776
2821
  <input
2777
2822
  #nativeInput
@@ -2780,7 +2825,8 @@ class Input {
2780
2825
  [type]="type()"
2781
2826
  [placeholder]="placeholder()"
2782
2827
  [disabled]="isDisabled()"
2783
- [attr.aria-describedby]="hint() ? hintId : null"
2828
+ [attr.aria-describedby]="errorMessage() ? errorId : hint() ? hintId : null"
2829
+ [attr.aria-invalid]="invalid() ? true : null"
2784
2830
  [value]="value()"
2785
2831
  (input)="onInput(nativeInput.value)"
2786
2832
  (blur)="onBlur()"
@@ -2790,14 +2836,16 @@ class Input {
2790
2836
  <span class="kf-input__suffix">{{ suffix() }}</span>
2791
2837
  }
2792
2838
  </div>
2793
- @if (hint()) {
2839
+ @if (errorMessage(); as message) {
2840
+ <span class="kf-input__error" [id]="errorId" role="alert">{{ message }}</span>
2841
+ } @else if (hint()) {
2794
2842
  <span class="kf-input__hint" [id]="hintId">{{ hint() }}</span>
2795
2843
  }
2796
- `, isInline: true, styles: [":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--disabled{opacity:.5}.kf-input__icon{width:1rem;height:1rem;flex:none}.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__hint{font-size:.75rem;color:var(--kf-color-text-muted)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldLabel, selector: "kf-field-label", inputs: ["for"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2844
+ `, isInline: true, styles: [":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:0 0 0 3px #eb575738}.kf-input__field--disabled{opacity:.5}.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__hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-input__error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2797
2845
  }
2798
2846
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: Input, decorators: [{
2799
2847
  type: Component,
2800
- args: [{ selector: 'kf-input', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, FieldLabel], providers: [
2848
+ args: [{ selector: 'kf-input', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, FieldLabel, Icon], providers: [
2801
2849
  {
2802
2850
  provide: NG_VALUE_ACCESSOR,
2803
2851
  useExisting: forwardRef(() => Input),
@@ -2805,17 +2853,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
2805
2853
  },
2806
2854
  ], template: `
2807
2855
  @if (label()) {
2808
- <kf-field-label [for]="inputId">{{ label() }}</kf-field-label>
2856
+ <kf-field-label [for]="inputId" [required]="required()">{{ label() }}</kf-field-label>
2809
2857
  }
2810
2858
  <div
2811
2859
  class="kf-input__field"
2812
2860
  [class.kf-input__field--disabled]="isDisabled()"
2813
2861
  [class.kf-input__field--focused]="focused()"
2862
+ [class.kf-input__field--invalid]="invalid()"
2814
2863
  >
2815
- @if (icon()) {
2816
- <!-- Pendiente: falta componente Icon / sprite SVG. Se reserva el
2817
- espacio pero no se renderiza ningún glyph todavía. -->
2818
- <span class="kf-input__icon" aria-hidden="true"></span>
2864
+ @if (icon(); as iconName) {
2865
+ <kf-icon class="kf-input__icon" [name]="iconName" size="sm" />
2819
2866
  }
2820
2867
  <input
2821
2868
  #nativeInput
@@ -2824,7 +2871,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
2824
2871
  [type]="type()"
2825
2872
  [placeholder]="placeholder()"
2826
2873
  [disabled]="isDisabled()"
2827
- [attr.aria-describedby]="hint() ? hintId : null"
2874
+ [attr.aria-describedby]="errorMessage() ? errorId : hint() ? hintId : null"
2875
+ [attr.aria-invalid]="invalid() ? true : null"
2828
2876
  [value]="value()"
2829
2877
  (input)="onInput(nativeInput.value)"
2830
2878
  (blur)="onBlur()"
@@ -2834,11 +2882,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
2834
2882
  <span class="kf-input__suffix">{{ suffix() }}</span>
2835
2883
  }
2836
2884
  </div>
2837
- @if (hint()) {
2885
+ @if (errorMessage(); as message) {
2886
+ <span class="kf-input__error" [id]="errorId" role="alert">{{ message }}</span>
2887
+ } @else if (hint()) {
2838
2888
  <span class="kf-input__hint" [id]="hintId">{{ hint() }}</span>
2839
2889
  }
2840
- `, styles: [":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--disabled{opacity:.5}.kf-input__icon{width:1rem;height:1rem;flex:none}.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__hint{font-size:.75rem;color:var(--kf-color-text-muted)}\n"] }]
2841
- }], propDecorators: { nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", 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 }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
2890
+ `, styles: [":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:0 0 0 3px #eb575738}.kf-input__field--disabled{opacity:.5}.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__hint{font-size:.75rem;color:var(--kf-color-text-muted)}.kf-input__error{display:flex;align-items:center;gap:var(--kf-space-xs);font-size:.75rem;font-weight:600;color:var(--kf-color-error-strong)}\n"] }]
2891
+ }], 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 }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
2842
2892
 
2843
2893
  /**
2844
2894
  * Card de estadística/KPI: label, valor grande, ícono opcional en la esquina
@@ -3264,7 +3314,7 @@ class MultiSelect {
3264
3314
  }
3265
3315
  </ul>
3266
3316
  }
3267
- `, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;min-width:200px}.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__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-multi-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-multi-select__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.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__checkbox{display:inline-flex;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-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:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;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:8px;height:2px;background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{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"] }] });
3317
+ `, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;min-width:200px}.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__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-multi-select__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-multi-select__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.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__checkbox{display:inline-flex;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-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:4px;height:8px;border:solid var(--kf-color-white);border-width:0 2px 2px 0;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:8px;height:2px;background:var(--kf-color-white);border:none;transform:none}.kf-multi-select__option-label{overflow:hidden;text-overflow:ellipsis}.kf-multi-select__empty{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"] }] });
3268
3318
  }
3269
3319
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MultiSelect, decorators: [{
3270
3320
  type: Component,
@@ -3687,7 +3737,7 @@ class PortalHeader {
3687
3737
  <kf-avatar [initials]="userInitials()" pill />
3688
3738
  </button>
3689
3739
  </div>
3690
- `, isInline: true, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);padding:var(--kf-space-xs) var(--kf-space-lg);background:var(--kf-color-tertiary-deep)}.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{display:flex;align-items:center;gap:var(--kf-space-lg);padding:var(--kf-space-sm) var(--kf-space-lg);background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.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__nav{display:flex;align-items:center;gap:var(--kf-space-xs);flex:1 1 auto}.kf-portal-header__nav-item{padding:var(--kf-space-xs) var(--kf-space-md);border-radius:var(--kf-radius-sm);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover{color:var(--kf-color-white)}.kf-portal-header__nav-item--active{background:var(--kf-color-white);color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}\n"], dependencies: [{ kind: "component", type: AdminBadge, selector: "kf-admin-badge", inputs: ["inline"] }, { kind: "component", type: Avatar, selector: "kf-avatar", inputs: ["initials", "src", "round", "pill"] }] });
3740
+ `, isInline: true, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);padding:var(--kf-space-xs) var(--kf-space-lg);background:var(--kf-color-tertiary-deep)}.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{display:flex;align-items:center;gap:var(--kf-space-lg);padding:var(--kf-space-sm) var(--kf-space-lg);background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.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__nav{display:flex;align-items:center;gap:var(--kf-space-xs);flex:1 1 auto}.kf-portal-header__nav-item{padding:var(--kf-space-xs) var(--kf-space-md);border-radius:var(--kf-radius-sm);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active){color:var(--kf-color-white)}.kf-portal-header__nav-item--active{background:var(--kf-color-white);color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}\n"], dependencies: [{ kind: "component", type: AdminBadge, selector: "kf-admin-badge", inputs: ["inline"] }, { kind: "component", type: Avatar, selector: "kf-avatar", inputs: ["initials", "src", "round", "pill"] }] });
3691
3741
  }
3692
3742
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PortalHeader, decorators: [{
3693
3743
  type: Component,
@@ -3719,7 +3769,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
3719
3769
  <kf-avatar [initials]="userInitials()" pill />
3720
3770
  </button>
3721
3771
  </div>
3722
- `, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);padding:var(--kf-space-xs) var(--kf-space-lg);background:var(--kf-color-tertiary-deep)}.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{display:flex;align-items:center;gap:var(--kf-space-lg);padding:var(--kf-space-sm) var(--kf-space-lg);background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.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__nav{display:flex;align-items:center;gap:var(--kf-space-xs);flex:1 1 auto}.kf-portal-header__nav-item{padding:var(--kf-space-xs) var(--kf-space-md);border-radius:var(--kf-radius-sm);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover{color:var(--kf-color-white)}.kf-portal-header__nav-item--active{background:var(--kf-color-white);color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}\n"] }]
3772
+ `, styles: [":host{display:block;font-family:var(--kf-font-body)}.kf-portal-header__admin-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--kf-space-md);padding:var(--kf-space-xs) var(--kf-space-lg);background:var(--kf-color-tertiary-deep)}.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{display:flex;align-items:center;gap:var(--kf-space-lg);padding:var(--kf-space-sm) var(--kf-space-lg);background:var(--kf-color-tertiary-deep);border-top:1px solid rgba(255,255,255,.1)}.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__nav{display:flex;align-items:center;gap:var(--kf-space-xs);flex:1 1 auto}.kf-portal-header__nav-item{padding:var(--kf-space-xs) var(--kf-space-md);border-radius:var(--kf-radius-sm);color:#ffffffbf;font-size:.875rem;font-weight:600;text-decoration:none;transition:background .14s,color .14s}.kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active){color:var(--kf-color-white)}.kf-portal-header__nav-item--active{background:var(--kf-color-white);color:var(--kf-color-ink)}.kf-portal-header__session{flex:none;border:none;background:transparent;padding:0;cursor:pointer}\n"] }]
3723
3773
  }], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", 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 }] }], sessionClick: [{ type: i0.Output, args: ["sessionClick"] }] } });
3724
3774
 
3725
3775
  /**
@@ -4066,7 +4116,7 @@ class SelectMenu {
4066
4116
  }
4067
4117
  </ul>
4068
4118
  }
4069
- `, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;min-width:200px}.kf-select-menu__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-select-menu__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select-menu__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-select-menu__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-select-menu__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select-menu__value--placeholder{color:var(--kf-color-text-muted)}.kf-select-menu__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-select-menu__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select-menu__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select-menu__option{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-select-menu__option:hover{background:var(--kf-color-primary-soft)}.kf-select-menu__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select-menu__empty{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"] }] });
4119
+ `, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;gap:var(--kf-space-xs);position:relative;font:inherit;min-width:200px}.kf-select-menu__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-select-menu__trigger:hover:not(:disabled){border-color:var(--kf-color-border-strong)}.kf-select-menu__trigger:focus-visible{outline:none;box-shadow:var(--kf-shadow-focus)}.kf-select-menu__trigger:disabled{opacity:.5;cursor:not-allowed}.kf-select-menu__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kf-select-menu__value--placeholder{color:var(--kf-color-text-muted)}.kf-select-menu__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-select-menu__caret--open{transform:rotate(-135deg);margin-top:4px}.kf-select-menu__panel{position:absolute;top:100%;left:0;right:0;z-index:10;margin:var(--kf-space-xs) 0 0;padding:var(--kf-space-xs) 0;list-style:none;max-height:240px;overflow-y:auto;background:var(--kf-color-white);border:1px solid var(--kf-color-border);border-radius:var(--kf-radius-sm);box-shadow:var(--kf-shadow-md)}.kf-select-menu__option{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-select-menu__option:hover{background:var(--kf-color-primary-soft)}.kf-select-menu__option--selected{background:var(--kf-color-primary-soft);color:var(--kf-color-primary);font-weight:600}.kf-select-menu__empty{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"] }] });
4070
4120
  }
4071
4121
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: SelectMenu, decorators: [{
4072
4122
  type: Component,