mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Add mobile menu open button and close on click outside nav
- Adds gh-view-title component to implement mobile menu button for titles on any page - Refactors the `content-cover` out into the application template - Fix various z-index issues with content-cover and gh-alert - Move `.settings-menu-expanded` application view state from body to `.gh-viewport` - Unify nav menu / mobile menu actions and code
This commit is contained in:
parent
540a3215c9
commit
c7a9e726e2
25 changed files with 97 additions and 60 deletions
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
|
||||
Implements a div for covering the page content
|
||||
when in a menu context that, for example,
|
||||
should be closed when the user clicks elsewhere.
|
||||
|
||||
Example:
|
||||
```
|
||||
{{gh-content-cover onClick="closeMenus" onMouseEnter="closeAutoNav"}}
|
||||
```
|
||||
**/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
|
|
|
@ -9,14 +9,8 @@ export default Ember.Component.extend({
|
|||
|
||||
open: false,
|
||||
|
||||
autoNav: null,
|
||||
|
||||
mouseEnter: function () {
|
||||
if (!this.get('autoNav')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.set('open', true);
|
||||
this.sendAction('onMouseEnter');
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
|
9
core/client/app/components/gh-view-title.js
Normal file
9
core/client/app/components/gh-view-title.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
actions: {
|
||||
openMobileMenu () {
|
||||
this.sendAction('openMobileMenu');
|
||||
}
|
||||
}
|
||||
});
|
|
@ -8,23 +8,37 @@ export default Ember.Controller.extend({
|
|||
// jscs: enable
|
||||
|
||||
topNotificationCount: 0,
|
||||
showNavMenu: false,
|
||||
showMobileMenu: false,
|
||||
showSettingsMenu: false,
|
||||
|
||||
autoNav: false,
|
||||
autoNavOpen: Ember.computed('autoNav', {
|
||||
get () {
|
||||
return false;
|
||||
},
|
||||
set (key, value) {
|
||||
if (this.get('autoNav')) {
|
||||
return value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}),
|
||||
|
||||
actions: {
|
||||
topNotificationChange: function (count) {
|
||||
topNotificationChange (count) {
|
||||
this.set('topNotificationCount', count);
|
||||
},
|
||||
|
||||
closeNavMenu: function () {
|
||||
this.get('dropdown').closeDropdowns();
|
||||
this.set('showNavMenu', false);
|
||||
toggleAutoNav () {
|
||||
this.toggleProperty('autoNav');
|
||||
},
|
||||
|
||||
navMenuToggleMaximise: function () {
|
||||
this.toggleProperty('autoNav');
|
||||
openAutoNav () {
|
||||
this.set('autoNavOpen', true);
|
||||
},
|
||||
|
||||
closeAutoNav () {
|
||||
this.set('autoNavOpen', false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ export default Ember.Controller.extend({
|
|||
name = tag.get('name'),
|
||||
self = this;
|
||||
|
||||
this.send('closeSettingsMenu');
|
||||
this.send('closeMenus');
|
||||
|
||||
tag.destroyRecord().then(function () {
|
||||
self.get('notifications').showSuccess('Deleted ' + name);
|
||||
|
|
|
@ -48,7 +48,7 @@ var EditorBaseRoute = Ember.Mixin.create(styleBody, ShortcutsRoute, {
|
|||
deletedWithoutChanges = state.isDeleted &&
|
||||
(state.isSaving || !state.isDirty);
|
||||
|
||||
this.send('closeSettingsMenu');
|
||||
this.send('closeMenus');
|
||||
|
||||
if (!fromNewToEdit && !deletedWithoutChanges && controllerIsDirty) {
|
||||
transition.abort();
|
||||
|
|
|
@ -8,7 +8,7 @@ import ctrlOrCmd from 'ghost/utils/ctrl-or-cmd';
|
|||
|
||||
var shortcuts = {};
|
||||
|
||||
shortcuts.esc = {action: 'closePopups', scope: 'all'};
|
||||
shortcuts.esc = {action: 'closeMenus', scope: 'all'};
|
||||
shortcuts.enter = {action: 'confirmModal', scope: 'modal'};
|
||||
shortcuts[ctrlOrCmd + '+s'] = {action: 'save', scope: 'all'};
|
||||
|
||||
|
@ -30,30 +30,22 @@ export default Ember.Route.extend(ApplicationRouteMixin, ShortcutsRoute, {
|
|||
},
|
||||
|
||||
actions: {
|
||||
toggleGlobalMobileNav: function () {
|
||||
this.toggleProperty('controller.showGlobalMobileNav');
|
||||
openMobileMenu () {
|
||||
this.controller.set('showMobileMenu', true);
|
||||
},
|
||||
|
||||
openSettingsMenu: function () {
|
||||
this.set('controller.showSettingsMenu', true);
|
||||
this.controller.set('showSettingsMenu', true);
|
||||
},
|
||||
|
||||
closeSettingsMenu: function () {
|
||||
this.set('controller.showSettingsMenu', false);
|
||||
},
|
||||
|
||||
toggleSettingsMenu: function () {
|
||||
this.toggleProperty('controller.showSettingsMenu');
|
||||
},
|
||||
|
||||
closePopups: function () {
|
||||
closeMenus () {
|
||||
this.get('dropdown').closeDropdowns();
|
||||
this.get('notifications').closeAll();
|
||||
|
||||
// Close right outlet if open
|
||||
this.send('closeSettingsMenu');
|
||||
|
||||
this.send('closeModal');
|
||||
this.controller.setProperties({
|
||||
showSettingsMenu: false,
|
||||
showMobileMenu: false
|
||||
});
|
||||
},
|
||||
|
||||
signedIn: function () {
|
||||
|
|
|
@ -47,7 +47,7 @@ TagsRoute = AuthenticatedRoute.extend(CurrentUserSettings, PaginationRouteMixin,
|
|||
|
||||
actions: {
|
||||
willTransition: function () {
|
||||
this.send('closeSettingsMenu');
|
||||
this.send('closeMenus');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
|
||||
/* Base alert style */
|
||||
.gh-alert {
|
||||
z-index: 1000;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
transform: translate3d(350px, 0px, 0px);
|
||||
}
|
||||
|
||||
body.settings-menu-expanded .settings-menu-container {
|
||||
.settings-menu-expanded .settings-menu-container {
|
||||
transform: translate3d(0, 0px, 0px);
|
||||
}
|
||||
|
||||
|
@ -153,14 +153,20 @@ body.settings-menu-expanded .settings-menu-container {
|
|||
/* Background
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
body.settings-menu-expanded .content-cover {
|
||||
.settings-menu-expanded .content-cover,
|
||||
.mobile-menu-expanded .content-cover {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 600;
|
||||
z-index: 900;
|
||||
transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);
|
||||
transform: translate3d(-350px, 0px, 0px);
|
||||
/* Not off the screen, to give a parallax effect */
|
||||
}
|
||||
.settings-menu-expanded .content-cover {
|
||||
transform: translate3d(-350px, 0px, 0px);
|
||||
}
|
||||
.mobile-menu-expanded .content-cover {
|
||||
transform: translate3d(235px, 0px, 0px);
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@
|
|||
}
|
||||
|
||||
/* Bring it back on toggle */
|
||||
.gh-main.open {
|
||||
.mobile-menu-expanded .gh-main {
|
||||
transition: transform 0.10s;
|
||||
transform: translate3d(235px,0,0);
|
||||
}
|
||||
|
@ -256,7 +256,7 @@
|
|||
.gh-nav {
|
||||
width: 75vw;
|
||||
}
|
||||
.gh-main.open {
|
||||
.mobile-menu-expanded .gh-main {
|
||||
transform: translate3d(75vw,0,0);
|
||||
}
|
||||
}
|
||||
|
@ -264,6 +264,10 @@
|
|||
|
||||
/* Auto Nav - Opens and closes like OSX dock
|
||||
/* ---------------------------------------------------------- */
|
||||
/* Autonav is hidden on mobile */
|
||||
.gh-autonav-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 801px) {
|
||||
.gh-autonav-toggle {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{{render 'post-tags-input'}}
|
||||
|
||||
<div class="publish-bar-actions">
|
||||
<button type="button" class="post-settings" {{action "toggleSettingsMenu"}}>
|
||||
<button type="button" class="post-settings" {{action "openSettingsMenu"}}>
|
||||
<i class="icon-settings"></i>
|
||||
</button>
|
||||
{{view "editor-save-button" id="entry-actions" classNameBindings="model.isNew:unsaved"}}
|
||||
|
|
|
@ -2,19 +2,22 @@
|
|||
|
||||
{{gh-alerts notify="topNotificationChange"}}
|
||||
|
||||
<div class="gh-viewport {{if autoNav 'gh-autonav'}}">
|
||||
<div class="gh-viewport {{if autoNav 'gh-autonav'}} {{if showSettingsMenu 'settings-menu-expanded'}} {{if showMobileMenu 'mobile-menu-expanded'}}">
|
||||
|
||||
{{#unless signedOut}}
|
||||
{{gh-nav-menu open=showNavMenu autoNav=autoNav toggleMaximise="navMenuToggleMaximise" openModal="openModal"}}
|
||||
{{gh-nav-menu open=autoNavOpen onMouseEnter="openAutoNav" toggleMaximise="toggleAutoNav" openModal="openModal"}}
|
||||
{{/unless}}
|
||||
|
||||
{{#gh-main onMouseEnter="closeNavMenu" data-notification-count=topNotificationCount}}
|
||||
{{#gh-main onMouseEnter="closeAutoNav" data-notification-count=topNotificationCount}}
|
||||
{{outlet}}
|
||||
{{/gh-main}}
|
||||
|
||||
|
||||
{{gh-notifications}}
|
||||
|
||||
{{gh-content-cover onClick="closeMenus" onMouseEnter="closeAutoNav"}}
|
||||
|
||||
{{outlet "modal"}}
|
||||
{{outlet "settings-menu"}}
|
||||
|
||||
</div>{{!gh-viewport}}
|
||||
</div>{{!gh-viewport}}
|
||||
|
|
1
core/client/app/templates/components/gh-view-title.hbs
Normal file
1
core/client/app/templates/components/gh-view-title.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
<h2 class="view-title"><button {{action "openMobileMenu"}} class="gh-mobilemenu-button" role="presentation"><i class="icon-gh"><span class="sr-only">Menu</span></i></button> {{yield}}</h2>
|
|
@ -1,11 +1,9 @@
|
|||
{{gh-content-cover onClick="closeSettingsMenu" onMouseEnter="closeNavMenu"}}
|
||||
|
||||
{{#gh-tabs-manager selected="showSubview" id="entry-controls" class="settings-menu-container"}}
|
||||
<div id="entry-controls">
|
||||
<div class="{{if isViewingSubview 'settings-menu-pane-out-left' 'settings-menu-pane-in'}} settings-menu settings-menu-pane">
|
||||
<div class="settings-menu-header">
|
||||
<h4>Post Settings</h4>
|
||||
<button class="close icon-x settings-menu-header-action" {{action "closeSettingsMenu"}}><span class="hidden">Close</span></button>
|
||||
<button class="close icon-x settings-menu-header-action" {{action "closeMenus"}}><span class="hidden">Close</span></button>
|
||||
</div>
|
||||
<div class="settings-menu-content">
|
||||
{{gh-uploader uploaded="setCoverImage" canceled="clearCoverImage" description="Add post image" image=model.image uploaderReference=uploaderReference tagName="section"}}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header class="view-header">
|
||||
<h2 class="view-title">Apps</h2>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}Apps{{/gh-view-title}}
|
||||
</header>
|
||||
|
||||
<section class="view-content settings-apps">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header class="view-header">
|
||||
<h2 class="view-title">Code Injection</h2>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}Code Injection{{/gh-view-title}}
|
||||
<section class="view-actions">
|
||||
<button type="button" class="btn btn-blue" {{action "save"}}>Save</button>
|
||||
</section>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header class="view-header">
|
||||
<h2 class="view-title"><button class="gh-mobilemenu-button" role="presentation"><i class="icon-gh"><span class="sr-only">Menu</span></i></button> General</h2>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}General{{/gh-view-title}}
|
||||
<section class="view-actions">
|
||||
<button type="button" class="btn btn-blue" {{action "save"}}>Save</button>
|
||||
</section>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header class="view-header">
|
||||
<h2 class="view-title">Labs</h2>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}Labs{{/gh-view-title}}
|
||||
</header>
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header class="view-header">
|
||||
<h2 class="view-title">Navigation</h2>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}Navigation{{/gh-view-title}}
|
||||
<section class="view-actions">
|
||||
<button type="button" class="btn btn-blue" {{action "save"}}>Save</button>
|
||||
</section>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header class="view-header">
|
||||
<h2 class="view-title">Tags</h2>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}Tags{{/gh-view-title}}
|
||||
<section class="view-actions">
|
||||
<button type="button" class="btn btn-green" {{action "newTag"}}>New Tag</button>
|
||||
</section>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
{{gh-content-cover onClick="closeSettingsMenu" onMouseEnter="closeNavMenu"}}
|
||||
|
||||
{{#gh-tabs-manager selected="showSubview" class="settings-menu-container"}}
|
||||
<div class="{{if isViewingSubview 'settings-menu-pane-out-left' 'settings-menu-pane-in'}} settings-menu settings-menu-pane">
|
||||
<div class="settings-menu-header">
|
||||
<h4>Tag Settings</h4>
|
||||
<button class="close icon-x settings-menu-header-action" {{action "closeSettingsMenu"}}>
|
||||
<button class="close icon-x settings-menu-header-action" {{action "closeMenus"}}>
|
||||
<span class="hidden">Close</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<header class="view-header">
|
||||
<h1 class="view-title">Team</h1>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}Team{{/gh-view-title}}
|
||||
<section class="view-actions">
|
||||
<button class="btn btn-green" {{action "openModal" "invite-new-user"}} >Invite People</button>
|
||||
</section>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<header class="view-header">
|
||||
<h2 class="view-title">{{#link-to "settings.users"}}Team{{/link-to}} <i class="icon-arrow-right"></i> {{user.name}}</h2>
|
||||
{{#gh-view-title openMobileMenu="openMobileMenu"}}
|
||||
{{#link-to "settings.users"}}Team{{/link-to}} <i class="icon-arrow-right"></i> {{user.name}}
|
||||
{{/gh-view-title}}
|
||||
<section class="view-actions">
|
||||
{{#if view.userActionsAreVisible}}
|
||||
<span class="dropdown">
|
||||
|
|
|
@ -5,7 +5,10 @@ var MobileContentView = Ember.View.extend({
|
|||
// Ensure that loading this view brings it into view on mobile
|
||||
showContent: function () {
|
||||
if (mobileQuery.matches) {
|
||||
this.get('parentView').showContent();
|
||||
var parent = this.get('parentView');
|
||||
if (parent.showContent) {
|
||||
parent.showContent();
|
||||
}
|
||||
}
|
||||
}.on('didInsertElement')
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue