From de9307611ca8db0ebf0067420cba6db2734b55e9 Mon Sep 17 00:00:00 2001 From: Ricardo Varanda Date: Mon, 22 May 2017 22:48:36 +0100 Subject: [PATCH 01/35] fix (data-table): missing colon in example (#613) --- .../components/components/data-table/data-table.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/components/data-table/data-table.component.html b/src/app/components/components/data-table/data-table.component.html index 9b1d7c1d64..3ec7495b68 100644 --- a/src/app/components/components/data-table/data-table.component.html +++ b/src/app/components/components/data-table/data-table.component.html @@ -72,7 +72,7 @@

with custom headings, columns, and inline editing

columns: ITdDataTableColumn[] = [ { name: 'sku', label: 'SKU #', tooltip: 'Stock Keeping Unit' }, { name: 'item', label: 'Item name' }, - { name: 'price', label 'Price (US$)', numeric: true, format: v => v.toFixed(2) }, + { name: 'price', label: 'Price (US$)', numeric: true, format: v => v.toFixed(2) }, ]; constructor(private _dialogService: TdDialogService) {} From ec1cbd8c962d0e5610b075b6f3655afa589ba121 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 24 May 2017 10:34:39 -0700 Subject: [PATCH 02/35] fix(data-table): block (rowClick) event when clicking on checkbox (closes #611) (#619) * fix(data-table): not throw (rowClick) event when clicking on checkbox even though clicking on the checkbox is still clicking on the row, we need to block this since people want to navigate when clickin on row and select when clicking on checkbox * Instead of looking for a tag name to know to stop the event propogation, added an attribute to the tag to look for. Looking for the tag name could be problamatic in that what if someone wants to put their own md-pseudo-checkbox on a cell. * changing attribute name to stopRowClick --- .../core/data-table/data-table.component.html | 3 +- .../data-table/data-table.component.spec.ts | 64 +++++++++++++++++++ .../core/data-table/data-table.component.ts | 9 ++- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/platform/core/data-table/data-table.component.html b/src/platform/core/data-table/data-table.component.html index fca74c66fd..d59c0a8337 100644 --- a/src/platform/core/data-table/data-table.component.html +++ b/src/platform/core/data-table/data-table.component.html @@ -30,7 +30,7 @@ [tabIndex]="isSelectable ? 0 : -1" [class.mat-selected]="(isClickable || isSelectable) && isRowSelected(row)" *ngFor="let row of data; let rowIndex = index" - (click)="handleRowClick(row, $event, rowIndex)" + (click)="handleRowClick(row, $event)" (keyup)="isSelectable && _rowKeyup($event, row, rowIndex)" (keydown.space)="blockEvent($event)" (keydown.shift.space)="blockEvent($event)" @@ -41,6 +41,7 @@ [state]="isRowSelected(row) ? 'checked' : 'unchecked'" (mousedown)="disableTextSelection()" (mouseup)="enableTextSelection()" + stopRowClick (click)="select(row, $event, rowIndex)"> diff --git a/src/platform/core/data-table/data-table.component.spec.ts b/src/platform/core/data-table/data-table.component.spec.ts index 2adbf1782e..fc26d9e6fd 100644 --- a/src/platform/core/data-table/data-table.component.spec.ts +++ b/src/platform/core/data-table/data-table.component.spec.ts @@ -29,6 +29,7 @@ describe('Component: DataTable', () => { TdDataTableBasicTestComponent, TdDataTableSelectableTestComponent, TdDataTableRowClickTestComponent, + TdDataTableSelectableRowClickTestComponent, ], providers: [ TdDataTableService, @@ -330,6 +331,38 @@ describe('Component: DataTable', () => { }); }); }))); + + it('should click on a row and see the rowClick event only when clicking on row', + async(inject([], () => { + let fixture: ComponentFixture = TestBed.createComponent(TdDataTableSelectableRowClickTestComponent); + let component: TdDataTableSelectableRowClickTestComponent = fixture.debugElement.componentInstance; + + component.clickable = true; + component.selectable = true; + + let clickEventSpy: jasmine.Spy = spyOn(component, 'clickEvent'); + let selectEventSpy: jasmine.Spy = spyOn(component, 'selectEvent'); + + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.debugElement.queryAll(By.directive(TdDataTableRowComponent))[1].nativeElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(clickEventSpy.calls.count()).toBe(1); + expect(selectEventSpy.calls.count()).toBe(0); + + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.debugElement.queryAll(By.directive(MdPseudoCheckbox))[0].nativeElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(clickEventSpy.calls.count()).toBe(1); + expect(selectEventSpy.calls.count()).toBe(1); + }); + }); + }); + }); + }))); }); }); @@ -392,3 +425,34 @@ class TdDataTableRowClickTestComponent { /* noop */ } } + +@Component({ + template: ` + + `, +}) +class TdDataTableSelectableRowClickTestComponent { + data: any[] = [ + { sku: '1452-2', item: 'Pork Chops', price: 32.11 }, + { sku: '1421-0', item: 'Prime Rib', price: 41.15 }, + ]; + columns: ITdDataTableColumn[] = [ + { name: 'sku', label: 'SKU #' }, + { name: 'item', label: 'Item name' }, + { name: 'price', label: 'Price (US$)', numeric: true }, + ]; + selectable: boolean = false; + clickable: boolean = false; + clickEvent(): void { + /* noop */ + } + selectEvent(): void { + /* noop */ + } +} diff --git a/src/platform/core/data-table/data-table.component.ts b/src/platform/core/data-table/data-table.component.ts index 4598af0d2b..7744985538 100644 --- a/src/platform/core/data-table/data-table.component.ts +++ b/src/platform/core/data-table/data-table.component.ts @@ -435,9 +435,14 @@ export class TdDataTableComponent implements ControlValueAccessor, AfterContentI * emits the onRowClickEvent when a row is clicked * if clickable is true and selectable is false then select the row */ - handleRowClick(row: any, event: Event, currentSelected: number): void { + handleRowClick(row: any, event: Event): void { if (this.isClickable) { - this.onRowClick.emit({row: row}); + // ignoring linting rules here because attribute it actually null or not there + // can't check for undefined + /* tslint:disable-next-line */ + if (event.srcElement.getAttribute('stopRowClick') === null) { + this.onRowClick.emit({row: row}); + } } } From 4544c1a5bcabb1fa3e60b6fe6c2f6e1a5215ab5c Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 24 May 2017 11:28:22 -0700 Subject: [PATCH 03/35] perf(providers): make sure all services are singleton (#610) * perf(providers): make sure all services are singleton when using modules, make sure we reuse the instance provided by the parent module rather than creation a new instance. all covalent services are meant to be singleton and app wise instances. * fix(http): revert to not singleton http service since devs might want a diff http per module * chore(http): remove unused imports --- src/platform/core/data-table/data-table.module.ts | 5 +++-- .../core/data-table/services/data-table.service.ts | 14 +++++++++++++- src/platform/core/dialogs/dialogs.module.ts | 4 ++-- .../core/dialogs/services/dialog.service.ts | 14 +++++++++++++- src/platform/core/loading/loading.module.ts | 8 ++++---- .../core/loading/services/loading.factory.ts | 14 +++++++++++++- .../core/loading/services/loading.service.ts | 14 +++++++++++++- src/platform/core/media/media.module.ts | 4 ++-- src/platform/core/media/services/media.service.ts | 14 +++++++++++++- src/platform/dynamic-forms/dynamic-forms.module.ts | 4 ++-- .../services/dynamic-forms.service.ts | 14 +++++++++++++- src/platform/http/http.module.ts | 13 ++++++++----- 12 files changed, 99 insertions(+), 23 deletions(-) diff --git a/src/platform/core/data-table/data-table.module.ts b/src/platform/core/data-table/data-table.module.ts index 6897c24a14..2e5f678029 100644 --- a/src/platform/core/data-table/data-table.module.ts +++ b/src/platform/core/data-table/data-table.module.ts @@ -8,9 +8,10 @@ import { TdDataTableColumnComponent } from './data-table-column/data-table-colum import { TdDataTableCellComponent } from './data-table-cell/data-table-cell.component'; import { TdDataTableRowComponent } from './data-table-row/data-table-row.component'; import { TdDataTableTableComponent } from './data-table-table/data-table-table.component'; -import { TdDataTableService } from './services/data-table.service'; import { TdDataTableTemplateDirective } from './directives/data-table-template.directive'; +import { TdDataTableService, DATA_TABLE_PROVIDER } from './services/data-table.service'; + const TD_DATA_TABLE: Type[] = [ TdDataTableComponent, TdDataTableTemplateDirective, @@ -45,7 +46,7 @@ export { TdDataTableTableComponent } from './data-table-table/data-table-table.c TD_DATA_TABLE, ], providers: [ - TdDataTableService, + DATA_TABLE_PROVIDER, ], }) export class CovalentDataTableModule { diff --git a/src/platform/core/data-table/services/data-table.service.ts b/src/platform/core/data-table/services/data-table.service.ts index 906b2155c3..d965d96bd4 100644 --- a/src/platform/core/data-table/services/data-table.service.ts +++ b/src/platform/core/data-table/services/data-table.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Provider, SkipSelf, Optional } from '@angular/core'; import { TdDataTableSortingOrder, ITdDataTableColumn } from '../data-table.component'; @@ -75,3 +75,15 @@ export class TdDataTableService { return data; } } + +export function DATA_TABLE_PROVIDER_FACTORY( + parent: TdDataTableService): TdDataTableService { + return parent || new TdDataTableService(); +} + +export const DATA_TABLE_PROVIDER: Provider = { + // If there is already a service available, use that. Otherwise, provide a new one. + provide: TdDataTableService, + deps: [[new Optional(), new SkipSelf(), TdDataTableService]], + useFactory: DATA_TABLE_PROVIDER_FACTORY, +}; diff --git a/src/platform/core/dialogs/dialogs.module.ts b/src/platform/core/dialogs/dialogs.module.ts index c42b48d416..ab5a43f29b 100644 --- a/src/platform/core/dialogs/dialogs.module.ts +++ b/src/platform/core/dialogs/dialogs.module.ts @@ -10,7 +10,7 @@ import { TdDialogComponent, TdDialogTitleDirective, import { TdAlertDialogComponent } from './alert-dialog/alert-dialog.component'; import { TdConfirmDialogComponent } from './confirm-dialog/confirm-dialog.component'; import { TdPromptDialogComponent } from './prompt-dialog/prompt-dialog.component'; -import { TdDialogService } from './services/dialog.service'; +import { TdDialogService, DIALOG_PROVIDER } from './services/dialog.service'; const TD_DIALOGS: Type[] = [ TdAlertDialogComponent, @@ -47,7 +47,7 @@ export { TdDialogService, TdDialogComponent, TdDialogTitleDirective, TD_DIALOGS, ], providers: [ - TdDialogService, + DIALOG_PROVIDER, ], entryComponents: [ TD_DIALOGS_ENTRY_COMPONENTS, diff --git a/src/platform/core/dialogs/services/dialog.service.ts b/src/platform/core/dialogs/services/dialog.service.ts index a6a36851cf..ccb22fdb63 100644 --- a/src/platform/core/dialogs/services/dialog.service.ts +++ b/src/platform/core/dialogs/services/dialog.service.ts @@ -1,4 +1,4 @@ -import { Injectable, ViewContainerRef } from '@angular/core'; +import { Injectable, ViewContainerRef, Provider, SkipSelf, Optional } from '@angular/core'; import { MdDialog, MdDialogRef, MdDialogConfig, ComponentType } from '@angular/material'; import { TdAlertDialogComponent } from '../alert-dialog/alert-dialog.component'; @@ -142,3 +142,15 @@ export class TdDialogService { } } + +export function DIALOG_PROVIDER_FACTORY( + parent: TdDialogService, dialog: MdDialog): TdDialogService { + return parent || new TdDialogService(dialog); +} + +export const DIALOG_PROVIDER: Provider = { + // If there is already service available, use that. Otherwise, provide a new one. + provide: TdDialogService, + deps: [[new Optional(), new SkipSelf(), TdDialogService], MdDialog], + useFactory: DIALOG_PROVIDER_FACTORY, +}; diff --git a/src/platform/core/loading/loading.module.ts b/src/platform/core/loading/loading.module.ts index 9224233f33..5149631a4b 100644 --- a/src/platform/core/loading/loading.module.ts +++ b/src/platform/core/loading/loading.module.ts @@ -4,8 +4,8 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MdProgressBarModule, MdProgressSpinnerModule, OverlayModule, PortalModule } from '@angular/material'; -import { TdLoadingService } from './services/loading.service'; -import { TdLoadingFactory } from './services/loading.factory'; +import { TdLoadingService, LOADING_PROVIDER } from './services/loading.service'; +import { TdLoadingFactory, LOADING_FACTORY_PROVIDER } from './services/loading.factory'; import { TdLoadingDirective } from './directives/loading.directive'; import { TdLoadingComponent } from './loading.component'; @@ -36,8 +36,8 @@ export { TdLoadingService, ITdLoadingConfig } from './services/loading.service'; TD_LOADING, ], providers: [ - TdLoadingFactory, - TdLoadingService, + LOADING_FACTORY_PROVIDER, + LOADING_PROVIDER, ], entryComponents: [ TD_LOADING_ENTRY_COMPONENTS, diff --git a/src/platform/core/loading/services/loading.factory.ts b/src/platform/core/loading/services/loading.factory.ts index e867ebfde1..ebe86e17aa 100644 --- a/src/platform/core/loading/services/loading.factory.ts +++ b/src/platform/core/loading/services/loading.factory.ts @@ -1,4 +1,4 @@ -import { Injectable, ComponentFactoryResolver, ChangeDetectorRef } from '@angular/core'; +import { Injectable, ComponentFactoryResolver, ChangeDetectorRef, Provider, SkipSelf, Optional } from '@angular/core'; import { Injector, ComponentRef, ViewContainerRef, TemplateRef } from '@angular/core'; import { TemplatePortal, Overlay, OverlayState, OverlayRef, OverlayOrigin, ComponentPortal } from '@angular/material'; import { Subject } from 'rxjs/Subject'; @@ -191,3 +191,15 @@ export class TdLoadingFactory { } } } + +export function LOADING_FACTORY_PROVIDER_FACTORY( + parent: TdLoadingFactory, componentFactoryResolver: ComponentFactoryResolver, overlay: Overlay, injector: Injector): TdLoadingFactory { + return parent || new TdLoadingFactory(componentFactoryResolver, overlay, injector); +} + +export const LOADING_FACTORY_PROVIDER: Provider = { + // If there is already a service available, use that. Otherwise, provide a new one. + provide: TdLoadingFactory, + deps: [[new Optional(), new SkipSelf(), TdLoadingFactory], ComponentFactoryResolver, Overlay, Injector], + useFactory: LOADING_FACTORY_PROVIDER_FACTORY, +}; diff --git a/src/platform/core/loading/services/loading.service.ts b/src/platform/core/loading/services/loading.service.ts index ac71493683..7be6495abf 100644 --- a/src/platform/core/loading/services/loading.service.ts +++ b/src/platform/core/loading/services/loading.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Provider, SkipSelf, Optional } from '@angular/core'; import { ViewContainerRef, TemplateRef } from '@angular/core'; import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; @@ -230,3 +230,15 @@ export class TdLoadingService { delete this._timeouts[name]; } } + +export function LOADING_PROVIDER_FACTORY( + parent: TdLoadingService, loadingFactory: TdLoadingFactory): TdLoadingService { + return parent || new TdLoadingService(loadingFactory); +} + +export const LOADING_PROVIDER: Provider = { + // If there is already a service available, use that. Otherwise, provide a new one. + provide: TdLoadingService, + deps: [[new Optional(), new SkipSelf(), TdLoadingService], TdLoadingFactory], + useFactory: LOADING_PROVIDER_FACTORY, +}; diff --git a/src/platform/core/media/media.module.ts b/src/platform/core/media/media.module.ts index 5147ee25bd..7db5f3302c 100644 --- a/src/platform/core/media/media.module.ts +++ b/src/platform/core/media/media.module.ts @@ -3,7 +3,7 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { TdMediaService } from './services/media.service'; +import { TdMediaService, MEDIA_PROVIDER } from './services/media.service'; import { TdMediaToggleDirective } from './directives/media-toggle.directive'; const TD_MEDIA: Type[] = [ @@ -23,7 +23,7 @@ export { TdMediaService, TdMediaToggleDirective }; TD_MEDIA, ], providers: [ - TdMediaService, + MEDIA_PROVIDER, ], }) export class CovalentMediaModule { diff --git a/src/platform/core/media/services/media.service.ts b/src/platform/core/media/services/media.service.ts index 5e574464f1..757ef2ce25 100644 --- a/src/platform/core/media/services/media.service.ts +++ b/src/platform/core/media/services/media.service.ts @@ -1,4 +1,4 @@ -import { Injectable, NgZone } from '@angular/core'; +import { Injectable, NgZone, SkipSelf, Optional, Provider } from '@angular/core'; import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; @@ -90,3 +90,15 @@ export class TdMediaService { this._querySources[query].next(window.matchMedia(query).matches); } } + +export function MEDIA_PROVIDER_FACTORY( + parent: TdMediaService, ngZone: NgZone): TdMediaService { + return parent || new TdMediaService(ngZone); +} + +export const MEDIA_PROVIDER: Provider = { + // If there is already a service available, use that. Otherwise, provide a new one. + provide: TdMediaService, + deps: [[new Optional(), new SkipSelf(), TdMediaService], NgZone], + useFactory: MEDIA_PROVIDER_FACTORY, +}; diff --git a/src/platform/dynamic-forms/dynamic-forms.module.ts b/src/platform/dynamic-forms/dynamic-forms.module.ts index cf0187b8f4..a87a29be4d 100644 --- a/src/platform/dynamic-forms/dynamic-forms.module.ts +++ b/src/platform/dynamic-forms/dynamic-forms.module.ts @@ -8,7 +8,7 @@ import { CovalentCommonModule } from '../core'; import { TdDynamicFormsComponent } from './dynamic-forms.component'; import { TdDynamicElementComponent, TdDynamicElementDirective } from './dynamic-element.component'; -import { TdDynamicFormsService } from './services/dynamic-forms.service'; +import { TdDynamicFormsService, DYNAMIC_FORMS_PROVIDER } from './services/dynamic-forms.service'; import { TdDynamicInputComponent } from './dynamic-elements/dynamic-input/dynamic-input.component'; import { TdDynamicTextareaComponent } from './dynamic-elements/dynamic-textarea/dynamic-textarea.component'; @@ -56,7 +56,7 @@ const TD_DYNAMIC_FORMS_ENTRY_COMPONENTS: Type[] = [ TD_DYNAMIC_FORMS_ENTRY_COMPONENTS, ], providers: [ - TdDynamicFormsService, + DYNAMIC_FORMS_PROVIDER, ], entryComponents: [ TD_DYNAMIC_FORMS_ENTRY_COMPONENTS ], }) diff --git a/src/platform/dynamic-forms/services/dynamic-forms.service.ts b/src/platform/dynamic-forms/services/dynamic-forms.service.ts index fe8310d88e..bddd3ef177 100644 --- a/src/platform/dynamic-forms/services/dynamic-forms.service.ts +++ b/src/platform/dynamic-forms/services/dynamic-forms.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Provider, SkipSelf, Optional } from '@angular/core'; import { Validators, ValidatorFn, FormControl } from '@angular/forms'; import { CovalentValidators } from '../../core'; @@ -131,3 +131,15 @@ export class TdDynamicFormsService { return validator; } } + +export function DYNAMIC_FORMS_PROVIDER_FACTORY( + parent: TdDynamicFormsService): TdDynamicFormsService { + return parent || new TdDynamicFormsService(); +} + +export const DYNAMIC_FORMS_PROVIDER: Provider = { + // If there is already a service available, use that. Otherwise, provide a new one. + provide: TdDynamicFormsService, + deps: [[new Optional(), new SkipSelf(), TdDynamicFormsService]], + useFactory: DYNAMIC_FORMS_PROVIDER_FACTORY, +}; diff --git a/src/platform/http/http.module.ts b/src/platform/http/http.module.ts index fd553058a5..3b14c07004 100644 --- a/src/platform/http/http.module.ts +++ b/src/platform/http/http.module.ts @@ -1,4 +1,4 @@ -import { NgModule, ModuleWithProviders, Injector, InjectionToken } from '@angular/core'; +import { NgModule, ModuleWithProviders, Injector, InjectionToken, Provider } from '@angular/core'; import { HttpModule, Http } from '@angular/http'; import { HttpInterceptorService, IHttpInterceptorConfig } from './interceptors/http-interceptor.service'; @@ -12,6 +12,12 @@ export function httpFactory(http: Http, injector: Injector, config: HttpConfig): return new HttpInterceptorService(http, injector, new URLRegExpInterceptorMatcher(), config.interceptors); } +export const HTTP_INTERCEPTOR_PROVIDER: Provider = { + provide: HttpInterceptorService, + useFactory: httpFactory, + deps: [Http, Injector, HTTP_CONFIG], +}; + @NgModule({ imports: [ HttpModule, @@ -24,11 +30,8 @@ export class CovalentHttpModule { providers: [{ provide: HTTP_CONFIG, useValue: config, - }, { - provide: HttpInterceptorService, - useFactory: httpFactory, - deps: [Http, Injector, HTTP_CONFIG], }, + HTTP_INTERCEPTOR_PROVIDER, ], }; } From e2172fafdd7ea03f7db1df8d21abea4238e14d65 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 24 May 2017 14:05:56 -0700 Subject: [PATCH 04/35] feat(layout): add `[mode]`, `[opened]` and `[sidenavWidth]` to main `td-layout` (#609) * feat(layout): add `[mode]` and `[opened]` to main layout this so we can use diff types of modes for mid-small size projects in `td-layout` * feat(layout): sidenavWidth --- src/app/app.component.html | 7 ++- src/app/app.component.ts | 13 ++++-- src/app/app.module.ts | 4 +- src/platform/core/layout/README.md | 24 +++++++++++ src/platform/core/layout/_layout-theme.scss | 3 ++ .../layout-manage-list.component.ts | 2 +- .../layout-nav-list.component.ts | 4 +- .../layout/layout-nav/layout-nav.component.ts | 2 +- .../core/layout/layout.component.html | 7 ++- src/platform/core/layout/layout.component.ts | 43 ++++++++++++++++++- 10 files changed, 97 insertions(+), 12 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index 7107236c76..6200aafa81 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,7 +1,10 @@ - + - {{item.icon}}{{item.title}} + {{item.icon}}{{item.title}} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index dc92ef04b6..be03bf9864 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,7 +1,7 @@ -import { Component } from '@angular/core'; +import { Component, AfterViewInit, ChangeDetectorRef } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { MdIconRegistry } from '@angular/material'; - +import { TdMediaService } from '@covalent/core'; import { TranslateService } from '@ngx-translate/core'; import { getSelectedLanguage } from './utilities/translate'; @@ -11,7 +11,7 @@ import { getSelectedLanguage } from './utilities/translate'; templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], }) -export class DocsAppComponent { +export class DocsAppComponent implements AfterViewInit { routes: Object[] = [{ icon: 'home', @@ -38,6 +38,8 @@ export class DocsAppComponent { constructor(private _iconRegistry: MdIconRegistry, private _domSanitizer: DomSanitizer, + private _changeDetectorRef: ChangeDetectorRef, + public media: TdMediaService, translateService: TranslateService) { // Set fallback language translateService.setDefaultLang('en'); @@ -63,4 +65,9 @@ export class DocsAppComponent { this._iconRegistry.addSvgIconInNamespace('assets', 'querygrid', this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/querygrid.svg')); } + + ngAfterViewInit(): void { + this.media.broadcast(); + this._changeDetectorRef.detectChanges(); + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index cb73a34a10..c299d22a71 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -12,7 +12,8 @@ import { appRoutes, appRoutingProviders } from './app.routes'; import { MdButtonModule, MdListModule, MdIconModule, MdCardModule, MdCoreModule, MdMenuModule } from '@angular/material'; -import { CovalentLayoutModule, CovalentExpansionPanelModule, CovalentNotificationsModule, CovalentMenuModule } from '../platform/core'; +import { CovalentLayoutModule, CovalentExpansionPanelModule, CovalentNotificationsModule, CovalentMenuModule, + CovalentMediaModule } from '../platform/core'; import { CovalentHighlightModule } from '../platform/highlight'; import { CovalentHttpModule } from '../platform/http'; import { CovalentMarkdownModule } from '../platform/markdown'; @@ -49,6 +50,7 @@ import { getSelectedLanguage, createTranslateLoader } from './utilities/translat CovalentHighlightModule, CovalentMarkdownModule, CovalentDynamicFormsModule, + CovalentMediaModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, diff --git a/src/platform/core/layout/README.md b/src/platform/core/layout/README.md index da68042cbe..1f47399cdb 100644 --- a/src/platform/core/layout/README.md +++ b/src/platform/core/layout/README.md @@ -3,6 +3,30 @@ `` is a blank main sidenav component that gets hooked as parent of all the other layouts. (triggered by their menu buttons) +## API Summary + +| Name | Type | Description | +| --- | --- | --- | +| mode | 'over', 'side' or 'push' | The mode or styling of the sidenav. Defaults to 'over'. +| opened | boolean | Whether or not the sidenav is opened. Use this binding to open/close the sidenav. Defaults to 'false'. +| sidenavWidth | string | Sets the 'width' of the sidenav in either 'px' or '%' ('%' is not well supported yet as stated in the layout docs). Defaults to '320px'. + + +## Usage + +`[td-sidenav-content]` is used to include content in the main sidenav. + +Example for Main Layout: + +```html + +
+ .. more sidenav content +
+ .. main content +
+``` + ## Installation This component can be installed as npm package. diff --git a/src/platform/core/layout/_layout-theme.scss b/src/platform/core/layout/_layout-theme.scss index 36801afc9f..6463f55a40 100644 --- a/src/platform/core/layout/_layout-theme.scss +++ b/src/platform/core/layout/_layout-theme.scss @@ -20,6 +20,9 @@ z-index: 1; } } + .mat-sidenav-side.td-layout-sidenav { + @include mat-elevation(2); + } .td-layout-footer { background: mat-color($background, app-bar); color: mat-color($foreground, text); diff --git a/src/platform/core/layout/layout-manage-list/layout-manage-list.component.ts b/src/platform/core/layout/layout-manage-list/layout-manage-list.component.ts index eb6acf79c8..6fd020b984 100644 --- a/src/platform/core/layout/layout-manage-list/layout-manage-list.component.ts +++ b/src/platform/core/layout/layout-manage-list/layout-manage-list.component.ts @@ -56,7 +56,7 @@ export class TdLayoutManageListComponent { * Proxy toggle method to access sidenav from outside (from td-layout template). */ public toggle(): Promise { - return this._sideNav.toggle(); + return this._sideNav.toggle(!this._sideNav.opened); } /** diff --git a/src/platform/core/layout/layout-nav-list/layout-nav-list.component.ts b/src/platform/core/layout/layout-nav-list/layout-nav-list.component.ts index 9f973c9f43..9b5dfaaf6f 100644 --- a/src/platform/core/layout/layout-nav-list/layout-nav-list.component.ts +++ b/src/platform/core/layout/layout-nav-list/layout-nav-list.component.ts @@ -117,7 +117,7 @@ export class TdLayoutNavListComponent { * Proxy toggle method to access sidenav from outside (from td-layout template). */ public toggle(): Promise { - return this._sideNav.toggle(); + return this._sideNav.toggle(!this._sideNav.opened); } /** @@ -138,7 +138,7 @@ export class TdLayoutNavListComponent { * If main sidenav is available, it will open the sidenav of the parent [TdLayoutComponent]. */ openMainSidenav(): void { - this._layout.open(); + this._layout.toggle(); } } diff --git a/src/platform/core/layout/layout-nav/layout-nav.component.ts b/src/platform/core/layout/layout-nav/layout-nav.component.ts index 5039c2d07a..502fa14c88 100644 --- a/src/platform/core/layout/layout-nav/layout-nav.component.ts +++ b/src/platform/core/layout/layout-nav/layout-nav.component.ts @@ -73,6 +73,6 @@ export class TdLayoutNavComponent { * If main sidenav is available, it will open the sidenav of the parent [TdLayoutComponent]. */ openMainSidenav(): void { - this._layout.open(); + this._layout.toggle(); } } diff --git a/src/platform/core/layout/layout.component.html b/src/platform/core/layout/layout.component.html index 34013ac955..a2b7160e5d 100644 --- a/src/platform/core/layout/layout.component.html +++ b/src/platform/core/layout/layout.component.html @@ -1,5 +1,10 @@ - + diff --git a/src/platform/core/layout/layout.component.ts b/src/platform/core/layout/layout.component.ts index bbbc7c906d..8f2e30d514 100644 --- a/src/platform/core/layout/layout.component.ts +++ b/src/platform/core/layout/layout.component.ts @@ -11,11 +11,52 @@ export class TdLayoutComponent { @ViewChild(MdSidenav) sidenav: MdSidenav; + /** + * mode?: 'side', 'push' or 'over' + * + * The mode or styling of the sidenav. + * Defaults to "over". + * See "MdSidenav" documentation for more info. + * + * https://github.com/angular/material2/tree/master/src/lib/sidenav + */ + @Input('mode') mode: 'side' | 'push' | 'over' = 'over'; + + /** + * opened?: boolean + * + * Whether or not the sidenav is opened. Use this binding to open/close the sidenav. + * Defaults to "false". + * + * See "MdSidenav" documentation for more info. + * + * https://github.com/angular/material2/tree/master/src/lib/sidenav + */ + @Input('opened') opened: boolean = false; + + /** + * sidenavWidth?: string + * + * Sets the "width" of the sidenav in either "px" or "%" ("%" is not well supported yet as stated in the layout docs) + * Defaults to "320px". + * + * https://github.com/angular/material2/tree/master/src/lib/sidenav + */ + @Input('sidenavWidth') sidenavWidth: string = '320px'; + + /** + * Checks if `ESC` should close the sidenav + * Should only close it for `push` and `over` modes + */ + get disableClose(): boolean { + return this.mode === 'side'; + } + /** * Proxy toggle method to access sidenav from outside (from td-layout template). */ public toggle(): Promise { - return this.sidenav.toggle(); + return this.sidenav.toggle(!this.sidenav.opened); } /** From 629d06f161c00f99218708570d6085acbf58ee4f Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Sat, 27 May 2017 10:27:55 -0700 Subject: [PATCH 05/35] fix(layout): upgrade to material@beta.6 to use exposed `ScrollDispatchModule` (closes #620) (#628) * fix(layout): upgrade to material@beta.6 to use exposed ScrollDispatchModule we need to add cdkScrollable in our layouts so components like md-autocomplete can hook into them. * feat(layout): add cdkScrollable to scrollable sidenavs too --- package.json | 2 +- .../layout-manage-list/layout-manage-list.component.html | 4 ++-- .../layout/layout-nav-list/layout-nav-list.component.html | 4 ++-- src/platform/core/layout/layout-nav/layout-nav.component.html | 2 +- src/platform/core/layout/layout.module.ts | 3 ++- src/platform/core/package.json | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 13ea605d49..820ac38583 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@angular/core": "^4.1.0", "@angular/forms": "^4.1.0", "@angular/http": "^4.1.0", - "@angular/material": "2.0.0-beta.5", + "@angular/material": "2.0.0-beta.6", "@angular/platform-browser": "^4.1.0", "@angular/platform-browser-dynamic": "^4.1.0", "@angular/platform-server": "^4.1.0", diff --git a/src/platform/core/layout/layout-manage-list/layout-manage-list.component.html b/src/platform/core/layout/layout-manage-list/layout-manage-list.component.html index 1e6d65c54f..8214ccf4f7 100644 --- a/src/platform/core/layout/layout-manage-list/layout-manage-list.component.html +++ b/src/platform/core/layout/layout-manage-list/layout-manage-list.component.html @@ -9,7 +9,7 @@ layout-fill class="md-whiteframe-z1"> -
+
@@ -20,7 +20,7 @@ -
+
diff --git a/src/platform/core/layout/layout-nav-list/layout-nav-list.component.html b/src/platform/core/layout/layout-nav-list/layout-nav-list.component.html index 18e52bd6ce..70db922e92 100644 --- a/src/platform/core/layout/layout-nav-list/layout-nav-list.component.html +++ b/src/platform/core/layout/layout-nav-list/layout-nav-list.component.html @@ -25,7 +25,7 @@ -
+
@@ -36,7 +36,7 @@ -
+
diff --git a/src/platform/core/layout/layout-nav/layout-nav.component.html b/src/platform/core/layout/layout-nav/layout-nav.component.html index 31dd9316e4..9e3a695ae5 100644 --- a/src/platform/core/layout/layout-nav/layout-nav.component.html +++ b/src/platform/core/layout/layout-nav/layout-nav.component.html @@ -14,7 +14,7 @@ -
+
diff --git a/src/platform/core/layout/layout.module.ts b/src/platform/core/layout/layout.module.ts index d6e30421f6..8366afa0d3 100644 --- a/src/platform/core/layout/layout.module.ts +++ b/src/platform/core/layout/layout.module.ts @@ -2,7 +2,7 @@ import { Type } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { MdSidenavModule, MdToolbarModule, MdButtonModule, MdIconModule, MdCardModule, MdListModule } from '@angular/material'; +import { MdSidenavModule, MdToolbarModule, MdButtonModule, MdIconModule, MdCardModule, MdListModule, ScrollDispatchModule } from '@angular/material'; import { TdLayoutComponent } from './layout.component'; import { TdLayoutNavComponent } from './layout-nav/layout-nav.component'; @@ -32,6 +32,7 @@ export { TdLayoutComponent, TdLayoutNavComponent, TdLayoutNavListComponent, @NgModule({ imports: [ CommonModule, + ScrollDispatchModule, MdSidenavModule, MdToolbarModule, MdButtonModule, diff --git a/src/platform/core/package.json b/src/platform/core/package.json index 94faa4c1c5..ca2a71aa2f 100644 --- a/src/platform/core/package.json +++ b/src/platform/core/package.json @@ -43,6 +43,6 @@ "@angular/forms": "^4.1.0", "@angular/http": "^4.1.0", "@angular/router": "^4.1.0", - "@angular/material": "2.0.0-beta.5" + "@angular/material": "2.0.0-beta.6" } } From a118fb9e9f5b83c830f7be9bc7ea19586e1067f6 Mon Sep 17 00:00:00 2001 From: Meg Stepp Date: Sat, 27 May 2017 13:49:21 -0400 Subject: [PATCH 06/35] chore(docs): make covalent homepage look right in IE11 chore(docs): make covalent homepage look right in IE11 --- src/app/components/home/home.component.html | 4 ++-- src/styles.scss | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html index 85c6e1c107..167a426fe7 100644 --- a/src/app/components/home/home.component.html +++ b/src/app/components/home/home.component.html @@ -53,7 +53,7 @@

{{item.title}}

-
+
{{item.icon}} @@ -252,4 +252,4 @@

Feature Requests & Bugs

- + \ No newline at end of file diff --git a/src/styles.scss b/src/styles.scss index fe4daf3902..0efa25962f 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -14,5 +14,4 @@ html[dir="rtl"] & { direction: rtl; } - } \ No newline at end of file From 05ed24d40905c9cfb32058bb9d1c8689ae124067 Mon Sep 17 00:00:00 2001 From: Meg Stepp Date: Sat, 27 May 2017 13:58:00 -0400 Subject: [PATCH 07/35] chore(docs): update overview.component.html to support IE11 chore(docs): update overview.component.html to support IE11 --- .../components/components/overview/overview.component.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/components/components/overview/overview.component.html b/src/app/components/components/overview/overview.component.html index b72ac5ad64..0027633e37 100644 --- a/src/app/components/components/overview/overview.component.html +++ b/src/app/components/components/overview/overview.component.html @@ -5,7 +5,7 @@
-
+
{{item.icon}} @@ -28,7 +28,7 @@
-
+
{{item.icon}} @@ -65,7 +65,7 @@
-
+
{{item.icon}} From 98eaf28287db5ebe0597804818a99a11fe82b00a Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Sat, 27 May 2017 22:26:20 -0700 Subject: [PATCH 08/35] fix(theme): remove duplicate functions that are already part of material (#633) this were clashing with material's sass mixins --- src/platform/core/common/styles/_palette.scss | 63 ------------------ .../core/common/styles/_theme-functions.scss | 66 +------------------ 2 files changed, 2 insertions(+), 127 deletions(-) diff --git a/src/platform/core/common/styles/_palette.scss b/src/platform/core/common/styles/_palette.scss index 0dab0b72c0..44fb8767af 100644 --- a/src/platform/core/common/styles/_palette.scss +++ b/src/platform/core/common/styles/_palette.scss @@ -635,66 +635,3 @@ $mat-blue-grey: ( A700: $white-87-opacity, ) ); - - -// Background palette for light themes. -$mat-light-theme-background: ( - status-bar: map_get($mat-grey, 300), - app-bar: map_get($mat-grey, 100), - background: map_get($mat-grey, 50), - hover: rgba(black, 0.04), // TODO(kara): check style with Material Design UX - card: white, - dialog: white, - disabled-button: $black-12-opacity, - raised-button: white, - focused-button: $black-6-opacity, - selected-button: map_get($mat-grey, 300), - selected-disabled-button: map_get($mat-grey, 400), - disabled-button-toggle: map_get($mat-grey, 200), -); - -// Background palette for dark themes. -$mat-dark-theme-background: ( - status-bar: black, - app-bar: map_get($mat-grey, 900), - background: #303030, - hover: rgba(white, 0.04), // TODO(kara): check style with Material Design UX - card: map_get($mat-grey, 800), - dialog: map_get($mat-grey, 800), - disabled-button: $white-12-opacity, - raised-button: map-get($mat-grey, 800), - focused-button: $white-6-opacity, - selected-button: map_get($mat-grey, 900), - selected-disabled-button: map_get($mat-grey, 800), - disabled-button-toggle: map_get($mat-grey, 1000), -); - -// Foreground palette for light themes. -$mat-light-theme-foreground: ( - base: black, - divider: $black-12-opacity, - dividers: $black-12-opacity, - disabled: rgba(black, 0.38), - disabled-button: rgba(black, 0.38), - disabled-text: rgba(black, 0.38), - hint-text: rgba(black, 0.38), - secondary-text: rgba(black, 0.54), - icon: rgba(black, 0.54), - icons: rgba(black, 0.54), - text: rgba(black, 0.87) -); - -// Foreground palette for dark themes. -$mat-dark-theme-foreground: ( - base: white, - divider: $white-12-opacity, - dividers: $white-12-opacity, - disabled: rgba(white, 0.3), - disabled-button: rgba(white, 0.3), - disabled-text: rgba(white, 0.3), - hint-text: rgba(white, 0.3), - secondary-text: rgba(white, 0.7), - icon: white, - icons: white, - text: white -); \ No newline at end of file diff --git a/src/platform/core/common/styles/_theme-functions.scss b/src/platform/core/common/styles/_theme-functions.scss index 19046d13d0..3bd6a8208a 100644 --- a/src/platform/core/common/styles/_theme-functions.scss +++ b/src/platform/core/common/styles/_theme-functions.scss @@ -1,44 +1,8 @@ -@import 'palette'; - @function rem($multiplier) { $font-size: 10px; @return $multiplier * $font-size; } -// For a given hue in a palette, return the contrast color from the map of contrast palettes. -// @param $color-map -// @param $hue -@function mat-contrast($palette, $hue) { - @return map-get(map-get($palette, contrast), $hue); -} - - -// Creates a map of hues to colors for a theme. This is used to define a theme palette in terms -// of the Material Design hues. -// @param $color-map -// @param $primary -// @param $lighter -@function mat-palette($base-palette, $default: 500, $lighter: 100, $darker: 700) { - $result: map_merge($base-palette, ( - default: map-get($base-palette, $default), - lighter: map-get($base-palette, $lighter), - darker: map-get($base-palette, $darker), - default-contrast: mat-contrast($base-palette, $default), - lighter-contrast: mat-contrast($base-palette, $lighter), - darker-contrast: mat-contrast($base-palette, $darker) - )); - - // For each hue in the palette, add a "-contrast" color to the map. - @each $hue, $color in $base-palette { - $result: map_merge($result, ( - '#{$hue}-contrast': mat-contrast($base-palette, $hue) - )); - } - - @return $result; -} - - // Gets a color from a theme palette (the output of mat-palette). // The hue can be one of the standard values (500, A400, etc.), one of the three preconfigured // hues (default, lighter, darker), or any of the aforementioned prefixed with "-contrast". @@ -47,7 +11,7 @@ // @param $hue The hue from the palette to use. If this is a value between 0 and 1, it will // be treated as opacity. // @param $opacity The alpha channel value for the color. -@function mat-color($palette, $hue: default, $opacity: 1) { +@function mat-color($palette, $hue: default, $opacity: null) { // If hueKey is a number between zero and one, then it actually contains an // opacity value, so recall this function with the default hue and that given opacity. @if type-of($hue) == number and $hue >= 0 and $hue <= 1 { @@ -55,33 +19,7 @@ } $color: map-get($palette, $hue); - $opacity: if(opacity($color) < 1, opacity($color), $opacity); + $opacity: if($opacity == null, opacity($color), $opacity); @return rgba($color, $opacity); } - - -// Creates a container object for a light theme to be given to individual component theme mixins. -@function mat-light-theme($primary, $accent, $warn: mat-palette($mat-red)) { - @return ( - primary: $primary, - accent: $accent, - warn: $warn, - is-dark: false, - foreground: $mat-light-theme-foreground, - background: $mat-light-theme-background, - ); -} - - -// Creates a container object for a dark theme to be given to individual component theme mixins. -@function mat-dark-theme($primary, $accent, $warn: mat-palette($mat-red)) { - @return ( - primary: $primary, - accent: $accent, - warn: $warn, - is-dark: true, - foreground: $mat-dark-theme-foreground, - background: $mat-dark-theme-background, - ); -} \ No newline at end of file From 22d4342c4072560e3903820c4009f8129ec0d184 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Mon, 29 May 2017 18:02:42 -0700 Subject: [PATCH 09/35] feat(chips): chip templates + object list support + async loading support. (closes #252) (closes #359) (closes #601) (#626) * feat(chips): ability to use object lists and set templates for both autocomplete and chips this will be the base to support contact chips. First we need to make sure it works fine with objects and strings, and add good a11y around this. * chore(chips): update demo with a better example * feat(chips): make children be centered and vertical aligned (including children in templates) * chore(chips): remove unused CSS rule for datalist * fx(chips): remove [Object] value when adding an object from the autocomplete in a11y mode * fix(chips): delete by index rather than by value * *BREAKING CHANGE* feat(chips): abstract the autocomplete filtering and add debounce input it makes more sense to have the filtering done outside of chips and provide examples on how to achieve it since this way chips are agnostic of local vs server side filtering + string vs object filtering * chore(chips): update README.md and codeblocks in inputs/outputs * feat(chips): add [td-autocomplete-header] to be able to add a loader or something on long filters * chore(chips): remove td-autocomplete-header and have it inject anything under chips * chore(chips): update demos and load README.md in docs * fix(): chips README.md not loading highlight correctly * fix(chips): prevent chip duplication when pressing enter super fast * fix(chips): check for undefined value from input * perf(chips): support OnPush change detection * fix(chips): make 4th demo work again * fix(chips): validate against use case where selection happened without requireMatch * chore(chips): fix unit tests and add unit tests for new behavior * fix(chips): underline stops working in beta.6 * perf(chips): remove usage of async in autocomplete and use simple array beta.6 has some nuances around autocomplete so its needed to have more control * fix(): unit tests * chore(chips): make underline animatate the same way as material * fix(chips): keep focused state as long as you keep clicking inside the chips context * fix(): ninja fix mat-color function * feat(chips): make focused state remain while inside the chip context * chore(chips): polish code and add code blocks * fix(chips): block click event when clicking on host or td-chips-wrapper * fix(chips): a11y left + right arrows * chore(chips): modify the demos for a better chips experience * fix(chips): check if value is part of the ngModel * chore(chips): added more unit tests --- .../components/chips/chips.component.html | 273 ++++++++--- .../components/chips/chips.component.ts | 71 ++- .../components/components.module.ts | 4 +- src/platform/core/chips/README.md | 37 +- src/platform/core/chips/_chips-theme.scss | 2 +- src/platform/core/chips/chips.component.html | 83 ++-- src/platform/core/chips/chips.component.scss | 88 ++-- .../core/chips/chips.component.spec.ts | 421 +++++++++++++--- src/platform/core/chips/chips.component.ts | 460 +++++++++++++----- src/platform/core/chips/chips.module.ts | 8 +- 10 files changed, 1090 insertions(+), 357 deletions(-) diff --git a/src/app/components/components/chips/chips.component.html b/src/app/components/components/chips/chips.component.html index 3265649bcf..457f657a9f 100644 --- a/src/app/components/components/chips/chips.component.html +++ b/src/app/components/components/chips/chips.component.html @@ -1,17 +1,18 @@ - Chips & Autocomplete + Chips & Autocomplete with strings Autocomplete with chips and no custom inputs Demo
-
Type and select a preset option:
+
Type and select a preset option or press enter:
@@ -23,10 +24,11 @@ ]]> @@ -38,7 +40,7 @@ readOnly: boolean = false; chipAddition: boolean = true; - items: string[] = [ + strings: string[] = [ 'stepper', 'expansion-panel', 'markdown', @@ -52,8 +54,25 @@ 'need more?', ]; - itemsRequireMatch: string[] = this.items.slice(0, 6); + filteredStrings: string[]; + stringsModel: string[] = this.strings.slice(0, 6); + + ngOnInit(): void { + this.filterStrings(''); + } + + filterStrings(value: string): void { + this.filteredStrings = this.strings.filter((item: any) => { + if (value) { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + } else { + return false; + } + }).filter((filteredItem: any) => { + return this.stringsModel ? this.stringsModel.indexOf(filteredItem) < 0 : true; + }); + } } ]]> @@ -75,6 +94,167 @@
+ + Chips & Autocomplete with objects + Autocomplete with chips and templates + + + + Demo +
+
Type and select a preset option or press enter:
+ + + {{chip.city}}, (Pop: {{chip.population}}) + + + location_city {{option.city}} + + +
+
+ + Code + +

HTML:

+ + + + { {chip.city} }, (Pop: { {chip.population} }) + + + location_city { {option.city} } + + + ]]> + +

Typescript:

+ + { + if (value) { + return obj.city.toLowerCase().indexOf(value.toLowerCase()) > -1; + } else { + return false; + } + }).filter((filteredObj: any) => { + return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true; + }); + } + } + ]]> + +
+
+
+
+ + Chips & async Autocomplete + Load autocomplete items asynchronous when typing in the input + + + + Demo +
+
Type and see how it will load items async:
+ + + +
+
+ + Code + +

HTML:

+ + + + + ]]> + +

Typescript:

+ + { + this.filteredAsync = this.strings.filter((item: any) => { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + }).filter((filteredItem: any) => { + return this.asyncModel ? this.asyncModel.indexOf(filteredItem) < 0 : true; + }); + this.filteringAsync = false; + }, 2000); + } + } + } + ]]> + +
+
+
+
Autocomplete with custom inputs Autocomplete demo allowing custom inputs @@ -84,7 +264,7 @@ Demo
Type and select option or enter custom text and press enter:
- +
@@ -93,7 +273,7 @@

HTML:

+ ]]>

Typescript:

@@ -101,7 +281,7 @@
- - TdChipsComponent - How to use this component - - -

]]>

-

Use ]]> element to generate a list of strings as chips.

-

Add the [items] attribute to enable the autocomplete with a search list, and [requireMatch] to validate the input against the provided search list.

-

When used with forms, you can track change-states [dirty/pristine] and [touched/untouched].

-

Since [(ngModel)] would be an array, you need to implement a custom validator for [valid/invalid] when its empty.

-

Properties:

-

The ]]> component has {{chipsAttrs.length}} properties:

- - - -

{{attr.name}}: {{attr.type}}

-

{{attr.description}}

-
- -
-
-

Example:

-

HTML:

- - - - ]]> - -

Typescript:

- - - -

Setup:

-

Import the [CovalentChipsModule] in your NgModule:

- - - -
-
+ + diff --git a/src/app/components/components/chips/chips.component.ts b/src/app/components/components/chips/chips.component.ts index c6952a6dcb..808d0488a4 100644 --- a/src/app/components/components/chips/chips.component.ts +++ b/src/app/components/components/chips/chips.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding } from '@angular/core'; +import { Component, HostBinding, OnInit } from '@angular/core'; import { slideInDownAnimation } from '../../../app.animations'; @@ -8,7 +8,7 @@ import { slideInDownAnimation } from '../../../app.animations'; templateUrl: './chips.component.html', animations: [slideInDownAnimation], }) -export class ChipsDemoComponent { +export class ChipsDemoComponent implements OnInit { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; @@ -49,7 +49,9 @@ export class ChipsDemoComponent { readOnly: boolean = false; chipAddition: boolean = true; - items: string[] = [ + filteringAsync: boolean = false; + + strings: string[] = [ 'stepper', 'expansion-panel', 'markdown', @@ -63,6 +65,67 @@ export class ChipsDemoComponent { 'need more?', ]; - itemsRequireMatch: string[] = this.items.slice(0, 6); + filteredStrings: string[]; + + stringsModel: string[] = this.strings.slice(0, 6); + + objects: any[] = [ + {id: 1, city: 'San Diego', population: '4M'}, + {id: 2, city: 'San Franscisco', population: '6M'}, + {id: 3, city: 'Los Angeles', population: '5M'}, + {id: 4, city: 'Austin', population: '3M'}, + {id: 5, city: 'New York City', population: '10M'}, + ]; + + filteredObjects: string[]; + + objectsModel: string[] = this.objects.slice(0, 2); + + filteredAsync: string[]; + + asyncModel: string[] = this.strings.slice(0, 2); + + ngOnInit(): void { + this.filterStrings(''); + this.filterObjects(''); + } + + filterStrings(value: string): void { + this.filteredStrings = this.strings.filter((item: any) => { + if (value) { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + } else { + return false; + } + }).filter((filteredItem: any) => { + return this.stringsModel ? this.stringsModel.indexOf(filteredItem) < 0 : true; + }); + } + + filterObjects(value: string): void { + this.filteredObjects = this.objects.filter((obj: any) => { + if (value) { + return obj.city.toLowerCase().indexOf(value.toLowerCase()) > -1; + } else { + return false; + } + }).filter((filteredObj: any) => { + return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true; + }); + } + filterAsync(value: string): void { + this.filteredAsync = undefined; + if (value) { + this.filteringAsync = true; + setTimeout(() => { + this.filteredAsync = this.strings.filter((item: any) => { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + }).filter((filteredItem: any) => { + return this.asyncModel ? this.asyncModel.indexOf(filteredItem) < 0 : true; + }); + this.filteringAsync = false; + }, 2000); + } + } } diff --git a/src/app/components/components/components.module.ts b/src/app/components/components/components.module.ts index b4fd411a94..61d770f626 100644 --- a/src/app/components/components/components.module.ts +++ b/src/app/components/components/components.module.ts @@ -34,7 +34,8 @@ import { NgxChartsModule } from '@swimlane/ngx-charts'; import { TranslateModule } from '@ngx-translate/core'; import { MdButtonModule, MdListModule, MdIconModule, MdCardModule, MdMenuModule, MdInputModule, MdButtonToggleModule, MdSlideToggleModule, - MdSelectModule, MdToolbarModule, MdTabsModule, MdTooltipModule, MdCoreModule, MdAutocompleteModule } from '@angular/material'; + MdSelectModule, MdToolbarModule, MdTabsModule, MdTooltipModule, MdCoreModule, MdAutocompleteModule, + MdProgressBarModule } from '@angular/material'; import { CovalentCommonModule, CovalentLayoutModule, CovalentMediaModule, CovalentExpansionPanelModule, CovalentFileModule, CovalentStepsModule, CovalentLoadingModule, CovalentDialogsModule, CovalentSearchModule, CovalentPagingModule, @@ -92,6 +93,7 @@ import { DocumentationToolsModule } from '../../documentation-tools'; MdToolbarModule, MdTabsModule, MdTooltipModule, + MdProgressBarModule, /** Covalent Modules */ CovalentCommonModule, CovalentLayoutModule, diff --git a/src/platform/core/chips/README.md b/src/platform/core/chips/README.md index 4e7410a4aa..e75c47cd6f 100644 --- a/src/platform/core/chips/README.md +++ b/src/platform/core/chips/README.md @@ -1,8 +1,8 @@ # td-chips -`td-chips` element generates a list of strings as chips. +`td-chips` element generates a list of strings or objects as chips. -Add the [items] attribute to enable the autocomplete with a search list, and [requireMatch] to validated the input against the provided search list. +Add the [items] attribute to enable the autocomplete with a list, and [requireMatch] to not allow custom values. ## API Summary @@ -10,12 +10,14 @@ Properties: | Name | Type | Description | | --- | --- | --- | -| `items?` | `string[]` | Enables Autocompletion with the provided list of search strings. -| `readOnly` | `boolean` | Disables the chip input and removal. -| `requireMatch?` | `boolean` | Validates input against the provided search list before adding it to the model. If it doesnt exist, it cancels the event. +| `items?` | `any[]` | Renders the `md-autocomplete` with the provided list to display as options. +| `requireMatch?` | `boolean` | Blocks custom inputs and only allows selections from the autocomplete list. | `placeholder?` | `string` | Placeholder for the autocomplete input. -| `add?` | `function` | Method to be executed when string is added as chip through the autocomplete. Sends chip value as event. -| `remove?` | `function` | Method to be executed when string is removed as chip with the "remove" button. Sends chip value as event. +| `chipAddition` | `boolean` | Disables the ability to add chips. When setting readOnly as true, this will be overriden. Defaults to true. +| `debounce` | `string` | Debounce timeout between keypresses. Defaults to 200. +| `add?` | `function` | Method to be executed when a chip is added. Sends chip value as event. +| `remove?` | `function` | Method to be executed when a chip is removed. Sends chip value as event. +| `inputChange?` | `function` | Method to be executed when the value in the autocomplete input changes. Sends string value as event. ## Setup @@ -37,7 +39,22 @@ export class MyModule {} Example for HTML usage: - ```html - +```html + + + {{chip}} + + + {{option}} + + // anything below it - ``` \ No newline at end of file +``` diff --git a/src/platform/core/chips/_chips-theme.scss b/src/platform/core/chips/_chips-theme.scss index 2ad63ddd1a..bc67beaf32 100644 --- a/src/platform/core/chips/_chips-theme.scss +++ b/src/platform/core/chips/_chips-theme.scss @@ -22,7 +22,7 @@ } } } - md-icon { + md-icon.td-chip-removal { color: mat-color($foreground, hint-text); &:hover { color: mat-color($foreground, icon); diff --git a/src/platform/core/chips/chips.component.html b/src/platform/core/chips/chips.component.html index b8df30f41e..454a036081 100644 --- a/src/platform/core/chips/chips.component.html +++ b/src/platform/core/chips/chips.component.html @@ -1,38 +1,53 @@ -
- - - - {{chip}} - +
+ + +
+
+ {{chip}} + + +
+ cancel - +
+
+
+ + + + + + + {{item}} + + + - - - - - - {{item}} - - - -
- -
+
+
+ +
+ \ No newline at end of file diff --git a/src/platform/core/chips/chips.component.scss b/src/platform/core/chips/chips.component.scss index d746e6458d..2f9d607a30 100644 --- a/src/platform/core/chips/chips.component.scss +++ b/src/platform/core/chips/chips.component.scss @@ -3,73 +3,79 @@ :host { display: block; padding: 0px 5px 0px 5px; + .td-chips-wrapper { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: flex-start; + } /deep/ { .mat-input-wrapper { margin-bottom: 2px; } + /* TODO see if we can make styles more abstract to future proof for contact chips */ .mat-basic-chip { display: inline-block; cursor: default; border-radius: 16px; - line-height: 32px; @include rtl(margin, 8px 8px 0 0, 8px 0 0 8px); - padding: 0 12px; + .td-basic-chip { + min-height: 30px; + font-size: 14px; + @include rtl(padding, 0 0 0 12px, 0 12px 0 0); + } box-sizing: border-box; max-width: 100%; position: relative; - md-icon { - position: relative; - top: 5px; - @include rtl(left, 5px, auto); - @include rtl(right, auto, 5px); - height: 18px; - width: 18px; - font-size: 19px; + &.td-chip-disabled { + @include rtl(padding, 0 12px 0 0, 0 0 0 12px); + } + md-icon.td-chip-removal { + margin: 0 4px; + font-size: 21px; &:hover { cursor: pointer; } } } } -} - -.mat-input-underline { - position: relative; - height: 1px; - width: 100%; - - &.mat-disabled { - border-top: 0; - background-position: 0; - background-size: 4px 1px; - background-repeat: repeat-x; - } - - .mat-input-ripple { - position: absolute; - height: 2px; - z-index: 1; - top: -1px; + .mat-input-underline { + position: relative; + height: 1px; width: 100%; - transform-origin: top; - opacity: 0; - transform: scaleY(0); - &.mat-warn { - opacity: 1; - transform: scaleY(1); + margin-top: 4px; + border-top-width: 1px; + border-top-style: solid; + + &.mat-disabled { + border-top: 0; + background-position: 0; + background-size: 4px 1px; + background-repeat: repeat-x; } - &.mat-focused { - opacity: 1; - transform: scaleY(1); + + .mat-input-ripple { + position: absolute; + height: 2px; + z-index: 1; + top: -1px; + width: 100%; + transform-origin: 50%; + transform: scaleX(0.5); + visibility: hidden; + transition: background-color .3s cubic-bezier(.55,0,.55,.2); + &.mat-focused { + visibility: visible; + transform: scaleX(1); + transition: transform 150ms linear, + background-color .3s cubic-bezier(.55,0,.55,.2); + } } } } :host { /deep/ md-input-container { - input::-webkit-calendar-picker-indicator { // removes input arrow for datalist in chrome - display: none; - } .mat-input-underline { display: none; } diff --git a/src/platform/core/chips/chips.component.spec.ts b/src/platform/core/chips/chips.component.spec.ts index a00e6d6f8c..0889ac34da 100644 --- a/src/platform/core/chips/chips.component.spec.ts +++ b/src/platform/core/chips/chips.component.spec.ts @@ -3,15 +3,27 @@ import { async, ComponentFixture, } from '@angular/core/testing'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Component, DebugElement } from '@angular/core'; import { FormControl, FormsModule, ReactiveFormsModule, } from '@angular/forms'; -import { OverlayContainer, MdInputDirective, DOWN_ARROW, UP_ARROW, ENTER, SPACE, TAB } from '@angular/material'; +import { OverlayContainer, MdInputDirective, MdChip, BACKSPACE, ENTER, LEFT_ARROW, RIGHT_ARROW } from '@angular/material'; import { By } from '@angular/platform-browser'; import { CovalentChipsModule, TdChipsComponent } from './chips.module'; +function createFakeKeyboardEvent(keyCode: number): any { + return { + keyCode: keyCode, + preventDefault: function(): void { + /* noop */ + }, + stopPropagation: function(): void { + /* noop */ + }, + }; +} + describe('Component: Chips', () => { let overlayContainerElement: HTMLElement; @@ -21,10 +33,12 @@ describe('Component: Chips', () => { CovalentChipsModule, FormsModule, ReactiveFormsModule, - BrowserAnimationsModule, + NoopAnimationsModule, ], declarations: [ + TdChipsA11yTestComponent, TdChipsBasicTestComponent, + TdChipsObjectsRequireMatchTestComponent, ], providers: [ {provide: OverlayContainer, useFactory: () => { @@ -44,6 +58,228 @@ describe('Component: Chips', () => { TestBed.compileComponents(); })); + describe('a11y keyboard in chips and input: ', () => { + let fixture: ComponentFixture; + let input: DebugElement; + let chips: DebugElement; + + beforeEach(() => { + fixture = TestBed.createComponent(TdChipsA11yTestComponent); + fixture.detectChanges(); + + chips = fixture.debugElement.query(By.directive(TdChipsComponent)); + input = chips.query(By.css('input')); + }); + + it('should focus input', (done: DoneFn) => { + fixture.componentInstance.chipAddition = true; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.componentInstance)._inputChild.focused).toBeTruthy(); + done(); + }); + }); + }); + + it('should focus first chip', (done: DoneFn) => { + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + done(); + }); + }); + }); + }); + + it('should focus around the chips going left', (done: DoneFn) => { + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[0] + .triggerEventHandler('keydown', createFakeKeyboardEvent(LEFT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[2].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[2] + .triggerEventHandler('keydown', createFakeKeyboardEvent(LEFT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[1].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[1] + .triggerEventHandler('keydown', createFakeKeyboardEvent(LEFT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + done(); + }); + }); + }); + }); + }); + }); + }); + + it('should focus around the chips going right', (done: DoneFn) => { + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[0] + .triggerEventHandler('keydown', createFakeKeyboardEvent(RIGHT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[1].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[1] + .triggerEventHandler('keydown', createFakeKeyboardEvent(RIGHT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[2].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[2] + .triggerEventHandler('keydown', createFakeKeyboardEvent(RIGHT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + done(); + }); + }); + }); + }); + }); + }); + }); + + }); + + describe('panel usage and add/removal: ', () => { + let fixture: ComponentFixture; + let input: DebugElement; + let chips: DebugElement; + + beforeEach(() => { + fixture = TestBed.createComponent(TdChipsBasicTestComponent); + fixture.detectChanges(); + + chips = fixture.debugElement.query(By.directive(TdChipsComponent)); + input = chips.query(By.css('input')); + }); + + it('should set a value in the input and enter it as chip', (done: DoneFn) => { + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + (chips.componentInstance)._inputChild.value = 'test'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + input.triggerEventHandler('keyup.enter', createFakeKeyboardEvent(ENTER)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + // set tiemout + setTimeout(() => { + expect(chips.componentInstance.value.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement.textContent).toContain('test'); + done(); + }, 200); + }); + }); + }); + }); + + it('should open the panel, click on an option and add it as chip', (done: DoneFn) => { + fixture.componentInstance.filter(''); + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const option: HTMLElement = overlayContainerElement.querySelector('md-option'); + option.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(1); + done(); + }); + }); + }); + + it('should open the panel, click on an option to add it as chip and remove it with backspace', (done: DoneFn) => { + fixture.componentInstance.filter(''); + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const option: HTMLElement = overlayContainerElement.querySelector('md-option'); + option.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(1); + fixture.debugElement.queryAll(By.directive(MdChip))[0].triggerEventHandler('keydown', createFakeKeyboardEvent(BACKSPACE)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(0); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(0); + done(); + }); + }); + }); + }); + + it('should open the panel, click on an option to add it as chip and remove it by clicking on the remove button', (done: DoneFn) => { + fixture.componentInstance.filter(''); + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const option: HTMLElement = overlayContainerElement.querySelector('md-option'); + option.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(1); + fixture.debugElement.queryAll(By.css('.td-chip-removal'))[0].triggerEventHandler('click', new Event('click')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(0); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(0); + done(); + }); + }); + }); + }); + + }); + describe('panel usage and filtering: ', () => { let fixture: ComponentFixture; let input: DebugElement; @@ -53,7 +289,6 @@ describe('Component: Chips', () => { fixture = TestBed.createComponent(TdChipsBasicTestComponent); fixture.detectChanges(); - input = fixture.debugElement.query(By.css('input')); chips = fixture.debugElement.query(By.directive(TdChipsComponent)); }); @@ -65,20 +300,18 @@ describe('Component: Chips', () => { expect(overlayContainerElement.textContent).not.toContain('chips'); expect(overlayContainerElement.textContent).not.toContain('pasta'); expect(overlayContainerElement.textContent).not.toContain('sushi'); - input.triggerEventHandler('focus', new Event('focus')); + fixture.componentInstance.filter(''); + chips.triggerEventHandler('focus', new Event('focus')); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(overlayContainerElement.textContent).toContain('steak'); - expect(overlayContainerElement.textContent).toContain('pizza'); - expect(overlayContainerElement.textContent).toContain('tacos'); - expect(overlayContainerElement.textContent).toContain('sandwich'); - expect(overlayContainerElement.textContent).toContain('chips'); - expect(overlayContainerElement.textContent).toContain('pasta'); - expect(overlayContainerElement.textContent).toContain('sushi'); - done(); - }); + expect(overlayContainerElement.textContent).toContain('steak'); + expect(overlayContainerElement.textContent).toContain('pizza'); + expect(overlayContainerElement.textContent).toContain('tacos'); + expect(overlayContainerElement.textContent).toContain('sandwich'); + expect(overlayContainerElement.textContent).toContain('chips'); + expect(overlayContainerElement.textContent).toContain('pasta'); + expect(overlayContainerElement.textContent).toContain('sushi'); + done(); }); }); @@ -90,86 +323,81 @@ describe('Component: Chips', () => { expect(overlayContainerElement.textContent).not.toContain('chips'); expect(overlayContainerElement.textContent).not.toContain('pasta'); expect(overlayContainerElement.textContent).not.toContain('sushi'); - input.triggerEventHandler('focus', new Event('focus')); + fixture.componentInstance.filter(''); + chips.triggerEventHandler('focus', new Event('focus')); fixture.detectChanges(); fixture.whenStable().then(() => { + expect(overlayContainerElement.textContent).toContain('steak'); + expect(overlayContainerElement.textContent).toContain('pizza'); + expect(overlayContainerElement.textContent).toContain('tacos'); + expect(overlayContainerElement.textContent).toContain('sandwich'); + expect(overlayContainerElement.textContent).toContain('chips'); + expect(overlayContainerElement.textContent).toContain('pasta'); + expect(overlayContainerElement.textContent).toContain('sushi'); + (chips.componentInstance).inputControl.setValue('a'); fixture.detectChanges(); fixture.whenStable().then(() => { - expect(overlayContainerElement.textContent).toContain('steak'); - expect(overlayContainerElement.textContent).toContain('pizza'); - expect(overlayContainerElement.textContent).toContain('tacos'); - expect(overlayContainerElement.textContent).toContain('sandwich'); - expect(overlayContainerElement.textContent).toContain('chips'); - expect(overlayContainerElement.textContent).toContain('pasta'); - expect(overlayContainerElement.textContent).toContain('sushi'); - (chips.componentInstance).inputControl.setValue('a'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(overlayContainerElement.textContent).toContain('steak'); - expect(overlayContainerElement.textContent).toContain('pizza'); - expect(overlayContainerElement.textContent).toContain('tacos'); - expect(overlayContainerElement.textContent).toContain('sandwich'); - expect(overlayContainerElement.textContent).not.toContain('chips'); - expect(overlayContainerElement.textContent).toContain('pasta'); - expect(overlayContainerElement.textContent).not.toContain('sushi'); - done(); - }); - }, 100); - }); + // mimic debounce + setTimeout(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(overlayContainerElement.textContent).toContain('steak'); + expect(overlayContainerElement.textContent).toContain('pizza'); + expect(overlayContainerElement.textContent).toContain('tacos'); + expect(overlayContainerElement.textContent).toContain('sandwich'); + expect(overlayContainerElement.textContent).not.toContain('chips'); + expect(overlayContainerElement.textContent).toContain('pasta'); + expect(overlayContainerElement.textContent).not.toContain('sushi'); + done(); + }); + }, 200); }); }); }); + }); - it('should open the panel, filter selectedItems and filter the list', (done: DoneFn) => { - expect(overlayContainerElement.textContent).not.toContain('steak'); - expect(overlayContainerElement.textContent).not.toContain('pizza'); - expect(overlayContainerElement.textContent).not.toContain('tacos'); - expect(overlayContainerElement.textContent).not.toContain('sandwich'); - expect(overlayContainerElement.textContent).not.toContain('chips'); - expect(overlayContainerElement.textContent).not.toContain('pasta'); - expect(overlayContainerElement.textContent).not.toContain('sushi'); - fixture.componentInstance.selectedItems.push('steak'); - fixture.componentInstance.selectedItems.push('sandwich'); - input.triggerEventHandler('focus', new Event('focus')); + describe('panel usage and requireMatch usage: ', () => { + let fixture: ComponentFixture; + let input: DebugElement; + let chips: DebugElement; + + beforeEach(() => { + fixture = TestBed.createComponent(TdChipsObjectsRequireMatchTestComponent); + fixture.detectChanges(); + + chips = fixture.debugElement.query(By.directive(TdChipsComponent)); + }); + + it('should open the panel, click on an option to add it as chip', (done: DoneFn) => { + fixture.componentInstance.objects = [{ + name: 'San Diego', + }, { + name: 'Los Angeles', + }]; + chips.triggerEventHandler('focus', new Event('focus')); fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); fixture.whenStable().then(() => { - expect(overlayContainerElement.textContent).not.toContain('steak'); - expect(overlayContainerElement.textContent).toContain('pizza'); - expect(overlayContainerElement.textContent).toContain('tacos'); - expect(overlayContainerElement.textContent).not.toContain('sandwich'); - expect(overlayContainerElement.textContent).toContain('chips'); - expect(overlayContainerElement.textContent).toContain('pasta'); - expect(overlayContainerElement.textContent).toContain('sushi'); - (chips.componentInstance).inputControl.setValue('a'); + const option: HTMLElement = overlayContainerElement.querySelector('md-option'); + option.click(); fixture.detectChanges(); fixture.whenStable().then(() => { - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(overlayContainerElement.textContent).not.toContain('steak'); - expect(overlayContainerElement.textContent).toContain('pizza'); - expect(overlayContainerElement.textContent).toContain('tacos'); - expect(overlayContainerElement.textContent).not.toContain('sandwich'); - expect(overlayContainerElement.textContent).not.toContain('chips'); - expect(overlayContainerElement.textContent).toContain('pasta'); - expect(overlayContainerElement.textContent).not.toContain('sushi'); - done(); - }); - }, 100); + expect(chips.componentInstance.value.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(1); + done(); }); }); }); }); + }); // TODO - // requireMatch usage + // more requireMatch usage + + // more a11y unit tests // readOnly usage @@ -185,11 +413,31 @@ describe('Component: Chips', () => { @Component({ template: ` - + + `, +}) +class TdChipsA11yTestComponent { + chipAddition: boolean = true; + items: string[] = [ + 'steak', + 'pizza', + 'tacos', + 'sandwich', + 'chips', + 'pasta', + 'sushi', + ]; + selectedItems: string[] = this.items.slice(0, 3); +} + +@Component({ + template: ` + `, }) class TdChipsBasicTestComponent { placeholder: string; + filteredItems: string[]; selectedItems: string[] = []; items: string[] = [ 'steak', @@ -200,4 +448,27 @@ class TdChipsBasicTestComponent { 'pasta', 'sushi', ]; + filter(value: string): void { + this.filteredItems = this.items.filter((item: any) => { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + }).filter((filteredItem: any) => { + return this.selectedItems ? this.selectedItems.indexOf(filteredItem) < 0 : true; + }); + } +} + +@Component({ + template: ` + + + {{chip.name}} + + + {{option.name}} + + `, +}) +class TdChipsObjectsRequireMatchTestComponent { + selectedObjects: any[] = []; + objects: any[]; } diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index 419da5af4a..f7dd7898f4 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -1,51 +1,84 @@ -import { Component, Input, Output, forwardRef, DoCheck, ViewChild, ViewChildren, QueryList, OnInit, HostListener } from '@angular/core'; +import { Component, Input, Output, forwardRef, DoCheck, ViewChild, ViewChildren, QueryList, OnInit, HostListener, + ElementRef, Optional, Inject, Directive, TemplateRef, ViewContainerRef, ContentChild, ChangeDetectionStrategy, + ChangeDetectorRef, AfterViewInit, OnDestroy, HostBinding } from '@angular/core'; +import { DOCUMENT } from '@angular/platform-browser'; import { EventEmitter } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor, FormControl } from '@angular/forms'; -import { MdChip, MdInputDirective, ESCAPE, LEFT_ARROW, RIGHT_ARROW, DELETE, BACKSPACE } from '@angular/material'; +import { MdChip, MdInputDirective, TemplatePortalDirective, MdOption, MdAutocompleteTrigger, UP_ARROW, DOWN_ARROW, + ESCAPE, LEFT_ARROW, RIGHT_ARROW, DELETE, BACKSPACE, ENTER, SPACE, TAB, HOME } from '@angular/material'; import { Observable } from 'rxjs/Observable'; -import { Subject } from 'rxjs/Subject'; +import { Subscription } from 'rxjs/Subscription'; import 'rxjs/add/observable/timer'; +import 'rxjs/add/operator/toPromise'; import 'rxjs/add/operator/debounceTime'; const noop: any = () => { // empty method }; -export const TD_CHIPS_CONTROL_VALUE_ACCESSOR: any = { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => TdChipsComponent), - multi: true, -}; +@Directive({ + selector: '[td-basic-chip]ng-template', +}) +export class TdBasicChipDirective extends TemplatePortalDirective { + constructor(templateRef: TemplateRef, viewContainerRef: ViewContainerRef) { + super(templateRef, viewContainerRef); + } +} + +@Directive({ + selector: '[td-autocomplete-option]ng-template', +}) +export class TdAutocompleteOptionDirective extends TemplatePortalDirective { + constructor(templateRef: TemplateRef, viewContainerRef: ViewContainerRef) { + super(templateRef, viewContainerRef); + } +} @Component({ - providers: [ TD_CHIPS_CONTROL_VALUE_ACCESSOR ], + providers: [{ + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => TdChipsComponent), + multi: true, + }], selector: 'td-chips', styleUrls: ['./chips.component.scss' ], templateUrl: './chips.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { +export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, AfterViewInit, OnDestroy { + + private _outsideClickSubs: Subscription; /** * Implemented as part of ControlValueAccessor. */ - private _value: any = []; + private _value: any[] = []; + private _items: any[]; private _length: number = 0; private _requireMatch: boolean = false; private _readOnly: boolean = false; private _chipAddition: boolean = true; + private _focused: boolean = false; + private _tabIndex: number = 0; + + _internalClick: boolean = false; @ViewChild(MdInputDirective) _inputChild: MdInputDirective; + @ViewChild(MdAutocompleteTrigger) _autocompleteTrigger: MdAutocompleteTrigger; @ViewChildren(MdChip) _chipsChildren: QueryList; - /** - * Boolean value that specifies if the input is valid against the provieded list. - */ - matches: boolean = true; + @ContentChild(TdBasicChipDirective) _basicChipTemplate: TdBasicChipDirective; + @ContentChild(TdAutocompleteOptionDirective) _autocompleteOptionTemplate: TdAutocompleteOptionDirective; + + @ViewChildren(MdOption) _options: QueryList; + /** * Flag that is true when autocomplete is focused. */ - focused: boolean = false; + get focused(): boolean { + return this._focused; + } /** * FormControl for the mdInput element. @@ -53,25 +86,22 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { inputControl: FormControl = new FormControl(); /** - * Subject to control what items to render in the autocomplete - */ - subject: Subject = new Subject(); - - /** - * Observable of items to render in the autocomplete + * items?: any[] + * Renders the `md-autocomplete` with the provided list to display as options. */ - filteredItems: Observable = this.subject.asObservable(); - - /** - * items?: string[] - * Enables Autocompletion with the provided list of strings. - */ - @Input('items') items: string[] = []; + @Input('items') + set items(items: any[]) { + this._items = items; + this._setFirstOptionActive(); + this._changeDetectorRef.markForCheck(); + } + get items(): any[] { + return this._items; + } /** * requireMatch?: boolean - * Validates input against the provided list before adding it to the model. - * If it doesnt exist, it cancels the event. + * Blocks custom inputs and only allows selections from the autocomplete list. */ @Input('requireMatch') set requireMatch(requireMatch: any) { @@ -96,8 +126,8 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { /** * chipAddition?: boolean - * Disables the ability to add chips. If it doesn't exist chip addition defaults to true. - * When setting readOnly as true, this will be overriden. + * Disables the ability to add chips. When setting readOnly as true, this will be overriden. + * Defaults to true. */ @Input('chipAddition') set chipAddition(chipAddition: boolean) { @@ -122,19 +152,32 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { */ @Input('placeholder') placeholder: string; + /** + * debounce?: number + * Debounce timeout between keypresses. Defaults to 200. + */ + @Input('debounce') debounce: number = 200; + /** * add?: function - * Method to be executed when string is added as chip through the autocomplete. + * Method to be executed when a chip is added. * Sends chip value as event. */ - @Output('add') add: EventEmitter = new EventEmitter(); + @Output('add') onAdd: EventEmitter = new EventEmitter(); /** * remove?: function - * Method to be executed when string is removed as chip with the "remove" button. + * Method to be executed when a chip is removed. * Sends chip value as event. */ - @Output('remove') remove: EventEmitter = new EventEmitter(); + @Output('remove') onRemove: EventEmitter = new EventEmitter(); + + /** + * inputChange?: function + * Method to be executed when the value in the autocomplete input changes. + * Sends string value as event. + */ + @Output('inputChange') onInputChange: EventEmitter = new EventEmitter(); /** * Implemented as part of ControlValueAccessor. @@ -143,24 +186,78 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { if (v !== this._value) { this._value = v; this._length = this._value ? this._value.length : 0; - if (this._value) { - this._filter(this.inputControl.value); - } } } get value(): any { return this._value; } + /** + * Hostbinding to set the a11y of the TdChipsComponent depending on its state + */ + @HostBinding('attr.tabindex') + get tabIndex(): number { + return this.readOnly ? -1 : this._tabIndex; + } + + constructor(private _elementRef: ElementRef, + private _changeDetectorRef: ChangeDetectorRef, + @Optional() @Inject(DOCUMENT) private _document: any) {} + + /** + * Listens to host focus event to act on it + */ + @HostListener('focus', ['$event']) + focusListener(event: FocusEvent): void { + this.focus(); + event.preventDefault(); + } + + /** + * If clicking on :host or `td-chips-wrapper`, then we stop the click propagation so the autocomplete + * doesnt close automatically. + */ + @HostListener('click', ['$event']) + clickListener(event: Event): void { + const clickTarget: HTMLElement = event.target; + if (clickTarget === this._elementRef.nativeElement || + clickTarget.className.indexOf('td-chips-wrapper') > -1) { + event.preventDefault(); + event.stopPropagation(); + } + } + + /** + * Listens to host keydown event to act on it depending on the keypress + */ + @HostListener('keydown', ['$event']) + keydownListener(event: KeyboardEvent): void { + switch (event.keyCode) { + case TAB: + // if tabing out, then unfocus the component + Observable.timer().toPromise().then(() => { + this.removeFocusedState(); + }); + break; + case ESCAPE: + case HOME: + this.focus(); + break; + default: + // default + } + } + ngOnInit(): void { this.inputControl.valueChanges - .debounceTime(100) + .debounceTime(this.debounce) .subscribe((value: string) => { - this.matches = true; - this._filter(value); + this.onInputChange.emit(value ? value : ''); }); - // filter the autocomplete options after everything is rendered - Observable.timer().subscribe(() => { - this._filter(this.inputControl.value); - }); + this._changeDetectorRef.markForCheck(); + } + + ngAfterViewInit(): void { + this._watchOutsideClick(); + this._changeDetectorRef.markForCheck(); } ngDoCheck(): void { @@ -171,35 +268,72 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { } } - /** - * Returns a list of filtered items. - */ - filter(val: string): string[] { - return this.items.filter((item: string) => { - return val ? item.indexOf(val) > -1 : true; - }); + ngOnDestroy(): void { + if (this._outsideClickSubs) { + this._outsideClickSubs.unsubscribe(); + this._outsideClickSubs = undefined; + } } /** * Method that is executed when trying to create a new chip from the autocomplete. + * It check if [requireMatch] is enabled, and tries to add the first active option + * else if just adds the value thats on the input * returns 'true' if successful, 'false' if it fails. */ - addChip(value: string): boolean { - if (value.trim() === '' || this._value.indexOf(value) > -1) { - this.matches = false; - return false; - } - if (this.items && this.requireMatch) { - if (this.items.indexOf(value) < 0) { - this.matches = false; + _handleAddChip(): boolean { + let value: any; + if (this.requireMatch) { + let selectedOptions: MdOption[] = this._options.toArray().filter((option: MdOption) => { + return option.active; + }); + if (selectedOptions.length > 0) { + value = selectedOptions[0].value; + selectedOptions[0].setInactiveStyles(); + } + if (!value) { return false; } + } else { + // if there is a selection, then use that + // else use the input value as chip + if (this._autocompleteTrigger.activeOption) { + value = this._autocompleteTrigger.activeOption.value; + this._autocompleteTrigger.activeOption.setInactiveStyles(); + } else { + value = this._inputChild.value; + if (value.trim() === '') { + return false; + } + } + } + return this.addChip(value); + } + + /** + * Method thats exectuted when trying to add a value as chip + * returns 'true' if successful, 'false' if it fails. + */ + addChip(value: any): boolean { + this.inputControl.setValue(''); + // check if value is already part of the model + if (this._value.indexOf(value) > -1) { + return false; } this._value.push(value); - this.add.emit(value); + this.onAdd.emit(value); this.onChange(this._value); - this.inputControl.setValue(''); - this.matches = true; + this._changeDetectorRef.markForCheck(); + /** + * add a 200 ms delay when reopening the autocomplete to give it time + * to rerender the next list and at the correct spot + */ + this._closeAutocomplete(); + Observable.timer(200).toPromise().then(() => { + this.setFocusedState(); + this._setFirstOptionActive(); + this._openAutocomplete(); + }); return true; } @@ -207,36 +341,66 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { * Method that is executed when trying to remove a chip. * returns 'true' if successful, 'false' if it fails. */ - removeChip(value: string): boolean { - let index: number = this._value.indexOf(value); - if (index < 0) { + removeChip(index: number): boolean { + let removedValues: any[] = this._value.splice(index, 1); + if (removedValues.length === 0) { return false; } - this._value.splice(index, 1); - this.remove.emit(value); + + /** + * Checks if deleting last single chip, to focus input afterwards + * Else check if its not the last chip of the list to focus the next one. + */ + if (index === (this._totalChips - 1) && index === 0) { + this._inputChild.focus(); + } else if (index < (this._totalChips - 1)) { + this._focusChip(index + 1); + } else if (index > 0) { + this._focusChip(index - 1); + } + + this.onRemove.emit(removedValues[0]); this.onChange(this._value); this.inputControl.setValue(''); + this._changeDetectorRef.markForCheck(); return true; } - handleFocus(): boolean { - this.focused = true; + _handleFocus(): boolean { + this.setFocusedState(); + this._setFirstOptionActive(); return true; } - handleBlur(): boolean { - this.focused = false; - this.matches = true; - this.onTouched(); - return true; + /** + * Sets focus state of the component + */ + setFocusedState(): void { + if (!this.readOnly) { + this._focused = true; + this._tabIndex = -1; + this._changeDetectorRef.markForCheck(); + } } /** - * Programmatically focus the input. Since its the component entry point + * Removes focus state of the component + */ + removeFocusedState(): void { + this._focused = false; + this._tabIndex = 0; + this._changeDetectorRef.markForCheck(); + } + + /** + * Programmatically focus the input or first chip. Since its the component entry point + * depending if a user can add or remove chips */ focus(): void { if (this.canAddChip) { this._inputChild.focus(); + } else if (!this.readOnly) { + this._focusFirstChip(); } } @@ -245,9 +409,23 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { */ _inputKeydown(event: KeyboardEvent): void { switch (event.keyCode) { + case UP_ARROW: + /** + * Since the first item is highlighted on [requireMatch], we need to inactivate it + * when pressing the up key + */ + if (this.requireMatch) { + let length: number = this._options.length; + if (length > 0 && this._options.toArray()[0].active) { + this._options.toArray()[0].setInactiveStyles(); + event.preventDefault(); + } + } + break; case LEFT_ARROW: case DELETE: case BACKSPACE: + this._closeAutocomplete(); /** Check to see if input is empty when pressing left arrow to move to the last chip */ if (!this._inputChild.value) { this._focusLastChip(); @@ -255,6 +433,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { } break; case RIGHT_ARROW: + this._closeAutocomplete(); /** Check to see if input is empty when pressing right arrow to move to the first chip */ if (!this._inputChild.value) { this._focusFirstChip(); @@ -275,16 +454,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { case BACKSPACE: /** Check to see if not in [readOnly] state to delete a chip */ if (!this.readOnly) { - /** - * Checks if deleting last single chip, to focus input afterwards - * Else check if its not the last chip of the list to focus the next one. - */ - if (index === (this._totalChips - 1) && index === 0) { - this.focus(); - } else if (index < (this._totalChips - 1)) { - this._focusChip(index + 1); - } - this.removeChip(this.value[index]); + this.removeChip(index); } break; case LEFT_ARROW: @@ -292,29 +462,65 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { * Check to see if left arrow was pressed while focusing the first chip to focus input next * Also check if input should be focused */ - if (index === 0 && this.canAddChip) { - this.focus(); - event.stopPropagation(); + if (index === 0) { + if (this.canAddChip) { + this._inputChild.focus(); + } else { + this._focusLastChip(); + } + } else if (index > 0) { + this._focusChip(index - 1); } + event.stopPropagation(); break; case RIGHT_ARROW: /** * Check to see if right arrow was pressed while focusing the last chip to focus input next * Also check if input should be focused */ - if (index === (this._totalChips - 1) && this.canAddChip) { - this.focus(); - event.stopPropagation(); + if (index === (this._totalChips - 1)) { + if (this.canAddChip) { + this._inputChild.focus(); + } else { + this._focusFirstChip(); + } + } else if (index < (this._totalChips - 1)) { + this._focusChip(index + 1); } - break; - case ESCAPE: - this.focus(); + event.stopPropagation(); break; default: // default } } + /** + * Method to remove from display the value added from the autocomplete since it goes directly as chip. + */ + _removeInputDisplay(): string { + return ''; + } + + /** + * Method to open the autocomplete manually if its not already opened + */ + _openAutocomplete(): void { + if (!this._autocompleteTrigger.panelOpen) { + this._autocompleteTrigger.openPanel(); + this._changeDetectorRef.markForCheck(); + } + } + + /** + * Method to close the autocomplete manually if its not already closed + */ + _closeAutocomplete(): void { + if (this._autocompleteTrigger.panelOpen) { + this._autocompleteTrigger.closePanel(); + this._changeDetectorRef.markForCheck(); + } + } + /** * Implemented as part of ControlValueAccessor. */ @@ -333,18 +539,6 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { onChange = (_: any) => noop; onTouched = () => noop; - /** - * - * Method to filter the options for the autocomplete - */ - private _filter(value: string): void { - let items: string[] = this.filter(value); - items = items.filter((filteredItem: string) => { - return this._value && filteredItem ? this._value.indexOf(filteredItem) < 0 : true; - }); - this.subject.next(items); - } - /** * Get total of chips */ @@ -383,5 +577,53 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit { } else { this.inputControl.disable(); } + this._changeDetectorRef.markForCheck(); + } + + /** + * Sets first option as active to let the user know which one will be added when pressing enter + * Only if [requireMatch] has been set + */ + private _setFirstOptionActive(): void { + if (this.requireMatch) { + // need to use a timer here to wait until the autocomplete has been opened (end of queue) + Observable.timer().toPromise().then(() => { + if (this.focused && this._options && this._options.length > 0) { + // clean up of previously active options + this._options.toArray().forEach((option: MdOption) => { + option.setInactiveStyles(); + }); + // set the first one as active + this._options.toArray()[0].setActiveStyles(); + this._changeDetectorRef.markForCheck(); + } + }); + } + } + + /** + * Watches clicks outside of the component to remove the focus + * The autocomplete panel is considered inside the component so we + * need to use a flag to find out when its clicked. + */ + private _watchOutsideClick(): void { + if (this._document) { + this._outsideClickSubs = Observable.fromEvent(this._document, 'click').filter((event: MouseEvent) => { + const clickTarget: HTMLElement = event.target; + setTimeout(() => { + this._internalClick = false; + }); + return this.focused && + (clickTarget !== this._elementRef.nativeElement) && + !this._elementRef.nativeElement.contains(clickTarget) && !this._internalClick; + }).subscribe(() => { + if (this.focused) { + this.removeFocusedState(); + this.onTouched(); + this._changeDetectorRef.markForCheck(); + } + }); + } + return undefined; } } diff --git a/src/platform/core/chips/chips.module.ts b/src/platform/core/chips/chips.module.ts index 90bbb29763..5dad8aa629 100644 --- a/src/platform/core/chips/chips.module.ts +++ b/src/platform/core/chips/chips.module.ts @@ -5,8 +5,8 @@ import { CommonModule } from '@angular/common'; import { MdInputModule, MdIconModule, MdAutocompleteModule, MdChipsModule } from '@angular/material'; -import { TdChipsComponent } from './chips.component'; -export { TdChipsComponent } from './chips.component'; +import { TdChipsComponent, TdBasicChipDirective, TdAutocompleteOptionDirective } from './chips.component'; +export { TdChipsComponent, TdBasicChipDirective, TdAutocompleteOptionDirective } from './chips.component'; @NgModule({ imports: [ @@ -19,9 +19,13 @@ export { TdChipsComponent } from './chips.component'; ], declarations: [ TdChipsComponent, + TdBasicChipDirective, + TdAutocompleteOptionDirective, ], exports: [ TdChipsComponent, + TdBasicChipDirective, + TdAutocompleteOptionDirective, ], }) export class CovalentChipsModule { From 9ca5bdfda23f4f1ab23cef24669fdd6b24c2d807 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Tue, 30 May 2017 09:43:11 -0700 Subject: [PATCH 10/35] fix(chips): protect against case where click would close the autocomplete in certain cases (#641) when clicking near the bottom of the input, the focus would make the autocomplete render, but the click event would close it since its technically outside of it. we need to disable the focus listener when its via click user interaction --- src/platform/core/chips/chips.component.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index f7dd7898f4..ab65dfd6c5 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -49,6 +49,8 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, private _outsideClickSubs: Subscription; + private _isMousedown: boolean = false; + /** * Implemented as part of ControlValueAccessor. */ @@ -207,10 +209,25 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, */ @HostListener('focus', ['$event']) focusListener(event: FocusEvent): void { - this.focus(); + // should only focus if its not via mousedown to prevent clashing with autocomplete + if (!this._isMousedown) { + this.focus(); + } event.preventDefault(); } + /** + * Listens to host mousedown event to act on it + */ + @HostListener('mousedown', ['$event']) + mousedownListener(event: FocusEvent): void { + // sets a flag to know if there was a mousedown and then it returns it back to false + this._isMousedown = true; + Observable.timer().toPromise().then(() => { + this._isMousedown = false; + }); + } + /** * If clicking on :host or `td-chips-wrapper`, then we stop the click propagation so the autocomplete * doesnt close automatically. @@ -220,6 +237,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, const clickTarget: HTMLElement = event.target; if (clickTarget === this._elementRef.nativeElement || clickTarget.className.indexOf('td-chips-wrapper') > -1) { + this.focus(); event.preventDefault(); event.stopPropagation(); } From 5c2635c6548741442100b98724adcf607c6fb770 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Tue, 30 May 2017 09:59:34 -0700 Subject: [PATCH 11/35] feat(chips): add [color] input to change the color of focused chips, input and underline (closes #605) (#627) * feat(chips): add [color] input to change the color of focused chips, input and underline following the material spec we allow `primary`, `accent` and `warn` * chore(chips): update README and demo with color * chore(chips): added unit tests for color * update(docs): chips demo w/ icons --- .../components/chips/chips.component.html | 26 +++++--- src/platform/core/chips/README.md | 2 + src/platform/core/chips/_chips-theme.scss | 39 ++++++++++-- src/platform/core/chips/chips.component.html | 3 +- .../core/chips/chips.component.spec.ts | 62 +++++++++++++++++++ src/platform/core/chips/chips.component.ts | 27 +++++++- 6 files changed, 141 insertions(+), 18 deletions(-) diff --git a/src/app/components/components/chips/chips.component.html b/src/app/components/components/chips/chips.component.html index 457f657a9f..0a2518c56e 100644 --- a/src/app/components/components/chips/chips.component.html +++ b/src/app/components/components/chips/chips.component.html @@ -96,23 +96,26 @@ Chips & Autocomplete with objects - Autocomplete with chips and templates + Autocomplete with chips and templates and accent color Demo
Type and select a preset option or press enter:
- - {{chip.city}}, (Pop: {{chip.population}}) + location_city {{chip.city}}, (Pop: {{chip.population}}) - location_city {{option.city}} +
+ location_city {{option.city}} +
@@ -123,16 +126,19 @@

HTML:

- { {chip.city} }, (Pop: { {chip.population} }) + location_city { {chip.city} }, (Pop: { {chip.population} }) - location_city { {option.city} } +
+ location_city { {option.city} } +
]]> @@ -304,14 +310,14 @@ Custom chips - Demo allowing custom inputs for tags + Demo allowing custom inputs for tags and warn color Demo
Type any test and press enter:
- +
@@ -320,7 +326,7 @@

HTML:

+ ]]>

Typescript:

diff --git a/src/platform/core/chips/README.md b/src/platform/core/chips/README.md index e75c47cd6f..ba175e3f9e 100644 --- a/src/platform/core/chips/README.md +++ b/src/platform/core/chips/README.md @@ -10,6 +10,7 @@ Properties: | Name | Type | Description | | --- | --- | --- | +| `color?` | `'primary' | 'accent' | 'warn'` | color for the input and focus state of the chips. Defaults to 'primary' | `items?` | `any[]` | Renders the `md-autocomplete` with the provided list to display as options. | `requireMatch?` | `boolean` | Blocks custom inputs and only allows selections from the autocomplete list. | `placeholder?` | `string` | Placeholder for the autocomplete input. @@ -41,6 +42,7 @@ Example for HTML usage: ```html
@@ -20,7 +21,7 @@ + [color]="color"> { NoopAnimationsModule, ], declarations: [ + TdChipsTestComponent, TdChipsA11yTestComponent, TdChipsBasicTestComponent, TdChipsObjectsRequireMatchTestComponent, @@ -58,6 +59,52 @@ describe('Component: Chips', () => { TestBed.compileComponents(); })); + describe('should test general features: ', () => { + let fixture: ComponentFixture; + let input: DebugElement; + let chips: DebugElement; + + beforeEach(() => { + fixture = TestBed.createComponent(TdChipsTestComponent); + fixture.detectChanges(); + + chips = fixture.debugElement.query(By.directive(TdChipsComponent)); + input = chips.query(By.css('input')); + }); + + it('should have primary color', (done: DoneFn) => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.nativeElement).classList.contains('mat-primary')).toBeTruthy(); + done(); + }); + }); + + it('should set to accent color', (done: DoneFn) => { + fixture.componentInstance.color = 'accent'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.nativeElement).classList.contains('mat-accent')).toBeTruthy(); + done(); + }); + }); + + it('should set to warn color and then to accent', (done: DoneFn) => { + fixture.componentInstance.color = 'warn'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.nativeElement).classList.contains('mat-warn')).toBeTruthy(); + fixture.componentInstance.color = 'accent'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.nativeElement).classList.contains('mat-accent')).toBeTruthy(); + done(); + }); + }); + }); + + }); + describe('a11y keyboard in chips and input: ', () => { let fixture: ComponentFixture; let input: DebugElement; @@ -411,6 +458,21 @@ describe('Component: Chips', () => { }); +@Component({ + template: ` + + `, +}) +class TdChipsTestComponent { + color: string; + items: string[] = [ + 'steak', + 'pizza', + 'tacos', + ]; + selectedItems: string[] = this.items.slice(0, 2); +} + @Component({ template: ` diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index ab65dfd6c5..9c2c2dda67 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -1,11 +1,13 @@ import { Component, Input, Output, forwardRef, DoCheck, ViewChild, ViewChildren, QueryList, OnInit, HostListener, ElementRef, Optional, Inject, Directive, TemplateRef, ViewContainerRef, ContentChild, ChangeDetectionStrategy, - ChangeDetectorRef, AfterViewInit, OnDestroy, HostBinding } from '@angular/core'; + ChangeDetectorRef, AfterViewInit, OnDestroy, HostBinding, Renderer2 } from '@angular/core'; import { DOCUMENT } from '@angular/platform-browser'; import { EventEmitter } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor, FormControl } from '@angular/forms'; + import { MdChip, MdInputDirective, TemplatePortalDirective, MdOption, MdAutocompleteTrigger, UP_ARROW, DOWN_ARROW, ESCAPE, LEFT_ARROW, RIGHT_ARROW, DELETE, BACKSPACE, ENTER, SPACE, TAB, HOME } from '@angular/material'; + import { Observable } from 'rxjs/Observable'; import { Subscription } from 'rxjs/Subscription'; import 'rxjs/add/observable/timer'; @@ -60,6 +62,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, private _length: number = 0; private _requireMatch: boolean = false; private _readOnly: boolean = false; + private _color: 'primary' | 'accent' | 'warn' = 'primary'; private _chipAddition: boolean = true; private _focused: boolean = false; private _tabIndex: number = 0; @@ -160,6 +163,23 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, */ @Input('debounce') debounce: number = 200; + /** + * color?: 'primary' | 'accent' | 'warn' + * Sets the color for the input and focus/selected state of the chips. + * Defaults to 'primary' + */ + @Input('color') + set color(color: 'primary' | 'accent' | 'warn') { + if (color) { + this._renderer.removeClass(this._elementRef.nativeElement, 'mat-' + this._color); + this._color = color; + this._renderer.addClass(this._elementRef.nativeElement, 'mat-' + this._color); + } + } + get color(): 'primary' | 'accent' | 'warn' { + return this._color; + } + /** * add?: function * Method to be executed when a chip is added. @@ -201,8 +221,11 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, } constructor(private _elementRef: ElementRef, + private _renderer: Renderer2, private _changeDetectorRef: ChangeDetectorRef, - @Optional() @Inject(DOCUMENT) private _document: any) {} + @Optional() @Inject(DOCUMENT) private _document: any) { + this._renderer.addClass(this._elementRef.nativeElement, 'mat-' + this._color); + } /** * Listens to host focus event to act on it From e62d3bd68553be7cee188c0b761c68d11247f902 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Tue, 30 May 2017 10:57:12 -0700 Subject: [PATCH 12/35] chore(expansion-panel): updated docs with better examples (closes #475) (#642) * chore(expansion-panel): updated docs with better examples also created README.md and loaded it in docs + added code blocks in the examples * fix(expansion-panel): only render label and sublabel when its needed also if sublabel is not rendered, label will not shrink to 33% now --- .../expansion-panel.component.html | 430 ++++++++++-------- .../expansion-panel.component.ts | 61 --- src/platform/core/expansion-panel/README.md | 58 +++ .../expansion-panel.component.html | 4 +- 4 files changed, 289 insertions(+), 264 deletions(-) create mode 100644 src/platform/core/expansion-panel/README.md diff --git a/src/app/components/components/expansion-panel/expansion-panel.component.html b/src/app/components/components/expansion-panel/expansion-panel.component.html index 993a400654..25348b1f61 100644 --- a/src/app/components/components/expansion-panel/expansion-panel.component.html +++ b/src/app/components/components/expansion-panel/expansion-panel.component.html @@ -1,17 +1,91 @@ - Expansion Panels - Expand & collapse containers + Expansion panels + Use single or multiple expansion panels - -

Expand/Collapse Event for Expansion 1: {{expandCollapseExpansion1Msg}}

-
-
- + + + Demo + +
+

md-padding class

+
Demo 1
+
Demo 2
+
Demo 3
+
Demo 4
+
+
+ +
+

md-padding class

+
Demo 5
+
Demo 6
+
Demo 7
+
Demo 8
+
+
+
+ + Code + +

HTML:

+ + +
+

md-padding class

+
Demo 1
+
Demo 2
+
Demo 3
+
Demo 4
+
+
+ +
+

md-padding class

+
Demo 5
+
Demo 6
+
Demo 7
+
Demo 8
+
+
+ ]]> + +

Typescript:

+ + + + + + + + +
+ + Disabled + +
+
+ + + + Expansion panel with summary and templates + Expand to view form, collapse to view summary + + + + Demo + + + star + Google + + + 1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA + @@ -38,201 +112,155 @@

Headquarters

- -
-

md-padding class

-
Demo 1
-
Demo 2
-
Demo 3
-
Demo 4
-
-
- - - star - Custom Label (template) - - - list - Custom Sublabel (template) - -
-

md-padding class

-
Phase 1
-
Phase 2
-
Phase 3
-
-
-
-
-

The entire panel header can be replaced as well:

-
-
- - - - Custom td-expansion-panel-header - - - -
-
- Owner - chevron_right - John Jameson -
-
- API Key - chevron_right - 1141e8e8-8d24-4956-93c2 -
-
- Last Updated - chevron_right - Wed, July 6, 2016 11:13 AM -
-
-
- -

Metadata

- - account_box -

John Jameson

-

Owner

-
- - - description -

An item description

-

Description

-
- - - vpn_key -

1141e8e8-8d24-4956-93c2

-

API Key

-
- -

Dates

- - access_time -

Wed, July 6, 2016 11:13 AM

-

Last Updated

-
- - - today -

Wed, July 4, 2016 09:11 AM

-

Created

-
-
-
-
-
- - - - - - +
+ + Code + +

HTML:

+ + + + star + Google + + + 1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA + + + + + pin_drop +

Google

+

Headquarters

+

+ 1600 Amphitheatre Pkwy
Mountain View, CA 94043, USA +

+
+
+
+
+ + + + + + +
+ +
+ + +
+ + ]]> +
+
+
+
+ - TdExpansionPanelComponent - How to use this component + Expansion panel with header template + replace the entire header as needed - -

]]>

-

Use ]]> element to add expand/collapse feature to your html blocks

-

Place your html in ]]> element.

-

Behavior:

- - -

Collapsed panel

-

A collapsed panel displays summary information. Upon selecting the collapsed panel, it expands to display the full expansion panel.

-
- - -

Expanded panel

-

Upon selection, a collapsed panel expands, allowing users to add or edit information. Helper text may be added to the panel to assist the user.

-
-
-

Usage:

-

The ]]> component can be used two ways:

- - -

Editing

-

Expansion panels are best used for lightweight editing of an element, such as selecting a value for a setting.

-
- - -

Creation flows

-

Expansion panels may be displayed in a sequence to form creation flows.

-
-
-

Properties:

-

The ]]> component has {{expansionAttrs.length}} properties:

- - - -

{{attr.name}}: {{attr.type}}

-

{{attr.description}}

-
- -
-
-

Example:

-

HTML:

- - + + + Demo + - ... add header content (overrides label and sublabel) - - - ... add label content (if not used, falls back to [label] input) - - - ... add sublabel content (if not used, falls back to [sublabel] input) + + Custom td-expansion-panel-header + - ... add summary that will be shown when expansion-panel is "collapsed". +
+
+ Owner + chevron_right + John Jameson +
+
+ API Key + chevron_right + 1141e8e8-8d24-4956-93c2 +
+
- ... add content that will be shown when the step is "expanded" + +

Metadata

+ + account_box +

John Jameson

+

Owner

+
+ + + description +

An item description

+

Description

+
+ + + vpn_key +

1141e8e8-8d24-4956-93c2

+

API Key

+
+
- ]]> -
-

Typescript:

- - - -

Setup:

-

Import the [CovalentExpansionPanelModule] in your NgModule:

- - - -
-
+ + + Code + +

HTML:

+ + + + + Custom td-expansion-panel-header + + + +
+
+ Owner + chevron_right + John Jameson +
+
+ API Key + chevron_right + 1141e8e8-8d24-4956-93c2 +
+
+
+ +

Metadata

+ + account_box +

John Jameson

+

Owner

+
+ + + description +

An item description

+

Description

+
+ + + vpn_key +

1141e8e8-8d24-4956-93c2

+

API Key

+
+
+ + ]]> +
+
+
+ + + diff --git a/src/app/components/components/expansion-panel/expansion-panel.component.ts b/src/app/components/components/expansion-panel/expansion-panel.component.ts index 5719af48fe..3086977400 100644 --- a/src/app/components/components/expansion-panel/expansion-panel.component.ts +++ b/src/app/components/components/expansion-panel/expansion-panel.component.ts @@ -13,67 +13,6 @@ export class ExpansionPanelDemoComponent { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; - expansionAttrs: Object[] = [{ - description: 'Sets label of [TdExpansionPanelComponent] header. Defaults to "Click to expand"', - name: 'label?', - type: 'string', - }, { - description: 'Sets sublabel of [TdExpansionPanelComponent] header.', - name: 'sublabel?', - type: 'string', - }, { - description: 'Toggles [TdExpansionPanelComponent] between expand/collapse.', - name: 'expand?', - type: 'boolean', - }, { - description: `Hides icon and disables header, blocks click event and sets [TdExpansionPanelComponent] - to collapse if "true".`, - name: 'disabled?', - type: 'boolean', - }, { - description: 'Event emitted when [TdExpansionPanelComponent] is expanded.', - name: 'expanded?', - type: 'function()', - }, { - description: 'Event emitted when [TdExpansionPanelComponent] is collapsed.', - name: 'collapsed?', - type: 'function()', - }, { - description: `Toggle active state of [TdExpansionPanelComponent]. Retuns "true" if successful, else "false". - Can be accessed by referencing element in local variable.`, - name: 'toggle', - type: 'function()', - }, { - description: `Opens [TdExpansionPanelComponent]. Retuns "true" if successful, else "false". - Can be accessed by referencing element in local variable.`, - name: 'open', - type: 'function()', - }, { - description: `Closes [TdExpansionPanelComponent]. Retuns "true" if successful, else "false". - Can be accessed by referencing element in local variable.`, - name: 'close', - type: 'function()', - }]; - - expandCollapseExpansion1Msg: string = 'No expanded/collapsed detected yet'; - expansion1: boolean = false; disabled: boolean = false; - toggleExpansion1(): void { - if (!this.disabled) { - this.expansion1 = !this.expansion1; - } - } - - toggleDisabled(): void { - this.disabled = !this.disabled; - } - - expandExpansion1Event(): void { - this.expandCollapseExpansion1Msg = 'Expand event emitted.'; - } - - collapseExpansion1Event(): void { - this.expandCollapseExpansion1Msg = 'Collapse event emitted.'; - } } diff --git a/src/platform/core/expansion-panel/README.md b/src/platform/core/expansion-panel/README.md new file mode 100644 index 0000000000..c491b6ec4f --- /dev/null +++ b/src/platform/core/expansion-panel/README.md @@ -0,0 +1,58 @@ +# td-expansion-panel + +`td-expansion-panel` element adds expand/collapse features to your html blocks + +It also contains an optional summary to display anything in collapsed state. + +## API Summary + +Properties: + +| Name | Type | Description | +| --- | --- | --- | +| `label?` | `string` | Sets label of component header. +| `sublabel?` | `string` | Sets sublabel of component header. +| `expand?` | `boolean` | Toggles component between expand/collapse state. +| `expanded?` | `function` | Event emitted when component is expanded. +| `collapsed?` | `function` | Event emitted when component is collapsed. +| `toggle?` | `function` | Toggle state of component. Returns "true" if successful, else "false". +| `open?` | `function` | Opens component and sets state to expanded. Retuns "true" if successful, else "false". +| `close?` | `function` | Closes component and sets state to collapsed. Retuns "true" if successful, else "false". + +## Setup + +Import the [CovalentExpansionPanelModule] in your NgModule: + +```typescript +import { CovalentExpansionPanelModule } from '@covalent/core'; +@NgModule({ + imports: [ + CovalentExpansionPanelModule, + ... + ], + ... +}) +export class MyModule {} +``` + +## Usage + +Example for HTML usage: + +```html + + + ... add header content (overrides label and sublabel) + + + ... add label content (if not used, falls back to [label] input) + + + ... add sublabel content (if not used, falls back to [sublabel] input) + + + ... add summary that will be shown when expansion-panel is "collapsed". + + ... add content that + +``` diff --git a/src/platform/core/expansion-panel/expansion-panel.component.html b/src/platform/core/expansion-panel/expansion-panel.component.html index 4939e8b2fa..b3ee929ec7 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.html +++ b/src/platform/core/expansion-panel/expansion-panel.component.html @@ -14,11 +14,11 @@ layout="row" layout-align="start center" flex> -
+
{{label}}
-
+
{{sublabel}}
From 8e9ab29d170f91bc61a54cb07581e0631a576410 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Tue, 30 May 2017 12:26:22 -0700 Subject: [PATCH 13/35] chore(common): add common module setup in directives and pipe docs. (closes #634) (#643) * chore(): remove max/min validators since angular already has them there will be no breaking change since the selectors are the same * chore(common): add common module setup in directives and pipe docs * update(docs): pipes - add link to angular pipes --- .../directives/directives.component.html | 45 +++++++------------ .../components/pipes/pipes.component.html | 28 +++++++++++- src/platform/core/common/common.module.ts | 6 --- .../forms/validators/max/max.validator.ts | 28 ------------ .../forms/validators/min/min.validator.ts | 28 ------------ 5 files changed, 43 insertions(+), 92 deletions(-) delete mode 100644 src/platform/core/common/forms/validators/max/max.validator.ts delete mode 100644 src/platform/core/common/forms/validators/min/min.validator.ts diff --git a/src/app/components/components/directives/directives.component.html b/src/app/components/components/directives/directives.component.html index bf25f1a54b..ec3d52f7a8 100644 --- a/src/app/components/components/directives/directives.component.html +++ b/src/app/components/components/directives/directives.component.html @@ -6,6 +6,22 @@

A directive is essentially like a component functionally without a template. There are structural and attribute directives.

Structural directives can change the DOM layout by adding and removing DOM elements. NgFor and NgIf are two familiar examples.

An Attribute directive can change the appearance or behavior of an element. The built-in NgStyle directive, for example, can change several element styles at the same time.

+ +

Setup:

+

Import the [CovalentCommonModule] in your NgModule:

+ + + @@ -102,32 +118,3 @@ - - - Min/Max Validators - - -

We've added min/max validations since @angular doesnt support them at the moment.

-

Supported:

-
    -
  • TdMinValidator for selector: [min][formControlName],[min][formControl],[min][ngModel]
  • -
  • TdMaxValidator for selector: [max][formControlName],[max][formControl],[max][ngModel]
  • -
-

Example enter lower than 5 or higher than 10:

-
- - - -
-

Errors:

- {{el?.errors | json}} -

HTML:

- - - - - ]]> - -
-
diff --git a/src/app/components/components/pipes/pipes.component.html b/src/app/components/components/pipes/pipes.component.html index 484ffe05f1..01cf4550ab 100644 --- a/src/app/components/components/pipes/pipes.component.html +++ b/src/app/components/components/pipes/pipes.component.html @@ -7,6 +7,21 @@
A pipe takes in data as input and transforms it to a desired output.
+

Setup:

+

Import the [CovalentCommonModule] in your NgModule:

+ + + @@ -177,4 +192,15 @@

Original value: { { log.text_value } }

]]> - \ No newline at end of file + + + + Angular Pipes + + + + launch + Angular comes with a stock of pipes such as DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe, and PercentPipe + + + \ No newline at end of file diff --git a/src/platform/core/common/common.module.ts b/src/platform/core/common/common.module.ts index fafe581edf..2936622908 100644 --- a/src/platform/core/common/common.module.ts +++ b/src/platform/core/common/common.module.ts @@ -34,15 +34,9 @@ const TD_FORMS: Type[] = [ export { TdAutoTrimDirective }; // Validators -import { TdMinValidator } from './forms/validators/min/min.validator'; -import { TdMaxValidator } from './forms/validators/max/max.validator'; - const TD_VALIDATORS: Type[] = [ - TdMinValidator, - TdMaxValidator, ]; -export { TdMinValidator, TdMaxValidator }; export { CovalentValidators } from './forms/validators/validators'; /** diff --git a/src/platform/core/common/forms/validators/max/max.validator.ts b/src/platform/core/common/forms/validators/max/max.validator.ts deleted file mode 100644 index 76bdbbdb1a..0000000000 --- a/src/platform/core/common/forms/validators/max/max.validator.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Directive, Input, forwardRef } from '@angular/core'; -import { NG_VALIDATORS, Validator, Validators, AbstractControl, ValidatorFn } from '@angular/forms'; - -import { CovalentValidators } from '../validators'; - -export const MAX_VALIDATOR: any = { - provide: NG_VALIDATORS, - useExisting: forwardRef(() => TdMaxValidator), - multi: true, -}; - -@Directive({ - selector: '[max][formControlName],[max][formControl],[max][ngModel]', - providers: [ MAX_VALIDATOR ], -}) -export class TdMaxValidator implements Validator { - - private _validator: ValidatorFn; - - @Input('max') - set max(max: number) { - this._validator = CovalentValidators.max(max); - } - - validate(c: AbstractControl): {[key: string]: any} { - return this._validator(c); - } -} diff --git a/src/platform/core/common/forms/validators/min/min.validator.ts b/src/platform/core/common/forms/validators/min/min.validator.ts deleted file mode 100644 index 6fdd69fce0..0000000000 --- a/src/platform/core/common/forms/validators/min/min.validator.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Directive, Input, forwardRef } from '@angular/core'; -import { NG_VALIDATORS, Validator, Validators, AbstractControl, ValidatorFn } from '@angular/forms'; - -import { CovalentValidators } from '../validators'; - -export const MIN_VALIDATOR: any = { - provide: NG_VALIDATORS, - useExisting: forwardRef(() => TdMinValidator), - multi: true, -}; - -@Directive({ - selector: '[min][formControlName],[min][formControl],[min][ngModel]', - providers: [ MIN_VALIDATOR ], -}) -export class TdMinValidator implements Validator { - - private _validator: ValidatorFn; - - @Input('min') - set min(min: number) { - this._validator = CovalentValidators.min(min); - } - - validate(c: AbstractControl): {[key: string]: any} { - return this._validator(c); - } -} From 9542139ba7b8e84435b1cda47f875b927787a64a Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Tue, 30 May 2017 13:41:04 -0700 Subject: [PATCH 14/35] fix(stepper): horizontal scroll was not appearing when needed in certain cases. (closes #282) (#640) * fix(stepper): horizontal scroll was not appearing when needed in certain cases * fix(stepper): missing auto overflow for content * fix(): missing autocomplete module in components * fix(stepper): add cdkScrollable to have a hook for repositioning autocomplete, etc --- src/app/components/components/components.module.ts | 1 + src/platform/core/steps/step-body/step-body.component.html | 4 ++-- src/platform/core/steps/step-body/step-body.component.scss | 6 ++++++ src/platform/core/steps/steps.module.ts | 3 ++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/app/components/components/components.module.ts b/src/app/components/components/components.module.ts index 61d770f626..caad360e37 100644 --- a/src/app/components/components/components.module.ts +++ b/src/app/components/components/components.module.ts @@ -94,6 +94,7 @@ import { DocumentationToolsModule } from '../../documentation-tools'; MdTabsModule, MdTooltipModule, MdProgressBarModule, + MdAutocompleteModule, /** Covalent Modules */ CovalentCommonModule, CovalentLayoutModule, diff --git a/src/platform/core/steps/step-body/step-body.component.html b/src/platform/core/steps/step-body/step-body.component.html index e7c7b97f71..77e7306998 100644 --- a/src/platform/core/steps/step-body/step-body.component.html +++ b/src/platform/core/steps/step-body/step-body.component.html @@ -1,9 +1,9 @@
-
+
-
+
diff --git a/src/platform/core/steps/step-body/step-body.component.scss b/src/platform/core/steps/step-body/step-body.component.scss index e69de29bb2..8a8f7dcb3a 100644 --- a/src/platform/core/steps/step-body/step-body.component.scss +++ b/src/platform/core/steps/step-body/step-body.component.scss @@ -0,0 +1,6 @@ +.td-step-body { + overflow-x: hidden; + .td-step-content { + overflow-x: auto; + } +} \ No newline at end of file diff --git a/src/platform/core/steps/steps.module.ts b/src/platform/core/steps/steps.module.ts index b08d118908..ab03a8b95d 100644 --- a/src/platform/core/steps/steps.module.ts +++ b/src/platform/core/steps/steps.module.ts @@ -2,7 +2,7 @@ import { Type } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { MdIconModule, MdRippleModule, PortalModule } from '@angular/material'; +import { MdIconModule, MdRippleModule, PortalModule, ScrollDispatchModule } from '@angular/material'; import { CovalentCommonModule } from '../common/common.module'; @@ -32,6 +32,7 @@ export { TdStepsComponent, IStepChangeEvent, StepMode } from './steps.component' MdIconModule, MdRippleModule, PortalModule, + ScrollDispatchModule, CovalentCommonModule, ], declarations: [ From 9a18a6314853f35991868cd0260884fa4cc5b3a4 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Tue, 30 May 2017 13:47:37 -0700 Subject: [PATCH 15/35] feat(chips): new `[stacked]` input to make chips stack vertically. (#639) * feat(chips): new [stacked] input to make chips stack vertically. * fix(chips): set min height to have a space when no chips rendered * chore(chips): update unit tests with stacked input usage * fix(chips): blur focus when pressing `ESC` while input is focused also close and reopen autocomplete when item exists already * chore(chips): show stacked chips by default and add filtering to show a real example --- .../components/chips/chips.component.html | 32 +++++++-- .../components/chips/chips.component.ts | 14 ++++ src/platform/core/chips/README.md | 4 +- src/platform/core/chips/chips.component.html | 6 +- src/platform/core/chips/chips.component.scss | 6 ++ .../core/chips/chips.component.spec.ts | 49 ++++++++++++++ src/platform/core/chips/chips.component.ts | 67 ++++++++++++++----- 7 files changed, 152 insertions(+), 26 deletions(-) diff --git a/src/app/components/components/chips/chips.component.html b/src/app/components/components/chips/chips.component.html index 0a2518c56e..75aef8c874 100644 --- a/src/app/components/components/chips/chips.component.html +++ b/src/app/components/components/chips/chips.component.html @@ -262,15 +262,20 @@ - Autocomplete with custom inputs - Autocomplete demo allowing custom inputs + Stacked chips and Autocomplete with custom inputs + Autocomplete demo allowing custom inputs and stacked chips Demo
Type and select option or enter custom text and press enter:
- + +
@@ -279,7 +284,12 @@

HTML:

+ + ]]>

Typescript:

@@ -301,6 +311,20 @@ 'need more?', ]; + filteredStackedStrings: string[]; + + stackedStringsModel: string[] = this.strings.slice(0, 2); + + filterStackedStrings(value: string): void { + this.filteredStackedStrings = this.strings.filter((item: any) => { + if (value) { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + } else { + return false; + } + }); + } + } ]]> diff --git a/src/app/components/components/chips/chips.component.ts b/src/app/components/components/chips/chips.component.ts index 808d0488a4..8045f3c5a3 100644 --- a/src/app/components/components/chips/chips.component.ts +++ b/src/app/components/components/chips/chips.component.ts @@ -85,6 +85,10 @@ export class ChipsDemoComponent implements OnInit { asyncModel: string[] = this.strings.slice(0, 2); + filteredStackedStrings: string[]; + + stackedStringsModel: string[] = this.strings.slice(0, 2); + ngOnInit(): void { this.filterStrings(''); this.filterObjects(''); @@ -128,4 +132,14 @@ export class ChipsDemoComponent implements OnInit { }, 2000); } } + + filterStackedStrings(value: string): void { + this.filteredStackedStrings = this.strings.filter((item: any) => { + if (value) { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + } else { + return false; + } + }); + } } diff --git a/src/platform/core/chips/README.md b/src/platform/core/chips/README.md index ba175e3f9e..b9e21c26ae 100644 --- a/src/platform/core/chips/README.md +++ b/src/platform/core/chips/README.md @@ -13,6 +13,7 @@ Properties: | `color?` | `'primary' | 'accent' | 'warn'` | color for the input and focus state of the chips. Defaults to 'primary' | `items?` | `any[]` | Renders the `md-autocomplete` with the provided list to display as options. | `requireMatch?` | `boolean` | Blocks custom inputs and only allows selections from the autocomplete list. +| `stacked?` | `boolean` | Set stacked or horizontal chips depending on value. Defaults to false. | `placeholder?` | `string` | Placeholder for the autocomplete input. | `chipAddition` | `boolean` | Disables the ability to add chips. When setting readOnly as true, this will be overriden. Defaults to true. | `debounce` | `string` | Debounce timeout between keypresses. Defaults to 200. @@ -50,7 +51,8 @@ Example for HTML usage: (add)="addEvent($event)" (remove)="removeEvent($event)" (inputChange)="inputChange($event)" - requireMatch> + requireMatch + stacked> {{chip}} diff --git a/src/platform/core/chips/chips.component.html b/src/platform/core/chips/chips.component.html index 23e5d82907..58a0624234 100644 --- a/src/platform/core/chips/chips.component.html +++ b/src/platform/core/chips/chips.component.html @@ -1,11 +1,11 @@ -
+
-
+
{{chip}} { TdChipsA11yTestComponent, TdChipsBasicTestComponent, TdChipsObjectsRequireMatchTestComponent, + TdChipsStackedTestComponent, ], providers: [ {provide: OverlayContainer, useFactory: () => { @@ -440,6 +441,35 @@ describe('Component: Chips', () => { }); + describe('stacked usage: ', () => { + let fixture: ComponentFixture; + let input: DebugElement; + let chips: DebugElement; + + beforeEach(() => { + fixture = TestBed.createComponent(TdChipsStackedTestComponent); + fixture.detectChanges(); + + chips = fixture.debugElement.query(By.directive(TdChipsComponent)); + }); + + it('should rendered chips stacked', (done: DoneFn) => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.query(By.css('.td-chips-wrapper')).nativeElement).classList.contains('td-chips-stacked')) + .toBeFalsy(); + fixture.componentInstance.stacked = true; + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.query(By.css('.td-chips-wrapper')).nativeElement).classList.contains('td-chips-stacked')) + .toBeTruthy(); + done(); + }); + }); + }); + + }); + // TODO // more requireMatch usage @@ -534,3 +564,22 @@ class TdChipsObjectsRequireMatchTestComponent { selectedObjects: any[] = []; objects: any[]; } + +@Component({ + template: ` + + `, +}) +class TdChipsStackedTestComponent { + stacked: boolean = false; + items: string[] = [ + 'steak', + 'pizza', + 'tacos', + 'sandwich', + 'chips', + 'pasta', + 'sushi', + ]; + selectedItems: string[] = this.items.slice(0, 3); +} diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index 9c2c2dda67..9ff88ed0cc 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -60,6 +60,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, private _items: any[]; private _length: number = 0; + private _stacked: boolean = false; private _requireMatch: boolean = false; private _readOnly: boolean = false; private _color: 'primary' | 'accent' | 'warn' = 'primary'; @@ -69,6 +70,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, _internalClick: boolean = false; + @ViewChild('input') _nativeInput: ElementRef; @ViewChild(MdInputDirective) _inputChild: MdInputDirective; @ViewChild(MdAutocompleteTrigger) _autocompleteTrigger: MdAutocompleteTrigger; @ViewChildren(MdChip) _chipsChildren: QueryList; @@ -103,6 +105,19 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, get items(): any[] { return this._items; } + + /** + * stacked?: boolean + * Set stacked or horizontal chips depending on value. + * Defaults to false. + */ + @Input('stacked') + set stacked(stacked: any) { + this._stacked = stacked !== '' ? (stacked === 'true' || stacked === true) : true; + } + get stacked(): any { + return this._stacked; + } /** * requireMatch?: boolean @@ -279,8 +294,13 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, }); break; case ESCAPE: - case HOME: - this.focus(); + if (this._inputChild.focused) { + this._nativeInput.nativeElement.blur(); + this.removeFocusedState(); + this._closeAutocomplete(); + } else { + this.focus(); + } break; default: // default @@ -356,15 +376,6 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, * returns 'true' if successful, 'false' if it fails. */ addChip(value: any): boolean { - this.inputControl.setValue(''); - // check if value is already part of the model - if (this._value.indexOf(value) > -1) { - return false; - } - this._value.push(value); - this.onAdd.emit(value); - this.onChange(this._value); - this._changeDetectorRef.markForCheck(); /** * add a 200 ms delay when reopening the autocomplete to give it time * to rerender the next list and at the correct spot @@ -375,6 +386,17 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, this._setFirstOptionActive(); this._openAutocomplete(); }); + + this.inputControl.setValue(''); + // check if value is already part of the model + if (this._value.indexOf(value) > -1) { + return false; + } + + this._value.push(value); + this.onAdd.emit(value); + this.onChange(this._value); + this._changeDetectorRef.markForCheck(); return true; } @@ -459,6 +481,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, let length: number = this._options.length; if (length > 0 && this._options.toArray()[0].active) { this._options.toArray()[0].setInactiveStyles(); + // prevent default window scrolling event.preventDefault(); } } @@ -470,6 +493,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, /** Check to see if input is empty when pressing left arrow to move to the last chip */ if (!this._inputChild.value) { this._focusLastChip(); + // prevent default window scrolling event.preventDefault(); } break; @@ -478,6 +502,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, /** Check to see if input is empty when pressing right arrow to move to the first chip */ if (!this._inputChild.value) { this._focusFirstChip(); + // prevent default window scrolling event.preventDefault(); } break; @@ -498,13 +523,15 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, this.removeChip(index); } break; + case UP_ARROW: case LEFT_ARROW: /** - * Check to see if left arrow was pressed while focusing the first chip to focus input next + * Check to see if left/down arrow was pressed while focusing the first chip to focus input next * Also check if input should be focused */ if (index === 0) { - if (this.canAddChip) { + // only try to target input if pressing left + if (this.canAddChip && event.keyCode === LEFT_ARROW) { this._inputChild.focus(); } else { this._focusLastChip(); @@ -512,15 +539,18 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, } else if (index > 0) { this._focusChip(index - 1); } - event.stopPropagation(); + // prevent default window scrolling + event.preventDefault(); break; + case DOWN_ARROW: case RIGHT_ARROW: /** - * Check to see if right arrow was pressed while focusing the last chip to focus input next + * Check to see if right/up arrow was pressed while focusing the last chip to focus input next * Also check if input should be focused */ if (index === (this._totalChips - 1)) { - if (this.canAddChip) { + // only try to target input if pressing right + if (this.canAddChip && event.keyCode === RIGHT_ARROW) { this._inputChild.focus(); } else { this._focusFirstChip(); @@ -528,7 +558,8 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, } else if (index < (this._totalChips - 1)) { this._focusChip(index + 1); } - event.stopPropagation(); + // prevent default window scrolling + event.preventDefault(); break; default: // default @@ -583,7 +614,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, /** * Get total of chips */ - private get _totalChips(): number { + get _totalChips(): number { let chips: MdChip[] = this._chipsChildren.toArray(); return chips.length; } From 363bf24db344963043fa2b86df72067f8d6222e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Toledo=20Navarro?= Date: Wed, 31 May 2017 02:14:49 +0200 Subject: [PATCH 16/35] fixed(docs): missing properties on data table documentation (#646) * Added missing selectedRows property on the component description. Closes #441 --- .../components/components/data-table/data-table.component.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/components/components/data-table/data-table.component.html b/src/app/components/components/data-table/data-table.component.html index 3ec7495b68..0661024791 100644 --- a/src/app/components/components/data-table/data-table.component.html +++ b/src/app/components/components/data-table/data-table.component.html @@ -267,6 +267,7 @@

No results to display.

[multiple]="multiple" [sortable]="true" [sortBy]="sortBy" + [(ngModel)]="selectedRows" [sortOrder]="sortOrder" (sortChange)="sort($event)"> @@ -305,6 +306,7 @@

No results to display.

currentPage: number = 1; pageSize: number = 5; sortBy: string = 'sku'; + selectedRows: any[] = []; sortOrder: TdDataTableSortingOrder = TdDataTableSortingOrder.Descending; constructor(private _dataTableService: TdDataTableService) {} From 51ba94db1b7adef51a67407fc9db8504678a9af8 Mon Sep 17 00:00:00 2001 From: JoshSchoen Date: Wed, 31 May 2017 11:13:48 -0500 Subject: [PATCH 17/35] feat(chips): ability to disable chip removal (input) (#615) * added chipRemoval feature * updated chip removal label * added chipRemoval to code preview in demo * added chipRemoval to code preview in demo * fixed linting * fixed linting * added unit tests for chip removal, updated readme and remove chipAttrs from app demo --- .../components/chips/chips.component.html | 9 + .../components/chips/chips.component.ts | 34 +-- src/platform/core/chips/README.md | 2 + src/platform/core/chips/chips.component.html | 4 +- .../core/chips/chips.component.spec.ts | 215 +++++++++++++++++- src/platform/core/chips/chips.component.ts | 22 +- 6 files changed, 249 insertions(+), 37 deletions(-) diff --git a/src/app/components/components/chips/chips.component.html b/src/app/components/components/chips/chips.component.html index 75aef8c874..08bcb88163 100644 --- a/src/app/components/components/chips/chips.component.html +++ b/src/app/components/components/chips/chips.component.html @@ -8,6 +8,7 @@
Type and select a preset option or press enter:
+ +
+ + Chip removal + +
diff --git a/src/app/components/components/chips/chips.component.ts b/src/app/components/components/chips/chips.component.ts index 8045f3c5a3..4dc3a25f10 100644 --- a/src/app/components/components/chips/chips.component.ts +++ b/src/app/components/components/chips/chips.component.ts @@ -13,41 +13,9 @@ export class ChipsDemoComponent implements OnInit { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; - chipsAttrs: Object[] = [{ - description: `Enables Autocompletion with the provided list of strings.`, - name: 'items?', - type: 'string[]', - }, { - description: `Disables the chip input and removal.`, - name: 'readOnly?', - type: 'boolean', - }, { - description: `Validates input against the provided search list before adding it to the model. - If it doesnt exist, it cancels the event.`, - name: 'requireMatch?', - type: 'boolean', - }, { - description: `Placeholder for the autocomplete input.`, - name: 'placeholder?', - type: 'string', - }, { - description: `Method to be executed when string is added as chip through the autocomplete. - Sends chip value as event.`, - name: 'add?', - type: 'function', - }, { - description: `Method to be executed when string is removed as chip with the "remove" button. - Sends chip value as event.`, - name: 'remove?', - type: 'function', - }, { - description: `Disables the ability to add chips. If it doesn't exist chipAddition defaults to true.`, - name: 'chipAddition?', - type: 'boolean', - }]; - readOnly: boolean = false; chipAddition: boolean = true; + chipRemoval: boolean = true; filteringAsync: boolean = false; diff --git a/src/platform/core/chips/README.md b/src/platform/core/chips/README.md index b9e21c26ae..1820bde75b 100644 --- a/src/platform/core/chips/README.md +++ b/src/platform/core/chips/README.md @@ -16,6 +16,7 @@ Properties: | `stacked?` | `boolean` | Set stacked or horizontal chips depending on value. Defaults to false. | `placeholder?` | `string` | Placeholder for the autocomplete input. | `chipAddition` | `boolean` | Disables the ability to add chips. When setting readOnly as true, this will be overriden. Defaults to true. +| `chipRemoval` | `boolean` | Disables the ability to remove chips. If it doesn't exist chipRemoval defaults to true. readyOnly must be false for this option to work. | `debounce` | `string` | Debounce timeout between keypresses. Defaults to 200. | `add?` | `function` | Method to be executed when a chip is added. Sends chip value as event. | `remove?` | `function` | Method to be executed when a chip is removed. Sends chip value as event. @@ -48,6 +49,7 @@ Example for HTML usage: [(ngModel)]="model" [readOnly]="readOnly" [chipAddition]="chipAddition" + [chipRemoval]="chipRemoval" (add)="addEvent($event)" (remove)="removeEvent($event)" (inputChange)="inputChange($event)" diff --git a/src/platform/core/chips/chips.component.html b/src/platform/core/chips/chips.component.html index 58a0624234..2a6b3ac7d9 100644 --- a/src/platform/core/chips/chips.component.html +++ b/src/platform/core/chips/chips.component.html @@ -1,6 +1,6 @@
- @@ -13,7 +13,7 @@ [ngOutletContext]="{ chip: chip }">
- + cancel
diff --git a/src/platform/core/chips/chips.component.spec.ts b/src/platform/core/chips/chips.component.spec.ts index a13c2a5b36..9a93681809 100644 --- a/src/platform/core/chips/chips.component.spec.ts +++ b/src/platform/core/chips/chips.component.spec.ts @@ -8,7 +8,7 @@ import { Component, DebugElement } from '@angular/core'; import { FormControl, FormsModule, ReactiveFormsModule, } from '@angular/forms'; -import { OverlayContainer, MdInputDirective, MdChip, BACKSPACE, ENTER, LEFT_ARROW, RIGHT_ARROW } from '@angular/material'; +import { OverlayContainer, MdInputDirective, MdChip, DELETE, BACKSPACE, ENTER, LEFT_ARROW, RIGHT_ARROW } from '@angular/material'; import { By } from '@angular/platform-browser'; import { CovalentChipsModule, TdChipsComponent } from './chips.module'; @@ -41,6 +41,7 @@ describe('Component: Chips', () => { TdChipsBasicTestComponent, TdChipsObjectsRequireMatchTestComponent, TdChipsStackedTestComponent, + TdChipRemovalTestComponent, ], providers: [ {provide: OverlayContainer, useFactory: () => { @@ -470,6 +471,197 @@ describe('Component: Chips', () => { }); + describe('chip removal usage, requires readOnly to be false: ', () => { + let fixture: ComponentFixture; + let input: DebugElement; + let chips: DebugElement; + + beforeEach(() => { + fixture = TestBed.createComponent(TdChipRemovalTestComponent); + fixture.detectChanges(); + + chips = fixture.debugElement.query(By.directive(TdChipsComponent)); + input = chips.query(By.css('input')); + }); + + it('should not focus input', (done: DoneFn) => { + fixture.componentInstance.chipRemoval = true; + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.componentInstance)._inputChild.focused).toBeFalsy(); + done(); + }); + }); + }); + + it('should not show cancel button', (done: DoneFn) => { + fixture.componentInstance.chipRemoval = false; + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.css('.td-chip-removal')).length).toBe(0); + done(); + }); + }); + }); + + it('should focus input, then focus first chip and remove first chip by clicking on the remove button', (done: DoneFn) => { + fixture.componentInstance.chipRemoval = true; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((chips.componentInstance)._inputChild.focused).toBeTruthy(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(3); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(3); + fixture.debugElement.queryAll(By.css('.td-chip-removal'))[0] + .triggerEventHandler('click', new Event('click')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(2); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(2); + done(); + }); + }); + }); + }); + }); + + it('should focus first chip and remove chip with backspace and delete', (done: DoneFn) => { + fixture.componentInstance.chipRemoval = true; + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.debugElement.queryAll(By.directive(MdChip))[0] + .triggerEventHandler('keydown', createFakeKeyboardEvent(BACKSPACE)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(2); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(2); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(2); + fixture.debugElement.queryAll(By.directive(MdChip))[0] + .triggerEventHandler('keydown', createFakeKeyboardEvent(DELETE)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(chips.componentInstance.value.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(MdChip)).length).toBe(1); + done(); + }); + }); + }); + }); + }); + }); + }); + }); + + it('should focus around the chips going left', (done: DoneFn) => { + fixture.componentInstance.chipRemoval = true; + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[0] + .triggerEventHandler('keydown', createFakeKeyboardEvent(LEFT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[2].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[2] + .triggerEventHandler('keydown', createFakeKeyboardEvent(LEFT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[1].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[1] + .triggerEventHandler('keydown', createFakeKeyboardEvent(LEFT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + done(); + }); + }); + }); + }); + }); + }); + }); + + it('should focus around the chips going right', (done: DoneFn) => { + fixture.componentInstance.chipRemoval = true; + fixture.componentInstance.chipAddition = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.nativeElement.focus(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + chips.triggerEventHandler('focus', new Event('focus')); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[0] + .triggerEventHandler('keydown', createFakeKeyboardEvent(RIGHT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[1].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[1] + .triggerEventHandler('keydown', createFakeKeyboardEvent(RIGHT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[2].nativeElement) + .toBe(document.activeElement); + fixture.debugElement.queryAll(By.directive(MdChip))[2] + .triggerEventHandler('keydown', createFakeKeyboardEvent(RIGHT_ARROW)); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.queryAll(By.directive(MdChip))[0].nativeElement) + .toBe(document.activeElement); + done(); + }); + }); + }); + }); + }); + }); + }); + + }); + // TODO // more requireMatch usage @@ -583,3 +775,24 @@ class TdChipsStackedTestComponent { ]; selectedItems: string[] = this.items.slice(0, 3); } + +@Component({ + template: ` + + `, +}) +class TdChipRemovalTestComponent { + chipRemoval: boolean = true; + chipAddition: boolean = true; + items: string[] = [ + 'steak', + 'pizza', + 'tacos', + 'sandwich', + 'chips', + 'pasta', + 'sushi', + ]; + selectedItems: string[] = this.items.slice(0, 3); +} diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index 9ff88ed0cc..272a434788 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -65,6 +65,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, private _readOnly: boolean = false; private _color: 'primary' | 'accent' | 'warn' = 'primary'; private _chipAddition: boolean = true; + private _chipRemoval: boolean = true; private _focused: boolean = false; private _tabIndex: number = 0; @@ -166,6 +167,19 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, return this.chipAddition && !this.readOnly; } + /** + * chipRemoval?: boolean + * Disables the ability to remove chips. If it doesn't exist chip remmoval defaults to true. + * When setting readOnly as true, this will be overriden to false. + */ + @Input('chipRemoval') + set chipRemoval(chipRemoval: boolean) { + this._chipRemoval = chipRemoval; + } + get chipRemoval(): boolean { + return this._chipRemoval; + } + /** * placeholder?: string * Placeholder for the autocomplete input. @@ -520,7 +534,13 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, case BACKSPACE: /** Check to see if not in [readOnly] state to delete a chip */ if (!this.readOnly) { - this.removeChip(index); + /** + * Checks [chipRemoval] state to delete a chips + * To enable [chipRemoval] the [readOnly] state must be true. + */ + if (this.chipRemoval) { + this.removeChip(index); + } } break; case UP_ARROW: From bdb0e08fc98f4a8eef7c099014b3112c802da517 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 31 May 2017 21:16:57 -0700 Subject: [PATCH 18/35] fix(chips): using debounce as output instead of input in demo (#647) * fix(chips): using debounce as output instead of input in demo * Updating demo code to explain use of timeout in chips * chore(chips): add single source of truth for removal state `canRemoveChip` flag * chore(): add code block for canRemoveChip flag * fix(): fix padding issue with not removal state in chips --- .../components/chips/chips.component.html | 5 ++-- .../components/chips/chips.component.ts | 1 + src/platform/core/chips/README.md | 2 +- src/platform/core/chips/chips.component.html | 5 ++-- src/platform/core/chips/chips.component.scss | 2 +- src/platform/core/chips/chips.component.ts | 24 ++++++++++--------- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/app/components/components/chips/chips.component.html b/src/app/components/components/chips/chips.component.html index 08bcb88163..a9b047f1df 100644 --- a/src/app/components/components/chips/chips.component.html +++ b/src/app/components/components/chips/chips.component.html @@ -200,10 +200,10 @@
Type and see how it will load items async:
@@ -216,10 +216,10 @@ @@ -253,6 +253,7 @@ this.filteredAsync = undefined; if (value) { this.filteringAsync = true; + // Timeout isn't actually needed here, only added for demo to simulate async behavior setTimeout(() => { this.filteredAsync = this.strings.filter((item: any) => { return item.toLowerCase().indexOf(value.toLowerCase()) > -1; diff --git a/src/app/components/components/chips/chips.component.ts b/src/app/components/components/chips/chips.component.ts index 4dc3a25f10..fe9da73ea2 100644 --- a/src/app/components/components/chips/chips.component.ts +++ b/src/app/components/components/chips/chips.component.ts @@ -90,6 +90,7 @@ export class ChipsDemoComponent implements OnInit { this.filteredAsync = undefined; if (value) { this.filteringAsync = true; + // Timeout isn't actually needed here, only added for demo to simulate async behavior setTimeout(() => { this.filteredAsync = this.strings.filter((item: any) => { return item.toLowerCase().indexOf(value.toLowerCase()) > -1; diff --git a/src/platform/core/chips/README.md b/src/platform/core/chips/README.md index 1820bde75b..4a53ecf9b2 100644 --- a/src/platform/core/chips/README.md +++ b/src/platform/core/chips/README.md @@ -16,7 +16,7 @@ Properties: | `stacked?` | `boolean` | Set stacked or horizontal chips depending on value. Defaults to false. | `placeholder?` | `string` | Placeholder for the autocomplete input. | `chipAddition` | `boolean` | Disables the ability to add chips. When setting readOnly as true, this will be overriden. Defaults to true. -| `chipRemoval` | `boolean` | Disables the ability to remove chips. If it doesn't exist chipRemoval defaults to true. readyOnly must be false for this option to work. +| `chipRemoval` | `boolean` | Disables the ability to remove chips. When setting readOnly as true, this will be overriden. Defaults to true. | `debounce` | `string` | Debounce timeout between keypresses. Defaults to 200. | `add?` | `function` | Method to be executed when a chip is added. Sends chip value as event. | `remove?` | `function` | Method to be executed when a chip is removed. Sends chip value as event. diff --git a/src/platform/core/chips/chips.component.html b/src/platform/core/chips/chips.component.html index 2a6b3ac7d9..901f2af191 100644 --- a/src/platform/core/chips/chips.component.html +++ b/src/platform/core/chips/chips.component.html @@ -1,6 +1,7 @@
- @@ -13,7 +14,7 @@ [ngOutletContext]="{ chip: chip }">
- + cancel
diff --git a/src/platform/core/chips/chips.component.scss b/src/platform/core/chips/chips.component.scss index 6e1234b7a1..1731442220 100644 --- a/src/platform/core/chips/chips.component.scss +++ b/src/platform/core/chips/chips.component.scss @@ -33,7 +33,7 @@ box-sizing: border-box; max-width: 100%; position: relative; - &.td-chip-disabled { + &.td-chip-after-pad { @include rtl(padding, 0 12px 0 0, 0 0 0 12px); } md-icon.td-chip-removal { diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index 272a434788..f4ee383fb0 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -180,6 +180,14 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, return this._chipRemoval; } + /** + * Checks if not in readOnly state and if chipRemoval is set to 'true' + * States if a chip can be removed + */ + get canRemoveChip(): boolean { + return this.chipRemoval && !this.readOnly; + } + /** * placeholder?: string * Placeholder for the autocomplete input. @@ -391,11 +399,11 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, */ addChip(value: any): boolean { /** - * add a 200 ms delay when reopening the autocomplete to give it time + * add a debounce ms delay when reopening the autocomplete to give it time * to rerender the next list and at the correct spot */ this._closeAutocomplete(); - Observable.timer(200).toPromise().then(() => { + Observable.timer(this.debounce).toPromise().then(() => { this.setFocusedState(); this._setFirstOptionActive(); this._openAutocomplete(); @@ -532,15 +540,9 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, switch (event.keyCode) { case DELETE: case BACKSPACE: - /** Check to see if not in [readOnly] state to delete a chip */ - if (!this.readOnly) { - /** - * Checks [chipRemoval] state to delete a chips - * To enable [chipRemoval] the [readOnly] state must be true. - */ - if (this.chipRemoval) { - this.removeChip(index); - } + /** Check to see if we can delete a chip */ + if (this.canRemoveChip) { + this.removeChip(index); } break; case UP_ARROW: From 615a4ee02976f4d0ffa0f0394c562cbdcdce5a25 Mon Sep 17 00:00:00 2001 From: Kyle Ledbetter Date: Thu, 1 Jun 2017 21:46:11 -0700 Subject: [PATCH 19/35] feature(docs): new landing page & theme (#645) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feature(home): new landing page, theme & toolbar component * update(theme): custom orange contrast * update(): responsive improvements * update(index): dark bg color * update(theme): tab-like toolbar nav * update(app): remove drawer from auto opening * update(routes): ordering to match others * update(app): import toolbar * update(components): move … LTR/RTL menu * update(home): layout overhaul * update(components): darker colors * update(toolbar): active routerlinks * update(components): remove unused columns * feature(templates): add templates page * feature(LTR): LTR/RTL switch in toolbar for entire docs * update(templates): grid-list of images w/ links * feat(firebase): load templates from firebase database and storage * chore(): remove template imgs since they arent needed anymore * fix(): separate home link so its active only when exact * fix(templates): make template rows be responsive * update(): responsive improvements * update(): import tooltips for templates page * update(theme): add alt-theme to match prev doc content --- src/app/app.component.html | 22 +- src/app/app.component.ts | 30 +- src/app/app.module.ts | 19 +- src/app/app.routes.ts | 4 + src/app/assets/ico/favicon.ico | Bin 32988 -> 15086 bytes src/app/assets/icons/angular-outline.svg | 13 + src/app/assets/icons/angular.svg | 16 + src/app/assets/icons/covalent-outline.svg | 12 + src/app/assets/icons/covalent-stroke.svg | 14 + src/app/assets/icons/covalent.svg | 7 +- src/app/assets/icons/material-outline.svg | 18 + src/app/assets/icons/material.svg | 1 + .../components/components.component.html | 25 +- .../components/components.component.ts | 11 +- .../components/components.module.ts | 3 + .../overview/overview.component.html | 8 +- .../components/overview/overview.component.ts | 44 +- src/app/components/docs/docs.component.html | 11 +- src/app/components/docs/docs.module.ts | 7 +- src/app/components/home/home.component.html | 535 ++++++++++-------- src/app/components/home/home.component.scss | 21 +- src/app/components/home/home.component.ts | 113 ++-- .../card-over/card-over.component.html | 1 + src/app/components/layouts/layouts.module.ts | 3 + .../manage-list/manage-list.component.html | 5 +- .../layouts/nav-list/nav-list.component.html | 7 +- .../layouts/nav-view/nav-view.component.html | 1 + .../layouts/overview/overview.component.html | 1 + .../style-guide/style-guide.component.html | 9 +- .../style-guide/style-guide.module.ts | 3 + .../templates/templates.component.html | 29 + .../templates/templates.component.scss | 10 + .../templates/templates.component.ts | 32 ++ .../components/toolbar/toolbar.component.html | 51 ++ .../components/toolbar/toolbar.component.scss | 8 + .../components/toolbar/toolbar.component.ts | 80 +++ src/app/components/toolbar/toolbar.module.ts | 31 + src/app/services/index.ts | 1 + src/app/services/internal-docs.service.ts | 44 ++ src/favicon.ico | Bin 32988 -> 15086 bytes src/index.html | 2 +- src/theme.scss | 87 ++- 42 files changed, 937 insertions(+), 402 deletions(-) create mode 100644 src/app/assets/icons/angular-outline.svg create mode 100644 src/app/assets/icons/angular.svg create mode 100644 src/app/assets/icons/covalent-outline.svg create mode 100644 src/app/assets/icons/covalent-stroke.svg create mode 100644 src/app/assets/icons/material-outline.svg create mode 100644 src/app/assets/icons/material.svg create mode 100644 src/app/components/templates/templates.component.html create mode 100644 src/app/components/templates/templates.component.scss create mode 100644 src/app/components/templates/templates.component.ts create mode 100644 src/app/components/toolbar/toolbar.component.html create mode 100644 src/app/components/toolbar/toolbar.component.scss create mode 100644 src/app/components/toolbar/toolbar.component.ts create mode 100644 src/app/components/toolbar/toolbar.module.ts create mode 100644 src/app/services/internal-docs.service.ts diff --git a/src/app/app.component.html b/src/app/app.component.html index 6200aafa81..bf30e56acd 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,10 +1,24 @@ - - - {{item.icon}}{{item.title}} + + + + home + Home + + + {{item.icon}} + {{item.title}} + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index be03bf9864..7d9e52cf30 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -14,25 +14,25 @@ import { getSelectedLanguage } from './utilities/translate'; export class DocsAppComponent implements AfterViewInit { routes: Object[] = [{ - icon: 'home', - route: '.', - title: 'Home', - }, { icon: 'library_books', route: 'docs', title: 'Documentation', }, { - icon: 'color_lens', - route: 'style-guide', - title: 'Style Guide', + icon: 'picture_in_picture', + route: 'components', + title: 'Components & Addons', }, { icon: 'view_quilt', route: 'layouts', title: 'Layouts', }, { - icon: 'picture_in_picture', - route: 'components', - title: 'Components & Addons', + icon: 'color_lens', + route: 'style-guide', + title: 'Style Guide', + }, { + icon: 'view_carousel', + route: 'templates', + title: 'Templates', }, ]; @@ -56,6 +56,16 @@ export class DocsAppComponent implements AfterViewInit { this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/github.svg')); this._iconRegistry.addSvgIconInNamespace('assets', 'covalent', this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/covalent.svg')); + this._iconRegistry.addSvgIconInNamespace('assets', 'covalent-stroke', + this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/covalent-stroke.svg')); + this._iconRegistry.addSvgIconInNamespace('assets', 'covalent-outline', + this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/covalent-outline.svg')); + this._iconRegistry.addSvgIconInNamespace('assets', 'angular', + this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/angular.svg')); + this._iconRegistry.addSvgIconInNamespace('assets', 'angular-outline', + this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/angular-outline.svg')); + this._iconRegistry.addSvgIconInNamespace('assets', 'material-outline', + this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/material-outline.svg')); this._iconRegistry.addSvgIconInNamespace('assets', 'teradata-ux', this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/teradata-ux.svg')); this._iconRegistry.addSvgIconInNamespace('assets', 'appcenter', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c299d22a71..d2c76bc991 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -8,9 +8,11 @@ import { TranslateModule, TranslateService, TranslateLoader } from '@ngx-transla import { DocsAppComponent } from './app.component'; import { HomeComponent } from './components/home/home.component'; +import { TemplatesComponent } from './components/templates/templates.component'; import { appRoutes, appRoutingProviders } from './app.routes'; -import { MdButtonModule, MdListModule, MdIconModule, MdCardModule, MdCoreModule, MdMenuModule } from '@angular/material'; +import { MdButtonModule, MdListModule, MdIconModule, MdCardModule, MdCoreModule, MdMenuModule, MdTabsModule, + MdToolbarModule, MdGridListModule, MdTooltipModule } from '@angular/material'; import { CovalentLayoutModule, CovalentExpansionPanelModule, CovalentNotificationsModule, CovalentMenuModule, CovalentMediaModule } from '../platform/core'; @@ -19,13 +21,16 @@ import { CovalentHttpModule } from '../platform/http'; import { CovalentMarkdownModule } from '../platform/markdown'; import { CovalentDynamicFormsModule } from '../platform/dynamic-forms'; -import { GitHubService } from './services'; +import { ToolbarModule } from './components/toolbar/toolbar.module'; + +import { GitHubService, InternalDocsService } from './services'; import { getSelectedLanguage, createTranslateLoader } from './utilities/translate'; @NgModule({ declarations: [ DocsAppComponent, HomeComponent, + TemplatesComponent, ], // directives, components, and pipes owned by this NgModule imports: [ BrowserAnimationsModule, @@ -41,16 +46,21 @@ import { getSelectedLanguage, createTranslateLoader } from './utilities/translat MdIconModule, MdCardModule, MdMenuModule, + MdTabsModule, + MdToolbarModule, + MdGridListModule, + MdTooltipModule, /** Covalent Modules */ CovalentLayoutModule, CovalentExpansionPanelModule, CovalentNotificationsModule, CovalentMenuModule, + CovalentMediaModule, CovalentHttpModule.forRoot(), CovalentHighlightModule, CovalentMarkdownModule, CovalentDynamicFormsModule, - CovalentMediaModule, + ToolbarModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, @@ -62,7 +72,8 @@ import { getSelectedLanguage, createTranslateLoader } from './utilities/translat ], // modules needed to run this module providers: [ appRoutingProviders, - GitHubService, { + GitHubService, + InternalDocsService, { // Configure LOCALE_ID depending on the language set in browser provide: LOCALE_ID, useFactory: getSelectedLanguage, deps: [TranslateService], }, diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 2568e6fe0d..446b1c0fa8 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,6 +1,7 @@ import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './components/home/home.component'; +import { TemplatesComponent } from './components/templates/templates.component'; const routes: Routes = [{ component: HomeComponent, @@ -13,6 +14,9 @@ const routes: Routes = [{ path: '', loadChildren: './components/layouts/layouts.module#LayoutsModule', }, { path: '', loadChildren: './components/components/components.module#ComponentsModule', + }, { + component: TemplatesComponent, + path: 'templates', }, ]; diff --git a/src/app/assets/ico/favicon.ico b/src/app/assets/ico/favicon.ico index f3699612c3f93082a6fe3ef4e9f18ca284fe1b98..fe7278dc3f191930e9d56aa1a129f8c9e70caf48 100644 GIT binary patch literal 15086 zcmdU$36xh=9moHm35W{rn8=JI2(Fmsg32Jdlv=rDxTKr4| zN_El`$0gT91H{zSBOKG*GLTWnoxxFOkb&3d^PhL?@%q32{|(F_evcpT_Pgu5_jm7q zvO=L#VZFkjK?TCts~Kvc3zSkXGXDr+p7V+8 zj=l)(N~eE=FqTJ%_s=@ahn$|1lP`XKZT3H{Jc6IL+iS(m9#kq)4*?Q9ewc- zSRL(8CD++@ZawS23CBW~dQ&hH?ttWX zIfC?SU>kvE;uBy)2s(wxv!H!a?wzsl8Cc)FIf<9nF62F%D?lu$#AN2(Btul-|lRpM*|2-HAm2?#b+MiR& zFfM;7wm%@JeJ~px*SjfXWQ6<1b_+7f)7h8A_J(=nnRULt5!#}T8o%rAc>E4|^f5-- z_sL_Nu<5AryYC&3=b(~&QwBfL);Cp0jbFdx`1OaCq`%bGIXIWR>W-o9TQ~3d)o1Pk zl~jX)?dG||w~cKZN;KM^yayqDK2IPooEiHO>*w*GE!bTLJt62wBJ&~m??J?E^GT?r z0T^iOJ2S0Y$q3_{NnHQ>SRyZ!CBstp*COgT=j*}oYp*Z;F?jd;`^-Gcyg#;&)4nMx zX>Say>)R)-?~?H;B*)j5coTKULpKQ8jmR8GxAQr9{#J7jZx)xoMOaA(V_;kJ${4yH zb7Q-7zgg*5vA159Mp9s1*T?;nl)sZL^Br7CM`NI^@6B>bzI(F9oXoFu_NwVj`>c16 zW4GM>R8FT-sNL_&8Bw;j$Ny$LF85M7g}ZJ_IU~x}_V{0~bqyI|EPhYhnw`iCWy#QedkoBg@UB`!Jbiz? zOWu#*3h-}Qw($`J-Au&1lS4*E7=D8sUZULZ>bg7)8zstz6R(5hxbwarmQ(N7kbEoF zl3ohqA?QjXwtsfW$Ovc0c7rp@v$8w#{brxRuZ+zaK%D<9q4R9(_^m!VuA6?}S(enk zBr?EK@*2lZ)5LjKU zN5!AQ2Vk47&n>VObfmsdsdidNP{tW*@WRJDc;lUl=hb*aQA$I0B&TTl*@QuQ- zUWN^YF5?Va3RU$v!p7LHk$U5?Z={``hO~QtVMISm3>gO=XlYc}98F@}wS+y2^NE~K z#Hu(y=F2~XtV(hIEj6v{5%p-UH9wlPsJLFy8(5ld?$H{ue8sd2-})%3=Bo{bP6cDA zXKT=o|L#RwzRA|MJa1<~12EeT`QP?wwxqm^p9X&;@Ffcef%mod#u#Ytw-HSirSG{G ze5*bVJ44X=L@omFY~N1p?MsiN&9~q~7zz6GQmP{JKJYiuZ(uW66ZNHX`0X}>_?9Ia z^IhlqcS)2TOZ-iE54>tMRFB+4*moSVUtx#{+HO3sK5R5v^N|(&(ovOAJX!D_giqk?GJdk;%@^yT=BmX zI+;+N37(PdOd#Lm=fcM@8?xk`?r~}LVtuhdj(q}AA zW~Aa1Nxz!PODFr0u^hBb>rgW6dqlb*PM=8VxUzIT1y-Q-~Q@E!QsSRYugKZKJ*>J z<&=5;e2bnAe%lj3|MwAm0-g)kOP^%DAy7*Cx?iLU^!4K)^j9ieNO=!PsyhkSPXE1O zTwq%(;5%_T9n_PdpGfO?GD`Iu@?76innUJIsRGv|_^DJ;aji~GXOeEu{#~oHOZ1_S zbUsIwDD!R)b1fCxX4d-unKIiBa;?UOL?Y}-+_r}%@&*z2o0#vuF4cFr{inZo{~DeF zY7SgwBqh&@?eCGuA58oMI1Ri9$AJ4ejAIt@tn)XWvaMlP@NA3*<$XQ17+dvU!8i0> zHT(Zk+mf@o{>R2`%96=mBs@b`Bs1gqw+U?{%l{osSsgqCX?ZqJ zg}1>w>H^T`rL_$ii@`ma)b%efE}T|-3(MeT@XqXL=_?)q=h_f+ zK4GczLUxDgC|bT2%K3}3o%`2<;-6@mr$ znoO*oKl?15%%6j5=(slWP`RP2;lF>U@bt7z-sj_?Yul<7&$MU!Eb!d8Zx4k^>W0B( za2x24m3z@Usure$cTXwlqyGZwex4#P%)CGGnJ@}ELC`)#Zig_>n|1d%-ObbRLo5!}lW|CD1SFr z=v=r5979^Jt84AP4{H`|4kO~)hxv#6QlWc6+k>GWIM;E|4f3ixh7({0WWEccS{^;K v`SG=cA3GQGf3m6~y^s(1Iu01G+k9y&cN2e7C=HmHatC&% zyJvP;SO^d#1k18KVrj*yXey>K#sg!-7!64{LUAm+Gkwg?&MwPxx8L8hO?o;ry)!+q zyNPeAUiEap|NZ~}{`cO0b-%}P6Szs-ym=h1aqdc7Z{#>G9v{A+!f|)wS#$I7{o6Ti z(;|+Wg6A&$B#!&z5{|nPZ2-n4Q0O`PF$q+XfS?;6j9Ns^oKp$sXg-T2dz7gBQ#({rzwaWLywQwNp{)#8Sp7A!W_4l~z4)WIrk9iOQRxnfHxEPtwd~ zQSnndK{an5iAE#!l4gG^Dt~0ZdCmM%HTpuz{tS&@RQ!mCR#(G)A)k{yjmjh0ab7j9 z5AxHzI{N{v+rG$nHRGp2oEPmL_LNVVzlqALn6fN??qo*Fm_zKu z1;k`m$-YM6nflMGHl--tpP1|tqV^x{_KJzFX&$c8ywbRlovlX(lrM>C*0n)C$d{TZ8ec$D;FZ-{VFH#=TgAe*zm?KZt8Ao`i zM(+wcO!k=i1%5Z2CyeJ52bJ}=!g~j_*~uq*-r=?La$c~P|DBfDf4TR3JYUHkQw#$h zC%AmVUxID>#Ylbk>M7^IA?LE~SNl4IrM{3o1K{&J>^Y059l{M=>8~@U|jnZfOkLkalUaR$<=|86b8r45z-Twbw|Bbc$8GR;!FbU8{xN($u zDC7B@0Q!bbSv#~9`vW%mi;%H5Ntr@NQ{o^_M2PmI@0G-KZ$`-UZSv!$|MHr_t$25T zFMZ=Fr3+``4>^vq{;aQ@bK;vF>^sQ+!T;S>&79DF)|CAi;ZW9}^Wi<~5G}d=n4{>u z3kjc?>RKSS6^Gf8+OJ9dk zp41B!nbx`A!xnb^4b%C@y#K$C0y7$^p{${Go<}x_)hgd?pOqPP}ZGt zL_NP(Oxl7+o8a;61(I)hzb%L0rA&Tbz2CghJ^~?A2$x_!X6H$5{R6>u>5e7j$t`x=a|TM|MfANnL-S?85i`XTLMrR7 z@p|a`VPi>SDdzw1e1<$RmZFybyV!w!8d}d%LCxMy-_G)SeuvUol7ZaT=dKrgpM94f zSJeMluisbJo^;|H9EVR^yQd}cm(yH_Y|dc5V_kON$k90H`R5eCl=MX|8I@k8b~wXe zo6vsjAbl^YXy(;Yx_C@kciNp_LR;SuuXlf(<{{Soes`T!LejvqncvI3bLInwX2p^P z1>b|e3LSF>-~AqUOMCG&blqXleIMqUO!8@fRA^Hg_hzjSr#&kE!s|ow#ojM-?H1<} z=$0?TelDZ^c>aR*f2XMCJ`&1&gO$^<-r+CU%7d_<&~yGWYl{QBVY}y^G)Sgu^QMjX z&OL1&AzLKDHv0?Bd+cB6tlIbjRJin2<8VnIm7i@xI!V;+br*n4RTPXq#-GWb%|F*q zXY0@JZ;gijnZ6DBUp0@#q3c~ggM5wQGW!we-#Yff9g0E@Hh@(q!-fJ-djg23c{*%ARrwh-N;-eBz zZXB5|=0!a>HwaJn!m8|iid`s2QKEqulKdMz|0`6N_I?dFl(hWMsIH_7O8Et`t^br8 z6AZ&tx*!h!D)CXuH-In7b!>2BsI^?enZ!NnOvD&w+-Kx#Ar6(1KadfJz|Xv+63*Z= z#Dza_<7mo(XeHj1&a=+UgfW}qSEcimn}?w~H$Ol=lxm#c*BHcC=^ioG7V5u@T*t5u zToFqixsFfuT!X!F%VnA`R0kM3I`C^sgZsUhk zhq2iKxkWlF0PDF~Z0lRuq;<^^(}lycke{L=>4l^8u1d`Gtq{`rif5~Z@*b$<^&VMT zJGe-ub&7&K)FRp+9{`JVJ7@j=OEF(?wp9UViJA9P!Q5(*)A=t(LKtX7XZ>If4#qc8 zKChG~ob@pI{Q2JnKqK8!ZU%8>cWKR)d<%E(QqJfC{22alAu{=d%V+A!1Cs^aERc?) zyc!j1xcLQH|LwqCY zBf!#F4CmD;Ul&J?L_*%&wL5C=eqS^9uaq*r>-q$+sRS!(*@PbkHgU6?XQ5moa`|{) zu+*y;l1CT2xfjAubToULSLeTCJRf&$Bi=c0hO#HXkC zAm5Y!cjNk@h*G&uJ<+```v{USd)iNZ8F5dKYADL4I_*+}{6V*r`Mqc(9K0 ziSQ+cXsjvEMP~*CVZ!byZ$@X(xH6}))a<{7!3XQcLwh<)#P!+XvtitJ26+s-ck|Ua z + + + angular + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/app/assets/icons/angular.svg b/src/app/assets/icons/angular.svg new file mode 100644 index 0000000000..96301efe1b --- /dev/null +++ b/src/app/assets/icons/angular.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/src/app/assets/icons/covalent-outline.svg b/src/app/assets/icons/covalent-outline.svg new file mode 100644 index 0000000000..74353cdb8a --- /dev/null +++ b/src/app/assets/icons/covalent-outline.svg @@ -0,0 +1,12 @@ + + + Covalent + Copyright 2016-2017 Teradata. + + + + + + + + \ No newline at end of file diff --git a/src/app/assets/icons/covalent-stroke.svg b/src/app/assets/icons/covalent-stroke.svg new file mode 100644 index 0000000000..bb277bc02a --- /dev/null +++ b/src/app/assets/icons/covalent-stroke.svg @@ -0,0 +1,14 @@ + + + covalent-stroke + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/app/assets/icons/covalent.svg b/src/app/assets/icons/covalent.svg index b37a47325d..ee3f0e9e32 100644 --- a/src/app/assets/icons/covalent.svg +++ b/src/app/assets/icons/covalent.svg @@ -1,10 +1,9 @@ - - covalent - Created with Sketch. + Covalent + Copyright 2016-2017 Teradata. - + diff --git a/src/app/assets/icons/material-outline.svg b/src/app/assets/icons/material-outline.svg new file mode 100644 index 0000000000..4fe075d923 --- /dev/null +++ b/src/app/assets/icons/material-outline.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/assets/icons/material.svg b/src/app/assets/icons/material.svg new file mode 100644 index 0000000000..a73fac1863 --- /dev/null +++ b/src/app/assets/icons/material.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/components/components/components.component.html b/src/app/components/components/components.component.html index cf6464ec84..f6f3e97cae 100644 --- a/src/app/components/components/components.component.html +++ b/src/app/components/components/components.component.html @@ -44,10 +44,10 @@

Angular Material

- {{item.icon}}

{{item.title}}

@@ -56,20 +56,11 @@

{{item.title}}

-
- Covalent Components & Addons - - - - - +
+ Components & Addons +
-
+
\ No newline at end of file diff --git a/src/app/components/components/components.component.ts b/src/app/components/components/components.component.ts index 0a90cc0f94..7222b81948 100644 --- a/src/app/components/components/components.component.ts +++ b/src/app/components/components/components.component.ts @@ -1,5 +1,4 @@ -import { Component, HostBinding, AfterViewInit, ElementRef, Inject, Renderer2 } from '@angular/core'; -import { DOCUMENT } from '@angular/platform-browser'; +import { Component, HostBinding, AfterViewInit} from '@angular/core'; import { TdMediaService } from '@covalent/core'; import { fadeAnimation } from '../../app.animations'; @@ -136,16 +135,10 @@ export class ComponentsComponent implements AfterViewInit { title: 'NGX-Translate', }]; - constructor(public media: TdMediaService, - private _renderer: Renderer2, - @Inject(DOCUMENT) private _document: any) {} + constructor(public media: TdMediaService) {} ngAfterViewInit(): void { // broadcast to all listener observables when loading the page this.media.broadcast(); } - - changeDir(dir: string): void { - this._renderer.setAttribute(this._document.querySelector('html'), 'dir', dir); - } } diff --git a/src/app/components/components/components.module.ts b/src/app/components/components/components.module.ts index caad360e37..470c785334 100644 --- a/src/app/components/components/components.module.ts +++ b/src/app/components/components/components.module.ts @@ -47,6 +47,8 @@ import { CovalentDynamicFormsModule } from '../../../platform/dynamic-forms'; import { DocumentationToolsModule } from '../../documentation-tools'; +import { ToolbarModule } from '../../components/toolbar/toolbar.module'; + @NgModule({ declarations: [ ComponentsComponent, @@ -119,6 +121,7 @@ import { DocumentationToolsModule } from '../../documentation-tools'; NgxChartsModule, TranslateModule, componentsRoutes, + ToolbarModule, ], }) export class ComponentsModule {} diff --git a/src/app/components/components/overview/overview.component.html b/src/app/components/components/overview/overview.component.html index 0027633e37..86bd7b0267 100644 --- a/src/app/components/components/overview/overview.component.html +++ b/src/app/components/components/overview/overview.component.html @@ -5,7 +5,7 @@
-
+
{{item.icon}} @@ -28,7 +28,7 @@
-
+
{{item.icon}} @@ -50,7 +50,7 @@
-
+ -
+
{{item.icon}} diff --git a/src/app/components/components/overview/overview.component.ts b/src/app/components/components/overview/overview.component.ts index 03548e424d..ff796eec12 100644 --- a/src/app/components/components/overview/overview.component.ts +++ b/src/app/components/components/overview/overview.component.ts @@ -14,116 +14,116 @@ export class ComponentsOverviewComponent { @HostBinding('class.td-route-animation') classAnimation: boolean = true; items: Object[] = [{ - color: 'deep-purple-700', + color: 'deep-purple-A700', icon: 'view_list', route: 'steps', title: 'Stepper', }, { - color: 'blue-700', + color: 'blue-A700', icon: 'open_with', route: 'expansion-panel', title: 'Expansion Panel', }, { - color: 'light-blue-700', + color: 'pink-A700', icon: 'space_bar', route: 'file-input', title: 'File Input', }, { - color: 'cyan-700', + color: 'cyan-A700', icon: 'attach_file', route: 'file-upload', title: 'File Upload', }, { - color: 'grey-700', + color: 'deep-orange-A700', icon: 'label', route: 'chips', title: 'Chips', }, { - color: 'light-green-700', + color: 'lime-A700', icon: 'hourglass_empty', route: 'loading', title: 'Loading', }, { - color: 'amber-700', + color: 'amber-A700', icon: 'open_in_browser', route: 'dialogs', title: 'Simple Dialogs', }, { - color: 'green-700', + color: 'green-A700', icon: 'grid_on', route: 'data-table', title: 'Data Table', }, { - color: 'teal-700', + color: 'teal-A700', icon: 'format_indent_increase', route: 'json-formatter', title: 'JSON Formatter', }, { - color: 'blue-grey-700', + color: 'indigo-A700', icon: 'swap_horiz', route: 'paging', title: 'Paging', }, { - color: 'purple-700', + color: 'purple-A700', icon: 'notifications', route: 'notifications', title: 'Notifications', }, { - color: 'light-blue-A400', + color: 'light-blue-A700', icon: 'info_outline', route: 'message', title: 'Messages', }, { - color: 'lime-700', + color: 'indigo-A700', icon: 'search', route: 'search', title: 'Search', }, { - color: 'red-700', + color: 'red-A700', icon: 'devices', route: 'media', title: 'Media Queries', }, { - color: 'light-blue-700', + color: 'light-blue-A700', icon: 'wb_iridescent', route: 'directives', title: 'Directives', }, { - color: 'deep-orange-700', + color: 'deep-orange-A700', icon: 'filter_list', route: 'pipes', title: 'Pipes', }, ]; optional: Object[] = [{ - color: 'pink-700', + color: 'pink-A700', icon: 'code', route: 'syntax-highlighting', title: 'Highlighting', }, { - color: 'orange-700', + color: 'orange-A700', icon: 'chrome_reader_mode', route: 'markdown', title: 'Markdown', }, { - color: 'green-700', + color: 'green-A700', icon: 'format_align_center', route: 'dynamic-forms', title: 'Dynamic Forms', }, { - color: 'indigo-700', + color: 'indigo-A700', icon: 'http', route: 'http', title: 'HTTP Service', }, ]; external: Object[] = [{ - color: 'purple-600', + color: 'purple-A700', icon: 'insert_chart', route: 'ngx-charts', title: 'NGX-Charts', }, { - color: 'blue-600', + color: 'blue-A700', icon: 'language', route: 'ngx-translate', title: 'NGX-Translate', diff --git a/src/app/components/docs/docs.component.html b/src/app/components/docs/docs.component.html index a554b53906..3e099197bb 100644 --- a/src/app/components/docs/docs.component.html +++ b/src/app/components/docs/docs.component.html @@ -1,4 +1,5 @@ {{item.title}} -
- Documentation - +
+ Documentation + +
+
+
- \ No newline at end of file diff --git a/src/app/components/docs/docs.module.ts b/src/app/components/docs/docs.module.ts index c00b4cc93d..fd31147211 100644 --- a/src/app/components/docs/docs.module.ts +++ b/src/app/components/docs/docs.module.ts @@ -17,11 +17,14 @@ import { MockDataComponent } from './mock-data/mock-data.component'; import { DocumentationToolsModule } from '../../documentation-tools'; -import { MdButtonModule, MdListModule, MdIconModule, MdCardModule, MdToolbarModule, MdCoreModule } from '@angular/material'; +import { MdButtonModule, MdListModule, MdIconModule, MdCardModule, MdToolbarModule, MdCoreModule, + MdMenuModule } from '@angular/material'; import { CovalentLayoutModule, CovalentMediaModule } from '../../../platform/core'; import { CovalentHighlightModule } from '../../../platform/highlight'; +import { ToolbarModule } from '../../components/toolbar/toolbar.module'; + @NgModule({ declarations: [ DocsComponent, @@ -46,12 +49,14 @@ import { CovalentHighlightModule } from '../../../platform/highlight'; MdIconModule, MdCardModule, MdToolbarModule, + MdMenuModule, /** Covalent Modules */ CovalentLayoutModule, CovalentMediaModule, CovalentHighlightModule, DocumentationToolsModule, docsRoutes, + ToolbarModule, ], }) export class DocsModule {} diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html index 167a426fe7..e375080807 100644 --- a/src/app/components/home/home.component.html +++ b/src/app/components/home/home.component.html @@ -1,255 +1,312 @@ -
- - - - -
Updates
- - -
- {{item.icon}} -

{{item.description}}

-

{{item.title}}

-
- - - - change_history -

Angular v4.1 and material@beta.5 support

-

Dependencies updated

+ +
+
+ + +
+
+ - - - - -
-

FAQs

- -
- Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). - Covalent gives you a quickstart to build a modern web application UI and ensure consistency across your enterprise products. - Some of Covalent's most important features include: -
    -
  • Angular-Material
  • -
  • Angular Command-line interface (CLI) for builds, deploys, testing & more.
  • -
  • Drastically simplified interface layouts (for dashboards, lists, etc).
  • -
  • Custom web components (stepper, file upload, expansion panels & more).
  • -
  • 750+ Material Design icons.
  • -
  • Style Guide with brand standards, color palettes & tips.
  • -
  • Design Patterns for consistent, reusable web components such as cards, forms, etc.
  • -
  • Testing Tools for both unit tests and end-to-end tests.
  • -
  • Quickstart app to get started right away!
  • -
-
-
- -
- We follow Atomic Design principles and apply them to Angular-Material web components. In Atomic Design, several atoms (such as buttons and inputs) form molecules (such as a search box). - Our covalent bonds are the molecules that we're building on top of Angular-Material. Also, covalent bonds are liquid and conform to their container, just like our responsive layouts! -
-
- -
- By using Covalent as a unified UI Platform there are a ton of benefits. Here are some highlights: -
    -
  • Angular-Material doesn't have a full app quickstart. Covalent does.
  • -
  • Covalent provides the Angular-Material (AngularJS) flexbox layout that was removed in Angular-Material (angular).
  • -
  • Covalent provides several custom components such as steppers & expansion panels.
  • -
  • Custom layouts & components in Covalent are developed specifically for enterprise solutions.
  • -
  • Covalent provides a selection of UI layouts out of the box.
  • -
  • Our team is continuously adding tools like Syntax Highlighting & Markdown.
  • -
  • Our team will always maintain native compatibility with Angular & Material
  • -
  • Our team will always follow the principles of the official Material Design spec.
  • -
-
-
- -
- By adopting Material Design along with Angular, we get a style guide spec that is perfectly matched with an incredbly powerful and modern web framework, all for free. - Along with that, there are lots of other great benefits such as: -
    -
  • A design spec that is married to code implementation.
  • -
  • Official implementations from the the designer/developer (Google).
  • -
  • Free code implementation and updates from a continuously evolving design spec.
  • -
  • Compatability with many devices & breakpoints, from watch and mobile all the way up to fullscreen desktop.
  • -
  • Usage familiarity for users, designers & developers.
  • -
  • Focus on out-of the box accessibility.
  • -
  • Open sourced design & code.
  • -
  • Modularity that gives a natural bridge to agile development principles.
  • -
  • Inspiration, community & resources from around the world.
  • -
-
-
- -
- With any new framework, people's intial reaction is that they'll lose their company brand or identity. - Consider when 960 grids came out, or Bootstrap from Twitter. Many said "all sites will look the same!". - They weren't completely wrong, for a time, when adoption of these new frameworks began. However, with time, usage, and innovation, your special brand identity and uniqueness will always shine through! - Also consider: -
    -
  • Material Design is being embraced across the web, and is not specific to Google anymore
  • -
  • Material Design can be thought of as a native Web SDK, similar to developing a MacOS or iOS app.
  • -
  • Onboarding users is a simpler process if design patterns are familiar.
  • -
  • Think of your favorite iOS, Android or Windows app that adheres to the OS's design. Aren’t the features more important? What woud you really consider “brand”?
  • -
-
-
- -
-

The short answer: we had to pick something & we believe Angular has won the adoption war.

- The longer answer: - Before passing judgement if you have Angular 1.x experience, remember that Angular is a complete rewrite from the ground up. - Angular moved from an opinionated framework to a sophistated platform. - Angular utilizes ES2015 (previously ES6) and the power of Typescript, which results in a much more native JavaScript platform with coding paradigms & power previously reserved for backend languages. - This means many more back end engineers can jump into the front end and ramp up quickly to productivity. - Also there are many other benefits, such as: -
    -
  • New & exciting software to learn & advocate
  • -
  • More easily attract new hires
  • -
  • An incredibly powerful standardized CLI that is provided to us
  • -
  • More powerful IDEs for development
  • -
  • Integrated testing tools
  • -
  • Native mobile & desktop app support
  • -
-
-
- -
- We give you everything you need to quickly get started on your UI, but you have the domain knowledge and are the expert in your product. - You'll need to build all the custom views, controllers & services for your product, and hook them up to your RESTful APIs. - Don't worry though, we have detailed docs & tips, and there's a wealth of help on the internet (it's why we chose such a popular platform). -
-
- -
- We'd LOVE any type of contribution and collaboration! There's all kinds of ways you can join in: -
    -
  • Submit a bug (cool)
  • -
  • Open a pull request to fix a bug (cooler)
  • -
  • Suggest a new feature (which we'll prioritize by demand)
  • -
  • Open a pull request with new feature (make sure it follows the guidelines)
  • -
  • Give us feedback on any aspect of this site or the platform
  • -
  • Join the Teradata UX team!
  • -
+
+
+
+
+
+
+
+

Built with favorite on Angular

+

Teradata is one of the largest enterprise consumers of Angular. Currently the entire product suite is being built or revamped on Angular v4.

+

As Angular unites Teradata developers across the organization, they are able to contribute back to the open-source community with the powerful new tools being developed internally.

- - -
- - -
- To build an atomic, standardized, reusable UI component platform based on Material Design, for Teradata to use for all user interfaces, while collaborating in an open source model. +
+
+
+ +
+
+
+
+
+
+
+
+ + + + {{item.icon}} +

{{item.title}}

+

{{item.description}}

+
+ +
+
+
+ + - - -
- Teradata's UX team is extremely lean & agile (notice agile is lower case). We have a simple list of milestones and issues prioritized by demand across products. - Some big ticket items are underway such as TD Charts, an extensive & standardized component built on Google Charts (continuing w/ the Google web stack). - We're also building Dynamic Forms which will allow products to build complex forms with a simple key:value pair JSON structure. - Remember, we're agile so our roadmap is iterative & bite sized for frequent, rapid releases. +
- - - launch -

Releases

-

Our latest version you can use today!

-
- - - launch -

Milestones

-

Rough time estimates

-
- - - launch -

Feature Requests & Bugs

-

Priotized by demand

-
-
- - -
- Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). - Electron is a framework for creating native desktop applications with web technologies like JavaScript, HTML, and CSS. - Covalent Electron is the Electron Platform to build desktop apps using Covalent and Electron - View Repo -
-
- -
- Covalent Data is a Mock API server for rapid prototyping and API standards - Built on Golang - Allows for quick prototyping for your Covalent Applications with an easy to mock http backend server - View Repo +
+
+
+
+
+
+
+
+
+

Following the Material Design spec

+

Covalent follows the Material Design specification as closely as possible through the construction of all components.

+

Adopting Material Design as our own spec allows our UI/UX staff to adopt and share powerful open-source resources, while Covalent end users enjoy the immediate familiarity and affordance of this global deign spec.

- +
+
+
+ +
- - -
- Copyright © 2016 - 2017 Teradata. All rights reserved +
+
+
+
+
+

FAQs

+ +
+ Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). + Covalent gives you a quickstart to build a modern web application UI and ensure consistency across your enterprise products. + Some of Covalent's most important features include: +
    +
  • Angular-Material
  • +
  • Angular Command-line interface (CLI) for builds, deploys, testing & more.
  • +
  • Drastically simplified interface layouts (for dashboards, lists, etc).
  • +
  • Custom web components (stepper, file upload, expansion panels & more).
  • +
  • 750+ Material Design icons.
  • +
  • Style Guide with brand standards, color palettes & tips.
  • +
  • Design Patterns for consistent, reusable web components such as cards, forms, etc.
  • +
  • Testing Tools for both unit tests and end-to-end tests.
  • +
  • Quickstart app to get started right away!
  • +
+
+
+ +
+ We follow Atomic Design principles and apply them to Angular-Material web components. In Atomic Design, several atoms (such as buttons and inputs) form molecules (such as a search box). + Our covalent bonds are the molecules that we're building on top of Angular-Material. Also, covalent bonds are liquid and conform to their container, just like our responsive layouts! +
+
+ +
+ By using Covalent as a unified UI Platform there are a ton of benefits. Here are some highlights: +
    +
  • Angular-Material doesn't have a full app quickstart. Covalent does.
  • +
  • Covalent provides the Angular-Material (AngularJS) flexbox layout that was removed in Angular-Material (angular).
  • +
  • Covalent provides several custom components such as steppers & expansion panels.
  • +
  • Custom layouts & components in Covalent are developed specifically for enterprise solutions.
  • +
  • Covalent provides a selection of UI layouts out of the box.
  • +
  • Our team is continuously adding tools like Syntax Highlighting & Markdown.
  • +
  • Our team will always maintain native compatibility with Angular & Material
  • +
  • Our team will always follow the principles of the official Material Design spec.
  • +
+
+
+ +
+ By adopting Material Design along with Angular, we get a style guide spec that is perfectly matched with an incredbly powerful and modern web framework, all for free. + Along with that, there are lots of other great benefits such as: +
    +
  • A design spec that is married to code implementation.
  • +
  • Official implementations from the the designer/developer (Google).
  • +
  • Free code implementation and updates from a continuously evolving design spec.
  • +
  • Compatability with many devices & breakpoints, from watch and mobile all the way up to fullscreen desktop.
  • +
  • Usage familiarity for users, designers & developers.
  • +
  • Focus on out-of the box accessibility.
  • +
  • Open sourced design & code.
  • +
  • Modularity that gives a natural bridge to agile development principles.
  • +
  • Inspiration, community & resources from around the world.
  • +
+
+
+ +
+ With any new framework, people's intial reaction is that they'll lose their company brand or identity. + Consider when 960 grids came out, or Bootstrap from Twitter. Many said "all sites will look the same!". + They weren't completely wrong, for a time, when adoption of these new frameworks began. However, with time, usage, and innovation, your special brand identity and uniqueness will always shine through! + Also consider: +
    +
  • Material Design is being embraced across the web, and is not specific to Google anymore
  • +
  • Material Design can be thought of as a native Web SDK, similar to developing a MacOS or iOS app.
  • +
  • Onboarding users is a simpler process if design patterns are familiar.
  • +
  • Think of your favorite iOS, Android or Windows app that adheres to the OS's design. Aren’t the features more important? What woud you really consider “brand”?
  • +
+
+
+ +
+

The short answer: we had to pick something & we believe Angular has won the adoption war.

+ The longer answer: + Before passing judgement if you have Angular 1.x experience, remember that Angular v2+ is a complete rewrite from the ground up. + Angular moved from an opinionated framework to a sophistated platform. + Angular utilizes ES2015 (previously ES6) and the power of Typescript, which results in a much more native JavaScript platform with coding paradigms & power previously reserved for backend languages. + This means many more back end engineers can jump into the front end and ramp up quickly to productivity. + Also there are many other benefits, such as: +
    +
  • New & exciting software to learn & advocate
  • +
  • More easily attract new hires
  • +
  • An incredibly powerful standardized CLI that is provided to us
  • +
  • More powerful IDEs for development
  • +
  • Integrated testing tools
  • +
  • Native mobile & desktop app support
  • +
+
+
+ +
+ We give you everything you need to quickly get started on your UI, but you have the domain knowledge and are the expert in your product. + You'll need to build all the custom views, controllers & services for your product, and hook them up to your RESTful APIs. + Don't worry though, we have detailed docs & tips, and there's a wealth of help on the internet (it's why we chose such a popular platform). +
+
+ +
+ We'd LOVE any type of contribution and collaboration! There's all kinds of ways you can join in: +
    +
  • Submit a bug (cool)
  • +
  • Open a pull request to fix a bug (cooler)
  • +
  • Suggest a new feature (which we'll prioritize by demand)
  • +
  • Open a pull request with new feature (make sure it follows the guidelines)
  • +
  • Give us feedback on any aspect of this site or the platform
  • +
  • Join the Teradata UX team!
  • +
+
+
+ +
+ + +
+ To build an atomic, standardized, reusable UI component platform based on Material Design, for Teradata to use for all user interfaces, while collaborating in an open source model. +
+
+
+
+ Teradata's UX team is extremely lean & agile (notice agile is lower case). We have a simple list of milestones and issues prioritized by demand across products. + Some big ticket items are underway such as TD Charts, an extensive & standardized component built on Google Charts (continuing w/ the Google web stack). + We're also building Dynamic Forms which will allow products to build complex forms with a simple key:value pair JSON structure. + Remember, we're agile so our roadmap is iterative & bite sized for frequent, rapid releases. +
+
+ + + launch +

Releases

+

Our latest version you can use today!

+
+ + + launch +

Milestones

+

Rough time estimates

+
+ + + launch +

Feature Requests & Bugs

+

Priotized by demand

+
+
+
+ +
+ Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). + Electron is a framework for creating native desktop applications with web technologies like JavaScript, HTML, and CSS. + Covalent Electron is the Electron Platform to build desktop apps using Covalent and Electron + View Repo +
+
+ +
+ Covalent Data is a Mock API server for rapid prototyping and API standards + Built on Golang + Allows for quick prototyping for your Covalent Applications with an easy to mock http backend server + View Repo +
+
+
+
+
+
+ +
+
Copyright © 2016 - 2017 Teradata. All rights reserved
- +
- \ No newline at end of file + diff --git a/src/app/components/home/home.component.scss b/src/app/components/home/home.component.scss index 5b11e4278c..35ad04d7f1 100644 --- a/src/app/components/home/home.component.scss +++ b/src/app/components/home/home.component.scss @@ -9,9 +9,26 @@ width: 60px; margin-left: 16px; } +.mat-icon-svg-xxl { + width: 90%; + height: auto; +} .md-icon-ux { width: 165px; } -[td-after-card] { - margin: 64px 8px 8px 8px; +@media (max-width: 799px) { + .mat-icon-md { + font-size: 50px; + } + .mat-icon-xl { + font-size: 120px; + } +} +@media (min-width: 800px) { + .mat-icon-md { + font-size: 70px; + } + .mat-icon-xl { + font-size: 160px; + } } \ No newline at end of file diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts index c65630815a..9bf61853be 100644 --- a/src/app/components/home/home.component.ts +++ b/src/app/components/home/home.component.ts @@ -1,5 +1,5 @@ -import { Component, HostBinding, OnInit } from '@angular/core'; - +import { Component, HostBinding, AfterViewInit } from '@angular/core'; +import { TdMediaService } from '@covalent/core'; import { GitHubService } from '../../services'; import { fadeAnimation } from '../../app.animations'; @@ -11,102 +11,73 @@ import { fadeAnimation } from '../../app.animations'; animations: [fadeAnimation], }) -export class HomeComponent implements OnInit { +export class HomeComponent implements AfterViewInit { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; starCount: number = 0; - items: Object[] = [{ - color: 'purple-700', + sections: Object[] = [{ + color: 'deep-purple-A400', description: 'Your guide to start using the UI platform in your app!', icon: 'library_books', route: 'docs', title: 'Documentation', }, { - color: 'blue-700', - description: 'Teradata brand logo usage, color palettes and more', - icon: 'color_lens', - route: 'style-guide', - title: 'Style Guide', + color: 'teal-A700', + description: 'Covalent Components, Directives, Pipes & Services', + icon: 'picture_in_picture', + route: 'components', + title: 'Components', }, { - color: 'teal-700', + color: 'cyan-A700', description: 'Several different material design layout options for your apps', icon: 'view_quilt', route: 'layouts', title: 'Layouts', }, { - color: 'green-700', - description: 'Covalent Components, Directives, Pipes & Services', - icon: 'picture_in_picture', - route: 'components', - title: 'Components & Addons', + color: 'indigo-A400', + description: 'Teradata brand logo usage, color palettes and more', + icon: 'color_lens', + route: 'style-guide', + title: 'Style Guide', + }, { + color: 'green-A700', + description: 'Gallery of example applications and usages', + icon: 'view_carousel', + route: 'templates', + title: 'Templates', }, ]; - updates: Object[] = [{ - description: 'Keyboard support for selection', - icon: 'grid_on', - route: 'components/data-table', - title: 'Data Table feature', - }, { - description: 'Row click events', - icon: 'grid_on', - route: 'components/data-table', - title: 'Data Table feature', - }, { - description: 'Hide columns & exclude from filtering', - icon: 'grid_on', - route: 'components/data-table', - title: 'Data Table feature', - }, { - description: 'Async & boolean loading', - icon: 'hourglass_empty', - route: 'components/loading', - title: 'Loading features', + repos: Object[] = [{ + color: 'amber-A400', + description: 'A pre-built Angular 4 app using Covalent ready to go!', + icon: 'flash_on', + link: 'https://github.com/Teradata/covalent-quickstart', + title: 'Covalent Quickstart', }, { - description: 'Component for alerts/info/warning/error/success', - icon: 'info_outline', - route: 'components/message', - title: 'New Messages component', + color: 'orange-A400', + description: 'A native desktop hybrid starter app built on Electron.', + icon: 'laptop_mac', + link: 'https://github.com/Teradata/covalent-electron', + title: 'Covalent Electron', }, { - description: 'Numbered page links to jump ahead', - icon: 'swap_horiz', - route: 'components/paging', - title: 'Pagination feature', - }, { - description: 'Disable adding of chips', - icon: 'label', - route: 'components/chips', - title: 'Chips feature', - }, { - description: 'New formData property', - icon: 'attach_file', - route: 'components/file-upload', - title: 'File service feature', - }, { - description: 'New contentReady event binding', - icon: 'chrome_reader_mode', - route: 'components/markdown', - title: 'Markdown feature', - }, { - description: 'New contentReady event binding', - icon: 'code', - route: 'components/highlight', - title: 'Highlight feature', - }, { - description: 'Make navigationRoute optional', - icon: 'view_quilt', - route: 'components/layouts', - title: 'Layouts feature', + color: 'deep-orange-A400', + description: 'Mock API server for rapid prototyping and API standards.', + icon: 'aspect_ratio', + link: 'https://github.com/Teradata/covalent-data', + title: 'Covalent Data', }, ]; - constructor(private _gitHubService: GitHubService) { + constructor(private _gitHubService: GitHubService, + public media: TdMediaService) { } - ngOnInit(): void { + ngAfterViewInit(): void { + this.media.broadcast(); this._gitHubService.queryStartCount().subscribe((starsCount: number) => { this.starCount = starsCount; }); diff --git a/src/app/components/layouts/card-over/card-over.component.html b/src/app/components/layouts/card-over/card-over.component.html index 87f14599a2..59f50e6ba9 100644 --- a/src/app/components/layouts/card-over/card-over.component.html +++ b/src/app/components/layouts/card-over/card-over.component.html @@ -1,4 +1,5 @@ + Card Over Layout A card overlaying a toolbar (this page is using card over) diff --git a/src/app/components/layouts/layouts.module.ts b/src/app/components/layouts/layouts.module.ts index af4b83f962..29cb47ce20 100644 --- a/src/app/components/layouts/layouts.module.ts +++ b/src/app/components/layouts/layouts.module.ts @@ -17,6 +17,8 @@ import { CovalentHighlightModule } from '../../../platform/highlight'; import { DocumentationToolsModule } from '../../documentation-tools'; +import { ToolbarModule } from '../../components/toolbar/toolbar.module'; + @NgModule({ declarations: [ LayoutsComponent, @@ -44,6 +46,7 @@ import { DocumentationToolsModule } from '../../documentation-tools'; CovalentHighlightModule, DocumentationToolsModule, layoutsRoutes, + ToolbarModule, ], }) export class LayoutsModule {} diff --git a/src/app/components/layouts/manage-list/manage-list.component.html b/src/app/components/layouts/manage-list/manage-list.component.html index 14b8787b9d..ff1f08217a 100644 --- a/src/app/components/layouts/manage-list/manage-list.component.html +++ b/src/app/components/layouts/manage-list/manage-list.component.html @@ -1,5 +1,6 @@ - - + + diff --git a/src/app/components/layouts/nav-list/nav-list.component.html b/src/app/components/layouts/nav-list/nav-list.component.html index 5bb057dcc3..514cac9b07 100644 --- a/src/app/components/layouts/nav-list/nav-list.component.html +++ b/src/app/components/layouts/nav-list/nav-list.component.html @@ -1,4 +1,5 @@ Item Name

item description

-
- Page Title - +
+ Nav List +
Nav List Layout diff --git a/src/app/components/layouts/nav-view/nav-view.component.html b/src/app/components/layouts/nav-view/nav-view.component.html index 5bf2418deb..cdee9ddbb4 100644 --- a/src/app/components/layouts/nav-view/nav-view.component.html +++ b/src/app/components/layouts/nav-view/nav-view.component.html @@ -1,4 +1,5 @@ +
Nav View diff --git a/src/app/components/layouts/overview/overview.component.html b/src/app/components/layouts/overview/overview.component.html index 9262571359..615fecc7c1 100644 --- a/src/app/components/layouts/overview/overview.component.html +++ b/src/app/components/layouts/overview/overview.component.html @@ -1,4 +1,5 @@ +

For your entire app or for different sections of your app, select one of these Material Design layout options:

diff --git a/src/app/components/style-guide/style-guide.component.html b/src/app/components/style-guide/style-guide.component.html index 6eefac4055..685afc6b0e 100644 --- a/src/app/components/style-guide/style-guide.component.html +++ b/src/app/components/style-guide/style-guide.component.html @@ -1,4 +1,5 @@ {{item.title}}
- Teradata Style Guide - + Style Guide + +
+
+
-
diff --git a/src/app/components/style-guide/style-guide.module.ts b/src/app/components/style-guide/style-guide.module.ts index 4507708f9f..c5eaf54c7a 100644 --- a/src/app/components/style-guide/style-guide.module.ts +++ b/src/app/components/style-guide/style-guide.module.ts @@ -24,6 +24,8 @@ import { CovalentLayoutModule, CovalentMediaModule, CovalentSearchModule, Covale CovalentExpansionPanelModule, CovalentDialogsModule } from '../../../platform/core'; import { CovalentHighlightModule } from '../../../platform/highlight'; +import { ToolbarModule } from '../../components/toolbar/toolbar.module'; + @NgModule({ declarations: [ StyleGuideComponent, @@ -66,6 +68,7 @@ import { CovalentHighlightModule } from '../../../platform/highlight'; CovalentHighlightModule, CovalentDialogsModule, styleGuideRoutes, + ToolbarModule, ], }) export class StyleGuideModule {} diff --git a/src/app/components/templates/templates.component.html b/src/app/components/templates/templates.component.html new file mode 100644 index 0000000000..298ebc0cc4 --- /dev/null +++ b/src/app/components/templates/templates.component.html @@ -0,0 +1,29 @@ + + +
+
+
+

Covalent Templates

+

Example starter templates for your application

+
+
+
+
+ +
+
diff --git a/src/app/components/templates/templates.component.scss b/src/app/components/templates/templates.component.scss new file mode 100644 index 0000000000..7c397a7636 --- /dev/null +++ b/src/app/components/templates/templates.component.scss @@ -0,0 +1,10 @@ +:host /deep/ { + md-grid-tile img { + width: 100%; + height: auto; + } + .mat-grid-tile .mat-figure { + align-items: flex-start; + justify-content: flex-start; + } +} \ No newline at end of file diff --git a/src/app/components/templates/templates.component.ts b/src/app/components/templates/templates.component.ts new file mode 100644 index 0000000000..b19130125e --- /dev/null +++ b/src/app/components/templates/templates.component.ts @@ -0,0 +1,32 @@ +import { Component, HostBinding, AfterViewInit, ChangeDetectorRef } from '@angular/core'; +import { TdMediaService } from '@covalent/core'; +import { fadeAnimation } from '../../app.animations'; + +import { Observable } from 'rxjs/Observable'; + +import { InternalDocsService, ITemplate } from '../../services'; + +@Component({ + selector: 'app-templates', + styleUrls: ['./templates.component.scss'], + templateUrl: './templates.component.html', + animations: [fadeAnimation], +}) +export class TemplatesComponent implements AfterViewInit { + + @HostBinding('@routeAnimation') routeAnimation: boolean = true; + @HostBinding('class.td-route-animation') classAnimation: boolean = true; + + templatesObs: Observable; + + constructor(public media: TdMediaService, + private _changeDetectorRef: ChangeDetectorRef, + private _internalDocsService: InternalDocsService) { + this.templatesObs = this._internalDocsService.queryTemplates(); + } + + ngAfterViewInit(): void { + this.media.broadcast(); + this._changeDetectorRef.detectChanges(); + } +} diff --git a/src/app/components/toolbar/toolbar.component.html b/src/app/components/toolbar/toolbar.component.html new file mode 100644 index 0000000000..0574cb00cf --- /dev/null +++ b/src/app/components/toolbar/toolbar.component.html @@ -0,0 +1,51 @@ + + \ No newline at end of file diff --git a/src/app/components/toolbar/toolbar.component.scss b/src/app/components/toolbar/toolbar.component.scss new file mode 100644 index 0000000000..7bfcb81600 --- /dev/null +++ b/src/app/components/toolbar/toolbar.component.scss @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2016-2017 by Teradata Corporation. All rights reserved. + * TERADATA CORPORATION CONFIDENTIAL AND TRADE SECRET + */ + +:host { + display: block; +} diff --git a/src/app/components/toolbar/toolbar.component.ts b/src/app/components/toolbar/toolbar.component.ts new file mode 100644 index 0000000000..19c90a3fe0 --- /dev/null +++ b/src/app/components/toolbar/toolbar.component.ts @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016-2017 by Teradata Corporation. All rights reserved. + * TERADATA CORPORATION CONFIDENTIAL AND TRADE SECRET + */ + +import { Component, ElementRef, Inject, Renderer2, Output, EventEmitter } from '@angular/core'; +import { DOCUMENT } from '@angular/platform-browser'; + +@Component({ + selector: 'td-toolbar', + templateUrl: '././toolbar.component.html', + styleUrls: ['././toolbar.component.scss'], +}) +export class ToolbarComponent { + updates: Object[] = [{ + description: 'Keyboard support for selection', + icon: 'grid_on', + route: 'components/data-table', + title: 'Data Table feature', + }, { + description: 'Row click events', + icon: 'grid_on', + route: 'components/data-table', + title: 'Data Table feature', + }, { + description: 'Hide columns & exclude from filtering', + icon: 'grid_on', + route: 'components/data-table', + title: 'Data Table feature', + }, { + description: 'Async & boolean loading', + icon: 'hourglass_empty', + route: 'components/loading', + title: 'Loading features', + }, { + description: 'Component for alerts/info/warning/error/success', + icon: 'info_outline', + route: 'components/message', + title: 'New Messages component', + }, { + description: 'Numbered page links to jump ahead', + icon: 'swap_horiz', + route: 'components/paging', + title: 'Pagination feature', + }, { + description: 'Disable adding of chips', + icon: 'label', + route: 'components/chips', + title: 'Chips feature', + }, { + description: 'New formData property', + icon: 'attach_file', + route: 'components/file-upload', + title: 'File service feature', + }, { + description: 'New contentReady event binding', + icon: 'chrome_reader_mode', + route: 'components/markdown', + title: 'Markdown feature', + }, { + description: 'New contentReady event binding', + icon: 'code', + route: 'components/highlight', + title: 'Highlight feature', + }, { + description: 'Make navigationRoute optional', + icon: 'view_quilt', + route: 'components/layouts', + title: 'Layouts feature', + }, + ]; + dir: string = 'ltr'; + @Output('changeDir') onChangeDir: EventEmitter = new EventEmitter(); + constructor(private _renderer: Renderer2, + @Inject(DOCUMENT) private _document: any) {} + changeDir(dir: string): void { + this._renderer.setAttribute(this._document.querySelector('html'), 'dir', dir); + this.onChangeDir.emit(this.dir); + } +} diff --git a/src/app/components/toolbar/toolbar.module.ts b/src/app/components/toolbar/toolbar.module.ts new file mode 100644 index 0000000000..9fbcd2cd7b --- /dev/null +++ b/src/app/components/toolbar/toolbar.module.ts @@ -0,0 +1,31 @@ +import { NgModule, ModuleWithProviders } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; + +import { ToolbarComponent } from './toolbar.component'; + +import { MdButtonModule, MdListModule, MdIconModule, MdMenuModule } from '@angular/material'; + +import { CovalentMenuModule, CovalentNotificationsModule } from '../../../platform/core'; + +@NgModule({ + imports: [ + CommonModule, + MdButtonModule, + MdListModule, + MdIconModule, + MdMenuModule, + CovalentMenuModule, + CovalentNotificationsModule, + RouterModule, + ], + declarations: [ + ToolbarComponent, + ], + exports: [ + ToolbarComponent, + ], +}) +export class ToolbarModule { + +} diff --git a/src/app/services/index.ts b/src/app/services/index.ts index 2c23c67f7d..fc0f68139e 100644 --- a/src/app/services/index.ts +++ b/src/app/services/index.ts @@ -1 +1,2 @@ export { GitHubService } from './github.service'; +export { InternalDocsService, ITemplate } from './internal-docs.service'; diff --git a/src/app/services/internal-docs.service.ts b/src/app/services/internal-docs.service.ts new file mode 100644 index 0000000000..3fe4c1c0a5 --- /dev/null +++ b/src/app/services/internal-docs.service.ts @@ -0,0 +1,44 @@ +import { Injectable } from '@angular/core'; +import { Response } from '@angular/http'; +import { Observable } from 'rxjs/Observable'; +import { Subscriber } from 'rxjs/Subscriber'; + +import { HttpInterceptorService } from '@covalent/http'; + +export interface ITemplate { + name: string; + description: string; + plnkr: string; + img: string; + color: string; + icon: string; +} + +const INTERNAL_DOCS_URL: string = 'https://covalent-docs.firebaseio.com/'; + +@Injectable() +export class InternalDocsService { + + constructor(private _http: HttpInterceptorService) { + + } + + queryTemplates(): Observable { + return new Observable((subscriber: Subscriber) => { + this._http.get(INTERNAL_DOCS_URL + '/templates.json').subscribe((response: Response) => { + let data: ITemplate[]; + try { + data = response.json(); + } catch (e) { + data = []; + subscriber.error(); + } + subscriber.next(data); + subscriber.complete(); + }, (error: any) => { + subscriber.error(); + }); + }); + } + +} diff --git a/src/favicon.ico b/src/favicon.ico index f3699612c3f93082a6fe3ef4e9f18ca284fe1b98..fe7278dc3f191930e9d56aa1a129f8c9e70caf48 100644 GIT binary patch literal 15086 zcmdU$36xh=9moHm35W{rn8=JI2(Fmsg32Jdlv=rDxTKr4| zN_El`$0gT91H{zSBOKG*GLTWnoxxFOkb&3d^PhL?@%q32{|(F_evcpT_Pgu5_jm7q zvO=L#VZFkjK?TCts~Kvc3zSkXGXDr+p7V+8 zj=l)(N~eE=FqTJ%_s=@ahn$|1lP`XKZT3H{Jc6IL+iS(m9#kq)4*?Q9ewc- zSRL(8CD++@ZawS23CBW~dQ&hH?ttWX zIfC?SU>kvE;uBy)2s(wxv!H!a?wzsl8Cc)FIf<9nF62F%D?lu$#AN2(Btul-|lRpM*|2-HAm2?#b+MiR& zFfM;7wm%@JeJ~px*SjfXWQ6<1b_+7f)7h8A_J(=nnRULt5!#}T8o%rAc>E4|^f5-- z_sL_Nu<5AryYC&3=b(~&QwBfL);Cp0jbFdx`1OaCq`%bGIXIWR>W-o9TQ~3d)o1Pk zl~jX)?dG||w~cKZN;KM^yayqDK2IPooEiHO>*w*GE!bTLJt62wBJ&~m??J?E^GT?r z0T^iOJ2S0Y$q3_{NnHQ>SRyZ!CBstp*COgT=j*}oYp*Z;F?jd;`^-Gcyg#;&)4nMx zX>Say>)R)-?~?H;B*)j5coTKULpKQ8jmR8GxAQr9{#J7jZx)xoMOaA(V_;kJ${4yH zb7Q-7zgg*5vA159Mp9s1*T?;nl)sZL^Br7CM`NI^@6B>bzI(F9oXoFu_NwVj`>c16 zW4GM>R8FT-sNL_&8Bw;j$Ny$LF85M7g}ZJ_IU~x}_V{0~bqyI|EPhYhnw`iCWy#QedkoBg@UB`!Jbiz? zOWu#*3h-}Qw($`J-Au&1lS4*E7=D8sUZULZ>bg7)8zstz6R(5hxbwarmQ(N7kbEoF zl3ohqA?QjXwtsfW$Ovc0c7rp@v$8w#{brxRuZ+zaK%D<9q4R9(_^m!VuA6?}S(enk zBr?EK@*2lZ)5LjKU zN5!AQ2Vk47&n>VObfmsdsdidNP{tW*@WRJDc;lUl=hb*aQA$I0B&TTl*@QuQ- zUWN^YF5?Va3RU$v!p7LHk$U5?Z={``hO~QtVMISm3>gO=XlYc}98F@}wS+y2^NE~K z#Hu(y=F2~XtV(hIEj6v{5%p-UH9wlPsJLFy8(5ld?$H{ue8sd2-})%3=Bo{bP6cDA zXKT=o|L#RwzRA|MJa1<~12EeT`QP?wwxqm^p9X&;@Ffcef%mod#u#Ytw-HSirSG{G ze5*bVJ44X=L@omFY~N1p?MsiN&9~q~7zz6GQmP{JKJYiuZ(uW66ZNHX`0X}>_?9Ia z^IhlqcS)2TOZ-iE54>tMRFB+4*moSVUtx#{+HO3sK5R5v^N|(&(ovOAJX!D_giqk?GJdk;%@^yT=BmX zI+;+N37(PdOd#Lm=fcM@8?xk`?r~}LVtuhdj(q}AA zW~Aa1Nxz!PODFr0u^hBb>rgW6dqlb*PM=8VxUzIT1y-Q-~Q@E!QsSRYugKZKJ*>J z<&=5;e2bnAe%lj3|MwAm0-g)kOP^%DAy7*Cx?iLU^!4K)^j9ieNO=!PsyhkSPXE1O zTwq%(;5%_T9n_PdpGfO?GD`Iu@?76innUJIsRGv|_^DJ;aji~GXOeEu{#~oHOZ1_S zbUsIwDD!R)b1fCxX4d-unKIiBa;?UOL?Y}-+_r}%@&*z2o0#vuF4cFr{inZo{~DeF zY7SgwBqh&@?eCGuA58oMI1Ri9$AJ4ejAIt@tn)XWvaMlP@NA3*<$XQ17+dvU!8i0> zHT(Zk+mf@o{>R2`%96=mBs@b`Bs1gqw+U?{%l{osSsgqCX?ZqJ zg}1>w>H^T`rL_$ii@`ma)b%efE}T|-3(MeT@XqXL=_?)q=h_f+ zK4GczLUxDgC|bT2%K3}3o%`2<;-6@mr$ znoO*oKl?15%%6j5=(slWP`RP2;lF>U@bt7z-sj_?Yul<7&$MU!Eb!d8Zx4k^>W0B( za2x24m3z@Usure$cTXwlqyGZwex4#P%)CGGnJ@}ELC`)#Zig_>n|1d%-ObbRLo5!}lW|CD1SFr z=v=r5979^Jt84AP4{H`|4kO~)hxv#6QlWc6+k>GWIM;E|4f3ixh7({0WWEccS{^;K v`SG=cA3GQGf3m6~y^s(1Iu01G+k9y&cN2e7C=HmHatC&% zyJvP;SO^d#1k18KVrj*yXey>K#sg!-7!64{LUAm+Gkwg?&MwPxx8L8hO?o;ry)!+q zyNPeAUiEap|NZ~}{`cO0b-%}P6Szs-ym=h1aqdc7Z{#>G9v{A+!f|)wS#$I7{o6Ti z(;|+Wg6A&$B#!&z5{|nPZ2-n4Q0O`PF$q+XfS?;6j9Ns^oKp$sXg-T2dz7gBQ#({rzwaWLywQwNp{)#8Sp7A!W_4l~z4)WIrk9iOQRxnfHxEPtwd~ zQSnndK{an5iAE#!l4gG^Dt~0ZdCmM%HTpuz{tS&@RQ!mCR#(G)A)k{yjmjh0ab7j9 z5AxHzI{N{v+rG$nHRGp2oEPmL_LNVVzlqALn6fN??qo*Fm_zKu z1;k`m$-YM6nflMGHl--tpP1|tqV^x{_KJzFX&$c8ywbRlovlX(lrM>C*0n)C$d{TZ8ec$D;FZ-{VFH#=TgAe*zm?KZt8Ao`i zM(+wcO!k=i1%5Z2CyeJ52bJ}=!g~j_*~uq*-r=?La$c~P|DBfDf4TR3JYUHkQw#$h zC%AmVUxID>#Ylbk>M7^IA?LE~SNl4IrM{3o1K{&J>^Y059l{M=>8~@U|jnZfOkLkalUaR$<=|86b8r45z-Twbw|Bbc$8GR;!FbU8{xN($u zDC7B@0Q!bbSv#~9`vW%mi;%H5Ntr@NQ{o^_M2PmI@0G-KZ$`-UZSv!$|MHr_t$25T zFMZ=Fr3+``4>^vq{;aQ@bK;vF>^sQ+!T;S>&79DF)|CAi;ZW9}^Wi<~5G}d=n4{>u z3kjc?>RKSS6^Gf8+OJ9dk zp41B!nbx`A!xnb^4b%C@y#K$C0y7$^p{${Go<}x_)hgd?pOqPP}ZGt zL_NP(Oxl7+o8a;61(I)hzb%L0rA&Tbz2CghJ^~?A2$x_!X6H$5{R6>u>5e7j$t`x=a|TM|MfANnL-S?85i`XTLMrR7 z@p|a`VPi>SDdzw1e1<$RmZFybyV!w!8d}d%LCxMy-_G)SeuvUol7ZaT=dKrgpM94f zSJeMluisbJo^;|H9EVR^yQd}cm(yH_Y|dc5V_kON$k90H`R5eCl=MX|8I@k8b~wXe zo6vsjAbl^YXy(;Yx_C@kciNp_LR;SuuXlf(<{{Soes`T!LejvqncvI3bLInwX2p^P z1>b|e3LSF>-~AqUOMCG&blqXleIMqUO!8@fRA^Hg_hzjSr#&kE!s|ow#ojM-?H1<} z=$0?TelDZ^c>aR*f2XMCJ`&1&gO$^<-r+CU%7d_<&~yGWYl{QBVY}y^G)Sgu^QMjX z&OL1&AzLKDHv0?Bd+cB6tlIbjRJin2<8VnIm7i@xI!V;+br*n4RTPXq#-GWb%|F*q zXY0@JZ;gijnZ6DBUp0@#q3c~ggM5wQGW!we-#Yff9g0E@Hh@(q!-fJ-djg23c{*%ARrwh-N;-eBz zZXB5|=0!a>HwaJn!m8|iid`s2QKEqulKdMz|0`6N_I?dFl(hWMsIH_7O8Et`t^br8 z6AZ&tx*!h!D)CXuH-In7b!>2BsI^?enZ!NnOvD&w+-Kx#Ar6(1KadfJz|Xv+63*Z= z#Dza_<7mo(XeHj1&a=+UgfW}qSEcimn}?w~H$Ol=lxm#c*BHcC=^ioG7V5u@T*t5u zToFqixsFfuT!X!F%VnA`R0kM3I`C^sgZsUhk zhq2iKxkWlF0PDF~Z0lRuq;<^^(}lycke{L=>4l^8u1d`Gtq{`rif5~Z@*b$<^&VMT zJGe-ub&7&K)FRp+9{`JVJ7@j=OEF(?wp9UViJA9P!Q5(*)A=t(LKtX7XZ>If4#qc8 zKChG~ob@pI{Q2JnKqK8!ZU%8>cWKR)d<%E(QqJfC{22alAu{=d%V+A!1Cs^aERc?) zyc!j1xcLQH|LwqCY zBf!#F4CmD;Ul&J?L_*%&wL5C=eqS^9uaq*r>-q$+sRS!(*@PbkHgU6?XQ5moa`|{) zu+*y;l1CT2xfjAubToULSLeTCJRf&$Bi=c0hO#HXkC zAm5Y!cjNk@h*G&uJ<+```v{USd)iNZ8F5dKYADL4I_*+}{6V*r`Mqc(9K0 ziSQ+cXsjvEMP~*CVZ!byZ$@X(xH6}))a<{7!3XQcLwh<)#P!+XvtitJ26+s-ck|Ua z -
+

Covalent Loading...

diff --git a/src/theme.scss b/src/theme.scss index a04235302b..dc2e20d613 100644 --- a/src/theme.scss +++ b/src/theme.scss @@ -8,11 +8,44 @@ // have to load a single css file for Angular Material in your app. @include mat-core(); +// Custom orange contrast +$mat-orange-custom: ( 50: #FFF3E0, + 100: #FFE0B2, + 200: #FFCC80, + 300: #FFB74D, + 400: #FFA726, + 500: #FF9800, + 600: #FB8C00, + 700: #F57C00, + 800: #EF6C00, + 900: #E65100, + A100: #FFD180, + A200: #FFAB40, + A400: #FF9100, + A700: #FF6D00, + contrast: ( + 50: $black-87-opacity, + 100: $black-87-opacity, + 200: $black-87-opacity, + 300: $black-87-opacity, + 400: $black-87-opacity, + 500: white, + 600: white, + 700: white, + 800: $white-87-opacity, + 900: $white-87-opacity, + A100: $black-87-opacity, + A200: $black-87-opacity, + A400: $black-87-opacity, + A700: $white-87-opacity, + ) + ); + // Define the palettes for your theme using the Material Design palettes available in palette.scss // (imported above). For each palette, you can optionally specify a default, lighter, and darker // hue. -$primary: mat-palette($mat-orange, 800); -$accent: mat-palette($mat-light-blue, 600, A100, A400); +$primary: mat-palette($mat-blue-grey, 900); +$accent: mat-palette($mat-orange-custom, A700, A100, A400); // The warn palette is optional (defaults to red). $warn: mat-palette($mat-red, 600); @@ -28,6 +61,36 @@ $theme: mat-light-theme($primary, $accent, $warn); @include covalent-markdown-theme($theme); @include covalent-highlight-theme(); // OR @import '~highlight.js/styles/vs.css'; +// Alt theme +.theme-alt { + $primary-alt: mat-palette($mat-orange, 800); + $accent-alt: mat-palette($mat-light-blue, 700); + $warn-alt: mat-palette($mat-red, 600); + $theme-alt: mat-light-theme($primary-alt, $accent-alt, $warn-alt); + @include angular-material-theme($theme-alt); + @include covalent-theme($theme-alt); +} + +// Dark theme +.theme-dark { + $primary-dark: mat-palette($mat-blue-grey, 900); + $accent-dark: mat-palette($mat-deep-orange, A400); + $warn-dark: mat-palette($mat-red, 600); + $theme-dark: mat-dark-theme($primary-dark, $accent-dark, $warn-dark); + @include angular-material-theme($theme-dark); + @include covalent-theme($theme-dark); +} + +// Subpage themes +.theme-docs { + $primary-docs: mat-palette($mat-deep-purple, 700); + $accent-docs: mat-palette($mat-cyan, A400); + $warn-docs: mat-palette($mat-red, 600); + $theme-docs: mat-light-theme($primary-docs, $accent-docs, $warn-docs); + @include angular-material-theme($theme-docs); + @include covalent-theme($theme-docs); +} + // Custom theme examples .blue-orange { $primary2: mat-palette($mat-blue, 700); @@ -86,3 +149,23 @@ md-nav-list { .legend-title-text { color: mat-color($foreground, secondary-text); } + +// Expansion panels +.theme-dark td-expansion-panel { + background-color: mat-color($mat-blue-grey, 800); +} + +// Active top nav +nav { + a { + line-height: 4; + display: block; + &:not(.active) { + color: rgba(255, 255, 255, 0.56); + } + &.active { + color: mat-color($accent); + border-bottom: 1px solid mat-color($accent); + } + } +} \ No newline at end of file From dda5d9cc3c5fe5728b9b9b27f8a6afa95f969861 Mon Sep 17 00:00:00 2001 From: Kyle Ledbetter Date: Tue, 6 Jun 2017 13:04:46 -0500 Subject: [PATCH 20/35] fix(card-images): sm/md/lg card images in title-group (closes #575) (#653) * fix(card-images): md-card-sm-image, md-card-md-image, md-card-lg-image, md-card-title-group (closes #575) - also included RTL/LTR proper border-radius on images * fix(card): add fix for last card-actions element in an md-card * fix(): set a card img in style guide that is not squished --- .../style-guide/cards/cards.component.html | 124 +++++++++++++++++- .../style-guide/style-guide.module.ts | 5 +- src/platform/core/common/styles/_card.scss | 72 +++++++++- .../core/common/styles/_variables.scss | 1 + 4 files changed, 194 insertions(+), 8 deletions(-) diff --git a/src/app/components/style-guide/cards/cards.component.html b/src/app/components/style-guide/cards/cards.component.html index 68d2ced694..746d9a9ec6 100644 --- a/src/app/components/style-guide/cards/cards.component.html +++ b/src/app/components/style-guide/cards/cards.component.html @@ -300,8 +300,8 @@

Item { {i} }

- Card with header & images - A card with header, avatar & image + Card with various components + A card with header, images, action icons & progress bar
@@ -311,11 +311,23 @@

Item { {i} }

Header title Header subtitle - +

Content title

Here is some more content

+ + +
+ + + + +
+
+ + +
@@ -326,16 +338,115 @@

Content title

Header title Header subtitle - +

Content title

Here is some more content

+ + +
+ + + + +
+
+ + +
]]> + + Card with image variations + md-card-sm-image, md-card-md-image, md-card-lg-image & md-card-title-group + + +
+
+ + + Card with image first + 100% width image + + Notice if the image is first it has proper rounded corners. + + +
+
+ + + Card with small image + 80px x 80px image + + + +
+
+ + + Card with medium image + 112px x 112px image + + + +
+
+ + + Card with large image + 152px x 152px image + + + +
+
+ + + + + Card with image first + 100% width image + + Notice if the image is first it has proper rounded corners. + + +
+
+ + + Card with small image + 80px x 80px image + + + +
+
+ + + Card with medium image + 112px x 112px image + + + +
+
+ + + Card with large image + 152px x 152px image + + + +
+ ]]> + +
+
Resources @@ -345,6 +456,11 @@

Content title

Card Specs + + launch + Angular Material Card Docs + + launch Google Now Cards diff --git a/src/app/components/style-guide/style-guide.module.ts b/src/app/components/style-guide/style-guide.module.ts index c5eaf54c7a..cebfb6b541 100644 --- a/src/app/components/style-guide/style-guide.module.ts +++ b/src/app/components/style-guide/style-guide.module.ts @@ -18,7 +18,8 @@ import { ResourcesComponent } from './resources/resources.component'; import { NavigationDrawerComponent } from './navigation-drawer/navigation-drawer.component'; import { MdButtonModule, MdListModule, MdIconModule, MdCardModule, MdToolbarModule, MdCoreModule, MdSnackBarModule, - MdInputModule, MdMenuModule, MdSelectModule, MdGridListModule, MdTabsModule, MdSidenavModule } from '@angular/material'; + MdInputModule, MdMenuModule, MdSelectModule, MdGridListModule, MdTabsModule, MdSidenavModule, + MdTooltipModule, MdProgressBarModule } from '@angular/material'; import { CovalentLayoutModule, CovalentMediaModule, CovalentSearchModule, CovalentPagingModule, CovalentExpansionPanelModule, CovalentDialogsModule } from '../../../platform/core'; @@ -59,6 +60,8 @@ import { ToolbarModule } from '../../components/toolbar/toolbar.module'; MdTabsModule, MdSidenavModule, MdSnackBarModule, + MdTooltipModule, + MdProgressBarModule, /** Covalent Modules */ CovalentLayoutModule, CovalentMediaModule, diff --git a/src/platform/core/common/styles/_card.scss b/src/platform/core/common/styles/_card.scss index 9154b25103..7f10bdd802 100644 --- a/src/platform/core/common/styles/_card.scss +++ b/src/platform/core/common/styles/_card.scss @@ -1,6 +1,6 @@ @import 'variables'; -body { +html { .mat-card { padding: 0; margin: 8px; @@ -15,8 +15,14 @@ body { margin: 16px 0 0 15px; border-radius: 50%; } - [md-card-image] { + .mat-card-image { width: 100%; + } + .mat-card-image, + .mat-card-lg-image, + .mat-card-md-image, + .mat-card-sm-image, + .mat-card-title-group { margin: 0; } md-card-title { @@ -32,10 +38,70 @@ body { padding: $padding; } &, & .mat-card { - & .mat-card-actions:last-child { + & .mat-card-actions { padding: $padding / 2; margin: 0; } } + .mat-card-actions:last-child { + margin-bottom: 0px; + padding-bottom: 8px; + } + } + &:not([dir='rtl']) { + .mat-card-title-group { + .mat-card-image, + .mat-card-lg-image, + .mat-card-md-image, + .mat-card-sm-image { + &:last-child { + border-top-right-radius: $md-card-radius; + border-bottom-right-radius: $md-card-radius; + } + } + } + .mat-card { + .mat-card-image { + &:first-child { + border-top-left-radius: $md-card-radius; + border-top-right-radius: $md-card-radius; + } + } + .mat-card-lg-image, + .mat-card-md-image, + .mat-card-sm-image { + &:first-child { + border-top-left-radius: $md-card-radius; + } + } + } + } + &[dir='rtl'] { + .mat-card-title-group { + .mat-card-image, + .mat-card-lg-image, + .mat-card-md-image, + .mat-card-sm-image { + &:last-child { + border-top-left-radius: $md-card-radius; + border-bottom-left-radius: $md-card-radius; + } + } + } + .mat-card { + .mat-card-image { + &:first-child { + border-top-left-radius: $md-card-radius; + border-top-right-radius: $md-card-radius; + } + } + .mat-card-lg-image, + .mat-card-md-image, + .mat-card-sm-image { + &:first-child { + border-top-right-radius: $md-card-radius; + } + } + } } } diff --git a/src/platform/core/common/styles/_variables.scss b/src/platform/core/common/styles/_variables.scss index 6bc0580026..fef76e571c 100644 --- a/src/platform/core/common/styles/_variables.scss +++ b/src/platform/core/common/styles/_variables.scss @@ -39,6 +39,7 @@ $app-bar-height: 64px; // card header variables $md-card-header-size: 40px; +$md-card-radius: 2px; // Icons $icon-size: rem(2.4); From 9ae0ba532bbabde6eca8d1b4315667333e83ae35 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 7 Jun 2017 13:38:17 -0700 Subject: [PATCH 21/35] feat(expansion-panel): introducing expansion-panel-group to only give margin to expansion panels when grouped (#666) * feat(expansion): introducing expansion-panel-group this will give spec marging to grouped expansion panels following the spec * chore(expansion): update DEMO with group example * fix(): only add transition when grouped and change to 120ms --- .../expansion-panel.component.html | 55 +++++++++++++++ src/platform/core/expansion-panel/README.md | 21 ++++++ .../_expansion-panel-theme.scss | 28 +++++--- .../expansion-panel-group.component.html | 1 + .../expansion-panel-group.component.scss | 0 .../expansion-panel-group.component.ts | 15 +++++ .../expansion-panel.component.html | 67 +++++++++---------- .../expansion-panel.component.scss | 31 ++++----- .../expansion-panel.component.ts | 10 ++- .../expansion-panel/expansion-panel.module.ts | 3 + 10 files changed, 167 insertions(+), 64 deletions(-) create mode 100644 src/platform/core/expansion-panel/expansion-panel-group.component.html create mode 100644 src/platform/core/expansion-panel/expansion-panel-group.component.scss create mode 100644 src/platform/core/expansion-panel/expansion-panel-group.component.ts diff --git a/src/app/components/components/expansion-panel/expansion-panel.component.html b/src/app/components/components/expansion-panel/expansion-panel.component.html index 25348b1f61..a0a18b90bb 100644 --- a/src/app/components/components/expansion-panel/expansion-panel.component.html +++ b/src/app/components/components/expansion-panel/expansion-panel.component.html @@ -71,6 +71,61 @@

md-padding class

+ + Grouped Expansion panels + Add margin animation between grouped expansion panels + + + + Demo + + +
+

md-padding class

+
+
+ +
+

md-padding class

+
+
+ +
+

md-padding class

+
+
+
+
+ + Code + +

HTML:

+ + + +
+

md-padding class

+
+
+ +
+

md-padding class

+
+
+ +
+

md-padding class

+
+
+ + ]]> +
+
+
+
+
+ Expansion panel with summary and templates Expand to view form, collapse to view summary diff --git a/src/platform/core/expansion-panel/README.md b/src/platform/core/expansion-panel/README.md index c491b6ec4f..62ad04b9a1 100644 --- a/src/platform/core/expansion-panel/README.md +++ b/src/platform/core/expansion-panel/README.md @@ -56,3 +56,24 @@ Example for HTML usage: ... add content that ``` + +# td-expansion-panel-group + +`td-expansion-panel-group` is used to group expansion panel components. + +It adds margin between them when expanded following the material spec. + +## Usage + +Example for HTML usage: + +```html + + + ..content + + + ..content + + +``` diff --git a/src/platform/core/expansion-panel/_expansion-panel-theme.scss b/src/platform/core/expansion-panel/_expansion-panel-theme.scss index 3ef2787967..609fd88fac 100644 --- a/src/platform/core/expansion-panel/_expansion-panel-theme.scss +++ b/src/platform/core/expansion-panel/_expansion-panel-theme.scss @@ -7,20 +7,26 @@ $warn: map-get($theme, warn); $foreground: map-get($theme, foreground); $background: map-get($theme, background); - // panel - td-expansion-panel { - @include mat-elevation(1); - background-color: mat-color($background, card); - &:not(:last-of-type) { - & .td-expanded { - margin-bottom: $margin; + + .td-expansion-panel-group { + .td-expansion-panel { + transition: 120ms ease-in; + &:not(:last-of-type) { + &.td-expanded { + margin-bottom: $margin; + } } - } - &:not(:first-of-type) { - & .td-expanded { - margin-top: $margin; + &:not(:first-of-type) { + &.td-expanded { + margin-top: $margin; + } } } + } + + .td-expansion-panel { + @include mat-elevation(1); + background-color: mat-color($background, card); .td-expansion-panel-header { &:focus, &:hover { diff --git a/src/platform/core/expansion-panel/expansion-panel-group.component.html b/src/platform/core/expansion-panel/expansion-panel-group.component.html new file mode 100644 index 0000000000..95a0b70bdc --- /dev/null +++ b/src/platform/core/expansion-panel/expansion-panel-group.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/platform/core/expansion-panel/expansion-panel-group.component.scss b/src/platform/core/expansion-panel/expansion-panel-group.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/platform/core/expansion-panel/expansion-panel-group.component.ts b/src/platform/core/expansion-panel/expansion-panel-group.component.ts new file mode 100644 index 0000000000..fbef2d651d --- /dev/null +++ b/src/platform/core/expansion-panel/expansion-panel-group.component.ts @@ -0,0 +1,15 @@ +import { Component, Renderer2, ElementRef } from '@angular/core'; + +@Component({ + selector: 'td-expansion-panel-group', + styleUrls: ['./expansion-panel-group.component.scss' ], + templateUrl: './expansion-panel-group.component.html', +}) +export class TdExpansionPanelGroupComponent { + + constructor(private _renderer: Renderer2, + private _elementRef: ElementRef) { + this._renderer.addClass(this._elementRef.nativeElement, 'td-expansion-panel-group'); + } + +} diff --git a/src/platform/core/expansion-panel/expansion-panel.component.html b/src/platform/core/expansion-panel/expansion-panel.component.html index b3ee929ec7..20d0f27f31 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.html +++ b/src/platform/core/expansion-panel/expansion-panel.component.html @@ -1,38 +1,35 @@ -
-
+ +
- -
-
- - {{label}} -
-
- - {{sublabel}} -
- - keyboard_arrow_down - keyboard_arrow_up + *ngIf="!expansionPanelHeader" + layout="row" + layout-align="start center" + flex> +
+ + {{label}}
+
+ + {{sublabel}} +
+ + keyboard_arrow_down + keyboard_arrow_up
-
- -
-
- -
-
\ No newline at end of file +
+
+ +
+
+ +
diff --git a/src/platform/core/expansion-panel/expansion-panel.component.scss b/src/platform/core/expansion-panel/expansion-panel.component.scss index 010de28b91..5393cb8db7 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.scss +++ b/src/platform/core/expansion-panel/expansion-panel.component.scss @@ -1,22 +1,19 @@ :host { display: block; - .td-expansion-panel { - transition: 400ms all ease; - .td-expansion-panel-header { - position: relative; - outline: none; - &:focus, - &:hover { - cursor: pointer; - } - &.mat-disabled { - background: none; - cursor: auto; - } - .td-expansion-panel-header-content { - height: 48px; - padding: 0 16px; - } + .td-expansion-panel-header { + position: relative; + outline: none; + &:focus, + &:hover { + cursor: pointer; + } + &.mat-disabled { + background: none; + cursor: auto; + } + .td-expansion-panel-header-content { + height: 48px; + padding: 0 16px; } } } diff --git a/src/platform/core/expansion-panel/expansion-panel.component.ts b/src/platform/core/expansion-panel/expansion-panel.component.ts index a28b7ab951..d1d6b515ca 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.ts +++ b/src/platform/core/expansion-panel/expansion-panel.component.ts @@ -1,4 +1,5 @@ -import { Component, Directive, Input, Output, TemplateRef, ViewContainerRef, ContentChild } from '@angular/core'; +import { Component, Directive, Input, Output, TemplateRef, ViewContainerRef, ContentChild, + ElementRef, Renderer2 } from '@angular/core'; import { EventEmitter } from '@angular/core'; import { TemplatePortalDirective } from '@angular/material'; @@ -107,6 +108,11 @@ export class TdExpansionPanelComponent { */ @Output() collapsed: EventEmitter = new EventEmitter(); + constructor(private _renderer: Renderer2, + private _elementRef: ElementRef) { + this._renderer.addClass(this._elementRef.nativeElement, 'td-expansion-panel'); + } + /** * Method executed when [TdExpansionPanelComponent] is clicked. */ @@ -149,8 +155,10 @@ export class TdExpansionPanelComponent { if (this._expand !== newExpand) { this._expand = newExpand; if (newExpand) { + this._renderer.addClass(this._elementRef.nativeElement, 'td-expanded'); this._onExpanded(); } else { + this._renderer.removeClass(this._elementRef.nativeElement, 'td-expanded'); this._onCollapsed(); } return true; diff --git a/src/platform/core/expansion-panel/expansion-panel.module.ts b/src/platform/core/expansion-panel/expansion-panel.module.ts index 508675cffe..a3713c3445 100644 --- a/src/platform/core/expansion-panel/expansion-panel.module.ts +++ b/src/platform/core/expansion-panel/expansion-panel.module.ts @@ -6,8 +6,10 @@ import { MdRippleModule, MdIconModule, PortalModule } from '@angular/material'; import { TdExpansionPanelComponent, TdExpansionPanelHeaderDirective, TdExpansionPanelLabelDirective, TdExpansionPanelSublabelDirective, TdExpansionPanelSummaryComponent } from './expansion-panel.component'; +import { TdExpansionPanelGroupComponent } from './expansion-panel-group.component'; const TD_EXPANSION_PANEL: Type[] = [ + TdExpansionPanelGroupComponent, TdExpansionPanelComponent, TdExpansionPanelHeaderDirective, TdExpansionPanelLabelDirective, @@ -16,6 +18,7 @@ const TD_EXPANSION_PANEL: Type[] = [ ]; export { TdExpansionPanelComponent } from './expansion-panel.component'; +export { TdExpansionPanelGroupComponent } from './expansion-panel-group.component'; @NgModule({ imports: [ From 33810ce86915c6d1e948e426a6056500d88e6827 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 7 Jun 2017 14:23:23 -0700 Subject: [PATCH 22/35] feat(expansion-panel) and (steps): add `[disableRipple]` input. (#665) * feat(expansion-panel): add [disableRipple] input * feat(steps): add [disableRipple] input * fix(): lint error and hover on disable introduced bug * fix(expansion): polish scss rules when not disabled * fix(): move disabledRipple to the correct step in example --- .../expansion-panel.component.html | 6 +++--- .../components/steps/steps.component.html | 6 +++--- .../components/steps/steps.component.ts | 4 ++++ src/platform/core/expansion-panel/README.md | 3 ++- .../expansion-panel/_expansion-panel-theme.scss | 4 ++-- .../expansion-panel.component.html | 2 +- .../expansion-panel.component.scss | 8 ++------ .../expansion-panel/expansion-panel.component.ts | 15 ++++++++++++++- src/platform/core/steps/_steps-theme.scss | 4 ++-- .../steps/step-header/step-header.component.html | 2 +- .../steps/step-header/step-header.component.scss | 7 +------ .../steps/step-header/step-header.component.ts | 6 ++++++ src/platform/core/steps/step.component.ts | 15 ++++++++++++++- src/platform/core/steps/steps.component.html | 6 ++++-- 14 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/app/components/components/expansion-panel/expansion-panel.component.html b/src/app/components/components/expansion-panel/expansion-panel.component.html index a0a18b90bb..d7af2f304e 100644 --- a/src/app/components/components/expansion-panel/expansion-panel.component.html +++ b/src/app/components/components/expansion-panel/expansion-panel.component.html @@ -217,12 +217,12 @@

Headquarters

Expansion panel with header template - replace the entire header as needed + replace the entire header as needed and disable ripple Demo - + Custom td-expansion-panel-header @@ -270,7 +270,7 @@

1141e8e8-8d24-4956-93c2

HTML:

+ Custom td-expansion-panel-header diff --git a/src/app/components/components/steps/steps.component.html b/src/app/components/components/steps/steps.component.html index fdf1ea6571..5dfb34fc82 100644 --- a/src/app/components/components/steps/steps.component.html +++ b/src/app/components/components/steps/steps.component.html @@ -21,7 +21,7 @@

{{horizontal ? 'Horizontal Mode' : 'Vertical Mode'}}

Basic Usage (template) Include any content you like for an active stepper - + This step is required! @@ -50,7 +50,7 @@

{{horizontal ? 'Horizontal Mode' : 'Vertical Mode'}}

Basic Usage (template) Include any content you like for an active stepper
- + This step is required! @@ -195,7 +195,7 @@

Example:

HTML:

+ ... add label content (if not used, falls back to [label] input) diff --git a/src/app/components/components/steps/steps.component.ts b/src/app/components/components/steps/steps.component.ts index 6f5f806893..f1b9328b8b 100644 --- a/src/app/components/components/steps/steps.component.ts +++ b/src/app/components/components/steps/steps.component.ts @@ -46,6 +46,10 @@ export class StepsDemoComponent implements OnInit, OnDestroy { description: 'Sets state of [TdStepComponent] depending on value. Defaults to [StepState.None | "none"]', name: 'state?', type: 'StepState or ["none" | "required" | "complete"]', + }, { + description: ' Whether the ripple effect for this component is disabled', + name: 'disableRipple?', + type: 'boolean', }, { description: 'Event emitted when [TdStepComponent] is activated.', name: 'activated?', diff --git a/src/platform/core/expansion-panel/README.md b/src/platform/core/expansion-panel/README.md index 62ad04b9a1..de50729009 100644 --- a/src/platform/core/expansion-panel/README.md +++ b/src/platform/core/expansion-panel/README.md @@ -13,6 +13,7 @@ Properties: | `label?` | `string` | Sets label of component header. | `sublabel?` | `string` | Sets sublabel of component header. | `expand?` | `boolean` | Toggles component between expand/collapse state. +| `disableRipple?` | `boolean` | Whether the ripple effect for this component is disabled. | `expanded?` | `function` | Event emitted when component is expanded. | `collapsed?` | `function` | Event emitted when component is collapsed. | `toggle?` | `function` | Toggle state of component. Returns "true" if successful, else "false". @@ -40,7 +41,7 @@ export class MyModule {} Example for HTML usage: ```html - + ... add header content (overrides label and sublabel) diff --git a/src/platform/core/expansion-panel/_expansion-panel-theme.scss b/src/platform/core/expansion-panel/_expansion-panel-theme.scss index 609fd88fac..057baa4c9f 100644 --- a/src/platform/core/expansion-panel/_expansion-panel-theme.scss +++ b/src/platform/core/expansion-panel/_expansion-panel-theme.scss @@ -28,8 +28,8 @@ @include mat-elevation(1); background-color: mat-color($background, card); .td-expansion-panel-header { - &:focus, - &:hover { + &:focus:not(.mat-disabled), + &:hover:not(.mat-disabled) { background: mat-color($background, 'hover'); } .td-expansion-panel-header-content { diff --git a/src/platform/core/expansion-panel/expansion-panel.component.html b/src/platform/core/expansion-panel/expansion-panel.component.html index 20d0f27f31..6d48433d0b 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.html +++ b/src/platform/core/expansion-panel/expansion-panel.component.html @@ -1,7 +1,7 @@
diff --git a/src/platform/core/expansion-panel/expansion-panel.component.scss b/src/platform/core/expansion-panel/expansion-panel.component.scss index 5393cb8db7..717659b151 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.scss +++ b/src/platform/core/expansion-panel/expansion-panel.component.scss @@ -3,14 +3,10 @@ .td-expansion-panel-header { position: relative; outline: none; - &:focus, - &:hover { + &:focus:not(.mat-disabled), + &:hover:not(.mat-disabled) { cursor: pointer; } - &.mat-disabled { - background: none; - cursor: auto; - } .td-expansion-panel-header-content { height: 48px; padding: 0 16px; diff --git a/src/platform/core/expansion-panel/expansion-panel.component.ts b/src/platform/core/expansion-panel/expansion-panel.component.ts index d1d6b515ca..ef91ea6c18 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.ts +++ b/src/platform/core/expansion-panel/expansion-panel.component.ts @@ -48,6 +48,7 @@ export class TdExpansionPanelSummaryComponent {} }) export class TdExpansionPanelComponent { + private _disableRipple: boolean = false; private _expand: boolean = false; private _disabled: boolean = false; @@ -68,13 +69,25 @@ export class TdExpansionPanelComponent { */ @Input() sublabel: string; + /** + * disableRipple?: string + * Whether the ripple effect for this component is disabled. + */ + @Input('disableRipple') + set disableRipple(disableRipple: boolean) { + this._disableRipple = disableRipple !== '' ? (disableRipple === 'true' || disableRipple === true) : true; + } + get disableRipple(): boolean { + return this._disableRipple; + } + /** * expand?: boolean * Toggles [TdExpansionPanelComponent] between expand/collapse. */ @Input('expand') set expand(expand: boolean) { - this._setExpand(expand); + this._setExpand(expand === 'true' || expand === true); } get expand(): boolean { return this._expand; diff --git a/src/platform/core/steps/_steps-theme.scss b/src/platform/core/steps/_steps-theme.scss index ac94c3c10b..34a1a953d4 100644 --- a/src/platform/core/steps/_steps-theme.scss +++ b/src/platform/core/steps/_steps-theme.scss @@ -25,8 +25,8 @@ } // header .td-step-header { - &:focus, - &:hover { + &:focus:not(.mat-disabled), + &:hover:not(.mat-disabled) { background: mat-color($background, 'hover'); } .td-step-label-wrapper { diff --git a/src/platform/core/steps/step-header/step-header.component.html b/src/platform/core/steps/step-header/step-header.component.html index 862019924a..b08bbcdbbf 100644 --- a/src/platform/core/steps/step-header/step-header.component.html +++ b/src/platform/core/steps/step-header/step-header.component.html @@ -1,7 +1,7 @@
disableRipple !== '' ? (disableRipple === 'true' || disableRipple === true) : true; + } + get disableRipple(): boolean { + return this._disableRipple; + } + /** * active?: boolean * Toggles [TdStepComponent] between active/deactive. */ @Input('active') set active(active: boolean) { - this._setActive(active); + this._setActive(active === 'true' || active === true); } get active(): boolean { return this._active; diff --git a/src/platform/core/steps/steps.component.html b/src/platform/core/steps/steps.component.html index 1ba2e40f14..26f72228a1 100644 --- a/src/platform/core/steps/steps.component.html +++ b/src/platform/core/steps/steps.component.html @@ -3,7 +3,8 @@ @@ -19,7 +20,8 @@ (keydown.enter)="step.toggle()" [number]="index + 1" [active]="step.active" - [disabled]="step.disabled" + [disabled]="step.disabled" + [disableRipple]="step.disableRipple" [state]="step.state" (click)="step.toggle()" *ngIf="isVertical()"> From bb9331b3dffb93c4e96281c8d9469fa8f12e52e3 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 7 Jun 2017 16:52:40 -0700 Subject: [PATCH 23/35] fix(steps): change internal class to mat-inactive (#669) --- src/platform/core/steps/_steps-theme.scss | 2 +- src/platform/core/steps/step-header/step-header.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/core/steps/_steps-theme.scss b/src/platform/core/steps/_steps-theme.scss index 34a1a953d4..6f4213286b 100644 --- a/src/platform/core/steps/_steps-theme.scss +++ b/src/platform/core/steps/_steps-theme.scss @@ -33,7 +33,7 @@ .md-caption { color: mat-color($foreground, secondary-text); } - &.mat-disabled { + &.mat-inactive { &, & * { color: mat-color($foreground, disabled); } diff --git a/src/platform/core/steps/step-header/step-header.component.html b/src/platform/core/steps/step-header/step-header.component.html index b08bbcdbbf..2117c23096 100644 --- a/src/platform/core/steps/step-header/step-header.component.html +++ b/src/platform/core/steps/step-header/step-header.component.html @@ -23,7 +23,7 @@ warning
From e9427aaee1520a83326cd242850b525915b7c5fe Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 7 Jun 2017 16:53:07 -0700 Subject: [PATCH 24/35] feat(dialog): improve prompt a11y by selection text in input when focused (#664) --- .../prompt-dialog.component.html | 2 ++ .../prompt-dialog/prompt-dialog.component.ts | 21 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.html b/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.html index 49e9c882c0..e82899552d 100644 --- a/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.html +++ b/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.html @@ -7,6 +7,8 @@
) {} + ngAfterViewInit(): void { + // focus input once everything is rendered and good to go + Promise.resolve().then(() => { + (this._input.nativeElement).focus(); + }); + } + + /** + * Method executed when input is focused + * Selects all text + */ + handleInputFocus(event: FocusEvent): void { + (this._input.nativeElement).select(); + } + cancel(): void { this._dialogRef.close(undefined); } From 7874b5b7a371aeffe9d9d239e910ab31c3a79399 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Wed, 7 Jun 2017 17:32:57 -0700 Subject: [PATCH 25/35] fix(rtl-demo): fix rtl/lrt demo in docs (#663) * fix(rtl-demo): fix rtl/lrt demo in docs there were issues when navigation between views or when using the td-layout.. state was lost and sidenavs were not working as intended. * fix(): responsive titles in docs, style-guide and components * fix(): set template route before the chunks so they arent loaded when not needed this still will happen when trying to access any other chunk though.. for some reason they load anything before them. * fix(): issue when refreshing docs in rtl --- src/app/app.component.html | 1 + src/app/app.component.ts | 9 ++++++++- src/app/app.routes.ts | 6 ++++-- .../components/components.component.html | 5 ++--- src/app/components/docs/docs.component.html | 5 ++--- .../manage-list/manage-list.component.html | 4 ++-- .../layouts/nav-list/nav-list.component.html | 3 +-- .../style-guide/style-guide.component.html | 5 ++--- .../templates/templates.component.html | 4 ++-- .../components/toolbar/toolbar.component.ts | 20 ++++++++++++++----- src/app/utilities/direction.ts | 20 +++++++++++++++++++ 11 files changed, 59 insertions(+), 23 deletions(-) create mode 100644 src/app/utilities/direction.ts diff --git a/src/app/app.component.html b/src/app/app.component.html index bf30e56acd..6657080123 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,4 +1,5 @@ diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7d9e52cf30..b50b568355 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,10 +1,11 @@ import { Component, AfterViewInit, ChangeDetectorRef } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; -import { MdIconRegistry } from '@angular/material'; +import { MdIconRegistry, Dir } from '@angular/material'; import { TdMediaService } from '@covalent/core'; import { TranslateService } from '@ngx-translate/core'; import { getSelectedLanguage } from './utilities/translate'; +import { getDirection } from './utilities/direction'; @Component({ selector: 'docs-covalent', @@ -36,6 +37,8 @@ export class DocsAppComponent implements AfterViewInit { }, ]; + dir: string; + constructor(private _iconRegistry: MdIconRegistry, private _domSanitizer: DomSanitizer, private _changeDetectorRef: ChangeDetectorRef, @@ -74,10 +77,14 @@ export class DocsAppComponent implements AfterViewInit { this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/listener.svg')); this._iconRegistry.addSvgIconInNamespace('assets', 'querygrid', this._domSanitizer.bypassSecurityTrustResourceUrl('app/assets/icons/querygrid.svg')); + + // set direction + this.dir = getDirection(); } ngAfterViewInit(): void { this.media.broadcast(); this._changeDetectorRef.detectChanges(); } + } diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 446b1c0fa8..292f3c02d2 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -6,6 +6,9 @@ import { TemplatesComponent } from './components/templates/templates.component'; const routes: Routes = [{ component: HomeComponent, path: '', + }, { + component: TemplatesComponent, + path: 'templates', }, { path: '', loadChildren: './components/docs/docs.module#DocsModule', }, { @@ -15,8 +18,7 @@ const routes: Routes = [{ }, { path: '', loadChildren: './components/components/components.module#ComponentsModule', }, { - component: TemplatesComponent, - path: 'templates', + path: '**', redirectTo: '/', }, ]; diff --git a/src/app/components/components/components.component.html b/src/app/components/components/components.component.html index f6f3e97cae..9a82dfca25 100644 --- a/src/app/components/components/components.component.html +++ b/src/app/components/components/components.component.html @@ -1,5 +1,4 @@ {{item.title}}
- Components & Addons - + Components & Addons +
diff --git a/src/app/components/docs/docs.component.html b/src/app/components/docs/docs.component.html index 3e099197bb..96f22fb1a2 100644 --- a/src/app/components/docs/docs.component.html +++ b/src/app/components/docs/docs.component.html @@ -1,5 +1,4 @@ {{item.title}}
- Documentation - + Documentation +
diff --git a/src/app/components/layouts/manage-list/manage-list.component.html b/src/app/components/layouts/manage-list/manage-list.component.html index ff1f08217a..f4d246648d 100644 --- a/src/app/components/layouts/manage-list/manage-list.component.html +++ b/src/app/components/layouts/manage-list/manage-list.component.html @@ -1,5 +1,5 @@ - - + + Item Name
Nav List - +
Nav List Layout diff --git a/src/app/components/style-guide/style-guide.component.html b/src/app/components/style-guide/style-guide.component.html index 685afc6b0e..048ad80ce9 100644 --- a/src/app/components/style-guide/style-guide.component.html +++ b/src/app/components/style-guide/style-guide.component.html @@ -1,5 +1,4 @@ {{item.title}}
- Style Guide - + Style Guide +
diff --git a/src/app/components/templates/templates.component.html b/src/app/components/templates/templates.component.html index 298ebc0cc4..f5c4fa8d49 100644 --- a/src/app/components/templates/templates.component.html +++ b/src/app/components/templates/templates.component.html @@ -1,5 +1,5 @@ - - + +
diff --git a/src/app/components/toolbar/toolbar.component.ts b/src/app/components/toolbar/toolbar.component.ts index 19c90a3fe0..e09279c47b 100644 --- a/src/app/components/toolbar/toolbar.component.ts +++ b/src/app/components/toolbar/toolbar.component.ts @@ -6,6 +6,10 @@ import { Component, ElementRef, Inject, Renderer2, Output, EventEmitter } from '@angular/core'; import { DOCUMENT } from '@angular/platform-browser'; +import { Dir } from '@angular/material'; + +import { getDirection, setDirection } from '../../utilities/direction'; + @Component({ selector: 'td-toolbar', templateUrl: '././toolbar.component.html', @@ -69,12 +73,18 @@ export class ToolbarComponent { title: 'Layouts feature', }, ]; - dir: string = 'ltr'; - @Output('changeDir') onChangeDir: EventEmitter = new EventEmitter(); + + dir: 'ltr' | 'rtl' = getDirection(); + constructor(private _renderer: Renderer2, - @Inject(DOCUMENT) private _document: any) {} - changeDir(dir: string): void { + private _dir: Dir, + @Inject(DOCUMENT) private _document: any) { + this._dir.dir = this.dir; + } + + changeDir(dir: 'ltr' | 'rtl'): void { this._renderer.setAttribute(this._document.querySelector('html'), 'dir', dir); - this.onChangeDir.emit(this.dir); + this._dir.dir = dir; + setDirection(dir); } } diff --git a/src/app/utilities/direction.ts b/src/app/utilities/direction.ts new file mode 100644 index 0000000000..706e7ee6f9 --- /dev/null +++ b/src/app/utilities/direction.ts @@ -0,0 +1,20 @@ +export const DIRECTION_STORAGE_KEY: string = 'app-direction'; + +/** + * Utility method to get selected direction from sessionStorage + */ +export function getDirection(): 'ltr' | 'rtl' { + let storedDirection: 'ltr' | 'rtl' = sessionStorage.getItem(DIRECTION_STORAGE_KEY); + // Check if the direction was stored + if (storedDirection) { + return storedDirection; + } + return 'ltr'; +} + +/** + * Utility method to set selected direction to sessionStorage + */ +export function setDirection(direction: 'ltr' | 'rtl'): void { + sessionStorage.setItem(DIRECTION_STORAGE_KEY, direction); +} From 3f86bcec7977404fe206970158064de1b179d78a Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Thu, 8 Jun 2017 11:33:02 -0700 Subject: [PATCH 26/35] fix(): aot build break with prompt commit (#676) --- .../core/dialogs/prompt-dialog/prompt-dialog.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.ts b/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.ts index 65b97a341b..e18e1d2de5 100644 --- a/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.ts +++ b/src/platform/core/dialogs/prompt-dialog/prompt-dialog.component.ts @@ -28,7 +28,7 @@ export class TdPromptDialogComponent implements AfterViewInit { * Method executed when input is focused * Selects all text */ - handleInputFocus(event: FocusEvent): void { + handleInputFocus(): void { (this._input.nativeElement).select(); } From fe9daccb5fd436a3ca527d4e694cc2e02e26f79d Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Thu, 8 Jun 2017 13:26:10 -0700 Subject: [PATCH 27/35] feat(chips): leverage `td-chip` for all cases introducing `td-chip-avatar` (#672) * feat(chips): leverage td-chip for all cases introducing td-chip-avatar directive now we can use normal chip strings, template chips and contact chips by mixin and matching our templates and directives * fix(): unit tests * fix(): demo example * fix(): make sure td-chip-avatar is always the first item on the template --- .../components/chips/chips.component.html | 12 +++++++++--- src/platform/core/chips/README.md | 6 ++++-- src/platform/core/chips/chips.component.html | 8 ++++---- src/platform/core/chips/chips.component.scss | 15 +++++++++++++-- src/platform/core/chips/chips.component.spec.ts | 2 +- src/platform/core/chips/chips.component.ts | 6 +++--- src/platform/core/chips/chips.module.ts | 8 ++++---- 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/app/components/components/chips/chips.component.html b/src/app/components/components/chips/chips.component.html index a9b047f1df..4aac7c41b4 100644 --- a/src/app/components/components/chips/chips.component.html +++ b/src/app/components/components/chips/chips.component.html @@ -118,7 +118,7 @@ placeholder="Enter autocomplete strings" (inputChange)="filterObjects($event)" requireMatch> - + location_city {{chip.city}}, (Pop: {{chip.population}}) @@ -141,7 +141,7 @@ placeholder="Enter autocomplete strings" (inputChange)="filterObjects($event)" requireMatch> - + location_city { {chip.city} }, (Pop: { {chip.population} }) @@ -191,7 +191,7 @@ - Chips & async Autocomplete + Chips & async Autocomplete with template chip avatar Load autocomplete items asynchronous when typing in the input @@ -205,6 +205,9 @@ placeholder="Enter autocomplete strings" (inputChange)="filterAsync($event)" requireMatch> + +
{{chip.substring(0, 1).toUpperCase()}}
{{chip}} +
@@ -221,6 +224,9 @@ placeholder="Enter autocomplete strings" (inputChange)="filterAsync($event)" requireMatch> + +
{ {chip.substring(0, 1).toUpperCase()} }
{ {chip} } +
]]> diff --git a/src/platform/core/chips/README.md b/src/platform/core/chips/README.md index 4a53ecf9b2..12206cde86 100644 --- a/src/platform/core/chips/README.md +++ b/src/platform/core/chips/README.md @@ -4,6 +4,8 @@ Add the [items] attribute to enable the autocomplete with a list, and [requireMatch] to not allow custom values. +Leverage the templates to create your own chip or contact chip. + ## API Summary Properties: @@ -55,8 +57,8 @@ Example for HTML usage: (inputChange)="inputChange($event)" requireMatch stacked> - - {{chip}} + +
A
{{chip}}
{{option}} diff --git a/src/platform/core/chips/chips.component.html b/src/platform/core/chips/chips.component.html index 901f2af191..0491a87736 100644 --- a/src/platform/core/chips/chips.component.html +++ b/src/platform/core/chips/chips.component.html @@ -6,11 +6,11 @@ (keydown)="_chipKeydown($event, index)" (focus)="setFocusedState()">
-
- {{chip}} +
+ {{chip}}
diff --git a/src/platform/core/chips/chips.component.scss b/src/platform/core/chips/chips.component.scss index 1731442220..23242095ae 100644 --- a/src/platform/core/chips/chips.component.scss +++ b/src/platform/core/chips/chips.component.scss @@ -25,10 +25,21 @@ cursor: default; border-radius: 16px; @include rtl(margin, 8px 8px 0 0, 8px 0 0 8px); - .td-basic-chip { - min-height: 30px; + .td-chip { + min-height: 32px; font-size: 14px; @include rtl(padding, 0 0 0 12px, 0 12px 0 0); + [td-chip-avatar] { + display: flex; + order: -20; + justify-content: center; + align-items: center; + height: 32px; + width: 32px; + flex-shrink: 0; + @include rtl(margin, 0 8px 0 -12px, 0 -12px 0 8px); + border-radius: 50%; + } } box-sizing: border-box; max-width: 100%; diff --git a/src/platform/core/chips/chips.component.spec.ts b/src/platform/core/chips/chips.component.spec.ts index 9a93681809..ca6be6759d 100644 --- a/src/platform/core/chips/chips.component.spec.ts +++ b/src/platform/core/chips/chips.component.spec.ts @@ -744,7 +744,7 @@ class TdChipsBasicTestComponent { @Component({ template: ` - + {{chip.name}} diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index f4ee383fb0..20694e9390 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -19,9 +19,9 @@ const noop: any = () => { }; @Directive({ - selector: '[td-basic-chip]ng-template', + selector: '[td-chip]ng-template', }) -export class TdBasicChipDirective extends TemplatePortalDirective { +export class TdChipDirective extends TemplatePortalDirective { constructor(templateRef: TemplateRef, viewContainerRef: ViewContainerRef) { super(templateRef, viewContainerRef); } @@ -76,7 +76,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, @ViewChild(MdAutocompleteTrigger) _autocompleteTrigger: MdAutocompleteTrigger; @ViewChildren(MdChip) _chipsChildren: QueryList; - @ContentChild(TdBasicChipDirective) _basicChipTemplate: TdBasicChipDirective; + @ContentChild(TdChipDirective) _chipTemplate: TdChipDirective; @ContentChild(TdAutocompleteOptionDirective) _autocompleteOptionTemplate: TdAutocompleteOptionDirective; @ViewChildren(MdOption) _options: QueryList; diff --git a/src/platform/core/chips/chips.module.ts b/src/platform/core/chips/chips.module.ts index 5dad8aa629..c22cf37545 100644 --- a/src/platform/core/chips/chips.module.ts +++ b/src/platform/core/chips/chips.module.ts @@ -5,8 +5,8 @@ import { CommonModule } from '@angular/common'; import { MdInputModule, MdIconModule, MdAutocompleteModule, MdChipsModule } from '@angular/material'; -import { TdChipsComponent, TdBasicChipDirective, TdAutocompleteOptionDirective } from './chips.component'; -export { TdChipsComponent, TdBasicChipDirective, TdAutocompleteOptionDirective } from './chips.component'; +import { TdChipsComponent, TdChipDirective, TdAutocompleteOptionDirective } from './chips.component'; +export { TdChipsComponent, TdChipDirective, TdAutocompleteOptionDirective } from './chips.component'; @NgModule({ imports: [ @@ -19,12 +19,12 @@ export { TdChipsComponent, TdBasicChipDirective, TdAutocompleteOptionDirective } ], declarations: [ TdChipsComponent, - TdBasicChipDirective, + TdChipDirective, TdAutocompleteOptionDirective, ], exports: [ TdChipsComponent, - TdBasicChipDirective, + TdChipDirective, TdAutocompleteOptionDirective, ], }) From 4243fca6c462c19f0d2e48140f15f70d6e0d880f Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Thu, 8 Jun 2017 15:14:10 -0700 Subject: [PATCH 28/35] fix(chips): call change detection when replacing the ngModel array this is needed when using OnPush since the chips arent rerendered --- src/platform/core/chips/chips.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/core/chips/chips.component.ts b/src/platform/core/chips/chips.component.ts index 20694e9390..b705e9a3a1 100644 --- a/src/platform/core/chips/chips.component.ts +++ b/src/platform/core/chips/chips.component.ts @@ -245,6 +245,7 @@ export class TdChipsComponent implements ControlValueAccessor, DoCheck, OnInit, if (v !== this._value) { this._value = v; this._length = this._value ? this._value.length : 0; + this._changeDetectorRef.markForCheck(); } } get value(): any { return this._value; } From e912ef4bed205d7da4743d83c45bce3edf150084 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Thu, 8 Jun 2017 17:41:07 -0700 Subject: [PATCH 29/35] feat(layout): add `color` input to `td-layout-footer` (#670) this input will be optional since by default the background is gray and can be overriden by using primary, accent or warn --- src/platform/core/layout/_layout-theme.scss | 21 +++++++++++++++ .../core/layout/layout-card-over/README.md | 6 ++--- .../layout-footer.component.html | 4 +-- .../layout-footer.component.scss | 2 -- .../layout-footer/layout-footer.component.ts | 26 ++++++++++++++++++- .../core/layout/layout-manage-list/README.md | 4 +-- .../core/layout/layout-nav-list/README.md | 4 +-- src/platform/core/layout/layout-nav/README.md | 4 +-- 8 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/platform/core/layout/_layout-theme.scss b/src/platform/core/layout/_layout-theme.scss index 6463f55a40..d70de3f6a2 100644 --- a/src/platform/core/layout/_layout-theme.scss +++ b/src/platform/core/layout/_layout-theme.scss @@ -2,6 +2,9 @@ @import '../common/styles/theme-functions'; @mixin td-layout-theme($theme) { + $primary: map-get($theme, primary); + $accent: map-get($theme, accent); + $warn: map-get($theme, warn); $background: map-get($theme, background); $foreground: map-get($theme, foreground); @@ -27,5 +30,23 @@ background: mat-color($background, app-bar); color: mat-color($foreground, text); @include mat-elevation(2); + &.mat-primary { + background: mat-color($primary); + &, md-icon { + color: mat-color($primary, default-contrast); + } + } + &.mat-accent { + background: mat-color($accent); + &, md-icon { + color: mat-color($accent, default-contrast); + } + } + &.mat-warn { + background: mat-color($warn); + &, md-icon { + color: mat-color($warn, default-contrast); + } + } } } \ No newline at end of file diff --git a/src/platform/core/layout/layout-card-over/README.md b/src/platform/core/layout/layout-card-over/README.md index 2618fd841b..3dbd2546e6 100644 --- a/src/platform/core/layout/layout-card-over/README.md +++ b/src/platform/core/layout/layout-card-over/README.md @@ -22,14 +22,14 @@ Example for Card Over Layout / Nav Layout combo: ```html - - + + .. main content
.. content after card
- + // color is optional ... main footer content
diff --git a/src/platform/core/layout/layout-footer/layout-footer.component.html b/src/platform/core/layout/layout-footer/layout-footer.component.html index ca5f777d98..6dbc743063 100644 --- a/src/platform/core/layout/layout-footer/layout-footer.component.html +++ b/src/platform/core/layout/layout-footer/layout-footer.component.html @@ -1,3 +1 @@ - + diff --git a/src/platform/core/layout/layout-footer/layout-footer.component.scss b/src/platform/core/layout/layout-footer/layout-footer.component.scss index 9a14b0c4d8..3864095759 100644 --- a/src/platform/core/layout/layout-footer/layout-footer.component.scss +++ b/src/platform/core/layout/layout-footer/layout-footer.component.scss @@ -1,6 +1,4 @@ :host { display: block; -} -.td-layout-footer { padding: 10px 16px; } diff --git a/src/platform/core/layout/layout-footer/layout-footer.component.ts b/src/platform/core/layout/layout-footer/layout-footer.component.ts index a74c928fdc..347716a2b9 100644 --- a/src/platform/core/layout/layout-footer/layout-footer.component.ts +++ b/src/platform/core/layout/layout-footer/layout-footer.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, Input, Renderer2, ElementRef } from '@angular/core'; @Component({ /* tslint:disable-next-line */ @@ -8,4 +8,28 @@ import { Component } from '@angular/core'; }) export class TdLayoutFooterComponent { + private _color: 'primary' | 'accent' | 'warn'; + + /** + * color?: string + * + * Optional color option: primary | accent | warn. + */ + @Input('color') + set color(color: 'primary' | 'accent' | 'warn') { + if (color) { + this._renderer.removeClass(this._elementRef.nativeElement, 'mat-' + this._color); + this._color = color; + this._renderer.addClass(this._elementRef.nativeElement, 'mat-' + this._color); + } + } + get color(): 'primary' | 'accent' | 'warn' { + return this._color; + } + + constructor(private _renderer: Renderer2, + private _elementRef: ElementRef) { + this._renderer.addClass(this._elementRef.nativeElement, 'td-layout-footer'); + } + } diff --git a/src/platform/core/layout/layout-manage-list/README.md b/src/platform/core/layout/layout-manage-list/README.md index ad051f4b56..f506bcccc8 100644 --- a/src/platform/core/layout/layout-manage-list/README.md +++ b/src/platform/core/layout/layout-manage-list/README.md @@ -23,7 +23,7 @@ Example for Manage List Layout / Nav Layout combo: ```html - +
.. main toolbar content
@@ -42,7 +42,7 @@ Example for Manage List Layout / Nav Layout combo: ... sub footer content - + // color is optional ... main footer content
diff --git a/src/platform/core/layout/layout-nav-list/README.md b/src/platform/core/layout/layout-nav-list/README.md index 57a528c711..6465597cb0 100644 --- a/src/platform/core/layout/layout-nav-list/README.md +++ b/src/platform/core/layout/layout-nav-list/README.md @@ -32,7 +32,7 @@ Example for Nav List Layout: ```html - +
... left toolbar content
@@ -46,7 +46,7 @@ Example for Nav List Layout: ... sub footer content - + // color is optional ... main footer content
diff --git a/src/platform/core/layout/layout-nav/README.md b/src/platform/core/layout/layout-nav/README.md index 5657f34b4e..45f65d4fb4 100644 --- a/src/platform/core/layout/layout-nav/README.md +++ b/src/platform/core/layout/layout-nav/README.md @@ -23,12 +23,12 @@ Example for Nav Layout: ```html - +
.. main toolbar content
... main content - + // color is optional ... main footer content
From 3b4da1cd72b64d20b6f0deb8c7668d785cbd272a Mon Sep 17 00:00:00 2001 From: Jerry Orta Date: Thu, 8 Jun 2017 19:56:18 -0500 Subject: [PATCH 30/35] feat(preload): add selective preload strategy for lazy loading (#678) * feat(preload): add selective preload strategy for lazy loading * docs(preload): documentation to preload configuration * chore(): load only the components module since we want to leverage lazy loading basically only fetch things when needed, since components module is masive we will preload it for now, but the real answer is to break that module into smaller docs modules. --- src/app/app.module.ts | 3 ++- src/app/app.routes.ts | 18 +++++++++++++----- src/app/services/index.ts | 1 + .../selective-preloading-strategy.service.ts | 19 +++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100755 src/app/services/selective-preloading-strategy.service.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d2c76bc991..60e36f836a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -23,7 +23,7 @@ import { CovalentDynamicFormsModule } from '../platform/dynamic-forms'; import { ToolbarModule } from './components/toolbar/toolbar.module'; -import { GitHubService, InternalDocsService } from './services'; +import { GitHubService, InternalDocsService, SelectivePreloadingStrategyService } from './services'; import { getSelectedLanguage, createTranslateLoader } from './utilities/translate'; @NgModule({ @@ -77,6 +77,7 @@ import { getSelectedLanguage, createTranslateLoader } from './utilities/translat // Configure LOCALE_ID depending on the language set in browser provide: LOCALE_ID, useFactory: getSelectedLanguage, deps: [TranslateService], }, + SelectivePreloadingStrategyService, ], // additional providers needed for this module entryComponents: [ ], bootstrap: [ DocsAppComponent ], diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 292f3c02d2..cb07cf7092 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -2,6 +2,7 @@ import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './components/home/home.component'; import { TemplatesComponent } from './components/templates/templates.component'; +import { SelectivePreloadingStrategyService } from './services'; const routes: Routes = [{ component: HomeComponent, @@ -10,13 +11,17 @@ const routes: Routes = [{ component: TemplatesComponent, path: 'templates', }, { - path: '', loadChildren: './components/docs/docs.module#DocsModule', + // preload: true loads the module immediately + path: '', data: { preload: false, }, loadChildren: './components/docs/docs.module#DocsModule', }, { - path: '', loadChildren: './components/style-guide/style-guide.module#StyleGuideModule', + // preload: true loads the module immediately + path: '', data: { preload: false, }, loadChildren: './components/style-guide/style-guide.module#StyleGuideModule', }, { - path: '', loadChildren: './components/layouts/layouts.module#LayoutsModule', + // preload: true loads the module immediately + path: '', data: { preload: false, }, loadChildren: './components/layouts/layouts.module#LayoutsModule', }, { - path: '', loadChildren: './components/components/components.module#ComponentsModule', + // preload: true loads the module immediately + path: '', data: { preload: true, }, loadChildren: './components/components/components.module#ComponentsModule', }, { path: '**', redirectTo: '/', }, @@ -26,4 +31,7 @@ export const appRoutingProviders: any[] = [ ]; -export const appRoutes: any = RouterModule.forRoot(routes, { useHash: true }); +export const appRoutes: any = RouterModule.forRoot(routes, { + useHash: true, + preloadingStrategy: SelectivePreloadingStrategyService, +}); diff --git a/src/app/services/index.ts b/src/app/services/index.ts index fc0f68139e..caae7dea53 100644 --- a/src/app/services/index.ts +++ b/src/app/services/index.ts @@ -1,2 +1,3 @@ export { GitHubService } from './github.service'; export { InternalDocsService, ITemplate } from './internal-docs.service'; +export { SelectivePreloadingStrategyService } from './selective-preloading-strategy.service'; diff --git a/src/app/services/selective-preloading-strategy.service.ts b/src/app/services/selective-preloading-strategy.service.ts new file mode 100755 index 0000000000..1a968b188b --- /dev/null +++ b/src/app/services/selective-preloading-strategy.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +import { PreloadingStrategy, Route } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; + +@Injectable() +export class SelectivePreloadingStrategyService implements PreloadingStrategy { + + preload(route: Route, load: () => Observable): Observable { + + // Configured on lazyload module route + if (route.data && route.data.preload) { + return load(); + } else { + /* tslint:disable-next-line */ + return Observable.of(null); + } + } +} From 90e16f5d7be080aee1601a2d86e72c47536c3e40 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Fri, 9 Jun 2017 11:18:48 -0700 Subject: [PATCH 31/35] feat(dependencies): upgrade to @angular@4.2.0 (#608) * feat(toggle): make toggle directive use new animations API this will grant better support and not depend on `BrowserAnimationsModule` (now we can use NoopAnimationsModule) * feat(fade): make fade directive use new animations API this will grant better support and not depend on `BrowserAnimationsModule` (now we can use NoopAnimationsModule) * fix(media): make media service not use `window` directly this to start tackling angular universal support * chore(): bump module dependencies to angular 4.2.0 * chore(): upgrade dependencies and point to 4.2.0-rc.0 pointing to rc.0 to start testing and getting ready for 4.2.0 release * chore(): polish loading unit tests and use NoopAnimationsModule in all unit test files * fix(): docs error with change detection init * fix(dynamic-forms): make max/min not clash with angular ones also use max/min from angular instead of our implementation * bump(): to angular/cli@1.1.0 * chore(docs): add td-expansion-panel-group in docs where needed * chore(): update to stable 4.2.0 * chore(): upgrade yarn.lock * rollback: fix(): dynamic forms min/max values * fix(media): media toggle wasnt removing attrs or styles when not matching * fix(): change detection problem in layout focs * fix(search-box): error when animating with partial styles * fix(): animations loading demo * chore(): bump to ngx-charts@5.3.1 and ngx-translate@7.0.0 * fix(): timeouts no longer needed in loading component * chore(loading): polish unit tests --- package.json | 40 +- .../components/components.component.ts | 7 +- .../components/loading/loading.component.ts | 3 +- src/app/components/docs/docs.component.ts | 6 +- src/app/components/home/home.component.html | 320 +++--- .../manage-list/manage-list.component.ts | 10 +- .../layouts/nav-list/nav-list.component.ts | 10 +- .../layouts/overview/overview.component.html | 272 ++--- .../style-guide/style-guide.component.ts | 6 +- .../common/animations/fade/fade.directive.ts | 93 +- .../animations/toggle/toggle.directive.ts | 86 +- .../data-table/data-table.component.spec.ts | 4 +- .../expansion-panel.component.spec.ts | 4 +- .../json-formatter.component.spec.ts | 4 +- .../directives/loading.directive.spec.ts | 220 ++-- .../core/loading/loading.component.ts | 10 +- .../loading/services/loading.service.spec.ts | 112 +- .../directives/media-toggle.directive.ts | 14 +- .../core/media/services/media.service.ts | 45 +- .../core/message/message.component.spec.ts | 4 +- src/platform/core/package.json | 10 +- .../core/paging/paging-bar.component.spec.ts | 4 +- .../search/search-box/search-box.component.ts | 8 +- .../core/steps/steps.component.spec.ts | 4 +- .../dynamic-input.component.html | 8 +- .../services/dynamic-forms.service.ts | 6 +- src/platform/highlight/package.json | 4 +- src/platform/http/package.json | 4 +- src/platform/markdown/package.json | 4 +- src/polyfills.ts | 1 + yarn.lock | 997 ++++++++++-------- 31 files changed, 1173 insertions(+), 1147 deletions(-) diff --git a/package.json b/package.json index 820ac38583..48039288b1 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "postinstall": "webdriver-manager update", "reinstall": "rm -rf node_modules tmp deploy dist && npm i", "webdriver-update": "bash ./node_modules/.bin/webdriver-manager update", - "test": "ng test --code-coverage --single-run", + "test": "ng test --code-coverage --single-run --sourcemap=false", "coverage-win": "start chrome ./coverage/index.html", "coverage-mac": "open -a \"Google Chrome\" coverage/index.html", "coveralls": "cat ./coverage/lcov.info | node ./node_modules/coveralls/bin/coveralls.js", @@ -55,33 +55,33 @@ "Steven Ov " ], "dependencies": { - "@angular/animations": "^4.1.0", - "@angular/common": "^4.1.0", - "@angular/compiler": "^4.1.0", - "@angular/core": "^4.1.0", - "@angular/forms": "^4.1.0", - "@angular/http": "^4.1.0", + "@angular/animations": "^4.2.0", + "@angular/common": "^4.2.0", + "@angular/compiler": "^4.2.0", + "@angular/core": "^4.2.0", + "@angular/forms": "^4.2.0", + "@angular/http": "^4.2.0", "@angular/material": "2.0.0-beta.6", - "@angular/platform-browser": "^4.1.0", - "@angular/platform-browser-dynamic": "^4.1.0", - "@angular/platform-server": "^4.1.0", - "@angular/router": "^4.1.0", - "@ngx-translate/core": "6.0.0", - "@ngx-translate/http-loader": "0.0.3", - "@swimlane/ngx-charts": "5.0.0", + "@angular/platform-browser": "^4.2.0", + "@angular/platform-browser-dynamic": "^4.2.0", + "@angular/platform-server": "^4.2.0", + "@angular/router": "^4.2.0", + "@ngx-translate/core": "7.0.0", + "@ngx-translate/http-loader": "0.1.0", + "@swimlane/ngx-charts": "5.3.1", "core-js": "^2.4.1", "d3": "^4.4.0", "hammerjs": "^2.0.8", "highlight.js": "9.11.0", "rxjs": "^5.2.0", "showdown": "1.6.4", - "web-animations-js": "2.2.2", - "zone.js": "^0.8.6" + "web-animations-js": "2.2.5", + "zone.js": "^0.8.12" }, "devDependencies": { - "@angular/cli": "1.0.3", - "@angular/compiler-cli": "^4.1.0", - "@angular/language-service": "^4.1.0", + "@angular/cli": "1.1.1", + "@angular/compiler-cli": "^4.2.0", + "@angular/language-service": "^4.2.0", "@types/hammerjs": "^2.0.30", "@types/jasmine": "2.5.38", "@types/node": "~6.0.60", @@ -117,6 +117,6 @@ "semver": "5.2.0", "ts-node": "~2.0.0", "tslint": "^5.2.0", - "typescript": "^2.3.1" + "typescript": "^2.3.2" } } diff --git a/src/app/components/components/components.component.ts b/src/app/components/components/components.component.ts index 7222b81948..fecd248123 100644 --- a/src/app/components/components/components.component.ts +++ b/src/app/components/components/components.component.ts @@ -1,4 +1,5 @@ -import { Component, HostBinding, AfterViewInit} from '@angular/core'; +import { Component, HostBinding, ChangeDetectorRef, AfterViewInit } from '@angular/core'; + import { TdMediaService } from '@covalent/core'; import { fadeAnimation } from '../../app.animations'; @@ -135,10 +136,12 @@ export class ComponentsComponent implements AfterViewInit { title: 'NGX-Translate', }]; - constructor(public media: TdMediaService) {} + constructor(private _changeDetectorRef: ChangeDetectorRef, + public media: TdMediaService) {} ngAfterViewInit(): void { // broadcast to all listener observables when loading the page this.media.broadcast(); + this._changeDetectorRef.detectChanges(); } } diff --git a/src/app/components/components/loading/loading.component.ts b/src/app/components/components/loading/loading.component.ts index 1663647ebf..c796e8aaf3 100644 --- a/src/app/components/components/loading/loading.component.ts +++ b/src/app/components/components/loading/loading.component.ts @@ -113,7 +113,6 @@ export class LoadingDemoComponent implements OnInit { } ngOnInit(): void { - this.toggleDefaultFullscreenDemo(); this.startDirectives(); } @@ -144,7 +143,7 @@ export class LoadingDemoComponent implements OnInit { this.replaceTemplateSyntaxDisabled = true; this._loadingService.register('replaceTemplateSyntax'); let value: number = 0; - let interval: number = setInterval(() => { + let interval: any = setInterval(() => { this._loadingService.setValue('replaceTemplateSyntax', value); value = value + 10; if (value > 100) { diff --git a/src/app/components/docs/docs.component.ts b/src/app/components/docs/docs.component.ts index b38c915cde..f9f2b20af8 100644 --- a/src/app/components/docs/docs.component.ts +++ b/src/app/components/docs/docs.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, AfterViewInit } from '@angular/core'; +import { Component, HostBinding, AfterViewInit, ChangeDetectorRef } from '@angular/core'; import { TdMediaService } from '@covalent/core'; import { fadeAnimation } from '../../app.animations'; @@ -66,11 +66,13 @@ export class DocsComponent implements AfterViewInit { title: 'Testing', }]; - constructor(public media: TdMediaService) {} + constructor(private _changeDetectorRef: ChangeDetectorRef, + public media: TdMediaService) {} ngAfterViewInit(): void { // broadcast to all listener observables when loading the page this.media.broadcast(); + this._changeDetectorRef.detectChanges(); } } diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html index e375080807..2c75775dc0 100644 --- a/src/app/components/home/home.component.html +++ b/src/app/components/home/home.component.html @@ -134,167 +134,169 @@

Adop

FAQs

- -
- Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). - Covalent gives you a quickstart to build a modern web application UI and ensure consistency across your enterprise products. - Some of Covalent's most important features include: -
    -
  • Angular-Material
  • -
  • Angular Command-line interface (CLI) for builds, deploys, testing & more.
  • -
  • Drastically simplified interface layouts (for dashboards, lists, etc).
  • -
  • Custom web components (stepper, file upload, expansion panels & more).
  • -
  • 750+ Material Design icons.
  • -
  • Style Guide with brand standards, color palettes & tips.
  • -
  • Design Patterns for consistent, reusable web components such as cards, forms, etc.
  • -
  • Testing Tools for both unit tests and end-to-end tests.
  • -
  • Quickstart app to get started right away!
  • -
-
-
- -
- We follow Atomic Design principles and apply them to Angular-Material web components. In Atomic Design, several atoms (such as buttons and inputs) form molecules (such as a search box). - Our covalent bonds are the molecules that we're building on top of Angular-Material. Also, covalent bonds are liquid and conform to their container, just like our responsive layouts! -
-
- -
- By using Covalent as a unified UI Platform there are a ton of benefits. Here are some highlights: -
    -
  • Angular-Material doesn't have a full app quickstart. Covalent does.
  • -
  • Covalent provides the Angular-Material (AngularJS) flexbox layout that was removed in Angular-Material (angular).
  • -
  • Covalent provides several custom components such as steppers & expansion panels.
  • -
  • Custom layouts & components in Covalent are developed specifically for enterprise solutions.
  • -
  • Covalent provides a selection of UI layouts out of the box.
  • -
  • Our team is continuously adding tools like Syntax Highlighting & Markdown.
  • -
  • Our team will always maintain native compatibility with Angular & Material
  • -
  • Our team will always follow the principles of the official Material Design spec.
  • -
-
-
- -
- By adopting Material Design along with Angular, we get a style guide spec that is perfectly matched with an incredbly powerful and modern web framework, all for free. - Along with that, there are lots of other great benefits such as: -
    -
  • A design spec that is married to code implementation.
  • -
  • Official implementations from the the designer/developer (Google).
  • -
  • Free code implementation and updates from a continuously evolving design spec.
  • -
  • Compatability with many devices & breakpoints, from watch and mobile all the way up to fullscreen desktop.
  • -
  • Usage familiarity for users, designers & developers.
  • -
  • Focus on out-of the box accessibility.
  • -
  • Open sourced design & code.
  • -
  • Modularity that gives a natural bridge to agile development principles.
  • -
  • Inspiration, community & resources from around the world.
  • -
-
-
- -
- With any new framework, people's intial reaction is that they'll lose their company brand or identity. - Consider when 960 grids came out, or Bootstrap from Twitter. Many said "all sites will look the same!". - They weren't completely wrong, for a time, when adoption of these new frameworks began. However, with time, usage, and innovation, your special brand identity and uniqueness will always shine through! - Also consider: -
    -
  • Material Design is being embraced across the web, and is not specific to Google anymore
  • -
  • Material Design can be thought of as a native Web SDK, similar to developing a MacOS or iOS app.
  • -
  • Onboarding users is a simpler process if design patterns are familiar.
  • -
  • Think of your favorite iOS, Android or Windows app that adheres to the OS's design. Aren’t the features more important? What woud you really consider “brand”?
  • -
-
-
- -
-

The short answer: we had to pick something & we believe Angular has won the adoption war.

- The longer answer: - Before passing judgement if you have Angular 1.x experience, remember that Angular v2+ is a complete rewrite from the ground up. - Angular moved from an opinionated framework to a sophistated platform. - Angular utilizes ES2015 (previously ES6) and the power of Typescript, which results in a much more native JavaScript platform with coding paradigms & power previously reserved for backend languages. - This means many more back end engineers can jump into the front end and ramp up quickly to productivity. - Also there are many other benefits, such as: -
    -
  • New & exciting software to learn & advocate
  • -
  • More easily attract new hires
  • -
  • An incredibly powerful standardized CLI that is provided to us
  • -
  • More powerful IDEs for development
  • -
  • Integrated testing tools
  • -
  • Native mobile & desktop app support
  • -
-
-
- -
- We give you everything you need to quickly get started on your UI, but you have the domain knowledge and are the expert in your product. - You'll need to build all the custom views, controllers & services for your product, and hook them up to your RESTful APIs. - Don't worry though, we have detailed docs & tips, and there's a wealth of help on the internet (it's why we chose such a popular platform). -
-
- -
- - -
- - -
- To build an atomic, standardized, reusable UI component platform based on Material Design, for Teradata to use for all user interfaces, while collaborating in an open source model. -
-
-
+ +
- Teradata's UX team is extremely lean & agile (notice agile is lower case). We have a simple list of milestones and issues prioritized by demand across products. - Some big ticket items are underway such as TD Charts, an extensive & standardized component built on Google Charts (continuing w/ the Google web stack). - We're also building Dynamic Forms which will allow products to build complex forms with a simple key:value pair JSON structure. - Remember, we're agile so our roadmap is iterative & bite sized for frequent, rapid releases. + Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). + Covalent gives you a quickstart to build a modern web application UI and ensure consistency across your enterprise products. + Some of Covalent's most important features include: +
    +
  • Angular-Material
  • +
  • Angular Command-line interface (CLI) for builds, deploys, testing & more.
  • +
  • Drastically simplified interface layouts (for dashboards, lists, etc).
  • +
  • Custom web components (stepper, file upload, expansion panels & more).
  • +
  • 750+ Material Design icons.
  • +
  • Style Guide with brand standards, color palettes & tips.
  • +
  • Design Patterns for consistent, reusable web components such as cards, forms, etc.
  • +
  • Testing Tools for both unit tests and end-to-end tests.
  • +
  • Quickstart app to get started right away!
  • +
-
- -
- launch -

Releases

-

Our latest version you can use today!

-
- - - launch -

Milestones

-

Rough time estimates

-
- - - launch -

Feature Requests & Bugs

-

Priotized by demand

-
- - - -
- Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). - Electron is a framework for creating native desktop applications with web technologies like JavaScript, HTML, and CSS. - Covalent Electron is the Electron Platform to build desktop apps using Covalent and Electron - View Repo -
-
- -
- Covalent Data is a Mock API server for rapid prototyping and API standards - Built on Golang - Allows for quick prototyping for your Covalent Applications with an easy to mock http backend server - View Repo -
-
+ + +
+ We follow Atomic Design principles and apply them to Angular-Material web components. In Atomic Design, several atoms (such as buttons and inputs) form molecules (such as a search box). + Our covalent bonds are the molecules that we're building on top of Angular-Material. Also, covalent bonds are liquid and conform to their container, just like our responsive layouts! +
+
+ +
+ By using Covalent as a unified UI Platform there are a ton of benefits. Here are some highlights: +
    +
  • Angular-Material doesn't have a full app quickstart. Covalent does.
  • +
  • Covalent provides the Angular-Material (AngularJS) flexbox layout that was removed in Angular-Material (angular).
  • +
  • Covalent provides several custom components such as steppers & expansion panels.
  • +
  • Custom layouts & components in Covalent are developed specifically for enterprise solutions.
  • +
  • Covalent provides a selection of UI layouts out of the box.
  • +
  • Our team is continuously adding tools like Syntax Highlighting & Markdown.
  • +
  • Our team will always maintain native compatibility with Angular & Material
  • +
  • Our team will always follow the principles of the official Material Design spec.
  • +
+
+
+ +
+ By adopting Material Design along with Angular, we get a style guide spec that is perfectly matched with an incredbly powerful and modern web framework, all for free. + Along with that, there are lots of other great benefits such as: +
    +
  • A design spec that is married to code implementation.
  • +
  • Official implementations from the the designer/developer (Google).
  • +
  • Free code implementation and updates from a continuously evolving design spec.
  • +
  • Compatability with many devices & breakpoints, from watch and mobile all the way up to fullscreen desktop.
  • +
  • Usage familiarity for users, designers & developers.
  • +
  • Focus on out-of the box accessibility.
  • +
  • Open sourced design & code.
  • +
  • Modularity that gives a natural bridge to agile development principles.
  • +
  • Inspiration, community & resources from around the world.
  • +
+
+
+ +
+ With any new framework, people's intial reaction is that they'll lose their company brand or identity. + Consider when 960 grids came out, or Bootstrap from Twitter. Many said "all sites will look the same!". + They weren't completely wrong, for a time, when adoption of these new frameworks began. However, with time, usage, and innovation, your special brand identity and uniqueness will always shine through! + Also consider: +
    +
  • Material Design is being embraced across the web, and is not specific to Google anymore
  • +
  • Material Design can be thought of as a native Web SDK, similar to developing a MacOS or iOS app.
  • +
  • Onboarding users is a simpler process if design patterns are familiar.
  • +
  • Think of your favorite iOS, Android or Windows app that adheres to the OS's design. Aren’t the features more important? What woud you really consider “brand”?
  • +
+
+
+ +
+

The short answer: we had to pick something & we believe Angular has won the adoption war.

+ The longer answer: + Before passing judgement if you have Angular 1.x experience, remember that Angular v2+ is a complete rewrite from the ground up. + Angular moved from an opinionated framework to a sophistated platform. + Angular utilizes ES2015 (previously ES6) and the power of Typescript, which results in a much more native JavaScript platform with coding paradigms & power previously reserved for backend languages. + This means many more back end engineers can jump into the front end and ramp up quickly to productivity. + Also there are many other benefits, such as: +
    +
  • New & exciting software to learn & advocate
  • +
  • More easily attract new hires
  • +
  • An incredibly powerful standardized CLI that is provided to us
  • +
  • More powerful IDEs for development
  • +
  • Integrated testing tools
  • +
  • Native mobile & desktop app support
  • +
+
+
+ +
+ We give you everything you need to quickly get started on your UI, but you have the domain knowledge and are the expert in your product. + You'll need to build all the custom views, controllers & services for your product, and hook them up to your RESTful APIs. + Don't worry though, we have detailed docs & tips, and there's a wealth of help on the internet (it's why we chose such a popular platform). +
+
+ +
+ We'd LOVE any type of contribution and collaboration! There's all kinds of ways you can join in: +
    +
  • Submit a bug (cool)
  • +
  • Open a pull request to fix a bug (cooler)
  • +
  • Suggest a new feature (which we'll prioritize by demand)
  • +
  • Open a pull request with new feature (make sure it follows the guidelines)
  • +
  • Give us feedback on any aspect of this site or the platform
  • +
  • Join the Teradata UX team!
  • +
+
+
+ +
+ + +
+ To build an atomic, standardized, reusable UI component platform based on Material Design, for Teradata to use for all user interfaces, while collaborating in an open source model. +
+
+
+
+ Teradata's UX team is extremely lean & agile (notice agile is lower case). We have a simple list of milestones and issues prioritized by demand across products. + Some big ticket items are underway such as TD Charts, an extensive & standardized component built on Google Charts (continuing w/ the Google web stack). + We're also building Dynamic Forms which will allow products to build complex forms with a simple key:value pair JSON structure. + Remember, we're agile so our roadmap is iterative & bite sized for frequent, rapid releases. +
+
+ + + launch +

Releases

+

Our latest version you can use today!

+
+ + + launch +

Milestones

+

Rough time estimates

+
+ + + launch +

Feature Requests & Bugs

+

Priotized by demand

+
+
+
+ +
+ Covalent is a UI Platform that combines proven design language with a comprehensive web framework, built on Angular & Angular-Material (Design). + Electron is a framework for creating native desktop applications with web technologies like JavaScript, HTML, and CSS. + Covalent Electron is the Electron Platform to build desktop apps using Covalent and Electron + View Repo +
+
+ +
+ Covalent Data is a Mock API server for rapid prototyping and API standards + Built on Golang + Allows for quick prototyping for your Covalent Applications with an easy to mock http backend server + View Repo +
+
+

diff --git a/src/app/components/layouts/manage-list/manage-list.component.ts b/src/app/components/layouts/manage-list/manage-list.component.ts index 912ecc7957..66470202c8 100644 --- a/src/app/components/layouts/manage-list/manage-list.component.ts +++ b/src/app/components/layouts/manage-list/manage-list.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, AfterViewInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, HostBinding, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { TdMediaService } from '@covalent/core'; import { fadeAnimation } from '../../../app.animations'; @@ -15,11 +15,15 @@ export class ManageListComponent implements AfterViewInit { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; - constructor(public media: TdMediaService) {} + constructor(private _changeDetectorRef: ChangeDetectorRef, + public media: TdMediaService) {} ngAfterViewInit(): void { // broadcast to all listener observables when loading the page - this.media.broadcast(); + Promise.resolve(undefined).then(() => { + this.media.broadcast(); + this._changeDetectorRef.markForCheck(); + }); } } diff --git a/src/app/components/layouts/nav-list/nav-list.component.ts b/src/app/components/layouts/nav-list/nav-list.component.ts index e53ea52e63..31e685a7f2 100644 --- a/src/app/components/layouts/nav-list/nav-list.component.ts +++ b/src/app/components/layouts/nav-list/nav-list.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, AfterViewInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, HostBinding, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { TdMediaService } from '@covalent/core'; import { fadeAnimation } from '../../../app.animations'; @@ -15,11 +15,15 @@ export class NavListComponent implements AfterViewInit { @HostBinding('@routeAnimation') routeAnimation: boolean = true; @HostBinding('class.td-route-animation') classAnimation: boolean = true; - constructor(public media: TdMediaService) {} + constructor(private _changeDetectorRef: ChangeDetectorRef, + public media: TdMediaService) {} ngAfterViewInit(): void { // broadcast to all listener observables when loading the page - this.media.broadcast(); + Promise.resolve(undefined).then(() => { + this.media.broadcast(); + this._changeDetectorRef.markForCheck(); + }); } } diff --git a/src/app/components/layouts/overview/overview.component.html b/src/app/components/layouts/overview/overview.component.html index 615fecc7c1..6397c947d3 100644 --- a/src/app/components/layouts/overview/overview.component.html +++ b/src/app/components/layouts/overview/overview.component.html @@ -26,145 +26,147 @@

{{item.title}}

Flexbox Layout ("grid")

- -
-

We've ported the CSS3 Flexbox layout system from Angular-Material v1, so those docs shoud be your starting point.

-

In a nutshell, the Flexbox layout gives you:

-
    -
  • Horizontal row layout for child elements
  • -
  • Vertical column layout for child elements
  • -
  • Alignment & ordering for child elements
  • -
  • Any "flex" elastic width for child elements
  • -
  • Conditionally responsive versions for xs,sm,md,lg,xl breakpoints
  • -
-
-
- -
-

Horizontal row container:

-
-
child
-
child
-
child
+ + +
+

We've ported the CSS3 Flexbox layout system from Angular-Material v1, so those docs shoud be your starting point.

+

In a nutshell, the Flexbox layout gives you:

+
    +
  • Horizontal row layout for child elements
  • +
  • Vertical column layout for child elements
  • +
  • Alignment & ordering for child elements
  • +
  • Any "flex" elastic width for child elements
  • +
  • Conditionally responsive versions for xs,sm,md,lg,xl breakpoints
  • +
- - - -
child
-
child
-
child
-
- ]]> - - -

Vertical column container:

-
-
child
-
child
-
child
+ + +
+

Horizontal row container:

+
+
child
+
child
+
child
+
+ + + +
child
+
child
+
child
+
+ ]]> + + +

Vertical column container:

+
+
child
+
child
+
child
+
+ + + +
child
+
child
+
child
+
+ ]]> +
- - - -
child
-
child
-
child
-
- ]]> - -
- - -
-

Layout margin

-
-
child
-
child
-
child
+ + +
+

Layout margin

+
+
child
+
child
+
child
+
+ + + +
child
+
child
+
child
+
+ ]]> + + +

Layout padding

+
+
child
+
child
+
child
+
+ + + +
child
+
child
+
child
+
+ ]]> +
- - - -
child
-
child
-
child
-
- ]]> - - -

Layout padding

-
-
child
-
child
-
child
+ + +
+

40/flex/30 (notice how flex fills remaining space):

+
+
child
+
child
+
child
+
+ + + +
child
+
child
+
child
+
+ ]]> + + +

Responsive widths (will change as you resize browser):

+
+
child
+
child
+
child
+
+ + + +
child
+
child
+
child
+
+ ]]> + + +

Typical responsive layout (just collapse on xs which is mobile)

+
+
child
+
child
+
+ + + +
child
+
child
+
+ ]]> +
- - - -
child
-
child
-
child
-
- ]]> - -
- - -
-

40/flex/30 (notice how flex fills remaining space):

-
-
child
-
child
-
child
-
- - - -
child
-
child
-
child
-
- ]]> - - -

Responsive widths (will change as you resize browser):

-
-
child
-
child
-
child
-
- - - -
child
-
child
-
child
-
- ]]> - - -

Typical responsive layout (just collapse on xs which is mobile)

-
-
child
-
child
-
- - - -
child
-
child
-
- ]]> - -
- + +
diff --git a/src/app/components/style-guide/style-guide.component.ts b/src/app/components/style-guide/style-guide.component.ts index 1330fc6d2e..eb11169230 100644 --- a/src/app/components/style-guide/style-guide.component.ts +++ b/src/app/components/style-guide/style-guide.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, AfterViewInit } from '@angular/core'; +import { Component, HostBinding, AfterViewInit, ChangeDetectorRef } from '@angular/core'; import { TdMediaService } from '@covalent/core'; import { fadeAnimation } from '../../app.animations'; @@ -72,10 +72,12 @@ export class StyleGuideComponent implements AfterViewInit { title: 'Navigation Drawer', }]; - constructor(public media: TdMediaService) {} + constructor(private _changeDetectorRef: ChangeDetectorRef, + public media: TdMediaService) {} ngAfterViewInit(): void { // broadcast to all listener observables when loading the page this.media.broadcast(); + this._changeDetectorRef.detectChanges(); } } diff --git a/src/platform/core/common/animations/fade/fade.directive.ts b/src/platform/core/common/animations/fade/fade.directive.ts index fa235bb7bc..bbdbd881c4 100644 --- a/src/platform/core/common/animations/fade/fade.directive.ts +++ b/src/platform/core/common/animations/fade/fade.directive.ts @@ -1,9 +1,5 @@ -import { - Directive, ElementRef, Input, Output, EventEmitter, HostBinding, Renderer2, OnInit, ChangeDetectorRef, AnimationPlayer, -} from '@angular/core'; -import { ɵAnimation as Animation, AnimationDriver, - ɵAnimationStyleNormalizer as AnimationStyleNormalizer, ɵDomAnimationEngine as DomAnimationEngine } from '@angular/animations/browser'; -import { animate } from '@angular/animations'; +import { Directive, ElementRef, Input, Output, EventEmitter, HostBinding, Renderer2, ChangeDetectorRef } from '@angular/core'; +import { animate, AnimationBuilder, AnimationPlayer, AUTO_STYLE, style, animation } from '@angular/animations'; @Directive({ selector: '[tdFade]', @@ -11,10 +7,9 @@ import { animate } from '@angular/animations'; export class TdFadeDirective { private _state: boolean; - private _defaultOpacity: string; private _defaultDisplay: string; - private _engine: DomAnimationEngine; - private _animationPlayer: AnimationPlayer; + private _animationFadeInPlayer: AnimationPlayer; + private _animationFadeOutPlayer: AnimationPlayer; /** * duration?: number @@ -30,13 +25,17 @@ export class TdFadeDirective { @Input('tdFade') set state(state: boolean) { this._state = state; - if (this._animationPlayer) { - this._animationPlayer.destroy(); - this._animationPlayer = undefined; - } if (state) { + if (this._animationFadeOutPlayer) { + this._animationFadeOutPlayer.destroy(); + this._animationFadeOutPlayer = undefined; + } this.hide(); } else { + if (this._animationFadeInPlayer) { + this._animationFadeInPlayer.destroy(); + this._animationFadeInPlayer = undefined; + } this.show(); } } @@ -45,13 +44,13 @@ export class TdFadeDirective { * fadeIn?: function * Method to be executed when fadeIn animation ends. */ - @Output('fadeIn') fadeIn: EventEmitter = new EventEmitter(); + @Output('fadeIn') onFadeIn: EventEmitter = new EventEmitter(); /** * fadeOut?: function * Method to be executed when fadeOut animation ends. */ - @Output('fadeOut') fadeOut: EventEmitter = new EventEmitter(); + @Output('fadeOut') onFadeOut: EventEmitter = new EventEmitter(); /** * Binds native 'aria-expanded' attribute. @@ -72,28 +71,25 @@ export class TdFadeDirective { constructor(private _renderer: Renderer2, private _element: ElementRef, private _changeDetectorRef: ChangeDetectorRef, - animationDriver: AnimationDriver, - animationStyleNormalizer: AnimationStyleNormalizer) { - this._engine = new DomAnimationEngine(animationDriver, animationStyleNormalizer); + private _animationBuilder: AnimationBuilder) { + this._defaultDisplay = this._element.nativeElement.style.display; } /** * Hides element: starts animation and adds "display:'none'" style at the end. */ hide(): void { - this._defaultDisplay = this._element.nativeElement.style.display; - this._defaultOpacity = !this._element.nativeElement.style.opacity ? 1 : this._element.nativeElement.style.opacity; - this._animationPlayer = this._engine.animateTimeline( - this._element.nativeElement, - new Animation([animate(this.duration + 'ms ease-out')], - ).buildTimelines([{opacity: this._defaultOpacity}], [{opacity: 0}])); - this._changeDetectorRef.markForCheck(); - this._animationPlayer.play(); - this._animationPlayer.onDone(() => { - this._animationPlayer.destroy(); - this._renderer.setStyle(this._element.nativeElement, 'display', 'none'); - this._changeDetectorRef.markForCheck(); + this._animationFadeInPlayer = this._animationBuilder.build(animation([ + style({ + opacity: AUTO_STYLE, + display: AUTO_STYLE, + }), + animate(this.duration + 'ms ease-out', style({opacity: '0'})), + ])).create(this._element.nativeElement); + this._animationFadeInPlayer.onDone(() => { + this._onFadeInDone(); }); + this._animationFadeInPlayer.play(); } /** @@ -102,14 +98,35 @@ export class TdFadeDirective { show(): void { this._renderer.setStyle(this._element.nativeElement, 'display', this._defaultDisplay); this._changeDetectorRef.markForCheck(); - this._animationPlayer = this._engine.animateTimeline( - this._element.nativeElement, - new Animation([animate(this.duration + 'ms ease-in')], - ).buildTimelines([{opacity: 0}], [{opacity: this._defaultOpacity}])); - this._animationPlayer.play(); - this._animationPlayer.onDone(() => { - this._animationPlayer.destroy(); - this._changeDetectorRef.markForCheck(); + this._animationFadeOutPlayer = this._animationBuilder.build(animation([ + style({ + opacity: '0', + display: 'none', + }), + animate(this.duration + 'ms ease-in', style({opacity: AUTO_STYLE})), + ])).create(this._element.nativeElement); + this._animationFadeOutPlayer.onDone(() => { + this._onFadeOutDone(); }); + this._animationFadeOutPlayer.play(); + } + + private _onFadeInDone(): void { + if (this._animationFadeInPlayer) { + this._animationFadeInPlayer.destroy(); + this._animationFadeInPlayer = undefined; + this._renderer.setStyle(this._element.nativeElement, 'display', 'none'); + this._changeDetectorRef.markForCheck(); + this.onFadeIn.emit(); + } + } + + private _onFadeOutDone(): void { + if (this._animationFadeOutPlayer) { + this._animationFadeOutPlayer.destroy(); + this._animationFadeOutPlayer = undefined; + this._changeDetectorRef.markForCheck(); + this.onFadeOut.emit(); + } } } diff --git a/src/platform/core/common/animations/toggle/toggle.directive.ts b/src/platform/core/common/animations/toggle/toggle.directive.ts index ce1d3b45c3..5aae207752 100644 --- a/src/platform/core/common/animations/toggle/toggle.directive.ts +++ b/src/platform/core/common/animations/toggle/toggle.directive.ts @@ -1,7 +1,5 @@ -import { Directive, ElementRef, Input, HostBinding, Renderer2, AnimationPlayer, OnInit, ChangeDetectorRef } from '@angular/core'; -import { ɵAnimation as Animation, AnimationDriver, - ɵAnimationStyleNormalizer as AnimationStyleNormalizer, ɵDomAnimationEngine as DomAnimationEngine } from '@angular/animations/browser'; -import { animate } from '@angular/animations'; +import { Directive, ElementRef, Input, HostBinding, Renderer2, ChangeDetectorRef } from '@angular/core'; +import { animate, AnimationBuilder, AnimationPlayer, AUTO_STYLE, style, animation } from '@angular/animations'; @Directive({ selector: '[tdToggle]', @@ -11,8 +9,8 @@ export class TdToggleDirective { private _state: boolean; private _defaultOverflow: string; private _defaultDisplay: string; - private _engine: DomAnimationEngine; - private _animationPlayer: AnimationPlayer; + private _animationShowPlayer: AnimationPlayer; + private _animationHidePlayer: AnimationPlayer; /** * duration?: number @@ -28,13 +26,17 @@ export class TdToggleDirective { @Input('tdToggle') set state(state: boolean) { this._state = state; - if (this._animationPlayer) { - this._animationPlayer.destroy(); - this._animationPlayer = undefined; - } if (state) { + if (this._animationShowPlayer) { + this._animationShowPlayer.destroy(); + this._animationShowPlayer = undefined; + } this.hide(); } else { + if (this._animationHidePlayer) { + this._animationHidePlayer.destroy(); + this._animationHidePlayer = undefined; + } this.show(); } } @@ -58,9 +60,9 @@ export class TdToggleDirective { constructor(private _renderer: Renderer2, private _element: ElementRef, private _changeDetectorRef: ChangeDetectorRef, - animationDriver: AnimationDriver, - animationStyleNormalizer: AnimationStyleNormalizer) { - this._engine = new DomAnimationEngine(animationDriver, animationStyleNormalizer); + private _animationBuilder: AnimationBuilder) { + this._defaultDisplay = this._element.nativeElement.style.display; + this._defaultOverflow = this._element.nativeElement.style.overflow; } /** @@ -68,21 +70,19 @@ export class TdToggleDirective { * starts animation and adds "display:'none'" style at the end. */ hide(): void { - this._defaultDisplay = this._element.nativeElement.style.display; - this._defaultOverflow = this._element.nativeElement.style.overflow; - this._animationPlayer = this._engine.animateTimeline( - this._element.nativeElement, - new Animation([animate(this.duration + 'ms ease-out')], - ).buildTimelines([{height: this._element.nativeElement.scrollHeight + 'px'}], [{height: 0}])); + this._animationHidePlayer = this._animationBuilder.build(animation([ + style({ + height: AUTO_STYLE, + display: AUTO_STYLE, + }), + animate(this.duration + 'ms ease-in', style({height: '0'})), + ])).create(this._element.nativeElement); this._renderer.setStyle(this._element.nativeElement, 'overflow', 'hidden'); this._changeDetectorRef.markForCheck(); - this._animationPlayer.play(); - this._animationPlayer.onDone(() => { - this._animationPlayer.destroy(); - this._renderer.setStyle(this._element.nativeElement, 'overflow', this._defaultOverflow); - this._renderer.setStyle(this._element.nativeElement, 'display', 'none'); - this._changeDetectorRef.markForCheck(); + this._animationHidePlayer.onDone(() => { + this._onHideDone(); }); + this._animationHidePlayer.play(); } /** @@ -92,16 +92,36 @@ export class TdToggleDirective { show(): void { this._renderer.setStyle(this._element.nativeElement, 'display', this._defaultDisplay); this._changeDetectorRef.markForCheck(); - this._animationPlayer = this._engine.animateTimeline( - this._element.nativeElement, - new Animation([animate(this.duration + 'ms ease-in')], - ).buildTimelines([{height: 0}], [{height: this._element.nativeElement.scrollHeight + 'px'}])); + this._animationShowPlayer = this._animationBuilder.build(animation([ + style({ + height: '0', + display: 'none', + }), + animate(this.duration + 'ms ease-out', style({height: AUTO_STYLE})), + ])).create(this._element.nativeElement); this._renderer.setStyle(this._element.nativeElement, 'overflow', 'hidden'); - this._animationPlayer.play(); - this._animationPlayer.onDone(() => { - this._animationPlayer.destroy(); + this._animationShowPlayer.onDone(() => { + this._onShowDone(); + }); + this._animationShowPlayer.play(); + } + + private _onHideDone(): void { + if (this._animationHidePlayer) { + this._animationHidePlayer.destroy(); + this._animationHidePlayer = undefined; this._renderer.setStyle(this._element.nativeElement, 'overflow', this._defaultOverflow); + this._renderer.setStyle(this._element.nativeElement, 'display', 'none'); this._changeDetectorRef.markForCheck(); - }); + } + } + + private _onShowDone(): void { + if (this._animationShowPlayer) { + this._animationShowPlayer.destroy(); + this._animationShowPlayer = undefined; + this._renderer.setStyle(this._element.nativeElement, 'overflow', this._defaultOverflow); + this._changeDetectorRef.markForCheck(); + } } } diff --git a/src/platform/core/data-table/data-table.component.spec.ts b/src/platform/core/data-table/data-table.component.spec.ts index fc26d9e6fd..e6cf4fb235 100644 --- a/src/platform/core/data-table/data-table.component.spec.ts +++ b/src/platform/core/data-table/data-table.component.spec.ts @@ -15,14 +15,14 @@ import { TdDataTableService } from './services/data-table.service'; import { CovalentDataTableModule } from './data-table.module'; import { NgModule, DebugElement } from '@angular/core'; import { MdCheckbox } from '@angular/material'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('Component: DataTable', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, CovalentDataTableModule, ], declarations: [ diff --git a/src/platform/core/expansion-panel/expansion-panel.component.spec.ts b/src/platform/core/expansion-panel/expansion-panel.component.spec.ts index 980f1b45d6..0dff991a77 100644 --- a/src/platform/core/expansion-panel/expansion-panel.component.spec.ts +++ b/src/platform/core/expansion-panel/expansion-panel.component.spec.ts @@ -5,7 +5,7 @@ import { ComponentFixture, } from '@angular/core/testing'; import { Component } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { CovalentExpansionPanelModule, TdExpansionPanelComponent } from './expansion-panel.module'; import { By } from '@angular/platform-browser'; @@ -18,7 +18,7 @@ describe('Component: ExpansionPanel', () => { TdExpansionPanelSummaryTestComponent, ], imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, CovalentExpansionPanelModule, ], }); diff --git a/src/platform/core/json-formatter/json-formatter.component.spec.ts b/src/platform/core/json-formatter/json-formatter.component.spec.ts index 33ec2f5444..d855b624dd 100644 --- a/src/platform/core/json-formatter/json-formatter.component.spec.ts +++ b/src/platform/core/json-formatter/json-formatter.component.spec.ts @@ -5,7 +5,7 @@ import { ComponentFixture, } from '@angular/core/testing'; import { Component } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { CovalentJsonFormatterModule, TdJsonFormatterComponent } from './json-formatter.module'; import { By } from '@angular/platform-browser'; @@ -17,7 +17,7 @@ describe('Component: JsonFormatter', () => { TdJsonFormatterBasicTestComponent, ], imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, CovalentJsonFormatterModule, ], }); diff --git a/src/platform/core/loading/directives/loading.directive.spec.ts b/src/platform/core/loading/directives/loading.directive.spec.ts index 507501e8ab..687439131a 100644 --- a/src/platform/core/loading/directives/loading.directive.spec.ts +++ b/src/platform/core/loading/directives/loading.directive.spec.ts @@ -7,7 +7,7 @@ import { import { Component } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { By } from '@angular/platform-browser'; import { CovalentLoadingModule, LoadingMode, LoadingType, LoadingStrategy, TdLoadingService } from '../loading.module'; @@ -24,7 +24,7 @@ describe('Directive: Loading', () => { TdLoadingBooleanTemplateUntilTestComponent, ], imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, CovalentLoadingModule, ], }); @@ -40,7 +40,6 @@ describe('Directive: Loading', () => { loadingService.register('name'); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('md-progress-spinner'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('.mat-primary'))).toBeTruthy(); @@ -50,13 +49,9 @@ describe('Directive: Loading', () => { loadingService.resolve('name'); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); - done(); - }); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); + done(); }); }); })(); @@ -75,7 +70,6 @@ describe('Directive: Loading', () => { loadingService.register('name'); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('md-progress-bar'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('.mat-accent'))).toBeTruthy(); @@ -85,13 +79,9 @@ describe('Directive: Loading', () => { loadingService.resolve('name'); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); - done(); - }); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); + done(); }); }); })(); @@ -109,60 +99,34 @@ describe('Directive: Loading', () => { expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe(''); + .style.opacity).toBe('0'); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe(''); + .style.display).toBe('none'); + loadingService.register('name'); fixture.detectChanges(); fixture.whenStable().then(() => { + expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('md-progress-spinner'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('.mat-warn'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('.td-overlay'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('.td-fullscreen'))).toBeFalsy(); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe('0'); + .style.opacity).toBe(''); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe('none'); - loadingService.register('name'); + .style.display).toBe(''); + loadingService.resolve('name'); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('md-progress-spinner'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('.mat-warn'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('.td-overlay'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('.td-fullscreen'))).toBeFalsy(); + expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) + .style.opacity).toBe('0'); + expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) + .style.display).toBe('none'); expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - setTimeout(() => { - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe(''); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe(''); - loadingService.resolve('name'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - setTimeout(() => { - fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe('0'); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe('none'); - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); - done(); - }); - }); - }, 200); - }); - }); - }, 200); - }); + expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); + done(); }); }); }); @@ -182,71 +146,50 @@ describe('Directive: Loading', () => { expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe(''); + .style.opacity).toBe('0'); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe(''); + .style.display).toBe('none'); + loadingService.register('name'); fixture.detectChanges(); fixture.whenStable().then(() => { + expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('md-progress-bar'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('.mat-primary'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('.td-overlay'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('.td-fullscreen'))).toBeFalsy(); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe('0'); + .style.opacity).toBe(''); expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe('none'); - loadingService.register('name'); + .style.display).toBe(''); + + loadingService.setValue('name', 20); fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('md-progress-bar'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('.mat-primary'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('.td-overlay'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('.td-fullscreen'))).toBeFalsy(); - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - setTimeout(() => { - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe(''); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe(''); - loadingService.setValue('name', 20); - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('md-progress-bar')).componentInstance._primaryTransform()) - .toEqual({transform: 'scaleX(0.2)'}); + expect(fixture.debugElement.query(By.css('md-progress-bar')).componentInstance._primaryTransform()) + .toEqual({transform: 'scaleX(0.2)'}); + + loadingService.setValue('name', 50); + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('md-progress-bar')).componentInstance._primaryTransform()) + .toEqual({transform: 'scaleX(0.5)'}); - loadingService.setValue('name', 50); - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('md-progress-bar')).componentInstance._primaryTransform()) - .toEqual({transform: 'scaleX(0.5)'}); + loadingService.setValue('name', 100); + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('md-progress-bar')).componentInstance._primaryTransform()) + .toEqual({transform: 'scaleX(1)'}); - loadingService.setValue('name', 100); - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('md-progress-bar')).componentInstance._primaryTransform()) - .toEqual({transform: 'scaleX(1)'}); - loadingService.resolve('name'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - setTimeout(() => { - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.opacity).toBe('0'); - expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) - .style.display).toBe('none'); - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); - done(); - }); - }, 200); - }); - }); - }, 200); - }); + loadingService.resolve('name'); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) + .style.opacity).toBe('0'); + expect((fixture.debugElement.query(By.css('.td-loading')).nativeElement) + .style.display).toBe('none'); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('td-loading'))).toBeTruthy(); + done(); }); }); }); @@ -293,17 +236,10 @@ describe('Directive: Loading', () => { component.sendResult('success'); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); - expect((fixture.debugElement.query(By.css('.content')).nativeElement).textContent).toContain('success'); - fixture.detectChanges(); - done(); - }); - }, 200); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); + expect((fixture.debugElement.query(By.css('.content')).nativeElement).textContent).toContain('success'); + done(); }); }); })(); @@ -327,17 +263,10 @@ describe('Directive: Loading', () => { component.sendError('error'); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); - expect((fixture.debugElement.query(By.css('.content')).nativeElement).textContent.trim()).toBeFalsy(); - fixture.detectChanges(); - done(); - }); - }, 200); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); + expect((fixture.debugElement.query(By.css('.content')).nativeElement).textContent.trim()).toBeFalsy(); + done(); }); }); })(); @@ -361,16 +290,9 @@ describe('Directive: Loading', () => { component.loading = false; fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); - expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); - fixture.detectChanges(); - done(); - }); - }, 200); + expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); + expect(fixture.debugElement.query(By.css('td-loading'))).toBeFalsy(); + done(); }); }); })(); diff --git a/src/platform/core/loading/loading.component.ts b/src/platform/core/loading/loading.component.ts index 1cd05f8820..9e71c03976 100644 --- a/src/platform/core/loading/loading.component.ts +++ b/src/platform/core/loading/loading.component.ts @@ -154,25 +154,19 @@ export class TdLoadingComponent { this.value = 0; // Check for changes for `OnPush` change detection this._changeDetectorRef.markForCheck(); - setTimeout(() => { - this._animationOut.next(undefined); - }); + this._animationOut.next(undefined); } /** * Starts in animation and returns an observable for completition event. */ startInAnimation(): Observable { - setTimeout(() => { - this.animation = true; - // Check for changes for `OnPush` change detection - this._changeDetectorRef.markForCheck(); - }); /* need to switch back to the selected mode, so we have saved it in another variable * and then recover it. (issue with protractor) */ this._mode = this._defaultMode; // Check for changes for `OnPush` change detection + this.animation = true; this._changeDetectorRef.markForCheck(); return this._animationIn.asObservable(); } diff --git a/src/platform/core/loading/services/loading.service.spec.ts b/src/platform/core/loading/services/loading.service.spec.ts index c69bcfbc0a..d374b5dd8e 100644 --- a/src/platform/core/loading/services/loading.service.spec.ts +++ b/src/platform/core/loading/services/loading.service.spec.ts @@ -43,25 +43,19 @@ describe('Service: Loading', () => { expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); loadingService.register(); fixture.detectChanges(); - setTimeout(() => { + fixture.whenStable().then(() => { + expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); + expect(overlayContainerElement.querySelector('md-progress-spinner')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.mat-primary')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); + loadingService.resolve(); + fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); - expect(overlayContainerElement.querySelector('md-progress-spinner')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.mat-primary')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); - loadingService.resolve(); - fixture.detectChanges(); - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); - done(); - }); - }, 200); + expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); + done(); }); - }, 200); + }); })(); }); @@ -77,25 +71,19 @@ describe('Service: Loading', () => { expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); loadingService.register('name'); fixture.detectChanges(); - setTimeout(() => { + fixture.whenStable().then(() => { + expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); + expect(overlayContainerElement.querySelector('md-progress-bar')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.mat-accent')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); + loadingService.resolve('name'); + fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); - expect(overlayContainerElement.querySelector('md-progress-bar')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.mat-accent')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); - loadingService.resolve('name'); - fixture.detectChanges(); - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); - done(); - }); - }, 200); + expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); + done(); }); - }, 200); + }); })(); }); @@ -111,25 +99,19 @@ describe('Service: Loading', () => { expect(fixture.debugElement.query(By.css('.content'))).toBeTruthy(); loadingService.register('name'); fixture.detectChanges(); - setTimeout(() => { + fixture.whenStable().then(() => { + expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); + expect(overlayContainerElement.querySelector('md-progress-bar')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.mat-accent')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); + loadingService.resolve('name'); + fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); - expect(overlayContainerElement.querySelector('md-progress-bar')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.mat-accent')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); - loadingService.resolve('name'); - fixture.detectChanges(); - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); - done(); - }); - }, 200); + expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); + done(); }); - }, 200); + }); })(); }); @@ -188,25 +170,19 @@ describe('Service: Loading', () => { loadingService.register(); loadingService.register(); fixture.detectChanges(); - setTimeout(() => { + fixture.whenStable().then(() => { + expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); + expect(overlayContainerElement.querySelector('md-progress-spinner')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.mat-primary')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); + expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); + loadingService.resolveAll(); + fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(overlayContainerElement.querySelector('td-loading')).toBeTruthy(); - expect(overlayContainerElement.querySelector('md-progress-spinner')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.mat-primary')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-overlay')).toBeTruthy(); - expect(overlayContainerElement.querySelector('.td-fullscreen')).toBeTruthy(); - loadingService.resolveAll(); - fixture.detectChanges(); - setTimeout(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); - done(); - }); - }, 200); + expect(overlayContainerElement.querySelector('td-loading')).toBeFalsy(); + done(); }); - }, 200); + }); })(); }); }); diff --git a/src/platform/core/media/directives/media-toggle.directive.ts b/src/platform/core/media/directives/media-toggle.directive.ts index 2de0cf4fbf..cc5739b047 100644 --- a/src/platform/core/media/directives/media-toggle.directive.ts +++ b/src/platform/core/media/directives/media-toggle.directive.ts @@ -81,8 +81,11 @@ export class TdMediaToggleDirective implements OnInit, OnDestroy { private _changeAttributes(): void { for (let attr in this._attributes) { - this._renderer.setAttribute(this._elementRef.nativeElement, attr, - this._matches ? this._attributes[attr] : undefined); + if (this._matches) { + this._renderer.setAttribute(this._elementRef.nativeElement, attr, this._attributes[attr]); + } else { + this._renderer.removeAttribute(this._elementRef.nativeElement, attr); + } } } @@ -98,8 +101,11 @@ export class TdMediaToggleDirective implements OnInit, OnDestroy { private _changeStyles(): void { for (let style in this._styles) { - this._renderer.setStyle(this._elementRef.nativeElement, style, - this._matches ? this._styles[style] : undefined); + if (this._matches) { + this._renderer.setStyle(this._elementRef.nativeElement, style, this._styles[style]); + } else { + this._renderer.removeStyle(this._elementRef.nativeElement, style); + } } } diff --git a/src/platform/core/media/services/media.service.ts b/src/platform/core/media/services/media.service.ts index 757ef2ce25..5300f4c974 100644 --- a/src/platform/core/media/services/media.service.ts +++ b/src/platform/core/media/services/media.service.ts @@ -1,10 +1,13 @@ import { Injectable, NgZone, SkipSelf, Optional, Provider } from '@angular/core'; import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; +import { Subscription } from 'rxjs/Subscription'; @Injectable() export class TdMediaService { + private _resizing: boolean = false; + private _globalSubscription: Subscription; private _queryMap: Map = new Map(); private _querySources: {[key: string]: Subject} = {}; private _queryObservables: {[key: string]: Observable} = {}; @@ -23,24 +26,32 @@ export class TdMediaService { this._queryMap.set('portrait', 'portrait'); this._queryMap.set('print', 'print'); - let running: boolean = false; - window.onresize = () => { - // way to prevent the resize event from triggering the match media if there is already one event running already. - if (!running) { - running = true; - if (window.requestAnimationFrame) { - window.requestAnimationFrame(() => { - this._onResize(); - running = false; - }); - } else { + this._resizing = false; + // we make sure that the resize checking happend outside of angular since it happens often + this._globalSubscription = this._ngZone.runOutsideAngular(() => { + return Observable.fromEvent(window, 'resize').subscribe(() => { + // way to prevent the resize event from triggering the match media if there is already one event running already. + if (!this._resizing) { + this._resizing = true; setTimeout(() => { this._onResize(); - running = false; - }, 66); + this._resizing = false; + }, 100); } - } - }; + }); + }); + } + + /** + * Deregisters a query so its stops being notified or used. + */ + deregisterQuery(query: string): void { + if (this._queryMap.get(query.toLowerCase())) { + query = this._queryMap.get(query.toLowerCase()); + } + this._querySources[query].unsubscribe(); + delete this._querySources[query]; + delete this._queryObservables[query]; } /** @@ -51,7 +62,7 @@ export class TdMediaService { query = this._queryMap.get(query.toLowerCase()); } return this._ngZone.run(() => { - return window.matchMedia(query).matches; + return matchMedia(query).matches; }); } @@ -87,7 +98,7 @@ export class TdMediaService { } private _matchMediaTrigger(query: string): void { - this._querySources[query].next(window.matchMedia(query).matches); + this._querySources[query].next(matchMedia(query).matches); } } diff --git a/src/platform/core/message/message.component.spec.ts b/src/platform/core/message/message.component.spec.ts index c1784c3823..ea8a8e4a66 100644 --- a/src/platform/core/message/message.component.spec.ts +++ b/src/platform/core/message/message.component.spec.ts @@ -10,14 +10,14 @@ import { By } from '@angular/platform-browser'; import { TdMessageComponent } from './message.component'; import { CovalentMessageModule } from './message.module'; import { NgModule, DebugElement } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('Component: Message', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, CovalentMessageModule, ], declarations: [ diff --git a/src/platform/core/package.json b/src/platform/core/package.json index ca2a71aa2f..a328d80fb3 100644 --- a/src/platform/core/package.json +++ b/src/platform/core/package.json @@ -38,11 +38,11 @@ "Steven Ov " ], "peerDependencies": { - "@angular/common": "^4.1.0", - "@angular/core": "^4.1.0", - "@angular/forms": "^4.1.0", - "@angular/http": "^4.1.0", - "@angular/router": "^4.1.0", + "@angular/common": "^4.2.0", + "@angular/core": "^4.2.0", + "@angular/forms": "^4.2.0", + "@angular/http": "^4.2.0", + "@angular/router": "^4.2.0", "@angular/material": "2.0.0-beta.6" } } diff --git a/src/platform/core/paging/paging-bar.component.spec.ts b/src/platform/core/paging/paging-bar.component.spec.ts index 1309bf3e16..554fb7813b 100644 --- a/src/platform/core/paging/paging-bar.component.spec.ts +++ b/src/platform/core/paging/paging-bar.component.spec.ts @@ -10,14 +10,14 @@ import { By } from '@angular/platform-browser'; import { TdPagingBarComponent } from './paging-bar.component'; import { CovalentPagingModule } from './paging.module'; import { NgModule, DebugElement } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('Component: PagingBar', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, CovalentPagingModule, ], declarations: [ diff --git a/src/platform/core/search/search-box/search-box.component.ts b/src/platform/core/search/search-box/search-box.component.ts index d1971e467a..aa96c12e9b 100644 --- a/src/platform/core/search/search-box/search-box.component.ts +++ b/src/platform/core/search/search-box/search-box.component.ts @@ -1,5 +1,5 @@ import { Component, ViewChild, Input, Output, EventEmitter } from '@angular/core'; -import { trigger, state, style, transition, animate } from '@angular/animations'; +import { trigger, state, style, transition, animate, AUTO_STYLE } from '@angular/animations'; import { TdSearchInputComponent } from '../search-input/search-input.component'; @@ -11,13 +11,11 @@ import { TdSearchInputComponent } from '../search-input/search-input.component'; trigger('inputState', [ state('0', style({ width: '0%', - 'margin-left': '0px', - 'margin-right': '0px', + margin: '0px', })), state('1', style({ width: '100%', - 'margin-left': '*', - 'margin-right': '*', + margin: AUTO_STYLE, })), transition('0 => 1', animate('200ms ease-in')), transition('1 => 0', animate('200ms ease-out')), diff --git a/src/platform/core/steps/steps.component.spec.ts b/src/platform/core/steps/steps.component.spec.ts index 466c7baf9c..572a94459c 100644 --- a/src/platform/core/steps/steps.component.spec.ts +++ b/src/platform/core/steps/steps.component.spec.ts @@ -5,7 +5,7 @@ import { ComponentFixture, } from '@angular/core/testing'; import { Component, DebugElement } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { By } from '@angular/platform-browser'; import { CovalentStepsModule, StepState, StepMode } from './steps.module'; @@ -19,7 +19,7 @@ describe('Component: Steps', () => { TdStepsDynamicTestComponent, ], imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, CovalentStepsModule, ], }); diff --git a/src/platform/dynamic-forms/dynamic-elements/dynamic-input/dynamic-input.component.html b/src/platform/dynamic-forms/dynamic-elements/dynamic-input/dynamic-input.component.html index c385ffbf77..f5d8ab3290 100644 --- a/src/platform/dynamic-forms/dynamic-elements/dynamic-input/dynamic-input.component.html +++ b/src/platform/dynamic-forms/dynamic-elements/dynamic-input/dynamic-input.component.html @@ -6,13 +6,13 @@ [placeholder]="label" [type]="type" [required]="required" - [min]="min" - [max]="max" + [attr.min]="min" + [attr.max]="max" flex> - Max: {{control.get('max')?.maxValue}} - Min: {{control.get('min')?.minValue}} + Max: {{max}} + Min: {{min}} diff --git a/src/platform/dynamic-forms/services/dynamic-forms.service.ts b/src/platform/dynamic-forms/services/dynamic-forms.service.ts index bddd3ef177..916c2b8729 100644 --- a/src/platform/dynamic-forms/services/dynamic-forms.service.ts +++ b/src/platform/dynamic-forms/services/dynamic-forms.service.ts @@ -1,8 +1,6 @@ import { Injectable, Provider, SkipSelf, Optional } from '@angular/core'; import { Validators, ValidatorFn, FormControl } from '@angular/forms'; -import { CovalentValidators } from '../../core'; - import { TdDynamicInputComponent } from '../dynamic-elements/dynamic-input/dynamic-input.component'; import { TdDynamicTextareaComponent } from '../dynamic-elements/dynamic-textarea/dynamic-textarea.component'; import { TdDynamicSlideToggleComponent } from '../dynamic-elements/dynamic-slide-toggle/dynamic-slide-toggle.component'; @@ -123,10 +121,10 @@ export class TdDynamicFormsService { validator = Validators.required; } if (config.max || config.max === 0) { - validator = Validators.compose([validator, CovalentValidators.max(config.max)]); + validator = Validators.compose([validator, Validators.max(parseFloat(config.max))]); } if (config.min || config.min === 0) { - validator = Validators.compose([validator, CovalentValidators.min(config.min)]); + validator = Validators.compose([validator, Validators.min(parseFloat(config.min))]); } return validator; } diff --git a/src/platform/highlight/package.json b/src/platform/highlight/package.json index 2bedeb5a8b..9c1114ac7f 100644 --- a/src/platform/highlight/package.json +++ b/src/platform/highlight/package.json @@ -40,7 +40,7 @@ "highlight.js": "9.11.0" }, "peerDependencies": { - "@angular/common": "^4.1.0", - "@angular/core": "^4.1.0" + "@angular/common": "^4.2.0", + "@angular/core": "^4.2.0" } } diff --git a/src/platform/http/package.json b/src/platform/http/package.json index 60646e5ffc..a26015ff7a 100644 --- a/src/platform/http/package.json +++ b/src/platform/http/package.json @@ -38,7 +38,7 @@ "Steven Ov " ], "peerDependencies": { - "@angular/core": "^4.1.0", - "@angular/http": "^4.1.0" + "@angular/core": "^4.2.0", + "@angular/http": "^4.2.0" } } diff --git a/src/platform/markdown/package.json b/src/platform/markdown/package.json index f07f310672..d9009cc06c 100644 --- a/src/platform/markdown/package.json +++ b/src/platform/markdown/package.json @@ -38,7 +38,7 @@ "showdown": "1.6.4" }, "peerDependencies": { - "@angular/common": "^4.1.0", - "@angular/core": "^4.1.0" + "@angular/common": "^4.2.0", + "@angular/core": "^4.2.0" } } diff --git a/src/polyfills.ts b/src/polyfills.ts index 602e30a8c4..d7515f9198 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -12,6 +12,7 @@ import 'core-js/es6/date'; import 'core-js/es6/array'; import 'core-js/es6/regexp'; import 'core-js/es6/map'; +import 'core-js/es6/weak-map'; import 'core-js/es6/set'; import 'core-js/es6/reflect'; diff --git a/yarn.lock b/yarn.lock index 724e714daa..a9614f8622 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,16 +2,18 @@ # yarn lockfile v1 -"@angular/animations@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.1.2.tgz#3371596e736b7d240e200477d0dd8c5929352124" +"@angular/animations@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.2.0.tgz#e964fc56c9621f28679f24d5e69026e2d1571425" + dependencies: + tslib "^1.7.1" -"@angular/cli@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-1.0.3.tgz#73a4b43f2ea8e720f52f1041e5e833cae1fb291f" +"@angular/cli@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-1.1.1.tgz#ee5cf7637ad859c08e8a5e7a7f2161d0e74ce7a5" dependencies: - "@ngtools/json-schema" "1.0.9" - "@ngtools/webpack" "1.3.1" + "@ngtools/json-schema" "1.1.0" + "@ngtools/webpack" "1.4.1" autoprefixer "^6.5.3" chalk "^1.1.3" common-tags "^1.3.1" @@ -34,11 +36,10 @@ isbinaryfile "^3.0.0" istanbul-instrumenter-loader "^2.0.0" json-loader "^0.5.4" - karma-sourcemap-loader "^0.3.7" - karma-webpack "^2.0.0" less "^2.7.2" less-loader "^4.0.2" lodash "^4.11.1" + memory-fs "^0.4.1" minimatch "^3.0.3" node-modules-path "^1.0.0" nopt "^4.0.1" @@ -55,89 +56,111 @@ script-loader "^0.7.0" semver "^5.1.0" silent-error "^1.0.0" - source-map-loader "^0.1.5" + source-map-loader "^0.2.0" style-loader "^0.13.1" stylus "^0.54.5" stylus-loader "^3.0.1" temp "0.8.3" - typescript ">=2.0.0 <2.3.0" + typescript ">=2.0.0 <2.4.0" url-loader "^0.5.7" walk-sync "^0.3.1" - webpack "~2.2.0" - webpack-dev-server "~2.4.2" + webpack "~2.4.0" + webpack-dev-middleware "^1.10.2" + webpack-dev-server "~2.4.5" webpack-merge "^2.4.0" zone.js "^0.8.4" optionalDependencies: node-sass "^4.3.0" -"@angular/common@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.1.2.tgz#8f6d0496c204210bfe255feb437a72253f06984d" +"@angular/common@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.2.0.tgz#5df34718bcefc49918bfcb2683f6c19720b66a61" + dependencies: + tslib "^1.7.1" -"@angular/compiler-cli@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.1.2.tgz#b65ba8980330c048702aed242a956daf0251f02a" +"@angular/compiler-cli@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.2.0.tgz#bd6f6b71f003df48a8f86184a8c16533afdf23ec" dependencies: - "@angular/tsc-wrapped" "4.1.2" + "@angular/tsc-wrapped" "4.2.0" minimist "^1.2.0" reflect-metadata "^0.1.2" -"@angular/compiler@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.1.2.tgz#09542381162fd8dd962d84559498ce69a05071ea" +"@angular/compiler@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.2.0.tgz#a21df81995b210f822ffd70b57247d474876fbed" + dependencies: + tslib "^1.7.1" -"@angular/core@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.1.2.tgz#37b5c040b9dd37003499aea04319d699e3870596" +"@angular/core@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.2.0.tgz#8bf57d01379c2a9e29476ad569dec9e20d5b17dc" + dependencies: + tslib "^1.7.1" -"@angular/forms@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.1.2.tgz#82983e9ec5d0833e7ae14beb8e47dd357c88f490" +"@angular/forms@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.2.0.tgz#cb3ae69172e254452fa77578605ebc1bb72138c9" + dependencies: + tslib "^1.7.1" -"@angular/http@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.1.2.tgz#fc378c3330c0410e1fb8aac2546329a6887776e4" +"@angular/http@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.2.0.tgz#484af53639e04a68834c5167a1955d2d0cde8e1c" + dependencies: + tslib "^1.7.1" -"@angular/language-service@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-4.1.2.tgz#438019426beb12178c3432b7eda55ad35fa8d1aa" +"@angular/language-service@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-4.2.0.tgz#4bec4b43af3ed866b994fdac5dc2ca96654fa361" + dependencies: + tslib "^1.7.1" -"@angular/material@2.0.0-beta.5": - version "2.0.0-beta.5" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-2.0.0-beta.5.tgz#712141ebfa77e3ace3ec8e32b5953b355e773965" +"@angular/material@2.0.0-beta.6": + version "2.0.0-beta.6" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-2.0.0-beta.6.tgz#83bfdf00f540a8c7db900a1e7b8ed2cff49df821" + dependencies: + tslib "^1.7.1" -"@angular/platform-browser-dynamic@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.1.2.tgz#d241c61792c794bec627ab64b31a66bea22abb9f" +"@angular/platform-browser-dynamic@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.2.0.tgz#b84c05616bd824e15b52b2b85c47b58b25d0158a" + dependencies: + tslib "^1.7.1" -"@angular/platform-browser@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.1.2.tgz#16e50a8f75b4d675c9e2903e499e0fe4c6a125ac" +"@angular/platform-browser@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.2.0.tgz#dfd782e7ebacba1bbe2ae0556d5d7fb012f2a6cd" + dependencies: + tslib "^1.7.1" -"@angular/platform-server@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.1.2.tgz#3ef2206a59fd2d138d267aad101a50d3d806e39c" +"@angular/platform-server@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.2.0.tgz#90add7fcd9c4f568a31058c9d93a9aca09eb4c58" dependencies: parse5 "^3.0.1" + tslib "^1.7.1" xhr2 "^0.1.4" -"@angular/router@^4.1.0": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.1.2.tgz#31b1b126fec2e1c32f4557ef8eb605536adccb27" +"@angular/router@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.2.0.tgz#7cda9a23621ee41b466eced8bb4cbb62237ba6b9" + dependencies: + tslib "^1.7.1" -"@angular/tsc-wrapped@4.1.2": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.1.2.tgz#26cb145a67b9b80f5dda7874c4f0b1f1e173927d" +"@angular/tsc-wrapped@4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.2.0.tgz#e62ce9953c27ba96e4c6daf117f10e31169ccea2" dependencies: tsickle "^0.21.0" -"@ngtools/json-schema@1.0.9": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@ngtools/json-schema/-/json-schema-1.0.9.tgz#19e46db409c66b4c43841eab514ff9640871affc" +"@ngtools/json-schema@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ngtools/json-schema/-/json-schema-1.1.0.tgz#c3a0c544d62392acc2813a42c8a0dc6f58f86922" -"@ngtools/webpack@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.3.1.tgz#12149b6b9cb3bf858f4b2ae9650456e17674d2eb" +"@ngtools/webpack@1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.4.1.tgz#6d498f21cd1afc027b8b746d8524a7f4e91e1dab" dependencies: enhanced-resolve "^3.1.0" loader-utils "^1.0.2" @@ -165,8 +188,8 @@ resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.5.38.tgz#a4379124c4921d4e21de54ec74669c9e9b356717" "@types/node@^6.0.46", "@types/node@~6.0.60": - version "6.0.73" - resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.73.tgz#85dc4bb6f125377c75ddd2519a1eeb63f0a4ed70" + version "6.0.78" + resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.78.tgz#5d4a3f579c1524e01ee21bf474e6fba09198f470" "@types/q@^0.0.32": version "0.0.32" @@ -197,9 +220,13 @@ acorn@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.3, acorn@^4.0.4: - version "4.0.11" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" +acorn@^4.0.3: + version "4.0.13" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + +acorn@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" adm-zip@0.4.4: version "0.4.4" @@ -214,8 +241,8 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" agent-base@2: - version "2.0.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.0.1.tgz#bd8f9e86a8eb221fffa07bd14befd55df142815e" + version "2.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" dependencies: extend "~3.0.0" semver "~5.0.1" @@ -224,13 +251,20 @@ ajv-keywords@^1.1.1: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" -ajv@^4.11.2, ajv@^4.7.0, ajv@^4.9.1: +ajv@^4.7.0, ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.1.5.tgz#8734931b601f00d4feef7c65738d77d1b65d1f68" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -253,9 +287,9 @@ ansi-cyan@^0.1.1: dependencies: ansi-wrap "0.1.0" -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" ansi-html@0.0.7: version "0.0.7" @@ -301,8 +335,8 @@ append-transform@^0.4.0: default-require-extensions "^1.0.0" aproba@^1.0.3: - version "1.1.1" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + version "1.1.2" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" archy@^1.0.0: version "1.0.0" @@ -418,7 +452,7 @@ async-foreach@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" -async@^0.9.0, async@~0.9.0: +async@^0.9.0: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" @@ -427,8 +461,8 @@ async@^1.4.0, async@^1.5.2: resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" async@^2.1.2, async@^2.1.4, async@^2.1.5: - version "2.4.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.4.0.tgz#4990200f18ea5b837c2cc4f8c031a6985c385611" + version "2.4.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7" dependencies: lodash "^4.14.0" @@ -468,12 +502,12 @@ babel-code-frame@^6.11.0, babel-code-frame@^6.22.0: js-tokens "^3.0.0" babel-generator@^6.18.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" dependencies: babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.24.1" + babel-types "^6.25.0" detect-indent "^4.0.0" jsesc "^1.3.0" lodash "^4.2.0" @@ -494,41 +528,41 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0: regenerator-runtime "^0.10.0" babel-template@^6.16.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" dependencies: babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" lodash "^4.2.0" -babel-traverse@^6.18.0, babel-traverse@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" +babel-traverse@^6.18.0, babel-traverse@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" dependencies: babel-code-frame "^6.22.0" babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.24.1" - babylon "^6.15.0" + babel-types "^6.25.0" + babylon "^6.17.2" debug "^2.2.0" globals "^9.0.0" invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.18.0, babel-types@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" +babel-types@^6.18.0, babel-types@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: babel-runtime "^6.22.0" esutils "^2.0.2" lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: - version "6.17.1" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.1.tgz#17f14fddf361b695981fe679385e4f1c01ebd86f" +babylon@^6.13.0, babylon@^6.17.2: + version "6.17.2" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.2.tgz#201d25ef5f892c41bae49488b08db0dd476e9f5c" backo2@1.0.2: version "1.0.2" @@ -550,9 +584,9 @@ base64id@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" -batch@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" bcrypt-pbkdf@^1.0.0: version "1.0.1" @@ -603,19 +637,19 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" body-parser@^1.12.4: - version "1.17.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.1.tgz#75b3bc98ddd6e7e0d8ffe750dfaca5c66993fa47" + version "1.17.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee" dependencies: bytes "2.4.0" content-type "~1.0.2" - debug "2.6.1" + debug "2.6.7" depd "~1.1.0" http-errors "~1.6.1" iconv-lite "0.4.15" on-finished "~2.3.0" qs "6.4.0" raw-body "~2.2.0" - type-is "~1.6.14" + type-is "~1.6.15" boolbase@~1.0.0: version "1.0.0" @@ -716,10 +750,6 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -buffer-shims@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - buffer-xor@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -795,8 +825,8 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000668" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000668.tgz#0999d376c8335a699cc98f10520afcc86fe1c0f1" + version "1.0.30000680" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000680.tgz#d76ebeaaeb82e3d9952bfdc5c231c4f83cd48144" caseless@~0.11.0: version "0.11.0" @@ -850,9 +880,9 @@ clap@^1.0.9: dependencies: chalk "^1.1.3" -clean-css@4.0.x: - version "4.0.13" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.0.13.tgz#feb2a176062d72a6c3e624d9213cac6a0c485e80" +clean-css@4.1.x: + version "4.1.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.3.tgz#07cfe8980edb20d455ddc23aadcf1e04c6e509ce" dependencies: source-map "0.5.x" @@ -913,8 +943,8 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" coa@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.1.tgz#7f959346cfc8719e3f7233cd6852854a7c67d8a3" + version "1.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.2.tgz#2ba9fec3b4aa43d7a49d7e6c3561e92061b6bcec" dependencies: q "^1.1.2" @@ -981,7 +1011,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@2, commander@2.9.x, commander@^2.9.0: +commander@2, commander@2.9.x, commander@^2.9.0, commander@~2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: @@ -1043,11 +1073,11 @@ connect-history-api-fallback@^1.3.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz#e51d17f8f0ef0db90a64fdb47de3051556e9f169" connect@^3.3.5: - version "3.6.1" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.1.tgz#b7760693a74f0454face1d9378edb3f885b43227" + version "3.6.2" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.2.tgz#694e8d20681bfe490282c8ab886be98f09f42fe7" dependencies: - debug "2.6.3" - finalhandler "1.0.1" + debug "2.6.7" + finalhandler "1.0.3" parseurl "~1.3.1" utils-merge "1.0.0" @@ -1175,12 +1205,13 @@ css-color-names@0.0.4: resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" css-loader@^0.28.1: - version "0.28.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.1.tgz#220325599f8f00452d9ceb4c3ca6c8a66798642d" + version "0.28.4" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.4.tgz#6cf3579192ce355e8b38d5f42dd7a1f2ec898d0f" dependencies: babel-code-frame "^6.11.0" css-selector-tokenizer "^0.7.0" cssnano ">=2.6.1 <4" + icss-utils "^2.1.0" loader-utils "^1.0.2" lodash.camelcase "^4.3.0" object-assign "^4.0.1" @@ -1205,14 +1236,6 @@ css-select@^1.1.0: domutils "1.5.1" nth-check "~1.0.1" -css-selector-tokenizer@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.6.0.tgz#6445f582c7930d241dcc5007a43d6fcb8f073152" - dependencies: - cssesc "^0.1.0" - fastparse "^1.1.1" - regexpu-core "^1.0.0" - css-selector-tokenizer@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" @@ -1289,13 +1312,13 @@ custom-event@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" -d3-array@1, d3-array@1.2.0: +d3-array@1, d3-array@1.2.0, d3-array@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.0.tgz#147d269720e174c4057a7f42be8b0f3f2ba53108" -d3-axis@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.6.tgz#dccbc21a73e5786de820bf1a22b237f522b878be" +d3-axis@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.7.tgz#048433d307061f62d1d248e2930c01d7b6738cd8" d3-brush@1.0.4: version "1.0.4" @@ -1326,9 +1349,9 @@ d3-dispatch@1, d3-dispatch@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8" -d3-drag@1, d3-drag@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.0.4.tgz#a9c1609f11dd5530ae275ebd64377ec54efb9d8f" +d3-drag@1, d3-drag@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.1.0.tgz#4a49b4d77a42e9e3d5a0ef3b492b14aaa2e5a733" dependencies: d3-dispatch "1" d3-selection "1" @@ -1358,9 +1381,9 @@ d3-format@1, d3-format@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.0.tgz#6b480baa886885d4651dc248a8f4ac9da16db07a" -d3-geo@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.6.3.tgz#21683a43a061eaba21a7f254b51d5937eb640756" +d3-geo@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.6.4.tgz#f20e1e461cb1845f5a8be55ab6f876542a7e3199" dependencies: d3-array "1" @@ -1368,9 +1391,9 @@ d3-hierarchy@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.4.tgz#96c3942f3f21cf997a11b4edf00dde2a77b4c6d0" -d3-interpolate@1, d3-interpolate@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.4.tgz#a43ec5b3bee350d8516efdf819a4c08c053db302" +d3-interpolate@1, d3-interpolate@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.5.tgz#69e099ff39214716e563c9aec3ea9d1ea4b8a79f" dependencies: d3-color "1" @@ -1386,13 +1409,13 @@ d3-quadtree@1, d3-quadtree@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.3.tgz#ac7987e3e23fe805a990f28e1b50d38fcb822438" -d3-queue@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.5.tgz#0ceffe1f131c459b13b9f69f1056b41dfc33c00d" +d3-queue@3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.7.tgz#c93a2e54b417c0959129d7d73f6cf7d4292e7618" -d3-random@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.0.3.tgz#6526c844aa5e7c457e29ddacd6f2734f845b42c1" +d3-random@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3" d3-request@1.0.5: version "1.0.5" @@ -1403,11 +1426,11 @@ d3-request@1.0.5: d3-dsv "1" xmlhttprequest "1" -d3-scale@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.5.tgz#418506f0fb18eb052b385e196398acc2a4134858" +d3-scale@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.6.tgz#bce19da80d3a0cf422c9543ae3322086220b34ed" dependencies: - d3-array "1" + d3-array "^1.2.0" d3-collection "1" d3-color "1" d3-format "1" @@ -1415,13 +1438,13 @@ d3-scale@1.0.5: d3-time "1" d3-time-format "2" -d3-selection@1, d3-selection@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.0.5.tgz#948c73b41a44e28d1742ae2ff207c2aebca2734b" +d3-selection@1, d3-selection@1.1.0, d3-selection@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.1.0.tgz#1998684896488f839ca0372123da34f1d318809c" -d3-shape@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.0.6.tgz#b09e305cf0c7c6b9a98c90e6b42f62dac4bcfd5b" +d3-shape@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.1.1.tgz#50a1037e48a79f5b8fd9d58cde52799aeb1f7723" dependencies: d3-path "1" @@ -1439,24 +1462,24 @@ d3-timer@1, d3-timer@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.5.tgz#b266d476c71b0d269e7ac5f352b410a3b6fe6ef0" -d3-transition@1, d3-transition@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.0.4.tgz#e1a9ebae3869a9d9c2874ab00841fa8313ae5de5" +d3-transition@1, d3-transition@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.0.tgz#cfc85c74e5239324290546623572990560c3966f" dependencies: d3-color "1" d3-dispatch "1" d3-ease "1" d3-interpolate "1" - d3-selection "1" + d3-selection "^1.1.0" d3-timer "1" d3-voronoi@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c" -d3-zoom@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.1.4.tgz#903fd2c988b5cace43f00dcf7aae09470c9cc12d" +d3-zoom@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.2.0.tgz#b3231f4f9386241475defe1c557bfd3fde1065fb" dependencies: d3-dispatch "1" d3-drag "1" @@ -1465,39 +1488,39 @@ d3-zoom@1.1.4: d3-transition "1" d3@^4.4.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/d3/-/d3-4.8.0.tgz#1ad8d18997869c90b6ad6114e9b92425cee78460" + version "4.9.1" + resolved "https://registry.yarnpkg.com/d3/-/d3-4.9.1.tgz#f860be9252261a3c14eea64b1d2590d14f4db838" dependencies: d3-array "1.2.0" - d3-axis "1.0.6" + d3-axis "1.0.7" d3-brush "1.0.4" d3-chord "1.0.4" d3-collection "1.0.3" d3-color "1.0.3" d3-dispatch "1.0.3" - d3-drag "1.0.4" + d3-drag "1.1.0" d3-dsv "1.0.5" d3-ease "1.0.3" d3-force "1.0.6" d3-format "1.2.0" - d3-geo "1.6.3" + d3-geo "1.6.4" d3-hierarchy "1.1.4" - d3-interpolate "1.1.4" + d3-interpolate "1.1.5" d3-path "1.0.5" d3-polygon "1.0.3" d3-quadtree "1.0.3" - d3-queue "3.0.5" - d3-random "1.0.3" + d3-queue "3.0.7" + d3-random "1.1.0" d3-request "1.0.5" - d3-scale "1.0.5" - d3-selection "1.0.5" - d3-shape "1.0.6" + d3-scale "1.0.6" + d3-selection "1.1.0" + d3-shape "1.1.1" d3-time "1.0.6" d3-time-format "2.0.5" d3-timer "1.0.5" - d3-transition "1.0.4" + d3-transition "1.1.0" d3-voronoi "1.1.2" - d3-zoom "1.1.4" + d3-zoom "1.2.0" dashdash@^1.12.0: version "1.14.1" @@ -1516,11 +1539,11 @@ dateformat@^1.0.11: get-stdin "^4.0.1" meow "^3.3.0" -debug@*, debug@2, debug@^2.1.3, debug@^2.2.0, debug@^2.6.3: - version "2.6.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a" +debug@*, debug@2, debug@2.6.8, debug@^2.1.3, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: - ms "0.7.3" + ms "2.0.0" debug@0.7.4: version "0.7.4" @@ -1538,17 +1561,11 @@ debug@2.3.3: dependencies: ms "0.7.2" -debug@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" - dependencies: - ms "0.7.2" - -debug@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" +debug@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" dependencies: - ms "0.7.2" + ms "2.0.0" decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" @@ -1629,6 +1646,10 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" +detect-node@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" + di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" @@ -1732,8 +1753,8 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" electron-to-chromium@^1.2.7: - version "1.3.10" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.10.tgz#63d62b785471f0d8dda85199d64579de8a449f08" + version "1.3.13" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.13.tgz#1b3a5eace6e087bb5e257a100b0cbfe81b2891fc" elliptic@^6.0.0: version "6.4.0" @@ -1946,8 +1967,8 @@ exports-loader@^0.6.3: source-map "0.5.x" express@^4.13.3: - version "4.15.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.15.2.tgz#af107fc148504457f2dca9a6f2571d7129b97b35" + version "4.15.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.15.3.tgz#bab65d0f03aa80c358408972fc700f916944b662" dependencies: accepts "~1.3.3" array-flatten "1.1.1" @@ -1955,28 +1976,28 @@ express@^4.13.3: content-type "~1.0.2" cookie "0.3.1" cookie-signature "1.0.6" - debug "2.6.1" + debug "2.6.7" depd "~1.1.0" encodeurl "~1.0.1" escape-html "~1.0.3" etag "~1.8.0" - finalhandler "~1.0.0" + finalhandler "~1.0.3" fresh "0.5.0" merge-descriptors "1.0.1" methods "~1.1.2" on-finished "~2.3.0" parseurl "~1.3.1" path-to-regexp "0.1.7" - proxy-addr "~1.1.3" + proxy-addr "~1.1.4" qs "6.4.0" range-parser "~1.2.0" - send "0.15.1" - serve-static "1.12.1" + send "0.15.3" + serve-static "1.12.3" setprototypeof "1.0.3" statuses "~1.3.1" - type-is "~1.6.14" + type-is "~1.6.15" utils-merge "1.0.0" - vary "~1.1.0" + vary "~1.1.1" extend-shallow@^1.1.2: version "1.1.4" @@ -1994,10 +2015,12 @@ extend@3, extend@^3.0.0, extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -external-editor@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.1.tgz#4c597c6c88fa6410e41dbbaa7b1be2336aa31095" +external-editor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" dependencies: + iconv-lite "^0.4.17" + jschardet "^1.4.2" tmp "^0.0.31" extglob@^0.3.1: @@ -2007,13 +2030,13 @@ extglob@^0.3.1: is-extglob "^1.0.0" extract-text-webpack-plugin@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.0.tgz#69315b885f876dbf96d3819f6a9f1cca7aebf159" + version "2.1.2" + resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.2.tgz#756ef4efa8155c3681833fbc34da53b941746d6c" dependencies: - ajv "^4.11.2" async "^2.1.2" loader-utils "^1.0.2" - webpack-sources "^0.1.0" + schema-utils "^0.3.0" + webpack-sources "^1.0.1" extract-zip@~1.5.0: version "1.5.0" @@ -2090,11 +2113,11 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" -finalhandler@1.0.1, finalhandler@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.1.tgz#bcd15d1689c0e5ed729b6f7f541a6df984117db8" +finalhandler@1.0.3, finalhandler@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89" dependencies: - debug "2.6.3" + debug "2.6.7" encodeurl "~1.0.1" escape-html "~1.0.3" on-finished "~2.3.0" @@ -2122,12 +2145,6 @@ findup-sync@^0.4.2: micromatch "^2.3.7" resolve-dir "^0.1.0" -findup-sync@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16" - dependencies: - glob "~5.0.0" - fined@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/fined/-/fined-1.0.2.tgz#5b28424b760d7598960b7ef8480dff8ad3660e97" @@ -2381,7 +2398,7 @@ glob@^4.3.1: minimatch "^2.0.1" once "^1.3.0" -glob@^5.0.3, glob@~5.0.0: +glob@^5.0.3: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" dependencies: @@ -2402,13 +2419,13 @@ glob@^6.0.4: path-is-absolute "^1.0.0" glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@~7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.2" + minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" @@ -2437,8 +2454,8 @@ global-prefix@^0.1.4: which "^1.2.12" globals@^9.0.0: - version "9.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" globby@^5.0.0: version "5.0.0" @@ -2602,7 +2619,7 @@ hammerjs@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" -handle-thing@^1.2.4: +handle-thing@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" @@ -2615,8 +2632,8 @@ handlebars@^1.3.0: uglify-js "~2.3" handlebars@^4.0.3: - version "4.0.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.8.tgz#22b875cd3f0e6cbea30314f144e82bc7a72ff420" + version "4.0.10" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" dependencies: async "^1.4.0" optimist "^0.6.1" @@ -2756,17 +2773,17 @@ html-entities@^1.2.0: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" html-minifier@^3.2.3: - version "3.4.4" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.4.4.tgz#616fe3e3ef16da02b393d9a6099eeff468a35df0" + version "3.5.2" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.2.tgz#d73bc3ff448942408818ce609bf3fb0ea7ef4eb7" dependencies: camel-case "3.0.x" - clean-css "4.0.x" + clean-css "4.1.x" commander "2.9.x" he "1.1.x" ncname "1.0.x" param-case "2.1.x" relateurl "0.2.x" - uglify-js "~2.8.22" + uglify-js "3.0.x" html-webpack-plugin@^2.19.0: version "2.28.0" @@ -2788,18 +2805,10 @@ htmlparser2@~3.3.0: domutils "1.1" readable-stream "1.0" -http-deceiver@^1.2.4: +http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" -http-errors@~1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" - dependencies: - inherits "2.0.3" - setprototypeof "1.0.2" - statuses ">= 1.3.1 < 2" - http-errors@~1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257" @@ -2845,7 +2854,7 @@ https-proxy-agent@^1.0.0: debug "2" extend "3" -iconv-lite@0.4: +iconv-lite@0.4, iconv-lite@^0.4.17: version "0.4.17" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.17.tgz#4fdaa3b38acbc2c031b045d0edcdfe1ecab18c8d" @@ -2853,17 +2862,23 @@ iconv-lite@0.4.15: version "0.4.15" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" -icss-replace-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.0.2.tgz#cb0b6054eb3af6edc9ab1d62d01933e2d4c8bfa5" +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + +icss-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" + dependencies: + postcss "^6.0.1" ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" image-size@~0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.3.tgz#5cbe9fafc8436386ceb7e9e3a9d90c5b71b70ad9" + version "0.5.4" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.4.tgz#94e07beec0659386f1aefb84b2222e88405485cd" img-stats@^0.5.2: version "0.5.2" @@ -2917,19 +2932,20 @@ ini@^1.3.4, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" inquirer@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" + version "3.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.0.tgz#e05400d48b94937c2d3caa7038663ba9189aab01" dependencies: - ansi-escapes "^1.1.0" + ansi-escapes "^2.0.0" chalk "^1.0.0" cli-cursor "^2.1.0" cli-width "^2.0.0" - external-editor "^2.0.1" + external-editor "^2.0.4" figures "^2.0.0" lodash "^4.3.0" mute-stream "0.0.7" run-async "^2.2.0" - rx "^4.1.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" string-width "^2.0.0" strip-ansi "^3.0.0" through "^2.3.6" @@ -2988,8 +3004,8 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" is-equal-shallow@^0.1.3: version "0.1.3" @@ -3077,10 +3093,10 @@ is-plain-obj@^1.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" is-plain-object@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.1.tgz#4d7ca539bc9db9b737b8acb612f2318ef92f294f" + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.3.tgz#c15bf3e4b66b62d72efaf2925848663ecbc619b6" dependencies: - isobject "^1.0.0" + isobject "^3.0.0" is-posix-bracket@^0.1.0: version "0.1.1" @@ -3152,32 +3168,32 @@ isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" -isobject@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-1.0.2.tgz#f0f9b8ce92dd540fa0740882e3835a2e022ec78a" - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" dependencies: isarray "1.0.0" +isobject@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.0.tgz#39565217f3661789e8a0a0c080d5f7e6bc46e1a0" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" istanbul-api@^1.1.1: - version "1.1.8" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.8.tgz#a844e55c6f9aeee292e7f42942196f60b23dc93e" + version "1.1.9" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.9.tgz#2827920d380d4286d857d57a2968a841db8a7ec8" dependencies: async "^2.1.4" fileset "^2.0.2" - istanbul-lib-coverage "^1.1.0" - istanbul-lib-hook "^1.0.6" - istanbul-lib-instrument "^1.7.1" - istanbul-lib-report "^1.1.0" - istanbul-lib-source-maps "^1.2.0" - istanbul-reports "^1.1.0" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-hook "^1.0.7" + istanbul-lib-instrument "^1.7.2" + istanbul-lib-report "^1.1.1" + istanbul-lib-source-maps "^1.2.1" + istanbul-reports "^1.1.1" js-yaml "^3.7.0" mkdirp "^0.5.1" once "^1.4.0" @@ -3191,50 +3207,50 @@ istanbul-instrumenter-loader@^2.0.0: loader-utils "^0.2.16" object-assign "^4.1.0" -istanbul-lib-coverage@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#caca19decaef3525b5d6331d701f3f3b7ad48528" +istanbul-lib-coverage@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" -istanbul-lib-hook@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.6.tgz#c0866d1e81cf2d5319249510131fc16dee49231f" +istanbul-lib-hook@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc" dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.1.3, istanbul-lib-instrument@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.1.tgz#169e31bc62c778851a99439dd99c3cc12184d360" +istanbul-lib-instrument@^1.1.3, istanbul-lib-instrument@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.2.tgz#6014b03d3470fb77638d5802508c255c06312e56" dependencies: babel-generator "^6.18.0" babel-template "^6.16.0" babel-traverse "^6.18.0" babel-types "^6.18.0" babylon "^6.13.0" - istanbul-lib-coverage "^1.1.0" + istanbul-lib-coverage "^1.1.1" semver "^5.3.0" -istanbul-lib-report@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.0.tgz#444c4ecca9afa93cf584f56b10f195bf768c0770" +istanbul-lib-report@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9" dependencies: - istanbul-lib-coverage "^1.1.0" + istanbul-lib-coverage "^1.1.1" mkdirp "^0.5.1" path-parse "^1.0.5" supports-color "^3.1.2" -istanbul-lib-source-maps@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.0.tgz#8c7706d497e26feeb6af3e0c28fd5b0669598d0e" +istanbul-lib-source-maps@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c" dependencies: debug "^2.6.3" - istanbul-lib-coverage "^1.1.0" + istanbul-lib-coverage "^1.1.1" mkdirp "^0.5.1" rimraf "^2.6.1" source-map "^0.5.3" -istanbul-reports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.0.tgz#1ef3b795889219cfb5fad16365f6ce108d5f8c66" +istanbul-reports@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e" dependencies: handlebars "^4.0.3" @@ -3243,8 +3259,8 @@ jasmine-core@~2.5.2: resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.5.2.tgz#6f61bd79061e27f43e6f9355e44b3c6cab6ff297" jasmine-core@~2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.6.1.tgz#66a61cddb699958e3613edef346c996f6311fc3b" + version "2.6.3" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.6.3.tgz#45072950e4a42b1e322fe55c001100a465d77815" jasmine@^2.5.3: version "2.6.0" @@ -3254,16 +3270,10 @@ jasmine@^2.5.3: glob "^7.0.6" jasmine-core "~2.6.0" -jasminewd2@^2.0.0: +jasminewd2@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/jasminewd2/-/jasminewd2-2.1.0.tgz#da595275d1ae631de736ac0a7c7d85c9f73ef652" -jodid25519@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" - dependencies: - jsbn "~0.1.0" - js-base64@^2.1.5, js-base64@^2.1.8, js-base64@^2.1.9: version "2.1.9" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" @@ -3297,6 +3307,10 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jschardet@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.4.2.tgz#2aa107f142af4121d145659d44f50830961e699a" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -3327,7 +3341,7 @@ json3@3.3.2, json3@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" -json5@^0.5.0: +json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -3394,22 +3408,6 @@ karma-phantomjs-launcher@1.0.1: lodash "^4.0.1" phantomjs-prebuilt "^2.1.7" -karma-sourcemap-loader@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" - dependencies: - graceful-fs "^4.1.2" - -karma-webpack@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.3.tgz#39cebf5ca2580139b27f9ae69b78816b9c82fae6" - dependencies: - async "~0.9.0" - loader-utils "^0.2.5" - lodash "^3.8.0" - source-map "^0.1.41" - webpack-dev-middleware "^1.0.11" - karma@~1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/karma/-/karma-1.4.1.tgz#41981a71d54237606b0a3ea8c58c90773f41650e" @@ -3457,8 +3455,8 @@ kind-of@^2.0.1: is-buffer "^1.0.2" kind-of@^3.0.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.0.tgz#b58abe4d5c044ad33726a8c1525b48cf891bff07" + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" dependencies: is-buffer "^1.1.5" @@ -3493,8 +3491,8 @@ lcov-parse@0.0.10: resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" less-loader@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.3.tgz#d1e6462ca2f090c11248455e14b8dda4616d0521" + version "4.0.4" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.4.tgz#b4a8c43843e65c67d2ea2eb1465b5c4233d5006a" dependencies: clone "^2.1.1" loader-utils "^1.1.0" @@ -3541,7 +3539,7 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2.2: +loader-utils@^0.2.16, loader-utils@~0.2.2: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: @@ -3750,8 +3748,8 @@ lru-cache@2, lru-cache@2.2.x: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" lru-cache@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + version "4.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.0.tgz#59be49a683b8d986a939f1ca60fdb6989f4b2046" dependencies: pseudomap "^1.0.1" yallist "^2.0.0" @@ -3773,8 +3771,8 @@ magic-string@^0.19.0: vlq "^0.2.1" make-error@^1.1.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.2.3.tgz#6c4402df732e0977ac6faf754a5074b3d2b1d19d" + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.0.tgz#52ad3a339ccf10ce62b4040b708fe707244b8b96" map-cache@^0.2.0: version "0.2.2" @@ -3798,7 +3796,7 @@ media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" -memory-fs@^0.4.0, memory-fs@~0.4.1: +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" dependencies: @@ -3893,7 +3891,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@~3.0.2: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -3951,9 +3949,9 @@ ms@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" -ms@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" multipipe@^0.1.2: version "0.1.2" @@ -3990,8 +3988,8 @@ no-case@^2.2.0: lower-case "^1.1.1" node-gyp@^3.3.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.1.tgz#19561067ff185464aded478212681f47fd578cbc" + version "3.6.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" dependencies: fstream "^1.0.0" glob "^7.0.3" @@ -4040,8 +4038,8 @@ node-modules-path@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-path/-/node-modules-path-1.0.1.tgz#40096b08ce7ad0ea14680863af449c7c75a5d1c8" node-pre-gyp@^0.6.29: - version "0.6.34" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" + version "0.6.36" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" dependencies: mkdirp "^0.5.1" nopt "^4.0.1" @@ -4073,8 +4071,8 @@ node-sass@3.8.0: sass-graph "^2.1.1" node-sass@^4.2.0, node-sass@^4.3.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.5.2.tgz#4012fa2bd129b1d6365117e88d9da0500d99da64" + version "4.5.3" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.5.3.tgz#d09c9d1179641239d1b97ffc6231fdcec53e1568" dependencies: async-foreach "^0.1.3" chalk "^1.1.1" @@ -4190,7 +4188,7 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" -obuf@^1.0.0, obuf@^1.1.0: +obuf@^1.0.0, obuf@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e" @@ -4645,31 +4643,31 @@ postcss-minify-selectors@^2.0.4: postcss-selector-parser "^2.0.0" postcss-modules-extract-imports@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.0.1.tgz#8fb3fef9a6dd0420d3f6d4353cf1ff73f2b2a341" + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85" dependencies: - postcss "^5.0.4" + postcss "^6.0.1" postcss-modules-local-by-default@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.1.1.tgz#29a10673fa37d19251265ca2ba3150d9040eb4ce" + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" dependencies: - css-selector-tokenizer "^0.6.0" - postcss "^5.0.4" + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" postcss-modules-scope@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.0.2.tgz#ff977395e5e06202d7362290b88b1e8cd049de29" + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" dependencies: - css-selector-tokenizer "^0.6.0" - postcss "^5.0.4" + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" postcss-modules-values@^1.1.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.2.2.tgz#f0e7d476fe1ed88c5e4c7f97533a3e772ad94ca1" + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" dependencies: - icss-replace-symbols "^1.0.2" - postcss "^5.0.14" + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" postcss-normalize-charset@^1.1.0: version "1.1.1" @@ -4772,6 +4770,14 @@ postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0. source-map "^0.5.6" supports-color "^3.2.3" +postcss@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.1.tgz#000dbd1f8eef217aa368b9a212c5fc40b2a8f3f2" + dependencies: + chalk "^1.1.3" + source-map "^0.5.6" + supports-color "^3.2.3" + prepend-http@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -4810,8 +4816,8 @@ promise@^7.1.1: asap "~2.0.3" protractor@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.1.1.tgz#10c4e336571b28875b8acc3ae3e4e1e40ef7e986" + version "5.1.2" + resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.1.2.tgz#9b221741709a4c62d5cd53c6aadd54a71137e95f" dependencies: "@types/node" "^6.0.46" "@types/q" "^0.0.32" @@ -4820,16 +4826,16 @@ protractor@~5.1.0: chalk "^1.1.3" glob "^7.0.3" jasmine "^2.5.3" - jasminewd2 "^2.0.0" + jasminewd2 "^2.1.0" optimist "~0.6.0" q "1.4.1" saucelabs "~1.3.0" selenium-webdriver "3.0.1" source-map-support "~0.4.0" webdriver-js-extender "^1.0.0" - webdriver-manager "^12.0.1" + webdriver-manager "^12.0.6" -proxy-addr@~1.1.3: +proxy-addr@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.4.tgz#27e545f6960a44a627d9b44467e35c1b6b4ce2f3" dependencies: @@ -4909,8 +4915,10 @@ randomatic@^1.1.3: kind-of "^3.0.2" randombytes@^2.0.0, randombytes@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.3.tgz#674c99760901c3c4112771a31e521dc349cc09ec" + version "2.0.5" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" + dependencies: + safe-buffer "^5.1.0" range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0: version "1.2.0" @@ -4961,15 +4969,15 @@ readable-stream@1.0, "readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0 isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.6: - version "2.2.9" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.6, readable-stream@^2.2.9: + version "2.2.11" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72" dependencies: - buffer-shims "~1.0.0" core-util-is "~1.0.0" inherits "~2.0.1" isarray "~1.0.0" process-nextick-args "~1.0.6" + safe-buffer "~5.0.1" string_decoder "~1.0.0" util-deprecate "~1.0.1" @@ -5071,8 +5079,8 @@ relateurl@0.2.x: resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" remove-trailing-separator@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + version "1.0.2" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511" renderkid@^2.0.1: version "2.0.1" @@ -5276,9 +5284,15 @@ rw@1: version "1.3.3" resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" -rx@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" rxjs@^5.0.1, rxjs@^5.2.0: version "5.4.0" @@ -5286,18 +5300,22 @@ rxjs@^5.0.1, rxjs@^5.2.0: dependencies: symbol-observable "^1.0.1" -safe-buffer@^5.0.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.0.tgz#fe4c8460397f9eaaaa58e73be46273408a45e223" + +safe-buffer@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" sass-graph@^2.1.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.3.tgz#2ba9f170f6cafed5b51665abe13cf319c9269c31" + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" dependencies: glob "^7.0.0" lodash "^4.0.0" scss-tokenizer "^0.2.3" - yargs "^6.6.0" + yargs "^7.0.0" sass-loader@^6.0.3: version "6.0.5" @@ -5327,6 +5345,12 @@ sax@>=0.6.0, sax@~1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" +schema-utils@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + dependencies: + ajv "^5.0.0" + script-loader@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/script-loader/-/script-loader-0.7.0.tgz#685dc7e7069e0dee7a92674f0ebc5b0f55baa5ec" @@ -5385,11 +5409,11 @@ semver@~5.0.1: version "5.0.3" resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" -send@0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.15.1.tgz#8a02354c26e6f5cca700065f5f0cdeba90ec7b5f" +send@0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/send/-/send-0.15.3.tgz#5013f9f99023df50d1bd9892c19e3defd1d53309" dependencies: - debug "2.6.1" + debug "2.6.7" depd "~1.1.0" destroy "~1.0.4" encodeurl "~1.0.1" @@ -5398,7 +5422,7 @@ send@0.15.1: fresh "0.5.0" http-errors "~1.6.1" mime "1.3.4" - ms "0.7.2" + ms "2.0.0" on-finished "~2.3.0" range-parser "~1.2.0" statuses "~1.3.1" @@ -5408,25 +5432,25 @@ sequencify@~0.0.7: resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" serve-index@^1.7.2: - version "1.8.0" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.8.0.tgz#7c5d96c13fb131101f93c1c5774f8516a1e78d3b" + version "1.9.0" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.0.tgz#d2b280fc560d616ee81b48bf0fa82abed2485ce7" dependencies: accepts "~1.3.3" - batch "0.5.3" - debug "~2.2.0" + batch "0.6.1" + debug "2.6.8" escape-html "~1.0.3" - http-errors "~1.5.0" - mime-types "~2.1.11" + http-errors "~1.6.1" + mime-types "~2.1.15" parseurl "~1.3.1" -serve-static@1.12.1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.1.tgz#7443a965e3ced647aceb5639fa06bf4d1bbe0039" +serve-static@1.12.3: + version "1.12.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.3.tgz#9f4ba19e2f3030c547f8af99107838ec38d5b1e2" dependencies: encodeurl "~1.0.1" escape-html "~1.0.3" parseurl "~1.3.1" - send "0.15.1" + send "0.15.3" set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -5440,10 +5464,6 @@ setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" -setprototypeof@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" - setprototypeof@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" @@ -5557,13 +5577,21 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" -source-list-map@^0.1.7, source-list-map@~0.1.7: +source-list-map@^0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" -source-map-loader@^0.1.5: - version "0.1.6" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.1.6.tgz#c09903da6d73b9e53b7ed8ee5245597051e98e91" +source-list-map@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1" + +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + +source-map-loader@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.1.tgz#48126be9230bd47fad05e46a8c3c2e3d2dabe507" dependencies: async "^0.9.0" loader-utils "~0.2.2" @@ -5575,7 +5603,7 @@ source-map-support@^0.4.0, source-map-support@^0.4.2, source-map-support@~0.4.0: dependencies: source-map "^0.5.6" -source-map@0.1.x, source-map@^0.1.41, source-map@~0.1.33, source-map@~0.1.7: +source-map@0.1.x, source-map@~0.1.33, source-map@~0.1.7: version "0.1.43" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" dependencies: @@ -5609,37 +5637,40 @@ spdx-license-ids@^1.0.2: version "1.2.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" -spdy-transport@^2.0.15: - version "2.0.18" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.0.18.tgz#43fc9c56be2cccc12bb3e2754aa971154e836ea6" +spdy-transport@^2.0.18: + version "2.0.20" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.0.20.tgz#735e72054c486b2354fe89e702256004a39ace4d" dependencies: - debug "^2.2.0" + debug "^2.6.8" + detect-node "^2.0.3" hpack.js "^2.1.6" - obuf "^1.1.0" - readable-stream "^2.0.1" - wbuf "^1.4.0" + obuf "^1.1.1" + readable-stream "^2.2.9" + safe-buffer "^5.0.1" + wbuf "^1.7.2" spdy@^3.4.1: - version "3.4.4" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.4.tgz#e0406407ca90ff01b553eb013505442649f5a819" + version "3.4.7" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc" dependencies: - debug "^2.2.0" - handle-thing "^1.2.4" - http-deceiver "^1.2.4" + debug "^2.6.8" + handle-thing "^1.2.5" + http-deceiver "^1.2.7" + safe-buffer "^5.0.1" select-hose "^2.0.0" - spdy-transport "^2.0.15" + spdy-transport "^2.0.18" sprintf-js@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.0.tgz#cffcaf702daf65ea39bb4e0fa2b299cec1a1be46" + version "1.1.1" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -5648,7 +5679,6 @@ sshpk@^1.7.0: optionalDependencies: bcrypt-pbkdf "^1.0.0" ecc-jsbn "~0.1.1" - jodid25519 "^1.0.0" jsbn "~0.1.0" tweetnacl "~0.14.0" @@ -5711,10 +5741,10 @@ string_decoder@^0.10.25, string_decoder@~0.10.x: resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" string_decoder@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667" + version "1.0.2" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.2.tgz#b29e1f4e1125fa97a10382b8a533737b7491e179" dependencies: - buffer-shims "~1.0.0" + safe-buffer "~5.0.1" stringstream@~0.0.4: version "0.0.5" @@ -5891,8 +5921,8 @@ tildify@^1.0.0: os-homedir "^1.0.0" time-stamp@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.0.1.tgz#9f4bd23559c9365966f3302dbba2b07c6b99b151" + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" timers-browserify@^2.0.2: version "2.0.2" @@ -5993,28 +6023,28 @@ tsickle@^0.21.0: source-map "^0.5.6" source-map-support "^0.4.2" -tslib@^1.6.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.0.tgz#6e8366695f72961252b35167b0dd4fbeeafba491" +tslib@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.1.tgz#bc8004164691923a79fe8378bbeb3da2017538ec" tslint@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.2.0.tgz#16a2addf20cb748385f544e9a0edab086bc34114" + version "5.4.3" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.4.3.tgz#761c8402b80e347b7733a04390a757b253580467" dependencies: babel-code-frame "^6.22.0" colors "^1.1.2" + commander "^2.9.0" diff "^3.2.0" - findup-sync "~0.3.0" glob "^7.1.1" - optimist "~0.6.0" + minimatch "^3.0.4" resolve "^1.3.2" semver "^5.3.0" - tslib "^1.6.0" - tsutils "^1.8.0" + tslib "^1.7.1" + tsutils "^2.3.0" -tsutils@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-1.8.0.tgz#bf8118ed8e80cd5c9fc7d75728c7963d44ed2f52" +tsutils@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.3.0.tgz#96e661d7c2363f31adc8992ac67bbe7b7fc175e5" tty-browserify@0.0.0: version "0.0.0" @@ -6034,7 +6064,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" -type-is@~1.6.14: +type-is@~1.6.15: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" dependencies: @@ -6045,17 +6075,20 @@ typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -"typescript@>=2.0.0 <2.3.0": - version "2.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c" +"typescript@>=2.0.0 <2.4.0", typescript@^2.3.2: + version "2.3.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.4.tgz#3d38321828231e434f287514959c37a82b629f42" -typescript@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.2.tgz#f0f045e196f69a72f06b25fd3bd39d01c3ce9984" +uglify-js@3.0.x: + version "3.0.15" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.15.tgz#aacb323a846b234602270dead8a32441a8806f42" + dependencies: + commander "~2.9.0" + source-map "~0.5.1" -uglify-js@^2.6, uglify-js@^2.7.5, uglify-js@~2.8.22: - version "2.8.24" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.24.tgz#48eb5175cf32e22ec11a47e638d7c8b4e0faf2dd" +uglify-js@^2.6, uglify-js@^2.8.5: + version "2.8.28" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.28.tgz#e335032df9bb20dcb918f164589d5af47f38834a" dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -6205,7 +6238,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" -vary@~1.1.0: +vary@~1.1.0, vary@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" @@ -6298,13 +6331,13 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" walk-sync@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.1.tgz#558a16aeac8c0db59c028b73c66f397684ece465" + version "0.3.2" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.2.tgz#4827280afc42d0e035367c4a4e31eeac0d136f75" dependencies: ensure-posix-path "^1.0.0" matcher-collection "^1.0.0" -watchpack@^1.2.0: +watchpack@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.3.1.tgz#7d8693907b28ce6013e7f3610aa2a1acf07dad87" dependencies: @@ -6312,15 +6345,15 @@ watchpack@^1.2.0: chokidar "^1.4.3" graceful-fs "^4.1.2" -wbuf@^1.1.0, wbuf@^1.4.0: +wbuf@^1.1.0, wbuf@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.2.tgz#d697b99f1f59512df2751be42769c1580b5801fe" dependencies: minimalistic-assert "^1.0.0" -web-animations-js@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/web-animations-js/-/web-animations-js-2.2.2.tgz#7c3aa5382c5eade70cd206880d56a37869630638" +web-animations-js@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/web-animations-js/-/web-animations-js-2.2.5.tgz#26ca1b34c1347332a0813f8b2bfe69664efa80aa" webdriver-js-extender@^1.0.0: version "1.0.0" @@ -6329,7 +6362,7 @@ webdriver-js-extender@^1.0.0: "@types/selenium-webdriver" "^2.53.35" selenium-webdriver "^2.53.2" -webdriver-manager@^12.0.1: +webdriver-manager@^12.0.6: version "12.0.6" resolved "https://registry.yarnpkg.com/webdriver-manager/-/webdriver-manager-12.0.6.tgz#3df1a481977010b4cbf8c9d85c7a577828c0e70b" dependencies: @@ -6345,7 +6378,7 @@ webdriver-manager@^12.0.1: semver "^5.3.0" xml2js "^0.4.17" -webpack-dev-middleware@^1.0.11, webpack-dev-middleware@^1.10.2: +webpack-dev-middleware@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.2.tgz#2e252ce1dfb020dbda1ccb37df26f30ab014dbd1" dependencies: @@ -6354,7 +6387,7 @@ webpack-dev-middleware@^1.0.11, webpack-dev-middleware@^1.10.2: path-is-absolute "^1.0.0" range-parser "^1.0.3" -webpack-dev-server@~2.4.2: +webpack-dev-server@~2.4.5: version "2.4.5" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.4.5.tgz#31384ce81136be1080b4b4cde0eb9b90e54ee6cf" dependencies: @@ -6382,18 +6415,25 @@ webpack-merge@^2.4.0: dependencies: lodash "^4.17.4" -webpack-sources@^0.1.0, webpack-sources@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" +webpack-sources@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" dependencies: - source-list-map "~0.1.7" + source-list-map "^1.1.1" source-map "~0.5.3" -webpack@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.2.1.tgz#7bb1d72ae2087dd1a4af526afec15eed17dda475" +webpack-sources@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.1.tgz#c7356436a4d13123be2e2426a05d1dad9cbe65cf" dependencies: - acorn "^4.0.4" + source-list-map "^2.0.0" + source-map "~0.5.3" + +webpack@~2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.4.1.tgz#15a91dbe34966d8a4b99c7d656efd92a2e5a6f6a" + dependencies: + acorn "^5.0.0" acorn-dynamic-import "^2.0.0" ajv "^4.7.0" ajv-keywords "^1.1.1" @@ -6401,6 +6441,7 @@ webpack@~2.2.0: enhanced-resolve "^3.0.0" interpret "^1.0.0" json-loader "^0.5.4" + json5 "^0.5.1" loader-runner "^2.3.0" loader-utils "^0.2.16" memory-fs "~0.4.1" @@ -6409,9 +6450,9 @@ webpack@~2.2.0: source-map "^0.5.3" supports-color "^3.1.0" tapable "~0.2.5" - uglify-js "^2.7.5" - watchpack "^1.2.0" - webpack-sources "^0.1.4" + uglify-js "^2.8.5" + watchpack "^1.3.1" + webpack-sources "^0.2.3" yargs "^6.0.0" websocket-driver@>=0.5.1: @@ -6551,6 +6592,12 @@ yargs-parser@^4.2.0: dependencies: camelcase "^3.0.0" +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + dependencies: + camelcase "^3.0.0" + yargs@^6.0.0, yargs@^6.6.0: version "6.6.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" @@ -6569,6 +6616,24 @@ yargs@^6.0.0, yargs@^6.6.0: y18n "^3.2.1" yargs-parser "^4.2.0" +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" @@ -6594,6 +6659,6 @@ yn@^1.2.0: dependencies: object-assign "^4.1.1" -zone.js@^0.8.4, zone.js@^0.8.6: - version "0.8.10" - resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.8.10.tgz#6d1b696492c029cdbe808e59e87bbd9491b98aa8" +zone.js@^0.8.4, zone.js@^0.8.9: + version "0.8.12" + resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.8.12.tgz#86ff5053c98aec291a0bf4bbac501d694a05cfbb" From 5a858c7a94bd3247487684a7473a2657105dbe2a Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Fri, 9 Jun 2017 12:43:21 -0700 Subject: [PATCH 32/35] feat(message): add animation when opening/closing (#671) * feat(message): add animation when opening/closing * fix(): typo in fadeAnimation binding * fix(message): issue when it always was attached even if initialized as false fixed unit tests and added some more * fix(): stop using `start` binding for animations there is a problem when unit testing where it throws the events in reverse order https://github.com/angular/angular/issues/17375 --- .../core/message/message.component.spec.ts | 57 +++++++++--- .../core/message/message.component.ts | 91 ++++++++++++++++--- 2 files changed, 124 insertions(+), 24 deletions(-) diff --git a/src/platform/core/message/message.component.spec.ts b/src/platform/core/message/message.component.spec.ts index ea8a8e4a66..18f984c5e4 100644 --- a/src/platform/core/message/message.component.spec.ts +++ b/src/platform/core/message/message.component.spec.ts @@ -81,7 +81,6 @@ describe('Component: Message', () => { fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.td-message-label'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('.td-message-sublabel'))).toBeFalsy(); done(); @@ -95,8 +94,6 @@ describe('Component: Message', () => { component.color = 'primary'; fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.td-message-wrapper')).query(By.css('button'))).toBeTruthy(); done(); }); @@ -111,19 +108,16 @@ describe('Component: Message', () => { component.color = 'primary'; fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeTruthy(); message.close(); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeFalsy(); message.open(); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeTruthy(); done(); }); @@ -131,6 +125,32 @@ describe('Component: Message', () => { }); }); + it('should not render the component, open it and then close it', (done: DoneFn) => { + let fixture: ComponentFixture = TestBed.createComponent(TdMessageOpenedTestComponent); + let component: TdMessageOpenedTestComponent = fixture.debugElement.componentInstance; + let message: TdMessageComponent = fixture.debugElement.query(By.directive(TdMessageComponent)).componentInstance; + + component.label = 'Label'; + component.color = 'primary'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeFalsy(); + + message.open(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeTruthy(); + + message.close(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeFalsy(); + done(); + }); + }); + }); + }); + it('should render the component, toggle it and then toggle it again', (done: DoneFn) => { let fixture: ComponentFixture = TestBed.createComponent(TdMessageBasicTestComponent); let component: TdMessageBasicTestComponent = fixture.debugElement.componentInstance; @@ -140,19 +160,16 @@ describe('Component: Message', () => { component.color = 'primary'; fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeTruthy(); message.toggle(); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeFalsy(); message.toggle(); fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeTruthy(); done(); }); @@ -160,6 +177,25 @@ describe('Component: Message', () => { }); }); + it('should render the component, then [opened] to false', (done: DoneFn) => { + let fixture: ComponentFixture = TestBed.createComponent(TdMessageOpenedTestComponent); + let component: TdMessageOpenedTestComponent = fixture.debugElement.componentInstance; + + component.opened = true; + component.label = 'Label'; + component.color = 'primary'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeTruthy(); + component.opened = false; + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeFalsy(); + done(); + }); + }); + }); + it('should not render the component, set [opened] to true and then [opened] to false', (done: DoneFn) => { let fixture: ComponentFixture = TestBed.createComponent(TdMessageOpenedTestComponent); let component: TdMessageOpenedTestComponent = fixture.debugElement.componentInstance; @@ -168,19 +204,16 @@ describe('Component: Message', () => { component.color = 'primary'; fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeFalsy(); component.opened = true; fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeTruthy(); component.opened = false; fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.td-message-wrapper'))).toBeFalsy(); done(); }); diff --git a/src/platform/core/message/message.component.ts b/src/platform/core/message/message.component.ts index 854ad923f5..772fb64770 100644 --- a/src/platform/core/message/message.component.ts +++ b/src/platform/core/message/message.component.ts @@ -1,5 +1,8 @@ import { Component, Directive, Input, Renderer2, ElementRef, AfterViewInit, ViewContainerRef, TemplateRef, ViewChild, - HostBinding, ChangeDetectorRef } from '@angular/core'; + HostBinding, HostListener, ChangeDetectorRef } from '@angular/core'; + +import { TdCollapseAnimation } from '../common/animations/collapse/collapse.animation'; +import { TdFadeInOutAnimation } from '../common/animations/fade/fadeInOut.animation'; @Directive({ selector: '[tdMessageContainer]', @@ -12,19 +15,44 @@ export class TdMessageContainerDirective { selector: 'td-message', templateUrl: './message.component.html', styleUrls: ['./message.component.scss'], + animations: [ + TdCollapseAnimation(100), + TdFadeInOutAnimation(100), + ], }) export class TdMessageComponent implements AfterViewInit { private _color: string; private _opened: boolean = true; + private _hidden: boolean = false; + private _animating: boolean = false; private _initialized: boolean = false; @ViewChild(TdMessageContainerDirective) _childElement: TdMessageContainerDirective; @ViewChild(TemplateRef) _template: TemplateRef; + /** + * Binding host to tdFadeInOut animation + */ + @HostBinding('@tdFadeInOut') + get fadeAnimation(): boolean { + return this._opened; + } + + /** + * Binding host to tdCollapse animation + */ + @HostBinding('@tdCollapse') + get collapsedAnimation(): boolean { + return !this._opened; + } + + /** + * Binding host to display style when hidden + */ @HostBinding('style.display') get hidden(): string { - return !this._opened ? 'none' : undefined; + return this._hidden ? 'none' : undefined; } /** @@ -102,37 +130,51 @@ export class TdMessageComponent implements AfterViewInit { } /** - * Initializes the component and attaches the content if [opened] was true. + * Detach element when close animation is finished to set animating state to false + * hidden state to true and detach element from DOM + */ + @HostListener('@tdCollapse.done') + animationDoneListener(): void { + if (!this._opened) { + this._hidden = true; + this._detach(); + } + this._animating = false; + this._changeDetectorRef.markForCheck(); + } + + /** + * Initializes the component and attaches the content. */ ngAfterViewInit(): void { Promise.resolve(undefined).then(() => { if (this._opened) { - this._childElement.viewContainer.createEmbeddedView(this._template); - this._changeDetectorRef.markForCheck(); + this._attach(); } this._initialized = true; }); } /** - * Renders the message on screen. + * Renders the message on screen + * Validates if there is an animation currently and if its already opened */ open(): void { - if (!this._opened) { + if (!this._opened && !this._animating) { this._opened = true; - this._childElement.viewContainer.createEmbeddedView(this._template); - this._changeDetectorRef.markForCheck(); + this._attach(); + this._startAnimationState(); } } /** * Removes the message content from screen. + * Validates if there is an animation currently and if its already closed */ close(): void { - if (this._opened) { + if (this._opened && !this._animating) { this._opened = false; - this._childElement.viewContainer.clear(); - this._changeDetectorRef.markForCheck(); + this._startAnimationState(); } } @@ -146,4 +188,29 @@ export class TdMessageComponent implements AfterViewInit { this.open(); } } + + /** + * Method to set the state before starting an animation + */ + private _startAnimationState(): void { + this._animating = true; + this._hidden = false; + this._changeDetectorRef.markForCheck(); + } + + /** + * Method to attach template to DOM + */ + private _attach(): void { + this._childElement.viewContainer.createEmbeddedView(this._template); + this._changeDetectorRef.markForCheck(); + } + + /** + * Method to detach template from DOM + */ + private _detach(): void { + this._childElement.viewContainer.clear(); + this._changeDetectorRef.markForCheck(); + } } From 44fb6720278e3edd90b95832843754e948cd49e5 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Fri, 9 Jun 2017 12:57:43 -0700 Subject: [PATCH 33/35] chore(): update changelog and notification updates (#681) * chore(): first pass on changelog * chore(): add release name and update home notifications * fix(): make navigation absolute * chore(): update with changelog from 4.2.0 commit * changelog updates * chore(): final pass on changelog --- docs/CHANGELOG.md | 186 +++++++++++++++--- .../components/toolbar/toolbar.component.html | 4 +- .../components/toolbar/toolbar.component.ts | 84 ++++---- 3 files changed, 200 insertions(+), 74 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c6fae149f8..2548dca176 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,3 +1,129 @@ + +# [1.0.0-beta.5 Blackhole Sun](https://github.com/Teradata/covalent/tree/v1.0.0-beta.5) (2017-06-09) + +## Breaking Change + +#### td-chips + +Now that chips have async support and we've abstracted the internal filtering mechanism, the developer needs to provide their own filter. + +This will also allow the developer to create custom filters both locally and server-side. + +e.g. + +```html + + +``` + + +```typescript + +strings: string[] = [ + 'stepper', + 'expansion-panel', + 'markdown', + 'highlight', + 'loading', + 'media', + 'chips', + 'http', + 'json-formatter', + 'pipes', + 'need more?', +]; + +filteredStrings: string[]; + +stringsModel: string[] = this.strings.slice(0, 6); + +ngOnInit(): void { + this.filterStrings(''); +} + +filterStrings(value: string): void { + if (value) { + this.filteredStrings = this.strings.filter((item: any) => { + return item.toLowerCase().indexOf(value.toLowerCase()) > -1; + }).filter((filteredItem: any) => { + return this.stringsModel ? this.stringsModel.indexOf(filteredItem) < 0 : true; + }); + } +} +``` + +#### td-expansion-panel + +With the introduction of `td-expansion-panel-group`, the `td-expansion-panel` expanded margin animation will not be applied unless the `td-expansion-panel` is grouped inside of a `td-expansion-panel-group`. + +e.g. + +```html + + + + + + + + + +``` + +## Bug Fixes + +* **chips:** keep focused state as long as you keep clicking inside the chips context ([22d4342c4072560e3903820c4009f8129ec0d184](https://github.com/Teradata/covalent/commit/22d4342c4072560e3903820c4009f8129ec0d184)) +* **data-table:** not throw `(rowClick)` event when clicking on checkbox ([ec1cbd8c962d0e5610b075b6f3655afa589ba121](https://github.com/Teradata/covalent/commit/ec1cbd8c962d0e5610b075b6f3655afa589ba121)), closes [#611](https://github.com/Teradata/covalent/issues/611) +* **expansion-panel:** only render label and sublabel when its needed ([e62d3bd68553be7cee188c0b761c68d11247f902](https://github.com/Teradata/covalent/commit/e62d3bd68553be7cee188c0b761c68d11247f902)) +* **layout:** use `ScrollDispatcherModule` and leverage `cdkScrollable` in layouts so material components readjust when scrolling ([629d06f161c00f99218708570d6085acbf58ee4f](https://github.com/Teradata/covalent/commit/629d06f161c00f99218708570d6085acbf58ee4f)), closes [#620](https://github.com/Teradata/covalent/issues/620) +* **media:** make media service not use window directly ([90e16f5d7be080aee1601a2d86e72c47536c3e40](https://github.com/Teradata/covalent/commit/90e16f5d7be080aee1601a2d86e72c47536c3e40)) +* **stepper:** horizontal scroll was not appearing when needed in certain cases ([9542139ba7b8e84435b1cda47f875b927787a64a](https://github.com/Teradata/covalent/commit/9542139ba7b8e84435b1cda47f875b927787a64a)), closes [#282](https://github.com/Teradata/covalent/issues/282) +* **stepper:** add `cdkScrollable` so material component can hook into it ([9542139ba7b8e84435b1cda47f875b927787a64a](https://github.com/Teradata/covalent/commit/9542139ba7b8e84435b1cda47f875b927787a64a)) +* **styles:** fix sm/md/lg card images in title-group ([dda5d9cc3c5fe5728b9b9b27f8a6afa95f969861](https://github.com/Teradata/covalent/commit/dda5d9cc3c5fe5728b9b9b27f8a6afa95f969861)) +* **theme:** remove duplicate functions that are already part of material ([98eaf28287db5ebe0597804818a99a11fe82b00a](https://github.com/Teradata/covalent/commit/98eaf28287db5ebe0597804818a99a11fe82b00a)), closes [#632](https://github.com/Teradata/covalent/issues/632) + +## Features + +* **chips:** new `[chipRemoval]` input to block chips from being removed ([51ba94db1b7adef51a67407fc9db8504678a9af8](https://github.com/Teradata/covalent/commit/51ba94db1b7adef51a67407fc9db8504678a9af8)) +* **chips:** add `[color]` input to change the color of focused chips, input and underline ([5c2635c6548741442100b98724adcf607c6fb770](https://github.com/Teradata/covalent/commit/5c2635c6548741442100b98724adcf607c6fb770)), closes [#605](https://github.com/Teradata/covalent/issues/605) +* **chips:** new `[stacked]` input to make chips stack vertically. ([9a18a6314853f35991868cd0260884fa4cc5b3a4](https://github.com/Teradata/covalent/commit/9a18a6314853f35991868cd0260884fa4cc5b3a4)) +* **chips:** ability to use object lists and set templates for both autocomplete and chips ([22d4342c4072560e3903820c4009f8129ec0d184](https://github.com/Teradata/covalent/commit/22d4342c4072560e3903820c4009f8129ec0d184)) +* **chips:** abstract the autocomplete filtering and add debounce input (local vs server) ([22d4342c4072560e3903820c4009f8129ec0d184](https://github.com/Teradata/covalent/commit/22d4342c4072560e3903820c4009f8129ec0d184)), closes [#252](https://github.com/Teradata/covalent/issues/252), [#359](https://github.com/Teradata/covalent/issues/252), [#359](https://github.com/Teradata/covalent/issues/601) +* **chips:** add `td-chip-avatar` when using template `td-chip` to mimic a contact chip ([fe9daccb5fd436a3ca527d4e694cc2e02e26f79d](https://github.com/Teradata/covalent/commit/fe9daccb5fd436a3ca527d4e694cc2e02e26f79d)) +* **dependencies:** upgrade to `@angular/material@1.0.0-beta.6` ([629d06f161c00f99218708570d6085acbf58ee4f](https://github.com/Teradata/covalent/commit/629d06f161c00f99218708570d6085acbf58ee4f)) +* **dialog:** improve `prompt-dialog` a11y by selection text in input when focused ([e9427aaee1520a83326cd242850b525915b7c5fe](https://github.com/Teradata/covalent/commit/e9427aaee1520a83326cd242850b525915b7c5fe)), closes [#616](https://github.com/Teradata/covalent/issues/616) +* **expansion-panel:** introducing `td-expansion-panel-group` to only give margin to expansion panels when grouped ([9ae0ba532bbabde6eca8d1b4315667333e83ae35](https://github.com/Teradata/covalent/commit/9ae0ba532bbabde6eca8d1b4315667333e83ae35)) +* **expansion-panel:** add `[disableRipple]` input to disable ripple effect on demand ([33810ce86915c6d1e948e426a6056500d88e6827](https://github.com/Teradata/covalent/commit/33810ce86915c6d1e948e426a6056500d88e6827)) +* **layout:** add `[mode]`, `[opened]` and `[sidenavWidth]` to `td-layout` ([e2172fafdd7ea03f7db1df8d21abea4238e14d65](https://github.com/Teradata/covalent/commit/e2172fafdd7ea03f7db1df8d21abea4238e14d65)) +* **layout:** add `[color]` input to `td-layout-footer` ([e912ef4bed205d7da4743d83c45bce3edf150084](https://github.com/Teradata/covalent/commit/e912ef4bed205d7da4743d83c45bce3edf150084)), closes [#489](https://github.com/Teradata/covalent/issues/489) +* **message:** add animation when opening/closing ([5a858c7a94bd3247487684a7473a2657105dbe2a](https://github.com/Teradata/covalent/commit/5a858c7a94bd3247487684a7473a2657105dbe2a)) +* **stepper:** add `[disableRipple]` input to disable ripple effect on demand ([33810ce86915c6d1e948e426a6056500d88e6827](https://github.com/Teradata/covalent/commit/33810ce86915c6d1e948e426a6056500d88e6827)) + +## Performance +* **all:** make sure all services are singleton when provided ([4544c1a5bcabb1fa3e60b6fe6c2f6e1a5215ab5c](https://github.com/Teradata/covalent/commit/4544c1a5bcabb1fa3e60b6fe6c2f6e1a5215ab5c)) +* **chips:** support `OnPush` change detection ([22d4342c4072560e3903820c4009f8129ec0d184](https://github.com/Teradata/covalent/commit/22d4342c4072560e3903820c4009f8129ec0d184)) +* **expansion-panel:** improved animation performance when toggling in group ([9ae0ba532bbabde6eca8d1b4315667333e83ae35](https://github.com/Teradata/covalent/commit/9ae0ba532bbabde6eca8d1b4315667333e83ae35)) + + +## Internal +* **animations:** make toggle directive use new animations API ([90e16f5d7be080aee1601a2d86e72c47536c3e40](https://github.com/Teradata/covalent/commit/90e16f5d7be080aee1601a2d86e72c47536c3e40)) +* **animations:** make fade directive use new animations API ([90e16f5d7be080aee1601a2d86e72c47536c3e40](https://github.com/Teradata/covalent/commit/90e16f5d7be080aee1601a2d86e72c47536c3e40)) +* **dependencies:** upgrade to @angular@4.2.0 ([90e16f5d7be080aee1601a2d86e72c47536c3e40](https://github.com/Teradata/covalent/commit/90e16f5d7be080aee1601a2d86e72c47536c3e40)) +* **dependencies:** upgrade to @angular/cli@1.1.0 ([90e16f5d7be080aee1601a2d86e72c47536c3e40](https://github.com/Teradata/covalent/commit/90e16f5d7be080aee1601a2d86e72c47536c3e40)) +* **docs:** new landing page and theme ([615a4ee02976f4d0ffa0f0394c562cbdcdce5a25](https://github.com/Teradata/covalent/commit/615a4ee02976f4d0ffa0f0394c562cbdcdce5a25)) +* **docs:** fix rtl/lrt demo in docs ([7874b5b7a371aeffe9d9d239e910ab31c3a79399](https://github.com/Teradata/covalent/commit/7874b5b7a371aeffe9d9d239e910ab31c3a79399)) +* **docs:** add selective preload strategy for lazy loading ([3b4da1cd72b64d20b6f0deb8c7668d785cbd272a](https://github.com/Teradata/covalent/commit/3b4da1cd72b64d20b6f0deb8c7668d785cbd272a)) +* **docs:** improved demos/examples +* **docs:** make docs render properly in IE11 ([a118fb9e9f5b83c830f7be9bc7ea19586e1067f6](https://github.com/Teradata/covalent/commit/a118fb9e9f5b83c830f7be9bc7ea19586e1067f6)) +* **chips:** add more unit tests +* **validators:** remove max/min validators since angular already has them ([8e9ab29d170f91bc61a54cb07581e0631a576410](https://github.com/Teradata/covalent/commit/8e9ab29d170f91bc61a54cb07581e0631a576410)) +* **stepper:** change internal label class to `mat-inactive` ([bb9331b3dffb93c4e96281c8d9469fa8f12e52e3](https://github.com/Teradata/covalent/commit/bb9331b3dffb93c4e96281c8d9469fa8f12e52e3)) + + # [1.0.0-beta.4 Johnny B Goode](https://github.com/Teradata/covalent/tree/v1.0.0-beta.4) (2017-05-16) @@ -18,7 +144,7 @@ import: [ This was announced as deprecated in `beta.3` to make developer import only what they need to reduce bundle size. -* **dependencies:** removal of flex-layout dependency ([a15d4936fb1ded2e2c1b8907c6b9a72892c946b7](https://github.com/Teradata/covalent/commit/a15d4936fb1ded2e2c1b8907c6b9a72892c946b7)), closes [#542](https://github.com/Teradata/covalent/issues/542) +* **dependencies:** removal of flex-layout dependency ([a15d4936fb1ded2e2c1b8907c6b9a72892c946b7](https://github.com/Teradata/covalent/commit/a15d4936fb1ded2e2c1b8907c6b9a72892c946b7)), closes [#542](https://github.com/Teradata/covalent/issues/542) Since `CovalentCoreModule` has been removed, there is really no use for @angular/flex-layout inernally. we will leave it to the developer to include it on demand. @@ -33,18 +159,18 @@ These selectors were deprecated a few releases back so it should be ok to remove ## Bug Fixes * **chips:** added missing rxjs/add/operator/debounceTime import ([755f84664e65dfa52b131406a8979c8f3502f1c2](https://github.com/Teradata/covalent/commit/755f84664e65dfa52b131406a8979c8f3502f1c2)) * **data-table:** fix when data is undefined and multiple selection ([783228f15154ec04911abf92da0bb199c67190de](https://github.com/Teradata/covalent/commit/783228f15154ec04911abf92da0bb199c67190de)) -* **data-table:** fix pseudo checkbox css ([d4d90a2cd20a30f6774a5198526381228a64363a](https://github.com/Teradata/covalent/commit/d4d90a2cd20a30f6774a5198526381228a64363a)), closes [#525](https://github.com/Teradata/covalent/issues/525) +* **data-table:** fix pseudo checkbox css ([d4d90a2cd20a30f6774a5198526381228a64363a](https://github.com/Teradata/covalent/commit/d4d90a2cd20a30f6774a5198526381228a64363a)), closes [#525](https://github.com/Teradata/covalent/issues/525) * **dev:** fix tsconfig typeRoots file path ([bec8a3a0d4c99123abe04426071ce3d5d81d9cf0](https://github.com/Teradata/covalent/commit/bec8a3a0d4c99123abe04426071ce3d5d81d9cf0)) -* **dynamic-forms:** fix AoT issue with min/max validators ([5bd684fdbd82d8b57bc6bb444cbe3f4e90b33f75](https://github.com/Teradata/covalent/commit/5bd684fdbd82d8b57bc6bb444cbe3f4e90b33f75)), closes [#508](https://github.com/Teradata/covalent/issues/508) -* **flex:** flex=“value” for grow/initial/auto/none/noshink/nogrow ([141550fc5429f8808224786bd7fc7e1119a84601](https://github.com/Teradata/covalent/commit/141550fc5429f8808224786bd7fc7e1119a84601)), closes [#586](https://github.com/Teradata/covalent/issues/586) +* **dynamic-forms:** fix AoT issue with min/max validators ([5bd684fdbd82d8b57bc6bb444cbe3f4e90b33f75](https://github.com/Teradata/covalent/commit/5bd684fdbd82d8b57bc6bb444cbe3f4e90b33f75)), closes [#508](https://github.com/Teradata/covalent/issues/508) +* **flex:** flex=“value” for grow/initial/auto/none/noshink/nogrow ([141550fc5429f8808224786bd7fc7e1119a84601](https://github.com/Teradata/covalent/commit/141550fc5429f8808224786bd7fc7e1119a84601)), closes [#586](https://github.com/Teradata/covalent/issues/586) * **loading:** remove OnPush change detection from `td-loading` since its a container component ([baea6b384f0c01f54a54b649aecf2b08ae276333](https://github.com/Teradata/covalent/commit/baea6b384f0c01f54a54b649aecf2b08ae276333)) -* **pipes:** convert bytes using powers of 2 in `TdBytesPipe` ([c77d517e8ae3beb94e6d4fa68503da7ebafaae9b](https://github.com/Teradata/covalent/commit/c77d517e8ae3beb94e6d4fa68503da7ebafaae9b)), closes [#527](https://github.com/Teradata/covalent/issues/527) +* **pipes:** convert bytes using powers of 2 in `TdBytesPipe` ([c77d517e8ae3beb94e6d4fa68503da7ebafaae9b](https://github.com/Teradata/covalent/commit/c77d517e8ae3beb94e6d4fa68503da7ebafaae9b)), closes [#527](https://github.com/Teradata/covalent/issues/527) ## Features * **chips:** ability to disable chip addition (input). ([1c75d35b3a399b2236ec49000e2c85af57552723](https://github.com/Teradata/covalent/commit/1c75d35b3a399b2236ec49000e2c85af57552723)), closes [#500](https://github.com/Teradata/covalent/issues/500) * **data-table:** ability to exclude columns when filtering data ([11c3d15a12b789d561fdb19bc1bad62d7a2f5eb3](https://github.com/Teradata/covalent/commit/11c3d15a12b789d561fdb19bc1bad62d7a2f5eb3)), closes [#513](https://github.com/Teradata/covalent/issues/513) -* **data-table:** ability to hide data table columns ([0ccb19190a6376adcd2345a1a62c642a38b2f11b](https://github.com/Teradata/covalent/commit/0ccb19190a6376adcd2345a1a62c642a38b2f11b)), closes [#511](https://github.com/Teradata/covalent/issues/511) -* **data-table:** indeterminate state in 'selectAll' checkbox ([bd0f7bcd64845801b96fb57a3de42e914da947f6](https://github.com/Teradata/covalent/commit/bd0f7bcd64845801b96fb57a3de42e914da947f6)), closes [#571](https://github.com/Teradata/covalent/issues/571) +* **data-table:** ability to hide data table columns ([0ccb19190a6376adcd2345a1a62c642a38b2f11b](https://github.com/Teradata/covalent/commit/0ccb19190a6376adcd2345a1a62c642a38b2f11b)), closes [#511](https://github.com/Teradata/covalent/issues/511) +* **data-table:** indeterminate state in 'selectAll' checkbox ([bd0f7bcd64845801b96fb57a3de42e914da947f6](https://github.com/Teradata/covalent/commit/bd0f7bcd64845801b96fb57a3de42e914da947f6)), closes [#571](https://github.com/Teradata/covalent/issues/571) * **data-table:** `(rowClick)` event for datatable rows enabled by new `[clickable]` input ([4f84c6ce493996fd749b55d2012f9eb6f4a9e367](https://github.com/Teradata/covalent/commit/4f84c6ce493996fd749b55d2012f9eb6f4a9e367)), closes [#468](https://github.com/Teradata/covalent/issues/468) * **data-table:** select event will be trigger only when clicking on checkbox ([4f84c6ce493996fd749b55d2012f9eb6f4a9e367](https://github.com/Teradata/covalent/commit/4f84c6ce493996fd749b55d2012f9eb6f4a9e367)), closes [#592](https://github.com/Teradata/covalent/issues/592) * **data-table:** shift-click for multiple row selection/deselection ([4f84c6ce493996fd749b55d2012f9eb6f4a9e367](https://github.com/Teradata/covalent/commit/4f84c6ce493996fd749b55d2012f9eb6f4a9e367)) @@ -53,12 +179,12 @@ These selectors were deprecated a few releases back so it should be ok to remove * **dependencies:** upgrade to `material@beta.5` ([b802efbc59e912b8c49fcc8540c77ff98eb829f3](https://github.com/Teradata/covalent/commit/b802efbc59e912b8c49fcc8540c77ff98eb829f3)) * **file:** add new `[formData]` property to TdFileService#upload options ([77c89acd4ba83b43754ce422fd74e6351e2a6297](https://github.com/Teradata/covalent/commit/77c89acd4ba83b43754ce422fd74e6351e2a6297)), closes [#546](https://github.com/Teradata/covalent/issues/546) * **file-upload:** add `cancel` event when cancel button is pressed ([9e3be77fb885928fb54e01adb8d023c3e26d7800](https://github.com/Teradata/covalent/commit/9e3be77fb885928fb54e01adb8d023c3e26d7800)), closes [#499](https://github.com/Teradata/covalent/issues/499) -* **highlight:** added `(contentReady)` event binding. ([b3e800cb5342722a50a97292bc81ea8282d3659e](https://github.com/Teradata/covalent/commit/b3e800cb5342722a50a97292bc81ea8282d3659e)), closes [#553](https://github.com/Teradata/covalent/issues/553) +* **highlight:** added `(contentReady)` event binding. ([b3e800cb5342722a50a97292bc81ea8282d3659e](https://github.com/Teradata/covalent/commit/b3e800cb5342722a50a97292bc81ea8282d3659e)), closes [#553](https://github.com/Teradata/covalent/issues/553) * **layout:** if [navigationRoute] is not set, then the icon/logo/title will not be navigatable. ([dda9b4b5fa6f2b44ce558665c49f1f06b0390237](https://github.com/Teradata/covalent/commit/dda9b4b5fa6f2b44ce558665c49f1f06b0390237)) -* **loading:** support for async and boolean with [until] input ([d57bf6757eb3426bd7404edb4b0d1d51c46f6478](https://github.com/Teradata/covalent/commit/d57bf6757eb3426bd7404edb4b0d1d51c46f6478)), closes [#528](https://github.com/Teradata/covalent/issues/528) +* **loading:** support for async and boolean with [until] input ([d57bf6757eb3426bd7404edb4b0d1d51c46f6478](https://github.com/Teradata/covalent/commit/d57bf6757eb3426bd7404edb4b0d1d51c46f6478)), closes [#528](https://github.com/Teradata/covalent/issues/528) * **markdown:** added `(contentReady)` event binding. ([cdf6cad19b3972259e78809aaff5aca6ba408bb1](https://github.com/Teradata/covalent/commit/cdf6cad19b3972259e78809aaff5aca6ba408bb1)), closes [#536](https://github.com/Teradata/covalent/issues/536) -* **message:** introducing `message` module for easy display of inline messages or info boxes ([8a517fb516ea2344a6471d22ec6b23b8fca8fc60](https://github.com/Teradata/covalent/commit/8a517fb516ea2344a6471d22ec6b23b8fca8fc60)), closes [#316](https://github.com/Teradata/covalent/issues/316) -* **paging:** ability to jump to page `n` with page links in `TdPagingBarComponent` ([459dcb3186a72d4e3f5d51108b7723698a13fffa](https://github.com/Teradata/covalent/commit/459dcb3186a72d4e3f5d51108b7723698a13fffa)), closes [#496](https://github.com/Teradata/covalent/issues/496) +* **message:** introducing `message` module for easy display of inline messages or info boxes ([8a517fb516ea2344a6471d22ec6b23b8fca8fc60](https://github.com/Teradata/covalent/commit/8a517fb516ea2344a6471d22ec6b23b8fca8fc60)), closes [#316](https://github.com/Teradata/covalent/issues/316) +* **paging:** ability to jump to page `n` with page links in `TdPagingBarComponent` ([459dcb3186a72d4e3f5d51108b7723698a13fffa](https://github.com/Teradata/covalent/commit/459dcb3186a72d4e3f5d51108b7723698a13fffa)), closes [#496](https://github.com/Teradata/covalent/issues/496) ## Internal * **chips:** added initial unit tests for `TdChipsComponent` ([755f84664e65dfa52b131406a8979c8f3502f1c2](https://github.com/Teradata/covalent/commit/755f84664e65dfa52b131406a8979c8f3502f1c2)) @@ -155,7 +281,7 @@ These selectors were deprecated a few releases back so it should be ok to remove * **docs:** update docs to updated Material style prefixes ([9142f083e55b77c3f8e89dfde318d23842388f20](https://github.com/Teradata/covalent/commit/9142f083e55b77c3f8e89dfde318d23842388f20)), closes [#410](https://github.com/Teradata/covalent/issues/410) * **docs:** clarify instructions to include the `platform.css` ([5d6bfe5110c29df6986cb4dd15135f0aa784c0f4](https://github.com/Teradata/covalent/commit/5d6bfe5110c29df6986cb4dd15135f0aa784c0f4)) * **docs:** add covalent-electron and covalent-data to README and docs ([878bacecde77f0e824669ed70ff62b89b7daff19](https://github.com/Teradata/covalent/commit/878bacecde77f0e824669ed70ff62b89b7daff19)) -* **theming:** use internal theme functions instead of materials. ([cc74bc154bd076eeaf965686127d9c5cf3c63969](https://github.com/Teradata/covalent/commit/cc74bc154bd076eeaf965686127d9c5cf3c63969))closes [#446](https://github.com/Teradata/covalent/issues/446), [#450](https://github.com/Teradata/covalent/issues/450), [#232](https://github.com/Teradata/covalent/issues/232), [#423](https://github.com/Teradata/covalent/issues/423) +* **theming:** use internal theme functions instead of materials. ([cc74bc154bd076eeaf965686127d9c5cf3c63969](https://github.com/Teradata/covalent/commit/cc74bc154bd076eeaf965686127d9c5cf3c63969))closes [#446](https://github.com/Teradata/covalent/issues/446), [#450](https://github.com/Teradata/covalent/issues/450), [#232](https://github.com/Teradata/covalent/issues/232), [#423](https://github.com/Teradata/covalent/issues/423) # [1.0.0-beta.2-1](https://github.com/Teradata/covalent/tree/v1.0.0-beta.2) (2017-02-27) @@ -173,7 +299,7 @@ These selectors were deprecated a few releases back so it should be ok to remove ## Breaking Change * **material:** [breaking changes](https://github.com/angular/material2/blob/master/CHANGELOG.md#breaking-changes-from-beta1) from `@material`. -* **file-upload:** add way to set its labels for easier i18n usage ([c91d3cdd61358a1af2ad459cd67f56d62070c3c7](https://github.com/Teradata/covalent/commit/c91d3cdd61358a1af2ad459cd67f56d62070c3c7)), closes [#286](https://github.com/Teradata/covalent/issues/286) +* **file-upload:** add way to set its labels for easier i18n usage ([c91d3cdd61358a1af2ad459cd67f56d62070c3c7](https://github.com/Teradata/covalent/commit/c91d3cdd61358a1af2ad459cd67f56d62070c3c7)), closes [#286](https://github.com/Teradata/covalent/issues/286) Usage: @@ -214,7 +340,7 @@ These selectors were deprecated a few releases back so it should be ok to remove ``` npm install --save https://github.com/Teradata/covalent-nightly.git ``` -* **covalent-data:** new `0.7.0` [@covalent/data](https://github.com/Teradata/covalent-data) release. +* **covalent-data:** new `0.7.0` [@covalent/data](https://github.com/Teradata/covalent-data) release. * **data-table:** add a way to configure a specific column as `sortable`. ([3e24fcfd505395da2f18db2fe2dd96f5cc6e8b87](https://github.com/Teradata/covalent/commit/3e24fcfd505395da2f18db2fe2dd96f5cc6e8b87)), closes [#347](https://github.com/Teradata/covalent/issues/347) * **data-table:** leverage the `md-pseudo-checkbox` to render the selectable rows more efficiently. ([717d309d0a31f21c0dc9870ea3f3f3b40f248a07](https://github.com/Teradata/covalent/commit/717d309d0a31f21c0dc9870ea3f3f3b40f248a07)) * **dependencies:** add documentation on how to use `ngx-translate` and `LOCALE_ID`. ([776331bb5bc4098a4264a36e1275b3c83727e61a](https://github.com/Teradata/covalent/commit/776331bb5bc4098a4264a36e1275b3c83727e61a)) @@ -409,7 +535,7 @@ Usage: * **layout:** `td-layout-nav-list` and `td-layout-nav` can be used as standalone without a `td-layout` parent (which will hide/show the menu button depending on that). ([026520cc346721d72c815b0d09fbd469fd3f2ad5](https://github.com/Teradata/covalent/commit/026520cc346721d72c815b0d09fbd469fd3f2ad5)) * **layout:** Removed fixed breakpoint for mobile in `td-layout-nav-list` and `td-layout-manage-list`. ([026520cc346721d72c815b0d09fbd469fd3f2ad5](https://github.com/Teradata/covalent/commit/026520cc346721d72c815b0d09fbd469fd3f2ad5)), closes [#265] (https://github.com/Teradata/covalent/issues/265) -* **layout:** `td-layout-nav-list` and `td-layout-manage-list` new inputs `[opened]`, `[mode]` and `[sidenavWidth]` to allow more flexibility. ([026520cc346721d72c815b0d09fbd469fd3f2ad5](https://github.com/Teradata/covalent/commit/026520cc346721d72c815b0d09fbd469fd3f2ad5)), closes [#180] (https://github.com/Teradata/covalent/issues/180) +* **layout:** `td-layout-nav-list` and `td-layout-manage-list` new inputs `[opened]`, `[mode]` and `[sidenavWidth]` to allow more flexibility. ([026520cc346721d72c815b0d09fbd469fd3f2ad5](https://github.com/Teradata/covalent/commit/026520cc346721d72c815b0d09fbd469fd3f2ad5)), closes [#180] (https://github.com/Teradata/covalent/issues/180) Usage: ```html @@ -520,13 +646,13 @@ ngAfterViewInit(): void { - CovalentDynamicFormsModule (`@covalent/dynamic-forms`) - CovalentHighlightModule (`@covalent/highlight`) - CovalentMarkdownModule (`@covalent/markdown`) - + - `markdown` is a separate module and its theme needs to be imported separatly `@import ~@covalent/markdown/markdown-theme'` and included `@include covalent-markdown-theme($theme);` - `highlight` is a separate module and its theme needs to be imported separatly `@import ~@covalent/highlight/highlight-theme'` and included `@include covalent-highlight-theme();` - `all-theme` and `platform.css` changed directories. - Before: + Before: ```scss `~@covalent/core/styles/platform.css` @@ -602,7 +728,7 @@ ngAfterViewInit(): void { ``` After (once at any toplevel component): - + ```typescript import { DomSanitizer } from '@angular/platform-browser'; import { MdIconRegistry } from '@angular/material'; @@ -634,7 +760,7 @@ ngAfterViewInit(): void { ## Features * **docs:** Added `GETTING_STARTED.md`. ([48dcbc21f10d1a8233cb3835bc4fe20644a00a6d](https://github.com/Teradata/covalent/commit/48dcbc21f10d1a8233cb3835bc4fe20644a00a6d)), closes [#178](https://github.com/Teradata/covalent/issues/178) * **dialogs:** Better a11y ([f6bc8292538bfe0468ee698f23f9911ff3a5ddaf](https://github.com/Teradata/covalent/commit/f6bc8292538bfe0468ee698f23f9911ff3a5ddaf)), closes [#170](https://github.com/Teradata/covalent/issues/170) -* **dialogs:** Exposed open/closeAll methods from MdDialog. ([f6bc8292538bfe0468ee698f23f9911ff3a5ddaf](https://github.com/Teradata/covalent/commit/f6bc8292538bfe0468ee698f23f9911ff3a5ddaf)), closes [#171](https://github.com/Teradata/covalent/issues/171) +* **dialogs:** Exposed open/closeAll methods from MdDialog. ([f6bc8292538bfe0468ee698f23f9911ff3a5ddaf](https://github.com/Teradata/covalent/commit/f6bc8292538bfe0468ee698f23f9911ff3a5ddaf)), closes [#171](https://github.com/Teradata/covalent/issues/171) * **http:** Adding an extra parameter for a `transform` callback in the RESTService methods. ([d73badbe62e7ed5a81be9b3279325b5b46ffc266](https://github.com/Teradata/covalent/commit/d73badbe62e7ed5a81be9b3279325b5b46ffc266)), closes [#179](https://github.com/Teradata/covalent/issues/179) * **http:** Added onRequestError interceptor hook. ([d73badbe62e7ed5a81be9b3279325b5b46ffc266](https://github.com/Teradata/covalent/commit/d73badbe62e7ed5a81be9b3279325b5b46ffc266)) * **http:** Request URL path interceptors. ([7db377e62254f6add6995065f09f4b5528bd0c16](https://github.com/Teradata/covalent/commit/7db377e62254f6add6995065f09f4b5528bd0c16)), closes [#194](https://github.com/Teradata/covalent/issues/194) @@ -658,7 +784,7 @@ ngAfterViewInit(): void { ``` * **dynamic-forms:** Introducing `dynamic-forms` module. ([3eb363873f11b5929655ec4c5ffa822a91fbc5e0](https://github.com/Teradata/covalent/commit/3eb363873f11b5929655ec4c5ffa822a91fbc5e0)), closes [#8](https://github.com/Teradata/covalent/issues/8) - + - Supported TdDynamicType - TdDynamicType.Text (renders md-input-container input type="text") @@ -676,7 +802,7 @@ ngAfterViewInit(): void { - TdDynamicElement.Select (renders md-select) * **notifications:** Introducing `notifications` module. ([746fe3caec62a77bc69b50a2fc0bfcf9b0a9a695](https://github.com/Teradata/covalent/commit/746fe3caec62a77bc69b50a2fc0bfcf9b0a9a695)), closes [#148](https://github.com/Teradata/covalent/issues/148) - + Usage: ```html @@ -895,14 +1021,14 @@ Usage: ... add label content (if not used, falls back to [label] input) ... add content that will be shown when the step is "active" - + ``` ## Internal -* **code-health:** added additional code-health for http forkJoin. ([9ea75f3accf0170a670c446b17f98c447d7a6454](https://github.com/Teradata/covalent/commit/9ea75f3accf0170a670c446b17f98c447d7a6454)), closes [#109](https://github.com/Teradata/covalent/issues/109) -* **dependencies:** Relaxed dependency limitations. ([f67bd1e150559ac1fe7faa22a730a70de5366635](https://github.com/Teradata/covalent/commit/f67bd1e150559ac1fe7faa22a730a70de5366635)), closes [#136](https://github.com/Teradata/covalent/issues/136) -* **http:** Remove covalent/core as dependency from http module and added angular/core and angular/http. ([f67bd1e150559ac1fe7faa22a730a70de5366635](https://github.com/Teradata/covalent/commit/f67bd1e150559ac1fe7faa22a730a70de5366635)), closes [#134](https://github.com/Teradata/covalent/issues/134) +* **code-health:** added additional code-health for http forkJoin. ([9ea75f3accf0170a670c446b17f98c447d7a6454](https://github.com/Teradata/covalent/commit/9ea75f3accf0170a670c446b17f98c447d7a6454)), closes [#109](https://github.com/Teradata/covalent/issues/109) +* **dependencies:** Relaxed dependency limitations. ([f67bd1e150559ac1fe7faa22a730a70de5366635](https://github.com/Teradata/covalent/commit/f67bd1e150559ac1fe7faa22a730a70de5366635)), closes [#136](https://github.com/Teradata/covalent/issues/136) +* **http:** Remove covalent/core as dependency from http module and added angular/core and angular/http. ([f67bd1e150559ac1fe7faa22a730a70de5366635](https://github.com/Teradata/covalent/commit/f67bd1e150559ac1fe7faa22a730a70de5366635)), closes [#134](https://github.com/Teradata/covalent/issues/134) * **dependencies:** Upgrade to `@angular@2.2.1` ([b806afabeda784b285342e3673fcaa20e722d954](https://github.com/Teradata/covalent/commit/b806afabeda784b285342e3673fcaa20e722d954)) * **dependencies:** Upgrade to `@angular-cli@beta.19-3` ([b806afabeda784b285342e3673fcaa20e722d954](https://github.com/Teradata/covalent/commit/b806afabeda784b285342e3673fcaa20e722d954)) @@ -1034,7 +1160,7 @@ After: * **docs:** Added resource docs with axure and sketch downloads for Covalent usage. ([13110bf701e3fdbfd487003b7c88f66b63c4642e](https://github.com/Teradata/covalent/commit/13110bf701e3fdbfd487003b7c88f66b63c4642e)), closes [#55](https://github.com/Teradata/covalent/issues/55) * **docs:** Updated docs with ngModule usage. closes [#65](https://github.com/Teradata/covalent/issues/65) * **release:** Inline html/css in compiled js files. ([23007cd7598a599539cc2e14d4f02735ff84a7a2](https://github.com/Teradata/covalent/commit/23007cd7598a599539cc2e14d4f02735ff84a7a2)), closes [#27](https://github.com/Teradata/covalent/issues/27) -* **release:** Bundle module code into a single `[module].umd.js` to match angular/angular2-material's. ([23007cd7598a599539cc2e14d4f02735ff84a7a2](https://github.com/Teradata/covalent/commit/23007cd7598a599539cc2e14d4f02735ff84a7a2)), closes [#56](https://github.com/Teradata/covalent/issues/56) +* **release:** Bundle module code into a single `[module].umd.js` to match angular/angular2-material's. ([23007cd7598a599539cc2e14d4f02735ff84a7a2](https://github.com/Teradata/covalent/commit/23007cd7598a599539cc2e14d4f02735ff84a7a2)), closes [#56](https://github.com/Teradata/covalent/issues/56) * **covalent-data:** Introducing `Covalent Data` mock server API endpoints for better prototyping. Visit our [repo](https://github.com/Teradata/covalent-data) for more information. * **docs:** Added covalent-data docs for usage with `Covalent Quickstart`. ([c77d42c22d2c9e745431c12b9b19e803e44871c1](https://github.com/Teradata/covalent/commit/c77d42c22d2c9e745431c12b9b19e803e44871c1)) @@ -1063,7 +1189,7 @@ After: * **all:** Updated packaging to match angular/angular2-material's packaging creating a `[module].umd.js` file per module. - Example SystemJS config with UMD bundles: + Example SystemJS config with UMD bundles: ```ts '@covalent/core': { @@ -1072,7 +1198,7 @@ After: } ``` -* **all:** Covalent modules must be included with `forRoot()` when bootstrapping. See the [ngModules guide](https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-for-root) for +* **all:** Covalent modules must be included with `forRoot()` when bootstrapping. See the [ngModules guide](https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-for-root) for more information. ```ts @@ -1152,7 +1278,7 @@ more information.
... -
+
``` @@ -1195,7 +1321,7 @@ more information. * **loading:** There is a need to add `TD_LOADING_ENTRY_COMPONENTS` in the `precompile` array of your main component, so the `TdLoadingComponent` can be resolved by the `ComponentFactoryResolver`. - e.g. + e.g. ```typescript import { TD_LOADING_ENTRY_COMPONENTS } from '@covalent/core'; diff --git a/src/app/components/toolbar/toolbar.component.html b/src/app/components/toolbar/toolbar.component.html index 0574cb00cf..3dcdf4b407 100644 --- a/src/app/components/toolbar/toolbar.component.html +++ b/src/app/components/toolbar/toolbar.component.html @@ -30,11 +30,11 @@

{{item.description}}

change_history -

Angular v4.1 and material@beta.5 support

+

Angular v4.2 and material@beta.6 support

Dependencies updated

- + View Full Changelog diff --git a/src/app/components/toolbar/toolbar.component.ts b/src/app/components/toolbar/toolbar.component.ts index e09279c47b..3f2310941e 100644 --- a/src/app/components/toolbar/toolbar.component.ts +++ b/src/app/components/toolbar/toolbar.component.ts @@ -17,60 +17,60 @@ import { getDirection, setDirection } from '../../utilities/direction'; }) export class ToolbarComponent { updates: Object[] = [{ - description: 'Keyboard support for selection', - icon: 'grid_on', - route: 'components/data-table', - title: 'Data Table feature', - }, { - description: 'Row click events', - icon: 'grid_on', - route: 'components/data-table', - title: 'Data Table feature', - }, { - description: 'Hide columns & exclude from filtering', - icon: 'grid_on', - route: 'components/data-table', - title: 'Data Table feature', + description: 'Agnostic filtering with (inputChange) and [debounce] (local vs server side)', + icon: 'label', + route: '/components/chips', + title: 'Chips feature', }, { - description: 'Async & boolean loading', - icon: 'hourglass_empty', - route: 'components/loading', - title: 'Loading features', + description: 'object list and template support and new [td-chip-avatar] attribute', + icon: 'label', + route: '/components/chips', + title: 'Chips feature', }, { - description: 'Component for alerts/info/warning/error/success', - icon: 'info_outline', - route: 'components/message', - title: 'New Messages component', + description: 'new [chipRemoval] input', + icon: 'label', + route: '/components/chips', + title: 'Chips feature', }, { - description: 'Numbered page links to jump ahead', - icon: 'swap_horiz', - route: 'components/paging', - title: 'Pagination feature', + description: 'new [color] input', + icon: 'label', + route: '/components/chips', + title: 'Chips feature', }, { - description: 'Disable adding of chips', + description: 'new [stacked] input', icon: 'label', - route: 'components/chips', + route: '/components/chips', title: 'Chips feature', }, { - description: 'New formData property', - icon: 'attach_file', - route: 'components/file-upload', - title: 'File service feature', + description: 'new td-expansion-panel-group component', + icon: 'open_with', + route: '/components/expansion-panel', + title: 'Expansion panel feature', }, { - description: 'New contentReady event binding', - icon: 'chrome_reader_mode', - route: 'components/markdown', - title: 'Markdown feature', + description: 'new [disableRipple] input', + icon: 'open_with', + route: '/components/expansion-panel', + title: 'Expansion panel feature', }, { - description: 'New contentReady event binding', - icon: 'code', - route: 'components/highlight', - title: 'Highlight feature', + description: 'new [mode], [opened], [sidenavWidth] inputs for td-layout', + icon: 'view_quilt', + route: '/layouts', + title: 'Layouts feature', }, { - description: 'Make navigationRoute optional', + description: 'new [color] input for td-layout-footer', icon: 'view_quilt', - route: 'components/layouts', + route: '/layouts', title: 'Layouts feature', + }, { + description: 'animation when opening/closing', + icon: 'info_outline', + route: '/components/message', + title: 'Message feature', + }, { + description: 'new [disableRipple] input', + icon: 'view_list', + route: '/components/steps', + title: 'Stepper feature', }, ]; From 597cff5e8273b8a2bce9d7785b53c0b1493bc12e Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Fri, 9 Jun 2017 13:05:17 -0700 Subject: [PATCH 34/35] Version bump --- package.json | 2 +- src/platform/core/package.json | 2 +- src/platform/dynamic-forms/package.json | 2 +- src/platform/highlight/package.json | 2 +- src/platform/http/package.json | 2 +- src/platform/markdown/package.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 48039288b1..f5c1bc7361 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "covalent", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.5", "private": true, "description": "Teradata UI Platform built on Angular Material", "keywords": [ diff --git a/src/platform/core/package.json b/src/platform/core/package.json index a328d80fb3..99cac29e3f 100644 --- a/src/platform/core/package.json +++ b/src/platform/core/package.json @@ -1,6 +1,6 @@ { "name": "@covalent/core", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.5", "description": "Teradata UI Platform built on Angular Material", "main": "./core.umd.js", "module": "./index.js", diff --git a/src/platform/dynamic-forms/package.json b/src/platform/dynamic-forms/package.json index abeea4c9dd..a831f09b9b 100644 --- a/src/platform/dynamic-forms/package.json +++ b/src/platform/dynamic-forms/package.json @@ -1,6 +1,6 @@ { "name": "@covalent/dynamic-forms", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.5", "description": "Teradata UI Platform Dynamic Forms Module", "main": "./dynamic-forms.umd.js", "module": "./index.js", diff --git a/src/platform/highlight/package.json b/src/platform/highlight/package.json index 9c1114ac7f..7d950a6cdf 100644 --- a/src/platform/highlight/package.json +++ b/src/platform/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@covalent/highlight", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.5", "description": "Teradata UI Platform Highlight Module", "main": "./highlight.umd.js", "module": "./index.js", diff --git a/src/platform/http/package.json b/src/platform/http/package.json index a26015ff7a..410515612d 100644 --- a/src/platform/http/package.json +++ b/src/platform/http/package.json @@ -1,6 +1,6 @@ { "name": "@covalent/http", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.5", "description": "Teradata UI Platform Http Helper Module", "main": "./http.umd.js", "module": "./index.js", diff --git a/src/platform/markdown/package.json b/src/platform/markdown/package.json index d9009cc06c..4876ddb7d0 100644 --- a/src/platform/markdown/package.json +++ b/src/platform/markdown/package.json @@ -1,6 +1,6 @@ { "name": "@covalent/markdown", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.5", "description": "Teradata UI Platform Markdown Module", "main": "./markdown.umd.js", "module": "./index.js", From 44c3ced853f4922279623c59a0c9ce739d239899 Mon Sep 17 00:00:00 2001 From: emoralesb05 Date: Fri, 9 Jun 2017 13:07:25 -0700 Subject: [PATCH 35/35] bump(): dynamic forms dependency to 1.0.0-beta.5 --- src/platform/dynamic-forms/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/dynamic-forms/package.json b/src/platform/dynamic-forms/package.json index a831f09b9b..ff2a415143 100644 --- a/src/platform/dynamic-forms/package.json +++ b/src/platform/dynamic-forms/package.json @@ -37,6 +37,6 @@ "Steven Ov " ], "dependencies": { - "@covalent/core": "1.0.0-beta.4" + "@covalent/core": "1.0.0-beta.5" } }