Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/checkbox/checkbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[attr.name]="name"
[attr.value]="value"
[attr.tabindex]="tabindex"
[disabled]="disabled"
[attr.disabled]="disabled ? true : null"
[checked]="checked"
(change)="onChange($event)"
(focus)="onFocus($event)"
Expand Down
119 changes: 119 additions & 0 deletions src/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {
async,
TestBed
} from "@angular/core/testing";
import { Component, ViewChild } from "@angular/core";
import { FormsModule } from '@angular/forms';
import { By } from "@angular/platform-browser";
import { IgCheckbox } from "./checkbox";

describe('IgCheckbox', function() {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
InitCheckbox,
CheckboxSimple,
CheckboxDisabled,
IgCheckbox
],
imports: [FormsModule]
})
.compileComponents();
}));

it('Initializes a checkbox', () => {
let fixture = TestBed.createComponent(InitCheckbox);
fixture.detectChanges();

let nativeCheckbox = fixture.debugElement.query(By.css('input')).nativeElement;
let nativeLabel = fixture.debugElement.query(By.css('label')).nativeElement;

expect(nativeCheckbox).toBeTruthy();
expect(nativeLabel).toBeTruthy();
expect(nativeLabel.textContent.trim()).toEqual('Init');
});

it('Initialize with a ngModel', () => {
let fixture = TestBed.createComponent(CheckboxSimple);
fixture.detectChanges();

let nativeCheckbox = fixture.debugElement.query(By.css('input')).nativeElement;
let checkboxInstance = fixture.componentInstance.cb;
let testInstance = fixture.componentInstance;

fixture.detectChanges();

expect(nativeCheckbox.checked).toBe(false);
expect(checkboxInstance.checked).toBe(false);

testInstance.subscribed = true;
fixture.detectChanges();

expect(nativeCheckbox.checked).toBe(true);
expect(checkboxInstance.checked).toBe(true);
});

it('Disabled state', () => {
let fixture = TestBed.createComponent(CheckboxDisabled);
fixture.detectChanges();

let nativeCheckbox = fixture.debugElement.query(By.css('input')).nativeElement;
let checkboxInstance = fixture.componentInstance.cb;
let testInstance = fixture.componentInstance;

fixture.detectChanges();

expect(checkboxInstance.disabled).toBe(true);
expect(nativeCheckbox.getAttribute('disabled')).toBe('true');

nativeCheckbox.dispatchEvent(new Event('change'));
fixture.detectChanges();

// Should not update
expect(checkboxInstance.checked).toBe(false);
expect(testInstance.subscribed).toBe(false);
});

it('Event handling', () => {
let fixture = TestBed.createComponent(CheckboxSimple);
fixture.detectChanges();

let nativeCheckbox = fixture.debugElement.query(By.css('input')).nativeElement;
let checkboxInstance = fixture.componentInstance.cb;
let testInstance = fixture.componentInstance;

nativeCheckbox.dispatchEvent(new Event('focus'));
fixture.detectChanges();

expect(checkboxInstance.focused).toBe(true);

nativeCheckbox.dispatchEvent(new Event('blur'));
fixture.detectChanges();

expect(checkboxInstance.focused).toBe(false);

spyOn(checkboxInstance.change, 'emit');
nativeCheckbox.dispatchEvent(new Event('change'));
fixture.detectChanges();

expect(checkboxInstance.change.emit).toHaveBeenCalled();
expect(testInstance.subscribed).toBe(true);
});
});

@Component({ template: `<ig-checkbox>Init</ig-checkbox>`})
class InitCheckbox {}

@Component({ template: `<ig-checkbox #cb [(ngModel)]="subscribed" [checked]="subscribed">Simple</ig-checkbox>`})
class CheckboxSimple {
@ViewChild('cb') cb: IgCheckbox;

subscribed: boolean = false;
}

@Component({ template: `<ig-checkbox #cb [(ngModel)]="subscribed" [checked]="subscribed" [disabled]="true">Disabled</ig-checkbox>`})
class CheckboxDisabled {
@ViewChild('cb') cb: IgCheckbox;

subscribed: boolean = false;
}
4 changes: 2 additions & 2 deletions src/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class IgCheckbox implements ControlValueAccessor {

protected _value: any;

focused: boolean = false;
focused: boolean = false;

onChange(event) {
if (this.disabled) {
Expand All @@ -67,7 +67,7 @@ export class IgCheckbox implements ControlValueAccessor {
return;
}
this._value = value;
this.checked = this._value;
this.checked = !!this._value;
}

private _onTouchedCallback: () => void = noop;
Expand Down
53 changes: 53 additions & 0 deletions src/layout/layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Directive, HostBinding, Input, NgModule } from '@angular/core';


@Directive({
selector: '[layout]'
})
export class LayoutDirective {

@Input() dir: string = "row";
@Input() reverse: boolean = false;
@Input() wrap: string = "nowrap";
@Input() justify: string = "flex-start";
@Input() itemAlign: string = "flex-start";

@HostBinding('style.display') display = 'flex';
@HostBinding('style.flex-wrap') get flexwrap() { return this.wrap; }
@HostBinding('style.justify-content') get justifycontent() { return this.justify; }
@HostBinding('style.align-content') get align() { return this.itemAlign; }

@HostBinding('style.flex-direction')
get direction() {
if (this.reverse) {
return (this.dir == 'row') ? 'row-reverse' : 'column-reverse';
}
return (this.dir == 'row') ? 'row' : 'column';
}
}

@Directive({
selector: '[flex]'
})
export class FlexDirective {
@Input() grow: number = 1;
@Input() shrink: number = 1;
@Input() flex: string;
@Input() order: number = 0;

@HostBinding('style.flex')
get style() {
return `${this.grow} ${this.shrink}`;
}

@HostBinding('style.order')
get itemorder() {
return this.order || 0;
}
}

@NgModule({
declarations: [LayoutDirective, FlexDirective],
exports: [FlexDirective, LayoutDirective]
})
export class IgLayout {}
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ export * from './radio/radio';
export * from './label/label';
export * from './switch/switch';
export * from './avatar/avatar';
export * from './layout/layout';
export * from './modal/modal';
8 changes: 8 additions & 0 deletions src/modal/modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div #modal
tabindex="-1"
[ngStyle]="{ display: isOpen ? 'block' : 'none' }"
(click)="closeOnClick ? close() : 0">
<div class="modal-inner">
<ng-content></ng-content>
<div>
</div>
69 changes: 69 additions & 0 deletions src/modal/modal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Component, ViewChild, Input, Output, EventEmitter, ElementRef, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
selector: 'modal',
moduleId: module.id,
templateUrl: 'modal.html',
styles: [`
.modalDialog {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0,0,0,.65);
z-index: 9999;
opacity: 1;
transition: all 400ms ease-in;
}
.modal-inner {
width: 400px;
position: relative;
margin: 10% auto;
padding: 5px 25px 10px 10px;
background: #fff;
}
`]
})
export class Modal {

@Input() closeOnClick = true;

@Output()
onOpen = new EventEmitter();

@Output()
onClose = new EventEmitter();

isOpen = false;

@ViewChild('modal') modalEl: ElementRef;
protected behindElement: HTMLElement;

open() {
if (this.isOpen) {
return;
}
this.isOpen = true;
this.onOpen.emit(this);
this.modalEl.nativeElement.classList.add('modalDialog');
}

close() {
if (!this.isOpen) {
return;
}
this.isOpen = false;
this.onClose.emit(this);
this.modalEl.nativeElement.classList.remove('modalDialog');
}

}

@NgModule({
declarations: [Modal],
exports: [Modal],
imports: [CommonModule]
})
export class ModalModule {}
73 changes: 73 additions & 0 deletions src/radio/radio.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
async,
TestBed
} from "@angular/core/testing";
import { FormsModule } from '@angular/forms';
import { Component, ViewChildren } from "@angular/core";
import { By } from "@angular/platform-browser";
import { IgRadio } from './radio';

describe('IgRadio', function() {

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
InitRadio,
RadioWithModel,
IgRadio
],
imports: [FormsModule]
})
.compileComponents();
}));

it('Init a radio', () => {
let fixture = TestBed.createComponent(InitRadio);
fixture.detectChanges();

let nativeRadio = fixture.debugElement.query(By.css('input')).nativeElement;
let nativeLabel = fixture.debugElement.query(By.css('label')).nativeElement;

expect(nativeRadio).toBeTruthy();
expect(nativeRadio.type).toBe('radio');
expect(nativeLabel).toBeTruthy();
expect(nativeLabel.textContent.trim()).toEqual('Radio');
});

it('Binding to ngModel', () => {
let fixture = TestBed.createComponent(RadioWithModel);
fixture.detectChanges();

let radios = fixture.componentInstance.radios.toArray();

expect(radios.length).toEqual(3);

fixture.whenStable().then(() => {
fixture.detectChanges();
expect(radios[0].checked).toBe(true);

radios[1].nativeRadio.nativeElement.dispatchEvent(new Event('change'));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(radios[1].checked).toBe(true);
expect(radios[0].checked).toBe(false);
expect(fixture.componentInstance.selected).toEqual('Bar');
});
});
});
});


@Component({ template: `<ig-radio>Radio</ig-radio>` })
class InitRadio {}

@Component({
template: `
<ig-radio *ngFor="let item of ['Foo', 'Bar', 'Baz']" value="{{item}}" name="group" [(ngModel)]="selected">{{item}}</ig-radio>
`
})
class RadioWithModel {
@ViewChildren(IgRadio) radios;

selected = "Foo";
}