diff --git a/CHANGELOG.md b/CHANGELOG.md
index a67ced1b8..5b9af6f4d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## Unreleased
+
+### Changed
+
+- Extended the toggle component to support icons
+
## 3.46.0 - 2026-08-09
### Added
diff --git a/apps/client/src/app/components/home-holdings/home-holdings.component.ts b/apps/client/src/app/components/home-holdings/home-holdings.component.ts
index bae154607..2a06f47ab 100644
--- a/apps/client/src/app/components/home-holdings/home-holdings.component.ts
+++ b/apps/client/src/app/components/home-holdings/home-holdings.component.ts
@@ -3,12 +3,15 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import {
AssetProfileIdentifier,
PortfolioPosition,
- ToggleOption,
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
-import { HoldingType, HoldingsViewMode } from '@ghostfolio/common/types';
+import {
+ HoldingType,
+ HoldingsViewMode,
+ ToggleOption
+} from '@ghostfolio/common/types';
import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table';
import { DataService } from '@ghostfolio/ui/services';
import { GfToggleComponent } from '@ghostfolio/ui/toggle';
diff --git a/apps/client/src/app/components/markets/markets.component.ts b/apps/client/src/app/components/markets/markets.component.ts
index 27f60d86a..7c69fede0 100644
--- a/apps/client/src/app/components/markets/markets.component.ts
+++ b/apps/client/src/app/components/markets/markets.component.ts
@@ -5,11 +5,10 @@ import {
HistoricalDataItem,
InfoItem,
MarketDataOfMarketsResponse,
- ToggleOption,
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
-import { FearAndGreedIndexMode } from '@ghostfolio/common/types';
+import { FearAndGreedIndexMode, ToggleOption } from '@ghostfolio/common/types';
import { GfBenchmarkComponent } from '@ghostfolio/ui/benchmark';
import { GfFearAndGreedIndexComponent } from '@ghostfolio/ui/fear-and-greed-index';
import { GfLineChartComponent } from '@ghostfolio/ui/line-chart';
diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
index d3e3d8a31..2c34dbcd7 100644
--- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
+++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
@@ -13,7 +13,6 @@ import {
PortfolioInvestmentsResponse,
PortfolioPerformance,
PortfolioPosition,
- ToggleOption,
User
} from '@ghostfolio/common/interfaces';
import {
@@ -21,7 +20,11 @@ import {
hasReadRestrictedAccessPermission,
permissions
} from '@ghostfolio/common/permissions';
-import type { AiPromptMode, GroupBy } from '@ghostfolio/common/types';
+import type {
+ AiPromptMode,
+ GroupBy,
+ ToggleOption
+} from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { DataService } from '@ghostfolio/ui/services';
diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts
index 008422f2d..62a038df0 100644
--- a/libs/common/src/lib/interfaces/index.ts
+++ b/libs/common/src/lib/interfaces/index.ts
@@ -94,7 +94,6 @@ import type { SubscriptionOffer } from './subscription-offer.interface';
import type { SymbolItem } from './symbol-item.interface';
import type { SymbolMetrics } from './symbol-metrics.interface';
import type { SystemMessage } from './system-message.interface';
-import type { ToggleOption } from './toggle-option.interface';
import type { UserItem } from './user-item.interface';
import type { UserSettings } from './user-settings.interface';
import type { User } from './user.interface';
@@ -191,7 +190,6 @@ export {
SymbolItem,
SymbolMetrics,
SystemMessage,
- ToggleOption,
User,
UserItem,
UserSettings,
diff --git a/libs/common/src/lib/interfaces/toggle-option.interface.ts b/libs/common/src/lib/interfaces/toggle-option.interface.ts
deleted file mode 100644
index ca7b16bb2..000000000
--- a/libs/common/src/lib/interfaces/toggle-option.interface.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface ToggleOption {
- label: string;
- value: string;
-}
diff --git a/libs/common/src/lib/types/index.ts b/libs/common/src/lib/types/index.ts
index f61bfdca7..22d772610 100644
--- a/libs/common/src/lib/types/index.ts
+++ b/libs/common/src/lib/types/index.ts
@@ -23,6 +23,7 @@ import type { PropertyKey } from './property-key.type';
import type { RequestWithUser } from './request-with-user.type';
import type { SectorName } from './sector-name.type';
import type { SubscriptionOfferKey } from './subscription-offer-key.type';
+import type { ToggleOption } from './toggle-option.type';
import type { UserWithSettings } from './user-with-settings.type';
import type { ViewMode } from './view-mode.type';
@@ -52,6 +53,7 @@ export type {
RequestWithUser,
SectorName,
SubscriptionOfferKey,
+ ToggleOption,
UserWithSettings,
ViewMode
};
diff --git a/libs/common/src/lib/types/toggle-option.type.ts b/libs/common/src/lib/types/toggle-option.type.ts
new file mode 100644
index 000000000..1e0012432
--- /dev/null
+++ b/libs/common/src/lib/types/toggle-option.type.ts
@@ -0,0 +1,9 @@
+interface BaseToggleOption {
+ value: string;
+}
+
+export type ToggleOption = BaseToggleOption &
+ (
+ | { iconName: string; label?: never; title: string }
+ | { iconName?: never; label: string; title?: never }
+ );
diff --git a/libs/ui/src/lib/toggle/toggle.component.html b/libs/ui/src/lib/toggle/toggle.component.html
index 3fe7d00ba..8ad5d75b3 100644
--- a/libs/ui/src/lib/toggle/toggle.component.html
+++ b/libs/ui/src/lib/toggle/toggle.component.html
@@ -12,8 +12,14 @@
!isLoading() && option.value !== optionFormControl.value
}"
[disabled]="isLoading()"
+ [title]="option.title ?? ''"
[value]="option.value"
- >{{ option.label }}
+ @if (option.iconName) {
+
+ } @else {
+ {{ option.label }}
+ }
+
}
diff --git a/libs/ui/src/lib/toggle/toggle.component.stories.ts b/libs/ui/src/lib/toggle/toggle.component.stories.ts
index 36468ea3c..30af31c42 100644
--- a/libs/ui/src/lib/toggle/toggle.component.stories.ts
+++ b/libs/ui/src/lib/toggle/toggle.component.stories.ts
@@ -1,17 +1,22 @@
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { MatRadioModule } from '@angular/material/radio';
+import { IonIcon } from '@ionic/angular/standalone';
import { moduleMetadata } from '@storybook/angular';
import type { Meta, StoryObj } from '@storybook/angular';
+import { addIcons } from 'ionicons';
+import { gridOutline, reorderFourOutline } from 'ionicons/icons';
import { GfToggleComponent } from './toggle.component';
+addIcons({ gridOutline, reorderFourOutline });
+
export default {
title: 'Toggle',
component: GfToggleComponent,
decorators: [
moduleMetadata({
- imports: [CommonModule, MatRadioModule, ReactiveFormsModule]
+ imports: [CommonModule, IonIcon, MatRadioModule, ReactiveFormsModule]
})
]
} as Meta;
@@ -31,3 +36,22 @@ export const Default: Story = {
]
}
};
+
+export const WithIcons: Story = {
+ args: {
+ defaultValue: 'TABLE',
+ isLoading: false,
+ options: [
+ {
+ iconName: 'reorder-four-outline',
+ title: 'Table',
+ value: 'TABLE'
+ },
+ {
+ iconName: 'grid-outline',
+ title: 'Chart',
+ value: 'CHART'
+ }
+ ]
+ }
+};
diff --git a/libs/ui/src/lib/toggle/toggle.component.ts b/libs/ui/src/lib/toggle/toggle.component.ts
index 9324b3be7..fe8db17a3 100644
--- a/libs/ui/src/lib/toggle/toggle.component.ts
+++ b/libs/ui/src/lib/toggle/toggle.component.ts
@@ -1,4 +1,4 @@
-import { ToggleOption } from '@ghostfolio/common/interfaces';
+import { ToggleOption } from '@ghostfolio/common/types';
import {
ChangeDetectionStrategy,
@@ -9,10 +9,11 @@ import {
} from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatRadioModule } from '@angular/material/radio';
+import { IonIcon } from '@ionic/angular/standalone';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
- imports: [MatRadioModule, ReactiveFormsModule],
+ imports: [IonIcon, MatRadioModule, ReactiveFormsModule],
selector: 'gf-toggle',
styleUrls: ['./toggle.component.scss'],
templateUrl: './toggle.component.html'