Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api-goldens/element-ng/tabs/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ElementRef } from '@angular/core';
import { FocusableOption } from '@angular/cdk/a11y';
import { FocusKeyManager } from '@angular/cdk/a11y';
import * as i1 from '@angular/router';
import * as i2 from '@siemens/element-ng/tooltip';
import { OnDestroy } from '@angular/core';
import { RouterLink } from '@angular/router';
import { RouterLinkActive } from '@angular/router';
Expand All @@ -19,6 +20,7 @@ import { TranslatableString } from '@siemens/element-translate-ng/translate';

// @public
export class SiTabComponent extends SiTabBaseDirective implements OnDestroy {
constructor();
readonly active: _angular_core.ModelSignal<boolean>;
readonly canActivate: _angular_core.InputSignal<(() => boolean) | undefined>;
readonly canDeactivate: _angular_core.InputSignal<(() => boolean) | undefined>;
Expand All @@ -28,6 +30,7 @@ export class SiTabComponent extends SiTabBaseDirective implements OnDestroy {

// @public
export class SiTabLinkComponent extends SiTabBaseDirective {
constructor();
// (undocumented)
readonly active: _angular_core.Signal<boolean | undefined>;
// (undocumented)
Expand Down
3 changes: 2 additions & 1 deletion api-goldens/element-ng/tooltip/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import { Type } from '@angular/core';
export class SiTooltipDirective implements OnDestroy {
readonly isDisabled: i0.InputSignalWithTransform<boolean, unknown>;
readonly placement: i0.InputSignal<"auto" | "top" | "start" | "end" | "bottom">;
readonly siTooltip: i0.InputSignal<TemplateRef<any> | TranslatableString>;
setTooltipContent(content: TranslatableString | TemplateRef<any>): void;
readonly siTooltip: i0.ModelSignal<TemplateRef<any> | TranslatableString>;
readonly tooltipContext: i0.InputSignal<unknown>;
}

Expand Down
12 changes: 12 additions & 0 deletions playwright/e2e/element-examples/si-tabs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ test.describe('si-tabs', () => {
const example = 'si-tabs/si-tabs';
const routingExample = 'si-tabs/si-tabs-routing';
const iconsExample = 'si-tabs/si-tabs-icons';
const routingIconsExample = 'si-tabs/si-tabs-routing-icons';

test(example, async ({ page, si }) => {
await si.visitExample(example);
Expand Down Expand Up @@ -61,6 +62,17 @@ test.describe('si-tabs', () => {

test(example + ' icons', async ({ page, si }) => {
await si.visitExample(iconsExample);
await expect(page.getByRole('tab', { name: 'Lobby' })).toBeVisible();
await page.getByRole('tab', { name: 'Lobby' }).click();
await expect(page.getByText('Content for Lobby')).toBeVisible();
await si.runVisualAndA11yTests('tabs-icons');
});

test(example + ' routing icons', async ({ page, si }) => {
await si.visitExample(routingIconsExample);
await expect(page.getByRole('tab', { name: 'Home' })).toBeVisible();
await page.getByRole('tab', { name: 'Home' }).click();
await expect(page.getByText('This is the home page')).toBeVisible();
await si.runVisualAndA11yTests('tabs-routing-icons');
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
- tablist:
- tab /\d+/ [selected]
- tab
- tab
- tab "1"
- tabpanel /\d+/:
- paragraph: Content for Reception
- tab /Reception \d+/
- tab "Conference"
- tab "Lobby" [selected]
- tab "Pantry 1"
- tabpanel "Lobby":
- paragraph: Content for Lobby
- tooltip "Lobby"
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- tablist:
- tab "Home" [selected]
- tab "Energy"
- tab "Test coverage"
- tabpanel "Home": This is the home page
- tooltip "Home"
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 9 additions & 6 deletions projects/element-ng/tabs/si-tab-link.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
* Copyright (c) Siemens 2016 - 2025
* SPDX-License-Identifier: MIT
*/
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { ChangeDetectionStrategy, Component, effect, inject } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { Router, RouterLink, RouterLinkActive } from '@angular/router';
import { SiIconComponent } from '@siemens/element-ng/icon';
import { SiTooltipDirective } from '@siemens/element-ng/tooltip';
import { SiTranslatePipe } from '@siemens/element-translate-ng/translate';
import { startWith } from 'rxjs/operators';

Expand All @@ -32,13 +33,10 @@ import { SiTabBaseDirective } from './si-tab-base.directive';
styleUrl: './si-tab.component.scss',
providers: [{ provide: SiTabBaseDirective, useExisting: SiTabLinkComponent }],
changeDetection: ChangeDetectionStrategy.OnPush,
hostDirectives: [
{
directive: RouterLinkActive
}
]
hostDirectives: [RouterLinkActive, SiTooltipDirective]
})
export class SiTabLinkComponent extends SiTabBaseDirective {
private tooltipDirective = inject(SiTooltipDirective);
private router = inject(Router);
/** @internal */
routerLink = inject(RouterLink, { self: true });
Expand All @@ -59,4 +57,9 @@ export class SiTabLinkComponent extends SiTabBaseDirective {
}
super.selectTab(retainFocus);
}

constructor() {
super();
effect(() => this.tooltipDirective.setTooltipContent(this.icon() ? this.heading() : ''));
}
}
2 changes: 1 addition & 1 deletion projects/element-ng/tabs/si-tab.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@let icon = this.icon();
@if (icon) {
<si-icon class="tab-icon" [icon]="icon" [attr.title]="heading() | translate" />
<si-icon class="tab-icon" [icon]="icon" [attr.aria-label]="heading() | translate" />
} @else {
<span class="text-truncate">{{ heading() | translate }}</span>
}
Expand Down
21 changes: 19 additions & 2 deletions projects/element-ng/tabs/si-tab.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@
* Copyright (c) Siemens 2016 - 2025
* SPDX-License-Identifier: MIT
*/
import { ChangeDetectionStrategy, Component, input, model, OnDestroy } from '@angular/core';
import {
ChangeDetectionStrategy,
Component,
effect,
inject,
input,
model,
OnDestroy
} from '@angular/core';
import { SiIconComponent } from '@siemens/element-ng/icon';
import { SiTooltipDirective } from '@siemens/element-ng/tooltip';
import { SiTranslatePipe } from '@siemens/element-translate-ng/translate';

import { SiTabBadgeComponent } from './si-tab-badge.component';
Expand Down Expand Up @@ -31,9 +40,12 @@ import { SiTabBaseDirective } from './si-tab-base.directive';
host: {
'(click)': 'selectTabByUser()',
'(keydown.enter)': 'selectTabByUser()'
}
},
hostDirectives: [SiTooltipDirective]
})
export class SiTabComponent extends SiTabBaseDirective implements OnDestroy {
private tooltipDirective = inject(SiTooltipDirective);

/**
* Whether the tab is active or not.
* If set to `true`, the tab will be selected and its content will be displayed.
Expand Down Expand Up @@ -77,4 +89,9 @@ export class SiTabComponent extends SiTabBaseDirective implements OnDestroy {
override deSelectTab(): void {
this.active.set(false);
}

constructor() {
super();
effect(() => this.tooltipDirective.setTooltipContent(this.icon() ? this.heading() : ''));
}
}
11 changes: 10 additions & 1 deletion projects/element-ng/tooltip/si-tooltip.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ElementRef,
inject,
input,
model,
OnDestroy,
TemplateRef
} from '@angular/core';
Expand Down Expand Up @@ -36,7 +37,7 @@ export class SiTooltipDirective implements OnDestroy {
*
* @defaultValue ''
*/
readonly siTooltip = input<TranslatableString | TemplateRef<any>>('');
readonly siTooltip = model<TranslatableString | TemplateRef<any>>('');

/**
* The placement of the tooltip. One of 'top', 'start', end', 'bottom'
Expand Down Expand Up @@ -69,6 +70,14 @@ export class SiTooltipDirective implements OnDestroy {
this.tooltipRef?.destroy();
}

/**
* Update the tooltip content.
* Can be used by components that use the tooltip directive via `hostDirectives`.
*/
setTooltipContent(content: TranslatableString | TemplateRef<any>): void {
this.siTooltip.set(content);
}

private clearShowTimeout(): void {
if (this.showTimeout) {
clearTimeout(this.showTimeout);
Expand Down
4 changes: 2 additions & 2 deletions src/app/examples/si-tabs/si-tabs-arrow.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
<si-tab heading="Eleven">
<p class="mt-4">Content Eleven</p>
</si-tab>
<si-tab icon="element-favorites-filled" heading="Favorites">
<si-tab heading="Favorites">
<p class="mt-4">Some content</p>
</si-tab>
<si-tab icon="element-alarm-filled" heading="notifications" badgeColor="danger" badgeContent="5">
<si-tab heading="Notifications" badgeColor="danger" badgeContent="5">
<p class="mt-4">Some other content</p>
</si-tab>
</si-tabset>
5 changes: 2 additions & 3 deletions src/app/examples/si-tabs/si-tabs-flex.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
<si-tab heading="Basic title" class="flex-scroll">
<p class="mt-4">Basic content</p>
</si-tab>
<si-tab icon="element-favorites-filled" heading="Favorites" class="flex-scroll">
<si-tab heading="Favorites" class="flex-scroll">
<p class="mt-4">Basic content 2</p>
</si-tab>
<si-tab
icon="element-alarm-filled"
heading="notifications"
heading="Notifications"
badgeColor="danger"
badgeContent="5"
class="flex-scroll"
Expand Down
7 changes: 7 additions & 0 deletions src/app/examples/si-tabs/si-tabs-routing-icons.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<si-tabset>
<a si-tab heading="Home" icon="element-home" [routerLink]="tabLink1"></a>
<a si-tab heading="Energy" icon="element-power" [routerLink]="tabLink2"></a>
<a si-tab heading="Test coverage" icon="element-alchemy-flask" [routerLink]="tabLink3"></a>

<router-outlet />
</si-tabset>
Loading
Loading