feat(tabs): provide the ability to render a tabpanel outside the tabset#1576
feat(tabs): provide the ability to render a tabpanel outside the tabset#1576
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the SiTabContentComponent to allow rendering tab content outside the SiTabsetComponent. It also updates the SiTabsetComponent to handle external content and adds corresponding tests. The changes enhance the flexibility of the tabs component. Feedback includes suggestions for improving the efficiency of signal computations, ensuring robustness in ARIA attribute handling, and adding a default case to a switch statement for better error handling.
| effect(() => { | ||
| const contentRef = this.content(); | ||
| const active = this.activeTab(); | ||
| if (contentRef) { | ||
| contentRef.panelId.set(active ? `content-${active.tabId}` : undefined); | ||
| contentRef.labelledBy.set(active ? `tab-${active.tabId}` : undefined); | ||
| } |
There was a problem hiding this comment.
The effect that pushes ARIA attributes to the external content component relies on active.tabId. If active is undefined, accessing active.tabId will result in an error. Add a check to ensure active is defined before accessing its properties.
Also, consider using takeUntilDestroyed to automatically unsubscribe from the effect when the component is destroyed to prevent memory leaks.
effect(() => {
const contentRef = this.content();
const active = this.activeTab();
if (contentRef && active) { // Add check for active
contentRef.panelId.set( `content-${active.tabId}` );
contentRef.labelledBy.set(`tab-${active.tabId}`);
} else {
contentRef?.panelId.set(undefined);
contentRef?.labelledBy.set(undefined);
}
});| readonly activeIndex = computed(() => { | ||
| const active = this.activeTab(); | ||
| return active ? this.tabPanels().indexOf(active) : -1; |
There was a problem hiding this comment.
The activeIndex computed signal calculates the index of the active tab. If no tab is active, it returns -1. This is good. However, if the tabPanels signal changes (e.g., a tab is added or removed), this computation might trigger unnecessarily, even if the active tab hasn't changed. Consider memoizing the tabPanels signal or using a more efficient way to track the active index to avoid redundant computations.
Consider using computed(() => this.tabPanels().findIndex(tab => tab.active())) for efficiency.
| @switch (tabset.activeIndex()) { | ||
| @case (0) { | ||
| {{ selectedEntity | json }} | ||
| } | ||
| @case (1) { | ||
| <div class="mx-auto text-center">History for {{ selectedEntity.name }}</div> | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.