I am interested in creating a custom Tabs component that has the ability to display content from [root] within itself. It functions perfectly when using selectors in html tags (<tab1>
), but there are instances where the selector is unknown. Since Tabs act as components, I need a method to render the component onto the view.
In my Tab.ts file, the goal is to show the root component inside the viewport
@Component({
selector: 'tab',
template:
`<div [hidden]="!active">
<ng-content></ng-content>
</div>`
})
export class Tab {
@Input('tabTitle') title: string;
@Input() active = false;
@Input('root') root: any;
}
Next, we have the Tabs.ts which connects tabs together (allowing for easy switching between them)
@Component({
selector: 'tabs',
template:
`<div class="tabbar">
<div class="tab-button" *ngFor="let tab of tabs" (click)="selectTab(tab)">
<a href="#">{{tab.title}}</a>
</div>
</div>
<ng-content></ng-content>`
})
export class Tabs implements AfterContentInit {
@ContentChildren(Tab) tabs: QueryList<Tab>;
ngAfterContentInit() {
let activeTabs = this.tabs.filter((tab) => tab.active);
if (activeTabs.length === 0) {
this.selectTab(this.tabs.first);
}
}
selectTab(tab: Tab) {
this.tabs.forEach(tab => tab.active = false);
tab.active = true;
if (this.menu) {
this.menu.active = false;
}
}
}
Here is a template that allows for the use of tabs and works consistently
<tabs>
<tab tabTitle="Tab 1">
<tab-home></tab-home>
</tab>
<tab tabTitle="Tab 2">
<tab-second></tab-second>
</tab>
<tab tabTitle="Tab 3">
Tab 3 content
</tab>
</tabs>
My ultimate goal is to achieve this structure:
<tabs>
<tab *ngFor="let tab of tabs" [title]="tab.title">
{{ tab.component }}
</tab>
</tabs>
Rather than using tab.component, I aim to display the rendered view of the component without specifying a directive. This way, I can inject the rendered view from the component into the template regardless of what the directive may be.