Skip to content

Commit

Permalink
feat(datepicker): initial version of datepicker component
Browse files Browse the repository at this point in the history
  • Loading branch information
maxokorokov committed Aug 31, 2016
1 parent 9556e4b commit c9164dd
Show file tree
Hide file tree
Showing 31 changed files with 1,632 additions and 3 deletions.
2 changes: 2 additions & 0 deletions demo/src/app/app.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
NgbdButtons,
NgbdCarousel,
NgbdCollapse,
NgbdDatepicker,
NgbdDropdown,
NgbdModal,
NgbdPagination,
Expand All @@ -29,6 +30,7 @@ const routes: Routes = [
{path: 'components/buttons', component: NgbdButtons},
{path: 'components/carousel', component: NgbdCarousel},
{path: 'components/collapse', component: NgbdCollapse},
{path: 'components/datepicker', component: NgbdDatepicker},
{path: 'components/dropdown', component: NgbdDropdown},
{path: 'components/modal', component: NgbdModal},
{path: 'components/pagination', component: NgbdPagination},
Expand Down
17 changes: 17 additions & 0 deletions demo/src/app/components/datepicker/datepicker.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {Component} from '@angular/core';
import {DEMO_SNIPPETS} from './demos';

@Component({
selector: 'ngbd-datepicker',
template: `
<ngbd-content-wrapper component="Datepicker">
<ngbd-api-docs directive="NgbDatepicker"></ngbd-api-docs>
<ngbd-example-box demoTitle="Basic datepicker" [htmlSnippet]="snippets.basic.markup" [tsSnippet]="snippets.basic.code">
<ngbd-datepicker-basic></ngbd-datepicker-basic>
</ngbd-example-box>
</ngbd-content-wrapper>
`
})
export class NgbdDatepicker {
snippets = DEMO_SNIPPETS;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<p>Simple datepicker</p>

<ngb-datepicker #dp [(ngModel)]="model" [minDate]="minDate" [maxDate]="maxDate"></ngb-datepicker>

<hr/>

<button class="btn btn-sm btn-outline-primary" (click)="selectToday()">Select Today</button>
<button class="btn btn-sm btn-outline-primary" (click)="dp.navigateTo()">To current month</button>
<button class="btn btn-sm btn-outline-primary" (click)="dp.navigateTo({year: 2013, month: 1})">To Feb 2013</button>

<hr/>

<pre>Model: {{ model | json }}</pre>
19 changes: 19 additions & 0 deletions demo/src/app/components/datepicker/demos/basic/datepicker-basic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {Component} from '@angular/core';

const now = new Date();

@Component({
selector: 'ngbd-datepicker-basic',
template: require('./datepicker-basic.html')
})
export class NgbdDatepickerBasic {

model;

minDate = {year: 2000, month: 0, date: 7};
maxDate = {year: 2020, month: 5, date: 15};

selectToday() {
this.model = {year: now.getFullYear(), month: now.getMonth(), date: now.getDate()};
}
}
9 changes: 9 additions & 0 deletions demo/src/app/components/datepicker/demos/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {NgbdDatepickerBasic} from './basic/datepicker-basic';

export const DEMO_DIRECTIVES = [NgbdDatepickerBasic];

export const DEMO_SNIPPETS = {
basic: {
code: require('!!prismjs?lang=typescript!./basic/datepicker-basic'),
markup: require('!!prismjs?lang=markup!./basic/datepicker-basic.html')}
};
14 changes: 14 additions & 0 deletions demo/src/app/components/datepicker/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export * from './datepicker.component';

import {NgModule} from '@angular/core';
import {NgbdSharedModule} from '../../shared';
import {NgbdComponentsSharedModule} from '../shared';
import {NgbdDatepicker} from './datepicker.component';
import {DEMO_DIRECTIVES} from './demos';

@NgModule({
imports: [NgbdSharedModule, NgbdComponentsSharedModule],
exports: [NgbdDatepicker],
declarations: [NgbdDatepicker, ...DEMO_DIRECTIVES]
})
export class NgbdDatepickerModule {}
4 changes: 4 additions & 0 deletions demo/src/app/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {NgbdDatepickerModule} from './datepicker/index';
export * from './accordion';
export * from './alert';
export * from './buttons';
export * from './carousel';
export * from './collapse';
export * from './datepicker';
export * from './dropdown';
export * from './modal';
export * from './pagination';
Expand Down Expand Up @@ -42,6 +44,7 @@ import {NgbdTypeaheadModule} from './typeahead';
NgbdButtonsModule,
NgbdCarouselModule,
NgbdCollapseModule,
NgbdDatepickerModule,
NgbdDropdownModule,
NgbdModalModule,
NgbdPaginationModule,
Expand All @@ -59,6 +62,7 @@ import {NgbdTypeaheadModule} from './typeahead';
NgbdButtonsModule,
NgbdCarouselModule,
NgbdCollapseModule,
NgbdDatepickerModule,
NgbdDropdownModule,
NgbdModalModule,
NgbdPaginationModule,
Expand Down
1 change: 1 addition & 0 deletions demo/src/app/shared/side-nav/side-nav.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class SideNavComponent {
'Buttons',
'Carousel',
'Collapse',
'Datepicker',
'Dropdown',
'Modal',
'Pagination',
Expand Down
81 changes: 81 additions & 0 deletions src/datepicker/datepicker-day-view.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {TestBed, ComponentFixture} from '@angular/core/testing';
import {createGenericTestComponent} from '../util/tests';

import {Component} from '@angular/core';

import {NgbDatepickerModule} from './datepicker.module';
import {MonthViewModel, DayViewModel} from './datepicker-view-model';
import {NgbDatepickerDayView} from './datepicker-day-view';
import {NgbDate} from './ngb-date';

const createTestComponent = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;

function getElement(element: HTMLElement): HTMLElement {
return <HTMLElement>element.querySelector('[ngb-datepicker-day-view]');
}

describe('ngb-datepicker-day-view', () => {

beforeEach(() => {
TestBed.overrideModule(NgbDatepickerModule, {set: {exports: [NgbDatepickerDayView]}});
TestBed.configureTestingModule({declarations: [TestComponent], imports: [NgbDatepickerModule]});
});

it('should display date', () => {
const fixture =
createTestComponent('<div ngb-datepicker-day-view [day]="day" [month]="month" [selected]="selected"></div>');

const el = getElement(fixture.nativeElement);
expect(el.innerText).toBe('22');

fixture.componentInstance.day.date = new NgbDate(2016, 7, 25);
fixture.detectChanges();
expect(el.innerText).toBe('25');
});

it('should apply text-muted style for disabled days', () => {
const fixture =
createTestComponent('<div ngb-datepicker-day-view [day]="day" [month]="month" [selected]="selected"></div>');

const el = getElement(fixture.nativeElement);
expect(el).not.toHaveCssClass('text-muted');

fixture.componentInstance.day.disabled = true;
fixture.detectChanges();
expect(el).toHaveCssClass('text-muted');
});

it('should apply text-muted style for days of a different month', () => {
const fixture =
createTestComponent('<div ngb-datepicker-day-view [day]="day" [month]="month" [selected]="selected"></div>');

const el = getElement(fixture.nativeElement);
expect(el).not.toHaveCssClass('text-muted');

fixture.componentInstance.day.date = new NgbDate(2016, 8, 22);
fixture.detectChanges();
expect(el).toHaveCssClass('text-muted');
});

it('should apply selected style', () => {
const fixture =
createTestComponent('<div ngb-datepicker-day-view [day]="day" [month]="month" [selected]="selected"></div>');

const el = getElement(fixture.nativeElement);
expect(el).not.toHaveCssClass('bg-primary');

fixture.componentInstance.selected = true;
fixture.detectChanges();
expect(el).toHaveCssClass('bg-primary');
});
});

@Component({selector: 'test-cmp', template: ''})
class TestComponent {
day: DayViewModel = {date: new NgbDate(2016, 7, 22), disabled: false};

selected = false;

month: MonthViewModel = {year: 2016, number: 7, weekdays: [0], weeks: []};
}
20 changes: 20 additions & 0 deletions src/datepicker/datepicker-day-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {Component, Input} from '@angular/core';
import {MonthViewModel, DayViewModel} from './datepicker-view-model';

@Component({
selector: '[ngb-datepicker-day-view]',
styles: [`
:host {
text-align: center;
padding: 0.185rem 0.25rem;
border-radius: 0.25rem;
}
`],
host: {'[class.bg-primary]': 'selected', '[class.text-muted]': 'day.date.month !== month.number || day.disabled'},
template: `{{ day.date.date }}`
})
export class NgbDatepickerDayView {
@Input() month: MonthViewModel;
@Input() day: DayViewModel;
@Input() selected: boolean;
}
21 changes: 21 additions & 0 deletions src/datepicker/datepicker-i18n.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {NgbDatepickerI18n} from './datepicker-i18n';

describe('ngb-datepicker-i18n', () => {

it('should return month name', () => {
const i18n = new NgbDatepickerI18n();

expect(i18n.getMonthName(0)).toBe('Jan');
expect(i18n.getMonthName(11)).toBe('Dec');
expect(i18n.getMonthName(12)).toBe(undefined);
});

it('should return weekday name', () => {
const i18n = new NgbDatepickerI18n();

expect(i18n.getWeekdayName(0)).toBe('Su');
expect(i18n.getWeekdayName(6)).toBe('Sa');
expect(i18n.getWeekdayName(7)).toBe(undefined);
});

});
11 changes: 11 additions & 0 deletions src/datepicker/datepicker-i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Injectable} from '@angular/core';

const WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

@Injectable()
export class NgbDatepickerI18n {
getWeekdayName(weekday: number): string { return WEEKDAYS[weekday]; }

getMonthName(month: number): string { return MONTHS[month]; }
}
Loading

0 comments on commit c9164dd

Please sign in to comment.