File

projects/tl-elements/src/lib/tl-mega-menu/tl-mega-menu.component.ts

Extends

TamuAbstractBaseComponent

Implements

AfterContentInit

Metadata

Index

Properties
Methods
Inputs
HostBindings
HostListeners
Accessors

Constructor

constructor(injector: Injector)
Parameters :
Name Type Optional
injector Injector No

Inputs

menuTitle
Type : string
Default value : 'Mega Menu'

The default text value to be displayed for tl-mega menu title.

openDelay
Type : number
Default value : 50

This property determines the delay in milliseconds the dropdown takes prior to display on mouse hover.

outOfHeader
Type : boolean
Default value : false

The boolean variable enables proper header display on window resize.

viewAllButtonText
Type : string

This variable allows customizing the text value of View All button in the mega menu.

viewAllHref
Type : any

This allows to provide href value for tl mega menu section href.

inheritFontStyle
Type : "true" | "false"

HostBindings

style.--tl-mobile-display-max-height
Type : string
Default value : '0px'

Allows for the override of the --tl-mobile-display-max-height variable.

style.--tl-font-family-sans-serif
Type : string
Default value : 'var(--tl-default-font-family-sans-serif)'

Allows for the override of the --tl-font-family-sans-serif css variable.

style.--tl-font-size
Type : string
Default value : 'var(--tl-default-font-size)'

Allows for the override of the --tl-default-font-size css variable.

HostListeners

window:resize
window:resize()

This event listener on window resize event helps the header for proper display.

Methods

addSection
addSection(section: TlMegaMenuSectionComponent)
Parameters :
Name Type Optional
section TlMegaMenuSectionComponent No
Returns : void
calculateMenuXOffset
calculateMenuXOffset()
Decorators :
@HostListener('window:resize')
@debounce()

This event listener on window resize event helps the header for proper display.

Returns : void
ngAfterContentInit
ngAfterContentInit()

This adjusts the dropdown menu x offset on page load.

Returns : void
toggleMobileMenuOpen
toggleMobileMenuOpen()

This toggles the display of mobile menu on click event.

Returns : void

Properties

active
Default value : false
menuXOffset
Type : number
Default value : 0

This property determines the mega menu dropdown x-offset.

mobileDisplayMaxHeight
Type : string
Default value : '0px'
Decorators :
@HostBinding('style.--tl-mobile-display-max-height')

Allows for the override of the --tl-mobile-display-max-height variable.

Private Readonly sections
Type : Array<TlMegaMenuSectionComponent>
Private sectionTitleHeight
Type : number
Default value : 0
variantTypes
Type : []
Default value : ['button']
_fontFamily
Type : string
Default value : 'var(--tl-default-font-family-sans-serif)'
Decorators :
@HostBinding('style.--tl-font-family-sans-serif')

Allows for the override of the --tl-font-family-sans-serif css variable.

_fontSize
Type : string
Default value : 'var(--tl-default-font-size)'
Decorators :
@HostBinding('style.--tl-font-size')

Allows for the override of the --tl-default-font-size css variable.

Accessors

viewAllButtonDisplayText
getviewAllButtonDisplayText()

This returns customized text or the default value to be displayed on the mega menu View All button.

Returns : string
import { AfterContentInit, ChangeDetectionStrategy, Component, HostBinding, HostListener, Injector, Input } from '@angular/core';
import { debounce, wvrTimeout } from '@wvr/elements';
import { TamuAbstractBaseComponent } from '../shared/tl-abstract-base.component';
import { TlMegaMenuSectionComponent } from './tl-mega-menu-section/tl-mega-menu-section.component';

@Component({
  selector: 'tl-mega-menu-component',
  templateUrl: './tl-mega-menu.component.html',
  styleUrls: ['./tl-mega-menu.component.scss'],
  changeDetection: ChangeDetectionStrategy.Default
})
export class TlMegaMenuComponent extends TamuAbstractBaseComponent implements AfterContentInit {

  /** The default text value to be displayed for tl-mega menu title. */
  @Input() menuTitle = 'Mega Menu';

  /** This allows to provide href value for tl mega menu section href. */
  @Input() viewAllHref;

  /** The boolean variable enables proper header display on window resize. */
  @Input() outOfHeader = false;

  /** This property determines the mega menu dropdown x-offset. */
  menuXOffset = 0;

  /** This variable allows customizing the text value of View All button in the mega menu. */
  @Input() viewAllButtonText: string;

  active = false;

  /** This property determines the delay in milliseconds the dropdown takes prior to display on mouse hover. */
  @Input() openDelay = 50;

  /** This returns customized text or the default value to be displayed on the mega menu View All button. */
  get viewAllButtonDisplayText(): string {
    return this.viewAllButtonText ? this.viewAllButtonText : `View All ${this.menuTitle}`;
  }

  /** Allows for the override of the --tl-mobile-display-max-height variable. */
  @HostBinding('style.--tl-mobile-display-max-height') mobileDisplayMaxHeight = '0px';

  private readonly sections: Array<TlMegaMenuSectionComponent>;

  private sectionTitleHeight = 0;

  variantTypes = ['button'];

  // tslint:disable-next-line:unnecessary-constructor
  constructor(injector: Injector) {
    super(injector);
    this.sections = new Array<TlMegaMenuSectionComponent>();
  }

  /** This adjusts the dropdown menu x offset on page load. */
  ngAfterContentInit(): void {
    super.ngAfterContentInit();
    wvrTimeout(() => {
      this.calculateMenuXOffset();
    });
  }

  addSection(section: TlMegaMenuSectionComponent): void {
    this.sections.push(section);
    this.sectionTitleHeight = section.getElementHeight() > this.sectionTitleHeight
      ? section.getElementHeight()
      : this.sectionTitleHeight;
  }

  /** This toggles the display of mobile menu on click event. */
  toggleMobileMenuOpen(): void {
    this.mobileDisplayMaxHeight = `${this.sections.length * this.sectionTitleHeight}px`;

    if (this.active) {
      this.sections.forEach(s => {
        s.close();
      });
      this.active = false;
    } else {
      this.active = true;
    }
  }

  /** This event listener on window resize event helps the header for proper display. */
  @HostListener('window:resize') @debounce() calculateMenuXOffset(): void {
    if (!this.outOfHeader) {
      const nativeElem = this.eRef.nativeElement as HTMLElement;
      const header = document.querySelector('tl-header');
      if (!header) { return; }
      const bottomNav = header.shadowRoot.querySelector('div[bottom-navigation]');
      if (bottomNav) {
        let wvrBtn;
        const frameReq = requestAnimationFrame(() => {
          wvrBtn = nativeElem.querySelector('wvr-button-component');
          if (wvrBtn && bottomNav.children.length >= 2) {
            this.menuXOffset = (bottomNav.children[1] as HTMLElement).offsetLeft - nativeElem.parentElement.offsetLeft;
            cancelAnimationFrame(frameReq);
          }
        });
      }
    }
  }

}
<wvr-dropdown-component
  [themeVariant]="'link'"
  [toggleOn]="'mouseover'"
  menuXOffset="{{menuXOffset}}px"
  [menuYOffset]="'-2px'"
  [menuWidth]="'928px'"
  [btnTextDecoration]="'none'"
  [btnColor]="'var(--tl-black)'"
  [btnFontWeight]="'bolder'"
  [btnColorHover]="'var(--tl-black)'"
  [btnTextDecorationHover]="'none'"
  [btnFontFamily]="'var(--tl-font-family-sans-serif)'"
  [ngClass]="{active: active}"
  [openDelay]="openDelay"
  ngbDropdownAnchor>
  <template dropdown-button>
    <span (click)="toggleMobileMenuOpen()">
      {{menuTitle}}
      <tl-icon-component
        class="x-icon"
        [hiddenInMobile]="true"
        [set]="'bootstrap'"
        [name]="'caret-right-fill'"
        [size]="'11px'">
      </tl-icon-component>
      <tl-icon-component
        class="plus-icon"
        [set]="'bootstrap'"
        [name]="'plus'"
        [size]="'24px'">
      </tl-icon-component>
    </span>
  </template>
  <template dropdown-menu>
    <div class="tl-mega-menu-custom-top" *ngIf="!isMobileLayout">
      <div class="flex-fill align-self-stretch">
        <ng-content select="tl-mega-menu-custom[top-content]"></ng-content>
      </div>
    </div>
    <div class="mega-menu-sections d-flex justify-content-between flex-wrap" *ngIf="!isMobileLayout">
      <ng-container *ngTemplateOutlet="sections"></ng-container>
    </div>
    <div class="tl-mega-menu-custom-bottom" *ngIf="!isMobileLayout">
      <div class="flex-fill align-self-stretch">
        <ng-content select="tl-mega-menu-custom[bottom-content]"></ng-content>
      </div>
    </div>
    <div class="mega-menu-view-all container pt-2" *ngIf="viewAllHref">
      <tl-button-component [href]="viewAllHref" [themeVariant]="'primary'">
        <template button-content>
          <wvr-text-component [value]="viewAllButtonDisplayText"></wvr-text-component>
        </template>
      </tl-button-component>
    </div>
  </template>
</wvr-dropdown-component>

<div *ngIf="isMobileLayout" class="mobile-display" [ngClass]="{active: active}">
  <ng-container *ngTemplateOutlet="sections"></ng-container>
  <tl-mega-menu-section [sectionTitle]="viewAllButtonDisplayText" [viewAllHref]="viewAllHref"></tl-mega-menu-section>
</div>

<ng-template #sections>
  <ng-content select="tl-mega-menu-section"></ng-content>
</ng-template>

./tl-mega-menu.component.scss

@import "../shared/styles/tl-variables.scss";

:host {
  font-family: var(--tl-font-family-sans-serif);
  --tl-mobile-display-max-height: 1500px;

  .mega-menu-sections {
    margin: 0px 20px;
  }

  .mega-menu-view-all {
    display: flex;
    justify-content: flex-end;
  }

  wvr-dropdown-component {
    ::ng-deep {
      @import "~@wvr/elements/styles/variables";
      @import "~bootstrap/scss/bootstrap";
      @import "~@wvr/elements/styles/mixins";
      @import "~@wvr/elements/styles/overrides";
      .wvr-dropdown .dropdown {
        .btn.btn-link.dropdown-toggle,
        .btn.btn-link:not(:disabled):not(.disabled).active,
        .btn.btn-link:not(:disabled):not(.disabled):active {
          text-decoration: none !important;
          color: var(--tl-black) !important;
        }

        .btn {
          width: 100%;

          tl-icon-component.x-icon svg {
            transition: transform 0.25s ease-in-out;
            transform: rotate(0deg);
          }

          tl-icon-component.plus-icon svg {
            transition: transform 0.25s ease-in-out;
            transform: rotate(0deg);
          }
        }
      }
    }
  }

  wvr-dropdown-component:focus-within,
  wvr-dropdown-component:hover {
    ::ng-deep {
      .wvr-dropdown .dropdown {
        .btn {
          tl-icon-component.x-icon svg {
            transition: transform 0.25s ease-in-out;
            transform: rotate(90deg);
          }
        }
      }
    }
  }

  wvr-dropdown-component.active {
    ::ng-deep {
      .wvr-dropdown .dropdown {
        .btn {
          tl-icon-component.plus-icon svg {
            transition: transform 0.25s ease-in-out;
            transform: rotate(45deg);
          }
        }
      }
    }
  }

  .mobile-display {
    max-height: 0px;
    overflow: hidden;
    transition: max-height 1s ease-in-out;
    background: var(--tl-grey);

    ::ng-deep {
      tl-mega-menu-section-component,
      tl-mega-menu-section {
        display: flex;
        flex-direction: column;
        width: 100%;
        padding: 0px;

        a {
          margin: 0px 15px 0px 0px;
          padding: 20px 0px 0px 60px;
          text-align: start;
          color: var(--tl-black);
          font-size: 17px;
          font-family: var(--tl-font-family-sans-serif);
          font-weight: 300;

          wvre-text {
            font-weight: 400;
            padding: 0px;
            margin: 0px;
            border-bottom: 0.5px solid #e4e4e4;
            display: flex;
            height: 40px;
            width: 97%;
          }
        }

        a:focus-within,
        a:hover {
          border-bottom: none;
          wvre-text {
            border-bottom: none;
          }
        }

        .section-title {
          cursor: pointer;
          margin: 0px 15px 0px 30px;
          padding: 20px 0px;
          text-align: start;
          color: var(--tl-black);
          font-size: 17px;
          font-family: var(--tl-font-family-sans-serif);
          font-weight: 300;
          border-bottom: 0.5px solid #e4e4e4;
          text-decoration: none;
        }

        a.mega-menu-view-all {
          cursor: pointer;
          margin: 0px 15px 0px 30px;
          padding: 20px 0px;
          text-align: start;
          color: var(--tl-black);
          font-size: 17px;
          font-family: var(--tl-font-family-sans-serif);
          font-weight: 300;
          border-bottom: 0.5px solid #e4e4e4;
        }
      }
    }
  }

  .mobile-display.active {
    max-height: var(--tl-mobile-display-max-height);
    transition: max-height 0.5s ease-in-out;
  }

  ::ng-deep {
    tl-button-component {
      --tl-btn-border-radius: 0px;
    }

    .wvr-dropdown .dropdown {
      wvr-button-component {
        width: 100%;

        tl-icon-component.plus-icon {
          display: none;
          float: right;
        }

        tl-icon-component.x-icon {
          display: inline-block;
        }
      }

      [ngbDropdownMenu] {
        padding: 20px 0px;
        border: 1px solid var(--tl-grey);
        border-radius: 3px;
        border-bottom: 12px solid var(--tl-deep-yellow);
        box-shadow: 0px 2px 3px 1px var(--tl-grey);
      }
    }
  }

  @media (max-width: 992px) {
    wvr-dropdown-component {
      ::ng-deep {
        .wvr-dropdown .dropdown {
          .btn {
            text-align: start !important;
          }
        }
      }
    }

    ::ng-deep {
      div[template="dropdown-menu"] {
        display: none;
      }

      .wvr-dropdown .dropdown {
        wvr-button-component {
          tl-icon-component.plus-icon {
            display: inline-block;
          }

          tl-icon-component.x-icon {
            display: none;
          }
        }
      }
    }
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""