diff --git a/core/client/assets/sass/components/navigation.scss b/core/client/assets/sass/components/navigation.scss index d7bfcb3373..49e1faf793 100644 --- a/core/client/assets/sass/components/navigation.scss +++ b/core/client/assets/sass/components/navigation.scss @@ -205,7 +205,7 @@ body.right-outlet-expanded & { display: block; } - &.global-nav-expanded { + body.global-nav-expanded & { transform: translate3d(0, 0px, 0px); } } @@ -257,13 +257,13 @@ body.right-outlet-expanded & { bottom: 0; left: 0; height: auto; - padding: 15px; + padding: 0; border-bottom: none; border-top: $darkgrey 1px solid; transition: color 0.5s, background 0.5s; .nav-label { - padding: 0; + padding: 15px; height: auto; } @@ -301,5 +301,28 @@ body.right-outlet-expanded & { } } + .dropdown .dropdown-menu { + top: auto; + right: auto; + bottom: calc(100% + 80px); + left: 10px; + } + + }//.user-menu + + body.global-nav-expanded & { + + .nav-cover { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 600; + transition: transform $side-outlet-transition-duration cubic-bezier(0.1, 0.7, 0.1, 1); + transform: translate3d(260px, 0px, 0px); // Not off the screen, to give a parallax effect + }//.nav-cover + }//body.global-nav-expanded + } \ No newline at end of file diff --git a/core/client/assets/sass/layouts/default.scss b/core/client/assets/sass/layouts/default.scss index 220540d6ff..9809e6d986 100644 --- a/core/client/assets/sass/layouts/default.scss +++ b/core/client/assets/sass/layouts/default.scss @@ -30,7 +30,7 @@ transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); } - &.global-nav-expanded { + body.global-nav-expanded & { transform: translate3d(260px, 0px, 0px); } diff --git a/core/client/controllers/application.js b/core/client/controllers/application.js index c8c1881922..4bf4e2ef88 100644 --- a/core/client/controllers/application.js +++ b/core/client/controllers/application.js @@ -2,6 +2,7 @@ var ApplicationController = Ember.Controller.extend({ hideNav: Ember.computed.match('currentPath', /(error|signin|signup|setup|forgotten|reset)/), topNotificationCount: 0, + showGlobalMobileNav: false, actions: { toggleMenu: function () { diff --git a/core/client/routes/application.js b/core/client/routes/application.js index 30800a7e6d..b8497502b5 100644 --- a/core/client/routes/application.js +++ b/core/client/routes/application.js @@ -25,6 +25,10 @@ var ApplicationRoute = Ember.Route.extend(SimpleAuth.ApplicationRouteMixin, Shor this._super(); }, + toggleGlobalMobileNav: function () { + this.toggleProperty('controller.showGlobalMobileNav'); + }, + closePopups: function () { this.get('popover').closePopovers(); this.get('notifications').closeAll(); diff --git a/core/client/templates/-navbar.hbs b/core/client/templates/-navbar.hbs index 4d3de563a6..852cb80fb1 100644 --- a/core/client/templates/-navbar.hbs +++ b/core/client/templates/-navbar.hbs @@ -4,16 +4,16 @@ <div class="nav-label"><i class="icon-ghost"></i> <span>Visit blog</span> </div> </a> - {{#link-to "posts" classNames="nav-item nav-content"}} + {{#link-to "posts" classNames="nav-item nav-content js-nav-item"}} <div class="nav-label"><i class="icon-content"></i> Content</div> {{/link-to}} - {{#link-to "editor.new" classNames="nav-item nav-new"}} + {{#link-to "editor.new" classNames="nav-item nav-new js-nav-item"}} <div class="nav-label"><i class="icon-add"></i> New Post</div> {{/link-to}} {{#unless session.user.isAuthor}} - {{#link-to "settings" classNames="nav-item nav-settings"}} + {{#link-to "settings" classNames="nav-item nav-settings js-nav-item"}} <div class="nav-label"><i class="icon-settings2"></i> Settings</div> {{/link-to}} {{/unless}} @@ -30,7 +30,7 @@ }} <div class="nav-item user-menu" data-href="#"> - {{#gh-popover-button popoverName="user-menu" tagName="div" classNames="nav-label"}} + {{#gh-popover-button popoverName="user-menu" tagName="div" classNames="nav-label clearfix"}} {{#if session.user.image}} <div class="image"><img {{bind-attr src="session.user.image"}} alt="{{session.user.name}}'s profile picture" /></div> {{else}} @@ -42,8 +42,8 @@ </div> {{/gh-popover-button}} {{#gh-popover tagName="div" classNames="dropdown" name="user-menu" closeOnClick="true"}} - <ul class="dropdown-menu dropdown-triangle-top-right" role="menu"> - <li role="presentation">{{#link-to "settings.users.user" session.user.slug classNames="dropdown-item user-menu-profile" role="menuitem" tabindex="-1"}}Your Profile{{/link-to}}</li> + <ul class="dropdown-menu dropdown-triangle-top-right js-user-menu-dropdown-menu" role="menu"> + <li role="presentation">{{#link-to "settings.users.user" session.user.slug classNames="dropdown-item user-menu-profile js-nav-item" role="menuitem" tabindex="-1"}}Your Profile{{/link-to}}</li> <li role="presentation"><a class="dropdown-item user-menu-support" role="menuitem" tabindex="-1" href="http://support.ghost.org/">Help / Support</a></li> <li class="divider"></li> <li role="presentation">{{#link-to "signout" classNames="dropdown-item user-menu-signout" role="menuitem" tabindex="-1"}}Sign Out{{/link-to}}</li> @@ -51,4 +51,6 @@ {{/gh-popover}} </div>{{! .user-menu }} -</nav>{{! .global-nav }} \ No newline at end of file +</nav>{{! .global-nav }} + +<div class="nav-cover js-nav-cover"></div> \ No newline at end of file diff --git a/core/client/templates/editor/edit.hbs b/core/client/templates/editor/edit.hbs index 9b29c76760..075eda1cdd 100644 --- a/core/client/templates/editor/edit.hbs +++ b/core/client/templates/editor/edit.hbs @@ -1,5 +1,5 @@ <header class="page-header"> - <a class="menu-button" href="#"><span class="sr-only">Menu</span></a> + <button class="menu-button js-menu-button" {{action "toggleGlobalMobileNav"}}><span class="sr-only">Menu</span></button> <h2 class="page-title">Editor</h2> </header> diff --git a/core/client/templates/posts.hbs b/core/client/templates/posts.hbs index e9caf0dfc7..e95d0d679e 100644 --- a/core/client/templates/posts.hbs +++ b/core/client/templates/posts.hbs @@ -1,5 +1,5 @@ <header class="page-header"> - <a class="menu-button" href="#"><span class="sr-only">Menu</span></a> + <button class="menu-button js-menu-button" {{action "toggleGlobalMobileNav"}}><span class="sr-only">Menu</span></button> <h2 class="page-title">Content</h2> </header> diff --git a/core/client/templates/settings.hbs b/core/client/templates/settings.hbs index 562d692ca5..a7d8b4cc10 100644 --- a/core/client/templates/settings.hbs +++ b/core/client/templates/settings.hbs @@ -1,5 +1,5 @@ <header class="page-header"> - <a class="menu-button" href="#"><span class="sr-only">Menu</span></a> + <button class="menu-button js-menu-button" {{action "toggleGlobalMobileNav"}}><span class="sr-only">Menu</span></button> <h2 class="page-title">Settings</h2> </header> diff --git a/core/client/views/application.js b/core/client/views/application.js index d6feba6fca..28e25e42f9 100644 --- a/core/client/views/application.js +++ b/core/client/views/application.js @@ -1,18 +1,61 @@ +import {mobileQuery} from 'ghost/utils/mobile'; + var ApplicationView = Ember.View.extend({ blogRoot: Ember.computed.alias('controller.ghostPaths.blogRoot'), - - setupCloseSidebar: function () { + + setupGlobalMobileNav: function () { // #### Navigating within the sidebar closes it. - $(document).on('click', '.js-close-sidebar', function () { - $('body').removeClass('off-canvas'); + var self = this; + $('body').on('click', '.js-nav-item', function () { + if (mobileQuery.matches) { + self.set('controller.showGlobalMobileNav', false); + } }); + + // #### Close the nav if mobile and clicking outside of the nav or not the burger toggle + $('.js-nav-cover').on('click', function () { + var isOpen = self.get('controller.showGlobalMobileNav'); + if (isOpen) { + self.set('controller.showGlobalMobileNav', false); + } + }); + + // #### Listen to the viewport and change user-menu dropdown triangle classes accordingly + mobileQuery.addListener(this.swapUserMenuPopoverTriangleClasses); + this.swapUserMenuPopoverTriangleClasses(mobileQuery); + }.on('didInsertElement'), - - actions: { - toggleSidebar: function () { - $('body').toggleClass('off-canvas'); + + swapUserMenuPopoverTriangleClasses: function (mq) { + if (mq.matches) { + $('.js-user-menu-dropdown-menu').removeClass('dropdown-triangle-top-right ').addClass('dropdown-triangle-bottom'); + } else { + $('.js-user-menu-dropdown-menu').removeClass('dropdown-triangle-bottom').addClass('dropdown-triangle-top-right'); } - } + }, + + showGlobalMobileNavObserver: function () { + if (this.get('controller.showGlobalMobileNav')) { + $('body').addClass('global-nav-expanded'); + } else { + $('body').removeClass('global-nav-expanded'); + } + }.observes('controller.showGlobalMobileNav'), + + setupCloseNavOnDesktop: function () { + this.set('closeGlobalMobileNavOnDesktop', _.bind(function closeGlobalMobileNavOnDesktop(mq) { + if (!mq.matches) { + // Is desktop sized + this.set('controller.showGlobalMobileNav', false); + } + }, this)); + mobileQuery.addListener(this.closeGlobalMobileNavOnDesktop); + }.on('didInsertElement'), + + removeCloseNavOnDesktop: function () { + mobileQuery.removeListener(this.closeGlobalMobileNavOnDesktop); + }.on('willDestroyElement'), + }); export default ApplicationView;