Skip to content

Commit 2b58de7

Browse files
committed
refactor(datepicker): clean up date selection model
- Removes some methods from the date selection model that were put in place under the assumption that they'd be used, but we never ended up using them. - Moves the selection model out of `core` and into `datepicker`. I decided to do it, because it seems very tightly coupled to the datepicker and I don't see us needing it in other components in the future.
1 parent e9f9cdd commit 2b58de7

15 files changed

+76
-153
lines changed

src/material/core/datetime/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export * from './date-adapter';
1717
export * from './date-formats';
1818
export * from './native-date-adapter';
1919
export * from './native-date-formats';
20-
export * from './date-selection-model';
2120

2221

2322
@NgModule({

src/material/datepicker/calendar.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ import {
2929
DateAdapter,
3030
MAT_DATE_FORMATS,
3131
MatDateFormats,
32-
MatDateSelectionModel,
33-
MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER,
34-
DateRange,
3532
} from '@angular/material/core';
3633
import {Subject, Subscription} from 'rxjs';
3734
import {MatCalendarCellCssClasses} from './calendar-body';
@@ -45,6 +42,11 @@ import {
4542
yearsPerPage
4643
} from './multi-year-view';
4744
import {MatYearView} from './year-view';
45+
import {
46+
MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER,
47+
DateRange,
48+
MatDateSelectionModel,
49+
} from './date-selection-model';
4850

4951
/**
5052
* Possible views for the calendar.

src/material/datepicker/date-range-input-parts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ import {
3636
DateAdapter,
3737
MatDateFormats,
3838
ErrorStateMatcher,
39-
DateRange,
4039
} from '@angular/material/core';
4140
import {BooleanInput} from '@angular/cdk/coercion';
4241
import {MatDatepickerInputBase, DateFilterFn} from './datepicker-input-base';
42+
import {DateRange} from './date-selection-model';
4343

4444
/** Parent component that should be wrapped around `MatStartDate` and `MatEndDate`. */
4545
export interface MatDateRangeInputParent<D> {

src/material/datepicker/date-range-input.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@ import {
2020
ElementRef,
2121
} from '@angular/core';
2222
import {MatFormFieldControl, MatFormField} from '@angular/material/form-field';
23-
import {
24-
DateRange,
25-
ThemePalette,
26-
DateAdapter,
27-
MatDateSelectionModel,
28-
} from '@angular/material/core';
23+
import {ThemePalette, DateAdapter} from '@angular/material/core';
2924
import {NgControl, ControlContainer} from '@angular/forms';
3025
import {Subject, merge} from 'rxjs';
3126
import {coerceBooleanProperty, BooleanInput} from '@angular/cdk/coercion';
@@ -39,6 +34,7 @@ import {MatDatepickerControl} from './datepicker-base';
3934
import {createMissingDateImplError} from './datepicker-errors';
4035
import {DateFilterFn} from './datepicker-input-base';
4136
import {MatDateRangePicker} from './date-range-picker';
37+
import {DateRange, MatDateSelectionModel} from './date-selection-model';
4238

4339
let nextUniqueId = 0;
4440

src/material/datepicker/date-range-picker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
*/
88

99
import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core';
10-
import {MAT_RANGE_DATE_SELECTION_MODEL_PROVIDER, DateRange} from '@angular/material/core';
1110
import {MatDatepickerBase, MatDatepickerContent} from './datepicker-base';
1211
import {MatDateRangeInput} from './date-range-input';
12+
import {MAT_RANGE_DATE_SELECTION_MODEL_PROVIDER, DateRange} from './date-selection-model';
1313

1414
// TODO(mmalerba): We use a component instead of a directive here so the user can use implicit
1515
// template reference variables (e.g. #d vs #d="matDateRangePicker"). We can change this to a

src/material/core/datetime/date-selection-model.ts renamed to src/material/datepicker/date-selection-model.ts

Lines changed: 3 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {FactoryProvider, Injectable, Optional, SkipSelf, OnDestroy} from '@angular/core';
10-
import {DateAdapter} from './date-adapter';
10+
import {DateAdapter} from '@angular/material/core';
1111
import {Observable, Subject} from 'rxjs';
1212

1313
/** A class representing a range of dates. */
@@ -76,15 +76,6 @@ export abstract class MatDateSelectionModel<S, D = ExtractDateTypeFromSelection<
7676

7777
/** Checks whether the current selection is complete. */
7878
abstract isComplete(): boolean;
79-
80-
/** Checks whether the current selection is identical to the passed-in selection. */
81-
abstract isSame(other: S): boolean;
82-
83-
/** Checks whether the current selection is valid. */
84-
abstract isValid(): boolean;
85-
86-
/** Checks whether the current selection overlaps with the given range. */
87-
abstract overlaps(range: DateRange<D>): boolean;
8879
}
8980

9081
/** A selection model that contains a single date. */
@@ -106,27 +97,8 @@ export class MatSingleDateSelectionModel<D> extends MatDateSelectionModel<D | nu
10697
* Checks whether the current selection is complete. In the case of a single date selection, this
10798
* is true if the current selection is not null.
10899
*/
109-
isComplete() { return this.selection != null; }
110-
111-
/** Checks whether the current selection is identical to the passed-in selection. */
112-
isSame(other: D): boolean {
113-
return this.adapter.sameDate(other, this.selection);
114-
}
115-
116-
/**
117-
* Checks whether the current selection is valid. In the case of a single date selection, this
118-
* means that the current selection is not null and is a valid date.
119-
*/
120-
isValid(): boolean {
121-
return this.selection != null && this.adapter.isDateInstance(this.selection) &&
122-
this.adapter.isValid(this.selection);
123-
}
124-
125-
/** Checks whether the current selection overlaps with the given range. */
126-
overlaps(range: DateRange<D>): boolean {
127-
return !!(this.selection && range.start && range.end &&
128-
this.adapter.compareDate(range.start, this.selection) <= 0 &&
129-
this.adapter.compareDate(this.selection, range.end) <= 0);
100+
isComplete() {
101+
return this.selection != null;
130102
}
131103
}
132104

@@ -164,45 +136,6 @@ export class MatRangeDateSelectionModel<D> extends MatDateSelectionModel<DateRan
164136
isComplete(): boolean {
165137
return this.selection.start != null && this.selection.end != null;
166138
}
167-
168-
/** Checks whether the current selection is identical to the passed-in selection. */
169-
isSame(other: DateRange<D>): boolean {
170-
return this.adapter.sameDate(this.selection.start, other.start) &&
171-
this.adapter.sameDate(this.selection.end, other.end);
172-
}
173-
174-
/**
175-
* Checks whether the current selection is valid. In the case of a date range selection, this
176-
* means that the current selection has a `start` and `end` that are both non-null and valid
177-
* dates.
178-
*/
179-
isValid(): boolean {
180-
return this.selection.start != null && this.selection.end != null &&
181-
this.adapter.isValid(this.selection.start!) && this.adapter.isValid(this.selection.end!);
182-
}
183-
184-
/**
185-
* Returns true if the given range and the selection overlap in any way. False if otherwise, that
186-
* includes incomplete selections or ranges.
187-
*/
188-
overlaps(range: DateRange<D>): boolean {
189-
if (!(this.selection.start && this.selection.end && range.start && range.end)) {
190-
return false;
191-
}
192-
193-
return (
194-
this._isBetween(range.start, this.selection.start, this.selection.end) ||
195-
this._isBetween(range.end, this.selection.start, this.selection.end) ||
196-
(
197-
this.adapter.compareDate(range.start, this.selection.start) <= 0 &&
198-
this.adapter.compareDate(this.selection.end, range.end) <= 0
199-
)
200-
);
201-
}
202-
203-
private _isBetween(value: D, from: D, to: D): boolean {
204-
return this.adapter.compareDate(from, value) <= 0 && this.adapter.compareDate(value, to) <= 0;
205-
}
206139
}
207140

208141
/** @docs-private */

src/material/datepicker/datepicker-base.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ import {
4444
DateAdapter,
4545
mixinColor,
4646
ThemePalette,
47-
MatDateSelectionModel,
48-
ExtractDateTypeFromSelection,
4947
} from '@angular/material/core';
5048
import {MatDialog, MatDialogRef} from '@angular/material/dialog';
5149
import {merge, Subject, Observable} from 'rxjs';
@@ -55,6 +53,7 @@ import {matDatepickerAnimations} from './datepicker-animations';
5553
import {createMissingDateImplError} from './datepicker-errors';
5654
import {MatCalendarCellCssClasses} from './calendar-body';
5755
import {DateFilterFn} from './datepicker-input-base';
56+
import {ExtractDateTypeFromSelection, MatDateSelectionModel} from './date-selection-model';
5857

5958
/** Used to generate a unique ID for each datepicker instance. */
6059
let datepickerUid = 0;

src/material/datepicker/datepicker-input-base.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@ import {
2929
DateAdapter,
3030
MAT_DATE_FORMATS,
3131
MatDateFormats,
32-
MatDateSelectionModel,
33-
ExtractDateTypeFromSelection,
3432
} from '@angular/material/core';
3533
import {Subscription} from 'rxjs';
3634
import {createMissingDateImplError} from './datepicker-errors';
35+
import {ExtractDateTypeFromSelection, MatDateSelectionModel} from './date-selection-model';
3736

3837
/**
3938
* An event used for datepicker input and change events. We don't always have access to a native

src/material/datepicker/datepicker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
*/
88

99
import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core';
10-
import {MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER} from '@angular/material/core';
1110
import {MatDatepickerBase} from './datepicker-base';
1211
import {MatDatepickerInput} from './datepicker-input';
12+
import {MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER} from './date-selection-model';
1313

1414
// TODO(mmalerba): We use a component instead of a directive here so the user can use implicit
1515
// template reference variables (e.g. #d vs #d="matDatepicker"). We can change this to a directive

src/material/datepicker/month-view.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ import {
3333
ViewChild,
3434
OnDestroy,
3535
} from '@angular/core';
36-
import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats, DateRange} from '@angular/material/core';
36+
import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats} from '@angular/material/core';
3737
import {Directionality} from '@angular/cdk/bidi';
3838
import {MatCalendarBody, MatCalendarCell, MatCalendarCellCssClasses} from './calendar-body';
3939
import {createMissingDateImplError} from './datepicker-errors';
4040
import {Subscription} from 'rxjs';
4141
import {startWith} from 'rxjs/operators';
42+
import {DateRange} from './date-selection-model';
4243

4344

4445
const DAYS_PER_WEEK = 7;

src/material/datepicker/multi-year-view.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ import {
3131
ViewEncapsulation,
3232
OnDestroy,
3333
} from '@angular/core';
34-
import {DateAdapter, DateRange} from '@angular/material/core';
34+
import {DateAdapter} from '@angular/material/core';
3535
import {Directionality} from '@angular/cdk/bidi';
3636
import {MatCalendarBody, MatCalendarCell} from './calendar-body';
3737
import {createMissingDateImplError} from './datepicker-errors';
3838
import {Subscription} from 'rxjs';
3939
import {startWith} from 'rxjs/operators';
40+
import {DateRange} from './date-selection-model';
4041

4142
export const yearsPerPage = 24;
4243

src/material/datepicker/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ export * from './month-view';
2929
export * from './year-view';
3030
export * from './date-range-input';
3131
export * from './date-range-picker';
32+
export * from './date-selection-model';
3233
export {MatStartDate, MatEndDate} from './date-range-input-parts';
3334
export {MatMultiYearView, yearsPerPage, yearsPerRow} from './multi-year-view';

src/material/datepicker/year-view.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ import {
3232
ViewEncapsulation,
3333
OnDestroy,
3434
} from '@angular/core';
35-
import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats, DateRange} from '@angular/material/core';
35+
import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats} from '@angular/material/core';
3636
import {Directionality} from '@angular/cdk/bidi';
3737
import {MatCalendarBody, MatCalendarCell} from './calendar-body';
3838
import {createMissingDateImplError} from './datepicker-errors';
3939
import {Subscription} from 'rxjs';
4040
import {startWith} from 'rxjs/operators';
41+
import {DateRange} from './date-selection-model';
4142

4243
/**
4344
* An internal component used to display a single year in the datepicker.

tools/public_api_guard/material/core.d.ts

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,6 @@ export declare abstract class DateAdapter<D> {
7979
abstract today(): D;
8080
}
8181

82-
export declare class DateRange<D> {
83-
readonly end: D | null;
84-
readonly start: D | null;
85-
constructor(
86-
start: D | null,
87-
end: D | null);
88-
}
89-
90-
export interface DateSelectionModelChange<S> {
91-
selection: S;
92-
source: unknown;
93-
}
94-
9582
export declare const JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9, NOV = 10, DEC = 11;
9683

9784
export declare const defaultRippleAnimationConfig: {
@@ -105,8 +92,6 @@ export declare class ErrorStateMatcher {
10592
static ɵprov: i0.ɵɵInjectableDef<ErrorStateMatcher>;
10693
}
10794

108-
export declare type ExtractDateTypeFromSelection<T> = T extends DateRange<infer D> ? D : NonNullable<T>;
109-
11095
export declare const JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9, NOV = 10, DEC = 11;
11196

11297
export declare type FloatLabelType = 'always' | 'never' | 'auto';
@@ -213,16 +198,8 @@ export declare const MAT_NATIVE_DATE_FORMATS: MatDateFormats;
213198

214199
export declare const MAT_OPTION_PARENT_COMPONENT: InjectionToken<MatOptionParentComponent>;
215200

216-
export declare function MAT_RANGE_DATE_SELECTION_MODEL_FACTORY(parent: MatSingleDateSelectionModel<unknown>, adapter: DateAdapter<unknown>): MatSingleDateSelectionModel<unknown>;
217-
218-
export declare const MAT_RANGE_DATE_SELECTION_MODEL_PROVIDER: FactoryProvider;
219-
220201
export declare const MAT_RIPPLE_GLOBAL_OPTIONS: InjectionToken<RippleGlobalOptions>;
221202

222-
export declare function MAT_SINGLE_DATE_SELECTION_MODEL_FACTORY(parent: MatSingleDateSelectionModel<unknown>, adapter: DateAdapter<unknown>): MatSingleDateSelectionModel<unknown>;
223-
224-
export declare const MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER: FactoryProvider;
225-
226203
export declare class MatCommonModule {
227204
protected _document?: Document;
228205
constructor(highContrastModeDetector: HighContrastModeDetector, sanityChecks: any,
@@ -243,24 +220,6 @@ export declare type MatDateFormats = {
243220
};
244221
};
245222

246-
export declare abstract class MatDateSelectionModel<S, D = ExtractDateTypeFromSelection<S>> implements OnDestroy {
247-
protected readonly adapter: DateAdapter<D>;
248-
readonly selection: S;
249-
selectionChanged: Observable<DateSelectionModelChange<S>>;
250-
protected constructor(
251-
adapter: DateAdapter<D>,
252-
selection: S);
253-
abstract add(date: D | null): void;
254-
abstract isComplete(): boolean;
255-
abstract isSame(other: S): boolean;
256-
abstract isValid(): boolean;
257-
ngOnDestroy(): void;
258-
abstract overlaps(range: DateRange<D>): boolean;
259-
updateSelection(value: S, source: unknown): void;
260-
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatDateSelectionModel<any, any>, never, never, {}, {}, never>;
261-
static ɵfac: i0.ɵɵFactoryDef<MatDateSelectionModel<any, any>>;
262-
}
263-
264223
export declare const MATERIAL_SANITY_CHECKS: InjectionToken<SanityChecks>;
265224

266225
export declare class MatLine {
@@ -356,17 +315,6 @@ export declare class MatPseudoCheckboxModule {
356315

357316
export declare type MatPseudoCheckboxState = 'unchecked' | 'checked' | 'indeterminate';
358317

359-
export declare class MatRangeDateSelectionModel<D> extends MatDateSelectionModel<DateRange<D>, D> {
360-
constructor(adapter: DateAdapter<D>);
361-
add(date: D | null): void;
362-
isComplete(): boolean;
363-
isSame(other: DateRange<D>): boolean;
364-
isValid(): boolean;
365-
overlaps(range: DateRange<D>): boolean;
366-
static ɵfac: i0.ɵɵFactoryDef<MatRangeDateSelectionModel<any>>;
367-
static ɵprov: i0.ɵɵInjectableDef<MatRangeDateSelectionModel<any>>;
368-
}
369-
370318
export declare class MatRipple implements OnInit, OnDestroy, RippleTarget {
371319
animation: RippleAnimationConfig;
372320
centered: boolean;
@@ -394,17 +342,6 @@ export declare class MatRippleModule {
394342
static ɵmod: i0.ɵɵNgModuleDefWithMeta<MatRippleModule, [typeof i1.MatRipple], [typeof i2.MatCommonModule, typeof i3.PlatformModule], [typeof i1.MatRipple, typeof i2.MatCommonModule]>;
395343
}
396344

397-
export declare class MatSingleDateSelectionModel<D> extends MatDateSelectionModel<D | null, D> {
398-
constructor(adapter: DateAdapter<D>);
399-
add(date: D | null): void;
400-
isComplete(): boolean;
401-
isSame(other: D): boolean;
402-
isValid(): boolean;
403-
overlaps(range: DateRange<D>): boolean;
404-
static ɵfac: i0.ɵɵFactoryDef<MatSingleDateSelectionModel<any>>;
405-
static ɵprov: i0.ɵɵInjectableDef<MatSingleDateSelectionModel<any>>;
406-
}
407-
408345
export declare const JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9, NOV = 10, DEC = 11;
409346

410347
export declare function mixinColor<T extends Constructor<HasElementRef>>(base: T, defaultColor?: ThemePalette): CanColorCtor & T;

0 commit comments

Comments
 (0)