diff options
author | Michael Lando <ml636r@att.com> | 2017-06-09 03:19:04 +0300 |
---|---|---|
committer | Michael Lando <ml636r@att.com> | 2017-06-09 03:19:04 +0300 |
commit | ed64b5edff15e702493df21aa3230b81593e6133 (patch) | |
tree | a4cb01fdaccc34930a8db403a3097c0d1e40914b /catalog-ui/src/app/ng2/shared | |
parent | 280f8015d06af1f41a3ef12e8300801c7a5e0d54 (diff) |
[SDC-29] catalog 1707 rebase commit.
Change-Id: I43c3dc5cf44abf5da817649bc738938a3e8388c1
Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/src/app/ng2/shared')
16 files changed, 455 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.html b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.html new file mode 100644 index 0000000000..efe830d6e0 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.html @@ -0,0 +1,8 @@ +<div class="checkbox-container {{checkboxStyle}}"> + <div class="checkbox-animation" [@checkEffect]="checked"></div> + <label class="checkbox-label" > + <input type="checkbox" class="checkbox-hidden" [ngModel]="checked" (ngModelChange)="toggleState($event)" [disabled]="disabled" /> + <div class="checkbox-icon"></div> + <span *ngIf="label" class="checkbox-label-content">{{label}}</span> + </label> +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.less b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.less new file mode 100644 index 0000000000..7ed8a22194 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.less @@ -0,0 +1,64 @@ + @import '../../../../assets/styles/tlv-sprite'; + +.checkbox-container { + display:inline-block; + position:relative; + text-align: left; + height: 20px; + + + .checkbox-icon { + display: inline-block; + } + + .checkbox-label { + font-weight: normal; + font-size: inherit; + } + + .checkbox-label-content { + margin-left:2px; + } + + .checkbox-icon::before { + .tlv-sprite; + background-position: -10px -60px; + width: 14px; + height: 14px; + content: ''; + display: inline-block; + margin-right: 0px; + margin-top: -2px; + vertical-align: middle; + } + + input[type=checkbox].checkbox-hidden { + width:0; + height:0; + display:none; + &:checked ~ .checkbox-icon::before{ + background-position: -10px -120px; + } + &[disabled] ~ .checkbox-icon::before { + /* TODO: add disabled styles here */ + background-image: none; + background-color: #EFEFEF; + border-radius: 2px; + border: solid #CCC 1px; + } + } + + .checkbox-animation { + background-color: #009fdb; + position: absolute; + left: 2px; + top: 5px; + width:10px; + height:10px; + border-radius: 50%; + z-index: 1; + pointer-events: none; + opacity:0; + } + +} diff --git a/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.ts b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.ts new file mode 100644 index 0000000000..5a9954c336 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.component.ts @@ -0,0 +1,30 @@ +import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core'; +import { trigger, state, style, transition, animate, keyframes } from '@angular/core'; + +@Component({ + selector: 'checkbox', + templateUrl: './checkbox.component.html', + styleUrls: ['./checkbox.component.less'], + encapsulation: ViewEncapsulation.None, + animations: [ + trigger('checkEffect', [ + state('true', style({ position: 'absolute', left: '2px', top: '5px', width: '10px', height: '10px', display: 'none', opacity: '.5' })), + state('false', style({ left: '-18px', top: '-15px', height: '50px', width: '50px', opacity: '0' })), + transition('1 => 0', animate('150ms ease-out')), + transition('0 => 1', animate('150ms ease-in')) + ]) + ] +}) +export class CheckboxComponent { + + @Input() checkboxStyle: string; + @Input() label: string; + @Input() checked: boolean; + @Input() disabled: boolean; + @Output() checkedChange: EventEmitter<any> = new EventEmitter<any>(); + + toggleState(newValue:boolean) { + this.checkedChange.emit(newValue); + } +} + diff --git a/catalog-ui/src/app/ng2/shared/checkbox/checkbox.module.ts b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.module.ts new file mode 100644 index 0000000000..116aa7f025 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/checkbox/checkbox.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; +import { CheckboxComponent } from './checkbox.component'; + + +@NgModule({ + imports: [CommonModule, BrowserModule, FormsModule], + declarations: [CheckboxComponent], + bootstrap: [], + exports: [CheckboxComponent] +}) +export class CheckboxModule { } + +/** README: **/ + +/** USAGE Example: + *In page.module.ts: import CheckboxModule + *In HTML: + *<checkbox checkboxStyle="class-goes-here" [label]="'Text goes here'" [disabled]="variable-goes-here" [(checked)]="default-or-variable-goes-here" (checkedChange)="change-event-goes-here()"></checkbox> + */ + +/**STYLING: (ViewEncapsulation is set to None to allow styles to be overridden or customized) + * + * To create or override styles: + * Use /deep/ or >>> prefix to override styles via other components stylesheets + */
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/shared/navbar/navbar-routes.config.ts b/catalog-ui/src/app/ng2/shared/navbar/navbar-routes.config.ts new file mode 100644 index 0000000000..d8a21e66c8 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/navbar/navbar-routes.config.ts @@ -0,0 +1,7 @@ +import { MenuType, RouteInfo } from './navbar.metadata'; + +export const ROUTES: RouteInfo[] = [ + { path: 'page1', title: 'Logo', menuType: MenuType.BRAND }, + { path: 'page1', title: 'Page 1', menuType: MenuType.LEFT }, + { path: 'page2', title: 'Page 2', menuType: MenuType.LEFT } +]; diff --git a/catalog-ui/src/app/ng2/shared/navbar/navbar.component.html b/catalog-ui/src/app/ng2/shared/navbar/navbar.component.html new file mode 100644 index 0000000000..d783be4c27 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/navbar/navbar.component.html @@ -0,0 +1,23 @@ +<nav class="navbar navbar-dark"> + <div class="clearfix"> + <button (click)="isCollapsed = !isCollapsed" + class="navbar-toggler pull-xs-right hidden-sm-up" type="button" + aria-controls="bd-main-nav" + aria-label="Toggle navigation"> + {{menuIcon}} + </button> + <a (click)="isCollapsed = true" class="navbar-brand hidden-sm-up" [routerLink]="[brandMenu.path]"> + {{brandMenu.title}} + </a> + </div> + <div class="navbar-toggleable-xs navbar-collapse" id="bd-main-nav" [attr.aria-expanded]="!isCollapsed" [ngClass]="{collapse: isCollapsed}"> + <ul class="nav navbar-nav"> + <li (click)="isCollapsed = true" class="nav-item" routerLinkActive="active"> + <a class="navbar-brand hidden-xs-down" [routerLink]="[brandMenu.path]">{{brandMenu.title}}</a> + </li> + <li (click)="isCollapsed = true" *ngFor="let menuItem of menuItems" class="nav-item" routerLinkActive="active" [ngClass]="getMenuItemClasses(menuItem)"> + <a class="nav-item nav-link" [routerLink]="[menuItem.path]" routerLinkActive="active">{{menuItem.title}}</a> + </li> + </ul> + </div> +</nav> diff --git a/catalog-ui/src/app/ng2/shared/navbar/navbar.component.less b/catalog-ui/src/app/ng2/shared/navbar/navbar.component.less new file mode 100644 index 0000000000..3e5165b798 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/navbar/navbar.component.less @@ -0,0 +1,11 @@ +.active { + color: #ffffff; +} +.navbar-toggler { + border: solid 1px #cccccc; + color: #ff0000; +} +.navbar { + background-color: #0000ff; + border-radius: 0; +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/shared/navbar/navbar.component.ts b/catalog-ui/src/app/ng2/shared/navbar/navbar.component.ts new file mode 100644 index 0000000000..b174f9d18d --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/navbar/navbar.component.ts @@ -0,0 +1,32 @@ +import {Component, OnInit, ViewEncapsulation} from '@angular/core'; +import { ROUTES } from './navbar-routes.config'; +import { MenuType, RouteInfo } from './navbar.metadata'; + +@Component({ + selector: 'app-navbar', + templateUrl: './navbar.component.html', + styleUrls: [ './navbar.component.less' ], + encapsulation: ViewEncapsulation.None +}) +export class NavbarComponent implements OnInit { + public menuItems: Array<RouteInfo>; + public brandMenu: RouteInfo; + isCollapsed = true; + + constructor() {} + + ngOnInit() { + this.menuItems = ROUTES.filter(menuItem => menuItem.menuType !== MenuType.BRAND); + this.brandMenu = ROUTES.filter(menuItem => menuItem.menuType === MenuType.BRAND)[0]; + } + + public get menuIcon(): string { + return this.isCollapsed ? '☰' : '✖'; + } + + public getMenuItemClasses(menuItem: any) { + return { + 'pull-xs-right': this.isCollapsed && menuItem.menuType === MenuType.RIGHT + }; + } +} diff --git a/catalog-ui/src/app/ng2/shared/navbar/navbar.metadata.ts b/catalog-ui/src/app/ng2/shared/navbar/navbar.metadata.ts new file mode 100644 index 0000000000..245d0e6cfe --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/navbar/navbar.metadata.ts @@ -0,0 +1,11 @@ +export enum MenuType { + BRAND, + LEFT, + RIGHT +} + +export interface RouteInfo { + path: string; + title: string; + menuType: MenuType; +} diff --git a/catalog-ui/src/app/ng2/shared/navbar/navbar.module.ts b/catalog-ui/src/app/ng2/shared/navbar/navbar.module.ts new file mode 100644 index 0000000000..18120a61fb --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/navbar/navbar.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { NavbarComponent } from "./navbar.component"; + +@NgModule({ + imports: [ + RouterModule, + CommonModule + ], + declarations: [ NavbarComponent ], + exports: [ + NavbarComponent + ] +}) +export class NavbarModule {} diff --git a/catalog-ui/src/app/ng2/shared/shared.module.ts b/catalog-ui/src/app/ng2/shared/shared.module.ts new file mode 100644 index 0000000000..3e59e04441 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/shared.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; + +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { NavbarModule } from "./navbar/navbar.module"; + +@NgModule({ + declarations: [ + + ], + imports: [ + CommonModule, + RouterModule, + NavbarModule + ], + exports: [ + ] +}) + +export class SharedModule {} diff --git a/catalog-ui/src/app/ng2/shared/tabs/tab/tab.component.ts b/catalog-ui/src/app/ng2/shared/tabs/tab/tab.component.ts new file mode 100644 index 0000000000..06dcfa0b16 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/tabs/tab/tab.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; +import { ViewEncapsulation } from '@angular/core'; + +@Component({ + selector: 'tab', + template: ` + <div *ngIf="active" class="tab-content"> + <ng-content></ng-content> + </div> + `, + encapsulation: ViewEncapsulation.None +}) +export class Tab { + @Input('tabTitle') title: string; + @Input() active:boolean = false; + @Input() indication?: number; + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/shared/tabs/tabs.component.html b/catalog-ui/src/app/ng2/shared/tabs/tabs.component.html new file mode 100644 index 0000000000..3e263a3862 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/tabs/tabs.component.html @@ -0,0 +1,9 @@ +<div class="tabs {{tabStyle}}"> + <div class="tab" *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active"> + {{tab.title}} + <div class="tab-indication" *ngIf="tab.indication" [@indicatorAnimation]="tab.indication">{{tab.indication}}</div> + </div> +</div> +<div class="tab-content-container"> + <ng-content></ng-content> +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/shared/tabs/tabs.component.less b/catalog-ui/src/app/ng2/shared/tabs/tabs.component.less new file mode 100644 index 0000000000..aa59428a64 --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/tabs/tabs.component.less @@ -0,0 +1,85 @@ +@import '../../../../assets/styles/variables'; + +.tabs { + display:flex; + flex: 0 0 auto; + flex-direction:row; +} + +.tab { + flex: 1 0 auto; + cursor: pointer; + padding: .5em; +} + +.tab-content-container { + flex: 1; + height: 100%; + overflow: hidden; + width:100%; +} + +.tab-content { + height:100%; +} + +/*Tab styles*/ +.tabs{ + &.round-tabs .tab{ + background-color: #f8f8f8; + color: #959595; + border: solid 1px #d2d2d2; + border-bottom:none; + border-left:none; + position:relative; + + &:first-child { + border-top-left-radius: 8px; + border-left:solid 1px #d2d2d2; + } + &:last-child { + border-top-right-radius: 8px; + } + + &.active { + background-color:#009fdb; + color:#e9e9e9; + border-color:#009fdb; + } + + .tab-indication { + position: absolute; + top: -10px; + background-color: #009fdb; + right: 10px; + padding: 2px 0; + border-radius: 15px; + border: solid 1px #d2d2d2; + color:white; + width: 25px; + height: 25px; + text-align: center; + + } + } + + &.simple-tabs .tab { + font-size: 12px; + color: @main_color_n; + + &:after { + display:block; + content: ''; + border-bottom: 2px solid @main_color_a; + transform: scaleX(0); + transition: transform 200ms ease-in-out; + } + + &.active { + color: @main_color_a; + &:after { + transform: scaleX(1); + } + } + } +} diff --git a/catalog-ui/src/app/ng2/shared/tabs/tabs.component.ts b/catalog-ui/src/app/ng2/shared/tabs/tabs.component.ts new file mode 100644 index 0000000000..dc5616c6cb --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/tabs/tabs.component.ts @@ -0,0 +1,58 @@ +import { Component, ContentChildren, QueryList, AfterContentInit, Input, Output, EventEmitter } from '@angular/core'; +import { Tab } from './tab/tab.component'; +import { ViewEncapsulation } from '@angular/core'; +import { trigger, state, style, transition, animate, keyframes } from '@angular/core'; + +@Component({ + selector: 'tabs', + templateUrl: './tabs.component.html', + styleUrls: ['./tabs.component.less'], + encapsulation: ViewEncapsulation.None, + animations: [ + trigger('indicatorAnimation', [ + transition(':enter', [style({ transform: 'translateY(-50%)', opacity: 0 }), animate('250ms', style({ transform: 'translateY(0)', opacity: 1 })) ]), + transition(':leave', [style({ opacity: 1 }), animate('500ms', style({ opacity: 0 })) ]) + ]) + ] +}) +export class Tabs implements AfterContentInit { + + @Input() tabStyle: string; + @Input() hideIndicationOnTabChange?: boolean = false; + @ContentChildren(Tab) tabs: QueryList<Tab>; + @Output() tabChanged: EventEmitter<Tab> = new EventEmitter<Tab>(); + + + ngAfterContentInit() { + //after contentChildren are set, determine active tab. If no active tab set, activate the first one + let activeTabs = this.tabs.filter((tab) => tab.active); + + if (activeTabs.length === 0) { + this.selectTab(this.tabs.first); + } + } + + selectTab(tab: Tab) { + //activate the tab the user clicked. + this.tabs.toArray().forEach(tab => { + tab.active = false; + if (this.hideIndicationOnTabChange && tab.indication) { + tab.indication = null; + } + }); + tab.active = true; + this.tabChanged.emit(tab); + } + + triggerTabChange(tabTitle) { + this.tabs.toArray().forEach(tab => { + tab.active = (tab.title == tabTitle) ? true : false; + }); + } + + setTabIndication(tabTitle:string, indication?:number) { + let selectedTab: Tab = this.tabs.toArray().find(tab => tab.title == tabTitle); + selectedTab.indication = indication || null; + } + +} diff --git a/catalog-ui/src/app/ng2/shared/tabs/tabs.module.ts b/catalog-ui/src/app/ng2/shared/tabs/tabs.module.ts new file mode 100644 index 0000000000..36c7335fde --- /dev/null +++ b/catalog-ui/src/app/ng2/shared/tabs/tabs.module.ts @@ -0,0 +1,35 @@ +import { Component, NgModule } from '@angular/core' +import { BrowserModule } from '@angular/platform-browser' + +import { Tabs } from './tabs.component'; +import { Tab } from './tab/tab.component'; + + +@NgModule({ + imports: [BrowserModule], + declarations: [Tabs, Tab], + bootstrap: [], + exports: [Tabs, Tab] +}) +export class TabModule { } + +/** README: **/ + +/** USAGE Example: + *In page.module.ts: import TabModule + *In HTML: + *<tabs tabStyle="class-goes-here" (tabChanged)="tabChangedEvent($event) [hideIndicationOnTabChange]="optional-boolean"> + * <tab [tabTitle]="'Tab 1'">Content of tab 1</tab> + * <tab tabTitle="Tab 2" >Content of tab 2</tab> + * ... + *</tabs> + */ + +/**STYLING: (ViewEncapsulation is set to None to allow styles to be overridden or customized) + * Existing options: + * tabStyle="round-tabs" will provide generic rounded tab look + * + * To create or override styles: + * Parent div has class ".tabs". Each tab has class ".tab". Active tab has class ".active". + * Use /deep/ or >>> prefix to override styles via other components stylesheets + */
\ No newline at end of file |