fix: adapta escrituras internas a model() y signal queries (toObservable)
This commit is contained in:
@@ -1,13 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
AfterContentInit,
|
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
ChangeDetectorRef,
|
|
||||||
Component,
|
Component,
|
||||||
HostBinding,
|
HostBinding,
|
||||||
OnChanges,
|
|
||||||
SimpleChanges,
|
|
||||||
input,
|
input,
|
||||||
output,
|
model,
|
||||||
contentChildren
|
contentChildren
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { padding, styleType, textColor } from '../../../styles';
|
import { padding, styleType, textColor } from '../../../styles';
|
||||||
@@ -37,7 +33,7 @@ import { TranslatePipe } from '@ngx-translate/core';
|
|||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class PiAccordionComponent implements OnChanges, AfterContentInit {
|
export class PiAccordionComponent {
|
||||||
@HostBinding('class') get classes(): string {
|
@HostBinding('class') get classes(): string {
|
||||||
const colorClass = `pi-accordion__${this.color()}`;
|
const colorClass = `pi-accordion__${this.color()}`;
|
||||||
const appearance = this.appearance();
|
const appearance = this.appearance();
|
||||||
@@ -50,7 +46,15 @@ export class PiAccordionComponent implements OnChanges, AfterContentInit {
|
|||||||
return ['pi-accordion', colorClass, appearanceClass, directionClass, paddingClass].join(' ');
|
return ['pi-accordion', colorClass, appearanceClass, directionClass, paddingClass].join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly expandedItemIndex = input.required<number>();
|
/**
|
||||||
|
* `model` en vez de `input` + output manual: el componente escribe este valor
|
||||||
|
* al plegar/desplegar. El evento `expandedItemIndexChange` que antes se
|
||||||
|
* declaraba a mano lo genera `model()` automáticamente.
|
||||||
|
*
|
||||||
|
* El tipo incluye `null` porque `toggleState` lo asigna al colapsar; antes
|
||||||
|
* estaba declarado como `number` y esa asignación no compilaba.
|
||||||
|
*/
|
||||||
|
readonly expandedItemIndex = model<number | null>(null);
|
||||||
readonly appearance = input<'default' | 'outline' | 'fill'>('default');
|
readonly appearance = input<'default' | 'outline' | 'fill'>('default');
|
||||||
readonly color = input<styleType>('white');
|
readonly color = input<styleType>('white');
|
||||||
readonly direction = input<'default' | 'horizontal'>('default');
|
readonly direction = input<'default' | 'horizontal'>('default');
|
||||||
@@ -59,37 +63,15 @@ export class PiAccordionComponent implements OnChanges, AfterContentInit {
|
|||||||
|
|
||||||
readonly hasChevron = input(true);
|
readonly hasChevron = input(true);
|
||||||
|
|
||||||
readonly expandedItemIndexChange = output<number>();
|
|
||||||
|
|
||||||
readonly items = contentChildren(PiAccordionItemDirective);
|
readonly items = contentChildren(PiAccordionItemDirective);
|
||||||
|
|
||||||
constructor(private cdr: ChangeDetectorRef) {}
|
// `items` es una signal query: Angular reevalúa la plantilla cuando cambia,
|
||||||
|
// así que el ngAfterContentInit que sólo hacía markForCheck() sobra.
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
|
||||||
if (
|
|
||||||
changes['expandedItemIndex'] &&
|
|
||||||
changes['expandedItemIndex'].currentValue !== changes['expandedItemIndex'].previousValue
|
|
||||||
) {
|
|
||||||
this.expandedItemIndex = changes['expandedItemIndex'].currentValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterContentInit(): void {
|
|
||||||
this.items().changes.subscribe(() => {
|
|
||||||
this.cdr.markForCheck();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleState = (item: PiAccordionItemDirective, index: number) => {
|
toggleState = (item: PiAccordionItemDirective, index: number) => {
|
||||||
if (this.direction() === 'horizontal' && this.isItemExpanded(index)) return;
|
if (this.direction() === 'horizontal' && this.isItemExpanded(index)) return;
|
||||||
if (item.status() === 'disabled') return;
|
if (item.status() === 'disabled') return;
|
||||||
const expandedItemIndex = this.expandedItemIndex();
|
this.expandedItemIndex.set(this.expandedItemIndex() === index ? null : index);
|
||||||
if (expandedItemIndex === index) {
|
|
||||||
this.expandedItemIndex = null;
|
|
||||||
} else {
|
|
||||||
this.expandedItemIndex = index;
|
|
||||||
}
|
|
||||||
this.expandedItemIndexChange.emit(expandedItemIndex);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
isItemExpanded = (index: number) => this.expandedItemIndex() === index;
|
isItemExpanded = (index: number) => this.expandedItemIndex() === index;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
Component,
|
Component,
|
||||||
HostBinding,
|
HostBinding,
|
||||||
input,
|
input,
|
||||||
|
model,
|
||||||
output
|
output
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { ComponentFamilyClass } from '../../../styles';
|
import { ComponentFamilyClass } from '../../../styles';
|
||||||
@@ -29,7 +30,7 @@ export class PiSwitchButtonComponent extends PiBaseButtonComponent {
|
|||||||
].join(' ');
|
].join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly isActive = input(true);
|
readonly isActive = model(true);
|
||||||
readonly toggledTo = output();
|
readonly toggledTo = output();
|
||||||
|
|
||||||
readonly contentType = input<'icon' | 'text'>('icon');
|
readonly contentType = input<'icon' | 'text'>('icon');
|
||||||
@@ -40,10 +41,10 @@ export class PiSwitchButtonComponent extends PiBaseButtonComponent {
|
|||||||
|
|
||||||
toggleSelected(): void {
|
toggleSelected(): void {
|
||||||
if (this.isActive()) {
|
if (this.isActive()) {
|
||||||
this.isActive = false;
|
this.isActive.set(false);
|
||||||
this.toggledTo.emit('off');
|
this.toggledTo.emit('off');
|
||||||
} else {
|
} else {
|
||||||
this.isActive = true;
|
this.isActive.set(true);
|
||||||
this.toggledTo.emit('on');
|
this.toggledTo.emit('on');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,10 +256,8 @@ export class PiCarouselComponent
|
|||||||
if (this.isDraggable()) {
|
if (this.isDraggable()) {
|
||||||
this.setDragEventListeners();
|
this.setDragEventListeners();
|
||||||
}
|
}
|
||||||
|
// La suscripción a `carouselItems.changes` sólo hacía markForCheck();
|
||||||
this.carouselItems().changes.pipe(takeUntil(this.destroyed$)).subscribe(() => {
|
// al ser `carouselItems` una signal query, Angular ya lo hace solo.
|
||||||
this.cdr.markForCheck();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewChecked(): void {
|
ngAfterViewChecked(): void {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit, HostBinding, forwardRef, input, output } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnInit, HostBinding, forwardRef, input, model, output } from '@angular/core';
|
||||||
import { PiIconButtonComponent } from '../../button/icon-button/icon-button.component';
|
import { PiIconButtonComponent } from '../../button/icon-button/icon-button.component';
|
||||||
import { NgIf, NgFor } from '@angular/common';
|
import { NgIf, NgFor } from '@angular/common';
|
||||||
import { PiIconComponent } from '../../icon/icon/icon.component';
|
import { PiIconComponent } from '../../icon/icon/icon.component';
|
||||||
@@ -19,7 +19,7 @@ import { PiIconComponent } from '../../icon/icon/icon.component';
|
|||||||
})
|
})
|
||||||
export class PiPaginatorComponent implements OnInit {
|
export class PiPaginatorComponent implements OnInit {
|
||||||
@HostBinding('class') className = 'pi-paginator';
|
@HostBinding('class') className = 'pi-paginator';
|
||||||
readonly currentPage = input(1);
|
readonly currentPage = model(1);
|
||||||
readonly pageSize = input.required<number>();
|
readonly pageSize = input.required<number>();
|
||||||
readonly totalPages = input.required<number>();
|
readonly totalPages = input.required<number>();
|
||||||
readonly isDisabled = input.required<boolean>();
|
readonly isDisabled = input.required<boolean>();
|
||||||
@@ -65,7 +65,7 @@ export class PiPaginatorComponent implements OnInit {
|
|||||||
this.firstPages = this.decrementPaginatorRangeBy(3);
|
this.firstPages = this.decrementPaginatorRangeBy(3);
|
||||||
this.firstPagesRange = this.firstPagesRange - 3;
|
this.firstPagesRange = this.firstPagesRange - 3;
|
||||||
}
|
}
|
||||||
this.currentPage = updatedCurrentPage;
|
this.currentPage.set(updatedCurrentPage);
|
||||||
this.changePage.emit(updatedCurrentPage);
|
this.changePage.emit(updatedCurrentPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ export class PiPaginatorComponent implements OnInit {
|
|||||||
this.firstPagesRange = this.firstPagesRange + 3;
|
this.firstPagesRange = this.firstPagesRange + 3;
|
||||||
this.firstPages = this.incrementPaginatorRangeBy(3);
|
this.firstPages = this.incrementPaginatorRangeBy(3);
|
||||||
}
|
}
|
||||||
this.currentPage = updatedCurrentPage;
|
this.currentPage.set(updatedCurrentPage);
|
||||||
this.changePage.emit(updatedCurrentPage);
|
this.changePage.emit(updatedCurrentPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ export class PiPaginatorComponent implements OnInit {
|
|||||||
if (this.isDisabled() && selectedPage > this.currentPage()) {
|
if (this.isDisabled() && selectedPage > this.currentPage()) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this.currentPage = selectedPage;
|
this.currentPage.set(selectedPage);
|
||||||
this.changePage.emit(this.currentPage());
|
this.changePage.emit(this.currentPage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
TemplateRef,
|
TemplateRef,
|
||||||
input,
|
input,
|
||||||
|
model,
|
||||||
output,
|
output,
|
||||||
contentChild
|
contentChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
@@ -59,7 +60,7 @@ export class PiExpansionPanelComponent extends PiBasePanelComponent implements O
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly type = input<'form' | 'custom'>('form');
|
readonly type = input<'form' | 'custom'>('form');
|
||||||
readonly isCollapsed = input(false);
|
readonly isCollapsed = model(false);
|
||||||
readonly title = input<string>();
|
readonly title = input<string>();
|
||||||
readonly subtitle = input<string>();
|
readonly subtitle = input<string>();
|
||||||
readonly formGroup = input.required<FormGroup>();
|
readonly formGroup = input.required<FormGroup>();
|
||||||
@@ -72,16 +73,16 @@ export class PiExpansionPanelComponent extends PiBasePanelComponent implements O
|
|||||||
readonly expandableContentRef = contentChild<TemplateRef<unknown>>('expandableContent');
|
readonly expandableContentRef = contentChild<TemplateRef<unknown>>('expandableContent');
|
||||||
|
|
||||||
override ngOnInit(): void {
|
override ngOnInit(): void {
|
||||||
if (this.status() === 'disabled') this.isCollapsed = true;
|
if (this.status() === 'disabled') this.isCollapsed.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges({ status }: SimpleChanges): void {
|
ngOnChanges({ status }: SimpleChanges): void {
|
||||||
if (status?.currentValue === 'disabled') this.isCollapsed = true;
|
if (status?.currentValue === 'disabled') this.isCollapsed.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle(): void {
|
toggle(): void {
|
||||||
const status = this.status();
|
const status = this.status();
|
||||||
if (status !== 'disabled' && status !== 'info') this.isCollapsed = !this.isCollapsed();
|
if (status !== 'disabled' && status !== 'info') this.isCollapsed.set(!this.isCollapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
onEdit(): void {
|
onEdit(): void {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import {
|
|||||||
ElementRef,
|
ElementRef,
|
||||||
HostBinding,
|
HostBinding,
|
||||||
Injector,
|
Injector,
|
||||||
QueryList,
|
|
||||||
Renderer2,
|
Renderer2,
|
||||||
input
|
input
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { toObservable } from '@angular/core/rxjs-interop';
|
||||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -145,8 +145,8 @@ export class PiSelectCarouselComponent extends PiBaseSelectComponent implements
|
|||||||
ngAfterContentInit(): void {
|
ngAfterContentInit(): void {
|
||||||
this.control.setValue(this.selectedOption);
|
this.control.setValue(this.selectedOption);
|
||||||
merge(
|
merge(
|
||||||
this.childrenOptionsComponents()?.changes || [],
|
toObservable(this.childrenOptionsComponents, { injector: this.injector }),
|
||||||
this.viewChildOptionsComponents()?.changes || [],
|
toObservable(this.viewChildOptionsComponents, { injector: this.injector }),
|
||||||
this.control.valueChanges
|
this.control.valueChanges
|
||||||
).subscribe(() => {
|
).subscribe(() => {
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
@@ -180,9 +180,9 @@ export class PiSelectCarouselComponent extends PiBaseSelectComponent implements
|
|||||||
*/
|
*/
|
||||||
private updateChildrenOptionsSelectedState(selectedOption: any): void {
|
private updateChildrenOptionsSelectedState(selectedOption: any): void {
|
||||||
// Array of child option components to work with.
|
// Array of child option components to work with.
|
||||||
let childrenOptionsComponent: Array<PiSelectOptionComponent>;
|
let childrenOptionsComponent: readonly PiSelectOptionComponent[];
|
||||||
// Reference to the child option elements for DOM manipulation.
|
// Reference to the child option elements for DOM manipulation.
|
||||||
let childrenOptionsElementRef: QueryList<ElementRef>;
|
let childrenOptionsElementRef: readonly ElementRef[];
|
||||||
|
|
||||||
// Check if we have child options that are content projected from a parent component.
|
// Check if we have child options that are content projected from a parent component.
|
||||||
const childrenOptionsComponents = this.childrenOptionsComponents();
|
const childrenOptionsComponents = this.childrenOptionsComponents();
|
||||||
@@ -191,7 +191,7 @@ export class PiSelectCarouselComponent extends PiBaseSelectComponent implements
|
|||||||
childrenOptionsElementRef = this.childrenOptionsEl();
|
childrenOptionsElementRef = this.childrenOptionsEl();
|
||||||
} else {
|
} else {
|
||||||
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
||||||
childrenOptionsComponent = this.viewChildOptionsComponents;
|
childrenOptionsComponent = this.viewChildOptionsComponents();
|
||||||
childrenOptionsElementRef = this.viewChildOptionsEl();
|
childrenOptionsElementRef = this.viewChildOptionsEl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,12 +202,12 @@ export class PiSelectCarouselComponent extends PiBaseSelectComponent implements
|
|||||||
: false;
|
: false;
|
||||||
// If the current child option matches the selected option, highlight it.
|
// If the current child option matches the selected option, highlight it.
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
this._renderer.addClass(childrenOptionsElementRef.get(index)?.nativeElement, 'is-selected');
|
this._renderer.addClass(childrenOptionsElementRef[index]?.nativeElement, 'is-selected');
|
||||||
childOption.isSelected.set(true);
|
childOption.isSelected.set(true);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, ensure it is not highlighted.
|
// Otherwise, ensure it is not highlighted.
|
||||||
this._renderer.removeClass(
|
this._renderer.removeClass(
|
||||||
childrenOptionsElementRef.get(index)?.nativeElement,
|
childrenOptionsElementRef[index]?.nativeElement,
|
||||||
'is-selected'
|
'is-selected'
|
||||||
);
|
);
|
||||||
childOption.isSelected.set(false);
|
childOption.isSelected.set(false);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
Renderer2,
|
Renderer2,
|
||||||
input
|
input
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { toObservable } from '@angular/core/rxjs-interop';
|
||||||
import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
||||||
import { merge } from 'rxjs';
|
import { merge } from 'rxjs';
|
||||||
@@ -164,8 +165,8 @@ export class PiSelectMultipleComponent extends PiBaseSelectComponent implements
|
|||||||
ngAfterContentInit(): void {
|
ngAfterContentInit(): void {
|
||||||
this.control.setValue(this.selectedOptions);
|
this.control.setValue(this.selectedOptions);
|
||||||
merge(
|
merge(
|
||||||
this.childrenOptionsComponents()?.changes || [],
|
toObservable(this.childrenOptionsComponents, { injector: this.injector }),
|
||||||
this.viewChildOptionsComponents()?.changes || [],
|
toObservable(this.viewChildOptionsComponents, { injector: this.injector }),
|
||||||
this.control.valueChanges
|
this.control.valueChanges
|
||||||
).subscribe(() => {
|
).subscribe(() => {
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
@@ -244,9 +245,9 @@ export class PiSelectMultipleComponent extends PiBaseSelectComponent implements
|
|||||||
*/
|
*/
|
||||||
private updateChildrenOptionsSelectedState(selectedOptions: any[]): void {
|
private updateChildrenOptionsSelectedState(selectedOptions: any[]): void {
|
||||||
// Array of child option components to work with.
|
// Array of child option components to work with.
|
||||||
let childrenOptionsComponent: Array<PiSelectOptionComponent>;
|
let childrenOptionsComponent: readonly PiSelectOptionComponent[];
|
||||||
// Reference to the child option elements for DOM manipulation.
|
// Reference to the child option elements for DOM manipulation.
|
||||||
let childrenOptionsElementRef: QueryList<ElementRef>;
|
let childrenOptionsElementRef: readonly ElementRef[];
|
||||||
|
|
||||||
// Check if we have child options that are content projected from a parent component.
|
// Check if we have child options that are content projected from a parent component.
|
||||||
const childrenOptionsComponents = this.childrenOptionsComponents();
|
const childrenOptionsComponents = this.childrenOptionsComponents();
|
||||||
@@ -255,7 +256,7 @@ export class PiSelectMultipleComponent extends PiBaseSelectComponent implements
|
|||||||
childrenOptionsElementRef = this.childrenOptionsEl();
|
childrenOptionsElementRef = this.childrenOptionsEl();
|
||||||
} else {
|
} else {
|
||||||
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
||||||
childrenOptionsComponent = this.viewChildOptionsComponents;
|
childrenOptionsComponent = this.viewChildOptionsComponents();
|
||||||
childrenOptionsElementRef = this.viewChildOptionsEl();
|
childrenOptionsElementRef = this.viewChildOptionsEl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,11 +265,11 @@ export class PiSelectMultipleComponent extends PiBaseSelectComponent implements
|
|||||||
(selectedOption) => selectedOption[this.keyIdProperty()] === childOption['id']
|
(selectedOption) => selectedOption[this.keyIdProperty()] === childOption['id']
|
||||||
);
|
);
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
this._renderer.addClass(childrenOptionsElementRef.get(index)?.nativeElement, 'is-selected');
|
this._renderer.addClass(childrenOptionsElementRef[index]?.nativeElement, 'is-selected');
|
||||||
childOption.isSelected.set(true);
|
childOption.isSelected.set(true);
|
||||||
} else {
|
} else {
|
||||||
this._renderer.removeClass(
|
this._renderer.removeClass(
|
||||||
childrenOptionsElementRef.get(index)?.nativeElement,
|
childrenOptionsElementRef[index]?.nativeElement,
|
||||||
'is-selected'
|
'is-selected'
|
||||||
);
|
);
|
||||||
childOption.isSelected.set(false);
|
childOption.isSelected.set(false);
|
||||||
@@ -295,9 +296,9 @@ export class PiSelectMultipleComponent extends PiBaseSelectComponent implements
|
|||||||
// Disable all options if the maximum number of selections has been reached.
|
// Disable all options if the maximum number of selections has been reached.
|
||||||
const disableOthers = selectedOptions.length >= (this.maxLength() || Infinity);
|
const disableOthers = selectedOptions.length >= (this.maxLength() || Infinity);
|
||||||
// Array of child option components to work with.
|
// Array of child option components to work with.
|
||||||
let childrenOptionsComponent: Array<PiSelectOptionComponent>;
|
let childrenOptionsComponent: readonly PiSelectOptionComponent[];
|
||||||
// Reference to the child option elements for DOM manipulation.
|
// Reference to the child option elements for DOM manipulation.
|
||||||
let childrenOptionsElementRef: QueryList<ElementRef>;
|
let childrenOptionsElementRef: readonly ElementRef[];
|
||||||
|
|
||||||
// Check if we have child options that are content projected from a parent component.
|
// Check if we have child options that are content projected from a parent component.
|
||||||
const childrenOptionsComponents = this.childrenOptionsComponents();
|
const childrenOptionsComponents = this.childrenOptionsComponents();
|
||||||
@@ -306,7 +307,7 @@ export class PiSelectMultipleComponent extends PiBaseSelectComponent implements
|
|||||||
childrenOptionsElementRef = this.childrenOptionsEl();
|
childrenOptionsElementRef = this.childrenOptionsEl();
|
||||||
} else {
|
} else {
|
||||||
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
||||||
childrenOptionsComponent = this.viewChildOptionsComponents;
|
childrenOptionsComponent = this.viewChildOptionsComponents();
|
||||||
childrenOptionsElementRef = this.viewChildOptionsEl();
|
childrenOptionsElementRef = this.viewChildOptionsEl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,10 +318,10 @@ export class PiSelectMultipleComponent extends PiBaseSelectComponent implements
|
|||||||
|
|
||||||
const isDisabled = childOption.isDisabled();
|
const isDisabled = childOption.isDisabled();
|
||||||
if ((!isSelected && disableOthers) || isDisabled) {
|
if ((!isSelected && disableOthers) || isDisabled) {
|
||||||
this._renderer.addClass(childrenOptionsElementRef.get(index)?.nativeElement, 'is-disabled');
|
this._renderer.addClass(childrenOptionsElementRef[index]?.nativeElement, 'is-disabled');
|
||||||
} else {
|
} else {
|
||||||
this._renderer.removeClass(
|
this._renderer.removeClass(
|
||||||
childrenOptionsElementRef.get(index)?.nativeElement,
|
childrenOptionsElementRef[index]?.nativeElement,
|
||||||
'is-disabled'
|
'is-disabled'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import {
|
|||||||
HostBinding,
|
HostBinding,
|
||||||
HostListener,
|
HostListener,
|
||||||
Injector,
|
Injector,
|
||||||
QueryList,
|
|
||||||
Renderer2,
|
Renderer2,
|
||||||
input
|
input
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { toObservable } from '@angular/core/rxjs-interop';
|
||||||
import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
||||||
import { merge } from 'rxjs';
|
import { merge } from 'rxjs';
|
||||||
@@ -161,8 +161,8 @@ export class PiSelectPeriodComponent extends PiBaseSelectComponent implements Af
|
|||||||
ngAfterContentInit(): void {
|
ngAfterContentInit(): void {
|
||||||
this.control.setValue(this.selectedOption);
|
this.control.setValue(this.selectedOption);
|
||||||
merge(
|
merge(
|
||||||
this.childrenOptionsComponents()?.changes || [],
|
toObservable(this.childrenOptionsComponents, { injector: this.injector }),
|
||||||
this.viewChildOptionsComponents()?.changes || [],
|
toObservable(this.viewChildOptionsComponents, { injector: this.injector }),
|
||||||
this.control.valueChanges
|
this.control.valueChanges
|
||||||
).subscribe(() => {
|
).subscribe(() => {
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
@@ -192,9 +192,9 @@ export class PiSelectPeriodComponent extends PiBaseSelectComponent implements Af
|
|||||||
*/
|
*/
|
||||||
private updateChildrenOptionsSelectedState(selectedOption: any): void {
|
private updateChildrenOptionsSelectedState(selectedOption: any): void {
|
||||||
// Array of child option components to work with.
|
// Array of child option components to work with.
|
||||||
let childrenOptionsComponent: Array<PiSelectOptionComponent>;
|
let childrenOptionsComponent: readonly PiSelectOptionComponent[];
|
||||||
// Reference to the child option elements for DOM manipulation.
|
// Reference to the child option elements for DOM manipulation.
|
||||||
let childrenOptionsElementRef: QueryList<ElementRef>;
|
let childrenOptionsElementRef: readonly ElementRef[];
|
||||||
|
|
||||||
// Check if we have child options that are content projected from a parent component.
|
// Check if we have child options that are content projected from a parent component.
|
||||||
const childrenOptionsComponents = this.childrenOptionsComponents();
|
const childrenOptionsComponents = this.childrenOptionsComponents();
|
||||||
@@ -203,7 +203,7 @@ export class PiSelectPeriodComponent extends PiBaseSelectComponent implements Af
|
|||||||
childrenOptionsElementRef = this.childrenOptionsEl();
|
childrenOptionsElementRef = this.childrenOptionsEl();
|
||||||
} else {
|
} else {
|
||||||
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
||||||
childrenOptionsComponent = this.viewChildOptionsComponents;
|
childrenOptionsComponent = this.viewChildOptionsComponents();
|
||||||
childrenOptionsElementRef = this.viewChildOptionsEl();
|
childrenOptionsElementRef = this.viewChildOptionsEl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,12 +214,12 @@ export class PiSelectPeriodComponent extends PiBaseSelectComponent implements Af
|
|||||||
: false;
|
: false;
|
||||||
// If the current child option matches the selected option, highlight it.
|
// If the current child option matches the selected option, highlight it.
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
this._renderer.addClass(childrenOptionsElementRef.get(index)?.nativeElement, 'is-selected');
|
this._renderer.addClass(childrenOptionsElementRef[index]?.nativeElement, 'is-selected');
|
||||||
childOption.isSelected.set(true);
|
childOption.isSelected.set(true);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, ensure it is not highlighted.
|
// Otherwise, ensure it is not highlighted.
|
||||||
this._renderer.removeClass(
|
this._renderer.removeClass(
|
||||||
childrenOptionsElementRef.get(index)?.nativeElement,
|
childrenOptionsElementRef[index]?.nativeElement,
|
||||||
'is-selected'
|
'is-selected'
|
||||||
);
|
);
|
||||||
childOption.isSelected.set(false);
|
childOption.isSelected.set(false);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { AfterContentInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, Injector, QueryList, Renderer2, forwardRef, input } from '@angular/core';
|
import { AfterContentInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, Injector, QueryList, Renderer2, forwardRef, input } from '@angular/core';
|
||||||
|
import { toObservable } from '@angular/core/rxjs-interop';
|
||||||
import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
|
||||||
import { merge } from 'rxjs';
|
import { merge } from 'rxjs';
|
||||||
@@ -151,8 +152,8 @@ export class PiSelectComponent extends PiBaseSelectComponent implements AfterCon
|
|||||||
ngAfterContentInit(): void {
|
ngAfterContentInit(): void {
|
||||||
this.control.setValue(this.selectedOption);
|
this.control.setValue(this.selectedOption);
|
||||||
merge(
|
merge(
|
||||||
this.childrenOptionsComponents()?.changes || [],
|
toObservable(this.childrenOptionsComponents, { injector: this.injector }),
|
||||||
this.viewChildOptionsComponents()?.changes || [],
|
toObservable(this.viewChildOptionsComponents, { injector: this.injector }),
|
||||||
this.control.valueChanges
|
this.control.valueChanges
|
||||||
).subscribe(() => {
|
).subscribe(() => {
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
@@ -182,9 +183,9 @@ export class PiSelectComponent extends PiBaseSelectComponent implements AfterCon
|
|||||||
*/
|
*/
|
||||||
private updateChildrenOptionsSelectedState(selectedOption: any): void {
|
private updateChildrenOptionsSelectedState(selectedOption: any): void {
|
||||||
// Array of child option components to work with.
|
// Array of child option components to work with.
|
||||||
let childrenOptionsComponent: Array<PiSelectOptionComponent>;
|
let childrenOptionsComponent: readonly PiSelectOptionComponent[];
|
||||||
// Reference to the child option elements for DOM manipulation.
|
// Reference to the child option elements for DOM manipulation.
|
||||||
let childrenOptionsElementRef: QueryList<ElementRef>;
|
let childrenOptionsElementRef: readonly ElementRef[];
|
||||||
|
|
||||||
// Check if we have child options that are content projected from a parent component.
|
// Check if we have child options that are content projected from a parent component.
|
||||||
const childrenOptionsComponents = this.childrenOptionsComponents();
|
const childrenOptionsComponents = this.childrenOptionsComponents();
|
||||||
@@ -193,7 +194,7 @@ export class PiSelectComponent extends PiBaseSelectComponent implements AfterCon
|
|||||||
childrenOptionsElementRef = this.childrenOptionsEl();
|
childrenOptionsElementRef = this.childrenOptionsEl();
|
||||||
} else {
|
} else {
|
||||||
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
// If not, it means they're internally defined (default), so we fetch from viewChildren.
|
||||||
childrenOptionsComponent = this.viewChildOptionsComponents;
|
childrenOptionsComponent = this.viewChildOptionsComponents();
|
||||||
childrenOptionsElementRef = this.viewChildOptionsEl();
|
childrenOptionsElementRef = this.viewChildOptionsEl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,11 +205,11 @@ export class PiSelectComponent extends PiBaseSelectComponent implements AfterCon
|
|||||||
: false;
|
: false;
|
||||||
// If the current child option matches the selected option, highlight it.
|
// If the current child option matches the selected option, highlight it.
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
this._renderer.addClass(childrenOptionsElementRef.get(index)?.nativeElement, 'is-selected');
|
this._renderer.addClass(childrenOptionsElementRef[index]?.nativeElement, 'is-selected');
|
||||||
childOption.isSelected.set(true);
|
childOption.isSelected.set(true);
|
||||||
} else { // Otherwise, ensure it is not highlighted.
|
} else { // Otherwise, ensure it is not highlighted.
|
||||||
this._renderer.removeClass(
|
this._renderer.removeClass(
|
||||||
childrenOptionsElementRef.get(index)?.nativeElement,
|
childrenOptionsElementRef[index]?.nativeElement,
|
||||||
'is-selected'
|
'is-selected'
|
||||||
);
|
);
|
||||||
childOption.isSelected.set(false);
|
childOption.isSelected.set(false);
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
AfterViewChecked,
|
AfterViewChecked,
|
||||||
AfterViewInit,
|
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
HostBinding,
|
HostBinding,
|
||||||
Input,
|
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
Renderer2,
|
Renderer2,
|
||||||
|
effect,
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
contentChildren,
|
contentChildren,
|
||||||
@@ -37,7 +36,7 @@ import { TranslatePipe } from '@ngx-translate/core';
|
|||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class PiTabComponent implements AfterViewInit, AfterViewChecked, OnDestroy {
|
export class PiTabComponent implements AfterViewChecked, OnDestroy {
|
||||||
@HostBinding('class') get classes(): string {
|
@HostBinding('class') get classes(): string {
|
||||||
const appearanceClass = `pi-tab__appearance--${this.appearance()}`;
|
const appearanceClass = `pi-tab__appearance--${this.appearance()}`;
|
||||||
const hideTabsClass = this.hideTabs() ? 'hide-tabs' : '';
|
const hideTabsClass = this.hideTabs() ? 'hide-tabs' : '';
|
||||||
@@ -106,11 +105,9 @@ export class PiTabComponent implements AfterViewInit, AfterViewChecked, OnDestro
|
|||||||
return isTabWrapperOverflowing;
|
return isTabWrapperOverflowing;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
// El ngAfterViewInit original sólo suscribía a tabContentItems.changes para
|
||||||
this.tabContentItems().changes.subscribe(() => {
|
// hacer markForCheck(); como ahora es una signal query, Angular ya reevalúa
|
||||||
this.cdr.markForCheck();
|
// la plantilla cuando cambia.
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewChecked(): void {
|
ngAfterViewChecked(): void {
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Directive, HostBinding, OnChanges, SimpleChanges, input } from '@angular/core';
|
import { Directive, HostBinding, input } from '@angular/core';
|
||||||
|
|
||||||
@Directive({ selector: '[pi-text-centered]', })
|
@Directive({ selector: '[pi-text-centered]', })
|
||||||
export class PiTextCenteredDirective {
|
export class PiTextCenteredDirective {
|
||||||
@@ -14,17 +14,13 @@ export class PiTextGroupDirective {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Directive({ selector: '[pi-disabled]', })
|
@Directive({ selector: '[pi-disabled]', })
|
||||||
export class PiDisabledDirective implements OnChanges {
|
export class PiDisabledDirective {
|
||||||
@HostBinding('style.opacity') get opacity(): number {
|
@HostBinding('style.opacity') get opacity(): number {
|
||||||
return this.isDisabled() ? 0.2 : 1;
|
return this.isDisabled() ? 0.2 : 1;
|
||||||
}
|
}
|
||||||
|
// El ngOnChanges original sólo reasignaba a la entrada su propio
|
||||||
|
// currentValue (no-op). Con signal inputs sobra.
|
||||||
readonly isDisabled = input<boolean>();
|
readonly isDisabled = input<boolean>();
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
|
||||||
if (changes) {
|
|
||||||
this.isDisabled = changes['isDisabled'].currentValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({ selector: '[pi-covered]', })
|
@Directive({ selector: '[pi-covered]', })
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { Directive, OnChanges, HostBinding, SimpleChanges, input } from '@angular/core';
|
import { Directive, HostBinding, input } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Los `ngOnChanges` originales sólo reasignaban a la entrada su propio
|
||||||
|
* `currentValue`, es decir, eran no-ops. Con signal inputs sobran.
|
||||||
|
*/
|
||||||
|
|
||||||
@Directive({ selector: '[pi-disabled]', })
|
@Directive({ selector: '[pi-disabled]', })
|
||||||
export class PiDisabledDirective implements OnChanges {
|
export class PiDisabledDirective {
|
||||||
@HostBinding('style.opacity') get opacity(): number {
|
@HostBinding('style.opacity') get opacity(): number {
|
||||||
return this.isDisabled() ? 0.33 : 1;
|
return this.isDisabled() ? 0.33 : 1;
|
||||||
}
|
}
|
||||||
@@ -10,12 +15,6 @@ export class PiDisabledDirective implements OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly isDisabled = input<boolean>();
|
readonly isDisabled = input<boolean>();
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
|
||||||
if (changes) {
|
|
||||||
this.isDisabled = changes['isDisabled'].currentValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({ selector: '[is-active]', })
|
@Directive({ selector: '[is-active]', })
|
||||||
@@ -25,12 +24,6 @@ export class PiIsActiveDirective {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly isActive = input.required<boolean>();
|
readonly isActive = input.required<boolean>();
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
|
||||||
if (changes) {
|
|
||||||
this.isActive = changes['isActive'].currentValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({ selector: '[is-visited]', })
|
@Directive({ selector: '[is-visited]', })
|
||||||
@@ -40,10 +33,4 @@ export class PiIsVisitedDirective {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly isVisited = input.required<boolean>();
|
readonly isVisited = input.required<boolean>();
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
|
||||||
if (changes) {
|
|
||||||
this.isVisited = changes['isVisited'].currentValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user