mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-15 03:01:37 -05:00
Merge pull request #5368 from novaugust/zelda-mobile-nav
Zelda mobile nav
This commit is contained in:
commit
d5ffffb034
26 changed files with 200 additions and 105 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);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
position: relative;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,65 +207,126 @@
|
|||
}
|
||||
|
||||
|
||||
/* Auto Nav - Opens and closes like OSX dock
|
||||
/* Mobile Nav
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
.gh-autonav-toggle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 5px 10px;
|
||||
width: 45px;
|
||||
height: 27px;
|
||||
border-right: #e1e1e1 1px solid;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
.gh-mobilemenu-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gh-autonav-toggle:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.gh-mobilemenu-button {
|
||||
flex-shrink: 0;
|
||||
display: block;
|
||||
margin: 0 5px 0 -10px;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.gh-autonav-toggle i {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.gh-mobilemenu-button .icon-gh {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.gh-autonav-toggle:hover i {
|
||||
color: var(--blue);
|
||||
}
|
||||
/* Hide the nav */
|
||||
.gh-nav {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 500;
|
||||
width: 235px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Hide the nav */
|
||||
.gh-autonav .gh-nav {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
width: 235px;
|
||||
height: 100%;
|
||||
transition: transform 0.20s;
|
||||
/* translate3d for GPU accelerated animation - http://bit.ly/1EY1Xhx */
|
||||
transform: translate3d(-220px,0,0);
|
||||
}
|
||||
.gh-main {
|
||||
z-index: 1000;
|
||||
transition: transform 0.15s;
|
||||
/* translate3d for GPU accelerated animation - http://bit.ly/1EY1Xhx */
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
/* THE FUTURE: Super sexy background blur for Webkit - http://cl.ly/b1rG */
|
||||
@supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) {
|
||||
.gh-autonav .gh-nav {
|
||||
background: rgba(246,246,246, 0.7);
|
||||
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
/* Bring it back on toggle */
|
||||
.mobile-menu-expanded .gh-main {
|
||||
transition: transform 0.10s;
|
||||
transform: translate3d(235px,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Bring it back on hover */
|
||||
.gh-autonav .gh-nav.open {
|
||||
transition: transform 0.15s;
|
||||
transform: translate3d(0,0,0);
|
||||
@media (max-width: 500px) {
|
||||
.gh-nav {
|
||||
width: 75vw;
|
||||
}
|
||||
.mobile-menu-expanded .gh-main {
|
||||
transform: translate3d(75vw,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Move main content over for the closed-nav trigger bar */
|
||||
.gh-autonav .gh-main {
|
||||
margin-left: 15px;
|
||||
|
||||
/* 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 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 5px 10px;
|
||||
width: 45px;
|
||||
height: 27px;
|
||||
border-right: #e1e1e1 1px solid;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gh-autonav-toggle:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gh-autonav-toggle i {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.gh-autonav-toggle:hover i {
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
/* Hide the nav */
|
||||
.gh-autonav .gh-nav {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
width: 235px;
|
||||
height: 100%;
|
||||
transition: transform 0.20s;
|
||||
/* translate3d for GPU accelerated animation - http://bit.ly/1EY1Xhx */
|
||||
transform: translate3d(-220px,0,0);
|
||||
}
|
||||
|
||||
/* THE FUTURE: Super sexy background blur for Webkit - http://cl.ly/b1rG */
|
||||
@supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) {
|
||||
.gh-autonav .gh-nav {
|
||||
background: rgba(246,246,246, 0.7);
|
||||
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Bring it back on hover */
|
||||
.gh-autonav .gh-nav.open {
|
||||
transition: transform 0.15s;
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
/* Move main content over for the closed-nav trigger bar */
|
||||
.gh-autonav .gh-main {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -2,7 +2,7 @@
|
|||
<h2 class="view-title gh-editor-title">{{gh-trim-focus-input type="text" id="entry-title" class="gh-input" placeholder="Your Post Title" value=model.titleScratch
|
||||
tabindex="1" focus=shouldFocusTitle}}</h2>
|
||||
<section class="view-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"}}
|
||||
|
|
|
@ -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">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