Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: toggle menu when ion-split-pane is visible #18692

Open
IsaacHub opened this issue Jul 2, 2019 · 24 comments
Open

feat: toggle menu when ion-split-pane is visible #18692

IsaacHub opened this issue Jul 2, 2019 · 24 comments
Labels
package: core @ionic/core package type: feature request a new feature, enhancement, or improvement

Comments

@IsaacHub
Copy link

IsaacHub commented Jul 2, 2019

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.

ionicsplitpane

@ionitron-bot ionitron-bot bot added the triage label Jul 2, 2019
@IsaacHub IsaacHub changed the title Toggle (hamburger) menu not showing up while using ion-split-pane [ionic v4] Toggle (hamburger) menu not showing up while using ion-split-pane Jul 2, 2019
@joelmeaders
Copy link

joelmeaders commented Jul 2, 2019

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>

image

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>

image
image
...Sorry for all the edits lol

@brandyscarney
Copy link
Member

brandyscarney commented Jul 2, 2019

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: #18666

Thanks!

@IsaacHub
Copy link
Author

IsaacHub commented Jul 3, 2019

@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.

@quynh-ng
Copy link

quynh-ng commented Jul 7, 2019

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.

@brandyscarney brandyscarney reopened this Jul 8, 2019
@brandyscarney
Copy link
Member

@quynh-ng You are thinking of the following issue: #18666

This is fixed by #18702 but it has not been in a release yet.

@brandyscarney
Copy link
Member

@IsaacHub Thanks, I can update your original issue, but it was not clear from your description.

@brandyscarney brandyscarney changed the title [ionic v4] Toggle (hamburger) menu not showing up while using ion-split-pane feat: toggle menu when ion-split-pane is visible Jul 8, 2019
@brandyscarney brandyscarney added package: core @ionic/core package type: feature request a new feature, enhancement, or improvement labels Jul 8, 2019
@ionitron-bot ionitron-bot bot removed triage labels Jul 8, 2019
@daveshirman
Copy link

daveshirman commented Aug 20, 2019

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.

@joelmeaders
Copy link

@daveshirman I posted a detailed way to accomplish what you want here: #15538 (comment)

@daveshirman
Copy link

daveshirman commented Aug 22, 2019

@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.

@mickdelaney
Copy link

Is there a solution yet to the original problem ?
i.e. being able to collapse the menu on desktop ?

@joelmeaders
Copy link

joelmeaders commented Oct 29, 2019

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.

@corysmc
Copy link
Contributor

corysmc commented Jun 5, 2020

Here's my solution to this problem - works really well:

  1. when on a mobile size screen - the menu toggles open and close
  2. when on desktop the split pane displays the menu
  3. The menu icon still displays so you can close the menu while on desktop

ion-split-pane

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>

@IsaacHub
Copy link
Author

@corysmc I tried your code snippet, and it worked.

@cameronrr
Copy link

cameronrr commented Jul 20, 2020

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')
}

@siutau
Copy link

siutau commented Dec 28, 2020

Only you need to add when="false" in ion-menu-toggle

Example:

<ion-split-pane contentId="main-content" when="false">...</ion-split-pane>

@aacassandra
Copy link

aacassandra commented Jan 6, 2021

Only you need to add when="false" in ion-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.

@y0nd0
Copy link

y0nd0 commented Feb 6, 2021

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.

@vicatcu
Copy link

vicatcu commented Feb 11, 2021

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?

@y0nd0
Copy link

y0nd0 commented Feb 12, 2021

@vicatcu In short: No, because the menu button still not work in this case. (as I wrote).

@folencao
Copy link

folencao commented Aug 7, 2021

Only you need to add when="false" in ion-menu-toggle

Example:

<ion-split-pane contentId="main-content" when="false">...</ion-split-pane>

This is the best simple solution.

@RZMiRaN
Copy link

RZMiRaN commented Aug 26, 2021

@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?

@cgonza85
Copy link

cgonza85 commented Sep 15, 2023

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.

@GarryLowther
Copy link

Is anyone able to post a complete index.html page with this split pane effect working?

@ingbioservicios
Copy link

Esta funcionalidad, algún día estará disponible de forma nativa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: core @ionic/core package type: feature request a new feature, enhancement, or improvement
Projects
None yet
Development

No branches or pull requests