Tabs

Tabs are used to switch between different views.

The <dt-tab-group> wraps a group of <dt-tab> components. Each tab gets a label and a content respectively. The label is provided with a ng-template with the directive dtTabLabel. The content is also declared with a ng-template, but with a directive called dtTabContent. By default the first enabled tab gets selected if no selected tab is specified.

´ Loading interactive demo...
<dt-tab-group> <dt-tab> <ng-template dtTabLabel>Traffic</ng-template> <ng-template dtTabContent> <h3>Traffic</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>Packets</ng-template> <ng-template dtTabContent> <h3>Packets</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>Quality</ng-template> <ng-template dtTabContent> <h3>Quality</h3> </ng-template> </dt-tab> </dt-tab-group> export class TabsPureExample {} <dt-tab-group> <dt-tab> <ng-template dtTabLabel>Traffic</ng-template> <ng-template dtTabContent> <h3>Traffic</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>Packets</ng-template> <ng-template dtTabContent> <h3>Packets</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>Quality</ng-template> <ng-template dtTabContent> <h3>Quality</h3> </ng-template> </dt-tab> </dt-tab-group> export class TabsPureExample {}

Imports

You have to import the DtTabsModule when you want to use the <dt-tab-group>:

@NgModule({
  imports: [DtTabsModule],
})
class MyModule {}

Initialization

To use the Dynatrace tabs, add the following components/directives:

Attribute Description
dt-tab-group wrapping container for dt-tabs
dt-tab definition for one tab containing a label and content
ng-template dtTabLabel label definition for one tab
ng-template dtTabContent content definition for one tab

DtTabGroup outputs

Name Type Default Description
selectionChanged EventEmitter<DtTabChange> Event emitted when the selected tab changes, includes the selected tab instance

DtTabGroup inputs

Name Type Default Description
selected boolean | undefined undefined Sets the selected state if property is set and the value is truthy or undefined
disabled boolean | undefined undefined Sets disable state if property is set and the value is truthy or undefined
color string | undefined main Sets color. Possible options:
  • main (default)
  • recovered
  • error
tabindex number 0 Tabindexof the tab.
id string The id of the tab.
aria-label string Aria label of the tab.

Tabgroups come with support for storing the selected tab for navigation purposes. You can enable navigation for a dt-tab-group by adding the dtTabGroupNavigation directive. The selected tab gets stored only on user interaction. If an id of a dt-tab matches an id stored inside the DtTabNavigationAdapter the tab gets selected. Ids stored in the DtTabNavigationAdapter take presedence over the selected attribute on the dt-tab component.

<dt-tab-group dtTabGroupNavigation>
  <dt-tab id="traffic">
    <ng-template dtTabLabel>Traffic</ng-template>
    <ng-template dtTabContent>
      <h1>Traffic</h1>
    </ng-template>
  </dt-tab>
  <dt-tab id="quality">
    <ng-template dtTabLabel>Quality</ng-template>
    <ng-template dtTabContent>
      <h1>Quality</h1>
    </ng-template>
  </dt-tab>
</dt-tab-group>

The DtTabModule comes with a DtTabRouterFragmentAdapter service that stores the id of the selected dt-tab inside the url fragment. If you want to implement your own logic of storing the selected tab ids, e.g. in localStorage - you need to implement the abstract class DtTabNavigationAdapter yourself.

Make sure to provide a DtTabNavigationAdapter with its dependencies in the root of your application. E.g.

...
providers: [
  { provide: DtTabNavigationAdapter,
    useClass: DtTabRouterFragmentAdapter,
    deps: [Router, ActivatedRoute, Location, LocationStrategy],
  },
],
...

Theming

The button styling depends on the theme the component is in. You can set a theme on an area of the app by using the dtTheme directive.

States

Additionally to their default state tabs can be disabled, in an error- or recovered-state.

´ Loading interactive demo...
<dt-tab-group> <dt-tab disabled> <ng-template dtTabLabel>Traffic</ng-template> <ng-template dtTabContent> <h3>Traffic</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>Packets</ng-template> <ng-template dtTabContent> <h3>Packets</h3> </ng-template> </dt-tab> <dt-tab color="error"> <ng-template dtTabLabel>Quality</ng-template> <ng-template dtTabContent> <h3>Quality</h3> </ng-template> </dt-tab> <dt-tab color="recovered"> <ng-template dtTabLabel>Connectivity</ng-template> <ng-template dtTabContent> <h3>Connectivity</h3> </ng-template> </dt-tab> </dt-tab-group> export class TabsDefaultExample {} <dt-tab-group> <dt-tab disabled> <ng-template dtTabLabel>Traffic</ng-template> <ng-template dtTabContent> <h3>Traffic</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>Packets</ng-template> <ng-template dtTabContent> <h3>Packets</h3> </ng-template> </dt-tab> <dt-tab color="error"> <ng-template dtTabLabel>Quality</ng-template> <ng-template dtTabContent> <h3>Quality</h3> </ng-template> </dt-tab> <dt-tab color="recovered"> <ng-template dtTabLabel>Connectivity</ng-template> <ng-template dtTabContent> <h3>Connectivity</h3> </ng-template> </dt-tab> </dt-tab-group> export class TabsDefaultExample {}

Problem indicator

If content in a tab is problematic the tab box as well as the text are red. If content in a tab has recovered the tab item is green.

´ Loading interactive demo...
<dt-tab-group> <dt-tab> <ng-template dtTabLabel>Physical CPU</ng-template> <ng-template dtTabContent> <h3>Physical CPUs content</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>CPU ready time</ng-template> <ng-template dtTabContent> <h3>cpu-ready-time content</h3> </ng-template> </dt-tab> <dt-tab *ngIf="hasProblems" color="error"> <ng-template dtTabLabel>11 problems</ng-template> <ng-template dtTabContent> <h3>Housten we have 11 problems!</h3> </ng-template> </dt-tab> </dt-tab-group> <button dt-button (click)="hasProblems = !hasProblems"> Toggle problems </button> export class TabsDynamicExample { hasProblems = false; } <dt-tab-group> <dt-tab> <ng-template dtTabLabel>Physical CPU</ng-template> <ng-template dtTabContent> <h3>Physical CPUs content</h3> </ng-template> </dt-tab> <dt-tab> <ng-template dtTabLabel>CPU ready time</ng-template> <ng-template dtTabContent> <h3>cpu-ready-time content</h3> </ng-template> </dt-tab> <dt-tab *ngIf="hasProblems" color="error"> <ng-template dtTabLabel>11 problems</ng-template> <ng-template dtTabContent> <h3>Housten we have 11 problems!</h3> </ng-template> </dt-tab> </dt-tab-group> <button dt-button (click)="hasProblems = !hasProblems"> Toggle problems </button> export class TabsDynamicExample { hasProblems = false; }

Dos and Don'ts

Abbreviation of long tab names

Do - abbreviate with ...
Do
Abbreviate long names with "..."
Don't - use multiple lines
Don't
Don't use more than one line for tabs.

Single tabs

Do - use headline instead of tab
Do
Don't - use a single tab
Don't

Interactive Tabs

´ Loading interactive demo...
<dt-tab-group> <dt-tab [disabled]="disableFirst"> <ng-template dtTabLabel>Traffic</ng-template> <ng-template dtTabContent> <h3>Traffic</h3> </ng-template> </dt-tab> <dt-tab [color]="simulatedColor" selected> <ng-template dtTabLabel>Connectivity {{ connectivity }}</ng-template> <ng-template dtTabContent> <h3>Connectivity</h3> </ng-template> </dt-tab> </dt-tab-group> <button dt-button (click)="disableFirst = !disableFirst"> Toggle disable for first tab </button> <button dt-button [disabled]="simulationRunning" (click)="simulateError()"> Simulate Error </button> export class TabsInteractiveExample { simulatedColor = 'main'; simulationRunning = false; disableFirst = false; connectivity = '100%'; simulateError(): void { this.simulatedColor = 'error'; this.simulationRunning = true; this.connectivity = '30%'; // tslint:disable-next-line:no-magic-numbers timer(1000, 1000) // tslint:disable-next-line:no-magic-numbers .pipe(take(2)) .subscribe( () => { this.simulatedColor = this.simulatedColor === 'error' ? 'recovered' : 'main'; this.connectivity = '80%'; }, () => {}, () => { this.simulationRunning = false; this.connectivity = '100%'; }, ); } } <dt-tab-group> <dt-tab [disabled]="disableFirst"> <ng-template dtTabLabel>Traffic</ng-template> <ng-template dtTabContent> <h3>Traffic</h3> </ng-template> </dt-tab> <dt-tab [color]="simulatedColor" selected> <ng-template dtTabLabel>Connectivity {{ connectivity }}</ng-template> <ng-template dtTabContent> <h3>Connectivity</h3> </ng-template> </dt-tab> </dt-tab-group> <button dt-button (click)="disableFirst = !disableFirst"> Toggle disable for first tab </button> <button dt-button [disabled]="simulationRunning" (click)="simulateError()"> Simulate Error </button> export class TabsInteractiveExample { simulatedColor = 'main'; simulationRunning = false; disableFirst = false; connectivity = '100%'; simulateError(): void { this.simulatedColor = 'error'; this.simulationRunning = true; this.connectivity = '30%'; // tslint:disable-next-line:no-magic-numbers timer(1000, 1000) // tslint:disable-next-line:no-magic-numbers .pipe(take(2)) .subscribe( () => { this.simulatedColor = this.simulatedColor === 'error' ? 'recovered' : 'main'; this.connectivity = '80%'; }, () => {}, () => { this.simulationRunning = false; this.connectivity = '100%'; }, ); } }