migrated `@Input` to `model`

uif/CL-999/update-tabs
Leslie Xiong 1 week ago
parent 427cda87c4
commit 522f091875
No known key found for this signature in database
GPG Key ID: 12CF833220CA1903

@ -36,9 +36,9 @@
[id]="getTabLabelId(i)"
[active]="tab.isActive()"
[disabled]="tab.disabled()"
[attr.aria-selected]="selectedIndex === i"
[attr.aria-selected]="selectedIndex() === i"
[hidden]="i > 0 && overflowTabIndex() !== undefined && i >= overflowTabIndex()!"
[attr.tabindex]="selectedIndex === i ? 0 : -1"
[attr.tabindex]="selectedIndex() === i ? 0 : -1"
[class.tw-flex-1]="truncate"
[class.tw-overflow-hidden]="truncate"
(click)="selectTab(i)"

@ -1,16 +1,15 @@
import { FocusKeyManager } from "@angular/cdk/a11y";
import { coerceNumberProperty } from "@angular/cdk/coercion";
import { NgTemplateOutlet } from "@angular/common";
import {
AfterContentChecked,
AfterViewInit,
Component,
Input,
afterNextRender,
contentChild,
contentChildren,
effect,
input,
model,
output,
viewChild,
viewChildren,
@ -58,7 +57,6 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit {
private readonly resizeObserver: ResizeObserver;
private readonly _groupId: number;
private readonly _indexToSelect = signal<number | null>(0);
/**
* Aria label for the tab list menu
@ -123,22 +121,10 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit {
return undefined;
});
/** The index of the active tab. */
// TODO: Skipped for signal migration because:
// Accessor inputs cannot be migrated as they are too complex.
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
get selectedIndex(): number | null {
return this._selectedIndex();
}
set selectedIndex(value: number) {
this._indexToSelect.set(coerceNumberProperty(value, null));
}
private readonly _selectedIndex = signal<number | null>(null);
/** The index of the active tab. Supports two-way binding via `[(selectedIndex)]`. */
readonly selectedIndex = model(0);
/** Output to enable support for two-way binding on `[(selectedIndex)]` */
readonly selectedIndexChange = output<number>();
private readonly _selectedIndex = signal<number | null>(null);
/** Event emitted when the tab selection has changed. */
readonly selectedTabChange = output<BitTabChangeEvent>();
@ -165,7 +151,7 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit {
});
effect(() => {
const indexToSelect = this._clampTabIndex(this._indexToSelect() ?? 0);
const indexToSelect = this._clampTabIndex(this.selectedIndex());
// If the selected tab didn't explicitly change, keep the previously
// selected tab selected/active
@ -175,10 +161,10 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit {
for (let i = 0; i < tabs.length; i++) {
if (tabs[i].isActive()) {
// Set both _indexToSelect and _selectedIndex to avoid firing a change
// Set both selectedIndex and _selectedIndex to avoid firing a change
// event which could cause an infinite loop if adding a tab within the
// selectedIndexChange event
this._indexToSelect.set(i);
// selectedIndex change event
this.selectedIndex.set(i);
this._selectedIndex.set(i);
selectedTab = tabs[i];
break;
@ -207,7 +193,7 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit {
}
selectTab(index: number) {
this.selectedIndex = index;
this.selectedIndex.set(index);
}
/**
@ -215,8 +201,8 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit {
* should be currently selected.
*/
ngAfterContentChecked(): void {
const indexToSelect = this._clampTabIndex(this._indexToSelect() ?? 0);
this._indexToSelect.set(indexToSelect);
const indexToSelect = this._clampTabIndex(this.selectedIndex());
this.selectedIndex.set(indexToSelect);
if (this._selectedIndex() != indexToSelect) {
const isFirstRun = this._selectedIndex() == null;
@ -234,10 +220,6 @@ export class TabGroupComponent implements AfterContentChecked, AfterViewInit {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Promise.resolve().then(() => {
this.tabs().forEach((tab, index) => tab.isActive.set(index === indexToSelect));
if (!isFirstRun) {
this.selectedIndexChange.emit(indexToSelect);
}
});
// Manually update the _selectedIndex and keyManager active item

Loading…
Cancel
Save