clr-angular-static-fix
Version:
1. Install Clarity Icons package through npm:
221 lines (197 loc) • 6.58 kB
text/typescript
/*
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Component, ContentChildren, ElementRef, HostListener, Input, QueryList } from '@angular/core';
import { Point } from '../../popover/common/popover';
import { CLR_MENU_POSITIONS } from '../../popover/dropdown/menu-positions';
import { ButtonInGroupService } from '../providers/button-in-group.service';
import { ClrButton } from './button';
export class ClrButtonGroup {
buttons: QueryList<ClrButton>;
constructor(public buttonGroupNewService: ButtonInGroupService, private elementRef: ElementRef) {}
inlineButtons: ClrButton[] = [];
menuButtons: ClrButton[] = [];
/**
* 1. Initializes the initial Button Group View
* 2. Subscribes to changes on the ContentChildren
* in case the user content projection changes
*/
ngAfterContentInit() {
this.initializeButtons();
this.buttonGroupNewService.changes.subscribe(button => this.rearrangeButton(button));
this.buttons.changes.subscribe(() => {
this.initializeButtons();
});
}
/**
* Moves the button into the other ViewContainer
* when an update is received.
*
* @param button
*/
rearrangeButton(button: ClrButton): void {
let fromView: ClrButton[];
let toView: ClrButton[];
if (button.inMenu) {
fromView = this.inlineButtons;
toView = this.menuButtons;
} else {
fromView = this.menuButtons;
toView = this.inlineButtons;
}
const index: number = fromView.indexOf(button);
if (index > -1) {
fromView.splice(index, 1);
const moveIndex = this.getMoveIndex(button);
if (moveIndex <= toView.length) {
toView.splice(moveIndex, 0, button);
}
}
}
/**
* Author: Eudes
*
* Finds the order of a button w.r.t other buttons
*
* @param buttonToMove
* @returns
*/
getMoveIndex(buttonToMove: ClrButton): number {
const tempArr: ClrButton[] = this.buttons.filter(button => button.inMenu === buttonToMove.inMenu);
return tempArr.indexOf(buttonToMove);
}
initializeButtons(): void {
const tempInlineButtons: ClrButton[] = [];
const tempInMenuButtons: ClrButton[] = [];
this.buttons.forEach(button => {
if (button.inMenu) {
tempInMenuButtons.push(button);
} else {
tempInlineButtons.push(button);
}
});
this.inlineButtons = tempInlineButtons;
this.menuButtons = tempInMenuButtons;
}
/**
* Overflow Menu
*
*/
// Indicates the position of the overflow menu
private _menuPosition: string;
get menuPosition(): string {
return this._menuPosition;
}
set menuPosition(pos: string) {
if (pos && CLR_MENU_POSITIONS.indexOf(pos) > -1) {
this._menuPosition = pos;
} else {
this._menuPosition = 'bottom-left';
}
// set the popover values based on menu position
switch (this._menuPosition) {
case 'top-right':
this.anchorPoint = Point.TOP_RIGHT;
this.popoverPoint = Point.RIGHT_BOTTOM;
break;
case 'top-left':
this.anchorPoint = Point.TOP_LEFT;
this.popoverPoint = Point.LEFT_BOTTOM;
break;
case 'bottom-right':
this.anchorPoint = Point.BOTTOM_RIGHT;
this.popoverPoint = Point.RIGHT_TOP;
break;
case 'bottom-left':
this.anchorPoint = Point.BOTTOM_LEFT;
this.popoverPoint = Point.LEFT_TOP;
break;
case 'right-top':
this.anchorPoint = Point.RIGHT_TOP;
this.popoverPoint = Point.LEFT_TOP;
break;
case 'right-bottom':
this.anchorPoint = Point.RIGHT_BOTTOM;
this.popoverPoint = Point.LEFT_BOTTOM;
break;
case 'left-top':
this.anchorPoint = Point.LEFT_TOP;
this.popoverPoint = Point.RIGHT_TOP;
break;
case 'left-bottom':
this.anchorPoint = Point.LEFT_BOTTOM;
this.popoverPoint = Point.RIGHT_BOTTOM;
break;
default:
this.anchorPoint = Point.BOTTOM_LEFT;
this.popoverPoint = Point.LEFT_TOP;
break;
}
}
private _openMenu: boolean = false;
get openMenu(): boolean {
return this._openMenu;
}
set openMenu(value: boolean) {
this._openMenu = value;
}
public anchorPoint: Point = Point.BOTTOM_LEFT; // default if menuPosition isn't set
public popoverPoint: Point = Point.LEFT_TOP; // default if menuPosition isn't set
/**
* Toggle the ClrDropdown Menu when the ClrDropdown Toggle is
* clicked. Also set a flag that indicates that the toggle
* was clicked so that we don't traverse the DOM to find the
* location of the click.
*/
toggleMenu(): void {
this.openMenu = !this.openMenu;
this._overflowMenuToggleClicked = true;
}
/**
* Flag with indicates if the overflow menu toggle was clicked.
* If true, this can save us traversing the DOM to find
* whether the click was withing the button group toggle
* or menu in the onMouseClick method
*/
private _overflowMenuToggleClicked: boolean = false;
// TODO: Generic Directive to handle this
/**
* Called on mouse clicks anywhere in the DOM.
* Checks to see if the mouseclick happened on the host or outside
*/
onMouseClick(target: any): void {
if (this.openMenu && !this._overflowMenuToggleClicked) {
// Reset the overflow menu toggle clicked flag
this._overflowMenuToggleClicked = false;
let current: any = target; // Get the element in the DOM on which the mouse was clicked
const host: any = this.elementRef.nativeElement; // Current Button Group
if (current.classList.contains('dropdown-menu')) {
current = current.parentNode;
while (current) {
if (current === document) {
this.openMenu = false;
return;
}
// If clicked on dropdown menu and menu is in host
// do nothing
if (current === host) {
return;
}
current = current.parentNode;
}
}
this.openMenu = false;
}
this._overflowMenuToggleClicked = false; // Reset the overflow menu toggle clicked flag
}
}