Notus Angular Dropdowns

An interactive menu that opens to the bottom of a button using Angular and Tailwind CSS.


For this component to properly work, you will need to install popper.js into your project. Please run the following: npm i -E @popperjs/core@2.4.4

import { Component, ViewChild, ElementRef } from '@angular/core';
import { createPopper } from '@popperjs/core';

@Component({
  selector: 'app-root',
  // templateUrl: './app.component.html',
  template: `<div class="flex flex-wrap">
  <div class="w-full sm:w-6/12 md:w-4/12 px-4">
    <div class="relative inline-flex align-middle w-full">
      <button class="text-white font-bold uppercase text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 bg-red-500 active:bg-red-600 ease-linear transition-all duration-150" type="button" (click)="toggleDropdown($event)" #btnDropdownRef>
        red Dropdown
      </button>
    </div>
  </div>
</div>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  dropdownPopoverShow = false;
  @ViewChild('btnDropdownRef',{ static: false }) btnDropdownRef:ElementRef;
  popper = document.createElement("div");
  ngOnInit() {
    this.popper.innerHTML = `<div class="bg-red-500 text-base z-50 float-left py-2 list-none text-left rounded shadow-lg mt-1 min-w-48" #popoverDropdownRef>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Action
  </a>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Another action
  </a>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Something else here
  </a>
  <div class="h-0 my-2 border border-solid border-t-0 border-blueGray-800 opacity-25"></div>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Seprated link
  </a>
</div>`;
  }
  toggleDropdown(){
    if(this.dropdownPopoverShow){
      this.dropdownPopoverShow = false;
      this.destroyPopper();
    } else {
      this.dropdownPopoverShow = true;
      this.createPoppper();
    }
  }
  destroyPopper(){
    this.popper.parentNode.removeChild(this.popper);
  }
  createPoppper(){
    createPopper(this.btnDropdownRef.nativeElement, this.popper, {
      placement: "bottom-start"
    });
    this.btnDropdownRef.nativeElement.parentNode.insertBefore(this.popper, this.btnDropdownRef.nativeElement.nextSibling);

  }
}

Dropup Example

import { Component, ViewChild, ElementRef } from '@angular/core';
import { createPopper } from '@popperjs/core';

@Component({
  selector: 'app-root',
  // templateUrl: './app.component.html',
  template: `<div class="flex flex-wrap">
  <div class="w-full sm:w-6/12 md:w-4/12 px-4">
    <div class="relative inline-flex align-middle w-full">
      <button class="text-white font-bold uppercase text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 bg-red-500 active:bg-red-600 ease-linear transition-all duration-150" type="button" (click)="toggleDropdown($event)" #btnDropdownRef>
        red Dropup
      </button>
    </div>
  </div>
</div>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  dropdownPopoverShow = false;
  @ViewChild('btnDropdownRef',{ static: false }) btnDropdownRef:ElementRef;
  popper = document.createElement("div");
  ngOnInit() {
    this.popper.innerHTML = `<div class="bg-red-500 text-base z-50 float-left py-2 list-none text-left rounded shadow-lg mt-1 min-w-48" #popoverDropdownRef>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Action
  </a>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Another action
  </a>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Something else here
  </a>
  <div class="h-0 my-2 border border-solid border-t-0 border-blueGray-800 opacity-25"></div>
  <a href="#pablo" class="text-sm py-2 px-4 font-normal block w-full whitespace-no-wrap bg-transparent text-white">
    Seprated link
  </a>
</div>`;
  }
  toggleDropdown(){
    if(this.dropdownPopoverShow){
      this.dropdownPopoverShow = false;
      this.destroyPopper();
    } else {
      this.dropdownPopoverShow = true;
      this.createPoppper();
    }
  }
  destroyPopper(){
    this.popper.parentNode.removeChild(this.popper);
  }
  createPoppper(){
    createPopper(this.btnDropdownRef.nativeElement, this.popper, {
      placement: "top"
    });
    this.btnDropdownRef.nativeElement.parentNode.insertBefore(this.popper, this.btnDropdownRef.nativeElement.nextSibling);

  }
}

Props

Please check the official PopperJS Documentation.

You can also check the Official PopperJS Github Repository.