diff --git a/resources/i18n/en.json b/resources/i18n/en.json
index 169ff0efe9..73cf536496 100644
--- a/resources/i18n/en.json
+++ b/resources/i18n/en.json
@@ -46,7 +46,15 @@
}
},
"nav": {
- "home": "Home",
+ "browse": {
+ "header": "All of DSpace"
+ },
+ "community-browse": {
+ "header": "By Community"
+ },
+ "statistics": {
+ "header": "Statistics"
+ },
"login": "Log In",
"logout": "Log Out"
},
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 24ce6dc843..41171d3081 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,7 +1,6 @@
-
-
+
diff --git a/src/app/app.component.scss b/src/app/app.component.scss
index 1b2a21b0c6..8e5031d0ba 100644
--- a/src/app/app.component.scss
+++ b/src/app/app.component.scss
@@ -34,6 +34,6 @@ body {
margin-bottom: $content-spacing;
}
-ds-navbar {
+ds-header-navbar-wrapper {
z-index: $nav-z-index;
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 987ce77dd1..0aceaf2ef6 100755
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -32,6 +32,7 @@ import { NotificationsBoardComponent } from './shared/notifications/notification
import { NotificationComponent } from './shared/notifications/notification/notification.component';
import { SharedModule } from './shared/shared.module';
import { NavbarComponent } from './navbar/navbar.component';
+import { HeaderNavbarWrapperComponent } from './header-nav-wrapper/header-navbar-wrapper.component';
export function getConfig() {
return ENV_CONFIG;
@@ -89,6 +90,7 @@ if (!ENV_CONFIG.production) {
AppComponent,
HeaderComponent,
NavbarComponent,
+ HeaderNavbarWrapperComponent,
FooterComponent,
PageNotFoundComponent,
NotificationComponent,
diff --git a/src/app/header-nav-wrapper/header-navbar-wrapper.component.html b/src/app/header-nav-wrapper/header-navbar-wrapper.component.html
new file mode 100644
index 0000000000..1eab1d9ffd
--- /dev/null
+++ b/src/app/header-nav-wrapper/header-navbar-wrapper.component.html
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/app/header-nav-wrapper/header-navbar-wrapper.component.scss b/src/app/header-nav-wrapper/header-navbar-wrapper.component.scss
new file mode 100644
index 0000000000..f514508385
--- /dev/null
+++ b/src/app/header-nav-wrapper/header-navbar-wrapper.component.scss
@@ -0,0 +1,9 @@
+@import '../../styles/variables.scss';
+
+@media screen and (max-width: map-get($grid-breakpoints, md)) {
+ :host.open {
+ background-color: $white;
+ top: 0;
+ position: sticky;
+ }
+}
\ No newline at end of file
diff --git a/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts b/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts
new file mode 100644
index 0000000000..1480758ee3
--- /dev/null
+++ b/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts
@@ -0,0 +1,36 @@
+import { Component, HostBinding, OnDestroy, OnInit } from '@angular/core';
+import { createSelector, Store } from '@ngrx/store';
+import { AppState } from '../app.reducer';
+import { Observable } from 'rxjs/Observable';
+import { NavbarState } from '../navbar/navbar.reducer';
+import { Subscription } from 'rxjs/Subscription';
+import { hasValue } from '../shared/empty.util';
+
+const navbarStateSelector = (state: AppState) => state.navbar;
+const navCollapsedSelector = createSelector(navbarStateSelector, (navbar: NavbarState) => navbar.navCollapsed);
+@Component({
+ selector: 'ds-header-navbar-wrapper',
+ styleUrls: ['header-navbar-wrapper.component.scss'],
+ templateUrl: 'header-navbar-wrapper.component.html',
+})
+export class HeaderNavbarWrapperComponent implements OnInit, OnDestroy {
+ @HostBinding('class.open') isOpen = false;
+ private sub: Subscription;
+ public isNavBarCollapsed: Observable;
+
+ constructor(
+ private store: Store
+ ) {
+ }
+
+ ngOnInit(): void {
+ this.isNavBarCollapsed = this.store.select(navCollapsedSelector);
+ this.sub = this.isNavBarCollapsed.subscribe((isCollapsed) => this.isOpen = !isCollapsed)
+ }
+
+ ngOnDestroy() {
+ if (hasValue(this.sub)) {
+ this.sub.unsubscribe();
+ }
+ }
+}
diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html
index 22e2a307a5..3a24f0e075 100644
--- a/src/app/header/header.component.html
+++ b/src/app/header/header.component.html
@@ -3,8 +3,16 @@
-
diff --git a/src/app/header/header.component.scss b/src/app/header/header.component.scss
index 627ce93c6c..7834cfbaaa 100644
--- a/src/app/header/header.component.scss
+++ b/src/app/header/header.component.scss
@@ -2,4 +2,8 @@
.navbar-brand img {
height: $header-logo-height;
-}
\ No newline at end of file
+}
+.navbar-toggler .navbar-toggler-icon {
+ background-image: none !important;
+ line-height: 1.5;
+}
diff --git a/src/app/header/header.component.ts b/src/app/header/header.component.ts
index 8ccc779873..6877f196aa 100644
--- a/src/app/header/header.component.ts
+++ b/src/app/header/header.component.ts
@@ -1,5 +1,8 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
+import { NavbarToggleAction } from '../navbar/navbar.actions';
+import { Store } from '@ngrx/store';
+import { AppState } from '../app.reducer';
@Component({
selector: 'ds-header',
@@ -13,4 +16,13 @@ export class HeaderComponent {
*/
public isAuthenticated: Observable
;
public showAuth = false;
+
+ constructor(
+ private store: Store,
+ ) {
+ }
+
+ public toggle(): void {
+ this.store.dispatch(new NavbarToggleAction());
+ }
}
diff --git a/src/app/navbar/navbar.component.html b/src/app/navbar/navbar.component.html
index 7c4de41098..cf8ff5166c 100644
--- a/src/app/navbar/navbar.component.html
+++ b/src/app/navbar/navbar.component.html
@@ -1,43 +1,43 @@
-
+
-
-
-
-
- -
+
+
diff --git a/src/app/navbar/navbar.component.scss b/src/app/navbar/navbar.component.scss
index 10e97834f3..43ce9e8a67 100644
--- a/src/app/navbar/navbar.component.scss
+++ b/src/app/navbar/navbar.component.scss
@@ -1,18 +1,56 @@
@import '../../styles/variables.scss';
nav.navbar {
- border-bottom: 1px $gray-400 solid;
-}
-
-nav.navbar .navbar-toggler .navbar-toggler-icon {
- background-image: none !important;
- line-height: 1.5;
+ border-bottom: 1px $gray-400 solid;
+ align-items: baseline;
}
.dropdown-menu {
- min-width: 100%;
+ min-width: 100%;
}
-.reset-padding {
- margin-left: -$spacer/2;
- margin-right: -$spacer/2;
-}
\ No newline at end of file
+
+/** Mobile menu styling **/
+@media screen and (max-width: map-get($grid-breakpoints, md)) {
+ .navbar {
+ width: 100%;
+ left: 0;
+ background-color: $white;
+ position: absolute;
+ overflow: hidden;
+ height: 0;
+ &.open {
+ height: 100vh; //doesn't matter because wrapper is sticky
+ }
+ .dropdown-toggle {
+ &:after {
+ float: right;
+ margin-top: $spacer/2;
+ }
+ }
+ .dropdown-menu {
+ border: 0;
+ }
+ }
+}
+
+@media screen and (min-width: map-get($grid-breakpoints, md)) {
+ .reset-padding-md {
+ margin-left: -$spacer/2;
+ margin-right: -$spacer/2;
+ }
+}
+
+/* TODO remove when https://github.com/twbs/bootstrap/issues/24726 is fixed */
+.navbar-expand-md.navbar-container {
+ @media screen and (max-width: map-get($grid-breakpoints, md)) {
+ > .container {
+ padding-left: $spacer;
+ padding-right: $spacer;
+ }
+ padding-left: 0;
+ padding-right: 0;
+ }
+
+}
+
+
diff --git a/src/app/navbar/navbar.component.ts b/src/app/navbar/navbar.component.ts
index e1f8d0bb82..e58d56ee94 100644
--- a/src/app/navbar/navbar.component.ts
+++ b/src/app/navbar/navbar.component.ts
@@ -1,34 +1,45 @@
-import { Component, OnInit } from '@angular/core';
-import { createSelector, Store } from '@ngrx/store';
+import { Component, Input } from '@angular/core';
+import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
-
-import { NavbarState } from './navbar.reducer';
-import { NavbarToggleAction } from './navbar.actions';
import { AppState } from '../app.reducer';
-
-const navbarStateSelector = (state: AppState) => state.navbar;
-const navCollapsedSelector = createSelector(navbarStateSelector, (navbar: NavbarState) => navbar.navCollapsed);
+import { slideMobileNav } from '../shared/animations/slide';
+import { HostWindowService } from '../shared/host-window.service';
+import { first } from 'rxjs/operators';
@Component({
selector: 'ds-navbar',
styleUrls: ['navbar.component.scss'],
templateUrl: 'navbar.component.html',
+ animations: [slideMobileNav]
})
-export class NavbarComponent implements OnInit {
- public isNavBarCollapsed: Observable
;
+export class NavbarComponent {
+ @Input() isNavBarCollapsed: Observable;
constructor(
private store: Store,
+ protected windowService: HostWindowService
) {
}
- ngOnInit(): void {
- // set loading
- this.isNavBarCollapsed = this.store.select(navCollapsedSelector);
+
+
+ openDropdownOnHover(dropdown: any): void {
+ this.windowService.isXsOrSm().pipe(
+ first()
+ ).subscribe((isMobile) => {
+ if (!isMobile) {
+ dropdown.open();
+ }
+ });
}
- public toggle(): void {
- this.store.dispatch(new NavbarToggleAction());
+ closeDropdownOnHover(dropdown: any): void {
+ this.windowService.isXsOrSm().pipe(
+ first()
+ ).subscribe((isMobile) => {
+ if (!isMobile) {
+ dropdown.close();
+ }
+ });
}
-
}
diff --git a/src/app/shared/animations/slide.ts b/src/app/shared/animations/slide.ts
index fa4a451863..20f63897ea 100644
--- a/src/app/shared/animations/slide.ts
+++ b/src/app/shared/animations/slide.ts
@@ -1,4 +1,4 @@
-import { animate, state, transition, trigger, style, stagger, query } from '@angular/animations';
+import { animate, state, style, transition, trigger } from '@angular/animations';
export const slide = trigger('slide', [
@@ -8,3 +8,12 @@ export const slide = trigger('slide', [
transition('expanded <=> collapsed', animate(250))
]);
+
+export const slideMobileNav = trigger('slideMobileNav', [
+
+ state('expanded', style({ height: '100vh' })),
+
+ state('collapsed', style({ height: 0 })),
+
+ transition('expanded <=> collapsed', animate(300))
+]);
diff --git a/src/styles/_bootstrap_variables.scss b/src/styles/_bootstrap_variables.scss
index ea89a3a0d5..7039a8c3c1 100644
--- a/src/styles/_bootstrap_variables.scss
+++ b/src/styles/_bootstrap_variables.scss
@@ -33,5 +33,6 @@ $navbar-dark-color: rgba(white, .5) !default;
$navbar-light-color: rgba(black, .5) !default;
$navbar-dark-toggler-icon-bg: url("data%3Aimage%2Fsvg+xml%3Bcharset%3Dutf8%2C%3Csvg+viewBox%3D%270+0+30+30%27+xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3Cpath+stroke%3D%27#{$navbar-dark-color}%27+stroke-width%3D%272%27+stroke-linecap%3D%27round%27+stroke-miterlimit%3D%2710%27+d%3D%27M4+7h22M4+15h22M4+23h22%27%2F%3E%3C%2Fsvg%3E");
$navbar-light-toggler-icon-bg: url("data%3Aimage%2Fsvg+xml%3Bcharset%3Dutf8%2C%3Csvg+viewBox%3D%270+0+30+30%27+xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3Cpath+stroke%3D%27#{$navbar-light-color}%27+stroke-width%3D%272%27+stroke-linecap%3D%27round%27+stroke-miterlimit%3D%2710%27+d%3D%27M4+7h22M4+15h22M4+23h22%27%2F%3E%3C%2Fsvg%3E");
+$dropdown-border-radius: 0px;
$enable-shadows: true !default;