@kaufmann-lab/ui 0.1.8 → 0.1.11
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.mjs +2007 -415
- package/fesm2022/kaufmann-lab-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/src/tokens/base.css +22 -0
- package/types/kaufmann-lab-ui.d.ts +697 -131
|
@@ -14,11 +14,11 @@ import { ControlValueAccessor } from '@angular/forms';
|
|
|
14
14
|
* reciba un `IconName` (`Button`, `MetricCard`, etc.) — no debería requerir
|
|
15
15
|
* importar el componente `Icon` completo solo para tipar una prop.
|
|
16
16
|
*/
|
|
17
|
-
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' | 'download' | 'edit' | 'external-link' | 'eye' | 'eye-off' | 'file' | 'filter' | 'gauge' | 'gift' | 'grid' | 'history' | 'inbox' | 'layers' | 'list' | 'map' | 'map-pin' | 'menu' | 'mic' | 'mic-off' | 'more-vertical' | 'pause' | 'phone' | 'play' | 'plus' | 'search' | 'settings' | 'shield-check' | 'sort' | 'star' | 'ticket' | 'tool' | 'trash' | 'truck' | 'upload-cloud' | 'user' | 'user-search' | 'video' | 'x';
|
|
17
|
+
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' | 'download' | 'edit' | 'external-link' | 'eye' | 'eye-off' | 'file' | 'filter' | 'gauge' | 'gift' | 'grid' | 'history' | 'home' | 'inbox' | 'layers' | 'list' | 'log-out' | 'map' | 'map-pin' | 'menu' | 'mic' | 'mic-off' | 'more-vertical' | 'pause' | 'phone' | 'play' | 'plus' | 'search' | 'settings' | 'shield-check' | 'sort' | 'star' | 'ticket' | 'tool' | 'trash' | 'truck' | 'upload-cloud' | 'user' | 'user-search' | 'video' | 'x';
|
|
18
18
|
|
|
19
19
|
type IconSize = 'sm' | 'md' | 'lg';
|
|
20
20
|
/**
|
|
21
|
-
* Ícono de trazo del design system —
|
|
21
|
+
* Ícono de trazo del design system — 61 glyphs (59 de la página 5 + `eye-off` y `log-out`), grilla 24×24,
|
|
22
22
|
* grosor de trazo 1.9px. Referencia un sprite SVG embebido (ver
|
|
23
23
|
* `icon-sprite.ts`) vía `<use>`, así que no hay peso de red adicional por
|
|
24
24
|
* cada instancia: el sprite se inyecta al DOM una única vez, la primera
|
|
@@ -157,6 +157,71 @@ declare class Alert {
|
|
|
157
157
|
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>;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Layout a pantalla completa para cualquier pantalla de autenticación
|
|
162
|
+
* (login, recuperar contraseña, confirmación de envío) — split marca a la
|
|
163
|
+
* izquierda / contenido libre a la derecha en desktop, formulario a
|
|
164
|
+
* pantalla completa en mobile (el panel de marca completo se oculta, no se
|
|
165
|
+
* apila arriba: en una pantalla angosta el usuario vino a loguearse, no a
|
|
166
|
+
* leer la tagline). Un logo compacto (o wordmark de respaldo) sí se
|
|
167
|
+
* mantiene visible arriba del formulario en mobile — el usuario nunca
|
|
168
|
+
* pierde de vista qué portal está usando, mismo criterio que ya sigue el
|
|
169
|
+
* resto del ecosistema (ver la topbar mobile de `css/otd.css`, que muestra
|
|
170
|
+
* el logo aunque el sidebar completo se oculte).
|
|
171
|
+
*
|
|
172
|
+
* Este componente resuelve el "cascarón" — nunca el formulario en sí. Cada
|
|
173
|
+
* portal arma su propio `<form>` con los componentes de la librería
|
|
174
|
+
* (`kf-input`, `kf-checkbox`, `kf-button`, `kf-alert`) y lo proyecta en el
|
|
175
|
+
* slot por defecto. Es la misma separación de responsabilidad que ya usa
|
|
176
|
+
* `kf-card`: un componente da la estructura visual, el consumidor decide
|
|
177
|
+
* qué va adentro.
|
|
178
|
+
*
|
|
179
|
+
* Antes de este componente, cada portal (LATAM primero, ahora OTD) hubiera
|
|
180
|
+
* tenido que reimplementar este mismo split desde cero — la librería
|
|
181
|
+
* había pospuesto esta abstracción a propósito hasta tener un segundo
|
|
182
|
+
* consumidor real que confirmara qué parte es realmente compartida (el
|
|
183
|
+
* cascarón) y qué parte es de cada portal (el formulario). OTD es ese
|
|
184
|
+
* segundo consumidor.
|
|
185
|
+
*
|
|
186
|
+
* Ningún input tiene valor por defecto propio de ningún portal — `brand`
|
|
187
|
+
* es obligatorio (`input.required`) y el resto de props de marca son
|
|
188
|
+
* opcionales sin fallback hardcodeado, precisamente para que cada
|
|
189
|
+
* consumidor (LATAM, OTD, Star, o el ERP de Asistencia en Ruta con sus
|
|
190
|
+
* propios temas) traiga su propio logo/tagline sin que la librería asuma
|
|
191
|
+
* cuál.
|
|
192
|
+
*
|
|
193
|
+
* <kf-auth-layout
|
|
194
|
+
* brand="Mi Portal"
|
|
195
|
+
* brandLogoSrc="images/mi-portal-logo-white.png"
|
|
196
|
+
* brandLogoMobileSrc="images/mi-portal-logo-black.png"
|
|
197
|
+
* brandTagline="Frase corta de marca, propia de cada portal."
|
|
198
|
+
* >
|
|
199
|
+
* <form (ngSubmit)="onSubmit()">
|
|
200
|
+
* <kf-input label="Correo" type="email" />
|
|
201
|
+
* <kf-input label="Contraseña" type="password" toggleable />
|
|
202
|
+
* <kf-button type="submit">Ingresar</kf-button>
|
|
203
|
+
* </form>
|
|
204
|
+
* </kf-auth-layout>
|
|
205
|
+
*/
|
|
206
|
+
declare class AuthLayout {
|
|
207
|
+
/** Nombre de marca/portal, usado como wordmark de respaldo si no hay ningún logo, y como `alt` de ambos logos. */
|
|
208
|
+
readonly brand: _angular_core.InputSignal<string>;
|
|
209
|
+
/** Logo en blanco para el panel oscuro de desktop — si no se pasa, se muestra `brand()` como wordmark tipográfico. */
|
|
210
|
+
readonly brandLogoSrc: _angular_core.InputSignal<string | undefined>;
|
|
211
|
+
/** Frase corta bajo el logo — opcional, cada portal decide su propio texto de marca. */
|
|
212
|
+
readonly brandTagline: _angular_core.InputSignal<string | undefined>;
|
|
213
|
+
/**
|
|
214
|
+
* Logo compacto para mobile, sobre el fondo claro del panel de contenido
|
|
215
|
+
* — normalmente la variante oscura/negra del mismo logo, ya que
|
|
216
|
+
* `brandLogoSrc` suele ser la variante blanca pensada para el gradiente
|
|
217
|
+
* oscuro. Si no se pasa, reutiliza `brandLogoSrc`; si tampoco hay logo en
|
|
218
|
+
* absoluto, cae al wordmark tipográfico igual que en desktop.
|
|
219
|
+
*/
|
|
220
|
+
readonly brandLogoMobileSrc: _angular_core.InputSignal<string | undefined>;
|
|
221
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AuthLayout, never>;
|
|
222
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<AuthLayout, "kf-auth-layout", never, { "brand": { "alias": "brand"; "required": true; "isSignal": true; }; "brandLogoSrc": { "alias": "brandLogoSrc"; "required": false; "isSignal": true; }; "brandTagline": { "alias": "brandTagline"; "required": false; "isSignal": true; }; "brandLogoMobileSrc": { "alias": "brandLogoMobileSrc"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
223
|
+
}
|
|
224
|
+
|
|
160
225
|
/**
|
|
161
226
|
* Avatar de usuario: muestra una foto (`src`) o, si no hay foto, las
|
|
162
227
|
* iniciales (`initials`) sobre un fondo con gradiente de marca. `round`
|
|
@@ -206,7 +271,7 @@ declare class Avatar {
|
|
|
206
271
|
* no existe un `-strong` para secondary todavía — usa el color base).
|
|
207
272
|
*/
|
|
208
273
|
declare class Badge {
|
|
209
|
-
readonly tone: _angular_core.InputSignal<"
|
|
274
|
+
readonly tone: _angular_core.InputSignal<"info" | "ok" | "warn" | "error" | "neutral" | "service">;
|
|
210
275
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
211
276
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Badge, never>;
|
|
212
277
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Badge, "kf-badge", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
@@ -393,7 +458,7 @@ declare class Checkbox implements ControlValueAccessor {
|
|
|
393
458
|
* de superficie/borde/texto-muted más cercanos).
|
|
394
459
|
*/
|
|
395
460
|
declare class Chip {
|
|
396
|
-
readonly tone: _angular_core.InputSignal<"
|
|
461
|
+
readonly tone: _angular_core.InputSignal<"ok" | "warn" | "error" | "neutral">;
|
|
397
462
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Chip, never>;
|
|
398
463
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Chip, "kf-chip", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
399
464
|
}
|
|
@@ -621,84 +686,209 @@ declare class Divider {
|
|
|
621
686
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Divider, "kf-divider", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
622
687
|
}
|
|
623
688
|
|
|
689
|
+
type DrawerSide = 'left' | 'right';
|
|
690
|
+
/**
|
|
691
|
+
* Panel lateral genérico, agnóstico de contenido — no sabe qué es navegación
|
|
692
|
+
* ni qué es sesión, solo da tres lugares para proyectar contenido
|
|
693
|
+
* (`[kf-drawer-header]`, default, `[kf-drawer-footer]`) y resuelve lo que
|
|
694
|
+
* cualquier drawer necesita resolver igual sin importar qué haya adentro:
|
|
695
|
+
* overlay con blur que cierra al click, `Escape`, atrapado de foco real y
|
|
696
|
+
* devolución de foco al cerrar.
|
|
697
|
+
*
|
|
698
|
+
* Extraído de `PortalHeader`, que hasta acá reimplementaba su propio drawer
|
|
699
|
+
* embebido (navegación hardcodeada + slot único al final). Cualquier
|
|
700
|
+
* consumidor que necesite un panel lateral — no solo `PortalHeader` — puede
|
|
701
|
+
* usar este componente directamente.
|
|
702
|
+
*
|
|
703
|
+
* `open` es two-way, mismo patrón que `Dropdown`/`Modal`: el consumidor
|
|
704
|
+
* decide qué dispara la apertura (un botón de hamburguesa, por ejemplo) y
|
|
705
|
+
* qué hace con el cierre.
|
|
706
|
+
*
|
|
707
|
+
* Foco: al abrir, se crea un `FocusTrap` del CDK sobre el panel (la misma
|
|
708
|
+
* pieza que usa Angular Material para `mat-sidenav`/`mat-dialog`) — Tab y
|
|
709
|
+
* Shift+Tab ciclan solo entre los elementos focuseables del drawer, sin
|
|
710
|
+
* escapar al contenido de fondo. Al cerrar, el foco vuelve al elemento que
|
|
711
|
+
* tenía el foco antes de abrir (guardado en `document.activeElement`), no
|
|
712
|
+
* se pierde en el `<body>`.
|
|
713
|
+
*
|
|
714
|
+
* `[kf-drawer-header]` tiene fondo oscuro propio (`--kf-color-tertiary-deep`),
|
|
715
|
+
* distinto del body (`--kf-color-white`) — pensado para contener
|
|
716
|
+
* `kf-drawer-session`, que asume ese fondo y no lo trae él mismo (ver
|
|
717
|
+
* `DrawerSession.ts`). Si el slot queda vacío, el contenedor colapsa
|
|
718
|
+
* (`display: none`) y no deja una franja oscura sin contenido.
|
|
719
|
+
*
|
|
720
|
+
* <kf-drawer [(open)]="menuOpen" ariaLabel="Menú de navegación">
|
|
721
|
+
* <div kf-drawer-header>
|
|
722
|
+
* <kf-drawer-session name="Tomás Soto" email="tomas@kaufmann.com" (logoutClick)="onLogout()" />
|
|
723
|
+
* </div>
|
|
724
|
+
* <a href="/">Home</a>
|
|
725
|
+
* <a href="/vehiculos">Vehículos</a>
|
|
726
|
+
* </kf-drawer>
|
|
727
|
+
*/
|
|
728
|
+
declare class Drawer {
|
|
729
|
+
/** Visibilidad del panel, two-way: `[(open)]="menuOpen"`. */
|
|
730
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
731
|
+
/** Borde de anclaje del panel. `left` (default) es la convención dominante
|
|
732
|
+
* (Material/iOS/Android): el botón que abre el drawer y el propio panel
|
|
733
|
+
* quedan del mismo lado. */
|
|
734
|
+
readonly side: _angular_core.InputSignal<DrawerSide>;
|
|
735
|
+
/** `aria-label` del `<nav>` interno — describe el propósito del panel para
|
|
736
|
+
* lectores de pantalla (ej. "Menú de navegación"). */
|
|
737
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
738
|
+
private readonly panelRef;
|
|
739
|
+
private readonly focusTrapFactory;
|
|
740
|
+
private readonly document;
|
|
741
|
+
private focusTrap;
|
|
742
|
+
private lastFocusedElement;
|
|
743
|
+
constructor();
|
|
744
|
+
/** Cierra el drawer con Escape — mismo patrón que `Dropdown`/`Modal`. */
|
|
745
|
+
protected onEscape(): void;
|
|
746
|
+
private getOrCreateFocusTrap;
|
|
747
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Drawer, never>;
|
|
748
|
+
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>;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Botón de cerrar sesión, pensado para proyectarse dentro de
|
|
753
|
+
* `[kf-drawer-footer]` de `kf-drawer`, o junto a `kf-drawer-session` dentro
|
|
754
|
+
* de `[kf-sidebar-footer]` de `kf-sidebar-shell` — separado de
|
|
755
|
+
* `kf-drawer-session` (que solo muestra identidad: brand, avatar, nombre,
|
|
756
|
+
* email), no anidado dentro de ella.
|
|
757
|
+
*
|
|
758
|
+
* Reproduce el mismo botón que antes vivía embebido en `DrawerSession`:
|
|
759
|
+
* ícono `log-out` + label, color `--kf-color-error` con hover en
|
|
760
|
+
* `--kf-color-error-soft` y foco visible con `--kf-shadow-focus`. Se separó
|
|
761
|
+
* en un componente propio porque identidad y logout son responsabilidades
|
|
762
|
+
* distintas — `kf-drawer-session` no debería saber que existe un botón de
|
|
763
|
+
* cerrar sesión, y el footer del drawer ya tiene su propio padding/borde
|
|
764
|
+
* superior (ver `Drawer.ts`) que reemplaza el borde que antes traía el botón
|
|
765
|
+
* mismo.
|
|
766
|
+
*
|
|
767
|
+
* No sabe nada de autenticación real — solo emite `logoutClick` cuando el
|
|
768
|
+
* consumidor debe cerrar la sesión real.
|
|
769
|
+
*
|
|
770
|
+
* `collapsed` oculta el label y centra el ícono, exponiéndolo vía `title`
|
|
771
|
+
* — mismo criterio que `SidebarNavItem.collapsed` y
|
|
772
|
+
* `DrawerSession.collapsed`, para cuando este botón vive dentro de un
|
|
773
|
+
* `kf-sidebar-shell` colapsado.
|
|
774
|
+
*
|
|
775
|
+
* <kf-drawer-logout kf-portal-header-footer (logoutClick)="onLogout()" />
|
|
776
|
+
*/
|
|
777
|
+
declare class DrawerLogout {
|
|
778
|
+
/** Label del botón, en español neutro por defecto. Input opcional por si
|
|
779
|
+
* algún consumidor futuro necesita otro texto. */
|
|
780
|
+
readonly label: _angular_core.InputSignal<string>;
|
|
781
|
+
/** Oculta el label y centra el ícono — ver comentario de la clase. */
|
|
782
|
+
readonly collapsed: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
783
|
+
readonly logoutClick: _angular_core.OutputEmitterRef<void>;
|
|
784
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DrawerLogout, never>;
|
|
785
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DrawerLogout, "kf-drawer-logout", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; }, { "logoutClick": "logoutClick"; }, never, never, true, never>;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* Bloque de identidad para `[kf-drawer-header]` de `kf-drawer` o
|
|
790
|
+
* `[kf-sidebar-footer]` de `kf-sidebar-shell`: avatar + nombre + email,
|
|
791
|
+
* brand opcional arriba. Solo identidad — el logout vive aparte, en
|
|
792
|
+
* `kf-drawer-logout`.
|
|
793
|
+
*
|
|
794
|
+
* `collapsed` oculta brand/nombre/email y deja solo el avatar (para un
|
|
795
|
+
* `kf-sidebar-shell` colapsado). `interactive` convierte la tarjeta en un
|
|
796
|
+
* botón real que emite `cardClick`, para cuando la identidad es el
|
|
797
|
+
* disparador de un menú de acciones (ej. envuelta en `kf-dropdown`).
|
|
798
|
+
*
|
|
799
|
+
* <kf-dropdown [(open)]="menuOpen">
|
|
800
|
+
* <kf-drawer-session interactive name="Juan Pérez" email="juan@empresa.com" (cardClick)="menuOpen.set(!menuOpen())" />
|
|
801
|
+
* <kf-dropdown-panel variant="dark">
|
|
802
|
+
* <kf-dropdown-item icon="log-out" tone="error" (click)="onLogout()">Cerrar sesión</kf-dropdown-item>
|
|
803
|
+
* </kf-dropdown-panel>
|
|
804
|
+
* </kf-dropdown>
|
|
805
|
+
*/
|
|
806
|
+
declare class DrawerSession {
|
|
807
|
+
readonly name: _angular_core.InputSignal<string>;
|
|
808
|
+
readonly email: _angular_core.InputSignal<string>;
|
|
809
|
+
readonly initials: _angular_core.InputSignal<string>;
|
|
810
|
+
readonly avatarUrl: _angular_core.InputSignal<string>;
|
|
811
|
+
/** Label superior opcional, ej. "Portal Kaufmann LATAM". */
|
|
812
|
+
readonly brand: _angular_core.InputSignal<string>;
|
|
813
|
+
/** Oculta brand/nombre/email y centra el avatar — ver comentario de la clase. */
|
|
814
|
+
readonly collapsed: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
815
|
+
/** Convierte la tarjeta en un botón real con ícono de kebab — ver comentario de la clase. */
|
|
816
|
+
readonly interactive: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
817
|
+
/** Se emite al clickear la tarjeta, solo cuando `interactive` es `true`. */
|
|
818
|
+
readonly cardClick: _angular_core.OutputEmitterRef<void>;
|
|
819
|
+
/** Si no se pasa `initials`, se derivan de `name`: primera letra de cada
|
|
820
|
+
* una de las primeras 2 palabras, en mayúscula. */
|
|
821
|
+
protected readonly displayInitials: _angular_core.Signal<string>;
|
|
822
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DrawerSession, never>;
|
|
823
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DrawerSession, "kf-drawer-session", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "email": { "alias": "email"; "required": false; "isSignal": true; }; "initials": { "alias": "initials"; "required": false; "isSignal": true; }; "avatarUrl": { "alias": "avatarUrl"; "required": false; "isSignal": true; }; "brand": { "alias": "brand"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; }, { "cardClick": "cardClick"; }, never, never, true, never>;
|
|
824
|
+
}
|
|
825
|
+
|
|
624
826
|
type DropdownItemTone = 'neutral' | 'error';
|
|
625
827
|
/**
|
|
626
828
|
* Ítem de acción dentro de un `kf-dropdown-panel`. Es un `<button>` nativo
|
|
627
|
-
*
|
|
628
|
-
* comportamiento en la pantalla actual (cerrar sesión, ejecutar un
|
|
629
|
-
* comando), no navegan a otra URL.
|
|
829
|
+
* (no un `<a>`): dispara comportamiento en la pantalla actual, no navega.
|
|
630
830
|
*
|
|
631
|
-
*
|
|
831
|
+
* `icon` es opcional — sin él, el ítem es solo texto.
|
|
832
|
+
*
|
|
833
|
+
* <kf-dropdown-item icon="log-out" (click)="onLogout()" tone="error">Cerrar sesión</kf-dropdown-item>
|
|
632
834
|
*/
|
|
633
835
|
declare class DropdownItem {
|
|
634
836
|
readonly tone: _angular_core.InputSignal<DropdownItemTone>;
|
|
837
|
+
/** Ícono opcional al inicio de la fila. */
|
|
838
|
+
readonly icon: _angular_core.InputSignal<IconName | undefined>;
|
|
635
839
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DropdownItem, never>;
|
|
636
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownItem, "kf-dropdown-item", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
840
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownItem, "kf-dropdown-item", never, { "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
637
841
|
}
|
|
842
|
+
type DropdownPanelVariant = 'solid' | 'dark';
|
|
638
843
|
/**
|
|
639
844
|
* Contenido del panel flotante de un `kf-dropdown`. Es solo una plantilla
|
|
640
|
-
* (`<ng-template
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
845
|
+
* (`<ng-template>`, capturada vía `TemplateRef`) — `Dropdown` la conecta al
|
|
846
|
+
* overlay real cuando `open` pasa a `true`, no la renderiza en su propio
|
|
847
|
+
* lugar del DOM. Esto permite que el panel aparezca pegado al host de
|
|
848
|
+
* `Dropdown` sin importar dónde esté ese host en la página.
|
|
849
|
+
*
|
|
850
|
+
* `variant`: `'solid'` (default, fondo blanco) o `'dark'` (fondo sólido
|
|
851
|
+
* oscuro, mismo tono que `[kf-drawer-header]`) para cuando el trigger vive
|
|
852
|
+
* sobre una superficie oscura de marca.
|
|
853
|
+
*
|
|
854
|
+
* `dark` es sólida a propósito, no semitransparente: el CDK Overlay
|
|
855
|
+
* reposiciona el panel según dónde entra en el viewport y puede terminar
|
|
856
|
+
* cayendo sobre fondo blanco en vez de sobre el rail oscuro — un color
|
|
857
|
+
* sólido se ve intencional sin importar dónde lo posicione el CDK.
|
|
650
858
|
*/
|
|
651
859
|
declare class DropdownPanel {
|
|
860
|
+
readonly variant: _angular_core.InputSignal<DropdownPanelVariant>;
|
|
652
861
|
readonly templateRef: _angular_core.Signal<TemplateRef<any>>;
|
|
653
862
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DropdownPanel, never>;
|
|
654
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownPanel, "kf-dropdown-panel", never, {}, {}, never, ["*"], true, never>;
|
|
863
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownPanel, "kf-dropdown-panel", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
655
864
|
}
|
|
656
865
|
/**
|
|
657
866
|
* Menú de acciones flotante, conectado a un elemento disparador vía
|
|
658
867
|
* `@angular/cdk/overlay` — la misma pieza que usa Angular Material para
|
|
659
|
-
* `mat-menu`/`mat-select`.
|
|
660
|
-
* mano en cada consumidor (ver el session-menu de `web-portal-latam-frontend`,
|
|
661
|
-
* ~80 líneas de HTML/TS/SCSS para toggle + click-afuera + Escape + animación
|
|
662
|
-
* de entrada, acopladas a una clase interna no pública de `PortalHeader`).
|
|
663
|
-
*
|
|
664
|
-
* Se apoya en el CDK en vez de un `position: absolute` casero (como sí hace
|
|
665
|
-
* `SelectMenu`, que puede permitírselo porque su trigger vive siempre dentro
|
|
666
|
-
* del propio componente) porque acá el disparador real puede vivir en OTRO
|
|
667
|
-
* componente por completo — ej. el avatar dentro de `kf-portal-header` — y
|
|
668
|
-
* el panel tiene que aparecer pegado a ESE elemento sin importar dónde el
|
|
669
|
-
* consumidor ubique al `Dropdown` en su HTML. El Overlay CDK calcula esa
|
|
670
|
-
* posición (con fallback si no entra en pantalla) en vez de que cada
|
|
671
|
-
* consumidor lo recalcule a mano.
|
|
672
|
-
*
|
|
673
|
-
* `open` es two-way, igual que `Alert`/`Modal`: el consumidor decide qué
|
|
674
|
-
* dispara la apertura (puede ser un `(click)` en un botón propio, o un
|
|
675
|
-
* evento de otro componente como `PortalHeader.sessionClick`) — `Dropdown`
|
|
676
|
-
* en sí no renderiza ningún trigger, su propio host es el punto de anclaje
|
|
677
|
-
* visual del panel.
|
|
868
|
+
* `mat-menu`/`mat-select`.
|
|
678
869
|
*
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
*
|
|
683
|
-
*
|
|
684
|
-
*
|
|
870
|
+
* Se apoya en el CDK en vez de un `position: absolute` casero (a diferencia
|
|
871
|
+
* de `SelectMenu`, que puede permitírselo porque su trigger vive siempre
|
|
872
|
+
* dentro del propio componente) porque acá el disparador real puede vivir
|
|
873
|
+
* en OTRO componente por completo — ej. el avatar dentro de
|
|
874
|
+
* `kf-portal-header` — y el panel tiene que aparecer pegado a ESE elemento
|
|
875
|
+
* sin importar dónde el consumidor ubique al `Dropdown` en su HTML.
|
|
876
|
+
*
|
|
877
|
+
* `open` es two-way: el consumidor decide qué dispara la apertura —
|
|
878
|
+
* `Dropdown` en sí no renderiza ningún trigger, su propio host es el punto
|
|
879
|
+
* de anclaje visual del panel.
|
|
880
|
+
*
|
|
881
|
+
* <kf-dropdown [(open)]="menuOpen"><kf-dropdown-panel>...</kf-dropdown-panel></kf-dropdown>
|
|
685
882
|
*/
|
|
686
883
|
declare class Dropdown {
|
|
687
884
|
/** Visibilidad del panel, two-way: `[(open)]="menuOpen"`. */
|
|
688
885
|
readonly open: _angular_core.ModelSignal<boolean>;
|
|
689
886
|
/**
|
|
690
887
|
* Elemento al que se conecta el overlay, si es distinto del propio host
|
|
691
|
-
* de `Dropdown`. Sin esto, `Dropdown` asume que ÉL MISMO es
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
* ensanchar el área de click a algo más grande que el botón (ej. el
|
|
696
|
-
* avatar de sesión dentro de `PortalHeader`, que convive con logo y
|
|
697
|
-
* navegación en el mismo host), `anchor` permite apuntar el overlay a la
|
|
698
|
-
* referencia real de ese componente en vez de al host vacío de
|
|
699
|
-
* `Dropdown`.
|
|
700
|
-
*
|
|
701
|
-
* <kf-dropdown [(open)]="menuOpen" [anchor]="headerRef()">
|
|
888
|
+
* de `Dropdown`. Sin esto, `Dropdown` asume que ÉL MISMO es el
|
|
889
|
+
* disparador. Útil cuando el disparador real vive dentro de OTRO
|
|
890
|
+
* componente que no se puede envolver sin ensanchar el área de click
|
|
891
|
+
* (ej. el avatar de sesión dentro de `PortalHeader`).
|
|
702
892
|
*/
|
|
703
893
|
readonly anchor: _angular_core.InputSignal<ElementRef<HTMLElement> | undefined>;
|
|
704
894
|
private readonly panel;
|
|
@@ -707,18 +897,41 @@ declare class Dropdown {
|
|
|
707
897
|
private readonly viewContainerRef;
|
|
708
898
|
private readonly destroyRef;
|
|
709
899
|
private overlayRef;
|
|
900
|
+
/**
|
|
901
|
+
* Suscripciones a `outsidePointerEvents()`/`keydownEvents()` del overlay
|
|
902
|
+
* ACTUALMENTE adjunto. `getOrCreateOverlayRef()` reutiliza el mismo
|
|
903
|
+
* `overlayRef` entre aperturas (no lo recrea cada vez) — sin esto,
|
|
904
|
+
* `attach()` se resuscribía a esos observables en cada apertura sin
|
|
905
|
+
* cancelar la suscripción de la vez anterior, acumulando N suscripciones
|
|
906
|
+
* activas sobre el mismo overlay persistente. Eso causaba el bug real de
|
|
907
|
+
* "clicks seguidos": al abrir de nuevo, el propio pointerdown que originó
|
|
908
|
+
* la apertura llegaba a más de una suscripción acumulada, disparando
|
|
909
|
+
* `open.set(false)` de forma errática en el mismo tick (patrón observado:
|
|
910
|
+
* abre cada 2 clicks, cierra cada 1). Se cancelan explícitamente en
|
|
911
|
+
* `detach()`, antes de la siguiente `attach()`.
|
|
912
|
+
*/
|
|
913
|
+
private overlaySubscription;
|
|
710
914
|
constructor();
|
|
711
915
|
/**
|
|
712
916
|
* Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo
|
|
713
|
-
* ve teclas
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
* vive fuera del overlay), `keydownEvents()` nunca dispara. Este listener
|
|
717
|
-
* a nivel de documento cubre ese caso; el de `keydownEvents()` sigue
|
|
718
|
-
* activo para cuando el foco sí está dentro del panel.
|
|
917
|
+
* ve teclas con el foco DENTRO del panel. Si el foco queda en el botón
|
|
918
|
+
* disparador (caso común), `keydownEvents()` nunca dispara — este
|
|
919
|
+
* listener a nivel de documento cubre ese caso.
|
|
719
920
|
*/
|
|
720
921
|
onDocumentEscape(): void;
|
|
721
922
|
private attach;
|
|
923
|
+
/**
|
|
924
|
+
* El trigger real (el `anchor`, o el propio host si no se pasó ninguno —
|
|
925
|
+
* ver comentario de la clase) vive FUERA del overlay a propósito: el
|
|
926
|
+
* overlay recién se crea/adjunta cuando `open` pasa a `true`, así que el
|
|
927
|
+
* CDK no tiene forma de saber que ese elemento externo "es parte" de su
|
|
928
|
+
* disparador. Sin este filtro, el mismo `pointerdown` que abre el menú
|
|
929
|
+
* (el trigger no es hijo del overlay) también llega a
|
|
930
|
+
* `outsidePointerEvents()`, cerrando el panel en el mismo gesto que lo
|
|
931
|
+
* abrió — bug real reproducido con Playwright: "abre y cierra" en
|
|
932
|
+
* clicks consecutivos rápidos sobre la tarjeta de sesión del sidebar.
|
|
933
|
+
*/
|
|
934
|
+
private isEventOnTrigger;
|
|
722
935
|
private detach;
|
|
723
936
|
private getOrCreateOverlayRef;
|
|
724
937
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Dropdown, never>;
|
|
@@ -881,6 +1094,21 @@ interface FolderTabOption {
|
|
|
881
1094
|
label: string;
|
|
882
1095
|
icon?: IconName;
|
|
883
1096
|
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Marca el contenido que `kf-folder-tabs` debe proyectar dentro de su
|
|
1099
|
+
* panel. Sin lógica propia — existe solo como token de tipo para que
|
|
1100
|
+
* `contentChild(FolderTabsPanel)` pueda detectar si el consumidor proyectó
|
|
1101
|
+
* algo (mismo mecanismo que `kf-dropdown` usa con `contentChild(DropdownPanel)`;
|
|
1102
|
+
* acá no hace falta un componente completo, alcanza con una directiva de
|
|
1103
|
+
* atributo porque el panel no necesita comportamiento propio, solo marcar
|
|
1104
|
+
* su presencia).
|
|
1105
|
+
*
|
|
1106
|
+
* <div kfFolderTabsPanel>...</div>
|
|
1107
|
+
*/
|
|
1108
|
+
declare class FolderTabsPanel {
|
|
1109
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FolderTabsPanel, never>;
|
|
1110
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<FolderTabsPanel, "[kfFolderTabsPanel]", never, {}, {}, never, never, true, never>;
|
|
1111
|
+
}
|
|
884
1112
|
/**
|
|
885
1113
|
* Tabs con forma de "carpeta": el borde superior queda redondeado y el borde
|
|
886
1114
|
* inferior de la pestaña activa se funde visualmente con el panel de
|
|
@@ -891,20 +1119,93 @@ interface FolderTabOption {
|
|
|
891
1119
|
* `--active` se mueve de un botón a otro, y eso vuelve a disparar el keyframe
|
|
892
1120
|
* sin tocar JS.
|
|
893
1121
|
*
|
|
894
|
-
* El
|
|
895
|
-
*
|
|
896
|
-
*
|
|
1122
|
+
* El panel de contenido es un `<ng-content>` OPCIONAL — si el consumidor no
|
|
1123
|
+
* proyecta nada, `kf-folder-tabs` renderiza solo la fila de pestañas (mismo
|
|
1124
|
+
* comportamiento que antes de que existiera este slot, detectado con
|
|
1125
|
+
* `contentChild()` sin `.required`, igual patrón que usa `kf-dropdown` para
|
|
1126
|
+
* saber si hay un `kf-dropdown-panel` proyectado). Si SÍ proyecta contenido,
|
|
1127
|
+
* se envuelve en un panel con la esquina superior-izquierda recta (nace ahí
|
|
1128
|
+
* la primera pestaña, siempre pegada al borde izquierdo de la fila — un
|
|
1129
|
+
* radio ahí competiría visualmente con el propio borde redondeado de esa
|
|
1130
|
+
* pestaña) y las otras tres redondeadas. El `border-bottom` de 2px de la
|
|
1131
|
+
* pestaña activa (ver `.kf-folder-tabs__tab--active` más abajo) es la señal
|
|
1132
|
+
* visual de conexión con el panel para CUALQUIER pestaña activa, sin
|
|
1133
|
+
* necesitar mover ni medir nada.
|
|
1134
|
+
*
|
|
1135
|
+
* El borde izquierdo de toda la fila (y por lo tanto de la esquina recta
|
|
1136
|
+
* del panel) depende de que ninguna pestaña se corra al cambiar de estado
|
|
1137
|
+
* — ver `transform-origin: bottom left` en `.kf-folder-tabs__tab`: con el
|
|
1138
|
+
* origen centrado (como estaba antes), el `scale()` de la pestaña inactiva
|
|
1139
|
+
* encogía el borde izquierdo unos px, y ese corrimiento sub-pixel es lo que
|
|
1140
|
+
* hacía que este mismo diseño (esquina fija) se viera "roto" cuando la
|
|
1141
|
+
* pestaña activa no era la primera. Con el origen anclado a la izquierda,
|
|
1142
|
+
* el corrimiento desaparece y la esquina fija vuelve a ser una solución
|
|
1143
|
+
* válida y simple — sin necesitar medir la pestaña activa por JS.
|
|
1144
|
+
*
|
|
1145
|
+
* Antes de este slot, el patrón era que el consumidor pusiera su propia
|
|
1146
|
+
* card como HERMANO de `kf-folder-tabs` y anulara a mano el radio superior
|
|
1147
|
+
* completo (`border-top-left-radius: 0`, `border-top-right-radius: 0` — ver
|
|
1148
|
+
* el caso original de `web-portal-latam-frontend`). Encapsular esto acá
|
|
1149
|
+
* evita que cada consumidor repita esas reglas a mano.
|
|
1150
|
+
*
|
|
1151
|
+
* <kf-folder-tabs [options]="tabs" [value]="active" (valueChange)="active = $event">
|
|
1152
|
+
* <div kfFolderTabsPanel>contenido de la pestaña activa</div>
|
|
1153
|
+
* </kf-folder-tabs>
|
|
1154
|
+
*
|
|
1155
|
+
* <!-- o, sin contenido, como antes: -->
|
|
897
1156
|
* <kf-folder-tabs [options]="tabs" [value]="active" (valueChange)="active = $event" />
|
|
898
1157
|
*/
|
|
899
1158
|
declare class FolderTabs {
|
|
900
1159
|
readonly options: _angular_core.InputSignal<FolderTabOption[]>;
|
|
901
1160
|
readonly value: _angular_core.InputSignal<string>;
|
|
902
1161
|
readonly valueChange: _angular_core.OutputEmitterRef<string>;
|
|
1162
|
+
/**
|
|
1163
|
+
* Detecta si el consumidor proyectó contenido marcado con
|
|
1164
|
+
* `kfFolderTabsPanel` — sin `.required`, así que es `undefined`
|
|
1165
|
+
* cuando no hay nada proyectado (mismo patrón que usa `kf-dropdown` con
|
|
1166
|
+
* `contentChild(DropdownPanel)` para saber si hay un panel que
|
|
1167
|
+
* attachear). `hasPanel()` decide si el wrapper del panel participa del
|
|
1168
|
+
* layout (`display: contents` si no).
|
|
1169
|
+
*/
|
|
1170
|
+
private readonly projectedPanel;
|
|
1171
|
+
protected readonly hasPanel: _angular_core.Signal<boolean>;
|
|
903
1172
|
select(value: string): void;
|
|
904
1173
|
/** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */
|
|
905
1174
|
onKeydown(event: KeyboardEvent, currentValue: string): void;
|
|
906
1175
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FolderTabs, never>;
|
|
907
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FolderTabs, "kf-folder-tabs", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; }, { "valueChange": "valueChange"; },
|
|
1176
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FolderTabs, "kf-folder-tabs", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; }, { "valueChange": "valueChange"; }, ["projectedPanel"], ["[kfFolderTabsPanel]"], true, never>;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/** Un link del pie — legales, contacto, soporte. */
|
|
1180
|
+
interface FooterLink {
|
|
1181
|
+
label: string;
|
|
1182
|
+
href?: string;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Pie de página general del portal (página 38): logo + copyright a la
|
|
1186
|
+
* izquierda, links legales/soporte empujados a la derecha. Logo y copyright
|
|
1187
|
+
* son inputs (cada portal del ecosistema — LATAM, OTD, Star — trae su
|
|
1188
|
+
* propia marca y texto legal); `links` es la lista de accesos, típicamente
|
|
1189
|
+
* placeholders hasta que existan destinos reales.
|
|
1190
|
+
*
|
|
1191
|
+
* <kf-footer
|
|
1192
|
+
* logoSrc="images/logo-kaufmann-dark.png"
|
|
1193
|
+
* logoAlt="Grupo Kaufmann"
|
|
1194
|
+
* copyright="© 2026 Kaufmann LATAM · Todos los derechos reservados"
|
|
1195
|
+
* [links]="[
|
|
1196
|
+
* { label: 'Políticas de privacidad' },
|
|
1197
|
+
* { label: 'Contacto' },
|
|
1198
|
+
* { label: 'Sugerencias y reclamos' },
|
|
1199
|
+
* ]"
|
|
1200
|
+
* />
|
|
1201
|
+
*/
|
|
1202
|
+
declare class Footer {
|
|
1203
|
+
readonly logoSrc: _angular_core.InputSignal<string | undefined>;
|
|
1204
|
+
readonly logoAlt: _angular_core.InputSignal<string>;
|
|
1205
|
+
readonly copyright: _angular_core.InputSignal<string>;
|
|
1206
|
+
readonly links: _angular_core.InputSignal<FooterLink[]>;
|
|
1207
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Footer, never>;
|
|
1208
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Footer, "kf-footer", never, { "logoSrc": { "alias": "logoSrc"; "required": false; "isSignal": true; }; "logoAlt": { "alias": "logoAlt"; "required": false; "isSignal": true; }; "copyright": { "alias": "copyright"; "required": true; "isSignal": true; }; "links": { "alias": "links"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
908
1209
|
}
|
|
909
1210
|
|
|
910
1211
|
/**
|
|
@@ -1109,18 +1410,25 @@ interface MultiSelectOption {
|
|
|
1109
1410
|
label: string;
|
|
1110
1411
|
}
|
|
1111
1412
|
/**
|
|
1112
|
-
* Dropdown de selección múltiple con checkboxes internos
|
|
1113
|
-
*
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1116
|
-
*
|
|
1117
|
-
*
|
|
1118
|
-
*
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1121
|
-
*
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1413
|
+
* Dropdown de selección múltiple con checkboxes internos. El panel flotante
|
|
1414
|
+
* se conecta al trigger vía `@angular/cdk/overlay` — el mismo mecanismo que
|
|
1415
|
+
* `Select` (ver `../select/Select.ts`) y `Dropdown` (`../dropdown/Dropdown.ts`).
|
|
1416
|
+
*
|
|
1417
|
+
* Hasta la `0.1.9` este panel vivía con `position: absolute` manual sobre el
|
|
1418
|
+
* propio host, sin depender del CDK Overlay. Se migró para unificar el
|
|
1419
|
+
* mecanismo de posicionamiento/cierre con el resto de los dropdowns flotantes
|
|
1420
|
+
* de la librería (4 posiciones de fallback, `withViewportMargin`, `withPush`,
|
|
1421
|
+
* cierre por `outsidePointerEvents()`/`keydownEvents()` en vez de un
|
|
1422
|
+
* `@HostListener('document:click')` manual).
|
|
1423
|
+
*
|
|
1424
|
+
* A diferencia de `Select`, el disparador no muestra un único valor sino los
|
|
1425
|
+
* nombres seleccionados junto a un badge circular con el conteo, y cada
|
|
1426
|
+
* opción del panel se marca/desmarca con un checkbox sin cerrar el panel.
|
|
1427
|
+
* Incluye una opción "Todas" al inicio de la lista, con estado
|
|
1428
|
+
* `indeterminate` cuando hay selección parcial — el mismo patrón de
|
|
1429
|
+
* "seleccionar todos" de `Checkbox`. "Todas" nunca se filtra por el buscador:
|
|
1430
|
+
* queda siempre visible y sigue actuando sobre el universo COMPLETO de
|
|
1431
|
+
* `options()`, no sobre el subconjunto filtrado (ver JSDoc de `toggleAll()`).
|
|
1124
1432
|
*
|
|
1125
1433
|
* <kf-multi-select
|
|
1126
1434
|
* label="Sucursales"
|
|
@@ -1139,14 +1447,27 @@ declare class MultiSelect {
|
|
|
1139
1447
|
readonly values: _angular_core.InputSignal<string[]>;
|
|
1140
1448
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
1141
1449
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1450
|
+
/**
|
|
1451
|
+
* Tri-state: si el consumidor no lo especifica (`undefined`), el buscador
|
|
1452
|
+
* se activa solo cuando `options().length` supera `searchThreshold()`. Si
|
|
1453
|
+
* el consumidor define `true`/`false` explícitamente, ese valor manda por
|
|
1454
|
+
* sobre el umbral automático. Mismo criterio que `Select`.
|
|
1455
|
+
*/
|
|
1456
|
+
readonly searchable: _angular_core.InputSignal<boolean | undefined>;
|
|
1457
|
+
readonly searchThreshold: _angular_core.InputSignal<number>;
|
|
1142
1458
|
readonly valuesChange: _angular_core.OutputEmitterRef<string[]>;
|
|
1143
1459
|
private readonly instanceId;
|
|
1144
1460
|
readonly triggerId: string;
|
|
1145
1461
|
readonly listboxId: string;
|
|
1146
1462
|
readonly isOpen: _angular_core.WritableSignal<boolean>;
|
|
1463
|
+
readonly searchQuery: _angular_core.WritableSignal<string>;
|
|
1464
|
+
readonly activeIndex: _angular_core.WritableSignal<number>;
|
|
1147
1465
|
readonly selectedCount: _angular_core.Signal<number>;
|
|
1148
1466
|
readonly allSelected: _angular_core.Signal<boolean>;
|
|
1149
1467
|
readonly isPartiallySelected: _angular_core.Signal<boolean>;
|
|
1468
|
+
readonly showSearch: _angular_core.Signal<boolean>;
|
|
1469
|
+
/** Opciones visibles tras aplicar el filtro de búsqueda ("Todas" nunca se filtra). */
|
|
1470
|
+
readonly filteredOptions: _angular_core.Signal<MultiSelectOption[]>;
|
|
1150
1471
|
/**
|
|
1151
1472
|
* Texto del disparador: placeholder si no hay selección, o los nombres
|
|
1152
1473
|
* seleccionados unidos por coma (el conteo va aparte, en el badge). Con
|
|
@@ -1154,18 +1475,88 @@ declare class MultiSelect {
|
|
|
1154
1475
|
* corta el texto — el badge de conteo siempre queda visible al lado.
|
|
1155
1476
|
*/
|
|
1156
1477
|
readonly summaryText: _angular_core.Signal<string>;
|
|
1157
|
-
private readonly
|
|
1478
|
+
private readonly triggerRef;
|
|
1479
|
+
private readonly panelTemplate;
|
|
1480
|
+
private readonly searchInputRef;
|
|
1481
|
+
private readonly overlayService;
|
|
1482
|
+
private readonly viewContainerRef;
|
|
1483
|
+
private readonly destroyRef;
|
|
1484
|
+
private overlayRef;
|
|
1485
|
+
constructor();
|
|
1158
1486
|
isSelected(value: string): boolean;
|
|
1159
1487
|
toggle(): void;
|
|
1160
1488
|
toggleOption(value: string): void;
|
|
1161
|
-
/**
|
|
1489
|
+
/**
|
|
1490
|
+
* Alterna entre "todas seleccionadas" y "ninguna seleccionada". Actúa
|
|
1491
|
+
* siempre sobre el universo COMPLETO de `options()`, no sobre
|
|
1492
|
+
* `filteredOptions()` — con un buscador activo, "Todas" no se filtra ni
|
|
1493
|
+
* cambia de significado: seguir marcando/desmarcando únicamente lo visible
|
|
1494
|
+
* sería sorprendente para quien ya tenía otras opciones (no visibles en el
|
|
1495
|
+
* filtro actual) seleccionadas de antes.
|
|
1496
|
+
*/
|
|
1162
1497
|
toggleAll(): void;
|
|
1163
|
-
|
|
1498
|
+
onSearchInput(event: Event): void;
|
|
1499
|
+
/** Mueve `activeIndex` sobre las opciones YA FILTRADAS visibles. Clamp simple, sin wraparound. */
|
|
1500
|
+
moveActive(delta: number): void;
|
|
1501
|
+
toggleActive(): void;
|
|
1164
1502
|
onEscape(): void;
|
|
1503
|
+
private attach;
|
|
1504
|
+
private detach;
|
|
1505
|
+
private getOrCreateOverlayRef;
|
|
1165
1506
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MultiSelect, never>;
|
|
1166
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MultiSelect, "kf-multi-select", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "valuesChange": "valuesChange"; }, never, never, true, never>;
|
|
1507
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MultiSelect, "kf-multi-select", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchThreshold": { "alias": "searchThreshold"; "required": false; "isSignal": true; }; }, { "valuesChange": "valuesChange"; }, never, never, true, never>;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
type TextAs = 'h1' | 'h2' | 'h3' | 'p' | 'span';
|
|
1511
|
+
type TextVariant = 'title-xxl' | 'title-xl' | 'title-lg' | 'title-md' | 'title-sm' | 'body' | 'body-muted' | 'caption';
|
|
1512
|
+
type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';
|
|
1513
|
+
/**
|
|
1514
|
+
* Tipografía unificada — separa la etiqueta semántica (`as`, qué es el
|
|
1515
|
+
* texto para el DOM/accesibilidad) del estilo visual (`variant`, cómo se
|
|
1516
|
+
* ve). Antes de este componente, cada pantalla que consume la librería
|
|
1517
|
+
* definía su propio `h1`/`p` con `font-size` suelto para el mismo rol
|
|
1518
|
+
* (título de página, subtítulo, texto secundario) — auditoría sobre
|
|
1519
|
+
* `web-portal-latam-frontend` encontró 9 tamaños distintos entre login y
|
|
1520
|
+
* home sin ningún paso de escala en común. `variant` resuelve eso contra
|
|
1521
|
+
* la escala de `tokens/base.css` (`--kf-font-size-*`).
|
|
1522
|
+
*
|
|
1523
|
+
* `tone` sigue la misma convención cerrada que `Alert`/`Badge`/`Chip`: sin
|
|
1524
|
+
* escape hatch de color libre. Si un caso necesita un color que `tone` no
|
|
1525
|
+
* cubre, es una discusión de design system, no una prop nueva acá.
|
|
1526
|
+
*
|
|
1527
|
+
* `title-xl`/`title-xxl` son un tier aparte de `title-lg|md|sm`: no vienen
|
|
1528
|
+
* de la auditoría de contenido de página (esa cerró en 2.125rem), son para
|
|
1529
|
+
* títulos protagonistas de pantalla completa (ej. bienvenida del home vía
|
|
1530
|
+
* `kf-page-header[size=xl|xxl]`) — ver tokens/base.css.
|
|
1531
|
+
*
|
|
1532
|
+
* <kf-text as="h1" variant="title-lg">Bienvenido de nuevo</kf-text>
|
|
1533
|
+
* <kf-text as="p" variant="body-muted">Ingresá con tu cuenta corporativa.</kf-text>
|
|
1534
|
+
* <kf-text as="span" variant="caption" tone="error">Campo obligatorio</kf-text>
|
|
1535
|
+
*/
|
|
1536
|
+
declare class Text {
|
|
1537
|
+
/** Etiqueta semántica real que se renderiza — nunca es solo un `div`. */
|
|
1538
|
+
readonly as: _angular_core.InputSignal<TextAs>;
|
|
1539
|
+
readonly variant: _angular_core.InputSignal<TextVariant>;
|
|
1540
|
+
readonly tone: _angular_core.InputSignal<TextTone>;
|
|
1541
|
+
/**
|
|
1542
|
+
* Copia de `as` para uso dentro del template: `as` es palabra reservada
|
|
1543
|
+
* en las expresiones de Angular (`@if (x; as y)`), así que `@switch (as())`
|
|
1544
|
+
* no parsea — NG5002. La prop pública sigue llamándose `as` (es solo un
|
|
1545
|
+
* atributo HTML ahí, `<kf-text as="h1">`, no una expresión).
|
|
1546
|
+
*/
|
|
1547
|
+
protected readonly tag: _angular_core.Signal<TextAs>;
|
|
1548
|
+
protected hostClass(): string;
|
|
1549
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Text, never>;
|
|
1550
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Text, "kf-text", never, { "as": { "alias": "as"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1167
1551
|
}
|
|
1168
1552
|
|
|
1553
|
+
/**
|
|
1554
|
+
* Tamaño del título — `md` es el tamaño de siempre (no rompe a nadie que no
|
|
1555
|
+
* lo especifique). Cada valor mapea 1:1 a una variante `title-*` de
|
|
1556
|
+
* `kf-text` (ver `Text.ts`); `xl`/`xxl` son el tier "hero" de esa escala,
|
|
1557
|
+
* pensado para casos de un título más protagonista (ej. bienvenida del home).
|
|
1558
|
+
*/
|
|
1559
|
+
type PageHeaderTitleSize = 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
|
|
1169
1560
|
/**
|
|
1170
1561
|
* Bloque de título al tope de una página: chip de ícono opcional, título (h1),
|
|
1171
1562
|
* subtítulo opcional y un área de acciones opcional proyectada vía
|
|
@@ -1177,13 +1568,17 @@ declare class MultiSelect {
|
|
|
1177
1568
|
* </kf-page-header>
|
|
1178
1569
|
*
|
|
1179
1570
|
* <kf-page-header icon="settings" title="Configuración" />
|
|
1571
|
+
*
|
|
1572
|
+
* <kf-page-header size="xl" title="Bienvenido de nuevo" />
|
|
1180
1573
|
*/
|
|
1181
1574
|
declare class PageHeader {
|
|
1182
1575
|
readonly icon: _angular_core.InputSignal<IconName | undefined>;
|
|
1183
1576
|
readonly title: _angular_core.InputSignal<string>;
|
|
1184
1577
|
readonly subtitle: _angular_core.InputSignal<string | undefined>;
|
|
1578
|
+
readonly size: _angular_core.InputSignal<PageHeaderTitleSize>;
|
|
1579
|
+
protected readonly titleVariant: _angular_core.Signal<TextVariant>;
|
|
1185
1580
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PageHeader, never>;
|
|
1186
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PageHeader, "kf-page-header", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; }, {}, never, ["[actions]"], true, never>;
|
|
1581
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PageHeader, "kf-page-header", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["[actions]"], true, never>;
|
|
1187
1582
|
}
|
|
1188
1583
|
|
|
1189
1584
|
/** Un número de página clickeable o un separador "…" no interactivo. */
|
|
@@ -1229,6 +1624,13 @@ declare class Pagination {
|
|
|
1229
1624
|
* <kf-panel title="Mis documentos por pagar" actionLabel="Ir a pagos" actionHref="/pagos">
|
|
1230
1625
|
* <kf-action-tile-row icon="download" title="Pagos" description="Revisa tu estado de cuenta y realiza pagos." />
|
|
1231
1626
|
* </kf-panel>
|
|
1627
|
+
*
|
|
1628
|
+
* El host y el `kf-card` interno son flex column con `flex:1` de punta a
|
|
1629
|
+
* punta — si un grid/flex externo estira `kf-panel` a la altura de un
|
|
1630
|
+
* hermano más alto, el contenido proyectado hereda esa altura en vez de
|
|
1631
|
+
* dejar un hueco vacío bajo el `kf-card`. Sin esa presión externa (altura
|
|
1632
|
+
* "auto" del contenedor), `flex:1` no tiene espacio extra que repartir y el
|
|
1633
|
+
* panel se comporta igual que antes.
|
|
1232
1634
|
*/
|
|
1233
1635
|
declare class Panel {
|
|
1234
1636
|
readonly title: _angular_core.InputSignal<string>;
|
|
@@ -1238,11 +1640,14 @@ declare class Panel {
|
|
|
1238
1640
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Panel, "kf-panel", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionHref": { "alias": "actionHref"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1239
1641
|
}
|
|
1240
1642
|
|
|
1241
|
-
/** Un ítem de navegación de la barra de marca.
|
|
1643
|
+
/** Un ítem de navegación de la barra de marca. `icon` es opcional y solo se
|
|
1644
|
+
* usa en el drawer mobile (columna, ver template) — el `<nav>` horizontal de
|
|
1645
|
+
* escritorio se mantiene solo texto, sin ícono ni chevron. */
|
|
1242
1646
|
interface PortalHeaderNavItem {
|
|
1243
1647
|
label: string;
|
|
1244
1648
|
href: string;
|
|
1245
1649
|
active?: boolean;
|
|
1650
|
+
icon?: IconName;
|
|
1246
1651
|
}
|
|
1247
1652
|
/** Una acción de la franja de administrador (ej. "Consultar deuda clientes"). */
|
|
1248
1653
|
interface PortalHeaderAdminAction {
|
|
@@ -1258,12 +1663,51 @@ interface PortalHeaderAdminAction {
|
|
|
1258
1663
|
* Es distinto de `kf-page-header`/`kf-page-head` (título de una vista
|
|
1259
1664
|
* interna) — este es el chrome global del portal, se monta una sola vez.
|
|
1260
1665
|
*
|
|
1666
|
+
* `:host` es `position: sticky; top: 0` — el header queda pegado arriba al
|
|
1667
|
+
* hacer scroll. No es `fixed`: como no se superpone al contenido en el
|
|
1668
|
+
* primer render, no hace falta que el consumidor compense con
|
|
1669
|
+
* `padding-top`.
|
|
1670
|
+
*
|
|
1671
|
+
* Bajo los 768px, el `<nav>` deja de mostrarse en línea junto al logo y
|
|
1672
|
+
* colapsa detrás de un botón de menú (ícono `menu`/`x`) que despliega un
|
|
1673
|
+
* `kf-drawer` (panel lateral genérico, ver `Drawer.ts`) anclado al borde
|
|
1674
|
+
* IZQUIERDO — mismo lado que el botón que lo abre, convención dominante
|
|
1675
|
+
* Material/iOS/Android — con los mismos `navItems` en columna dentro del
|
|
1676
|
+
* body (fondo claro) de ese drawer.
|
|
1677
|
+
*
|
|
1678
|
+
* `PortalHeader` expone dos slots propios pensados para que el consumidor
|
|
1679
|
+
* proyecte contenido que en escritorio vive en otro lugar:
|
|
1680
|
+
* - `<ng-content select="[kf-portal-header-extra]">`: identidad de sesión
|
|
1681
|
+
* (ej. `kf-drawer-session`). Cae en `[kf-drawer-header]` de `kf-drawer` —
|
|
1682
|
+
* el único contenedor con fondo oscuro (`--kf-color-tertiary-deep`, ver
|
|
1683
|
+
* `Drawer.ts`) que `kf-drawer-session` espera como fondo (no trae uno
|
|
1684
|
+
* propio, ver `DrawerSession.ts`).
|
|
1685
|
+
* - `<ng-content select="[kf-portal-header-footer]">`: acciones separadas del
|
|
1686
|
+
* resto (ej. `kf-drawer-logout`). Cae en `[kf-drawer-footer]` de
|
|
1687
|
+
* `kf-drawer`, mismo criterio de "no reimplementar nada del drawer": el
|
|
1688
|
+
* footer ya trae su propio padding/separador (ver `Drawer.ts`).
|
|
1689
|
+
*
|
|
1690
|
+
* `PortalHeader` no sabe qué es ninguno de los dos contenidos ni cómo se
|
|
1691
|
+
* abren, solo les da el lugar correcto dentro del drawer ya desplegado.
|
|
1692
|
+
* `kf-drawer` resuelve overlay con blur, cierre con click-afuera/`Escape`,
|
|
1693
|
+
* atrapado de foco real y devolución de foco al cerrar — `PortalHeader` no
|
|
1694
|
+
* reimplementa nada de eso, solo controla su `open` desde el botón de
|
|
1695
|
+
* hamburguesa.
|
|
1696
|
+
*
|
|
1261
1697
|
* <kf-portal-header
|
|
1262
1698
|
* [isAdmin]="true"
|
|
1263
1699
|
* [adminActions]="[{ label: 'Consultar deuda clientes', href: '/deuda' }, { label: 'Cambiar DNI', href: '/dni' }]"
|
|
1264
|
-
* [navItems]="[{ label: 'Home', href: '/', active: true }, { label: 'Vehículos', href: '/vehiculos' }]"
|
|
1700
|
+
* [navItems]="[{ label: 'Home', href: '/', active: true, icon: 'grid' }, { label: 'Vehículos', href: '/vehiculos', icon: 'truck' }]"
|
|
1265
1701
|
* userInitials="TS"
|
|
1266
|
-
*
|
|
1702
|
+
* >
|
|
1703
|
+
* <kf-drawer-session
|
|
1704
|
+
* kf-portal-header-extra
|
|
1705
|
+
* brand="Portal Kaufmann LATAM"
|
|
1706
|
+
* name="Tomás Soto"
|
|
1707
|
+
* email="tomas.soto@kaufmann.com"
|
|
1708
|
+
* />
|
|
1709
|
+
* <kf-drawer-logout kf-portal-header-footer (logoutClick)="onLogout()" />
|
|
1710
|
+
* </kf-portal-header>
|
|
1267
1711
|
*/
|
|
1268
1712
|
declare class PortalHeader {
|
|
1269
1713
|
readonly brand: _angular_core.InputSignal<string>;
|
|
@@ -1272,8 +1716,23 @@ declare class PortalHeader {
|
|
|
1272
1716
|
readonly navItems: _angular_core.InputSignal<PortalHeaderNavItem[]>;
|
|
1273
1717
|
readonly userInitials: _angular_core.InputSignal<string>;
|
|
1274
1718
|
readonly sessionClick: _angular_core.OutputEmitterRef<void>;
|
|
1719
|
+
/** Visibilidad del drawer de navegación mobile (bajo los 768px). Se pasa a
|
|
1720
|
+
* `kf-drawer` como `[(open)]` — `PortalHeader` ya no implementa overlay,
|
|
1721
|
+
* `Escape` ni atrapado de foco por su cuenta, eso vive en `Drawer`. */
|
|
1722
|
+
protected readonly mobileMenuOpen: _angular_core.WritableSignal<boolean>;
|
|
1723
|
+
/**
|
|
1724
|
+
* `ElementRef` real del botón de sesión (el avatar en la esquina
|
|
1725
|
+
* derecha), no de todo el header. Pensado para anclar un `kf-dropdown`
|
|
1726
|
+
* externo — sin esto, el único `ElementRef` disponible desde afuera es el
|
|
1727
|
+
* del host de `PortalHeader`, que ocupa el ancho completo de la pantalla
|
|
1728
|
+
* (logo + nav + sesión), y el overlay del CDK termina "pegado" a la
|
|
1729
|
+
* esquina del header entero en vez de al botón que el usuario clickeó.
|
|
1730
|
+
*
|
|
1731
|
+
* <kf-dropdown [(open)]="menuOpen" [anchor]="header().sessionButtonRef()">
|
|
1732
|
+
*/
|
|
1733
|
+
readonly sessionButtonRef: _angular_core.Signal<ElementRef<any>>;
|
|
1275
1734
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PortalHeader, never>;
|
|
1276
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PortalHeader, "kf-portal-header", never, { "brand": { "alias": "brand"; "required": false; "isSignal": true; }; "isAdmin": { "alias": "isAdmin"; "required": false; "isSignal": true; }; "adminActions": { "alias": "adminActions"; "required": false; "isSignal": true; }; "navItems": { "alias": "navItems"; "required": false; "isSignal": true; }; "userInitials": { "alias": "userInitials"; "required": true; "isSignal": true; }; }, { "sessionClick": "sessionClick"; }, never,
|
|
1735
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PortalHeader, "kf-portal-header", never, { "brand": { "alias": "brand"; "required": false; "isSignal": true; }; "isAdmin": { "alias": "isAdmin"; "required": false; "isSignal": true; }; "adminActions": { "alias": "adminActions"; "required": false; "isSignal": true; }; "navItems": { "alias": "navItems"; "required": false; "isSignal": true; }; "userInitials": { "alias": "userInitials"; "required": true; "isSignal": true; }; }, { "sessionClick": "sessionClick"; }, never, ["[kf-portal-header-extra]", "[kf-portal-header-footer]"], true, never>;
|
|
1277
1736
|
}
|
|
1278
1737
|
|
|
1279
1738
|
/**
|
|
@@ -1287,7 +1746,12 @@ declare class PortalHeader {
|
|
|
1287
1746
|
* invitación + las acciones como un bloque compuesto propio del dominio
|
|
1288
1747
|
* "taller", no un placeholder de una sola pieza.
|
|
1289
1748
|
*
|
|
1290
|
-
*
|
|
1749
|
+
* `grow` estira el panel de invitación para llenar el espacio vertical
|
|
1750
|
+
* disponible — solo cuando el consumidor comparte fila con una tarjeta más
|
|
1751
|
+
* alta (ej. junto a "Total de vehículos"); en un lugar sin esa presión
|
|
1752
|
+
* (home, debajo del carousel) se deja en su alto natural.
|
|
1753
|
+
*
|
|
1754
|
+
* <kf-reserve-block emptyLabel="No tienes reservas de taller" grow
|
|
1291
1755
|
* title="¿Necesitas mantención?" description="Tenemos la mejor red de talleres."
|
|
1292
1756
|
* actionLabel="Agenda tu reserva aquí" actionHref="/taller/agendar">
|
|
1293
1757
|
* <kf-button actions icon="calendar">Reservar hora</kf-button>
|
|
@@ -1300,8 +1764,10 @@ declare class ReserveBlock {
|
|
|
1300
1764
|
readonly description: _angular_core.InputSignal<string | undefined>;
|
|
1301
1765
|
readonly actionLabel: _angular_core.InputSignal<string | undefined>;
|
|
1302
1766
|
readonly actionHref: _angular_core.InputSignal<string | undefined>;
|
|
1767
|
+
/** La invitación se estira para llenar la tarjeta (ej. junto a "Total de vehículos"). */
|
|
1768
|
+
readonly grow: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1303
1769
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ReserveBlock, never>;
|
|
1304
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ReserveBlock, "kf-reserve-block", never, { "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionHref": { "alias": "actionHref"; "required": false; "isSignal": true; }; }, {}, never, ["[actions]"], true, never>;
|
|
1770
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ReserveBlock, "kf-reserve-block", never, { "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionHref": { "alias": "actionHref"; "required": false; "isSignal": true; }; "grow": { "alias": "grow"; "required": false; "isSignal": true; }; }, {}, never, ["[actions]"], true, never>;
|
|
1305
1771
|
}
|
|
1306
1772
|
|
|
1307
1773
|
/**
|
|
@@ -1402,16 +1868,30 @@ declare class Select {
|
|
|
1402
1868
|
readonly value: _angular_core.InputSignal<string | undefined>;
|
|
1403
1869
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
1404
1870
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1871
|
+
/**
|
|
1872
|
+
* Tri-state: si el consumidor no lo especifica (`undefined`), el buscador
|
|
1873
|
+
* se activa solo cuando `options().length` supera `searchThreshold()`. Si
|
|
1874
|
+
* el consumidor define `true`/`false` explícitamente, ese valor manda por
|
|
1875
|
+
* sobre el umbral automático.
|
|
1876
|
+
*/
|
|
1877
|
+
readonly searchable: _angular_core.InputSignal<boolean | undefined>;
|
|
1878
|
+
readonly searchThreshold: _angular_core.InputSignal<number>;
|
|
1405
1879
|
readonly valueChange: _angular_core.OutputEmitterRef<string>;
|
|
1406
1880
|
private readonly instanceId;
|
|
1407
1881
|
readonly triggerId: string;
|
|
1408
1882
|
readonly listboxId: string;
|
|
1409
1883
|
readonly isOpen: _angular_core.WritableSignal<boolean>;
|
|
1884
|
+
readonly searchQuery: _angular_core.WritableSignal<string>;
|
|
1885
|
+
readonly activeIndex: _angular_core.WritableSignal<number>;
|
|
1410
1886
|
/** Resolves the union (`string[] | { value; label }[]`) into a single shape for the template. */
|
|
1411
1887
|
readonly normalizedOptions: _angular_core.Signal<SelectOption[]>;
|
|
1412
1888
|
readonly selectedOption: _angular_core.Signal<SelectOption | undefined>;
|
|
1889
|
+
readonly showSearch: _angular_core.Signal<boolean>;
|
|
1890
|
+
/** Opciones visibles tras aplicar el filtro de búsqueda (case/acento-insensitive). */
|
|
1891
|
+
readonly filteredOptions: _angular_core.Signal<SelectOption[]>;
|
|
1413
1892
|
private readonly triggerRef;
|
|
1414
1893
|
private readonly panelTemplate;
|
|
1894
|
+
private readonly searchInputRef;
|
|
1415
1895
|
private readonly overlayService;
|
|
1416
1896
|
private readonly viewContainerRef;
|
|
1417
1897
|
private readonly destroyRef;
|
|
@@ -1426,11 +1906,107 @@ declare class Select {
|
|
|
1426
1906
|
onDocumentEscape(): void;
|
|
1427
1907
|
toggle(): void;
|
|
1428
1908
|
select(option: SelectOption): void;
|
|
1909
|
+
onSearchInput(event: Event): void;
|
|
1910
|
+
/**
|
|
1911
|
+
* Mueve `activeIndex` sobre las opciones YA FILTRADAS visibles. Clamp
|
|
1912
|
+
* simple (sin wraparound): llegar al final o al principio de la lista se
|
|
1913
|
+
* queda ahí en vez de dar la vuelta — es el comportamiento más predecible
|
|
1914
|
+
* cuando se combina con un buscador que puede reducir la lista a 1 opción.
|
|
1915
|
+
*/
|
|
1916
|
+
moveActive(delta: number): void;
|
|
1917
|
+
selectActive(): void;
|
|
1429
1918
|
private attach;
|
|
1430
1919
|
private detach;
|
|
1431
1920
|
private getOrCreateOverlayRef;
|
|
1432
1921
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Select, never>;
|
|
1433
|
-
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; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
1922
|
+
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; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchThreshold": { "alias": "searchThreshold"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
/** Tipo que consume `kf-sidebar-shell.navItems`. `icon` es requerido: en el
|
|
1926
|
+
* sidebar persistente el ícono es parte permanente del diseño. */
|
|
1927
|
+
interface SidebarNavItemData {
|
|
1928
|
+
icon: IconName;
|
|
1929
|
+
label: string;
|
|
1930
|
+
href: string;
|
|
1931
|
+
active?: boolean;
|
|
1932
|
+
}
|
|
1933
|
+
/**
|
|
1934
|
+
* Ítem de navegación de `kf-sidebar-shell` — ícono + label en fila, estado
|
|
1935
|
+
* activo, sin agrupación. Es el equivalente vertical/persistente del `<a>`
|
|
1936
|
+
* que arma `kf-portal-header` para su `<nav>` horizontal.
|
|
1937
|
+
*
|
|
1938
|
+
* `collapsed` se recibe como input explícito (no vía `:host-context`): el
|
|
1939
|
+
* componente no necesita saber cómo funciona el estado de colapso del
|
|
1940
|
+
* shell, solo qué hacer cuando `collapsed` es `true`.
|
|
1941
|
+
*
|
|
1942
|
+
* No sabe nada de routing — emite `href` como cualquier link y deja que el
|
|
1943
|
+
* consumidor intercepte el click para integrarlo con el Router.
|
|
1944
|
+
*/
|
|
1945
|
+
declare class SidebarNavItem {
|
|
1946
|
+
readonly icon: _angular_core.InputSignal<IconName>;
|
|
1947
|
+
readonly label: _angular_core.InputSignal<string>;
|
|
1948
|
+
readonly href: _angular_core.InputSignal<string>;
|
|
1949
|
+
readonly active: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1950
|
+
/** Oculta el label y centra el ícono — lo controla `kf-sidebar-shell` según su propio estado de colapso. */
|
|
1951
|
+
readonly collapsed: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1952
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SidebarNavItem, never>;
|
|
1953
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SidebarNavItem, "kf-sidebar-nav-item", never, { "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "href": { "alias": "href"; "required": true; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
/**
|
|
1957
|
+
* Shell de layout con navegación lateral persistente — el complemento
|
|
1958
|
+
* vertical de `kf-portal-header` (navbar horizontal). Pensado para
|
|
1959
|
+
* portales tipo "aplicación interna" (Portal OTD, Servicio Star).
|
|
1960
|
+
*
|
|
1961
|
+
* `navItems` se recibe como array de datos (no como contenido proyectado):
|
|
1962
|
+
* el componente no sabe nada de routing, emite `navItemClick` con el ítem
|
|
1963
|
+
* clickeado y deja que el consumidor decida cómo navegar.
|
|
1964
|
+
*
|
|
1965
|
+
* Slots: `[kf-sidebar-brand]` (logo del rail expandido, visible en desktop
|
|
1966
|
+
* y en el panel mobile — es el MISMO rail), `[kf-sidebar-brand-collapsed]`
|
|
1967
|
+
* (reemplazo opcional cuando el rail está colapsado en desktop),
|
|
1968
|
+
* `[kf-sidebar-brand-mobile]` (logo de la topbar angosta de mobile, fondo
|
|
1969
|
+
* claro) y `[kf-sidebar-footer]` (tarjeta de usuario / acciones al pie).
|
|
1970
|
+
*
|
|
1971
|
+
* Botón de colapso: vive como último ítem de la propia lista de
|
|
1972
|
+
* navegación, no flotando en el borde del rail — mismo criterio de
|
|
1973
|
+
* tap-target grande y predecible que el resto de los ítems.
|
|
1974
|
+
*
|
|
1975
|
+
* Responsive: bajo los 900px el sidebar NO se reemplaza por un panel
|
|
1976
|
+
* distinto — es el MISMO rail el que pasa a `position: fixed` fuera de la
|
|
1977
|
+
* pantalla (`translateX(-100%)`) y se desliza a la vista (`translateX(0)`)
|
|
1978
|
+
* sobre un backdrop cuando `mobileOpen` es `true`. Una topbar angosta con
|
|
1979
|
+
* botón de hamburguesa reemplaza al rail en el flujo del documento
|
|
1980
|
+
* mientras el panel está cerrado.
|
|
1981
|
+
*
|
|
1982
|
+
* A propósito NO reutiliza `kf-drawer` (el panel lateral genérico de la
|
|
1983
|
+
* librería): `kf-drawer` tiene su propio fondo claro fijo y duplicaría el
|
|
1984
|
+
* árbol de navegación en un segundo lugar del DOM. Bug de contraste ya
|
|
1985
|
+
* corregido en el historial: los `kf-sidebar-nav-item`, con texto claro
|
|
1986
|
+
* pensado para el gradiente oscuro, quedaban invisibles sobre el fondo
|
|
1987
|
+
* blanco de `kf-drawer`. Acá hay un solo rail, un solo árbol de nav, que
|
|
1988
|
+
* cambia de posición según el viewport.
|
|
1989
|
+
*/
|
|
1990
|
+
declare class SidebarShell {
|
|
1991
|
+
/** Ítems del menú del rail. */
|
|
1992
|
+
readonly navItems: _angular_core.InputSignal<SidebarNavItemData[]>;
|
|
1993
|
+
/** Estado de colapso del rail en desktop, two-way. Sin efecto bajo los 900px (ver estilos). */
|
|
1994
|
+
readonly collapsed: _angular_core.ModelSignal<boolean>;
|
|
1995
|
+
/** Visibilidad del rail deslizado como panel en mobile, two-way. */
|
|
1996
|
+
readonly mobileOpen: _angular_core.ModelSignal<boolean>;
|
|
1997
|
+
/** Se emite al clickear un ítem — el consumidor decide cómo navegar (ej. `router.navigateByUrl`). */
|
|
1998
|
+
readonly navItemClick: _angular_core.OutputEmitterRef<SidebarNavItemData>;
|
|
1999
|
+
/** `true` bajo los 900px — sin esto, un rail dejado colapsado en desktop
|
|
2000
|
+
* seguía ocultando el label de cada ítem al abrir el panel en mobile. */
|
|
2001
|
+
private readonly isMobileViewport;
|
|
2002
|
+
/** Estado de colapso que efectivamente se le pasa a cada `kf-sidebar-nav-item`
|
|
2003
|
+
* y al propio botón de colapso. */
|
|
2004
|
+
protected readonly itemsCollapsed: _angular_core.Signal<boolean>;
|
|
2005
|
+
/** Cierra el panel mobile con Escape — mismo criterio que `Dropdown`/`Modal`/`Drawer`. */
|
|
2006
|
+
protected onEscape(): void;
|
|
2007
|
+
protected onNavItemClick(event: Event, item: SidebarNavItemData): void;
|
|
2008
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SidebarShell, never>;
|
|
2009
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SidebarShell, "kf-sidebar-shell", never, { "navItems": { "alias": "navItems"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "mobileOpen": { "alias": "mobileOpen"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; "mobileOpen": "mobileOpenChange"; "navItemClick": "navItemClick"; }, never, ["[kf-sidebar-brand]", "[kf-sidebar-brand-collapsed]", "[kf-sidebar-footer]", "[kf-sidebar-brand-mobile]"], true, never>;
|
|
1434
2010
|
}
|
|
1435
2011
|
|
|
1436
2012
|
/** Forma del placeholder. */
|
|
@@ -1522,7 +2098,7 @@ declare class StatTile {
|
|
|
1522
2098
|
* <kf-status-pill tone="error" dot>Fuera de servicio</kf-status-pill>
|
|
1523
2099
|
*/
|
|
1524
2100
|
declare class StatusPill {
|
|
1525
|
-
readonly tone: _angular_core.InputSignal<"
|
|
2101
|
+
readonly tone: _angular_core.InputSignal<"ok" | "warn" | "error" | "blue">;
|
|
1526
2102
|
readonly dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1527
2103
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<StatusPill, never>;
|
|
1528
2104
|
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>;
|
|
@@ -1561,44 +2137,6 @@ declare class Tabs {
|
|
|
1561
2137
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Tabs, "kf-tabs", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
1562
2138
|
}
|
|
1563
2139
|
|
|
1564
|
-
type TextAs = 'h1' | 'h2' | 'h3' | 'p' | 'span';
|
|
1565
|
-
type TextVariant = 'title-lg' | 'title-md' | 'title-sm' | 'body' | 'body-muted' | 'caption';
|
|
1566
|
-
type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';
|
|
1567
|
-
/**
|
|
1568
|
-
* Tipografía unificada — separa la etiqueta semántica (`as`, qué es el
|
|
1569
|
-
* texto para el DOM/accesibilidad) del estilo visual (`variant`, cómo se
|
|
1570
|
-
* ve). Antes de este componente, cada pantalla que consume la librería
|
|
1571
|
-
* definía su propio `h1`/`p` con `font-size` suelto para el mismo rol
|
|
1572
|
-
* (título de página, subtítulo, texto secundario) — auditoría sobre
|
|
1573
|
-
* `web-portal-latam-frontend` encontró 9 tamaños distintos entre login y
|
|
1574
|
-
* home sin ningún paso de escala en común. `variant` resuelve eso contra
|
|
1575
|
-
* la escala de `tokens/base.css` (`--kf-font-size-*`).
|
|
1576
|
-
*
|
|
1577
|
-
* `tone` sigue la misma convención cerrada que `Alert`/`Badge`/`Chip`: sin
|
|
1578
|
-
* escape hatch de color libre. Si un caso necesita un color que `tone` no
|
|
1579
|
-
* cubre, es una discusión de design system, no una prop nueva acá.
|
|
1580
|
-
*
|
|
1581
|
-
* <kf-text as="h1" variant="title-lg">Bienvenido de nuevo</kf-text>
|
|
1582
|
-
* <kf-text as="p" variant="body-muted">Ingresá con tu cuenta corporativa.</kf-text>
|
|
1583
|
-
* <kf-text as="span" variant="caption" tone="error">Campo obligatorio</kf-text>
|
|
1584
|
-
*/
|
|
1585
|
-
declare class Text {
|
|
1586
|
-
/** Etiqueta semántica real que se renderiza — nunca es solo un `div`. */
|
|
1587
|
-
readonly as: _angular_core.InputSignal<TextAs>;
|
|
1588
|
-
readonly variant: _angular_core.InputSignal<TextVariant>;
|
|
1589
|
-
readonly tone: _angular_core.InputSignal<TextTone>;
|
|
1590
|
-
/**
|
|
1591
|
-
* Copia de `as` para uso dentro del template: `as` es palabra reservada
|
|
1592
|
-
* en las expresiones de Angular (`@if (x; as y)`), así que `@switch (as())`
|
|
1593
|
-
* no parsea — NG5002. La prop pública sigue llamándose `as` (es solo un
|
|
1594
|
-
* atributo HTML ahí, `<kf-text as="h1">`, no una expresión).
|
|
1595
|
-
*/
|
|
1596
|
-
protected readonly tag: _angular_core.Signal<TextAs>;
|
|
1597
|
-
protected hostClass(): string;
|
|
1598
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Text, never>;
|
|
1599
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Text, "kf-text", never, { "as": { "alias": "as"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
2140
|
/**
|
|
1603
2141
|
* Visual tone of a toast. Maps to the state tokens in
|
|
1604
2142
|
* projects/ui/src/tokens/base.css. `loading` has no auto-dismiss and shows an
|
|
@@ -1696,6 +2234,34 @@ declare class ToastHost {
|
|
|
1696
2234
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ToastHost, "kf-toast-host", never, {}, {}, never, never, true, never>;
|
|
1697
2235
|
}
|
|
1698
2236
|
|
|
2237
|
+
type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
2238
|
+
/**
|
|
2239
|
+
* Tooltip de hover/focus — reemplaza el atributo `title` nativo del
|
|
2240
|
+
* navegador (lento en aparecer, sin estilo, inconsistente entre
|
|
2241
|
+
* navegadores/SO) por un panel propio, mismo mecanismo de
|
|
2242
|
+
* `@angular/cdk/overlay` que ya usa `Dropdown`.
|
|
2243
|
+
*
|
|
2244
|
+
* Pensado para el caso "ícono sin label visible necesita comunicar qué
|
|
2245
|
+
* es" (ej. `kf-sidebar-nav-item` colapsado). No es two-way: a diferencia
|
|
2246
|
+
* de `Dropdown`, esto se abre/cierra solo con hover/focus, nunca por click.
|
|
2247
|
+
*
|
|
2248
|
+
* <a [kfTooltip]="label()" kfTooltipPosition="right">…</a>
|
|
2249
|
+
*/
|
|
2250
|
+
declare class TooltipDirective {
|
|
2251
|
+
text: string;
|
|
2252
|
+
kfTooltipPosition: TooltipPosition;
|
|
2253
|
+
private readonly host;
|
|
2254
|
+
private readonly overlayService;
|
|
2255
|
+
private readonly viewContainerRef;
|
|
2256
|
+
private readonly injector;
|
|
2257
|
+
private overlayRef;
|
|
2258
|
+
protected show(): void;
|
|
2259
|
+
protected hide(): void;
|
|
2260
|
+
private positionsFor;
|
|
2261
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TooltipDirective, never>;
|
|
2262
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TooltipDirective, "[kfTooltip]", never, { "text": { "alias": "kfTooltip"; "required": false; }; "kfTooltipPosition": { "alias": "kfTooltipPosition"; "required": false; }; }, {}, never, never, true, never>;
|
|
2263
|
+
}
|
|
2264
|
+
|
|
1699
2265
|
/**
|
|
1700
2266
|
* Estado puntual mostrado junto a la identidad del vehículo (ej. "En ruta",
|
|
1701
2267
|
* "Mantenimiento", "Fuera de servicio"). `tone` define el color semántico:
|
|
@@ -1754,5 +2320,5 @@ declare class ViewToggle {
|
|
|
1754
2320
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ViewToggle, "kf-view-toggle", never, { "view": { "alias": "view"; "required": true; "isSignal": true; }; }, { "viewChange": "viewChange"; }, never, never, true, never>;
|
|
1755
2321
|
}
|
|
1756
2322
|
|
|
1757
|
-
export { ActionTile, AdminBadge, Alert, Avatar, Badge, Breadcrumb, Button, Card, Carousel, CarouselSlide, Checkbox, Chip, CompanySelector, ContentSlot, ContentState, DataTable, Divider, Dropdown, DropdownItem, DropdownPanel, EmptyState, FeatureCard, Field, FieldLabel, FilterChips, FolderTabs, Icon, Input, Link, MetricCard, Modal, MultiSelect, PageHeader, Pagination, Panel, PortalHeader, ReserveBlock, SectionHeader, Segmented, Select, Skeleton, Spinner, StatTile, StatusPill, Tabs, Text, ToastHost, ToastService, VehicleHeader, ViewToggle };
|
|
1758
|
-
export type { AlertTone, BreadcrumbItem, CompanySelectorMeta, ContentStateKind, ContentStateLoad, DataTableCardRole, DataTableColumn, DataTableView, DividerOrientation, DropdownItemTone, FolderTabOption, IconName, IconSize, LinkVariant, MultiSelectOption, PaginationItem, PortalHeaderAdminAction, PortalHeaderNavItem, SegmentedOption, SkeletonVariant, SpinnerSize, TabOption, TextAs, TextTone, TextVariant, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, VehicleHeaderStatus, ViewToggleOption };
|
|
2323
|
+
export { ActionTile, AdminBadge, Alert, AuthLayout, Avatar, Badge, Breadcrumb, Button, Card, Carousel, CarouselSlide, Checkbox, Chip, CompanySelector, ContentSlot, ContentState, DataTable, Divider, Drawer, DrawerLogout, DrawerSession, Dropdown, DropdownItem, DropdownPanel, EmptyState, FeatureCard, Field, FieldLabel, FilterChips, FolderTabs, FolderTabsPanel, Footer, Icon, Input, Link, MetricCard, Modal, MultiSelect, PageHeader, Pagination, Panel, PortalHeader, ReserveBlock, SectionHeader, Segmented, Select, SidebarNavItem, SidebarShell, Skeleton, Spinner, StatTile, StatusPill, Tabs, Text, ToastHost, ToastService, TooltipDirective, VehicleHeader, ViewToggle };
|
|
2324
|
+
export type { AlertTone, BreadcrumbItem, CompanySelectorMeta, ContentStateKind, ContentStateLoad, DataTableCardRole, DataTableColumn, DataTableView, DividerOrientation, DrawerSide, DropdownItemTone, DropdownPanelVariant, FolderTabOption, FooterLink, IconName, IconSize, LinkVariant, MultiSelectOption, PageHeaderTitleSize, PaginationItem, PortalHeaderAdminAction, PortalHeaderNavItem, SegmentedOption, SidebarNavItemData, SkeletonVariant, SpinnerSize, TabOption, TextAs, TextTone, TextVariant, ToastOptions, ToastPromiseMessages, ToastState, ToastTone, TooltipPosition, VehicleHeaderStatus, ViewToggleOption };
|