mirror of https://github.com/ghostfolio/ghostfolio
committed by
GitHub
25 changed files with 204 additions and 451 deletions
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2" [innerHTML]="tab.label"></div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -1,30 +1 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs; track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
<gf-page-tabs [tabs]="tabs" /> |
|||
|
|||
@ -0,0 +1,2 @@ |
|||
export * from './interfaces/interfaces'; |
|||
export * from './page-tabs.component'; |
|||
@ -0,0 +1,30 @@ |
|||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
|||
<router-outlet /> |
|||
</mat-tab-nav-panel> |
|||
|
|||
<nav |
|||
mat-align-tabs="center" |
|||
mat-tab-nav-bar |
|||
[disablePagination]="true" |
|||
[tabPanel]="tabPanel" |
|||
> |
|||
@for (tab of tabs(); track tab) { |
|||
@if (tab.showCondition !== false) { |
|||
<a |
|||
#rla="routerLinkActive" |
|||
class="no-min-width px-3" |
|||
mat-tab-link |
|||
routerLinkActive |
|||
[active]="rla.isActive" |
|||
[routerLink]="tab.routerLink" |
|||
[routerLinkActiveOptions]="{ exact: true }" |
|||
> |
|||
<ion-icon |
|||
[name]="tab.iconName" |
|||
[size]="deviceType === 'mobile' ? 'large' : 'small'" |
|||
/> |
|||
<div class="d-none d-sm-block ml-2" [innerHTML]="tab.label"></div> |
|||
</a> |
|||
} |
|||
} |
|||
</nav> |
|||
@ -0,0 +1,70 @@ |
|||
@use '@angular/material' as mat; |
|||
|
|||
:host { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: calc(100svh - var(--mat-toolbar-standard-height)); |
|||
width: 100%; |
|||
|
|||
@include mat.tabs-overrides( |
|||
( |
|||
active-indicator-height: 0, |
|||
divider-height: 0, |
|||
label-text-tracking: normal |
|||
) |
|||
); |
|||
|
|||
.fab-container { |
|||
@media (max-width: 575.98px) { |
|||
bottom: 5rem; |
|||
} |
|||
} |
|||
|
|||
::ng-deep { |
|||
.mat-mdc-tab-nav-panel { |
|||
padding: 2rem 0; |
|||
} |
|||
} |
|||
|
|||
@media (max-width: 575.98px) { |
|||
@include mat.tabs-overrides( |
|||
( |
|||
container-height: 3rem |
|||
) |
|||
); |
|||
} |
|||
|
|||
@media (min-width: 576px) { |
|||
flex-direction: row-reverse; |
|||
|
|||
@include mat.tabs-overrides( |
|||
( |
|||
container-height: 2rem |
|||
) |
|||
); |
|||
|
|||
::ng-deep { |
|||
.mat-mdc-tab-header { |
|||
background-color: rgba(var(--palette-foreground-base), 0.02); |
|||
padding: 2rem 0; |
|||
width: 14rem; |
|||
|
|||
.mat-mdc-tab-links { |
|||
flex-direction: column; |
|||
|
|||
.mat-mdc-tab-link { |
|||
justify-content: flex-start; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
:host-context(.theme-dark) { |
|||
@media (min-width: 576px) { |
|||
.mat-mdc-tab-header { |
|||
background-color: rgba(var(--palette-foreground-base-dark), 0.02); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
import { |
|||
ChangeDetectionStrategy, |
|||
Component, |
|||
inject, |
|||
input |
|||
} from '@angular/core'; |
|||
import { MatTabsModule } from '@angular/material/tabs'; |
|||
import { RouterModule } from '@angular/router'; |
|||
import { IonIcon } from '@ionic/angular/standalone'; |
|||
import { DeviceDetectorService } from 'ngx-device-detector'; |
|||
|
|||
import { TabConfiguration } from './interfaces/interfaces'; |
|||
|
|||
@Component({ |
|||
changeDetection: ChangeDetectionStrategy.OnPush, |
|||
imports: [IonIcon, MatTabsModule, RouterModule], |
|||
selector: 'gf-page-tabs', |
|||
styleUrls: ['./page-tabs.component.scss'], |
|||
templateUrl: './page-tabs.component.html' |
|||
}) |
|||
export class GfPageTabsComponent { |
|||
public deviceType: string; |
|||
public readonly tabs = input.required<TabConfiguration[]>(); |
|||
|
|||
private readonly deviceService = inject(DeviceDetectorService); |
|||
|
|||
public constructor() { |
|||
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue