UNPKG

6.92 kBJavaScriptView Raw
1/*
2 * Copyright 2016 Palantir Technologies, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import { Boundary } from "@blueprintjs/core";
17import { areSameDay } from "./common/dateUtils";
18/* eslint-disable-next-line @typescript-eslint/no-extraneous-class */
19export class DateRangeSelectionStrategy {
20 /**
21 * Returns the new date-range and the boundary that would be affected if `day` were clicked. The
22 * affected boundary may be different from the provided `boundary` in some cases. For example,
23 * clicking a particular boundary's selected date will always deselect it regardless of which
24 * `boundary` you provide to this function (because it's simply a more intuitive interaction).
25 */
26 static getNextState(currentRange, day, allowSingleDayRange, boundary) {
27 if (boundary != null) {
28 return this.getNextStateForBoundary(currentRange, day, allowSingleDayRange, boundary);
29 }
30 else {
31 return this.getDefaultNextState(currentRange, day, allowSingleDayRange);
32 }
33 }
34 static getNextStateForBoundary(currentRange, day, allowSingleDayRange, boundary) {
35 const boundaryDate = this.getBoundaryDate(boundary, currentRange);
36 const otherBoundary = this.getOtherBoundary(boundary);
37 const otherBoundaryDate = this.getBoundaryDate(otherBoundary, currentRange);
38 let nextBoundary;
39 let nextDateRange;
40 if (boundaryDate == null && otherBoundaryDate == null) {
41 nextBoundary = boundary;
42 nextDateRange = this.createRangeForBoundary(boundary, day, null);
43 }
44 else if (boundaryDate != null && otherBoundaryDate == null) {
45 const nextBoundaryDate = areSameDay(boundaryDate, day) ? null : day;
46 nextBoundary = boundary;
47 nextDateRange = this.createRangeForBoundary(boundary, nextBoundaryDate, null);
48 }
49 else if (boundaryDate == null && otherBoundaryDate != null) {
50 if (areSameDay(day, otherBoundaryDate)) {
51 let nextDate;
52 if (allowSingleDayRange) {
53 nextBoundary = boundary;
54 nextDate = otherBoundaryDate;
55 }
56 else {
57 nextBoundary = otherBoundary;
58 nextDate = null;
59 }
60 nextDateRange = this.createRangeForBoundary(boundary, nextDate, nextDate);
61 }
62 else if (this.isOverlappingOtherBoundary(boundary, day, otherBoundaryDate)) {
63 nextBoundary = otherBoundary;
64 nextDateRange = this.createRangeForBoundary(boundary, otherBoundaryDate, day);
65 }
66 else {
67 nextBoundary = boundary;
68 nextDateRange = this.createRangeForBoundary(boundary, day, otherBoundaryDate);
69 }
70 }
71 else {
72 // both boundaryDate and otherBoundaryDate are already defined
73 if (areSameDay(boundaryDate, day)) {
74 const isSingleDayRangeSelected = areSameDay(boundaryDate, otherBoundaryDate);
75 const nextOtherBoundaryDate = isSingleDayRangeSelected ? null : otherBoundaryDate;
76 nextBoundary = boundary;
77 nextDateRange = this.createRangeForBoundary(boundary, null, nextOtherBoundaryDate);
78 }
79 else if (areSameDay(day, otherBoundaryDate)) {
80 const [nextBoundaryDate, nextOtherBoundaryDate] = allowSingleDayRange
81 ? [otherBoundaryDate, otherBoundaryDate]
82 : [boundaryDate, null];
83 nextBoundary = allowSingleDayRange ? boundary : otherBoundary;
84 nextDateRange = this.createRangeForBoundary(boundary, nextBoundaryDate, nextOtherBoundaryDate);
85 }
86 else if (this.isOverlappingOtherBoundary(boundary, day, otherBoundaryDate)) {
87 nextBoundary = boundary;
88 nextDateRange = this.createRangeForBoundary(boundary, day, null);
89 }
90 else {
91 // extend the date range with an earlier boundaryDate date
92 nextBoundary = boundary;
93 nextDateRange = this.createRangeForBoundary(boundary, day, otherBoundaryDate);
94 }
95 }
96 return { dateRange: nextDateRange, boundary: nextBoundary };
97 }
98 static getDefaultNextState(selectedRange, day, allowSingleDayRange) {
99 const [start, end] = selectedRange;
100 let nextDateRange;
101 if (start == null && end == null) {
102 nextDateRange = [day, null];
103 }
104 else if (start != null && end == null) {
105 nextDateRange = this.createRange(day, start, allowSingleDayRange);
106 }
107 else if (start == null && end != null) {
108 nextDateRange = this.createRange(day, end, allowSingleDayRange);
109 }
110 else {
111 const isStart = areSameDay(start, day);
112 const isEnd = areSameDay(end, day);
113 if (isStart && isEnd) {
114 nextDateRange = [null, null];
115 }
116 else if (isStart) {
117 nextDateRange = [null, end];
118 }
119 else if (isEnd) {
120 nextDateRange = [start, null];
121 }
122 else {
123 nextDateRange = [day, null];
124 }
125 }
126 return { dateRange: nextDateRange };
127 }
128 static getOtherBoundary(boundary) {
129 return boundary === Boundary.START ? Boundary.END : Boundary.START;
130 }
131 static getBoundaryDate(boundary, dateRange) {
132 return boundary === Boundary.START ? dateRange[0] : dateRange[1];
133 }
134 static isOverlappingOtherBoundary(boundary, boundaryDate, otherBoundaryDate) {
135 return boundary === Boundary.START ? boundaryDate > otherBoundaryDate : boundaryDate < otherBoundaryDate;
136 }
137 static createRangeForBoundary(boundary, boundaryDate, otherBoundaryDate) {
138 return boundary === Boundary.START
139 ? [boundaryDate, otherBoundaryDate]
140 : [otherBoundaryDate, boundaryDate];
141 }
142 static createRange(a, b, allowSingleDayRange) {
143 // clicking the same date again will clear it
144 if (!allowSingleDayRange && areSameDay(a, b)) {
145 return [null, null];
146 }
147 return a < b ? [a, b] : [b, a];
148 }
149}
150//# sourceMappingURL=dateRangeSelectionStrategy.js.map
\No newline at end of file