Search code examples
csslayoutng-zorro-antd

Issue with ng-zorro's layout - autocomplete box does not stay in position when scrolling


so I am having an issue with setting up NG-ZORROs layout

I have the following layout

HERE IS A STACKBLITZ EXAMPLE OF THE SETUP

  1. Where the HEADER should be fixed in position
  2. The SIDE NAVIGATION (on the left) should also be fixed in position when the user is scrolling the content, but it also has an internal scroll if the menu items dont fit the screen
  3. The CONTENT should have internal scroll so that

// WRAPPER
.wrapper {
  height: 100vh;
}

// HEADER
.header {
  color: white;
  background-color: rgb(24, 132, 255);
  height: 45px;
  display: flex;
  justify-content: center;
  position: fixed;
  z-index: 999999;
  width: 100%;
}

// SIDE NAV MENU
[nz-menu] {
  line-height: 64px;
  height: 100vh;
  overflow: auto;
}

[nz-menu]::-webkit-scrollbar {
  display: none;
}

// CONTENT
.input {
  border: solid 1px rgb(24, 132, 255);
}

.before {
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
  background-color: rgb(184, 216, 208);
  opacity: 0.3;
  height: 300px;
  align-items: center;
}

.after {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  background-color: rgb(184, 185, 216);
  opacity: 0.3;
  height: 800px;
  align-items: center;
}

// HERE IS WHERE THE ISSUE IS
nz-content {
  padding: 0 50px;
  margin-top: 64px;
  // WE NEED THE OVERFLOW SO THAT ONLY THE CONTENT IS SCROLLABLE AND THE REST OF THE ELEMENTS ARE NOT
  overflow: auto;
}
<nz-layout class="wrapper">
  <!-- HEADER -->
  <header class="header">
    HEADER
  </header>
  <nz-layout class="content">
    <!-- SIDE NAVIGATION -->
    <nz-sider nzCollapsible nzWidth="200px">
      <ul nz-menu nzMode="inline" nzTheme="dark" class="menu-children">
        <li nz-menu-item>
          <span>Menu 0</span>
        </li>
        <li nz-submenu *ngFor="let item of menuItems" (nzOpen)="openMap.menu+item"
          (nzOpenChange)="openHandler('menu'+ item)" nzTitle="{{'Menu' + item}}">
          <ul>
            <li *ngFor="let submenuItem of menuItems" nz-menu-item>
              Menu {{submenuItem}}
            </li>
          </ul>
        </li>

        <li nz-menu-item (click)="openHandler('menu11')">
          <span>Templates</span>
        </li>
      </ul>
    </nz-sider>

    <!-- CONTENT -->
    <nz-content>
      <!-- ONLY CONTENT IN THE NZ-CONTENT SHOULD BE SCROLLABLE -->
      <p class="before">
        CONTENT BEFORE SEARCHBAR
      </p>

      <!-- SEARCHBAR + AUTOCOMPLETE -->
      <nz-input-group class="search-wrapper" nzSize="large">
        <!-- INPUT -->
        <input
          class="input"
          type="text"
          nz-input
          placeholder="Click here and scroll..."
          [nzAutocomplete]="auto"
        />

        <!-- AUTOCOMPLETE -->
        <nz-autocomplete #auto>
          <nz-auto-option [nzDisabled]="true">
            <span class="no-results"> No Results </span>
          </nz-auto-option>
        </nz-autocomplete>
      </nz-input-group>

      <p class="after">
        CONTENT AFTER SEARCHBAR
      </p>
    </nz-content>
  </nz-layout>
</nz-layout>

My issue is that in order to achieve that i have set up the CONTENT with overflow: auto and everything works as expected... until I added a search bar with an autocomplete box.

Now when you click the search box and scroll on the content the autocomplete box stays in position instead of sticking to the input field of the the search bar - see image

HERE IS A STACKBLITZ EXAMPLE OF THE SETUP

I was able to do some hacky workarounds, but they dont work 100%.

Does anyone know why setting up the nz-content with overflow:auto breaks the autocomplete box position ?!


Solution

  • Ok, after a lot more research I was able to find a working solution to the problem.

    It turned out to be the following

    In the usage of tooltip (including popconfirm、popover), body element's scroll event will update the position of tooltip. It will never update the position of tooltip if the scroll event happens in a custom element.You can add cdkScrollable directive to achieve the goal. Take notice that you need to import relative package import {ScrollingModule} from '@angular/cdk/scrolling';, for more information you can visit scrolling/api.

    source - ng-zorro (bottom of the page)

    I also found this stackoverflow question about Material Design Autocomplete

    So based on those two, what ended up doing is I imported the ScrollingModule to my module like so

    import { ScrollingModule } from '@angular/cdk/scrolling';
    
    @NgModule({
       imports: [
       // ...
       ScrollingModule,
       ],
       // ...
     })
     export class MyAppModule { }
    

    and then just applying the cdkScrollable to NZ-CONTENT

    <nz-content cdkScrollable> CONTENT GOES HERE </nz-content>
    

    Here is a link with the working solution - line 37