Open IsaacHub opened 5 years ago
I had the same problem and found a fix. Previously I was just using:
<ion-buttons>
<ion-menu-button></ion-menu-button>
...other code
</ion-buttons>
To fix it, I am now using:
<ion-buttons>
<ion-menu-toggle color="light">
<ion-menu-button color="light"></ion-menu-button>
</ion-menu-toggle>
...other code
</ion-buttons>
...Sorry for all the edits lol
Thanks for the issue! If you just want the ion-menu-button
to always show, you can add the auto-hide
attribute / autoHide
property to the element.
I'm not sure what framework you're using, but in vanilla JS it would be:
<ion-menu-button auto-hide="false">
and in Angular:
<ion-menu-button autoHide="false">
Documentation on menu button properties: https://ionicframework.com/docs/api/menu-button#properties
If you're running into the problem where there is a space even though the menu button is hidden, please subscribe to this issue: https://github.com/ionic-team/ionic/issues/18666
Thanks!
@joelmeaders @brandyscarney You both completely got me wrong. I said I should be able to collapse and expand the side menu whenever I want. (I'm talking about desktop browser only). It's possible only if the menu button shows up. This is my requirement.
I have another choice and get rid of ion-split-pane
completely, and just use ion-menu
without wrapping in ion-split-pane
, but we have a problem with that also, it has only <ion-menu type="push | reveal | overlay">
these 3 options, and all these options pushes the content off-screen. This is not expected behavior.
I want the side-menu to be fixed, not overlay or something. It's unbelievable this tiny feature is missing from this popular framework.
I still got this issue even upgrade to dev version of 4.6.1 In previous version, the ion-menu-button works correctly with ion-split-pane: hide on large screen and shown on small screen. To get the expected behavior (in current dev version), need to wrap into ion-menu-toggle (just like the way of @joelmeaders does). This is just a bug of ion-menu-button component @brandyscarney.
@quynh-ng You are thinking of the following issue: https://github.com/ionic-team/ionic/issues/18666
This is fixed by https://github.com/ionic-team/ionic/pull/18702 but it has not been in a release yet.
@IsaacHub Thanks, I can update your original issue, but it was not clear from your description.
Solution: For anyone wanting a right side menu that is always hidden in a SplitPane, just put it outside the SplitPane in your app.html. Then just programmatically show/hide it using MenuController.open/close.
This should be documented!
@IsaacHub Did you ever find a fix for this? I have a right side menu that I want to optionally show/hide on desktop, same as you do with your left.
@brandyscarney How this still not a documented feature is beyond me!
Thanks.
@daveshirman I posted a detailed way to accomplish what you want here: https://github.com/ionic-team/ionic/issues/15538#issuecomment-479090705
@daveshirman I posted a detailed way to accomplish what you want here: #15538 (comment)
Thanks - I ended up (by chance) figuring out that you can just put the second menu outside the split pane and it works as I wanted, with the left menu collapsing as normal and the right one always hidden. See my edit. Don't know if that achieves anything different to your solution which I've read. Cheers!
Note: I see yours is V4, mine is V3.
Is there a solution yet to the original problem ? i.e. being able to collapse the menu on desktop ?
Is there a solution yet to the original problem ? i.e. being able to collapse the menu on desktop ?
If the menu is inside of a split pane use the "when" property on it. Pass in a boolean value of false. If it's false the menu is hidden on desktop unless it's swiped open or toggled. An observable in a singleton service does the trick nicely. It also plays nice with the toggle buttons and they're visible as they should be when the menu is not showing.
<ion-split-pane when="menuService.$showMenu | async">
You can also just pass in "false" right there in the HTML to quickly test it out.
Here's my solution to this problem - works really well:
toggleMenu() {
const splitPane = document.querySelector('ion-split-pane');
const windowWidth = window.innerWidth;
const splitPaneShownAt = 992;
const when = `(min-width: ${splitPaneShownAt}px)`;
if (windowWidth >= splitPaneShownAt) {
// split pane view is visible
const open = splitPane.when === when;
splitPane.when = open ? false : when;
} else {
// split pane view is not visible
// toggle menu open
const menu = splitPane.querySelector('ion-menu');
return menu.open();
}
}
Then in your view use an ion-button
instead of the ion-menu-button
:
<ion-buttons slot="start">
<ion-button onClick={() => this.toggleMenu()}>
<ion-icon name="menu" slot="icon-only" />
</ion-button>
</ion-buttons>
@corysmc I tried your code snippet, and it worked.
Add a click handler on the standard ion-menu-toggle button. Make sure 'auto-hide="false"' is set on the toggle so the button is always visible even in split pane mode.
In the event handler, check the ion-split-pane 'when' attribute against the ionic media query breakpoints (or directly if not using a breakpoint alias). If the screen width is large enough to usually show the split panel, toggle the visibility to toggle the menu display.
The default click handler to animate menu in single pane view still works as per normal.
<ion-buttons slot="start">
<ion-menu-toggle auto-hide="false" menu="main-menu">
<ion-button @click="toggleMenu">
<ion-icon slot="icon-only" name="menu"></ion-icon>
</ion-button>
</ion-menu-toggle>
</ion-buttons>
import { SIZE_TO_MEDIA } from '@ionic/core/dist/collection/utils/media'
toggleMenu: () => {
const splitPane = document.querySelector('ion-split-pane')
if (window.matchMedia(SIZE_TO_MEDIA[splitPane.when] || splitPane.when).matches)
splitPane.classList.toggle('split-pane-visible')
}
Only you need to add when="false"
in ion-menu-toggle
Example:
<ion-split-pane contentId="main-content" when="false">...</ion-split-pane>
Only you need to add
when="false"
inion-menu-toggle
Example:
<ion-split-pane contentId="main-content" when="false">...</ion-split-pane>
this method make a sidebar was autohide for first look
trick of @cameronrr, it works like a charm 🎉 but like a hacky, but unfortunately Ionic doesn't provide this functionality.
The current behavior is great. The only problem is that the menu button is not able to trigger the menu anymore when the split-pane shows the menu. The auto-hide="false"
option is useless in this case.
But I'm not sure if that will work with the split-pane. We need an drawer. The menu should work like type=push. But in this case the app content (e.g. router-outlet) should not be pushed, it should be act like a flex element. Complete width. The side menu should just take some width when displayed.
Other frameworks like Angular Material or Vuetify works like that. ...
But the current behavior of Ionic is also a great case. But some developer want to keep toggle the menu.
Isn't the actual solution to this to bind [when]="false"
to the ion-split-pane? ... or an application-specific boolean-valued variable that tracks whether or not the given ion-split-pane should be open or not?
@vicatcu In short: No, because the menu button still not work in this case. (as I wrote).
Only you need to add
when="false"
inion-menu-toggle
Example:
<ion-split-pane contentId="main-content" when="false">...</ion-split-pane>
This is the best simple solution.
@corysmc @cameronrr you guys are the best! I've been trying to animate the .split-pane-visible class, any idea how can I do that?
toggle menu in web format with animation, under the 992 it works normally, since only in web format the behavior was very rough.
Can be improve but it works.
<ion-split-pane contentId="main">
<ion-menu contentId="main">
...
</ion-menu>
<div class="ion-page" id="main">
<ion-header [translucent]="true">
<ion-toolbar>
<ion-buttons slot="start">
<ion-menu-button autoHide="false" (click)="toggleMenu()"></ion-menu-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-router-outlet></ion-router-outlet>
</div>
</ion-split-pane>
toggleMenu() {
const splitPane = document.querySelector('ion-split-pane');
if(splitPane) {
const main = splitPane.querySelector('#main');
const menu = splitPane.querySelector('ion-menu');
if(menu && main) {
main.classList.toggle('split-pane-main-hide-menu');
const windowWidth = window.innerWidth;
const splitPaneShownAt = 992;
if (windowWidth >= splitPaneShownAt) {
if(!main.classList.contains('split-pane-main-hide-menu')){
menu.classList.remove('menu-pane-visible-animation-out');
menu.classList.add('menu-pane-visible-animation-in');
} else {
menu.classList.add('menu-pane-visible-animation-out');
menu.classList.remove('menu-pane-visible-animation-in');
}
} else {
menu.classList.remove('menu-pane-visible-animation-in');
menu.classList.remove('menu-pane-visible-animation-out');
}
}
}
}
@keyframes slideInFromLeft {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}
@keyframes slideOutFromRight {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
.menu-pane-visible-animation-out {
animation: 0.5s ease 0s 1 slideOutFromRight;
}
.menu-pane-visible-animation-in {
animation: 0.5s ease 0s 1 slideInFromLeft;
}
.split-pane-visible > .ion-page.split-pane-main {
position: absolute;
margin-left: 300px;
}
.split-pane-main-hide-menu {
margin-left: 0px !important;
}
.ion-page.split-pane-main {
transition: all 500ms ease;
}
There is one thing that I could not solve, when changing the resolution manually the menu disappears without animation, but the content has animation so it is not very noticeable.
Is anyone able to post a complete index.html page with this split pane effect working?
I'm using
<ion-split-pane>
and I need the menu toggle button on all screen sizes, how can I achieve this?In desktop toggle menu doesn't appear, and
<ion-menu-button></ion-menu-button>
exists in all pages' toolbar.Toggle menu only show up in the mobile view, but I want this in desktop view also.