Skip to content

Commit 123d7ec

Browse files
mmalerbakara
authored andcommitted
feat(datepicker): merge datepicker branch into master (#4404)
1 parent 1ec88e0 commit 123d7ec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+4562
-13
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<h2>Options</h2>
2+
<p>
3+
<md-checkbox [(ngModel)]="touch">Use touch UI</md-checkbox>
4+
<md-checkbox [(ngModel)]="filterOdd">Filter odd months and dates</md-checkbox>
5+
<md-checkbox [(ngModel)]="yearView">Start in year view</md-checkbox>
6+
</p>
7+
<p>
8+
<md-input-container>
9+
<input mdInput [mdDatepicker]="minDatePicker" [(ngModel)]="minDate" placeholder="Min date">
10+
<button mdSuffix [mdDatepickerToggle]="minDatePicker"></button>
11+
</md-input-container>
12+
<md-datepicker #minDatePicker [touchUi]="touch"></md-datepicker>
13+
<md-input-container>
14+
<input mdInput [mdDatepicker]="maxDatePicker" [(ngModel)]="maxDate" placeholder="Max date">
15+
<button mdSuffix [mdDatepickerToggle]="maxDatePicker"></button>
16+
</md-input-container>
17+
<md-datepicker #maxDatePicker [touchUi]="touch"></md-datepicker>
18+
</p>
19+
<p>
20+
<md-input-container>
21+
<input mdInput [mdDatepicker]="startAtPicker" [(ngModel)]="startAt" placeholder="Start at date">
22+
<button mdSuffix [mdDatepickerToggle]="startAtPicker"></button>
23+
</md-input-container>
24+
<md-datepicker #startAtPicker [touchUi]="touch"></md-datepicker>
25+
</p>
26+
27+
<h2>Result</h2>
28+
29+
<p>
30+
<button [mdDatepickerToggle]="resultPicker"></button>
31+
<md-input-container>
32+
<input mdInput
33+
#resultPickerModel="ngModel"
34+
[mdDatepicker]="resultPicker"
35+
[(ngModel)]="date"
36+
[min]="minDate"
37+
[max]="maxDate"
38+
[mdDatepickerFilter]="filterOdd ? dateFilter : null"
39+
placeholder="Pick a date">
40+
<md-error *ngIf="resultPickerModel.hasError('mdDatepickerMin')">Too early!</md-error>
41+
<md-error *ngIf="resultPickerModel.hasError('mdDatepickerMax')">Too late!</md-error>
42+
<md-error *ngIf="resultPickerModel.hasError('mdDatepickerFilter')">Date unavailable!</md-error>
43+
</md-input-container>
44+
<md-datepicker
45+
#resultPicker
46+
[touchUi]="touch"
47+
[startAt]="startAt"
48+
[startView]="yearView ? 'year' : 'month'">
49+
</md-datepicker>
50+
</p>
51+
<p>
52+
<input [mdDatepicker]="resultPicker2"
53+
[(ngModel)]="date"
54+
[min]="minDate"
55+
[max]="maxDate"
56+
[mdDatepickerFilter]="filterOdd ? dateFilter : null"
57+
placeholder="Pick a date">
58+
<button [mdDatepickerToggle]="resultPicker2"></button>
59+
<md-datepicker
60+
#resultPicker2
61+
[touchUi]="touch"
62+
[startAt]="startAt"
63+
[startView]="yearView ? 'year' : 'month'">
64+
</md-datepicker>
65+
</p>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
md-calendar {
2+
width: 300px;
3+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {Component} from '@angular/core';
2+
3+
4+
@Component({
5+
moduleId: module.id,
6+
selector: 'datepicker-demo',
7+
templateUrl: 'datepicker-demo.html',
8+
styleUrls: ['datepicker-demo.css'],
9+
})
10+
export class DatepickerDemo {
11+
touch: boolean;
12+
filterOdd: boolean;
13+
yearView: boolean;
14+
minDate: Date;
15+
maxDate: Date;
16+
startAt: Date;
17+
date: Date;
18+
dateFilter = (date: Date) => date.getMonth() % 2 == 1 && date.getDate() % 2 == 0;
19+
}

src/demo-app/demo-app-module.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import {NgModule, ApplicationRef} from '@angular/core';
1+
import {ApplicationRef, NgModule} from '@angular/core';
22
import {BrowserModule} from '@angular/platform-browser';
33
import {HttpModule} from '@angular/http';
44
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
55
import {RouterModule} from '@angular/router';
66
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
77
import {DemoApp, Home} from './demo-app/demo-app';
88
import {
9-
MaterialModule,
10-
OverlayContainer,
119
FullscreenOverlayContainer,
10+
MaterialModule,
11+
MdNativeDateModule,
1212
MdSelectionModule,
13+
OverlayContainer
1314
} from '@angular/material';
1415
import {DEMO_APP_ROUTES} from './demo-app/routes';
1516
import {ProgressBarDemo} from './progress-bar/progress-bar-demo';
16-
import {JazzDialog, ContentElementDialog, DialogDemo, IFrameDialog} from './dialog/dialog-demo';
17+
import {ContentElementDialog, DialogDemo, IFrameDialog, JazzDialog} from './dialog/dialog-demo';
1718
import {RippleDemo} from './ripple/ripple-demo';
1819
import {IconDemo} from './icon/icon-demo';
1920
import {GesturesDemo} from './gestures/gestures-demo';
@@ -27,22 +28,23 @@ import {ListDemo} from './list/list-demo';
2728
import {BaselineDemo} from './baseline/baseline-demo';
2829
import {GridListDemo} from './grid-list/grid-list-demo';
2930
import {LiveAnnouncerDemo} from './live-announcer/live-announcer-demo';
30-
import {OverlayDemo, SpagettiPanel, RotiniPanel} from './overlay/overlay-demo';
31+
import {OverlayDemo, RotiniPanel, SpagettiPanel} from './overlay/overlay-demo';
3132
import {SlideToggleDemo} from './slide-toggle/slide-toggle-demo';
3233
import {ToolbarDemo} from './toolbar/toolbar-demo';
3334
import {ButtonDemo} from './button/button-demo';
34-
import {MdCheckboxDemoNestedChecklist, CheckboxDemo} from './checkbox/checkbox-demo';
35+
import {CheckboxDemo, MdCheckboxDemoNestedChecklist} from './checkbox/checkbox-demo';
3536
import {SelectDemo} from './select/select-demo';
3637
import {SliderDemo} from './slider/slider-demo';
3738
import {SidenavDemo} from './sidenav/sidenav-demo';
3839
import {SnackBarDemo} from './snack-bar/snack-bar-demo';
3940
import {PortalDemo, ScienceJoke} from './portal/portal-demo';
4041
import {MenuDemo} from './menu/menu-demo';
41-
import {TabsDemo, SunnyTabContent, RainyTabContent, FoggyTabContent} from './tabs/tabs-demo';
42+
import {FoggyTabContent, RainyTabContent, SunnyTabContent, TabsDemo} from './tabs/tabs-demo';
4243
import {PlatformDemo} from './platform/platform-demo';
4344
import {AutocompleteDemo} from './autocomplete/autocomplete-demo';
4445
import {InputDemo} from './input/input-demo';
4546
import {StyleDemo} from './style/style-demo';
47+
import {DatepickerDemo} from './datepicker/datepicker-demo';
4648

4749

4850
@NgModule({
@@ -54,6 +56,7 @@ import {StyleDemo} from './style/style-demo';
5456
ReactiveFormsModule,
5557
RouterModule.forRoot(DEMO_APP_ROUTES),
5658
MaterialModule,
59+
MdNativeDateModule,
5760
MdSelectionModule,
5861
],
5962
declarations: [
@@ -64,6 +67,7 @@ import {StyleDemo} from './style/style-demo';
6467
CardDemo,
6568
ChipsDemo,
6669
CheckboxDemo,
70+
DatepickerDemo,
6771
DemoApp,
6872
DialogDemo,
6973
GesturesDemo,

src/demo-app/demo-app/demo-app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export class DemoApp {
3030
{name: 'Card', route: 'card'},
3131
{name: 'Chips', route: 'chips'},
3232
{name: 'Checkbox', route: 'checkbox'},
33+
{name: 'Datepicker', route: 'datepicker'},
3334
{name: 'Dialog', route: 'dialog'},
3435
{name: 'Gestures', route: 'gestures'},
3536
{name: 'Grid List', route: 'grid-list'},

src/demo-app/demo-app/routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@ import {PlatformDemo} from '../platform/platform-demo';
3232
import {AutocompleteDemo} from '../autocomplete/autocomplete-demo';
3333
import {InputDemo} from '../input/input-demo';
3434
import {StyleDemo} from '../style/style-demo';
35+
import {DatepickerDemo} from '../datepicker/datepicker-demo';
3536

3637
export const DEMO_APP_ROUTES: Routes = [
3738
{path: '', component: Home},
3839
{path: 'autocomplete', component: AutocompleteDemo},
3940
{path: 'button', component: ButtonDemo},
4041
{path: 'card', component: CardDemo},
4142
{path: 'chips', component: ChipsDemo},
43+
{path: 'datepicker', component: DatepickerDemo},
4244
{path: 'radio', component: RadioDemo},
4345
{path: 'select', component: SelectDemo},
4446
{path: 'sidenav', component: SidenavDemo},

src/lib/core/core.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ export {CompatibilityModule, NoConflictStyleCompatibilityMode} from './compatibi
103103
// Common material module
104104
export {MdCommonModule} from './common-behaviors/common-module';
105105

106+
// Datetime
107+
export * from './datetime/index';
106108

107109
@NgModule({
108110
imports: [

src/lib/core/datetime/date-adapter.ts

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/** Adapts type `D` to be usable as a date by cdk-based components that work with dates. */
2+
export abstract class DateAdapter<D> {
3+
/** The locale to use for all dates. */
4+
protected locale: any;
5+
6+
/**
7+
* Gets the year component of the given date.
8+
* @param date The date to extract the year from.
9+
* @returns The year component.
10+
*/
11+
abstract getYear(date: D): number;
12+
13+
/**
14+
* Gets the month component of the given date.
15+
* @param date The date to extract the month from.
16+
* @returns The month component (0-indexed, 0 = January).
17+
*/
18+
abstract getMonth(date: D): number;
19+
20+
/**
21+
* Gets the date of the month component of the given date.
22+
* @param date The date to extract the date of the month from.
23+
* @returns The month component (1-indexed, 1 = first of month).
24+
*/
25+
abstract getDate(date: D): number;
26+
27+
/**
28+
* Gets the day of the week component of the given date.
29+
* @param date The date to extract the day of the week from.
30+
* @returns The month component (0-indexed, 0 = Sunday).
31+
*/
32+
abstract getDayOfWeek(date: D): number;
33+
34+
/**
35+
* Gets a list of names for the months.
36+
* @param style The naming style (e.g. long = 'January', short = 'Jan', narrow = 'J').
37+
* @returns An ordered list of all month names, starting with January.
38+
*/
39+
abstract getMonthNames(style: 'long' | 'short' | 'narrow'): string[];
40+
41+
/**
42+
* Gets a list of names for the dates of the month.
43+
* @returns An ordered list of all date of the month names, starting with '1'.
44+
*/
45+
abstract getDateNames(): string[];
46+
47+
/**
48+
* Gets a list of names for the days of the week.
49+
* @param style The naming style (e.g. long = 'Sunday', short = 'Sun', narrow = 'S').
50+
* @returns An ordered list of all weekday names, starting with Sunday.
51+
*/
52+
abstract getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): string[];
53+
54+
/**
55+
* Gets the name for the year of the given date.
56+
* @param date The date to get the year name for.
57+
* @returns The name of the given year (e.g. '2017').
58+
*/
59+
abstract getYearName(date: D): string;
60+
61+
/**
62+
* Gets the first day of the week.
63+
* @returns The first day of the week (0-indexed, 0 = Sunday).
64+
*/
65+
abstract getFirstDayOfWeek(): number;
66+
67+
/**
68+
* Gets the number of days in the month of the given date.
69+
* @param date The date whose month should be checked.
70+
* @returns The number of days in the month of the given date.
71+
*/
72+
abstract getNumDaysInMonth(date: D): number;
73+
74+
/**
75+
* Clones the given date.
76+
* @param date The date to clone
77+
* @returns A new date equal to the given date.
78+
*/
79+
abstract clone(date: D): D;
80+
81+
/**
82+
* Creates a date with the given year, month, and date. Does not allow over/under-flow of the
83+
* month and date.
84+
* @param year The full year of the date. (e.g. 89 means the year 89, not the year 1989).
85+
* @param month The month of the date (0-indexed, 0 = January). Must be an integer 0 - 11.
86+
* @param date The date of month of the date. Must be an integer 1 - length of the given month.
87+
* @returns The new date, or null if invalid.
88+
*/
89+
abstract createDate(year: number, month: number, date: number): D;
90+
91+
/**
92+
* Gets today's date.
93+
* @returns Today's date.
94+
*/
95+
abstract today(): D;
96+
97+
/**
98+
* Parses a date from a value.
99+
* @param value The value to parse.
100+
* @param parseFormat The expected format of the value being parsed
101+
* (type is implementation-dependent).
102+
* @returns The parsed date, or null if date could not be parsed.
103+
*/
104+
abstract parse(value: any, parseFormat: any): D | null;
105+
106+
/**
107+
* Formats a date as a string.
108+
* @param date The value to parse.
109+
* @param displayFormat The format to use to display the date as a string.
110+
* @returns The parsed date, or null if date could not be parsed.
111+
*/
112+
abstract format(date: D, displayFormat: any): string;
113+
114+
/**
115+
* Adds the given number of years to the date. Years are counted as if flipping 12 pages on the
116+
* calendar for each year and then finding the closest date in the new month. For example when
117+
* adding 1 year to Feb 29, 2016, the resulting date will be Feb 28, 2017.
118+
* @param date The date to add years to.
119+
* @param years The number of years to add (may be negative).
120+
* @returns A new date equal to the given one with the specified number of years added.
121+
*/
122+
abstract addCalendarYears(date: D, years: number): D;
123+
124+
/**
125+
* Adds the given number of months to the date. Months are counted as if flipping a page on the
126+
* calendar for each month and then finding the closest date in the new month. For example when
127+
* adding 1 month to Jan 31, 2017, the resulting date will be Feb 28, 2017.
128+
* @param date The date to add months to.
129+
* @param months The number of months to add (may be negative).
130+
* @returns A new date equal to the given one with the specified number of months added.
131+
*/
132+
abstract addCalendarMonths(date: D, months: number): D;
133+
134+
/**
135+
* Adds the given number of days to the date. Days are counted as if moving one cell on the
136+
* calendar for each day.
137+
* @param date The date to add days to.
138+
* @param days The number of days to add (may be negative).
139+
* @returns A new date equal to the given one with the specified number of days added.
140+
*/
141+
abstract addCalendarDays(date: D, days: number): D;
142+
143+
/**
144+
* Gets the RFC 3339 compatible date string (https://tools.ietf.org/html/rfc3339) for the given
145+
* date.
146+
* @param date The date to get the ISO date string for.
147+
* @returns The ISO date string date string.
148+
*/
149+
abstract getISODateString(date: D): string;
150+
151+
/**
152+
* Sets the locale used for all dates.
153+
* @param locale The new locale.
154+
*/
155+
setLocale(locale: any) {
156+
this.locale = locale;
157+
}
158+
159+
/**
160+
* Compares two dates.
161+
* @param first The first date to compare.
162+
* @param second The second date to compare.
163+
* @returns 0 if the dates are equal, a number less than 0 if the first date is earlier,
164+
* a number greater than 0 if the first date is later.
165+
*/
166+
compareDate(first: D, second: D): number {
167+
return this.getYear(first) - this.getYear(second) ||
168+
this.getMonth(first) - this.getMonth(second) ||
169+
this.getDate(first) - this.getDate(second);
170+
}
171+
172+
/**
173+
* Checks if two dates are equal.
174+
* @param first The first date to check.
175+
* @param second The second date to check.
176+
* @returns {boolean} Whether the two dates are equal.
177+
* Null dates are considered equal to other null dates.
178+
*/
179+
sameDate(first: D | null, second: D | null): boolean {
180+
return first && second ? !this.compareDate(first, second) : first == second;
181+
}
182+
183+
/**
184+
* Clamp the given date between min and max dates.
185+
* @param date The date to clamp.
186+
* @param min The minimum value to allow. If null or omitted no min is enforced.
187+
* @param max The maximum value to allow. If null or omitted no max is enforced.
188+
* @returns `min` if `date` is less than `min`, `max` if date is greater than `max`,
189+
* otherwise `date`.
190+
*/
191+
clampDate(date: D, min?: D | null, max?: D | null): D {
192+
if (min && this.compareDate(date, min) < 0) {
193+
return min;
194+
}
195+
if (max && this.compareDate(date, max) > 0) {
196+
return max;
197+
}
198+
return date;
199+
}
200+
}

0 commit comments

Comments
 (0)