1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | exports.DateInput = void 0;
|
19 | var tslib_1 = require("tslib");
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | var classnames_1 = tslib_1.__importDefault(require("classnames"));
|
27 | var React = tslib_1.__importStar(require("react"));
|
28 | var core_1 = require("@blueprintjs/core");
|
29 | var Classes = tslib_1.__importStar(require("./common/classes"));
|
30 | var dateUtils_1 = require("./common/dateUtils");
|
31 | var dateFormat_1 = require("./dateFormat");
|
32 | var datePicker_1 = require("./datePicker");
|
33 | var datePickerCore_1 = require("./datePickerCore");
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | var DateInput = (function (_super) {
|
41 | tslib_1.__extends(DateInput, _super);
|
42 | function DateInput() {
|
43 | var _this = this;
|
44 | var _a;
|
45 | _this = _super.apply(this, arguments) || this;
|
46 | _this.state = {
|
47 | isInputFocused: false,
|
48 | isOpen: false,
|
49 | value: _this.props.value !== undefined ? _this.props.value : _this.props.defaultValue,
|
50 | valueString: null,
|
51 | };
|
52 | _this.inputElement = null;
|
53 | _this.popoverContentElement = null;
|
54 | _this.handleInputRef = (0, core_1.refHandler)(_this, "inputElement", (_a = _this.props.inputProps) === null || _a === void 0 ? void 0 : _a.inputRef);
|
55 | _this.handlePopoverContentRef = (0, core_1.refHandler)(_this, "popoverContentElement");
|
56 | _this.handleClosePopover = function (e) {
|
57 | var _a;
|
58 | var _b = _this.props.popoverProps, popoverProps = _b === void 0 ? {} : _b;
|
59 | (_a = popoverProps.onClose) === null || _a === void 0 ? void 0 : _a.call(popoverProps, e);
|
60 | _this.setState({ isOpen: false });
|
61 | };
|
62 | _this.handleDateChange = function (newDate, isUserChange, didSubmitWithEnter) {
|
63 | var _a, _b;
|
64 | if (didSubmitWithEnter === void 0) { didSubmitWithEnter = false; }
|
65 | var prevDate = _this.state.value;
|
66 |
|
67 |
|
68 |
|
69 | var isOpen = !isUserChange ||
|
70 | !_this.props.closeOnSelection ||
|
71 | (prevDate != null && (_this.hasMonthChanged(prevDate, newDate) || _this.hasTimeChanged(prevDate, newDate)));
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 | var isInputFocused = didSubmitWithEnter ? true : false;
|
78 | if (_this.props.value === undefined) {
|
79 | var valueString = (0, dateFormat_1.getFormattedDateString)(newDate, _this.props);
|
80 | _this.setState({ isInputFocused: isInputFocused, isOpen: isOpen, value: newDate, valueString: valueString });
|
81 | }
|
82 | else {
|
83 | _this.setState({ isInputFocused: isInputFocused, isOpen: isOpen });
|
84 | }
|
85 | (_b = (_a = _this.props).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, newDate, isUserChange);
|
86 | };
|
87 | _this.handleInputFocus = function (e) {
|
88 | var valueString = _this.state.value == null ? "" : _this.formatDate(_this.state.value);
|
89 | _this.setState({ isInputFocused: true, isOpen: true, valueString: valueString });
|
90 | _this.safeInvokeInputProp("onFocus", e);
|
91 | };
|
92 | _this.handleInputClick = function (e) {
|
93 |
|
94 |
|
95 | e.stopPropagation();
|
96 | _this.safeInvokeInputProp("onClick", e);
|
97 | };
|
98 | _this.handleInputChange = function (e) {
|
99 | var _a, _b, _c, _d;
|
100 | var valueString = e.target.value;
|
101 | var value = _this.parseDate(valueString);
|
102 | if ((0, dateUtils_1.isDateValid)(value) && _this.isDateInRange(value)) {
|
103 | if (_this.props.value === undefined) {
|
104 | _this.setState({ value: value, valueString: valueString });
|
105 | }
|
106 | else {
|
107 | _this.setState({ valueString: valueString });
|
108 | }
|
109 | (_b = (_a = _this.props).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, value, true);
|
110 | }
|
111 | else {
|
112 | if (valueString.length === 0) {
|
113 | (_d = (_c = _this.props).onChange) === null || _d === void 0 ? void 0 : _d.call(_c, null, true);
|
114 | }
|
115 | _this.setState({ valueString: valueString });
|
116 | }
|
117 | _this.safeInvokeInputProp("onChange", e);
|
118 | };
|
119 | _this.handleInputBlur = function (e) {
|
120 | var _a, _b, _c, _d, _e, _f;
|
121 | var valueString = _this.state.valueString;
|
122 | var date = _this.parseDate(valueString);
|
123 | if (valueString.length > 0 &&
|
124 | valueString !== (0, dateFormat_1.getFormattedDateString)(_this.state.value, _this.props) &&
|
125 | (!(0, dateUtils_1.isDateValid)(date) || !_this.isDateInRange(date))) {
|
126 | if (_this.props.value === undefined) {
|
127 | _this.setState({ isInputFocused: false, value: date, valueString: null });
|
128 | }
|
129 | else {
|
130 | _this.setState({ isInputFocused: false });
|
131 | }
|
132 | if (isNaN(date.valueOf())) {
|
133 | (_b = (_a = _this.props).onError) === null || _b === void 0 ? void 0 : _b.call(_a, new Date(undefined));
|
134 | }
|
135 | else if (!_this.isDateInRange(date)) {
|
136 | (_d = (_c = _this.props).onError) === null || _d === void 0 ? void 0 : _d.call(_c, date);
|
137 | }
|
138 | else {
|
139 | (_f = (_e = _this.props).onChange) === null || _f === void 0 ? void 0 : _f.call(_e, date, true);
|
140 | }
|
141 | }
|
142 | else {
|
143 | if (valueString.length === 0) {
|
144 | _this.setState({ isInputFocused: false, value: null, valueString: null });
|
145 | }
|
146 | else {
|
147 | _this.setState({ isInputFocused: false });
|
148 | }
|
149 | }
|
150 | _this.safeInvokeInputProp("onBlur", e);
|
151 | };
|
152 | _this.handleInputKeyDown = function (e) {
|
153 | var _a, _b;
|
154 |
|
155 | if (e.which === core_1.Keys.ENTER) {
|
156 | var nextDate = _this.parseDate(_this.state.valueString);
|
157 | _this.handleDateChange(nextDate, true, true);
|
158 | }
|
159 | else if (e.which === core_1.Keys.TAB && e.shiftKey) {
|
160 |
|
161 | _this.handleClosePopover();
|
162 | }
|
163 | else if (e.which === core_1.Keys.TAB && _this.state.isOpen) {
|
164 | (_a = _this.getKeyboardFocusableElements().shift()) === null || _a === void 0 ? void 0 : _a.focus();
|
165 |
|
166 | e.preventDefault();
|
167 | }
|
168 | else if (e.which === core_1.Keys.ESCAPE) {
|
169 | _this.setState({ isOpen: false });
|
170 | (_b = _this.inputElement) === null || _b === void 0 ? void 0 : _b.blur();
|
171 | }
|
172 | _this.safeInvokeInputProp("onKeyDown", e);
|
173 | };
|
174 | _this.getKeyboardFocusableElements = function () {
|
175 | var _a;
|
176 | var elements = Array.from((_a = _this.popoverContentElement) === null || _a === void 0 ? void 0 : _a.querySelectorAll("button:not([disabled]),input,[tabindex]:not([tabindex='-1'])"));
|
177 |
|
178 | elements.pop();
|
179 | elements.shift();
|
180 | return elements;
|
181 | };
|
182 | _this.handleStartFocusBoundaryFocusIn = function (e) {
|
183 | var _a, _b;
|
184 | if (_this.popoverContentElement.contains(_this.getRelatedTarget(e))) {
|
185 |
|
186 |
|
187 | (_a = _this.inputElement) === null || _a === void 0 ? void 0 : _a.focus();
|
188 | }
|
189 | else {
|
190 | (_b = _this.getKeyboardFocusableElements().shift()) === null || _b === void 0 ? void 0 : _b.focus();
|
191 | }
|
192 | };
|
193 | _this.handleEndFocusBoundaryFocusIn = function (e) {
|
194 | var _a, _b;
|
195 | if (_this.popoverContentElement.contains(_this.getRelatedTarget(e))) {
|
196 | (_a = _this.inputElement) === null || _a === void 0 ? void 0 : _a.focus();
|
197 | _this.handleClosePopover();
|
198 | }
|
199 | else {
|
200 | (_b = _this.getKeyboardFocusableElements().pop()) === null || _b === void 0 ? void 0 : _b.focus();
|
201 | }
|
202 | };
|
203 | _this.handleShortcutChange = function (_, selectedShortcutIndex) {
|
204 | _this.setState({ selectedShortcutIndex: selectedShortcutIndex });
|
205 | };
|
206 | return _this;
|
207 | }
|
208 | DateInput.prototype.render = function () {
|
209 | var _this = this;
|
210 | var _a = this.state, value = _a.value, valueString = _a.valueString;
|
211 | var dateString = this.state.isInputFocused ? valueString : (0, dateFormat_1.getFormattedDateString)(value, this.props);
|
212 | var dateValue = (0, dateUtils_1.isDateValid)(value) ? value : null;
|
213 | var dayPickerProps = tslib_1.__assign(tslib_1.__assign({}, this.props.dayPickerProps), { onDayKeyDown: function (day, modifiers, e) {
|
214 | var _a, _b;
|
215 | (_b = (_a = _this.props.dayPickerProps).onDayKeyDown) === null || _b === void 0 ? void 0 : _b.call(_a, day, modifiers, e);
|
216 | }, onMonthChange: function (month) {
|
217 | var _a, _b;
|
218 | (_b = (_a = _this.props.dayPickerProps).onMonthChange) === null || _b === void 0 ? void 0 : _b.call(_a, month);
|
219 | } });
|
220 |
|
221 |
|
222 |
|
223 | var wrappedPopoverContent = (React.createElement("div", { ref: this.handlePopoverContentRef },
|
224 | React.createElement("div", { onFocus: this.handleStartFocusBoundaryFocusIn, tabIndex: 0 }),
|
225 | React.createElement(datePicker_1.DatePicker, tslib_1.__assign({}, this.props, { dayPickerProps: dayPickerProps, onChange: this.handleDateChange, value: dateValue, onShortcutChange: this.handleShortcutChange, selectedShortcutIndex: this.state.selectedShortcutIndex })),
|
226 | React.createElement("div", { onFocus: this.handleEndFocusBoundaryFocusIn, tabIndex: 0 })));
|
227 |
|
228 | var _b = this.props, _c = _b.inputProps, inputProps = _c === void 0 ? {} : _c, _d = _b.popoverProps, popoverProps = _d === void 0 ? {} : _d;
|
229 | var isErrorState = value != null && (!(0, dateUtils_1.isDateValid)(value) || !this.isDateInRange(value));
|
230 | return (React.createElement(core_1.Popover, tslib_1.__assign({ isOpen: this.state.isOpen && !this.props.disabled, fill: this.props.fill }, popoverProps, { autoFocus: false, className: (0, classnames_1.default)(popoverProps.className, this.props.className), content: wrappedPopoverContent, enforceFocus: false, onClose: this.handleClosePopover, popoverClassName: (0, classnames_1.default)(Classes.DATEINPUT_POPOVER, popoverProps.popoverClassName) }),
|
231 | React.createElement(core_1.InputGroup, tslib_1.__assign({ autoComplete: "off", intent: isErrorState ? core_1.Intent.DANGER : core_1.Intent.NONE, placeholder: this.props.placeholder, rightElement: this.props.rightElement, type: "text" }, inputProps, { disabled: this.props.disabled, inputRef: this.handleInputRef, onBlur: this.handleInputBlur, onChange: this.handleInputChange, onClick: this.handleInputClick, onFocus: this.handleInputFocus, onKeyDown: this.handleInputKeyDown, value: dateString }))));
|
232 | };
|
233 | DateInput.prototype.componentDidUpdate = function (prevProps, prevState) {
|
234 | var _a, _b, _c, _d, _e;
|
235 | _super.prototype.componentDidUpdate.call(this, prevProps, prevState);
|
236 | if (((_a = prevProps.inputProps) === null || _a === void 0 ? void 0 : _a.inputRef) !== ((_b = this.props.inputProps) === null || _b === void 0 ? void 0 : _b.inputRef)) {
|
237 | (0, core_1.setRef)((_c = prevProps.inputProps) === null || _c === void 0 ? void 0 : _c.inputRef, null);
|
238 | this.handleInputRef = (0, core_1.refHandler)(this, "inputElement", (_d = this.props.inputProps) === null || _d === void 0 ? void 0 : _d.inputRef);
|
239 | (0, core_1.setRef)((_e = this.props.inputProps) === null || _e === void 0 ? void 0 : _e.inputRef, this.inputElement);
|
240 | }
|
241 | if (prevProps.value !== this.props.value) {
|
242 | this.setState({ value: this.props.value });
|
243 | }
|
244 | };
|
245 | DateInput.prototype.isDateInRange = function (value) {
|
246 | return (0, dateUtils_1.isDayInRange)(value, [this.props.minDate, this.props.maxDate]);
|
247 | };
|
248 | DateInput.prototype.hasMonthChanged = function (prevDate, nextDate) {
|
249 | return (prevDate == null) !== (nextDate == null) || nextDate.getMonth() !== prevDate.getMonth();
|
250 | };
|
251 | DateInput.prototype.hasTimeChanged = function (prevDate, nextDate) {
|
252 | if (this.props.timePrecision == null) {
|
253 | return false;
|
254 | }
|
255 | return ((prevDate == null) !== (nextDate == null) ||
|
256 | nextDate.getHours() !== prevDate.getHours() ||
|
257 | nextDate.getMinutes() !== prevDate.getMinutes() ||
|
258 | nextDate.getSeconds() !== prevDate.getSeconds() ||
|
259 | nextDate.getMilliseconds() !== prevDate.getMilliseconds());
|
260 | };
|
261 | DateInput.prototype.getRelatedTarget = function (e) {
|
262 | var _a;
|
263 |
|
264 | return ((_a = e.relatedTarget) !== null && _a !== void 0 ? _a : document.activeElement);
|
265 | };
|
266 |
|
267 | DateInput.prototype.safeInvokeInputProp = function (name, e) {
|
268 | var _a;
|
269 | var _b = this.props.inputProps, inputProps = _b === void 0 ? {} : _b;
|
270 | (_a = inputProps[name]) === null || _a === void 0 ? void 0 : _a.call(inputProps, e);
|
271 | };
|
272 | DateInput.prototype.parseDate = function (dateString) {
|
273 | if (dateString === this.props.outOfRangeMessage || dateString === this.props.invalidDateMessage) {
|
274 | return null;
|
275 | }
|
276 | var _a = this.props, locale = _a.locale, parseDate = _a.parseDate;
|
277 | var newDate = parseDate(dateString, locale);
|
278 | return newDate === false ? new Date(undefined) : newDate;
|
279 | };
|
280 | DateInput.prototype.formatDate = function (date) {
|
281 | if (!(0, dateUtils_1.isDateValid)(date) || !this.isDateInRange(date)) {
|
282 | return "";
|
283 | }
|
284 | var _a = this.props, locale = _a.locale, formatDate = _a.formatDate;
|
285 | return formatDate(date, locale);
|
286 | };
|
287 | DateInput.displayName = "".concat(core_1.DISPLAYNAME_PREFIX, ".DateInput");
|
288 | DateInput.defaultProps = {
|
289 | closeOnSelection: true,
|
290 | dayPickerProps: {},
|
291 | disabled: false,
|
292 | invalidDateMessage: "Invalid date",
|
293 | maxDate: (0, datePickerCore_1.getDefaultMaxDate)(),
|
294 | minDate: (0, datePickerCore_1.getDefaultMinDate)(),
|
295 | outOfRangeMessage: "Out of range",
|
296 | reverseMonthAndYearMenus: false,
|
297 | };
|
298 | return DateInput;
|
299 | }(core_1.AbstractPureComponent2));
|
300 | exports.DateInput = DateInput;
|
301 |
|
\ | No newline at end of file |