@kaufmann-lab/ui 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/kaufmann-lab-ui-business.mjs +269 -17
- package/fesm2022/kaufmann-lab-ui-business.mjs.map +1 -1
- package/fesm2022/kaufmann-lab-ui-core.mjs +1418 -101
- package/fesm2022/kaufmann-lab-ui-core.mjs.map +1 -1
- package/fesm2022/kaufmann-lab-ui-map.mjs +1 -1
- package/fesm2022/kaufmann-lab-ui-map.mjs.map +1 -1
- package/package.json +1 -1
- package/types/kaufmann-lab-ui-business.d.ts +175 -14
- package/types/kaufmann-lab-ui-core.d.ts +871 -55
|
@@ -31,8 +31,16 @@ import { SafeResourceUrl } from '@angular/platform-browser';
|
|
|
31
31
|
* `map-pin`, que en este mismo dominio representa ubicación geográfica real
|
|
32
32
|
* de vehículos; reusarlo para "fijar" generaría ambigüedad con los markers
|
|
33
33
|
* de mapa.
|
|
34
|
+
*
|
|
35
|
+
* `refresh` (`refresh-cw` de Lucide) e `info` son extensión propia: la
|
|
36
|
+
* acción "Reintentar" y los avisos informativos (ej. estados de
|
|
37
|
+
* `kf-empty-state` en tono `info`) no tenían glyph equivalente en el set.
|
|
38
|
+
*
|
|
39
|
+
* `layout-grid` (de Lucide, cuatro cuadros) es extensión propia: representa
|
|
40
|
+
* la vista de tarjetas; `grid` dibuja una cuadrícula de tabla y no se
|
|
41
|
+
* distingue de la vista de tabla.
|
|
34
42
|
*/
|
|
35
|
-
type IconName = 'activity' | 'alert-circle' | 'alert-octagon' | 'alert-triangle' | 'award' | 'bar-chart' | 'bell' | 'bus' | 'calculator' | 'calendar' | 'car' | 'cart' | 'check' | 'check-circle' | 'check-square' | 'chevron-down' | 'chevron-left' | 'chevron-left-bar' | 'chevron-right' | 'clipboard' | 'clock' | 'credit-card' | 'crosshair' | 'download' | 'edit' | 'external-link' | 'eye' | 'eye-off' | 'file' | 'filter' | 'gauge' | 'gift' | 'grid' | 'history' | 'home' | 'inbox' | 'layers' | 'list' | 'log-out' | 'mail' | 'map' | 'map-pin' | 'maximize' | 'menu' | 'message-circle' | 'mic' | 'mic-off' | 'minimize' | 'minus' | 'monitor' | 'more-vertical' | 'navigation' | 'pause' | 'phone' | 'pin' | 'play' | 'plus' | 'search' | 'settings' | 'shield-check' | 'sort' | 'star' | 'ticket' | 'tool' | 'trash' | 'truck' | 'upload-cloud' | 'user' | 'user-search' | 'video' | 'x' | 'zap';
|
|
43
|
+
type IconName = 'activity' | 'alert-circle' | 'alert-octagon' | 'alert-triangle' | 'award' | 'bar-chart' | 'bell' | 'bus' | 'calculator' | 'calendar' | 'car' | 'cart' | 'check' | 'check-circle' | 'check-square' | 'chevron-down' | 'chevron-left' | 'chevron-left-bar' | 'chevron-right' | 'clipboard' | 'clock' | 'credit-card' | 'crosshair' | 'download' | 'edit' | 'external-link' | 'eye' | 'eye-off' | 'file' | 'filter' | 'gauge' | 'gift' | 'grid' | 'history' | 'home' | 'inbox' | 'info' | 'layers' | 'layout-grid' | 'list' | 'log-out' | 'mail' | 'map' | 'map-pin' | 'maximize' | 'menu' | 'message-circle' | 'mic' | 'mic-off' | 'minimize' | 'minus' | 'monitor' | 'more-vertical' | 'navigation' | 'pause' | 'phone' | 'pin' | 'play' | 'plus' | 'refresh' | 'search' | 'settings' | 'shield-check' | 'sort' | 'star' | 'ticket' | 'tool' | 'trash' | 'truck' | 'upload-cloud' | 'user' | 'user-search' | 'video' | 'x' | 'zap';
|
|
36
44
|
|
|
37
45
|
type IconSize = 'sm' | 'md' | 'lg';
|
|
38
46
|
/** Ángulos de rotación soportados por `rotate` — cubre los casos reales del
|
|
@@ -128,7 +136,7 @@ declare class AdminBadge {
|
|
|
128
136
|
* Envuelve un `<button>` nativo: mantiene teclado, foco y submit de formulario.
|
|
129
137
|
* Como es un elemento personalizado, ningún atributo ARIA puesto en el host
|
|
130
138
|
* llega al `<button>` interno — por eso `disabled`, `type`, `ariaLabel`,
|
|
131
|
-
* `ariaExpanded` y `
|
|
139
|
+
* `ariaExpanded`, `ariaPressed` y `ariaHaspopup` se reenvían a mano.
|
|
132
140
|
*
|
|
133
141
|
* Seis variantes: `primary`, `secondary`, `ghost`, `outline`, `danger`,
|
|
134
142
|
* `surface`. Tres tamaños (`sm`/`md`/`lg`). `icon` agrega un glifo antes del
|
|
@@ -147,6 +155,15 @@ declare class AdminBadge {
|
|
|
147
155
|
*
|
|
148
156
|
* `(click)` no se reenvía: burbujea del botón interno al host solo.
|
|
149
157
|
*
|
|
158
|
+
* Objetivo táctil: el alto y el ancho mínimos del `<button>` interno salen
|
|
159
|
+
* de `--kf-button-min-height` y `--kf-button-min-width` (default `auto`,
|
|
160
|
+
* sin cambio). Un contenedor los sube (ej. a 44px en pantallas táctiles,
|
|
161
|
+
* sobre todo para un botón solo-ícono) declarando las variables en su
|
|
162
|
+
* propio CSS — heredan a través del límite de encapsulación.
|
|
163
|
+
*
|
|
164
|
+
* `focus()` enfoca el `<button>` interno: el consumidor no necesita
|
|
165
|
+
* buscarlo con `querySelector` en el DOM del componente.
|
|
166
|
+
*
|
|
150
167
|
* `loading` reemplaza el contenido proyectado por `kf-spinner` y fuerza
|
|
151
168
|
* `disabled`.
|
|
152
169
|
*
|
|
@@ -162,10 +179,10 @@ declare class AdminBadge {
|
|
|
162
179
|
declare class Button {
|
|
163
180
|
readonly variant: _angular_core.InputSignal<"primary" | "secondary" | "ghost" | "outline" | "danger" | "surface">;
|
|
164
181
|
readonly size: _angular_core.InputSignal<"sm" | "md" | "lg">;
|
|
165
|
-
readonly shape: _angular_core.InputSignal<"
|
|
182
|
+
readonly shape: _angular_core.InputSignal<"circle" | "rect">;
|
|
166
183
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
167
184
|
/** Igual al default nativo: hace submit dentro de un `<form>`. */
|
|
168
|
-
readonly type: _angular_core.InputSignal<"button" | "
|
|
185
|
+
readonly type: _angular_core.InputSignal<"button" | "reset" | "submit">;
|
|
169
186
|
/** Ícono líder, renderizado con `kf-icon` antes del label proyectado. */
|
|
170
187
|
readonly icon: _angular_core.InputSignal<IconName | undefined>;
|
|
171
188
|
/** Estira el botón a todo el ancho de su contenedor. */
|
|
@@ -186,12 +203,18 @@ declare class Button {
|
|
|
186
203
|
* más fuerte para leerse activo, y así ningún consumidor tiene que
|
|
187
204
|
* acordarse de pedirlo aparte. */
|
|
188
205
|
readonly ariaPressed: _angular_core.InputSignal<boolean | undefined>;
|
|
206
|
+
/** Tipo de elemento emergente que abre el botón (ej. `'dialog'` para un
|
|
207
|
+
* panel de filtros, `'listbox'`) — mismo motivo de reenvío manual. */
|
|
208
|
+
readonly ariaHaspopup: _angular_core.InputSignal<"dialog" | "menu" | "listbox" | "true" | undefined>;
|
|
209
|
+
private readonly nativeButton;
|
|
210
|
+
/** Enfoca el `<button>` interno (mismas opciones que `HTMLElement.focus`). */
|
|
211
|
+
focus(options?: FocusOptions): void;
|
|
189
212
|
/** `ghost`/`outline`/`surface` no tienen fondo oscuro sólido — el anillo
|
|
190
213
|
* del spinner por defecto ya se lee bien ahí sin variante propia
|
|
191
214
|
* (`surface` es fondo claro con texto oscuro, mismo motivo que `outline`). */
|
|
192
215
|
protected readonly hasSolidFill: _angular_core.Signal<boolean>;
|
|
193
216
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Button, never>;
|
|
194
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Button, "kf-button", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "block": { "alias": "block"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaExpanded": { "alias": "ariaExpanded"; "required": false; "isSignal": true; }; "ariaPressed": { "alias": "ariaPressed"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
217
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Button, "kf-button", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "block": { "alias": "block"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaExpanded": { "alias": "ariaExpanded"; "required": false; "isSignal": true; }; "ariaPressed": { "alias": "ariaPressed"; "required": false; "isSignal": true; }; "ariaHaspopup": { "alias": "ariaHaspopup"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
195
218
|
}
|
|
196
219
|
|
|
197
220
|
type AlertTone = 'info' | 'ok' | 'warn' | 'error';
|
|
@@ -218,7 +241,7 @@ declare class Alert {
|
|
|
218
241
|
* `alert` interrumpe al lector de pantalla; se reserva para error/warn.
|
|
219
242
|
* Los avisos informativos se anuncian sin cortar lo que se esté leyendo.
|
|
220
243
|
*/
|
|
221
|
-
protected readonly ariaRole: _angular_core.Signal<"
|
|
244
|
+
protected readonly ariaRole: _angular_core.Signal<"status" | "alert">;
|
|
222
245
|
protected readonly toneIcon: _angular_core.Signal<IconName>;
|
|
223
246
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Alert, never>;
|
|
224
247
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Alert, "kf-alert", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*"], true, never>;
|
|
@@ -279,13 +302,24 @@ declare class Avatar {
|
|
|
279
302
|
* punto (`dot`) usa el color BASE de cada tono, no `-strong` — ese último
|
|
280
303
|
* está pensado para texto legible sobre el fondo pastel de `soft` y se ve
|
|
281
304
|
* apagado sobre una superficie translúcida/oscura.
|
|
305
|
+
*
|
|
306
|
+
* `truncate` corta un texto largo con elipsis (ej. un estado de SAP como
|
|
307
|
+
* "WF Aprobación Política descuento") en vez de ensanchar la fila que lo
|
|
308
|
+
* contiene: el badge se limita al ancho de su contenedor (`max-width: 100%`,
|
|
309
|
+
* `min-width: 0`) y el punto no se recorta. El texto completo lo pone el
|
|
310
|
+
* consumidor en `title` (el badge no puede leer su propio contenido
|
|
311
|
+
* proyectado para generarlo):
|
|
312
|
+
*
|
|
313
|
+
* <kf-badge tone="warn" dot truncate [title]="q.statusLabel">{{ q.statusLabel }}</kf-badge>
|
|
282
314
|
*/
|
|
283
315
|
declare class Badge {
|
|
284
|
-
readonly tone: _angular_core.InputSignal<"
|
|
316
|
+
readonly tone: _angular_core.InputSignal<"error" | "info" | "neutral" | "ok" | "warn" | "service">;
|
|
285
317
|
readonly variant: _angular_core.InputSignal<"soft" | "glass">;
|
|
286
318
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
319
|
+
/** Corta el texto con elipsis al ancho del contenedor. Ver JSDoc de la clase. */
|
|
320
|
+
readonly truncate: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
287
321
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Badge, never>;
|
|
288
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Badge, "kf-badge", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
322
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Badge, "kf-badge", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; "truncate": { "alias": "truncate"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
289
323
|
}
|
|
290
324
|
|
|
291
325
|
interface BreadcrumbItem {
|
|
@@ -641,7 +675,7 @@ declare class Checkbox implements ControlValueAccessor {
|
|
|
641
675
|
* de superficie/borde/texto-muted más cercanos).
|
|
642
676
|
*/
|
|
643
677
|
declare class Chip {
|
|
644
|
-
readonly tone: _angular_core.InputSignal<"
|
|
678
|
+
readonly tone: _angular_core.InputSignal<"error" | "neutral" | "ok" | "warn">;
|
|
645
679
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
646
680
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Chip, never>;
|
|
647
681
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Chip, "kf-chip", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
@@ -836,10 +870,14 @@ declare class ContentViewer {
|
|
|
836
870
|
* usa como `src` salvo que la columna traiga su `cellTemplates`.
|
|
837
871
|
* - `title`: título del encabezado (ej. la patente/unidad).
|
|
838
872
|
* - `status`: chip/estado al lado del título.
|
|
839
|
-
* - `field` (default): par label/valor en el cuerpo.
|
|
873
|
+
* - `field` (default): par label/valor en el cuerpo. Con `cardClamp`, el
|
|
874
|
+
* valor ocupa el ancho completo (sin label visible) recortado a N líneas.
|
|
875
|
+
* - `meta`: dato secundario corto (fecha, monto) en una fila inferior de la
|
|
876
|
+
* tarjeta, rótulo chico arriba y valor abajo; con `emphasis` se destaca
|
|
877
|
+
* (ej. el precio) y se alinea al final.
|
|
840
878
|
* - `action`: va al pie, separado del cuerpo por una línea.
|
|
841
879
|
*/
|
|
842
|
-
type DataTableCardRole = 'media' | 'title' | 'status' | 'field' | 'action';
|
|
880
|
+
type DataTableCardRole = 'media' | 'title' | 'status' | 'field' | 'meta' | 'action';
|
|
843
881
|
interface DataTableColumn {
|
|
844
882
|
key: string;
|
|
845
883
|
label: string;
|
|
@@ -862,6 +900,46 @@ interface DataTableColumn {
|
|
|
862
900
|
* corto) se comprima más de la cuenta cuando hay poco espacio y otras
|
|
863
901
|
* columnas compiten por él. */
|
|
864
902
|
minWidth?: string;
|
|
903
|
+
/** Ancho fijo de la columna (ej. `'56px'` para una columna de acciones
|
|
904
|
+
* solo ícono, `'9rem'` para una fecha). En la tabla va como `width` de la
|
|
905
|
+
* celda; en `kf-quote-picker` (`modalLayout="list"`), como el ancho de su
|
|
906
|
+
* pista en la grilla. */
|
|
907
|
+
width?: string;
|
|
908
|
+
/** Techo de ancho. En la tabla, junto con `truncate`, reemplaza al
|
|
909
|
+
* techo automático (ver `truncate`). En una tabla con `grow` admite
|
|
910
|
+
* unidades de contenedor relativas al ancho de la tabla, ej.
|
|
911
|
+
* `'min(14rem, 22cqw)'`: el techo baja solo cuando la tabla es angosta. */
|
|
912
|
+
maxWidth?: string;
|
|
913
|
+
/** Peso con el que la columna se reparte TODO el espacio sobrante de la
|
|
914
|
+
* tabla (ej. `1`; con dos columnas `grow: 2` y `grow: 1`, la primera
|
|
915
|
+
* recibe el doble). Con al menos una columna `grow` la tabla pasa a
|
|
916
|
+
* reparto de anchos: las columnas con `width` mantienen ese ancho, las que
|
|
917
|
+
* no traen `width` ni `grow` se ajustan a su contenido (con `maxWidth` como
|
|
918
|
+
* techo) y las `grow` absorben el resto. Se combina con `truncate` para
|
|
919
|
+
* que el texto largo ocupe el espacio sin empujar a las demás. Sin ninguna
|
|
920
|
+
* columna `grow`, el reparto es el de siempre. */
|
|
921
|
+
grow?: number;
|
|
922
|
+
/** Texto largo en UNA línea con elipsis y el valor completo en `title`
|
|
923
|
+
* (ej. el modelo de un vehículo). La columna deja de imponer su ancho
|
|
924
|
+
* mínimo: cede espacio para que las demás (y la de acciones) entren en
|
|
925
|
+
* pantalla sin scroll horizontal. Con `maxWidth`, se corta en ese ancho. */
|
|
926
|
+
truncate?: boolean;
|
|
927
|
+
/** Alineación horizontal. `'end'` equivale a `right: true` (que se
|
|
928
|
+
* mantiene por compatibilidad). */
|
|
929
|
+
align?: 'start' | 'center' | 'end';
|
|
930
|
+
/** Oculta el rótulo del encabezado a la vista (queda para lectores de
|
|
931
|
+
* pantalla) — ej. una columna de acciones solo ícono. */
|
|
932
|
+
hideLabel?: boolean;
|
|
933
|
+
/** Valor en tipografía monoespaciada (ej. un identificador "COT-2026-0042"),
|
|
934
|
+
* en la celda de la tabla y como título de la tarjeta. */
|
|
935
|
+
mono?: boolean;
|
|
936
|
+
/** Vista tarjetas, columna `field`: el valor va a ancho completo (rótulo
|
|
937
|
+
* solo para lectores de pantalla), recortado a este número de líneas con
|
|
938
|
+
* el texto completo en `title` — ej. el modelo del vehículo con `2`. */
|
|
939
|
+
cardClamp?: number;
|
|
940
|
+
/** Destaca el valor (peso y color de tinta) — ej. el monto. En la vista
|
|
941
|
+
* tarjetas, una columna `meta` con `emphasis` va al final de su fila. */
|
|
942
|
+
emphasis?: boolean;
|
|
865
943
|
}
|
|
866
944
|
/** Vistas disponibles cuando `cardable` está activo. */
|
|
867
945
|
type DataTableView = 'table' | 'cards';
|
|
@@ -940,6 +1018,12 @@ type DataTableSort = `${string}:${'asc' | 'desc'}`;
|
|
|
940
1018
|
* <kf-data-table [columns]="columns" [rows]="rows" [pageSize]="25" itemLabel="beneficios" />
|
|
941
1019
|
* <kf-data-table [columns]="columns" [rows]="rows" [pageSize]="25" [pageSizeOptions]="[]" />
|
|
942
1020
|
*
|
|
1021
|
+
* La página es `[(page)]` (el consumidor puede llevarla a la URL) y se
|
|
1022
|
+
* corrige sola si queda fuera de rango. Por defecto un cambio de `rows` la
|
|
1023
|
+
* devuelve a 1; con `keepPageOnRowsChange` la conserva (el consumidor decide
|
|
1024
|
+
* cuándo volver a 1). Un `pageSize` nuevo del consumidor pisa el elegido en
|
|
1025
|
+
* el selector, y `pageSizeChange` avisa cuando el usuario lo cambia.
|
|
1026
|
+
*
|
|
943
1027
|
* Ordenamiento por columna: cada `DataTableColumn` con `sortable: true`
|
|
944
1028
|
* vuelve su header clickeable, con el mismo formato `key:direction` que
|
|
945
1029
|
* usa `sort` de `kf-quote-picker` (two-way manual, no `model()` — el
|
|
@@ -953,6 +1037,55 @@ type DataTableSort = `${string}:${'asc' | 'desc'}`;
|
|
|
953
1037
|
*
|
|
954
1038
|
* Densidad: `density="compact"` reduce el padding vertical de cada fila,
|
|
955
1039
|
* para priorizar cantidad de filas visibles sobre aire entre ellas.
|
|
1040
|
+
*
|
|
1041
|
+
* Listados largos con textos largos (ej. cotizaciones con el modelo del
|
|
1042
|
+
* vehículo): la columna de texto largo lleva `truncate` (elipsis + `title`),
|
|
1043
|
+
* las de dato corto `width`/`align: 'end'`, y la de acciones solo ícono
|
|
1044
|
+
* `width` angosto + `hideLabel` + `sticky: 'right'`. Así la acción queda
|
|
1045
|
+
* siempre a la vista sin scroll horizontal:
|
|
1046
|
+
*
|
|
1047
|
+
* columns = [
|
|
1048
|
+
* { key: 'id', label: 'Cotización', width: '9rem' },
|
|
1049
|
+
* { key: 'model', label: 'Vehículo', truncate: true, minWidth: '10rem' },
|
|
1050
|
+
* { key: 'amount', label: 'Monto', align: 'end', width: '8rem' },
|
|
1051
|
+
* { key: 'open', label: 'Abrir', hideLabel: true, width: '56px', sticky: 'right' },
|
|
1052
|
+
* ];
|
|
1053
|
+
* <kf-data-table [columns]="columns" [rows]="quotes" [rowClickable]="true"
|
|
1054
|
+
* (rowClick)="open($event.row)" [cellTemplates]="{ open: openCell }" />
|
|
1055
|
+
*
|
|
1056
|
+
* Reparto de anchos: con `grow` en alguna columna, esa(s) se reparten TODO el
|
|
1057
|
+
* espacio sobrante según su peso, las de `width` lo mantienen y las que no
|
|
1058
|
+
* traen `width` ni `grow` se ajustan a su contenido (con `maxWidth` como
|
|
1059
|
+
* techo). Así una columna de dato corto (estado, precio, fecha) no acapara
|
|
1060
|
+
* espacio y el texto largo (el vehículo) lo aprovecha:
|
|
1061
|
+
*
|
|
1062
|
+
* columns = [
|
|
1063
|
+
* { key: 'id', label: 'Cotización', width: '8.5rem', mono: true },
|
|
1064
|
+
* { key: 'model', label: 'Vehículo', grow: 1, truncate: true },
|
|
1065
|
+
* { key: 'issuedAt', label: 'Emisión' },
|
|
1066
|
+
* { key: 'price', label: 'Precio', align: 'end', emphasis: true },
|
|
1067
|
+
* { key: 'status', label: 'Estado', truncate: true, maxWidth: '14rem' },
|
|
1068
|
+
* ];
|
|
1069
|
+
*
|
|
1070
|
+
* Listado completo con vista tarjetas (ej. cotizaciones): la vista es
|
|
1071
|
+
* two-way (`[(view)]`) y el toggle interno se oculta con
|
|
1072
|
+
* `[showViewToggle]="false"` cuando el consumidor lo pone en su barra. En
|
|
1073
|
+
* tarjetas: título (`mono`) y estado en una fila, el campo principal a
|
|
1074
|
+
* ancho completo en 2 líneas (`cardClamp: 2`), y fecha/monto en una fila
|
|
1075
|
+
* inferior (`cardRole: 'meta'`, el monto con `emphasis`). Las tarjetas de
|
|
1076
|
+
* una fila miden lo mismo; `cardMinWidth` fija el ancho mínimo. Con
|
|
1077
|
+
* `rowClickable` la tarjeta entera es un botón (Enter/Espacio):
|
|
1078
|
+
*
|
|
1079
|
+
* columns = [
|
|
1080
|
+
* { key: 'id', label: 'Cotización', cardRole: 'title', mono: true },
|
|
1081
|
+
* { key: 'status', label: 'Estado', cardRole: 'status' },
|
|
1082
|
+
* { key: 'model', label: 'Vehículo', truncate: true, cardClamp: 2 },
|
|
1083
|
+
* { key: 'date', label: 'Fecha', cardRole: 'meta', width: '7rem' },
|
|
1084
|
+
* { key: 'amount', label: 'Monto', cardRole: 'meta', align: 'end', emphasis: true },
|
|
1085
|
+
* ];
|
|
1086
|
+
* <kf-data-table [columns]="columns" [rows]="quotes" cardable [(view)]="view"
|
|
1087
|
+
* [showViewToggle]="false" cardMinWidth="300px" [rowClickable]="true"
|
|
1088
|
+
* (rowClick)="open($event.row)" />
|
|
956
1089
|
*/
|
|
957
1090
|
declare class DataTable<T = unknown> {
|
|
958
1091
|
readonly columns: _angular_core.InputSignal<DataTableColumn[]>;
|
|
@@ -972,6 +1105,13 @@ declare class DataTable<T = unknown> {
|
|
|
972
1105
|
*/
|
|
973
1106
|
protected readonly canScrollLeft: _angular_core.WritableSignal<boolean>;
|
|
974
1107
|
protected readonly canScrollRight: _angular_core.WritableSignal<boolean>;
|
|
1108
|
+
/**
|
|
1109
|
+
* Hay contenido oculto por scroll horizontal. Solo entonces el contenedor
|
|
1110
|
+
* es una región nombrada y enfocable (`tabindex="0"`, `role="region"`):
|
|
1111
|
+
* sin foco, quien navega con teclado no puede desplazarlo (WCAG 2.1.1).
|
|
1112
|
+
* Una tabla que entra completa no suma una parada de Tab vacía.
|
|
1113
|
+
*/
|
|
1114
|
+
protected readonly hasOverflow: _angular_core.WritableSignal<boolean>;
|
|
975
1115
|
constructor();
|
|
976
1116
|
private updateScrollState;
|
|
977
1117
|
/** Default: índice de la fila dentro de `rows`. */
|
|
@@ -979,8 +1119,14 @@ declare class DataTable<T = unknown> {
|
|
|
979
1119
|
/** Sin borde/sombra de card — para tablas anidadas dentro de otra card. */
|
|
980
1120
|
readonly flush: _angular_core.InputSignal<boolean>;
|
|
981
1121
|
/** Habilita el toggle de vista tabla/cards. */
|
|
982
|
-
readonly cardable: _angular_core.
|
|
1122
|
+
readonly cardable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
983
1123
|
readonly defaultView: _angular_core.InputSignal<DataTableView>;
|
|
1124
|
+
/** Muestra el toggle tabla/tarjetas interno (con `cardable`). En `false`,
|
|
1125
|
+
* el consumidor controla la vista con `[(view)]` desde su propio control. */
|
|
1126
|
+
readonly showViewToggle: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1127
|
+
/** Ancho mínimo de cada tarjeta en la grilla (default `220px`, histórico).
|
|
1128
|
+
* Nunca supera el ancho disponible: en pantallas angostas, una columna. */
|
|
1129
|
+
readonly cardMinWidth: _angular_core.InputSignal<string>;
|
|
984
1130
|
/**
|
|
985
1131
|
* Formateo simple de celda como texto: `(row) => string`. Para marcado
|
|
986
1132
|
* real (badges, links, botones) usar `cellTemplates`.
|
|
@@ -1000,6 +1146,15 @@ declare class DataTable<T = unknown> {
|
|
|
1000
1146
|
row: T;
|
|
1001
1147
|
index: number;
|
|
1002
1148
|
}>;
|
|
1149
|
+
/** Nombre accesible del contenedor con scroll horizontal (solo se aplica cuando hay overflow). */
|
|
1150
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
1151
|
+
/**
|
|
1152
|
+
* Clave (la misma que devuelve `rowKey`, o el índice sin él) de la fila
|
|
1153
|
+
* "actual" — ej. el registro que se está viendo en un selector. Esa fila
|
|
1154
|
+
* o card lleva `aria-current="true"` y la clase `--current` (fondo
|
|
1155
|
+
* `primary-soft`). `null` (default): ninguna.
|
|
1156
|
+
*/
|
|
1157
|
+
readonly currentRowKey: _angular_core.InputSignal<string | number | null>;
|
|
1003
1158
|
/**
|
|
1004
1159
|
* Paginación interna opcional — sin `pageSize`, cero cambio de
|
|
1005
1160
|
* comportamiento (el consumidor sigue paginando afuera si quiere, vía el
|
|
@@ -1014,7 +1169,16 @@ declare class DataTable<T = unknown> {
|
|
|
1014
1169
|
* portal) — pasar `[]` explícitamente desactiva el selector de tamaño
|
|
1015
1170
|
* aunque `pageSize` esté activo (paginación sin selector). */
|
|
1016
1171
|
readonly pageSizeOptions: _angular_core.InputSignal<number[]>;
|
|
1017
|
-
|
|
1172
|
+
/** Página actual (desde 1), bidireccional: `[(page)]="page"`. El consumidor
|
|
1173
|
+
* puede llevarla fuera de la tabla (ej. en la URL) y la tabla la corrige
|
|
1174
|
+
* si queda fuera de rango. `pageChange` emite en cada cambio, también los
|
|
1175
|
+
* automáticos (volver a 1 al cambiar de tamaño de página). */
|
|
1176
|
+
readonly page: _angular_core.ModelSignal<number>;
|
|
1177
|
+
/** Con `true`, un cambio de `rows` NO devuelve la página a 1: el
|
|
1178
|
+
* consumidor decide cuándo (ej. al filtrar) y la tabla solo la corrige si
|
|
1179
|
+
* queda fuera de rango. Default `false`: vuelve a 1, como siempre. */
|
|
1180
|
+
readonly keepPageOnRowsChange: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1181
|
+
/** Emite el tamaño elegido en el selector de la paginación interna. */
|
|
1018
1182
|
readonly pageSizeChange: _angular_core.OutputEmitterRef<number>;
|
|
1019
1183
|
/** Nombre de la entidad listada (ej. "beneficios", "facturas"), en
|
|
1020
1184
|
* plural — se agrega al final del texto informativo de la paginación
|
|
@@ -1022,7 +1186,6 @@ declare class DataTable<T = unknown> {
|
|
|
1022
1186
|
* números ("1–5 de 7"): la librería no impone un idioma ni un nombre
|
|
1023
1187
|
* fijo, cada consumidor decide el suyo. */
|
|
1024
1188
|
readonly itemLabel: _angular_core.InputSignal<string>;
|
|
1025
|
-
protected readonly page: _angular_core.WritableSignal<number>;
|
|
1026
1189
|
private readonly internalPageSize;
|
|
1027
1190
|
/** Tamaño de página efectivo: el que el usuario elija en el selector
|
|
1028
1191
|
* (si `pageSizeOptions` está activo), o el `pageSize` del consumidor. */
|
|
@@ -1044,8 +1207,8 @@ declare class DataTable<T = unknown> {
|
|
|
1044
1207
|
* asc → desc → sin orden; clickear otra columna reinicia el ciclo en esa
|
|
1045
1208
|
* columna nueva.
|
|
1046
1209
|
*/
|
|
1047
|
-
readonly sort: _angular_core.InputSignal<`${string}:
|
|
1048
|
-
readonly sortChange: _angular_core.OutputEmitterRef<`${string}:
|
|
1210
|
+
readonly sort: _angular_core.InputSignal<`${string}:asc` | `${string}:desc` | null>;
|
|
1211
|
+
readonly sortChange: _angular_core.OutputEmitterRef<`${string}:asc` | `${string}:desc` | null>;
|
|
1049
1212
|
protected readonly sortedRows: _angular_core.Signal<T[]>;
|
|
1050
1213
|
/** Filas realmente renderizadas: ordenadas y, si `pageSize` está activo,
|
|
1051
1214
|
* recortadas a la página actual. */
|
|
@@ -1055,21 +1218,60 @@ declare class DataTable<T = unknown> {
|
|
|
1055
1218
|
protected toggleSort(column: DataTableColumn): void;
|
|
1056
1219
|
protected goToPage(target: number): void;
|
|
1057
1220
|
protected setPageSize(size: number | null): void;
|
|
1221
|
+
/**
|
|
1222
|
+
* Reparto de anchos activo: hay al menos una columna `grow`. Sin ella, los
|
|
1223
|
+
* anchos son los de siempre (`width`/`minWidth`/`maxWidth` tal cual).
|
|
1224
|
+
*/
|
|
1225
|
+
protected readonly weighted: _angular_core.Signal<boolean>;
|
|
1226
|
+
/** Porción (%) del espacio sobrante de cada columna `grow`, según su peso. */
|
|
1227
|
+
private readonly growShares;
|
|
1228
|
+
private growWeight;
|
|
1229
|
+
/**
|
|
1230
|
+
* `width` de la celda. En reparto de anchos: la columna `grow` toma su
|
|
1231
|
+
* porción en porcentaje (las porciones suman 100% y el navegador las escala
|
|
1232
|
+
* al espacio que dejan las demás), la de `width` conserva su ancho y la que
|
|
1233
|
+
* no trae ni `width` ni `grow` pide 1% — con `nowrap` queda en el ancho de
|
|
1234
|
+
* su contenido.
|
|
1235
|
+
*/
|
|
1236
|
+
protected widthFor(column: DataTableColumn): string | null;
|
|
1237
|
+
/**
|
|
1238
|
+
* `min-width` de la celda. En reparto de anchos, el `width` de una columna
|
|
1239
|
+
* (también de una `grow`) funciona como piso: ni las porciones en
|
|
1240
|
+
* porcentaje ni el contenido de las demás pueden comprimirla.
|
|
1241
|
+
*/
|
|
1242
|
+
protected minWidthFor(column: DataTableColumn): string | null;
|
|
1243
|
+
/**
|
|
1244
|
+
* `max-width` de la celda. En reparto de anchos, una columna que se ajusta
|
|
1245
|
+
* a su contenido y es `truncate` SIN `maxWidth` no debe heredar el techo de
|
|
1246
|
+
* 0 de `truncate` (quedaría sin ancho): se libera con `none`.
|
|
1247
|
+
*/
|
|
1248
|
+
protected maxWidthFor(column: DataTableColumn): string | null;
|
|
1058
1249
|
/** Columnas fijas del lado izquierdo/derecho, con el offset acumulado
|
|
1059
1250
|
* (medido en runtime, ver `measureStickyOffsets`) para `position: sticky`. */
|
|
1060
1251
|
protected readonly stickyLeftColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1061
1252
|
protected readonly stickyRightColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1062
1253
|
protected readonly stickyOffsets: _angular_core.WritableSignal<Map<string, number>>;
|
|
1063
1254
|
protected stickyStyle(column: DataTableColumn): Record<string, string> | null;
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1255
|
+
/**
|
|
1256
|
+
* Vista elegida, two-way: `[(view)]="view"`. Sin valor (default) manda
|
|
1257
|
+
* `defaultView`; el toggle interno la escribe. Para controlarla desde
|
|
1258
|
+
* afuera (ej. con el toggle en `kf-list-toolbar` y el estado en la URL),
|
|
1259
|
+
* enlazar `[(view)]` y ocultar el interno con `[showViewToggle]="false"`.
|
|
1260
|
+
* La vista efectivamente renderizada es `activeView()`.
|
|
1261
|
+
*/
|
|
1262
|
+
readonly view: _angular_core.ModelSignal<DataTableView | undefined>;
|
|
1263
|
+
/** Vista activa: `view` si está definida, si no `defaultView`. */
|
|
1264
|
+
readonly activeView: _angular_core.Signal<DataTableView>;
|
|
1067
1265
|
/** Primera columna de cada rol único; el resto se ignora en el encabezado. */
|
|
1068
1266
|
readonly cardMediaColumn: _angular_core.Signal<DataTableColumn | undefined>;
|
|
1069
1267
|
readonly cardTitleColumn: _angular_core.Signal<DataTableColumn | undefined>;
|
|
1070
1268
|
readonly cardStatusColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1071
1269
|
readonly cardActionColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1072
1270
|
readonly cardFieldColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1271
|
+
/** Campos a ancho completo y recortados (`cardClamp`), antes del resto. */
|
|
1272
|
+
readonly cardLeadColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1273
|
+
/** Fila inferior de datos secundarios (`cardRole: 'meta'`). */
|
|
1274
|
+
readonly cardMetaColumns: _angular_core.Signal<DataTableColumn[]>;
|
|
1073
1275
|
/**
|
|
1074
1276
|
* La card entera es clickeable solo si no tiene acciones propias: un
|
|
1075
1277
|
* `role="button"` con botones adentro es inválido y deja el foco ambiguo.
|
|
@@ -1087,8 +1289,28 @@ declare class DataTable<T = unknown> {
|
|
|
1087
1289
|
readonly rowInteractive: _angular_core.Signal<boolean>;
|
|
1088
1290
|
setView(next: DataTableView): void;
|
|
1089
1291
|
trackRow(row: T, index: number): string | number;
|
|
1292
|
+
/** Alineada al final: `align: 'end'` o el histórico `right: true`. */
|
|
1293
|
+
protected isEndAligned(column: DataTableColumn): boolean;
|
|
1294
|
+
/** `title` de una celda `truncate`: el valor completo como texto. */
|
|
1295
|
+
protected truncateTitle(row: T, column: DataTableColumn): string | null;
|
|
1090
1296
|
cellValue(row: T, column: DataTableColumn): string;
|
|
1091
|
-
|
|
1297
|
+
protected isCurrentRow(row: T, index: number): boolean;
|
|
1298
|
+
/**
|
|
1299
|
+
* Espacio activa la fila/card igual que Enter, como un botón. Solo si el
|
|
1300
|
+
* foco está en la fila misma (no en un control dentro de ella): ahí
|
|
1301
|
+
* `preventDefault` evita el scroll de página; en cualquier otro caso
|
|
1302
|
+
* Espacio conserva su comportamiento nativo.
|
|
1303
|
+
*/
|
|
1304
|
+
protected onRowSpace(event: Event, row: T, index: number): void;
|
|
1305
|
+
/**
|
|
1306
|
+
* Emite `rowClick` salvo que el evento nazca dentro de un control
|
|
1307
|
+
* interactivo de la celda (enlace, botón, campo…): ese control ya resuelve
|
|
1308
|
+
* su propia acción. Así una celda con un `<a href>` real (clic derecho →
|
|
1309
|
+
* "abrir en nueva pestaña", Ctrl/Cmd+clic) no navega dos veces. El parámetro
|
|
1310
|
+
* `event` es opcional para no romper llamadas programáticas existentes.
|
|
1311
|
+
*/
|
|
1312
|
+
onRowClick(row: T, index: number, event?: Event): void;
|
|
1313
|
+
private originatesInInteractiveControl;
|
|
1092
1314
|
/**
|
|
1093
1315
|
* Ancho real de cada columna `sticky` — se mide después de cada render
|
|
1094
1316
|
* porque el ancho de una columna depende de su contenido, no hay forma
|
|
@@ -1099,7 +1321,7 @@ declare class DataTable<T = unknown> {
|
|
|
1099
1321
|
*/
|
|
1100
1322
|
protected measureStickyOffsets(): void;
|
|
1101
1323
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataTable<any>, never>;
|
|
1102
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTable<any>, "kf-data-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "flush": { "alias": "flush"; "required": false; "isSignal": true; }; "cardable": { "alias": "cardable"; "required": false; "isSignal": true; }; "defaultView": { "alias": "defaultView"; "required": false; "isSignal": true; }; "render": { "alias": "render"; "required": false; "isSignal": true; }; "cellTemplates": { "alias": "cellTemplates"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "rowClickable": { "alias": "rowClickable"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "itemLabel": { "alias": "itemLabel"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; }, { "rowClick": "rowClick"; "
|
|
1324
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTable<any>, "kf-data-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "flush": { "alias": "flush"; "required": false; "isSignal": true; }; "cardable": { "alias": "cardable"; "required": false; "isSignal": true; }; "defaultView": { "alias": "defaultView"; "required": false; "isSignal": true; }; "showViewToggle": { "alias": "showViewToggle"; "required": false; "isSignal": true; }; "cardMinWidth": { "alias": "cardMinWidth"; "required": false; "isSignal": true; }; "render": { "alias": "render"; "required": false; "isSignal": true; }; "cellTemplates": { "alias": "cellTemplates"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "rowClickable": { "alias": "rowClickable"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "currentRowKey": { "alias": "currentRowKey"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "page": { "alias": "page"; "required": false; "isSignal": true; }; "keepPageOnRowsChange": { "alias": "keepPageOnRowsChange"; "required": false; "isSignal": true; }; "itemLabel": { "alias": "itemLabel"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "view": { "alias": "view"; "required": false; "isSignal": true; }; }, { "rowClick": "rowClick"; "page": "pageChange"; "pageSizeChange": "pageSizeChange"; "sortChange": "sortChange"; "view": "viewChange"; }, never, ["[empty]", "[footer]"], true, never>;
|
|
1103
1325
|
}
|
|
1104
1326
|
|
|
1105
1327
|
/**
|
|
@@ -1164,7 +1386,14 @@ declare class DocumentRow {
|
|
|
1164
1386
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DocumentRow, "kf-document-row", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "downloadLabel": { "alias": "downloadLabel"; "required": false; "isSignal": true; }; "pendingLabel": { "alias": "pendingLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1165
1387
|
}
|
|
1166
1388
|
|
|
1167
|
-
|
|
1389
|
+
/** Borde de anclaje del panel. `bottom` es una hoja inferior (bottom sheet). */
|
|
1390
|
+
type DrawerSide = 'left' | 'right' | 'bottom';
|
|
1391
|
+
/**
|
|
1392
|
+
* Rol del panel. `navigation` (default) es el menú lateral histórico;
|
|
1393
|
+
* `dialog` es un panel modal de tarea (filtros, resumen) con
|
|
1394
|
+
* `aria-modal="true"`.
|
|
1395
|
+
*/
|
|
1396
|
+
type DrawerRole = 'navigation' | 'dialog';
|
|
1168
1397
|
/**
|
|
1169
1398
|
* Panel lateral genérico, agnóstico de contenido — no sabe qué es navegación
|
|
1170
1399
|
* ni qué es sesión, solo da tres lugares para proyectar contenido
|
|
@@ -1197,17 +1426,71 @@ type DrawerSide = 'left' | 'right';
|
|
|
1197
1426
|
* <a href="/">Home</a>
|
|
1198
1427
|
* <a href="/vehiculos">Vehículos</a>
|
|
1199
1428
|
* </kf-drawer>
|
|
1429
|
+
*
|
|
1430
|
+
* ## Panel de tarea (`role="dialog"`)
|
|
1431
|
+
*
|
|
1432
|
+
* Para un panel modal que no es navegación (filtros de un listado, resumen
|
|
1433
|
+
* de un registro): `role="dialog"` expone `role="dialog"` + `aria-modal`,
|
|
1434
|
+
* `title` dibuja una barra clara con el título (que nombra el diálogo vía
|
|
1435
|
+
* `aria-labelledby`) y un botón de cierre con `closeLabel`. En pantallas de
|
|
1436
|
+
* hasta 640px el panel ocupa el ancho completo; arriba de eso mide
|
|
1437
|
+
* `--kf-drawer-width` (default 480px). El pie (`[kf-drawer-footer]`) queda
|
|
1438
|
+
* fijo abajo mientras el cuerpo hace scroll.
|
|
1439
|
+
*
|
|
1440
|
+
* <kf-drawer [(open)]="filtersOpen" role="dialog" side="right"
|
|
1441
|
+
* title="Filtros" closeLabel="Cerrar filtros">
|
|
1442
|
+
* <kf-option-list label="Estado" ... />
|
|
1443
|
+
* <div kf-drawer-footer> ...Limpiar / Ver 12 resultados... </div>
|
|
1444
|
+
* </kf-drawer>
|
|
1445
|
+
*
|
|
1446
|
+
* `side="bottom"` lo convierte en hoja inferior (grip, esquinas superiores
|
|
1447
|
+
* redondeadas, alto máximo 80vh) — pensado para un resumen en mobile.
|
|
1448
|
+
*
|
|
1449
|
+
* Escape cierra el panel salvo que un control interno ya haya consumido la
|
|
1450
|
+
* tecla (`event.defaultPrevented`, ej. un `kf-select` abierto dentro del
|
|
1451
|
+
* drawer cierra solo su propio panel).
|
|
1452
|
+
*
|
|
1453
|
+
* Nombres por defecto: con `role="navigation"` el panel se llama "Menú" y
|
|
1454
|
+
* el cierre "Cerrar menú" (comportamiento histórico). Con `role="dialog"`
|
|
1455
|
+
* los defaults son neutros ("Diálogo" / "Cerrar") y en modo desarrollo se
|
|
1456
|
+
* avisa por consola si no hay `title` ni `ariaLabel`: un diálogo sin nombre
|
|
1457
|
+
* propio no le dice nada al lector de pantalla.
|
|
1458
|
+
*
|
|
1459
|
+
* Limitación conocida: NO colocar un `kf-select` (ni otro control con panel
|
|
1460
|
+
* flotante del CDK) dentro de un drawer `role="dialog"`. Su listbox se
|
|
1461
|
+
* monta en `.cdk-overlay-container`, fuera del diálogo con `aria-modal`: un
|
|
1462
|
+
* lector de pantalla puede tratarlo como contenido inerte y la trampa de
|
|
1463
|
+
* foco no lo incluye. Para elegir una opción dentro del panel usar
|
|
1464
|
+
* `kf-option-list`.
|
|
1465
|
+
*
|
|
1466
|
+
* Al cerrar, el foco vuelve al elemento que lo tenía al abrir solo si sigue
|
|
1467
|
+
* en el documento (`isConnected`); si fue desmontado mientras el drawer
|
|
1468
|
+
* estaba abierto, no se fuerza ningún destino.
|
|
1200
1469
|
*/
|
|
1201
1470
|
declare class Drawer {
|
|
1202
1471
|
/** Visibilidad del panel, two-way: `[(open)]="menuOpen"`. */
|
|
1203
1472
|
readonly open: _angular_core.ModelSignal<boolean>;
|
|
1204
1473
|
/** Borde de anclaje del panel. `left` (default) es la convención dominante
|
|
1205
1474
|
* (Material/iOS/Android): el botón que abre el drawer y el propio panel
|
|
1206
|
-
* quedan del mismo lado. */
|
|
1475
|
+
* quedan del mismo lado. `bottom` lo convierte en hoja inferior. */
|
|
1207
1476
|
readonly side: _angular_core.InputSignal<DrawerSide>;
|
|
1208
|
-
/** `
|
|
1209
|
-
|
|
1210
|
-
|
|
1477
|
+
/** `navigation` (default, menú) o `dialog` (panel modal de tarea). Ver JSDoc de la clase. */
|
|
1478
|
+
readonly role: _angular_core.InputSignal<DrawerRole>;
|
|
1479
|
+
/** `aria-label` del panel — describe su propósito para lectores de
|
|
1480
|
+
* pantalla (ej. "Menú de navegación"). Ignorado cuando hay `title`, que
|
|
1481
|
+
* nombra el panel con su texto visible. Default: "Menú" (`navigation`) o
|
|
1482
|
+
* "Diálogo" (`dialog`). */
|
|
1483
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
1484
|
+
/** Título visible en una barra clara arriba del panel, con botón de cierre. Sin él no hay barra (comportamiento histórico). */
|
|
1485
|
+
readonly title: _angular_core.InputSignal<string | undefined>;
|
|
1486
|
+
/** Nombre accesible del botón de cierre de la barra de título y del
|
|
1487
|
+
* overlay. Default: "Cerrar menú" (`navigation`) o "Cerrar" (`dialog`). */
|
|
1488
|
+
readonly closeLabel: _angular_core.InputSignal<string | undefined>;
|
|
1489
|
+
/** `ariaLabel` o, sin él, el default según el rol. */
|
|
1490
|
+
protected readonly resolvedAriaLabel: _angular_core.Signal<string>;
|
|
1491
|
+
/** `closeLabel` o, sin él, el default según el rol. */
|
|
1492
|
+
protected readonly resolvedCloseLabel: _angular_core.Signal<string>;
|
|
1493
|
+
protected readonly titleId: string;
|
|
1211
1494
|
private readonly panelRef;
|
|
1212
1495
|
private readonly focusTrapFactory;
|
|
1213
1496
|
private readonly document;
|
|
@@ -1215,10 +1498,10 @@ declare class Drawer {
|
|
|
1215
1498
|
private lastFocusedElement;
|
|
1216
1499
|
constructor();
|
|
1217
1500
|
/** Cierra el drawer con Escape — mismo patrón que `Dropdown`/`Modal`. */
|
|
1218
|
-
protected onEscape(): void;
|
|
1501
|
+
protected onEscape(event: Event): void;
|
|
1219
1502
|
private getOrCreateFocusTrap;
|
|
1220
1503
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Drawer, never>;
|
|
1221
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Drawer, "kf-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "side": { "alias": "side"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[kf-drawer-header]", "*", "[kf-drawer-footer]"], true, never>;
|
|
1504
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Drawer, "kf-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "side": { "alias": "side"; "required": false; "isSignal": true; }; "role": { "alias": "role"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[kf-drawer-header]", "*", "[kf-drawer-footer]"], true, never>;
|
|
1222
1505
|
}
|
|
1223
1506
|
|
|
1224
1507
|
/**
|
|
@@ -1334,6 +1617,8 @@ declare class DropdownPanel {
|
|
|
1334
1617
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownPanel, "kf-dropdown-panel", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1335
1618
|
}
|
|
1336
1619
|
|
|
1620
|
+
/** Tono del estado. `warn`/`info` solo cambian el chip del ícono. */
|
|
1621
|
+
type EmptyStateTone = 'neutral' | 'error' | 'warn' | 'info';
|
|
1337
1622
|
/**
|
|
1338
1623
|
* Placeholder para una sección sin contenido. Dos tonos, con anatomía
|
|
1339
1624
|
* distinta (páginas 27-28 del design system, que los trata como piezas
|
|
@@ -1353,13 +1638,45 @@ declare class DropdownPanel {
|
|
|
1353
1638
|
* No pudimos cargar tus vehículos
|
|
1354
1639
|
* <kf-button (click)="retry()">Reintentar</kf-button>
|
|
1355
1640
|
* </kf-empty-state>
|
|
1641
|
+
*
|
|
1642
|
+
* ## Variante `card`
|
|
1643
|
+
* Tarjeta centrada (fondo blanco, borde, sombra, ancho máximo 480px) para
|
|
1644
|
+
* un estado que REEMPLAZA a un contenido grande — ej. un iframe que no
|
|
1645
|
+
* cargó o un documento que aún no existe. Ícono en un círculo tonal de
|
|
1646
|
+
* 56px según `tone` (`warn`, `info`, `error` o `neutral`), `title` como
|
|
1647
|
+
* título, el contenido proyectado como texto (puede incluir una lista de
|
|
1648
|
+
* pasos) y `[kf-empty-state-actions]` para los botones. Los roles
|
|
1649
|
+
* (`role="alert"` para un error) los pone el consumidor en el host: no
|
|
1650
|
+
* todo estado de esta forma debe interrumpir al lector de pantalla.
|
|
1651
|
+
*
|
|
1652
|
+
* <kf-empty-state variant="card" tone="warn" icon="alert-triangle"
|
|
1653
|
+
* title="No pudimos cargar la propuesta" role="alert">
|
|
1654
|
+
* <p>Este contenido solo está disponible dentro de la red de la empresa.</p>
|
|
1655
|
+
* <ol>…pasos…</ol>
|
|
1656
|
+
* <div kf-empty-state-actions>
|
|
1657
|
+
* <kf-button (click)="retry()">Reintentar</kf-button>
|
|
1658
|
+
* </div>
|
|
1659
|
+
* </kf-empty-state>
|
|
1660
|
+
*
|
|
1661
|
+
* `[kf-empty-state-footer]` va DESPUÉS de las acciones, para pistas y
|
|
1662
|
+
* metadatos debajo de los botones ("¿Ya estás conectado? …", "Intento 2 ·
|
|
1663
|
+
* 10:42"). Vacío, no ocupa lugar.
|
|
1664
|
+
*
|
|
1665
|
+
* `title` se dibuja como texto destacado, no como encabezado (`<h*>`): el
|
|
1666
|
+
* nivel de encabezado depende de la página que lo contiene, y un estado
|
|
1667
|
+
* vacío no debe alterar su estructura.
|
|
1356
1668
|
*/
|
|
1357
1669
|
declare class EmptyState {
|
|
1358
1670
|
readonly icon: _angular_core.InputSignal<IconName | undefined>;
|
|
1359
|
-
/** `neutral` (default): cero resultados. `error`: fallo real de carga. */
|
|
1360
|
-
readonly tone: _angular_core.InputSignal<
|
|
1671
|
+
/** `neutral` (default): cero resultados. `error`: fallo real de carga. `warn`/`info`: tiñen el chip del ícono. */
|
|
1672
|
+
readonly tone: _angular_core.InputSignal<EmptyStateTone>;
|
|
1673
|
+
/** `inline` (default, histórico) o `card` (tarjeta centrada). Ver JSDoc de la clase. */
|
|
1674
|
+
readonly variant: _angular_core.InputSignal<"inline" | "card">;
|
|
1675
|
+
/** Título destacado sobre el contenido. Opcional en ambas variantes. */
|
|
1676
|
+
readonly title: _angular_core.InputSignal<string | undefined>;
|
|
1677
|
+
protected readonly iconSize: _angular_core.Signal<IconSize>;
|
|
1361
1678
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EmptyState, never>;
|
|
1362
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EmptyState, "kf-empty-state", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1679
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EmptyState, "kf-empty-state", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[kf-empty-state-actions]", "[kf-empty-state-footer]"], true, never>;
|
|
1363
1680
|
}
|
|
1364
1681
|
|
|
1365
1682
|
/** Color del marcador. Distingue la CLASE de evento de un vistazo en un log
|
|
@@ -1627,43 +1944,63 @@ declare class Filter {
|
|
|
1627
1944
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Filter, "kf-filter", never, { "fields": { "alias": "fields"; "required": true; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "mobileTitle": { "alias": "mobileTitle"; "required": false; "isSignal": true; }; }, { "fieldChange": "fieldChange"; }, never, never, true, never>;
|
|
1628
1945
|
}
|
|
1629
1946
|
|
|
1630
|
-
/**
|
|
1947
|
+
/**
|
|
1948
|
+
* Opción en forma de objeto. `count` es opcional: cuando está presente se
|
|
1949
|
+
* muestra a la derecha del label (ej. "Pendientes 3"), con cifras tabulares
|
|
1950
|
+
* para que el ancho del chip no salte al cambiar el número.
|
|
1951
|
+
*/
|
|
1631
1952
|
interface FilterChipOption {
|
|
1632
1953
|
value: string;
|
|
1633
1954
|
label: string;
|
|
1955
|
+
count?: number;
|
|
1634
1956
|
}
|
|
1635
1957
|
/**
|
|
1636
1958
|
* Fila de chips tipo "pill" para filtros de una sola selección.
|
|
1637
1959
|
*
|
|
1638
1960
|
* Cada opción puede pasarse como string simple (se usa como value y label
|
|
1639
|
-
* a la vez) o como objeto { value, label } cuando el texto
|
|
1640
|
-
* del valor interno.
|
|
1961
|
+
* a la vez) o como objeto `{ value, label, count? }` cuando el texto
|
|
1962
|
+
* mostrado difiere del valor interno o cuando cada chip lleva un contador.
|
|
1641
1963
|
*
|
|
1642
1964
|
* El chip activo se resalta con `--kf-color-primary` — mismo color de marca
|
|
1643
1965
|
* que `kf-tabs`/`kf-select` para su propio estado activo, así el filtro
|
|
1644
1966
|
* seleccionado se lee con el color del tema activo, no un negro fijo que
|
|
1645
1967
|
* no cambia entre marcas.
|
|
1646
1968
|
*
|
|
1969
|
+
* Densidad: el padding horizontal de cada chip sale de
|
|
1970
|
+
* `--kf-filter-chips-padding-inline` (default `--kf-space-md`). Un
|
|
1971
|
+
* contenedor puede reducirlo sin tocar este componente — `kf-list-toolbar`
|
|
1972
|
+
* lo baja a 12px en su modo compacto.
|
|
1973
|
+
*
|
|
1647
1974
|
* <kf-filter-chips [options]="['Todos', 'Activos', 'Archivados']"
|
|
1648
1975
|
* [value]="filtro"
|
|
1649
1976
|
* (valueChange)="filtro = $event" />
|
|
1650
1977
|
*
|
|
1651
|
-
*
|
|
1978
|
+
* `layout="scroll"` deja todos los chips en UNA línea con desplazamiento
|
|
1979
|
+
* horizontal (para mobile: los filtros no ocupan más alto que una fila); el
|
|
1980
|
+
* default `wrap` los reparte en varias líneas. `deselectable` permite
|
|
1981
|
+
* quitar el filtro volviendo a tocar el chip activo (emite `''`), para el
|
|
1982
|
+
* caso "ningún chip = sin filtro".
|
|
1983
|
+
*
|
|
1984
|
+
* <kf-filter-chips ariaLabel="Filtrar por estado"
|
|
1985
|
+
* [options]="[{ value: '', label: 'Todas', count: 12 }]"
|
|
1652
1986
|
* [value]="filtro"
|
|
1653
1987
|
* (valueChange)="filtro = $event" />
|
|
1654
1988
|
*/
|
|
1655
1989
|
declare class FilterChips {
|
|
1656
|
-
readonly options: _angular_core.InputSignal<(string |
|
|
1657
|
-
value: string;
|
|
1658
|
-
label: string;
|
|
1659
|
-
})[]>;
|
|
1990
|
+
readonly options: _angular_core.InputSignal<(string | FilterChipOption)[]>;
|
|
1660
1991
|
readonly value: _angular_core.InputSignal<string>;
|
|
1992
|
+
/** Nombre accesible del grupo (ej. "Filtrar por estado"). Sin él, el grupo se anuncia sin nombre. */
|
|
1993
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
1994
|
+
/** `wrap` (default): varias líneas. `scroll`: una sola línea con desplazamiento horizontal. */
|
|
1995
|
+
readonly layout: _angular_core.InputSignal<"scroll" | "wrap">;
|
|
1996
|
+
/** Tocar el chip activo lo desactiva y emite `''`. Default `false` (comportamiento histórico). */
|
|
1997
|
+
readonly deselectable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1661
1998
|
readonly valueChange: _angular_core.OutputEmitterRef<string>;
|
|
1662
|
-
/** Normaliza cada opción string/objeto a la forma { value, label }
|
|
1999
|
+
/** Normaliza cada opción string/objeto a la forma `{ value, label, count? }`. */
|
|
1663
2000
|
readonly normalizedOptions: _angular_core.Signal<FilterChipOption[]>;
|
|
1664
2001
|
select(value: string): void;
|
|
1665
2002
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FilterChips, never>;
|
|
1666
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FilterChips, "kf-filter-chips", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
2003
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FilterChips, "kf-filter-chips", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "deselectable": { "alias": "deselectable"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
1667
2004
|
}
|
|
1668
2005
|
|
|
1669
2006
|
/** Un link del pie — legales, contacto, soporte. */
|
|
@@ -1740,6 +2077,27 @@ declare class Footer {
|
|
|
1740
2077
|
* está en vuelo).
|
|
1741
2078
|
*
|
|
1742
2079
|
* <kf-input label="DNI" readonly formControlName="documentId" />
|
|
2080
|
+
*
|
|
2081
|
+
* Buscador sin label visible: `ariaLabel` da el nombre accesible del
|
|
2082
|
+
* `<input>` (el placeholder no lo reemplaza: desaparece al escribir) y
|
|
2083
|
+
* `clearable` agrega un botón "×" mientras haya texto. Borrar limpia el
|
|
2084
|
+
* valor, notifica al formulario (`ngModel`/`formControl`), dispara un
|
|
2085
|
+
* evento `input` nativo (para quien escucha `(input)`), emite `cleared` y
|
|
2086
|
+
* devuelve el foco al campo.
|
|
2087
|
+
*
|
|
2088
|
+
* <kf-input type="search" icon="search" ariaLabel="Buscar cotizaciones"
|
|
2089
|
+
* placeholder="Buscar cotización" clearable [(ngModel)]="query" />
|
|
2090
|
+
*
|
|
2091
|
+
* `focus()` enfoca el `<input>` nativo, sin que el consumidor busque el
|
|
2092
|
+
* control interno con `querySelector`.
|
|
2093
|
+
*
|
|
2094
|
+
* `autocomplete`, `name` e `inputmode` se reenvían al `<input>` nativo (un
|
|
2095
|
+
* atributo en el host no llega adentro) para que el navegador y los gestores
|
|
2096
|
+
* de contraseñas identifiquen el campo; sin valor no se renderiza ningún
|
|
2097
|
+
* atributo. Funcionan igual con `type="password"` y `toggleable`.
|
|
2098
|
+
*
|
|
2099
|
+
* <kf-input label="RUT" autocomplete="username" name="rut" inputmode="text" formControlName="rut" />
|
|
2100
|
+
* <kf-input type="password" label="Contraseña" toggleable autocomplete="current-password" name="password" formControlName="password" />
|
|
1743
2101
|
*/
|
|
1744
2102
|
declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
1745
2103
|
private static nextId;
|
|
@@ -1766,11 +2124,29 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
|
1766
2124
|
readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1767
2125
|
readonly type: _angular_core.InputSignal<string>;
|
|
1768
2126
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
1769
|
-
/**
|
|
1770
|
-
*
|
|
1771
|
-
|
|
2127
|
+
/** Token de autocompletado HTML (`username`, `email`, `current-password`,
|
|
2128
|
+
* `new-password`, `off`, etc.) que se reenvía al `<input>` nativo para que
|
|
2129
|
+
* el navegador y los gestores de contraseñas identifiquen el propósito del
|
|
2130
|
+
* campo (WCAG 1.3.5 y 3.3.8). Sin valor, el atributo no se renderiza. */
|
|
2131
|
+
readonly autocomplete: _angular_core.InputSignal<string | null | undefined>;
|
|
2132
|
+
/** `name` del `<input>` nativo; los gestores de contraseñas y el envío
|
|
2133
|
+
* nativo de formularios lo usan para identificar el campo. Sin valor, el
|
|
2134
|
+
* atributo no se renderiza. */
|
|
2135
|
+
readonly name: _angular_core.InputSignal<string | null | undefined>;
|
|
2136
|
+
/** Sugiere el teclado virtual (`numeric`, `email`, `tel`, etc.) sin cambiar
|
|
2137
|
+
* el `type`. Sin valor, el atributo no se renderiza. */
|
|
2138
|
+
readonly inputmode: _angular_core.InputSignal<string | null | undefined>;
|
|
1772
2139
|
/** Agrega el botón de mostrar/ocultar — sin efecto si `type` no es `"password"`. */
|
|
1773
2140
|
readonly toggleable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2141
|
+
/** Nombre accesible del `<input>` cuando no hay `label` visible. Ignorado
|
|
2142
|
+
* si hay `label`: un `aria-label` pisaría al `<label for>` visible. */
|
|
2143
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
2144
|
+
/** Agrega un botón "×" para borrar el valor mientras haya texto (sin efecto con `disabled`/`readonly`). */
|
|
2145
|
+
readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2146
|
+
/** Nombre accesible del botón de borrar. */
|
|
2147
|
+
readonly clearLabel: _angular_core.InputSignal<string>;
|
|
2148
|
+
/** Emitido después de borrar el valor con el botón "×". */
|
|
2149
|
+
readonly cleared: _angular_core.OutputEmitterRef<void>;
|
|
1774
2150
|
protected readonly inputId: string;
|
|
1775
2151
|
protected readonly hintId: string;
|
|
1776
2152
|
protected readonly errorId: string;
|
|
@@ -1784,6 +2160,8 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
|
1784
2160
|
protected readonly passwordVisible: _angular_core.WritableSignal<boolean>;
|
|
1785
2161
|
/** El botón solo tiene sentido si el campo realmente es de contraseña. */
|
|
1786
2162
|
protected readonly showPasswordToggle: _angular_core.Signal<boolean>;
|
|
2163
|
+
/** El botón de borrar solo aparece con texto y con el campo editable. */
|
|
2164
|
+
protected readonly showClear: _angular_core.Signal<boolean>;
|
|
1787
2165
|
/**
|
|
1788
2166
|
* `type` real que recibe el `<input>` nativo: igual a `type()` salvo
|
|
1789
2167
|
* cuando el toggle está activo y visible, donde pasa a `text` para
|
|
@@ -1794,12 +2172,22 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
|
1794
2172
|
private onChange;
|
|
1795
2173
|
private onTouched;
|
|
1796
2174
|
ngAfterViewInit(): void;
|
|
2175
|
+
/** Enfoca el `<input>` nativo (mismas opciones que `HTMLElement.focus`). */
|
|
2176
|
+
focus(options?: FocusOptions): void;
|
|
1797
2177
|
writeValue(value: string): void;
|
|
1798
2178
|
registerOnChange(fn: (value: string) => void): void;
|
|
1799
2179
|
registerOnTouched(fn: () => void): void;
|
|
1800
2180
|
setDisabledState(isDisabled: boolean): void;
|
|
1801
2181
|
protected onInput(rawValue: string): void;
|
|
1802
2182
|
protected onBlur(): void;
|
|
2183
|
+
/**
|
|
2184
|
+
* Borra el valor reutilizando el mismo camino que el tipeo: un evento
|
|
2185
|
+
* `input` nativo pasa por `onInput` (notifica al formulario) y además
|
|
2186
|
+
* llega a cualquier `(input)` del consumidor. Con el mouse no hay blur:
|
|
2187
|
+
* el `mousedown` del botón hace `preventDefault` (ver Input.html), así el
|
|
2188
|
+
* campo no se marca `touched` por usar su propio "×".
|
|
2189
|
+
*/
|
|
2190
|
+
protected onClear(): void;
|
|
1803
2191
|
/**
|
|
1804
2192
|
* Alterna la visibilidad del valor. No dispara `onBlur`/pierde el foco:
|
|
1805
2193
|
* el botón vive dentro del mismo `.kf-input__field`, así que un click acá
|
|
@@ -1807,7 +2195,7 @@ declare class Input implements ControlValueAccessor, AfterViewInit {
|
|
|
1807
2195
|
*/
|
|
1808
2196
|
protected onTogglePasswordVisibility(): void;
|
|
1809
2197
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Input, never>;
|
|
1810
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Input, "kf-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "inputmode": { "alias": "inputmode"; "required": false; "isSignal": true; }; "toggleable": { "alias": "toggleable"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2198
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Input, "kf-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "inputmode": { "alias": "inputmode"; "required": false; "isSignal": true; }; "toggleable": { "alias": "toggleable"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; }, { "cleared": "cleared"; }, never, never, true, never>;
|
|
1811
2199
|
}
|
|
1812
2200
|
|
|
1813
2201
|
type JourneyStepStatus = 'done' | 'current' | 'delayed' | 'pending';
|
|
@@ -1900,6 +2288,205 @@ declare class Link {
|
|
|
1900
2288
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Link, "kf-link", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "showArrow": { "alias": "showArrow"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1901
2289
|
}
|
|
1902
2290
|
|
|
2291
|
+
/**
|
|
2292
|
+
* Modo de `kf-list-toolbar` según el ancho REAL disponible:
|
|
2293
|
+
* - `full`: todo en una fila con la densidad normal.
|
|
2294
|
+
* - `compact`: todo en una fila, con los chips más angostos (`data-density="compact"`).
|
|
2295
|
+
* - `panel`: solo el buscador y un botón "Filtros"; filtros y acciones finales se ocultan.
|
|
2296
|
+
*/
|
|
2297
|
+
type ListToolbarMode = 'full' | 'compact' | 'panel';
|
|
2298
|
+
/** Anchos medidos (px): disponible en la barra y requerido por cada densidad. */
|
|
2299
|
+
interface ListToolbarWidths {
|
|
2300
|
+
available: number;
|
|
2301
|
+
full: number;
|
|
2302
|
+
compact: number;
|
|
2303
|
+
}
|
|
2304
|
+
/**
|
|
2305
|
+
* Margen de histéresis (px) para SUBIR de modo. Bajar es inmediato (si no
|
|
2306
|
+
* cabe, no cabe); subir exige este margen extra, así un ancho que oscila
|
|
2307
|
+
* justo en el umbral (scrollbar que aparece y desaparece, un contador que
|
|
2308
|
+
* pasa de 9 a 10) no hace parpadear la barra entre dos modos.
|
|
2309
|
+
*/
|
|
2310
|
+
declare const LIST_TOOLBAR_HYSTERESIS = 24;
|
|
2311
|
+
/**
|
|
2312
|
+
* Decide el modo a partir del modo actual y los anchos medidos. Función pura
|
|
2313
|
+
* para poder probar la histéresis sin layout real.
|
|
2314
|
+
*/
|
|
2315
|
+
declare function resolveListToolbarMode(widths: ListToolbarWidths, current: ListToolbarMode, hysteresis?: number): ListToolbarMode;
|
|
2316
|
+
|
|
2317
|
+
/**
|
|
2318
|
+
* Barra de herramientas de un listado: buscador, filtros y acciones finales
|
|
2319
|
+
* (orden, cambio de vista) en UNA fila, que se adapta al ancho REAL que
|
|
2320
|
+
* tiene disponible — no al del viewport. El mismo listado puede renderizarse
|
|
2321
|
+
* con el menú lateral abierto o cerrado, dentro de un panel o a pantalla
|
|
2322
|
+
* completa, y una `@media` no distingue esos casos; la barra mide su propio
|
|
2323
|
+
* ancho con `ResizeObserver`.
|
|
2324
|
+
*
|
|
2325
|
+
* ## Cuándo usarla y cuándo `kf-filter`
|
|
2326
|
+
* - `kf-list-toolbar`: chips con contador (`kf-filter-chips`) + orden + cambio
|
|
2327
|
+
* de vista + panel de filtros en modo estrecho, fija al hacer scroll y
|
|
2328
|
+
* guiada por el ancho del contenedor.
|
|
2329
|
+
* - `kf-filter`: selects, multi-select y buscador de texto en una fila de
|
|
2330
|
+
* formulario, que se pliega en un `kf-collapsible` a ≤768px de viewport.
|
|
2331
|
+
* Si el listado se filtra con campos, usar `kf-filter`; no se combinan ni
|
|
2332
|
+
* se reimplementan entre sí.
|
|
2333
|
+
*
|
|
2334
|
+
* ## Slots
|
|
2335
|
+
* - `[kf-toolbar-search]`: el buscador (ej. `kf-input icon="search"`). Siempre visible; ocupa el espacio libre.
|
|
2336
|
+
* - `[kf-toolbar-filters]`: filtros rápidos (ej. `kf-filter-chips`).
|
|
2337
|
+
* - `[kf-toolbar-end]`: acciones al final de la fila (ej. `kf-select` de orden, `kf-view-toggle`).
|
|
2338
|
+
*
|
|
2339
|
+
* Cada slot acepta VARIOS elementos con el mismo atributo y los ubica en
|
|
2340
|
+
* fila con `gap`; marcar cada control (no un `<div>` envoltorio sin
|
|
2341
|
+
* `display: flex`, que apilaría sus hijos en bloque).
|
|
2342
|
+
*
|
|
2343
|
+
* La barra ocupa el ancho de su contenedor (`display: block`). Dentro de un
|
|
2344
|
+
* contenedor flex que ajusta su ancho al contenido, darle un ancho
|
|
2345
|
+
* explícito: si el contenedor mide lo que la barra pide, la barra mide lo
|
|
2346
|
+
* que el contenedor le da y el modo nunca puede subir de `panel`.
|
|
2347
|
+
* - default: contenido no visual que debe quedar SIEMPRE presente, como una
|
|
2348
|
+
* región `aria-live` con el conteo de resultados (nunca dentro de un slot
|
|
2349
|
+
* que se oculta).
|
|
2350
|
+
*
|
|
2351
|
+
* ## Modos (`mode`, `modeChange`, atributo `data-mode`)
|
|
2352
|
+
* - `full`: todo cabe en una fila.
|
|
2353
|
+
* - `compact`: cabe en una fila solo con chips más angostos. El host expone
|
|
2354
|
+
* `data-density="compact"` y redefine `--kf-filter-chips-padding-inline`
|
|
2355
|
+
* (12px), que `kf-filter-chips` adopta sin configuración extra.
|
|
2356
|
+
* - `panel`: no cabe. Se ocultan `filters` y `end` y aparece, junto al
|
|
2357
|
+
* buscador, un botón "Filtros" (`filtersLabel`) con un badge de
|
|
2358
|
+
* `activeCount` (filtros/orden distintos del valor por defecto) que emite
|
|
2359
|
+
* `filtersClick` — el consumidor abre su propio panel (típicamente
|
|
2360
|
+
* `kf-drawer role="dialog"` con `kf-option-list`).
|
|
2361
|
+
*
|
|
2362
|
+
* Contrato con el panel de filtros: el consumidor DEBE pasar
|
|
2363
|
+
* `[filtersExpanded]` con el estado de su panel y DEBE cerrarlo al recibir
|
|
2364
|
+
* un `modeChange` distinto de `'panel'`. Al salir de `panel` con el panel
|
|
2365
|
+
* abierto, la barra mueve el foco al primer filtro visible (el botón
|
|
2366
|
+
* "Filtros" ya no existe para recibirlo); si el panel modal siguiera
|
|
2367
|
+
* abierto, ese foco quedaría fuera del diálogo.
|
|
2368
|
+
*
|
|
2369
|
+
* El modo sale de comparar el ancho disponible con el ancho natural de los
|
|
2370
|
+
* slots en cada densidad (más `searchMinWidth` para el buscador), con
|
|
2371
|
+
* histéresis al subir de modo (`LIST_TOOLBAR_HYSTERESIS`) para que no
|
|
2372
|
+
* parpadee en el umbral. Los slots ocultos en modo `panel` se siguen
|
|
2373
|
+
* midiendo (quedan fuera de vista con `visibility: hidden`, sin foco ni
|
|
2374
|
+
* árbol de accesibilidad), así un contador que crece se refleja igual.
|
|
2375
|
+
*
|
|
2376
|
+
* ## Fija (`sticky`)
|
|
2377
|
+
* Con `sticky`, la barra queda pegada arriba al hacer scroll (`stickyTop`
|
|
2378
|
+
* compensa una cabecera fija del shell). Cuando efectivamente queda pegada,
|
|
2379
|
+
* el host recibe la clase `kf-list-toolbar--stuck`: sombra más marcada y
|
|
2380
|
+
* menos alto. "Pegada" = el contenedor con scroll (el ancestro más cercano
|
|
2381
|
+
* con `overflow-y: auto|scroll`, o la ventana) ya se desplazó Y la barra
|
|
2382
|
+
* está en su posición fija. Sin centinela: un centinela por encima de la
|
|
2383
|
+
* barra quedaría recortado cuando la barra es el primer elemento del
|
|
2384
|
+
* contenedor, y la marcaría pegada en reposo. El fondo alrededor de
|
|
2385
|
+
* la barra fija sale de `--kf-list-toolbar-backdrop` (default
|
|
2386
|
+
* `--kf-color-surface`, el fondo habitual del área de contenido).
|
|
2387
|
+
*
|
|
2388
|
+
* Foco tapado (WCAG 2.4.11): una barra fija puede quedar encima del control
|
|
2389
|
+
* que recibe el foco al tabular hacia arriba. El consumidor debe aplicar
|
|
2390
|
+
* `scroll-padding-top` = `stickyTop` + alto de la barra al contenedor que
|
|
2391
|
+
* hace scroll (o a `html` si es la ventana), así el navegador deja ese
|
|
2392
|
+
* margen al llevar un elemento enfocado a la vista. El alto vigente se
|
|
2393
|
+
* publica como señal `height` (px), output `heightChange` y variable CSS
|
|
2394
|
+
* `--kf-list-toolbar-height` en el host (esta última solo la heredan los
|
|
2395
|
+
* descendientes; un ancestro debe usar la señal):
|
|
2396
|
+
*
|
|
2397
|
+
* <main class="content" [style.scroll-padding-top.px]="56 + toolbar.height()">
|
|
2398
|
+
* <kf-list-toolbar #toolbar sticky [stickyTop]="56" ... />
|
|
2399
|
+
* </main>
|
|
2400
|
+
*
|
|
2401
|
+
* <kf-list-toolbar sticky ariaLabel="Filtrar cotizaciones" [activeCount]="activeFilters()"
|
|
2402
|
+
* (filtersClick)="filtersOpen.set(true)" (modeChange)="mode.set($event)">
|
|
2403
|
+
* <span class="sr-only" aria-live="polite">{{ resultsLabel() }}</span>
|
|
2404
|
+
* <kf-input kf-toolbar-search icon="search" ... />
|
|
2405
|
+
* <kf-filter-chips kf-toolbar-filters ... />
|
|
2406
|
+
* <kf-select kf-toolbar-end variant="compact" icon="sort" ariaLabel="Ordenar por" ... />
|
|
2407
|
+
* <kf-view-toggle kf-toolbar-end ... />
|
|
2408
|
+
* </kf-list-toolbar>
|
|
2409
|
+
*/
|
|
2410
|
+
declare class ListToolbar {
|
|
2411
|
+
/** Nombre accesible del landmark de búsqueda (`role="search"`). */
|
|
2412
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
2413
|
+
/** Fija la barra arriba al hacer scroll. */
|
|
2414
|
+
readonly sticky: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2415
|
+
/** Offset superior de la barra fija: número (px) o longitud CSS (ej. `'var(--shell-header-height)'`). */
|
|
2416
|
+
readonly stickyTop: _angular_core.InputSignal<string | number>;
|
|
2417
|
+
/** Ancho mínimo útil del buscador (px) — entra en el cálculo de si todo cabe en una fila. */
|
|
2418
|
+
readonly searchMinWidth: _angular_core.InputSignal<number>;
|
|
2419
|
+
/** Texto del botón del modo `panel`. */
|
|
2420
|
+
readonly filtersLabel: _angular_core.InputSignal<string>;
|
|
2421
|
+
/** Cantidad de filtros/orden distintos del valor por defecto; se muestra como badge en el botón del modo `panel`. */
|
|
2422
|
+
readonly activeCount: _angular_core.InputSignal<number>;
|
|
2423
|
+
/**
|
|
2424
|
+
* `aria-expanded` del botón del modo `panel`: el estado del panel que abre
|
|
2425
|
+
* el consumidor. Además, si es `true` al salir de `panel`, el foco pasa al
|
|
2426
|
+
* primer filtro visible — por eso el consumidor DEBE cerrar su panel en
|
|
2427
|
+
* ese mismo `modeChange` (ver "Contrato con el panel de filtros").
|
|
2428
|
+
*/
|
|
2429
|
+
readonly filtersExpanded: _angular_core.InputSignal<boolean | undefined>;
|
|
2430
|
+
readonly filtersClick: _angular_core.OutputEmitterRef<void>;
|
|
2431
|
+
/**
|
|
2432
|
+
* Nuevo modo. Al recibir un valor distinto de `'panel'`, el consumidor
|
|
2433
|
+
* DEBE cerrar su panel de filtros (ver "Contrato con el panel de filtros").
|
|
2434
|
+
*/
|
|
2435
|
+
readonly modeChange: _angular_core.OutputEmitterRef<ListToolbarMode>;
|
|
2436
|
+
/** Alto del host (px) cada vez que cambia — ver "Foco tapado" en el JSDoc de la clase. */
|
|
2437
|
+
readonly heightChange: _angular_core.OutputEmitterRef<number>;
|
|
2438
|
+
private readonly modeState;
|
|
2439
|
+
/** Modo vigente (también disponible como `data-mode` en el host). */
|
|
2440
|
+
readonly mode: _angular_core.Signal<ListToolbarMode>;
|
|
2441
|
+
private readonly stuckState;
|
|
2442
|
+
/** `true` mientras la barra fija está efectivamente pegada arriba. */
|
|
2443
|
+
readonly stuck: _angular_core.Signal<boolean>;
|
|
2444
|
+
private readonly heightState;
|
|
2445
|
+
/** Alto vigente del host en px (barra + padding de la variante fija). */
|
|
2446
|
+
readonly height: _angular_core.Signal<number>;
|
|
2447
|
+
protected readonly stickyTopCss: _angular_core.Signal<string>;
|
|
2448
|
+
protected readonly filtersAriaLabel: _angular_core.Signal<string | undefined>;
|
|
2449
|
+
private readonly hostRef;
|
|
2450
|
+
private readonly document;
|
|
2451
|
+
private readonly destroyRef;
|
|
2452
|
+
private readonly barRef;
|
|
2453
|
+
private readonly filtersRef;
|
|
2454
|
+
private readonly endRef;
|
|
2455
|
+
private readonly filtersButtonRef;
|
|
2456
|
+
/** A dónde mover el foco tras un cambio de modo que desmonta/oculta el elemento enfocado. */
|
|
2457
|
+
private pendingFocus;
|
|
2458
|
+
/** `requestAnimationFrame` pendiente de `measure()` (coalesce de notificaciones). */
|
|
2459
|
+
private measureFrame;
|
|
2460
|
+
private stuckFrame;
|
|
2461
|
+
private removeScrollListener;
|
|
2462
|
+
constructor();
|
|
2463
|
+
protected onFiltersClick(): void;
|
|
2464
|
+
/**
|
|
2465
|
+
* Mide el ancho disponible y el natural de cada slot en ambas
|
|
2466
|
+
* densidades, y actualiza el modo. La densidad de medición se fuerza con
|
|
2467
|
+
* `data-measure` (que gana sobre `data-density` en el CSS) y se retira en
|
|
2468
|
+
* el mismo frame: el navegador nunca pinta ese estado intermedio.
|
|
2469
|
+
*/
|
|
2470
|
+
private measure;
|
|
2471
|
+
private updateHeight;
|
|
2472
|
+
private applyMode;
|
|
2473
|
+
private slotsContain;
|
|
2474
|
+
private restorePendingFocus;
|
|
2475
|
+
private observeSize;
|
|
2476
|
+
private scheduleMeasure;
|
|
2477
|
+
/** Engancha (o suelta) el cálculo de `stuck` al scroll del contenedor. */
|
|
2478
|
+
private watchScroll;
|
|
2479
|
+
/**
|
|
2480
|
+
* Pegada = el contenedor ya se desplazó Y la barra está en su posición
|
|
2481
|
+
* fija (`top` resuelto, con medio píxel de tolerancia por subpíxeles).
|
|
2482
|
+
* Sin la primera condición, una barra que es el primer elemento del
|
|
2483
|
+
* contenedor se leería pegada en reposo.
|
|
2484
|
+
*/
|
|
2485
|
+
private updateStuck;
|
|
2486
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ListToolbar, never>;
|
|
2487
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ListToolbar, "kf-list-toolbar", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "sticky": { "alias": "sticky"; "required": false; "isSignal": true; }; "stickyTop": { "alias": "stickyTop"; "required": false; "isSignal": true; }; "searchMinWidth": { "alias": "searchMinWidth"; "required": false; "isSignal": true; }; "filtersLabel": { "alias": "filtersLabel"; "required": false; "isSignal": true; }; "activeCount": { "alias": "activeCount"; "required": false; "isSignal": true; }; "filtersExpanded": { "alias": "filtersExpanded"; "required": false; "isSignal": true; }; }, { "filtersClick": "filtersClick"; "modeChange": "modeChange"; "heightChange": "heightChange"; }, never, ["*", "[kf-toolbar-search]", "[kf-toolbar-filters]", "[kf-toolbar-end]"], true, never>;
|
|
2488
|
+
}
|
|
2489
|
+
|
|
1903
2490
|
/**
|
|
1904
2491
|
* Card de estadística/KPI: label, valor grande, ícono opcional en la esquina
|
|
1905
2492
|
* superior derecha, badge de esquina opcional (pegado al valor) y una nota
|
|
@@ -1974,6 +2561,27 @@ declare class MetricCard {
|
|
|
1974
2561
|
*
|
|
1975
2562
|
* <kf-link footer class="kf-modal__footer-start" disabled>Ver documento</kf-link>
|
|
1976
2563
|
* <kf-button footer (click)="open.set(false)">Cerrar</kf-button>
|
|
2564
|
+
*
|
|
2565
|
+
* ## Modal de listado (alto acotado, filtros fijos)
|
|
2566
|
+
* Para un diálogo con mucho contenido (ej. elegir un ítem entre cientos):
|
|
2567
|
+
* - `maxHeight` (ej. `"85vh"`) acota el panel; solo `.kf-modal__body` se
|
|
2568
|
+
* desplaza, el encabezado, la zona `[kf-modal-toolbar]` y el footer
|
|
2569
|
+
* quedan fijos.
|
|
2570
|
+
* - `[kf-modal-toolbar]`: zona FIJA entre el encabezado y el cuerpo, para
|
|
2571
|
+
* buscador y filtros.
|
|
2572
|
+
* - `[kf-modal-meta]`: dato corto junto al título (ej. "12 de 86").
|
|
2573
|
+
* - `fullscreenOnMobile`: hasta 640px de viewport ocupa toda la pantalla
|
|
2574
|
+
* (`100dvh`, sin radio).
|
|
2575
|
+
* - `initialFocus`: selector CSS del elemento que recibe el foco al abrir
|
|
2576
|
+
* (si apunta a un contenedor, se enfoca su primer control). Sin él, el
|
|
2577
|
+
* `<dialog>` nativo decide (`autofocus` o el primer control).
|
|
2578
|
+
*
|
|
2579
|
+
* <kf-modal [(open)]="open" title="Cambiar cotización" width="1040px"
|
|
2580
|
+
* maxHeight="85vh" fullscreenOnMobile initialFocus=".search">
|
|
2581
|
+
* <span kf-modal-meta aria-live="polite">12 de 86</span>
|
|
2582
|
+
* <div kf-modal-toolbar><kf-input class="search" … /></div>
|
|
2583
|
+
* <ul>…</ul>
|
|
2584
|
+
* </kf-modal>
|
|
1977
2585
|
*/
|
|
1978
2586
|
declare class Modal {
|
|
1979
2587
|
readonly title: _angular_core.InputSignal<string>;
|
|
@@ -1986,11 +2594,26 @@ declare class Modal {
|
|
|
1986
2594
|
* más, ej. `width="720px"` — sigue topeado por `100vw` en pantallas
|
|
1987
2595
|
* angostas, mismo `min()` de siempre. */
|
|
1988
2596
|
readonly width: _angular_core.InputSignal<string | null>;
|
|
2597
|
+
/** Alto máximo del panel (ej. `"85vh"`); con valor, solo el cuerpo se
|
|
2598
|
+
* desplaza. Sin valor (default) el panel crece con su contenido. */
|
|
2599
|
+
readonly maxHeight: _angular_core.InputSignal<string | null>;
|
|
2600
|
+
/** Hasta 640px de viewport, ocupa toda la pantalla (100dvh, sin radio). */
|
|
2601
|
+
readonly fullscreenOnMobile: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2602
|
+
/** Selector CSS (dentro del panel) del elemento a enfocar al abrir. */
|
|
2603
|
+
readonly initialFocus: _angular_core.InputSignal<string | null>;
|
|
1989
2604
|
protected readonly titleId: string;
|
|
1990
2605
|
private readonly dialog;
|
|
2606
|
+
private readonly panel;
|
|
1991
2607
|
private readonly document;
|
|
1992
2608
|
private readonly overlayContainer;
|
|
1993
2609
|
constructor();
|
|
2610
|
+
/**
|
|
2611
|
+
* Enfoca `initialFocus` DESPUÉS de `showModal()` (que ya movió el foco al
|
|
2612
|
+
* primer control): un elemento dentro de un `<dialog>` cerrado no se puede
|
|
2613
|
+
* enfocar. Si el selector apunta a un host (ej. `kf-input`), se enfoca su
|
|
2614
|
+
* primer control interno.
|
|
2615
|
+
*/
|
|
2616
|
+
private focusInitial;
|
|
1994
2617
|
/** `Escape` dispara `cancel`; cancelarlo lo deja abierto. */
|
|
1995
2618
|
protected onCancel(event: Event): void;
|
|
1996
2619
|
/**
|
|
@@ -2004,7 +2627,7 @@ declare class Modal {
|
|
|
2004
2627
|
*/
|
|
2005
2628
|
protected onHostClick(event: MouseEvent): void;
|
|
2006
2629
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Modal, never>;
|
|
2007
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Modal, "kf-modal", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*", "[footer]"], true, never>;
|
|
2630
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Modal, "kf-modal", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "fullscreenOnMobile": { "alias": "fullscreenOnMobile"; "required": false; "isSignal": true; }; "initialFocus": { "alias": "initialFocus"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[kf-modal-meta]", "[kf-modal-toolbar]", "*", "[footer]"], true, never>;
|
|
2008
2631
|
}
|
|
2009
2632
|
|
|
2010
2633
|
/** Color de la franja izquierda y del fondo. */
|
|
@@ -2026,6 +2649,84 @@ declare class NoteBlock {
|
|
|
2026
2649
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NoteBlock, "kf-note-block", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "signature": { "alias": "signature"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
2027
2650
|
}
|
|
2028
2651
|
|
|
2652
|
+
/** Opción de `kf-option-list`. `count` se muestra alineado a la derecha. */
|
|
2653
|
+
interface OptionListOption {
|
|
2654
|
+
value: string;
|
|
2655
|
+
label: string;
|
|
2656
|
+
count?: number;
|
|
2657
|
+
}
|
|
2658
|
+
/**
|
|
2659
|
+
* Lista vertical de opciones de UNA sola selección para paneles (ej. las
|
|
2660
|
+
* secciones "Estado", "Ordenar por" y "Vista" de un panel de filtros): una
|
|
2661
|
+
* fila de al menos 44px por opción, contador opcional a la derecha y la
|
|
2662
|
+
* opción elegida resaltada con `--kf-color-primary-soft`.
|
|
2663
|
+
*
|
|
2664
|
+
* Es la contraparte en panel de `kf-filter-chips`: misma función (filtrar u
|
|
2665
|
+
* ordenar lo que se muestra) cuando no hay ancho para una fila de chips. No
|
|
2666
|
+
* es `kf-selectable-card-group`: aquel responde una pregunta de un flujo
|
|
2667
|
+
* ("¿con qué método pagas?") con affordance de radio y cards grandes; esta
|
|
2668
|
+
* lista ajusta una vista, con filas densas y contador.
|
|
2669
|
+
*
|
|
2670
|
+
* Semántica: `role="radiogroup"` + `role="radio"` con `aria-checked`, no
|
|
2671
|
+
* botones con `aria-pressed`. Las opciones son mutuamente excluyentes (eso
|
|
2672
|
+
* es un radio; `aria-pressed` describe toggles independientes), el lector
|
|
2673
|
+
* de pantalla anuncia la posición ("2 de 4") y cada grupo es UNA sola
|
|
2674
|
+
* parada de Tab: un panel con tres secciones se recorre con 3 Tabs en vez
|
|
2675
|
+
* de uno por opción. Dentro del grupo, flechas arriba/abajo y Home/End
|
|
2676
|
+
* mueven el foco y seleccionan (`handleArrowKeyNavigation`, mismo helper que
|
|
2677
|
+
* `kf-tabs`/`kf-selectable-card-group`).
|
|
2678
|
+
*
|
|
2679
|
+
* La opción elegida lleva además un check (no solo color), para que el
|
|
2680
|
+
* estado no dependa de distinguir el tinte `primary-soft` (WCAG 1.4.1).
|
|
2681
|
+
*
|
|
2682
|
+
* El `@for` hace `track` por índice: cuando el padre re-renderiza (ej. los
|
|
2683
|
+
* contadores cambian al elegir), los botones existentes se reutilizan y el
|
|
2684
|
+
* foco no se pierde. Por índice y no por `value` para no fallar (NG0955)
|
|
2685
|
+
* si dos opciones repiten `value`; aun así los values deben ser únicos:
|
|
2686
|
+
* con repetidos, ambas filas se marcan elegidas.
|
|
2687
|
+
*
|
|
2688
|
+
* `label` dibuja el título de la sección (chico, en mayúsculas) y nombra el
|
|
2689
|
+
* grupo vía `aria-labelledby`; sin título visible, pasar `ariaLabel`.
|
|
2690
|
+
*
|
|
2691
|
+
* <kf-option-list label="Estado"
|
|
2692
|
+
* [options]="[{ value: '', label: 'Todas', count: 12 },
|
|
2693
|
+
* { value: 'pending', label: 'Pendientes', count: 3 }]"
|
|
2694
|
+
* [value]="status()"
|
|
2695
|
+
* (valueChange)="status.set($event)" />
|
|
2696
|
+
*/
|
|
2697
|
+
declare class OptionList {
|
|
2698
|
+
readonly options: _angular_core.InputSignal<(string | OptionListOption)[]>;
|
|
2699
|
+
readonly value: _angular_core.InputSignal<string>;
|
|
2700
|
+
/** Título visible de la sección; nombra el grupo. */
|
|
2701
|
+
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
2702
|
+
/** Nombre accesible del grupo cuando no hay `label` visible. */
|
|
2703
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
2704
|
+
readonly valueChange: _angular_core.OutputEmitterRef<string>;
|
|
2705
|
+
private readonly instanceId;
|
|
2706
|
+
protected readonly labelId: string;
|
|
2707
|
+
/**
|
|
2708
|
+
* Prefijo de id de cada opción — único por instancia (dos listas con los
|
|
2709
|
+
* mismos values no colisionan). El id termina en el ÍNDICE, no en el
|
|
2710
|
+
* value: un value con espacios u otros caracteres daría un id inválido.
|
|
2711
|
+
*/
|
|
2712
|
+
protected readonly optionIdPrefix: string;
|
|
2713
|
+
readonly normalizedOptions: _angular_core.Signal<OptionListOption[]>;
|
|
2714
|
+
/**
|
|
2715
|
+
* Opción que recibe `tabindex="0"`: la seleccionada o, si ninguna lo
|
|
2716
|
+
* está, la primera — el grupo siempre debe ser alcanzable con Tab.
|
|
2717
|
+
*/
|
|
2718
|
+
protected readonly tabStopValue: _angular_core.Signal<string>;
|
|
2719
|
+
select(value: string): void;
|
|
2720
|
+
/**
|
|
2721
|
+
* `handleArrowKeyNavigation` ubica el botón destino por `idPrefix + value`;
|
|
2722
|
+
* como los ids usan el índice, se le pasa la lista con el índice como
|
|
2723
|
+
* value y se traduce de vuelta al value real al seleccionar.
|
|
2724
|
+
*/
|
|
2725
|
+
protected onKeydown(event: KeyboardEvent, index: number): void;
|
|
2726
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OptionList, never>;
|
|
2727
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OptionList, "kf-option-list", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2029
2730
|
type TextAs = 'h1' | 'h2' | 'h3' | 'p' | 'span';
|
|
2030
2731
|
type TextVariant = 'title-xxl' | 'title-xl' | 'title-lg' | 'title-md' | 'title-sm' | 'body' | 'body-muted' | 'caption' | 'overline' | 'overline-strong';
|
|
2031
2732
|
type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';
|
|
@@ -2628,10 +3329,20 @@ declare class Segmented {
|
|
|
2628
3329
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Segmented, "kf-segmented", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
2629
3330
|
}
|
|
2630
3331
|
|
|
2631
|
-
/**
|
|
3332
|
+
/**
|
|
3333
|
+
* Opción en forma de objeto. `tag` se muestra como `kf-badge` a la derecha
|
|
3334
|
+
* del label (en el panel y en el trigger) y `detail` como línea secundaria
|
|
3335
|
+
* atenuada debajo, solo en el panel. Ambos entran en la búsqueda.
|
|
3336
|
+
* `shortLabel` reemplaza al label SOLO en el trigger (ej. panel "Más
|
|
3337
|
+
* recientes primero", trigger "Más recientes") — para triggers compactos
|
|
3338
|
+
* donde el label completo se truncaría.
|
|
3339
|
+
*/
|
|
2632
3340
|
interface SelectOption {
|
|
2633
3341
|
value: string;
|
|
2634
3342
|
label: string;
|
|
3343
|
+
tag?: string;
|
|
3344
|
+
detail?: string;
|
|
3345
|
+
shortLabel?: string;
|
|
2635
3346
|
}
|
|
2636
3347
|
/**
|
|
2637
3348
|
* Dropdown de selección simple con panel propio — NUNCA usa el `<select>`
|
|
@@ -2644,6 +3355,7 @@ interface SelectOption {
|
|
|
2644
3355
|
*
|
|
2645
3356
|
* <kf-select label="Sede" [options]="['Lima', 'Arequipa', 'Trujillo']" placeholder="Selecciona…" />
|
|
2646
3357
|
* <kf-select [options]="[{ value: 'pe', label: 'Perú' }]" (valueChange)="onCountry($event)" />
|
|
3358
|
+
* <kf-select [options]="[{ value: '1002099', label: 'BBVA', tag: 'Empresa', detail: 'RUC 20100130204' }]" />
|
|
2647
3359
|
*
|
|
2648
3360
|
* `variant="compact"` cambia el ancho de `240px` fijo a intrínseco con un
|
|
2649
3361
|
* techo de `160px` (se ajusta al contenido de la opción seleccionada hasta
|
|
@@ -2660,10 +3372,29 @@ interface SelectOption {
|
|
|
2660
3372
|
* layouts flex/grid donde el ancho fijo de `md` no encaja.
|
|
2661
3373
|
*
|
|
2662
3374
|
* <kf-select width="full" [options]="branches" [value]="branch()" (valueChange)="..." />
|
|
3375
|
+
*
|
|
3376
|
+
* Control de orden de una barra de herramientas (ícono + valor + caret, sin
|
|
3377
|
+
* label visible): `icon` agrega un glifo `sm` a la izquierda del valor,
|
|
3378
|
+
* `ariaLabel` da el nombre accesible (el trigger se anuncia como
|
|
3379
|
+
* `"<ariaLabel>: <valor actual>"`), `panelTitle` agrega un título chico en
|
|
3380
|
+
* mayúsculas dentro del panel (decorativo, `aria-hidden`) y
|
|
3381
|
+
* `panelWidth="content"` deja que el panel crezca hasta el ancho de sus
|
|
3382
|
+
* opciones en vez de truncarlas al ancho del trigger compacto.
|
|
3383
|
+
*
|
|
3384
|
+
* <kf-select variant="compact" icon="sort" ariaLabel="Ordenar por"
|
|
3385
|
+
* panelTitle="Ordenar por" panelWidth="content"
|
|
3386
|
+
* [options]="sortOptions" [value]="sort()" (valueChange)="sort.set($event)" />
|
|
3387
|
+
*
|
|
3388
|
+
* Teclado (patrón listbox de WAI-ARIA): ArrowDown/ArrowUp sobre el trigger
|
|
3389
|
+
* cerrado lo abren; al abrir, el foco pasa a la opción seleccionada (o al
|
|
3390
|
+
* buscador, si está visible). En el panel, flechas y Home/End mueven el
|
|
3391
|
+
* foco, Enter/Espacio eligen, Escape cierra y devuelve el foco al trigger,
|
|
3392
|
+
* y Tab cierra el panel y continúa la tabulación desde el trigger. Las
|
|
3393
|
+
* opciones nunca son paradas de Tab (`tabindex="-1"`).
|
|
2663
3394
|
*/
|
|
2664
3395
|
declare class Select {
|
|
2665
3396
|
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
2666
|
-
readonly options: _angular_core.InputSignal<string
|
|
3397
|
+
readonly options: _angular_core.InputSignal<readonly (string | SelectOption)[]>;
|
|
2667
3398
|
readonly value: _angular_core.InputSignal<string | undefined>;
|
|
2668
3399
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
2669
3400
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
@@ -2671,7 +3402,7 @@ declare class Select {
|
|
|
2671
3402
|
readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2672
3403
|
/** Mensaje de error con `role="alert"`, debajo del trigger. */
|
|
2673
3404
|
readonly errorMessage: _angular_core.InputSignal<string | undefined>;
|
|
2674
|
-
readonly variant: _angular_core.InputSignal<"
|
|
3405
|
+
readonly variant: _angular_core.InputSignal<"compact" | "field">;
|
|
2675
3406
|
/**
|
|
2676
3407
|
* Ancho del control. 'md' (240px) es el default histórico y preserva el
|
|
2677
3408
|
* comportamiento actual sin cambios para consumidores existentes.
|
|
@@ -2687,6 +3418,26 @@ declare class Select {
|
|
|
2687
3418
|
*/
|
|
2688
3419
|
readonly searchable: _angular_core.InputSignal<boolean | undefined>;
|
|
2689
3420
|
readonly searchThreshold: _angular_core.InputSignal<number>;
|
|
3421
|
+
/**
|
|
3422
|
+
* Nombre accesible del control cuando no hay `label` visible (ej. "Ordenar
|
|
3423
|
+
* por"). El trigger se anuncia como `"<ariaLabel>: <valor visible>"` (el
|
|
3424
|
+
* mismo texto que muestra el trigger, `shortLabel` si la opción lo trae),
|
|
3425
|
+
* así el nombre contiene el texto visible (WCAG 2.5.3) y además dice qué se
|
|
3426
|
+
* está eligiendo. Ignorado si hay `label`: un `aria-label` pisaría al
|
|
3427
|
+
* `<label for>` visible.
|
|
3428
|
+
*/
|
|
3429
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
3430
|
+
/** Ícono `sm` a la izquierda del valor en el trigger (ej. `'sort'`). */
|
|
3431
|
+
readonly icon: _angular_core.InputSignal<IconName | undefined>;
|
|
3432
|
+
/** Título chico en mayúsculas dentro del panel, sobre las opciones. Decorativo (`aria-hidden`): el nombre del listbox ya lo da `ariaLabel`/`label`. */
|
|
3433
|
+
readonly panelTitle: _angular_core.InputSignal<string | undefined>;
|
|
3434
|
+
/**
|
|
3435
|
+
* `'trigger'` (default): el panel mide lo mismo que el trigger.
|
|
3436
|
+
* `'content'`: el trigger es el ancho mínimo y el panel crece hasta el
|
|
3437
|
+
* ancho de la opción más larga — para triggers compactos cuyas opciones
|
|
3438
|
+
* son más largas que el valor resumido.
|
|
3439
|
+
*/
|
|
3440
|
+
readonly panelWidth: _angular_core.InputSignal<"content" | "trigger">;
|
|
2690
3441
|
readonly valueChange: _angular_core.OutputEmitterRef<string>;
|
|
2691
3442
|
private readonly instanceId;
|
|
2692
3443
|
readonly triggerId: string;
|
|
@@ -2695,15 +3446,25 @@ declare class Select {
|
|
|
2695
3446
|
readonly isOpen: _angular_core.WritableSignal<boolean>;
|
|
2696
3447
|
readonly searchQuery: _angular_core.WritableSignal<string>;
|
|
2697
3448
|
readonly activeIndex: _angular_core.WritableSignal<number>;
|
|
2698
|
-
/** Resolves
|
|
3449
|
+
/** Resolves `string | SelectOption` entries into a single shape for the template. */
|
|
2699
3450
|
readonly normalizedOptions: _angular_core.Signal<SelectOption[]>;
|
|
2700
3451
|
readonly selectedOption: _angular_core.Signal<SelectOption | undefined>;
|
|
3452
|
+
/** Texto que muestra el trigger: `shortLabel` o `label` de la opción elegida, o el placeholder. */
|
|
3453
|
+
readonly triggerText: _angular_core.Signal<string>;
|
|
3454
|
+
/**
|
|
3455
|
+
* `aria-label` del trigger: solo con `ariaLabel` y SIN `label` visible. Un
|
|
3456
|
+
* `aria-label` tiene prioridad sobre el `<label for>` en el cálculo del
|
|
3457
|
+
* nombre accesible, así que con label visible no se emite.
|
|
3458
|
+
*/
|
|
3459
|
+
readonly triggerAriaLabel: _angular_core.Signal<string | null>;
|
|
2701
3460
|
readonly showSearch: _angular_core.Signal<boolean>;
|
|
2702
3461
|
/** Opciones visibles tras aplicar el filtro de búsqueda (case/acento-insensitive). */
|
|
2703
3462
|
readonly filteredOptions: _angular_core.Signal<SelectOption[]>;
|
|
2704
3463
|
private readonly triggerRef;
|
|
2705
3464
|
private readonly panelTemplate;
|
|
2706
3465
|
private readonly searchInputRef;
|
|
3466
|
+
private readonly panelRef;
|
|
3467
|
+
private readonly document;
|
|
2707
3468
|
private readonly overlay;
|
|
2708
3469
|
constructor();
|
|
2709
3470
|
/**
|
|
@@ -2714,6 +3475,40 @@ declare class Select {
|
|
|
2714
3475
|
*/
|
|
2715
3476
|
onDocumentEscape(): void;
|
|
2716
3477
|
toggle(): void;
|
|
3478
|
+
/** Abre el panel con la opción seleccionada como activa (o la primera). */
|
|
3479
|
+
open(): void;
|
|
3480
|
+
/**
|
|
3481
|
+
* Cierra el panel. `restoreFocus` (default: solo si el foco está dentro
|
|
3482
|
+
* del panel) devuelve el foco al trigger ANTES de desmontar el panel —
|
|
3483
|
+
* si no, el elemento enfocado desaparece y el foco cae al `<body>`. Un
|
|
3484
|
+
* click afuera no lo restaura: el foco ya se fue a donde se hizo click.
|
|
3485
|
+
*/
|
|
3486
|
+
close(restoreFocus?: boolean): void;
|
|
3487
|
+
/** ArrowDown/ArrowUp con el panel cerrado lo abren (patrón listbox). */
|
|
3488
|
+
onTriggerKeydown(event: KeyboardEvent): void;
|
|
3489
|
+
/**
|
|
3490
|
+
* Teclado con el foco en una opción del panel. Las flechas parten SIEMPRE
|
|
3491
|
+
* de la opción que recibió el evento (`index`), no de `activeIndex`: el
|
|
3492
|
+
* `mouseenter` mueve `activeIndex` sin mover el foco, y sin esto, con el
|
|
3493
|
+
* foco en la opción 1 y el mouse sobre la 4, ArrowDown saltaría a la 5.
|
|
3494
|
+
*/
|
|
3495
|
+
onOptionKeydown(event: KeyboardEvent, option: SelectOption, index: number): void;
|
|
3496
|
+
/** Teclas de salida del buscador: Escape y Tab, igual que desde una opción. */
|
|
3497
|
+
onSearchKeydown(event: KeyboardEvent): void;
|
|
3498
|
+
/**
|
|
3499
|
+
* Escape cierra y devuelve el foco al trigger; `preventDefault` le avisa a
|
|
3500
|
+
* un contenedor que también escucha Escape (ej. `kf-drawer`) que la tecla
|
|
3501
|
+
* ya se consumió. Tab cierra y mueve el foco al trigger SIN
|
|
3502
|
+
* `preventDefault`: la tabulación nativa continúa desde el trigger, así
|
|
3503
|
+
* Tab/Shift+Tab salen del panel hacia el control siguiente/anterior.
|
|
3504
|
+
*/
|
|
3505
|
+
private handleExitKeys;
|
|
3506
|
+
private focusOption;
|
|
3507
|
+
private isFocusInPanel;
|
|
3508
|
+
/** Id de cada opción, para `aria-activedescendant` del buscador. */
|
|
3509
|
+
optionId(index: number): string;
|
|
3510
|
+
/** Nombre accesible explícito solo para opciones con `tag`/`detail`, para separar las partes al leerlas. */
|
|
3511
|
+
optionAriaLabel(option: SelectOption): string | null;
|
|
2717
3512
|
select(option: SelectOption): void;
|
|
2718
3513
|
onSearchInput(event: Event): void;
|
|
2719
3514
|
/**
|
|
@@ -2723,9 +3518,16 @@ declare class Select {
|
|
|
2723
3518
|
* cuando se combina con un buscador que puede reducir la lista a 1 opción.
|
|
2724
3519
|
*/
|
|
2725
3520
|
moveActive(delta: number): void;
|
|
3521
|
+
/**
|
|
3522
|
+
* Con el foco en el buscador, la opción activa se marca con
|
|
3523
|
+
* `aria-activedescendant` pero no recibe foco, así que el navegador no la
|
|
3524
|
+
* desplaza a la vista: se hace a mano. (`scrollIntoView` puede no existir
|
|
3525
|
+
* en entornos sin layout.)
|
|
3526
|
+
*/
|
|
3527
|
+
private scrollActiveIntoView;
|
|
2726
3528
|
selectActive(): void;
|
|
2727
3529
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Select, never>;
|
|
2728
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Select, "kf-select", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchThreshold": { "alias": "searchThreshold"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
3530
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Select, "kf-select", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchThreshold": { "alias": "searchThreshold"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "panelTitle": { "alias": "panelTitle"; "required": false; "isSignal": true; }; "panelWidth": { "alias": "panelWidth"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
2729
3531
|
}
|
|
2730
3532
|
|
|
2731
3533
|
interface SelectableCardOption {
|
|
@@ -2999,7 +3801,7 @@ declare class StatTile {
|
|
|
2999
3801
|
* <kf-status-pill tone="error" dot>Fuera de servicio</kf-status-pill>
|
|
3000
3802
|
*/
|
|
3001
3803
|
declare class StatusPill {
|
|
3002
|
-
readonly tone: _angular_core.InputSignal<"
|
|
3804
|
+
readonly tone: _angular_core.InputSignal<"error" | "ok" | "warn" | "blue">;
|
|
3003
3805
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3004
3806
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatusPill, never>;
|
|
3005
3807
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<StatusPill, "kf-status-pill", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
@@ -3443,17 +4245,31 @@ type ViewToggleOption = 'table' | 'cards';
|
|
|
3443
4245
|
* navegación con flechas izquierda/derecha, igual que un <input type="radio">
|
|
3444
4246
|
* nativo agrupado.
|
|
3445
4247
|
*
|
|
4248
|
+
* Con `iconOnly` cada opción muestra solo su ícono (`list` / `grid`); el
|
|
4249
|
+
* nombre accesible y el tooltip salen de `tableLabel` / `cardsLabel`. El
|
|
4250
|
+
* objetivo táctil mide 32px en escritorio y 44px en pantallas táctiles o de
|
|
4251
|
+
* hasta 640px.
|
|
4252
|
+
*
|
|
3446
4253
|
* <kf-view-toggle [view]="view" (viewChange)="view = $event" />
|
|
4254
|
+
* <kf-view-toggle iconOnly [view]="view" (viewChange)="view = $event" />
|
|
3447
4255
|
*/
|
|
3448
4256
|
declare class ViewToggle {
|
|
3449
4257
|
readonly view: _angular_core.InputSignal<ViewToggleOption>;
|
|
4258
|
+
/** Solo íconos (el rótulo queda como nombre accesible y `title`). */
|
|
4259
|
+
readonly iconOnly: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
4260
|
+
/** Rótulo de la opción de tabla. */
|
|
4261
|
+
readonly tableLabel: _angular_core.InputSignal<string>;
|
|
4262
|
+
/** Rótulo de la opción de tarjetas. */
|
|
4263
|
+
readonly cardsLabel: _angular_core.InputSignal<string>;
|
|
4264
|
+
/** Nombre accesible del grupo. */
|
|
4265
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
3450
4266
|
readonly viewChange: _angular_core.OutputEmitterRef<ViewToggleOption>;
|
|
3451
4267
|
select(next: ViewToggleOption): void;
|
|
3452
4268
|
/** Navegación estándar de ARIA radiogroup: flechas mueven foco y seleccionan. */
|
|
3453
4269
|
onKeydown(event: KeyboardEvent): void;
|
|
3454
4270
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ViewToggle, never>;
|
|
3455
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ViewToggle, "kf-view-toggle", never, { "view": { "alias": "view"; "required": true; "isSignal": true; }; }, { "viewChange": "viewChange"; }, never, never, true, never>;
|
|
4271
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ViewToggle, "kf-view-toggle", never, { "view": { "alias": "view"; "required": true; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; "tableLabel": { "alias": "tableLabel"; "required": false; "isSignal": true; }; "cardsLabel": { "alias": "cardsLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "viewChange": "viewChange"; }, never, never, true, never>;
|
|
3456
4272
|
}
|
|
3457
4273
|
|
|
3458
|
-
export { ActionTile, AdminBadge, Alert, AlertRow, Avatar, Badge, Breadcrumb, BucketProgress, Button, Calendar, Card, Carousel, CarouselSlide, Checkbox, Chip, Collapsible, ContactPopover, ContentSlot, ContentState, ContentViewer, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, Divider, DocumentRow, Drawer, Dropdown, DropdownItem, DropdownPanel, EmptyState, EventTimeline, FeatureCard, Field, FieldLabel, Filter, FilterChips, FolderTabs, FolderTabsPanel, Footer, FormatInputDirective, Icon, Input, JourneyStepper, Link, MetricCard, Modal, MultiSelect, NoteBlock, PageHeader, Pagination, Panel, PortalHeader, Progress, PulseDot, RowActions, SectionHeader, SectionNav, SectionNavItem, SectionNavSubsection, Segmented, Select, SelectableCardGroup, SidebarShell, Skeleton, Spinner, StatCard, StatTile, StatusPill, Tabs, Text, Textarea, TileGrid, TimeSlotPicker, ToastHost, ToastService, TooltipDirective, ViewToggle, dataTableViewSignal };
|
|
3459
|
-
export type { AlertRowTone, AlertTone, BreadcrumbItem, BucketProgressItem, CalendarDay, ContentStateKind, ContentStateLoad, ContentViewerType, DataTableCardRole, DataTableColumn, DataTableDensity, DataTableSort, DataTableView, DividerOrientation, DocumentRowTone, DrawerSide, DropdownItemTone, DropdownPanelVariant, EventTimelineItem, EventTimelineTone, FilterFieldChange, FilterFieldConfig, FilterFieldType, FilterValue, FolderTabOption, FooterLink, IconName, IconRotation, IconSize, JourneyStep, JourneyStepStatus, JourneyStepperColorScheme, JourneyStepperSurface, LinkVariant, MultiSelectOption, NoteBlockTone, PageHeaderTitleSize, PaginationItem, PortalHeaderAdminAction, PortalHeaderNavItem, ProgressTone, RowAction, RowActionKind, RowActionsMode, SectionNavSubsectionData, SegmentedOption, SelectableCardOption, SidebarNavItemData, SkeletonVariant, SpinnerSize, StatCardTone, StatTileTone, StatTileVariant, TabOption, TextAs, TextTone, TextVariant, TimeSlot, ToastAction, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, TooltipPosition, ViewToggleOption };
|
|
4274
|
+
export { ActionTile, AdminBadge, Alert, AlertRow, Avatar, Badge, Breadcrumb, BucketProgress, Button, Calendar, Card, Carousel, CarouselSlide, Checkbox, Chip, Collapsible, ContactPopover, ContentSlot, ContentState, ContentViewer, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, Divider, DocumentRow, Drawer, Dropdown, DropdownItem, DropdownPanel, EmptyState, EventTimeline, FeatureCard, Field, FieldLabel, Filter, FilterChips, FolderTabs, FolderTabsPanel, Footer, FormatInputDirective, Icon, Input, JourneyStepper, LIST_TOOLBAR_HYSTERESIS, Link, ListToolbar, MetricCard, Modal, MultiSelect, NoteBlock, OptionList, PageHeader, Pagination, Panel, PortalHeader, Progress, PulseDot, RowActions, SectionHeader, SectionNav, SectionNavItem, SectionNavSubsection, Segmented, Select, SelectableCardGroup, SidebarShell, Skeleton, Spinner, StatCard, StatTile, StatusPill, Tabs, Text, Textarea, TileGrid, TimeSlotPicker, ToastHost, ToastService, TooltipDirective, ViewToggle, dataTableViewSignal, resolveListToolbarMode };
|
|
4275
|
+
export type { AlertRowTone, AlertTone, BreadcrumbItem, BucketProgressItem, CalendarDay, ContentStateKind, ContentStateLoad, ContentViewerType, DataTableCardRole, DataTableColumn, DataTableDensity, DataTableSort, DataTableView, DividerOrientation, DocumentRowTone, DrawerRole, DrawerSide, DropdownItemTone, DropdownPanelVariant, EmptyStateTone, EventTimelineItem, EventTimelineTone, FilterChipOption, FilterFieldChange, FilterFieldConfig, FilterFieldType, FilterValue, FolderTabOption, FooterLink, IconName, IconRotation, IconSize, JourneyStep, JourneyStepStatus, JourneyStepperColorScheme, JourneyStepperSurface, LinkVariant, ListToolbarMode, MultiSelectOption, NoteBlockTone, OptionListOption, PageHeaderTitleSize, PaginationItem, PortalHeaderAdminAction, PortalHeaderNavItem, ProgressTone, RowAction, RowActionKind, RowActionsMode, SectionNavSubsectionData, SegmentedOption, SelectOption, SelectableCardOption, SidebarNavItemData, SkeletonVariant, SpinnerSize, StatCardTone, StatTileTone, StatTileVariant, TabOption, TextAs, TextTone, TextVariant, TimeSlot, ToastAction, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, TooltipPosition, ViewToggleOption };
|