Skip to content

Commit daf44cb

Browse files
gianluca-rkyubisation
authored andcommitted
feat(business/header): implement header component (#148)
1 parent 1851c94 commit daf44cb

File tree

14 files changed

+913
-7
lines changed

14 files changed

+913
-7
lines changed

projects/angular-showcase/src/app/app.module.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import { MonacoEditorModule } from 'ngx-monaco-editor';
2+
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
3+
14
import { HttpClientModule } from '@angular/common/http';
25
import { NgModule } from '@angular/core';
36
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
47
import { BrowserModule } from '@angular/platform-browser';
58
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
69
import { ICON_COMPONENT_LIST, IconCollectionModule } from '@sbb-esta/angular-icons';
7-
import { MonacoEditorModule } from 'ngx-monaco-editor';
8-
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
910

1011
import { AppRoutingModule } from './app-routing.module';
1112
import { AppComponent } from './app.component';
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { CommonModule } from '@angular/common';
22
import { NgModule } from '@angular/core';
33

4+
import { HeaderModule } from '@sbb-esta/angular-business';
5+
46
@NgModule({
57
declarations: [],
6-
imports: [CommonModule]
8+
imports: [CommonModule, HeaderModule]
79
})
810
export class ExamplesModule {}

projects/angular-showcase/src/app/public/examples/examples.module.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1+
import { MonacoEditorModule } from 'ngx-monaco-editor';
2+
13
import { CommonModule } from '@angular/common';
24
import { NgModule } from '@angular/core';
35
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
46
import { BrowserModule } from '@angular/platform-browser';
5-
67
import { RouterModule } from '@angular/router';
7-
8-
import { MonacoEditorModule } from 'ngx-monaco-editor';
9-
108
import { IconCollectionModule } from '@sbb-esta/angular-icons';
119
import {
1210
AccordionModule,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Header Overview
2+
3+
Import header module in your application
4+
5+
```ts
6+
import { HeaderModule } from '@sbb-esta/angular-business';
7+
```
8+
9+
The header will appear at the top of the screen in a fixed position, and provide a container for navigation, usermenu, and eventually a logo.
10+
It supports <a> and <button> tags for navigation. Optionally an <sbb-usermenu> can be provided, as well as any element with a [brand] property, or .brand class, for replacing the standard logo.
11+
12+
```html
13+
<sbb-header [label]="Title" [subtitle]="Subtitle" [environment]="dev" [environmentColor]="red">
14+
<a routerLink="/">A tag</a>
15+
<button sbbNavbutton type="button" [sbbDropdown]="dropdown">Button tag</button>
16+
<button sbbNavbutton type="button">Button tag with dropdown</button>
17+
<sbb-dropdown #dropdown="sbbDropdown">
18+
<a sbbDropdownItem routerLink="/navigation1/section1" routerLinkActive="sbb-selected"
19+
>Option 1</a
20+
>
21+
<a sbbDropdownItem routerLink="/navigation1/section2" routerLinkActive="sbb-selected"
22+
>Option 2</a
23+
>
24+
</sbb-dropdown>
25+
<sbb-usermenu ...>
26+
<!-- A usermenu can be optionally included -->
27+
</sbb-usermenu>
28+
<svg brand>
29+
<!-- A logo can be optionally included -->
30+
</svg>
31+
</sbb-header>
32+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { CommonModule } from '@angular/common';
2+
import { NgModule } from '@angular/core';
3+
import {
4+
IconChevronSmallDownModule,
5+
IconChevronSmallUpModule,
6+
IconHamburgerMenuModule
7+
} from '@sbb-esta/angular-icons';
8+
import { DropdownModule } from '@sbb-esta/angular-public';
9+
10+
import { HeaderComponent } from './header/header.component';
11+
import { NavbuttonComponent } from './navbutton/navbutton.component';
12+
13+
@NgModule({
14+
imports: [
15+
CommonModule,
16+
IconHamburgerMenuModule,
17+
IconChevronSmallDownModule,
18+
IconChevronSmallUpModule,
19+
DropdownModule
20+
],
21+
declarations: [HeaderComponent, NavbuttonComponent],
22+
exports: [HeaderComponent, NavbuttonComponent]
23+
})
24+
export class HeaderModule {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './header.module';
2+
3+
export * from './header/header.component';
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<div class="sbb-header-ribbon" *ngIf="environment" [style.background]="environmentColor">
2+
{{ environment }}
3+
</div>
4+
5+
<div class="sbb-header-appchooser">
6+
<span class="sbb-svgsprite-icon">
7+
<!-- placeholder for other icon -->
8+
<sbb-icon-hamburger-menu></sbb-icon-hamburger-menu>
9+
</span>
10+
<!-- Content here -->
11+
</div>
12+
13+
<div class="sbb-header-titlebox">
14+
<div class="sbb-header-titlebox-label">{{ label }}</div>
15+
<div *ngIf="subtitle" class="sbb-header-titlebox-subtitle">{{ subtitle }}</div>
16+
</div>
17+
18+
<div class="sbb-header-mainnavigation">
19+
<div #content>
20+
<ng-content select="a,button[sbbNavbutton]"></ng-content>
21+
</div>
22+
<template #navigationButtons></template>
23+
</div>
24+
<div class="sbb-header-usermenu">
25+
<ng-content select="sbb-usermenu"></ng-content>
26+
</div>
27+
28+
<!-- If an icon is provided, use that, otherwise use the sbb logo -->
29+
<!-- TODO: make cleaner -->
30+
<div #iconContent class="sbb-header-logo">
31+
<ng-content select="[brand],.brand"></ng-content>
32+
</div>
33+
<div *ngIf="!iconContent.childElementCount" class="sbb-header-logo">
34+
<svg viewBox="0 0 80 21" xmlns="http://www.w3.org/2000/svg">
35+
<path d="M0 0h59.233v20.603H0V0z" fill="#EC0000"></path>
36+
<path
37+
d="M35.186 17.02h3.75l-5.047-5.163h6.265v5.163h2.96v-5.163h6.267l-5.05 5.163h3.752l6.427-6.708-6.426-6.73h-3.752l5.05 5.185h-6.266V3.583h-2.96v5.184h-6.267l5.047-5.184h-3.75l-6.43 6.73 6.43 6.707"
38+
fill="#FFF"
39+
></path>
40+
</svg>
41+
</div>
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
@import 'common';
2+
3+
$border: solid 2px $sbbColorGranite;
4+
$buttonMarginTop: calc(54px / 2 - 15px);
5+
6+
@mixin headerBlockComponent {
7+
position: absolute;
8+
top: 0px;
9+
height: 54px;
10+
}
11+
12+
@mixin smallIconDropdown() {
13+
position: relative;
14+
top: 3px;
15+
16+
svg {
17+
width: 20px;
18+
height: 20px;
19+
}
20+
}
21+
22+
@mixin navButtonDefaultButton() {
23+
@include buttonResetFrameless();
24+
25+
position: relative;
26+
white-space: nowrap;
27+
font-family: $fontSbbLight;
28+
font-size: pxToRem(15);
29+
text-decoration: none;
30+
text-align: left;
31+
background: $sbbColorWhite; //TODO: this is required for overlaps
32+
33+
&:hover,
34+
&:focus {
35+
cursor: pointer;
36+
outline: none;
37+
}
38+
39+
&::after {
40+
content: '';
41+
display: block;
42+
position: absolute;
43+
bottom: 0;
44+
width: 0;
45+
left: 50%;
46+
height: 1px;
47+
border-bottom: 1px solid currentColor;
48+
transition: width 0.3s, left 0.3s;
49+
}
50+
51+
&.sbb-active::after,
52+
&:not(.sbb-active):focus::after,
53+
&:not(.sbb-active):hover::after {
54+
left: 0;
55+
width: 100%;
56+
}
57+
58+
&:not(.sbb-active):focus &:not([aria-expanded='true']),
59+
&:not(.sbb-active):hover {
60+
color: $sbbColorRed125;
61+
62+
&::after {
63+
border-bottom-color: $sbbColorRed125;
64+
}
65+
}
66+
67+
&[disabled] {
68+
color: $sbbColorStorm;
69+
70+
&:hover,
71+
&:focus {
72+
color: $sbbColorStorm;
73+
cursor: default;
74+
75+
&::after {
76+
width: 0;
77+
}
78+
}
79+
}
80+
81+
&.sbb-active:hover,
82+
&.sbb-active:focus {
83+
color: currentColor;
84+
cursor: default;
85+
86+
&::after {
87+
border-bottom-color: currentColor;
88+
}
89+
}
90+
}
91+
92+
.sbb-header {
93+
width: 100%;
94+
95+
position: fixed;
96+
top: 0px;
97+
left: 0px;
98+
z-index: 1000;
99+
height: 54px;
100+
101+
background-color: $sbbColorWhite;
102+
border-bottom: solid 1px $sbbColorSilver;
103+
104+
&-ribbon {
105+
width: 80px;
106+
position: absolute;
107+
top: 12px;
108+
left: -20px;
109+
text-align: center;
110+
line-height: 12px;
111+
letter-spacing: 0px;
112+
font-size: 10px;
113+
color: $sbbColorSilver;
114+
transform: rotate(-45deg);
115+
}
116+
117+
&-appchooser {
118+
@include headerBlockComponent();
119+
120+
left: 46px;
121+
width: 54px;
122+
padding: 17px;
123+
}
124+
125+
&-titlebox {
126+
@include headerBlockComponent();
127+
128+
left: 100px;
129+
width: 200px;
130+
font-family: $fontSbbLight;
131+
&-label {
132+
height: 23px;
133+
width: 200px;
134+
color: $sbbColorBlack;
135+
font-size: 15px;
136+
line-height: 23px;
137+
138+
margin-top: 8px;
139+
}
140+
&-subtitle {
141+
height: 16px;
142+
width: 200px;
143+
color: $sbbColorAnthracite;
144+
font-size: 13px;
145+
font-weight: 300;
146+
line-height: 16px;
147+
148+
margin-bottom: 7px;
149+
}
150+
}
151+
152+
&-mainnavigation {
153+
@include headerBlockComponent();
154+
left: 350px;
155+
156+
a {
157+
@include navButtonDefaultButton();
158+
white-space: nowrap;
159+
position: absolute;
160+
height: 30px;
161+
margin-top: $buttonMarginTop;
162+
display: flex;
163+
}
164+
165+
.sbb-navbutton {
166+
@include navButtonDefaultButton();
167+
white-space: nowrap;
168+
position: absolute;
169+
height: 30px;
170+
// top: -1px;
171+
// margin-top: $buttonMarginTop;
172+
margin-top: -1px;
173+
top: $buttonMarginTop;
174+
display: flex;
175+
176+
.sbb-navbutton-icon-small {
177+
@include smallIconDropdown();
178+
}
179+
.sbb-navbutton-icon-small-expanded {
180+
@include smallIconDropdown();
181+
position: absolute;
182+
right: 5px;
183+
}
184+
}
185+
186+
.sbb-navbutton.sbb-navbutton-dropdown-expanded {
187+
border: $border;
188+
border-bottom: none;
189+
190+
z-index: 5;
191+
192+
padding-left: calc(15px - 2px);
193+
margin-left: -15px;
194+
margin-top: calc($buttonMarginTop - 7px);
195+
height: 35px;
196+
197+
&::after {
198+
border-bottom: none;
199+
}
200+
}
201+
}
202+
203+
&-usermenu {
204+
@include headerBlockComponent();
205+
206+
right: 159px;
207+
width: 200px;
208+
z-index: 1;
209+
}
210+
211+
&-logo {
212+
@include headerBlockComponent();
213+
214+
top: 17px;
215+
right: 35px;
216+
width: 80px;
217+
}
218+
}

0 commit comments

Comments
 (0)