Files
pireon-ui/libs/ui/README.md

6.9 KiB

@pi/ui

Librería de componentes Angular migrada desde monorepo-nx-ddd-demo/libs/shared (Angular 14, NgModules, decoradores) a Angular 22 con componentes standalone y señales.

libs/ui/src/
  index.ts            barrel público de @pi/ui
  lib/styles/         antes shared/styles
  lib/util/<n>/       antes shared/util/<n>   (24 libs)
  lib/ui/<n>/         antes shared/ui/<n>     (29 libs)

Construir: nx build ui · Lint: nx lint ui

Qué se hizo

Prefijo Dl→Pi, dl-→pi- (selectores, clases CSS, nombres de fichero), @deale-workspace/…→rutas relativas
NgModules 41 → 4 (sólo quedan los que aportan providers: icon-registry, loaders, router-store, scroll-to)
Componentes 70, todos con ChangeDetectionStrategy.OnPush
Decoradores 0 restantes: 460 input(), 6 model(), 20 output(), 8 viewChild(), 2 viewChildren(), 17 contentChild(), 6 contentChildren()
Control flow *ngIf/*ngFor/*ngSwitch → @if/@for/@switch (110 @if, 26 @for, 3 @switch). Ya no se importa ninguna directiva de CommonModule

Se usaron las migraciones oficiales de Angular (@angular/core:standalone, signal-input-migration, output-migration, signal-queries-migration, control-flow-migration, cleanup-unused-imports) y se resolvió a mano lo que no cubren.

Decisiones que cambian comportamiento

Revisar estos puntos antes de usar la librería en producción:

1. input.required no significa lo mismo que el antiguo !. La migración convierte @Input() x!: T en input.required<T>(), pero en Angular 14 no existían las entradas obligatorias: el ! sólo era una aserción de asignación definida. Se devolvieron a opcionales las que las propias plantillas de la librería demostraban que no eran obligatorias (allowPropagation, flexDirection, value de text-viewer, gap/icon/label de divider, link/gap de headline, device/justify/itemWidth de carousel, las de grid-item…). Las input.required que quedan endurecen la API respecto al original; conviene repasarlas contra el uso real en las aplicaciones.

2. Entradas con accessor → input()/model() + effect(). Seis entradas tenían getter/setter con efectos secundarios. El efecto se ejecuta durante la detección de cambios, no de forma síncrona en la asignación:

  • PiTabComponent.defaultSelectedTab — el onTabChange() del setter pasa a un effect().
  • PiBaseFormFieldComponent.isDisabled — pasa a input(); el estado efectivo a leer sigue siendo disabled (lo escriben también el CVA y el efecto).
  • PiSearchFieldComponent.isExpanded — model(); la emisión de isActive pasa a un effect().
  • PiSelectOptionComponent.isSelected — model() (los selects padre lo asignan sobre las instancias hijas); su markForCheck() manual ya no hace falta.
  • PiBaseMenuComponent.menuItems — el setter era un pass-through puro.
  • PiSelectMultipleComponent.selectedOptions — sólo tenía getter, así que el @Input() nunca pudo asignarse desde fuera: era un valor derivado.

3. PiAccordionComponent.expandedItemIndex pasa a model(). Tenía un two-way binding hecho a mano (expandedItemIndex + expandedItemIndexChange). model() genera el evento automáticamente. Ojo: el código original emitía el valor anterior al plegar/desplegar (emit(expandedItemIndex) antes de reasignar); model() emite el nuevo. Parece que el original tenía un bug. Su tipo pasa a number | null porque toggleState asigna null al colapsar.

4. Suscripciones a .changes eliminadas. Las signal queries no exponen QueryList.changes. Donde sólo se usaba para markForCheck() (accordion, tab, carousel) se eliminó: Angular ya reevalúa la plantilla al cambiar la señal. En los 4 selects se sustituyó por toObservable().

5. Salidas que emitían any. changePage y toggledTo eran new EventEmitter() sin genérico. Ahora son output<number>() y output<'on' | 'off'>().

6. Aserciones ! en plantillas. *ngIf="icon()" no estrecha el tipo (TypeScript no estrecha resultados de llamada entre expresiones), así que hay [svgIcon]="icon()!" en ~30 sitios. Mantiene el runtime idéntico al original. Se pueden eliminar migrando a @if (icon(); as icon).

7. Precedencia de pipes en select-multiple. x | truncate : 33 || (placeholder() | translate) se parseaba como truncate : (33 || …), así que el fallback nunca se aplicaba. Ahora está parentizado como se pretendía.

8. Los 3 selects se convirtieron a control flow a mano. La migración automática se rindió con ellos: tenían un *ngIf ... else que apuntaba a un <ng-template> con un [ngSwitch] dentro. Al reescribirlos hubo que renombrar plantillas duplicadas (#defaultSelected aparecía dos veces en ramas distintas del switch) a #defaultSelectedFill/#defaultSelectedOutline, y en select-period #defaultOption → #defaultMonthOption/#defaultYearOption. Los *ngFor sin trackBy pasaron a track <item>, que es lo que hacía ngFor por defecto. En data-grid y select-carousel la migración generó track trackByFn(i, item) pero esos trackByFn sólo declaran index: se corrigió la aridad a track trackByFn(i).

Colisiones de nombres en el barrel

El origen tiene símbolos duplicados. En index.ts gana el primero y el otro se omite (queda anotado en el fichero). Siguen siendo accesibles por ruta directa:

Símbolo Se exporta desde Se omite de
PiSlideToggleComponent ui/form-field ui/slide-toggle
PiDisabledDirective util/status ui/text
featureKey, getFeatureState, initialState util/device-configs util/list-configs

APIs de terceros actualizadas

  • ngx-translate 18 — no hay TranslateModule. PiSharedUtilTranslateModule → providePiTranslate(); en plantillas se importa TranslatePipe/TranslateDirective.
  • apollo-angular 14 — no hay ApolloModule. PiSharedUtilDatoCmsModule → providePiDatoCms().
  • ngx-currency 19 — CurrencyMaskInputMode→NgxCurrencyInputMode, NgxCurrencyModule→NgxCurrencyDirective.
  • chart.js 4 — chart.js/dist/types/utils no es importable; los tipos se derivan de ChartOptions.
  • Angular — TransferState/StateKey/makeStateKey vienen de @angular/core.

Pendiente

  • Tests: no se copiaron los *.spec.ts del origen.
  • Sector vivía en deale-saas/util/models (lib de aplicación, fuera de alcance); se trajo la interfaz a util/models.
  • ngrx 21 con Angular 22: instalado con --legacy-peer-deps (aún no declara soporte para 22).
  • Lint: nx lint ui falla con avisos heredados del código original — prefer-inject (51), directive-selector (46), no-explicit-any (35), no-unused-expressions (33), a11y (click-events-have-key-events, interactive-supports-focus, label-has-associated-control) y no-unused-vars. Nada bloquea el build. Para el primer grupo hay migración oficial: nx g @angular/core:inject-migration.