UNPKG

13.9 kBJavaScriptView Raw
1import { __assign, __extends } from "tslib";
2import * as React from 'react';
3import { DayOfWeek, FirstWeekOfYear, DateRangeType } from '../../utilities/dateValues/DateValues';
4import { CalendarDay } from './CalendarDay';
5import { CalendarMonth } from './CalendarMonth';
6import { compareDates, getDateRangeArray } from '../../utilities/dateMath/DateMath';
7import { css, elementContains, KeyCodes, getNativeProps, divProperties, initializeComponentRef, FocusRects, } from '../../Utilities';
8import * as stylesImport from './Calendar.scss';
9var styles = stylesImport;
10var leftArrow = 'Up';
11var rightArrow = 'Down';
12var closeIcon = 'CalculatorMultiply';
13var iconStrings = {
14 leftNavigation: leftArrow,
15 rightNavigation: rightArrow,
16 closeIcon: closeIcon,
17};
18var defaultWorkWeekDays = [
19 DayOfWeek.Monday,
20 DayOfWeek.Tuesday,
21 DayOfWeek.Wednesday,
22 DayOfWeek.Thursday,
23 DayOfWeek.Friday,
24];
25var dateTimeFormatterCallbacks = {
26 formatMonthDayYear: function (date, strings) {
27 return strings.months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear();
28 },
29 formatMonthYear: function (date, strings) {
30 return strings.months[date.getMonth()] + ' ' + date.getFullYear();
31 },
32 formatDay: function (date) { return date.getDate().toString(); },
33 formatYear: function (date) { return date.getFullYear().toString(); },
34};
35var Calendar = /** @class */ (function (_super) {
36 __extends(Calendar, _super);
37 function Calendar(props) {
38 var _this = _super.call(this, props) || this;
39 _this._dayPicker = React.createRef();
40 _this._monthPicker = React.createRef();
41 _this._hasFocus = false;
42 _this._onBlur = function (event) {
43 if (!elementContains(event.currentTarget, event.relatedTarget)) {
44 _this._hasFocus = false;
45 _this.props.onBlur && _this.props.onBlur(event);
46 }
47 };
48 _this._onFocus = function (event) {
49 if (!_this._hasFocus) {
50 _this._hasFocus = true;
51 _this.props.onFocus && _this.props.onFocus(event);
52 }
53 };
54 _this._navigateDayPickerDay = function (date) {
55 _this.setState({
56 navigatedDayDate: date,
57 navigatedMonthDate: date,
58 });
59 };
60 _this._navigateMonthPickerDay = function (date) {
61 _this.setState({
62 navigatedMonthDate: date,
63 });
64 };
65 _this._onNavigateDayDate = function (date, focusOnNavigatedDay) {
66 _this._navigateDayPickerDay(date);
67 _this._focusOnUpdate = focusOnNavigatedDay;
68 };
69 _this._onNavigateMonthDate = function (date, focusOnNavigatedDay) {
70 if (!focusOnNavigatedDay) {
71 _this._navigateMonthPickerDay(date);
72 _this._focusOnUpdate = focusOnNavigatedDay;
73 return;
74 }
75 var monthPickerOnly = !_this.props.showMonthPickerAsOverlay && !_this.props.isDayPickerVisible;
76 if (monthPickerOnly) {
77 _this._onSelectDate(date);
78 }
79 _this._navigateDayPickerDay(date);
80 };
81 _this._onSelectDate = function (date, selectedDateRangeArray) {
82 var onSelectDate = _this.props.onSelectDate;
83 _this.setState({
84 selectedDate: date,
85 });
86 if (onSelectDate) {
87 onSelectDate(date, selectedDateRangeArray);
88 }
89 };
90 _this._onHeaderSelect = function (focus) {
91 _this.setState({
92 isDayPickerVisible: !_this.state.isDayPickerVisible,
93 isMonthPickerVisible: !_this.state.isMonthPickerVisible,
94 });
95 if (focus) {
96 _this._focusOnUpdate = true;
97 }
98 };
99 _this._onGotoToday = function () {
100 var _a = _this.props, dateRangeType = _a.dateRangeType, firstDayOfWeek = _a.firstDayOfWeek, today = _a.today, workWeekDays = _a.workWeekDays, selectDateOnClick = _a.selectDateOnClick;
101 if (selectDateOnClick) {
102 // When using Defaultprops, TypeScript doesn't know that React is going to inject defaults
103 // so we use exclamation mark as a hint to the type checker (see link below)
104 // https://decembersoft.com/posts/error-ts2532-optional-react-component-props-in-typescript/
105 var dates = getDateRangeArray(today, dateRangeType, firstDayOfWeek, workWeekDays);
106 _this._onSelectDate(today, dates);
107 }
108 _this._navigateDayPickerDay(today);
109 _this._focusOnUpdate = true;
110 };
111 _this._onGotoTodayClick = function (ev) {
112 _this._onGotoToday();
113 };
114 _this._onGotoTodayKeyDown = function (ev) {
115 if (ev.which === KeyCodes.enter) {
116 ev.preventDefault();
117 _this._onGotoToday();
118 }
119 };
120 _this._onDatePickerPopupKeyDown = function (ev) {
121 switch (ev.which) {
122 case KeyCodes.enter:
123 ev.preventDefault();
124 break;
125 case KeyCodes.backspace:
126 ev.preventDefault();
127 break;
128 case KeyCodes.escape:
129 _this._handleEscKey(ev);
130 break;
131 default:
132 break;
133 }
134 };
135 _this._handleEscKey = function (ev) {
136 if (_this.props.onDismiss) {
137 _this.props.onDismiss();
138 }
139 };
140 initializeComponentRef(_this);
141 var currentDate = props.value && !isNaN(props.value.getTime()) ? props.value : props.today || new Date();
142 _this.state = {
143 selectedDate: currentDate,
144 navigatedDayDate: currentDate,
145 navigatedMonthDate: currentDate,
146 /** When showMonthPickerAsOverlay is active it overrides isMonthPickerVisible/isDayPickerVisible props
147 (These props permanently set the visibility of their respective calendars). */
148 isMonthPickerVisible: _this.props.showMonthPickerAsOverlay ? false : _this.props.isMonthPickerVisible,
149 isDayPickerVisible: _this.props.showMonthPickerAsOverlay ? true : _this.props.isDayPickerVisible,
150 };
151 _this._focusOnUpdate = false;
152 return _this;
153 }
154 Calendar.prototype.UNSAFE_componentWillReceiveProps = function (nextProps) {
155 var autoNavigateOnSelection = nextProps.autoNavigateOnSelection, value = nextProps.value, _a = nextProps.today, today = _a === void 0 ? new Date() : _a;
156 // Make sure auto-navigation is supported for programmatic changes to selected date, i.e.,
157 // if selected date is updated via props, we may need to modify the navigated date
158 var overrideNavigatedDate = autoNavigateOnSelection && !compareDates(value, this.props.value);
159 if (overrideNavigatedDate) {
160 this.setState({
161 navigatedMonthDate: value,
162 navigatedDayDate: value,
163 });
164 }
165 this.setState({
166 selectedDate: value || today,
167 });
168 };
169 Calendar.prototype.componentDidUpdate = function () {
170 if (this._focusOnUpdate) {
171 this.focus();
172 this._focusOnUpdate = false;
173 }
174 };
175 Calendar.prototype.render = function () {
176 var _a;
177 var rootClass = 'ms-DatePicker';
178 var _b = this.props, firstDayOfWeek = _b.firstDayOfWeek, dateRangeType = _b.dateRangeType, strings = _b.strings, showMonthPickerAsOverlay = _b.showMonthPickerAsOverlay, autoNavigateOnSelection = _b.autoNavigateOnSelection, showGoToToday = _b.showGoToToday, highlightCurrentMonth = _b.highlightCurrentMonth, highlightSelectedMonth = _b.highlightSelectedMonth, navigationIcons = _b.navigationIcons, minDate = _b.minDate, maxDate = _b.maxDate, restrictedDates = _b.restrictedDates, className = _b.className, showCloseButton = _b.showCloseButton, allFocusable = _b.allFocusable, yearPickerHidden = _b.yearPickerHidden, today = _b.today;
179 var nativeProps = getNativeProps(this.props, divProperties, ['value']);
180 var _c = this.state, selectedDate = _c.selectedDate, navigatedDayDate = _c.navigatedDayDate, navigatedMonthDate = _c.navigatedMonthDate, isMonthPickerVisible = _c.isMonthPickerVisible, isDayPickerVisible = _c.isDayPickerVisible;
181 var onHeaderSelect = showMonthPickerAsOverlay ? this._onHeaderSelect : undefined;
182 var monthPickerOnly = !showMonthPickerAsOverlay && !isDayPickerVisible;
183 var overlayedWithButton = showMonthPickerAsOverlay && showGoToToday;
184 var goTodayEnabled = showGoToToday;
185 if (goTodayEnabled && navigatedDayDate && navigatedMonthDate && today) {
186 goTodayEnabled =
187 navigatedDayDate.getFullYear() !== today.getFullYear() ||
188 navigatedDayDate.getMonth() !== today.getMonth() ||
189 navigatedMonthDate.getFullYear() !== today.getFullYear() ||
190 navigatedMonthDate.getMonth() !== today.getMonth();
191 }
192 return (React.createElement("div", { className: css(rootClass, styles.root, className), role: "application" },
193 React.createElement("div", __assign({}, nativeProps, { onBlur: this._onBlur, onFocus: this._onFocus, className: css('ms-DatePicker-picker ms-DatePicker-picker--opened ms-DatePicker-picker--focused', styles.picker, styles.pickerIsOpened, styles.pickerIsFocused, isMonthPickerVisible && 'ms-DatePicker-monthPickerVisible ' + styles.monthPickerVisible, isMonthPickerVisible && isDayPickerVisible && 'ms-DatePicker-calendarsInline ' + styles.calendarsInline, monthPickerOnly && 'ms-DatePicker-monthPickerOnly ' + styles.monthPickerOnly, showMonthPickerAsOverlay && 'ms-DatePicker-monthPickerAsOverlay ' + styles.monthPickerAsOverlay) }),
194 React.createElement("div", { className: css('ms-DatePicker-holder ms-slideDownIn10', styles.holder, overlayedWithButton && styles.holderWithButton), onKeyDown: this._onDatePickerPopupKeyDown },
195 React.createElement("div", { className: css('ms-DatePicker-frame', styles.frame) },
196 React.createElement("div", { className: css('ms-DatePicker-wrap', styles.wrap, showGoToToday && styles.goTodaySpacing) },
197 isDayPickerVisible && (React.createElement(CalendarDay, { selectedDate: selectedDate, navigatedDate: navigatedDayDate, today: this.props.today, onSelectDate: this._onSelectDate, onNavigateDate: this._onNavigateDayDate, onDismiss: this.props.onDismiss, firstDayOfWeek: firstDayOfWeek, dateRangeType: dateRangeType, autoNavigateOnSelection: autoNavigateOnSelection, strings: strings, onHeaderSelect: onHeaderSelect, navigationIcons: navigationIcons, showWeekNumbers: this.props.showWeekNumbers, firstWeekOfYear: this.props.firstWeekOfYear, dateTimeFormatter: this.props.dateTimeFormatter, showSixWeeksByDefault: this.props.showSixWeeksByDefault, minDate: minDate, maxDate: maxDate, restrictedDates: restrictedDates, workWeekDays: this.props.workWeekDays, componentRef: this._dayPicker, showCloseButton: showCloseButton, allFocusable: allFocusable })),
198 isDayPickerVisible && isMonthPickerVisible && React.createElement("div", { className: styles.divider }),
199 isMonthPickerVisible && (React.createElement(CalendarMonth, { navigatedDate: navigatedMonthDate, selectedDate: navigatedDayDate, strings: strings, onNavigateDate: this._onNavigateMonthDate, today: this.props.today, highlightCurrentMonth: highlightCurrentMonth, highlightSelectedMonth: highlightSelectedMonth, onHeaderSelect: onHeaderSelect, navigationIcons: navigationIcons, dateTimeFormatter: this.props.dateTimeFormatter, minDate: minDate, maxDate: maxDate, componentRef: this._monthPicker, yearPickerHidden: yearPickerHidden || showMonthPickerAsOverlay })),
200 showGoToToday && (React.createElement("button", { role: "button", className: css('ms-DatePicker-goToday js-goToday', styles.goToday, (_a = {},
201 _a[styles.goTodayInlineMonth] = isMonthPickerVisible,
202 _a[styles.goToTodayIsDisabled] = !goTodayEnabled,
203 _a)), onClick: this._onGotoTodayClick, onKeyDown: this._onGotoTodayKeyDown, tabIndex: 0, disabled: !goTodayEnabled, type: "button" }, strings.goToToday)))))),
204 React.createElement(FocusRects, null)));
205 };
206 Calendar.prototype.focus = function () {
207 if (this.state.isDayPickerVisible && this._dayPicker.current) {
208 this._dayPicker.current.focus();
209 }
210 else if (this.state.isMonthPickerVisible && this._monthPicker.current) {
211 this._monthPicker.current.focus();
212 }
213 };
214 Calendar.defaultProps = {
215 onSelectDate: undefined,
216 onDismiss: undefined,
217 isMonthPickerVisible: true,
218 isDayPickerVisible: true,
219 showMonthPickerAsOverlay: false,
220 value: undefined,
221 today: new Date(),
222 firstDayOfWeek: DayOfWeek.Sunday,
223 dateRangeType: DateRangeType.Day,
224 autoNavigateOnSelection: false,
225 showGoToToday: true,
226 strings: null,
227 highlightCurrentMonth: false,
228 highlightSelectedMonth: false,
229 navigationIcons: iconStrings,
230 showWeekNumbers: false,
231 firstWeekOfYear: FirstWeekOfYear.FirstDay,
232 dateTimeFormatter: dateTimeFormatterCallbacks,
233 showSixWeeksByDefault: false,
234 workWeekDays: defaultWorkWeekDays,
235 showCloseButton: false,
236 allFocusable: false,
237 };
238 return Calendar;
239}(React.Component));
240export { Calendar };
241//# sourceMappingURL=Calendar.js.map
\No newline at end of file