From cfffdfd192ff4cd9218ff2e9c3c00936f10b6be5 Mon Sep 17 00:00:00 2001 From: Josep Piguillem Date: Mon, 27 Jul 2026 23:49:11 +0200 Subject: [PATCH] fix: resuelve invarianza de inputs heredados y estrictez de tipos heredada --- libs/ui/src/lib/ui/button/base-button.component.ts | 4 ++-- .../ui/button/switch-button/switch-button.component.ts | 2 +- libs/ui/src/lib/ui/card/base-card.component.ts | 2 +- .../lib/ui/chip/chip-action/chip-action.component.ts | 2 +- .../src/lib/ui/chip/chip-date/chip-date.component.ts | 3 ++- .../lib/ui/chip/chip-status/chip-status.component.ts | 2 +- .../src/lib/ui/chip/chip-time/chip-time.component.ts | 7 ++++--- .../src/lib/ui/chip/chip-value/chip-value.component.ts | 5 ++--- libs/ui/src/lib/ui/chip/chip/chip.component.ts | 3 ++- .../lib/ui/list-item/list-item/list-item.component.ts | 2 +- libs/ui/src/lib/ui/modal/modal/modal.component.ts | 2 +- libs/ui/src/lib/ui/note/note/note.component.ts | 2 +- .../lib/ui/paginator/paginator/paginator.component.ts | 4 ++-- libs/ui/src/lib/ui/panel/base-panel.component.ts | 2 +- libs/ui/src/lib/ui/select/base-select.component.ts | 2 +- .../ui/select/select-period/select-period.component.ts | 2 -- .../text-viewer-link/text-viewer-link.component.ts | 1 - .../ui/wrapper/directives/grid-wrapper.directive.ts | 2 +- libs/ui/src/lib/ui/wrapper/main/main.wrapper.ts | 3 ++- .../application/device-configs.facade.ts | 8 +++++--- .../list-configs/application/list-configs.facade.ts | 8 +++++--- .../src/lib/util/loaders/aplication/loader.facade.ts | 10 ++++++---- 22 files changed, 42 insertions(+), 36 deletions(-) diff --git a/libs/ui/src/lib/ui/button/base-button.component.ts b/libs/ui/src/lib/ui/button/base-button.component.ts index e1e4f77..84d08c7 100644 --- a/libs/ui/src/lib/ui/button/base-button.component.ts +++ b/libs/ui/src/lib/ui/button/base-button.component.ts @@ -23,11 +23,11 @@ export abstract class PiBaseButtonComponent implements OnInit { return `pi-color__${this.color()}`; } - protected get sizeClass(): string { + protected get sizeClass(): string | null { return `pi-button__${this.size()}`; } - protected get appearanceClass(): string { + protected get appearanceClass(): string | null { return `pi-button__appearance--${this.appearance()}`; } diff --git a/libs/ui/src/lib/ui/button/switch-button/switch-button.component.ts b/libs/ui/src/lib/ui/button/switch-button/switch-button.component.ts index 92c7233..a1109a9 100644 --- a/libs/ui/src/lib/ui/button/switch-button/switch-button.component.ts +++ b/libs/ui/src/lib/ui/button/switch-button/switch-button.component.ts @@ -31,7 +31,7 @@ export class PiSwitchButtonComponent extends PiBaseButtonComponent { } readonly isActive = model(true); - readonly toggledTo = output(); + readonly toggledTo = output<'on' | 'off'>(); readonly contentType = input<'icon' | 'text'>('icon'); readonly content = input.required<[ diff --git a/libs/ui/src/lib/ui/card/base-card.component.ts b/libs/ui/src/lib/ui/card/base-card.component.ts index ff92e4d..5206a77 100644 --- a/libs/ui/src/lib/ui/card/base-card.component.ts +++ b/libs/ui/src/lib/ui/card/base-card.component.ts @@ -40,7 +40,7 @@ export abstract class PiBaseCardComponent implements OnInit { return this.hasShadow() && 'has-shadow'; } - protected get isClickableClass(): string | undefined { + protected get isClickableClass(): string | false | undefined { return this.isClickable() && 'is-clickable'; } diff --git a/libs/ui/src/lib/ui/chip/chip-action/chip-action.component.ts b/libs/ui/src/lib/ui/chip/chip-action/chip-action.component.ts index f162884..b0a5f69 100644 --- a/libs/ui/src/lib/ui/chip/chip-action/chip-action.component.ts +++ b/libs/ui/src/lib/ui/chip/chip-action/chip-action.component.ts @@ -52,7 +52,7 @@ export class PiChipActionComponent extends PiBaseChipComponent { // Skin override readonly size = input<'small' | 'medium' | 'large'>('small'); - override readonly color = input('primary'); + override readonly color = input('primary'); // Status readonly isActive = input.required(); diff --git a/libs/ui/src/lib/ui/chip/chip-date/chip-date.component.ts b/libs/ui/src/lib/ui/chip/chip-date/chip-date.component.ts index 2eadcbe..4251992 100644 --- a/libs/ui/src/lib/ui/chip/chip-date/chip-date.component.ts +++ b/libs/ui/src/lib/ui/chip/chip-date/chip-date.component.ts @@ -5,6 +5,7 @@ import { input, output } from '@angular/core'; +import { chipColor } from '../entities/chip.model'; import { ComponentFamilyClass, theming } from '../../../styles'; import { Date } from '../../../util/models'; import { PiBaseChipComponent } from '../base-chip.component'; @@ -48,7 +49,7 @@ export class PiChipDateComponent extends PiBaseChipComponent { readonly date = input.required(); // ISO format in UTC time zone // Skin - override readonly color = input('primary'); + override readonly color = input('primary'); readonly isStroked = input(false); // Size - weekday only available in LARGE diff --git a/libs/ui/src/lib/ui/chip/chip-status/chip-status.component.ts b/libs/ui/src/lib/ui/chip/chip-status/chip-status.component.ts index 01e0ab5..a172dd1 100644 --- a/libs/ui/src/lib/ui/chip/chip-status/chip-status.component.ts +++ b/libs/ui/src/lib/ui/chip/chip-status/chip-status.component.ts @@ -30,7 +30,7 @@ export class PiChipStatusComponent extends PiBaseChipComponent { // Skin readonly appearance = input<'ghost' | 'fill'>('fill'); override readonly affixPosition = input<'previous' | 'after'>('previous'); - override readonly size = input<'small' | 'medium'>('small'); + override readonly size = input<'small' | 'medium' | 'large'>('small'); /* green | red | yellow | blue | opacity */ readonly status = input.required(); diff --git a/libs/ui/src/lib/ui/chip/chip-time/chip-time.component.ts b/libs/ui/src/lib/ui/chip/chip-time/chip-time.component.ts index 21ad0b3..c9d21bd 100644 --- a/libs/ui/src/lib/ui/chip/chip-time/chip-time.component.ts +++ b/libs/ui/src/lib/ui/chip/chip-time/chip-time.component.ts @@ -5,6 +5,7 @@ import { input, output } from '@angular/core'; +import { chipColor } from '../entities/chip.model'; import { ComponentFamilyClass } from '../../../styles'; import { DateTime } from 'luxon'; import { PiBaseChipComponent } from '../base-chip.component'; @@ -39,17 +40,17 @@ export class PiChipTimeComponent extends PiBaseChipComponent { readonly timezone = input('utc'); // Skin - override readonly color = input('primary'); + override readonly color = input('primary'); /** * On the chip time cases, we override the affix position property because it will be always used by the thime input and will be always previous */ - override readonly affixPosition = input<'previous'>('previous'); + override readonly affixPosition = input<'previous' | 'after'>('previous'); // time - available in S and M // time + date - available in S - override readonly size = input<'small' | 'medium'>('small'); + override readonly size = input<'small' | 'medium' | 'large'>('small'); // Status readonly isActive = input.required(); diff --git a/libs/ui/src/lib/ui/chip/chip-value/chip-value.component.ts b/libs/ui/src/lib/ui/chip/chip-value/chip-value.component.ts index 349b159..d748ef3 100644 --- a/libs/ui/src/lib/ui/chip/chip-value/chip-value.component.ts +++ b/libs/ui/src/lib/ui/chip/chip-value/chip-value.component.ts @@ -12,7 +12,7 @@ import { NgIf } from '@angular/common'; }) export class PiChipValueComponent extends PiBaseChipComponent { @HostBinding('class') get valueClasses(): string { - const colorClass = this.value() > 0 ? 'pi-color__success' : 'pi-color__warn'; + const colorClass = Number(this.value()) > 0 ? 'pi-color__success' : 'pi-color__warn'; const hasLabelClass = !!this.label() ? 'has-label' : ''; const unitPosition = this.unitPosition(); const unitPositionClass = @@ -26,11 +26,10 @@ export class PiChipValueComponent extends PiBaseChipComponent { } // Content - override readonly value = input.required(); readonly unit = input.required(); // Skin - override readonly size = input<'medium' | 'large'>('large'); + override readonly size = input<'small' | 'medium' | 'large'>('large'); // Unit readonly unitPosition = input<'previous' | 'after'>('after'); diff --git a/libs/ui/src/lib/ui/chip/chip/chip.component.ts b/libs/ui/src/lib/ui/chip/chip/chip.component.ts index 47af103..1869159 100644 --- a/libs/ui/src/lib/ui/chip/chip/chip.component.ts +++ b/libs/ui/src/lib/ui/chip/chip/chip.component.ts @@ -1,5 +1,6 @@ import { ChangeDetectionStrategy, Component, HostBinding, input } from '@angular/core'; import { theming } from '../../../styles'; +import { chipColor } from '../entities/chip.model'; import { PiBaseChipComponent } from '../base-chip.component'; import { NgIf } from '@angular/common'; import { MatIcon } from '@angular/material/icon'; @@ -29,5 +30,5 @@ export class PiChipComponent extends PiBaseChipComponent { // Skin readonly appearance = input<'outline' | 'fill'>('outline'); - override readonly color = input('primary'); + override readonly color = input('primary'); } diff --git a/libs/ui/src/lib/ui/list-item/list-item/list-item.component.ts b/libs/ui/src/lib/ui/list-item/list-item/list-item.component.ts index 13272b3..ec43d51 100644 --- a/libs/ui/src/lib/ui/list-item/list-item/list-item.component.ts +++ b/libs/ui/src/lib/ui/list-item/list-item/list-item.component.ts @@ -90,7 +90,7 @@ export class PiListItemComponent { return color ? `pi-color__${color}` : ''; } - protected get maxWidthClass(): string { + protected get maxWidthClass(): string | false { const maxWidth = this.maxWidth(); return maxWidth !== 'full' && `pi-list-item__max-width--${maxWidth}`; } diff --git a/libs/ui/src/lib/ui/modal/modal/modal.component.ts b/libs/ui/src/lib/ui/modal/modal/modal.component.ts index 5f561d2..82461af 100644 --- a/libs/ui/src/lib/ui/modal/modal/modal.component.ts +++ b/libs/ui/src/lib/ui/modal/modal/modal.component.ts @@ -73,7 +73,7 @@ export class PiModalComponent { return this.data as CustomModalData; } - get buttonColorClass(): string { + get buttonColorClass(): string | null { return this.buttonColor ? `pi-button pi-color__${this.buttonColor}` : null; } diff --git a/libs/ui/src/lib/ui/note/note/note.component.ts b/libs/ui/src/lib/ui/note/note/note.component.ts index 93c3546..6baa88e 100644 --- a/libs/ui/src/lib/ui/note/note/note.component.ts +++ b/libs/ui/src/lib/ui/note/note/note.component.ts @@ -105,7 +105,7 @@ export class PiNoteComponent implements OnInit { this.noteStatus = this.getNoteStatus(); } - getNoteStatus(): NoteStatus { + getNoteStatus(): NoteStatus | undefined { const noteStatusOptions = this.noteDataService.getNoteStatusData(); return noteStatusOptions.find((noteStatus) => this.status() === noteStatus.statusType); } diff --git a/libs/ui/src/lib/ui/paginator/paginator/paginator.component.ts b/libs/ui/src/lib/ui/paginator/paginator/paginator.component.ts index 0e045e6..2e165eb 100644 --- a/libs/ui/src/lib/ui/paginator/paginator/paginator.component.ts +++ b/libs/ui/src/lib/ui/paginator/paginator/paginator.component.ts @@ -24,7 +24,7 @@ export class PiPaginatorComponent implements OnInit { readonly totalPages = input.required(); readonly isDisabled = input.required(); - readonly changePage = output(); + readonly changePage = output(); firstPages!: number[]; @@ -101,7 +101,7 @@ export class PiPaginatorComponent implements OnInit { if (!this.isDisabled()) { this.firstPagesRange = this.firstPagesRange + 3; this.firstPages = this.incrementPaginatorRangeBy(3); - this.currentPage = this.firstPages[0]; + this.currentPage.set(this.firstPages[0]); this.changePage.emit(this.currentPage()); } } diff --git a/libs/ui/src/lib/ui/panel/base-panel.component.ts b/libs/ui/src/lib/ui/panel/base-panel.component.ts index 2a5b74c..9b52ef1 100644 --- a/libs/ui/src/lib/ui/panel/base-panel.component.ts +++ b/libs/ui/src/lib/ui/panel/base-panel.component.ts @@ -98,7 +98,7 @@ export abstract class PiBasePanelComponent implements OnInit { return paddingValue ? `pi-panel__padding--${paddingValue}` : ''; } - protected get gridClass(): string { + protected get gridClass(): string | false { const grid = this.grid(); return grid && `pi-panel__grid--${grid}`; } diff --git a/libs/ui/src/lib/ui/select/base-select.component.ts b/libs/ui/src/lib/ui/select/base-select.component.ts index 67c13f8..7188ca2 100644 --- a/libs/ui/src/lib/ui/select/base-select.component.ts +++ b/libs/ui/src/lib/ui/select/base-select.component.ts @@ -280,7 +280,7 @@ export class PiBaseSelectComponent extends PiFormControl { /** * Manage the Select & Select Multiple appearance property */ - protected get appearanceClass(): string | undefined { + protected get appearanceClass(): string | false | undefined { const appearance = this.appearance(); return ( this.menuType() !== 'custom-grid' && diff --git a/libs/ui/src/lib/ui/select/select-period/select-period.component.ts b/libs/ui/src/lib/ui/select/select-period/select-period.component.ts index 22ef2d6..301ba2a 100644 --- a/libs/ui/src/lib/ui/select/select-period/select-period.component.ts +++ b/libs/ui/src/lib/ui/select/select-period/select-period.component.ts @@ -93,8 +93,6 @@ export class PiSelectPeriodComponent extends PiBaseSelectComponent implements Af } } - override readonly type = input<'dropdown'>(); - override readonly menuType = input<'flex-wrap'>(); /** * Component's constructor. Initializes the component with required services. diff --git a/libs/ui/src/lib/ui/text/text-viewer-link/text-viewer-link.component.ts b/libs/ui/src/lib/ui/text/text-viewer-link/text-viewer-link.component.ts index 2b4de40..f51c978 100644 --- a/libs/ui/src/lib/ui/text/text-viewer-link/text-viewer-link.component.ts +++ b/libs/ui/src/lib/ui/text/text-viewer-link/text-viewer-link.component.ts @@ -39,7 +39,6 @@ export class PiTextViewerLinkComponent extends PiBaseTextViewerComponent { readonly target = input('_self'); readonly queryParams = input(); - override readonly color = input.required<'primary' | 'accent' | 'white' | 'highlighted' | 'grey' | undefined>(); // Skin override readonly alignment = input('center'); diff --git a/libs/ui/src/lib/ui/wrapper/directives/grid-wrapper.directive.ts b/libs/ui/src/lib/ui/wrapper/directives/grid-wrapper.directive.ts index 4ba0779..3ab1cc2 100644 --- a/libs/ui/src/lib/ui/wrapper/directives/grid-wrapper.directive.ts +++ b/libs/ui/src/lib/ui/wrapper/directives/grid-wrapper.directive.ts @@ -26,7 +26,7 @@ export abstract class PiBaseGridWrapper { return gap && `pi-wrapper__gap--${gap}`; } - protected get fillClass(): string | undefined { + protected get fillClass(): string | false | undefined { const fill = this.fill(); return fill !== 'fit-content' && `pi-wrapper__fill--${fill}`; } diff --git a/libs/ui/src/lib/ui/wrapper/main/main.wrapper.ts b/libs/ui/src/lib/ui/wrapper/main/main.wrapper.ts index 49f0719..c34a4bc 100644 --- a/libs/ui/src/lib/ui/wrapper/main/main.wrapper.ts +++ b/libs/ui/src/lib/ui/wrapper/main/main.wrapper.ts @@ -1,5 +1,6 @@ import { ChangeDetectionStrategy, Component, Directive, HostBinding, input } from '@angular/core'; import { WrapperTypeClass } from '../../../styles'; +import { gap } from '../../../styles'; import { PiBaseWrapper } from '../base.wrapper'; @Directive() @@ -49,5 +50,5 @@ export class PiMainWrapper extends PiBaseWrapper { readonly isCentered = input(false); readonly type = input<'' | 'document'>(''); - override readonly gap = input<'s' | 'm' | 'l' | 'xl' | 'xxl' | 'xxxl'>('xxl'); + override readonly gap = input('xxl'); } diff --git a/libs/ui/src/lib/util/device-configs/application/device-configs.facade.ts b/libs/ui/src/lib/util/device-configs/application/device-configs.facade.ts index 6f18075..74bf175 100644 --- a/libs/ui/src/lib/util/device-configs/application/device-configs.facade.ts +++ b/libs/ui/src/lib/util/device-configs/application/device-configs.facade.ts @@ -1,5 +1,5 @@ // Angular -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; // Ngrx import { Store } from '@ngrx/store'; @@ -15,6 +15,10 @@ import * as fromSelectors from '../state/device-configs.selectors'; @Injectable({ providedIn: 'root' }) export class DeviceConfigsFacade { + // `inject()` en vez de parámetro de constructor: los inicializadores de + // propiedad de abajo se evalúan antes que los parámetros del constructor. + private readonly store = inject>(Store); + // Device readonly device$: Observable = this.store.select(fromSelectors.getDevice); readonly size$: Observable = this.store.select(fromSelectors.getSize); @@ -23,8 +27,6 @@ export class DeviceConfigsFacade { // Browser readonly browser$: Observable = this.store.select(fromSelectors.getBrowser); - constructor(private store: Store) {} - getBrowser(): void { this.store.dispatch(fromActions.BrowserActions.getBrowser()); } diff --git a/libs/ui/src/lib/util/list-configs/application/list-configs.facade.ts b/libs/ui/src/lib/util/list-configs/application/list-configs.facade.ts index e73a6be..04632e0 100644 --- a/libs/ui/src/lib/util/list-configs/application/list-configs.facade.ts +++ b/libs/ui/src/lib/util/list-configs/application/list-configs.facade.ts @@ -1,5 +1,5 @@ // Angular -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; // Ngrx import { Store } from '@ngrx/store'; @@ -14,9 +14,11 @@ import * as fromState from '../state/list-configs.reducer'; @Injectable({ providedIn: 'root' }) export class ListConfigsFacade { - readonly mode$: Observable = this.store.select(fromSelectors.getListMode); + // `inject()` en vez de parámetro de constructor: los inicializadores de + // propiedad de abajo se evalúan antes que los parámetros del constructor. + private readonly store = inject>(Store); - constructor(private store: Store) {} + readonly mode$: Observable = this.store.select(fromSelectors.getListMode); setListMode(payload: fromState.ListMode): void { this.store.dispatch(fromActions.setListMode({ payload })); diff --git a/libs/ui/src/lib/util/loaders/aplication/loader.facade.ts b/libs/ui/src/lib/util/loaders/aplication/loader.facade.ts index d681d1a..ac37929 100644 --- a/libs/ui/src/lib/util/loaders/aplication/loader.facade.ts +++ b/libs/ui/src/lib/util/loaders/aplication/loader.facade.ts @@ -1,5 +1,5 @@ // Angular -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; // RxJS import { Observable, Subscribable } from 'rxjs'; @@ -13,10 +13,12 @@ import * as LoaderActions from '../state/loader.actions'; @Injectable() export class LoaderFacade { - loader$: Observable = this.store.pipe(select(LoaderSelectors.getLoader)); - showLoader$: Observable | Subscribable | Promise; + // `inject()` en vez de parámetro de constructor: los inicializadores de + // propiedad de abajo se evalúan antes que los parámetros del constructor. + private readonly store = inject(Store); - constructor(private store: Store) {} + loader$: Observable = this.store.pipe(select(LoaderSelectors.getLoader)); + showLoader$?: Observable | Subscribable | Promise; showLoader() { this.store.dispatch(LoaderActions.showLoader());