Skip to content

Commit c35acb1

Browse files
committed
Add overlaps function to date selection model
1 parent aa1686a commit c35acb1

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/material/core/datetime/date-selection-model.ts

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

99
import {DateAdapter} from '@angular/material/core';
10+
import {FactoryProvider, Optional, SkipSelf, Injectable} from '@angular/core';
1011
import {Subject, Observable} from 'rxjs';
1112

1213
export abstract class MatDateSelectionModel<D> {
@@ -23,6 +24,7 @@ export abstract class MatDateSelectionModel<D> {
2324
abstract isComplete(): boolean;
2425
abstract isSame(other: MatDateSelectionModel<D>): boolean;
2526
abstract isValid(): boolean;
27+
abstract overlaps(range: DateRange<D>): boolean;
2628
}
2729

2830
export interface DateRange<D> {
@@ -33,6 +35,7 @@ export interface DateRange<D> {
3335
/**
3436
* Concrete implementation of a MatDateSelectionModel that holds a single date.
3537
*/
38+
@Injectable()
3639
export class MatSingleDateSelectionModel<D> extends MatDateSelectionModel<D> {
3740
private _date: D | null = null;
3841

@@ -75,12 +78,22 @@ export class MatSingleDateSelectionModel<D> extends MatDateSelectionModel<D> {
7578
this._date = date;
7679
this._valueChangesSubject.next();
7780
}
81+
/**
82+
* Determines if the single date is within a given date range. Retuns false if either dates of
83+
* the range is null or if the selection is undefined.
84+
*/
85+
overlaps(range: DateRange<D>): boolean {
86+
return !!(this._date && range.start && range.end &&
87+
this.adapter.compareDate(range.start, this._date) <= 0 &&
88+
this.adapter.compareDate(this._date, range.end) <= 0);
89+
}
7890
}
7991

8092
/**
8193
* Concrete implementation of a MatDateSelectionModel that holds a date range, represented by
8294
* a start date and an end date.
8395
*/
96+
@Injectable()
8497
export class MatRangeDateSelectionModel<D> extends MatDateSelectionModel<D> {
8598
private _start: D | null = null;
8699
private _end: D | null = null;
@@ -138,4 +151,39 @@ export class MatRangeDateSelectionModel<D> extends MatDateSelectionModel<D> {
138151
end: this._end,
139152
};
140153
}
154+
155+
/**
156+
* Returns true if the given range and the selection overlap in any way. False if otherwise, that
157+
* includes incomplete selections or ranges.
158+
*/
159+
overlaps(range: DateRange<D>): boolean {
160+
if (!(this._start && this._end && range.start && range.end)) {
161+
return false;
162+
}
163+
164+
return (
165+
this._isBetween(range.start, this._start, this._end) ||
166+
this._isBetween(range.end, this._start, this._end) ||
167+
(
168+
this.adapter.compareDate(range.start, this._start) <= 0 &&
169+
this.adapter.compareDate(this._end, range.end) <= 0
170+
)
171+
);
172+
}
173+
174+
private _isBetween(value: D, from: D, to: D): boolean {
175+
return this.adapter.compareDate(from, value) <= 0 && this.adapter.compareDate(value, to) <= 0;
176+
}
141177
}
178+
179+
export function MAT_SINGLE_DATE_SELECTION_MODEL_FACTORY<D>(parent:
180+
MatSingleDateSelectionModel<D>,
181+
adapter: DateAdapter<D>) {
182+
return parent || new MatSingleDateSelectionModel(adapter);
183+
}
184+
185+
export const MAT_SINGLE_DATE_SELECTION_MODEL_PROVIDER: FactoryProvider = {
186+
provide: MatDateSelectionModel,
187+
deps: [[new Optional(), new SkipSelf(), MatDateSelectionModel], DateAdapter],
188+
useFactory: MAT_SINGLE_DATE_SELECTION_MODEL_FACTORY,
189+
};

0 commit comments

Comments
 (0)