Left/right buttons are misplaced in navbar?


#1

Hey guys,

tried to be clever and created my navbar as a component, as the functionality is often the same throughout the app, however I am getting some styling issues with left and right buttons in it.

One of my pages has the following in it.

<ion-header no-border-top no-border-top>
  <ion-navbar class="wb-navbar" primary>
    <wb-navbar pageName="Accounts"></wb-navbar>
  </ion-navbar>
</ion-header>

<ion-content #content class="accounts">
...

The <wb-navbar> is a component and is structured as following. Used left/right to override the platform start/end.

<ion-buttons *ngIf="showMenu === 'true'" left>
  <button (click)="openMenu()">
    <ion-icon name="menu"></ion-icon>
  </button>
</ion-buttons>

<ion-title>{{pageName}}</ion-title>

<ion-buttons *ngIf="showChat === 'true'" right>
  <button (click)="openChat()">
    <ion-icon name="chatboxes"></ion-icon>
  </button>
</ion-buttons>

Any ideas how I can either get the above to work, or a different approach to this?

Thanks


#2

I’ve had trouble in the past with using ngIf with ion-buttons. I’d try utilizing [hide] instead, i.e changing your header template to be…

<ion-buttons [hide]="showMenu === 'false'" left> <!--- This right here --->
  <button (click)="openMenu()">
    <ion-icon name="menu"></ion-icon>
  </button>
</ion-buttons>

<ion-title>{{pageName}}</ion-title>

<ion-buttons [hide]="showChat === 'false'" right> <!--- ...and this here -->
  <button (click)="openChat()">
    <ion-icon name="chatboxes"></ion-icon>
  </button>
</ion-buttons>

#3

Ah, was s hopeful that’d work, but no dice :confused:


#4

Try using it in a ion-row you can style ion-col with center, text-right or left, give them fixed widths etc

<ion-row>
<ion-col>
<ion-buttons *ngIf="showMenu === 'true'" left>
  <button (click)="openMenu()">
    <ion-icon name="menu"></ion-icon>
  </button>
</ion-buttons>
</ion-col>
<ion-col>
<ion-title>{{pageName}}</ion-title>
</ion-col>
<ion-col>
<ion-buttons *ngIf="showChat === 'true'" right>
  <button (click)="openChat()">
    <ion-icon name="chatboxes"></ion-icon>
  </button>
</ion-buttons>
</ion-col>
</ion-row>

#5

This is caused by the navbar’s content projection. The navbar component is looking for direct children elements in order to position them. Since you are wrapping the children elements in another element it can’t find them and is placing them incorrectly. Please see this issue:

You should be able to change it to something like this:

<ion-header no-border-top>
  <wb-navbar pageName="Accounts"></wb-navbar>
</ion-header>

then the wb-navbar template:

<ion-navbar class="wb-navbar" primary>
  <ion-buttons *ngIf="showMenu === 'true'" left>
    <button (click)="openMenu()">
      <ion-icon name="menu"></ion-icon>
    </button>
  </ion-buttons>

  <ion-title>{{pageName}}</ion-title>

  <ion-buttons *ngIf="showChat === 'true'" right>
    <button (click)="openChat()">
      <ion-icon name="chatboxes"></ion-icon>
    </button>
  </ion-buttons>
</ion-navbar>

Let me know if this doesn’t work. Thanks!


#6

Thanks for the reply Brandy.

So while that does work…sort of, the reason why I went away from that approach is in the iOS emulator, the top is now no longer calculated for as you can see below. Having the <ion-navbar> in there with the <ion-content> fixed that, but with the original issue with the button placement however :slight_smile:


#7

Yeah, so this is the problem with custom wrapper components. We can make them work with content projection and then we run into problems with styling. The styling needs to get the toolbar that is the first direct child of the header. So if you have the following markup:

<ion-header>
  <ion-navbar class="toolbar"></ion-navbar>
  <ion-toolbar class="toolbar"></ion-toolbar>
</ion-header>

It will look for ion-header > .toolbar:first-child because it doesn’t want to add any extra styling to the second toolbar. So when you wrap it in a custom component the markup ends up something like this:

<ion-header>
  <wb-navbar>
    <ion-navbar class="toolbar"></ion-navbar>
  </wb-navbar>
</ion-header>

and the .toolbar is no longer the direct child of the ion-header, nor would it be the first-child. As a workaround, you could copy the Sass that includes this function in your custom header:

It’s a rather complex issue to solve because when you start modifying the structure we no longer know which elements to look for. I hope that helps to explain why this is happening. We don’t have a great solution for this yet.


#8

I’ve got a similar problem with creating the header as a custom component. I tried the following solution, but this did not work. Since this was last updated in July, has there been any updated solution since?