diff --git a/demo-shell/src/app/components/app-layout/app-layout.component.html b/demo-shell/src/app/components/app-layout/app-layout.component.html
index 0aafef8cfc..e8f6c6fe4d 100644
--- a/demo-shell/src/app/components/app-layout/app-layout.component.html
+++ b/demo-shell/src/app/components/app-layout/app-layout.component.html
@@ -2,31 +2,29 @@
-
-
+
- {{'APP_LAYOUT.APP_NAME' | translate }}
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
+
diff --git a/demo-shell/src/assets/logo.png b/demo-shell/src/assets/logo.png
new file mode 100644
index 0000000000..d342b10ee0
Binary files /dev/null and b/demo-shell/src/assets/logo.png differ
diff --git a/docs/core/header.component.md b/docs/core/header.component.md
new file mode 100644
index 0000000000..d3203299d6
--- /dev/null
+++ b/docs/core/header.component.md
@@ -0,0 +1,42 @@
+---
+Added: v2.4.0
+Status: Experimental
+---
+
+## Header component
+
+Reuseble header for Alfresco applications
+
+## Basic usage
+
+```html
+
+
+
+
+
+```
+
+## Class members
+
+### Properties
+| Name | Type | Description |
+| -- | -- | -- |
+| title | string | Title of the application
+| logo | string| Path to an image file for the application logo.
+| color | string | Primary color for the header
+| showSidenavToggle | boolean | Signals if the sidenav button will be displayed in the header or not. By default is true.
+
+### Events
+| Name | Type | Description |
+| -- | -- | -- |
+| clicked | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when click on sidenav button
+
+## Details
+This component displays a customizable header which can be reused. The left side of the header (title, button) and the primary color for the header can be configured via input parameters.
+
+The right part of the header are existing components which are transcluded in the header component.
diff --git a/lib/core/assets/images/logo.png b/lib/core/assets/images/logo.png
new file mode 100644
index 0000000000..d342b10ee0
Binary files /dev/null and b/lib/core/assets/images/logo.png differ
diff --git a/lib/core/core.module.ts b/lib/core/core.module.ts
index 568d50240f..d51059b806 100644
--- a/lib/core/core.module.ts
+++ b/lib/core/core.module.ts
@@ -39,7 +39,7 @@ import { ToolbarModule } from './toolbar/toolbar.module';
import { UserInfoModule } from './userinfo/userinfo.module';
import { ViewerModule } from './viewer/viewer.module';
import { FormModule } from './form/form.module';
-import { SidenavLayoutModule } from './sidenav-layout/sidenav-layout.module';
+import { SidenavLayoutModule } from './layout/layout.module';
import { CommentsModule } from './comments/comments.module';
import { ButtonsMenuModule } from './buttons-menu/buttons-menu.module';
import { TemplateModule } from './templates/template.module';
diff --git a/lib/core/index.ts b/lib/core/index.ts
index a7c994c411..23669abccf 100644
--- a/lib/core/index.ts
+++ b/lib/core/index.ts
@@ -31,7 +31,7 @@ export * from './collapsable/index';
export * from './card-view/index';
export * from './app-config/index';
export * from './form/index';
-export * from './sidenav-layout/index';
+export * from './layout/index';
export * from './comments/index';
export * from './buttons-menu/index';
export * from './sorting-picker/index';
diff --git a/lib/core/layout/components/header/header.component.html b/lib/core/layout/components/header/header.component.html
new file mode 100644
index 0000000000..9704290267
--- /dev/null
+++ b/lib/core/layout/components/header/header.component.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+ {{title}}
+
+
+
diff --git a/lib/core/layout/components/header/header.component.scss b/lib/core/layout/components/header/header.component.scss
new file mode 100644
index 0000000000..357c9888d6
--- /dev/null
+++ b/lib/core/layout/components/header/header.component.scss
@@ -0,0 +1,54 @@
+@mixin adf-header-layout-theme($theme) {
+ $primary: map-get($theme, primary);
+ $accent: map-get($theme, accent);
+ $background: map-get($theme, background);
+
+ adf-layout-header .mat-toolbar-single-row {
+
+ color: mat-color($primary, default-contrast) !important;
+ position: relative;
+ padding: 0 24px 0 0;
+
+ .adf-menu-icon {
+ position: relative;
+ margin-left: 14px;
+ }
+
+ .adf-app-logo {
+ position: relative;
+ height: 28px;
+ width: 28px;
+ margin-right: 6px;
+ margin-left: 3px;
+ }
+
+ .adf-header-delimiter {
+ height: 24px;
+ width: 2px;
+ background-color: mat-color($primary, default-contrast);
+ margin-right: 16px;
+ }
+
+ .adf-app-layout-user-profile {
+ margin-right: 16px;
+ }
+
+ .adf-userinfo-container {
+ flex-direction: row;
+ padding: 0;
+ }
+
+ .adf-userinfo-name{
+ padding-right: 8px;
+ }
+
+ @media screen and ($mat-xsmall) {
+ .adf-app-logo,
+ .adf-app-title {
+ display: none;
+ }
+ }
+ }
+}
+
+
diff --git a/lib/core/layout/components/header/header.component.spec.ts b/lib/core/layout/components/header/header.component.spec.ts
new file mode 100644
index 0000000000..5d95747a1b
--- /dev/null
+++ b/lib/core/layout/components/header/header.component.spec.ts
@@ -0,0 +1,124 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
+import { HeaderLayoutComponent } from './header.component';
+import { setupTestBed } from '../../../testing/setupTestBed';
+import { CoreTestingModule } from '../../../testing/core.testing.module';
+import { By } from '@angular/platform-browser';
+import { LayoutModule } from '../..';
+import { Component } from '@angular/core';
+import { MaterialModule } from './../../../material.module';
+
+describe('HeaderLayoutComponent', () => {
+ let fixture: ComponentFixture;
+ let component: HeaderLayoutComponent;
+
+ describe('Input parameters', () => {
+ setupTestBed({
+ imports: [CoreTestingModule]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HeaderLayoutComponent);
+ component = fixture.componentInstance;
+ });
+
+ afterEach(() => {
+ fixture.destroy();
+ });
+
+ it('should create instance of HeaderLayoutComponent', () => {
+ expect(fixture.componentInstance instanceof HeaderLayoutComponent).toBe(true, 'should create HeaderLayoutComponent');
+ });
+
+ it('title element should been displayed', () => {
+ const titleElement = fixture.debugElement.query(By.css('.adf-app-title'));
+ expect(titleElement === null).toBeFalsy();
+ });
+
+ it('should show TEST TITLE', () => {
+ component.title = 'TEST TITLE';
+ fixture.detectChanges();
+
+ const titleElement = fixture.nativeElement.querySelector('.adf-app-title');
+ expect(titleElement.innerText).toEqual('TEST TITLE');
+ });
+
+ it('color attribute should be present on mat-toolbar', () => {
+ component.color = 'primary';
+ fixture.detectChanges();
+
+ const toolbar = fixture.nativeElement.querySelector('mat-toolbar');
+ expect(toolbar.getAttribute('ng-reflect-color') === null).toBeFalsy();
+ expect(toolbar.getAttribute('ng-reflect-color')).toEqual('primary');
+ });
+
+ it('should display the img element with the expected src if a logo path is set', () => {
+ component.logo = 'logo.png';
+ fixture.detectChanges();
+
+ const logo = fixture.nativeElement.querySelector('.adf-app-logo');
+ const src = logo.getAttribute('src');
+ expect(logo === null).toBeFalsy();
+ expect(src).toEqual('logo.png');
+ });
+
+ it('test click on sidenav button', () => {
+ component.showSidenavToggle = true;
+ fixture.detectChanges();
+ spyOn(component.clicked, 'emit');
+ const button = fixture.nativeElement.querySelector('.adf-menu-icon');
+
+ button.dispatchEvent(new Event('click'));
+ fixture.detectChanges();
+ expect(component.clicked.emit).toHaveBeenCalledWith(true);
+ });
+
+ it('if showSidenavToggle is false the button menu should not be displayed', () => {
+ component.showSidenavToggle = false;
+ fixture.detectChanges();
+
+ const button = fixture.nativeElement.querySelector('.adf-menu-icon');
+ expect(button === null).toBeTruthy();
+ });
+ });
+
+ describe('Template tranclusion', () => {
+
+ @Component({
+ selector: 'adf-test-layout-header',
+ template: `Test text
`
+ })
+ class HeaderLayoutTesterComponent {}
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [HeaderLayoutTesterComponent],
+ imports: [ LayoutModule, MaterialModule ]
+ })
+ .compileComponents();
+ }));
+
+ it('should transclude the provided nodes into the component', () => {
+ const hostFixture = TestBed.createComponent(HeaderLayoutTesterComponent);
+ hostFixture.detectChanges();
+ const innerText = hostFixture.nativeElement.querySelector('mat-toolbar>p').innerText;
+ expect(innerText).toEqual('Test text');
+ });
+ });
+});
diff --git a/lib/core/layout/components/header/header.component.ts b/lib/core/layout/components/header/header.component.ts
new file mode 100644
index 0000000000..2828955f80
--- /dev/null
+++ b/lib/core/layout/components/header/header.component.ts
@@ -0,0 +1,39 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
+
+@Component({
+ selector: 'adf-layout-header',
+ templateUrl: './header.component.html',
+ styleUrls: ['./header.component.scss'],
+ encapsulation: ViewEncapsulation.None,
+ host: { 'class': 'adf-layout-header' }
+})
+
+export class HeaderLayoutComponent {
+
+ @Input() title: string;
+ @Input() logo: string = '../assets/logo.png';
+ @Input() color: string;
+ @Input() showSidenavToggle: boolean = true;
+ @Output() clicked = new EventEmitter();
+
+ toggleMenu() {
+ this.clicked.emit(true);
+ }
+}
diff --git a/lib/core/sidenav-layout/components/layout-container/layout-container.component.html b/lib/core/layout/components/layout-container/layout-container.component.html
similarity index 100%
rename from lib/core/sidenav-layout/components/layout-container/layout-container.component.html
rename to lib/core/layout/components/layout-container/layout-container.component.html
diff --git a/lib/core/sidenav-layout/components/layout-container/layout-container.component.scss b/lib/core/layout/components/layout-container/layout-container.component.scss
similarity index 100%
rename from lib/core/sidenav-layout/components/layout-container/layout-container.component.scss
rename to lib/core/layout/components/layout-container/layout-container.component.scss
diff --git a/lib/core/sidenav-layout/components/layout-container/layout-container.component.ts b/lib/core/layout/components/layout-container/layout-container.component.ts
similarity index 100%
rename from lib/core/sidenav-layout/components/layout-container/layout-container.component.ts
rename to lib/core/layout/components/layout-container/layout-container.component.ts
diff --git a/lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.html b/lib/core/layout/components/sidebar-action/sidebar-action-menu.component.html
similarity index 100%
rename from lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.html
rename to lib/core/layout/components/sidebar-action/sidebar-action-menu.component.html
diff --git a/lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.scss b/lib/core/layout/components/sidebar-action/sidebar-action-menu.component.scss
similarity index 100%
rename from lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.scss
rename to lib/core/layout/components/sidebar-action/sidebar-action-menu.component.scss
diff --git a/lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.spec.ts b/lib/core/layout/components/sidebar-action/sidebar-action-menu.component.spec.ts
similarity index 100%
rename from lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.spec.ts
rename to lib/core/layout/components/sidebar-action/sidebar-action-menu.component.spec.ts
diff --git a/lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.ts b/lib/core/layout/components/sidebar-action/sidebar-action-menu.component.ts
similarity index 100%
rename from lib/core/sidenav-layout/components/sidebar-action/sidebar-action-menu.component.ts
rename to lib/core/layout/components/sidebar-action/sidebar-action-menu.component.ts
diff --git a/lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.html b/lib/core/layout/components/sidenav-layout/sidenav-layout.component.html
similarity index 100%
rename from lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.html
rename to lib/core/layout/components/sidenav-layout/sidenav-layout.component.html
diff --git a/lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.scss b/lib/core/layout/components/sidenav-layout/sidenav-layout.component.scss
similarity index 100%
rename from lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.scss
rename to lib/core/layout/components/sidenav-layout/sidenav-layout.component.scss
diff --git a/lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.spec.ts b/lib/core/layout/components/sidenav-layout/sidenav-layout.component.spec.ts
similarity index 100%
rename from lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.spec.ts
rename to lib/core/layout/components/sidenav-layout/sidenav-layout.component.spec.ts
diff --git a/lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.ts b/lib/core/layout/components/sidenav-layout/sidenav-layout.component.ts
similarity index 100%
rename from lib/core/sidenav-layout/components/sidenav-layout/sidenav-layout.component.ts
rename to lib/core/layout/components/sidenav-layout/sidenav-layout.component.ts
diff --git a/lib/core/sidenav-layout/directives/sidenav-layout-content.directive.ts b/lib/core/layout/directives/sidenav-layout-content.directive.ts
similarity index 100%
rename from lib/core/sidenav-layout/directives/sidenav-layout-content.directive.ts
rename to lib/core/layout/directives/sidenav-layout-content.directive.ts
diff --git a/lib/core/sidenav-layout/directives/sidenav-layout-header.directive.ts b/lib/core/layout/directives/sidenav-layout-header.directive.ts
similarity index 100%
rename from lib/core/sidenav-layout/directives/sidenav-layout-header.directive.ts
rename to lib/core/layout/directives/sidenav-layout-header.directive.ts
diff --git a/lib/core/sidenav-layout/directives/sidenav-layout-navigation.directive.ts b/lib/core/layout/directives/sidenav-layout-navigation.directive.ts
similarity index 100%
rename from lib/core/sidenav-layout/directives/sidenav-layout-navigation.directive.ts
rename to lib/core/layout/directives/sidenav-layout-navigation.directive.ts
diff --git a/lib/core/sidenav-layout/helpers/animations.ts b/lib/core/layout/helpers/animations.ts
similarity index 100%
rename from lib/core/sidenav-layout/helpers/animations.ts
rename to lib/core/layout/helpers/animations.ts
diff --git a/lib/core/sidenav-layout/index.ts b/lib/core/layout/index.ts
similarity index 100%
rename from lib/core/sidenav-layout/index.ts
rename to lib/core/layout/index.ts
diff --git a/lib/core/sidenav-layout/sidenav-layout.module.ts b/lib/core/layout/layout.module.ts
similarity index 88%
rename from lib/core/sidenav-layout/sidenav-layout.module.ts
rename to lib/core/layout/layout.module.ts
index c2e34236e3..22a696f809 100644
--- a/lib/core/sidenav-layout/sidenav-layout.module.ts
+++ b/lib/core/layout/layout.module.ts
@@ -25,7 +25,7 @@ import { SidenavLayoutComponent } from './components/sidenav-layout/sidenav-layo
import { LayoutContainerComponent } from './components/layout-container/layout-container.component';
import { SidebarActionMenuComponent, SidebarMenuDirective,
SidebarMenuExpandIconDirective, SidebarMenuTitleIconDirective } from './components/sidebar-action/sidebar-action-menu.component';
-
+import { HeaderLayoutComponent } from './components/header/header.component';
@NgModule({
imports: [
CommonModule,
@@ -40,7 +40,8 @@ import { SidebarActionMenuComponent, SidebarMenuDirective,
SidebarActionMenuComponent,
SidebarMenuDirective,
SidebarMenuExpandIconDirective,
- SidebarMenuTitleIconDirective
+ SidebarMenuTitleIconDirective,
+ HeaderLayoutComponent
],
declarations: [
SidenavLayoutHeaderDirective,
@@ -51,7 +52,9 @@ import { SidebarActionMenuComponent, SidebarMenuDirective,
SidebarActionMenuComponent,
SidebarMenuDirective,
SidebarMenuExpandIconDirective,
- SidebarMenuTitleIconDirective
+ SidebarMenuTitleIconDirective,
+ HeaderLayoutComponent
]
})
-export class SidenavLayoutModule {}
+export class LayoutModule {}
+export { LayoutModule as SidenavLayoutModule };
diff --git a/lib/core/sidenav-layout/public-api.ts b/lib/core/layout/public-api.ts
similarity index 94%
rename from lib/core/sidenav-layout/public-api.ts
rename to lib/core/layout/public-api.ts
index 300a5ec5b5..880bafe4ab 100644
--- a/lib/core/sidenav-layout/public-api.ts
+++ b/lib/core/layout/public-api.ts
@@ -17,4 +17,4 @@
export * from './components/sidenav-layout/sidenav-layout.component';
-export * from './sidenav-layout.module';
+export * from './layout.module';
diff --git a/lib/core/styles/_index.scss b/lib/core/styles/_index.scss
index 98dfbb42b7..b6177709dd 100644
--- a/lib/core/styles/_index.scss
+++ b/lib/core/styles/_index.scss
@@ -22,13 +22,14 @@
@import '../viewer/components/txtViewer.component';
@import '../viewer/components/imgViewer.component';
@import '../form/components/form.component';
-@import '../sidenav-layout/components/sidebar-action/sidebar-action-menu.component';
+@import '../layout/components/sidebar-action/sidebar-action-menu.component';
@import '../comments/comment-list.component';
@import '../comments/comments.component';
-@import '../sidenav-layout/components/layout-container/layout-container.component';
+@import '../layout/components/layout-container/layout-container.component';
@import "../templates/empty-content/empty-content.component";
@import "../templates/error-content/error-content.component";
@import "../buttons-menu/buttons-menu.component";
+@import '../layout/components/header/header.component';
@mixin adf-core-theme($theme) {
@include adf-colors-theme($theme);
@@ -60,6 +61,7 @@
@include adf-empty-content-theme($theme);
@include adf-error-content-theme($theme);
@include adf-buttons-menu-theme($theme);
+ @include adf-header-layout-theme($theme);
}