@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
634 lines (632 loc) • 26.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _stubFalse2 = _interopRequireDefault(require("lodash/stubFalse"));
var _noop2 = _interopRequireDefault(require("lodash/noop"));
var _react = _interopRequireDefault(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _dateFns = require("date-fns");
var _monthsGridFoundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/datePicker/monthsGridFoundation"));
var _constants = require("@douyinfe/semi-foundation/lib/cjs/datePicker/constants");
var _parser = require("@douyinfe/semi-foundation/lib/cjs/datePicker/_utils/parser");
var _baseComponent = _interopRequireDefault(require("../_base/baseComponent"));
var _navigation = _interopRequireDefault(require("./navigation"));
var _month = _interopRequireDefault(require("./month"));
var _Combobox = _interopRequireDefault(require("../timePicker/Combobox"));
var _yearAndMonth = _interopRequireDefault(require("./yearAndMonth"));
var _semiIcons = require("@douyinfe/semi-icons");
var _getDefaultFormatToken = require("@douyinfe/semi-foundation/lib/cjs/datePicker/_utils/getDefaultFormatToken");
var _getDefaultPickerDate = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/datePicker/_utils/getDefaultPickerDate"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/* eslint-disable jsx-a11y/interactive-supports-focus */
const prefixCls = _constants.cssClasses.PREFIX;
class MonthsGrid extends _baseComponent.default {
constructor(props) {
super(props);
this.cacheRefCurrent = (key, current) => {
if (typeof key === 'string' && key.length) {
this.adapter.setCache(key, current);
}
};
this.leftIsYearOrTime = state => {
const {
monthLeft
} = state || this.state;
if (monthLeft && (monthLeft.isTimePickerOpen || monthLeft.isYearPickerOpen)) {
return true;
} else {
return false;
}
};
this.rightIsYearOrTime = state => {
const {
monthRight
} = state || this.state;
if (monthRight && (monthRight.isTimePickerOpen || monthRight.isYearPickerOpen)) {
return true;
} else {
return false;
}
};
/**
* Calculate the height of the scrolling list, if the animation is not over, return 0
*/
this.calcScrollListHeight = () => {
const wrapLeft = this.adapter.getCache(`wrap-${_constants.strings.PANEL_TYPE_LEFT}`);
const wrapRight = this.adapter.getCache(`wrap-${_constants.strings.PANEL_TYPE_RIGHT}`);
const switchLeft = this.adapter.getCache(`switch-${_constants.strings.PANEL_TYPE_LEFT}`);
const switchRight = this.adapter.getCache(`switch-${_constants.strings.PANEL_TYPE_RIGHT}`);
const leftRect = wrapLeft && wrapLeft.getBoundingClientRect();
const rightRect = wrapRight && wrapRight.getBoundingClientRect();
let leftHeight = leftRect && leftRect.height || 0;
let rightHeight = rightRect && rightRect.height || 0;
if (switchLeft) {
leftHeight += switchLeft.getBoundingClientRect().height;
}
if (switchRight) {
rightHeight += switchRight.getBoundingClientRect().height;
}
return Math.max(leftHeight, rightHeight);
};
this.handleWeeksRowNumChange = (weeksRowNum, panelType) => {
const isLeft = panelType === _constants.strings.PANEL_TYPE_RIGHT;
const isRight = panelType === _constants.strings.PANEL_TYPE_RIGHT;
const allIsYearOrTime = this.leftIsYearOrTime() && this.rightIsYearOrTime();
if (this.foundation.isRangeType() && !allIsYearOrTime) {
const states = {
weeksRowNum,
currentPanelHeight: this.calcScrollListHeight()
};
this.setState(states, () => {
if (this.leftIsYearOrTime() && isRight || this.rightIsYearOrTime() && isLeft) {
this.reselect();
}
});
}
};
this.reselect = () => {
const refKeys = [`timepicker-${_constants.strings.PANEL_TYPE_LEFT}`, `timepicker-${_constants.strings.PANEL_TYPE_RIGHT}`, `yam-${_constants.strings.PANEL_TYPE_LEFT}`, `yam-${_constants.strings.PANEL_TYPE_RIGHT}`];
refKeys.forEach(key => {
const current = this.adapter.getCache(key);
if (current && typeof current.reselect === 'function') {
current.reselect();
}
});
};
this.getYAMOpenType = () => {
return this.foundation.getYAMOpenType();
};
const validFormat = props.format || (0, _getDefaultFormatToken.getDefaultFormatTokenByType)(props.type);
const {
nowDate,
nextDate
} = (0, _getDefaultPickerDate.default)({
defaultPickerValue: props.defaultPickerValue,
format: validFormat,
dateFnsLocale: props.dateFnsLocale
});
const dateState = {
// Direct use of full date string storage, mainly considering the month rendering comparison to save a conversion
// The selected value for single or multiple selection, full date string, eg. {'2019-10-01', '2019-10-02'}
selected: new Set()
};
const rangeState = {
monthLeft: {
pickerDate: nowDate,
showDate: nowDate,
isTimePickerOpen: false,
isYearPickerOpen: false
},
monthRight: {
pickerDate: nextDate,
showDate: nextDate,
isTimePickerOpen: false,
isYearPickerOpen: false
},
maxWeekNum: 0,
hoverDay: '',
rangeStart: props.rangeStart,
rangeEnd: '',
currentPanelHeight: 0,
offsetRangeStart: '',
offsetRangeEnd: ''
};
this.state = Object.assign(Object.assign({}, dateState), rangeState);
this.foundation = new _monthsGridFoundation.default(this.adapter);
}
get dateAdapter() {
return {
updateDaySelected: selected => this.setState({
selected
})
};
}
get rangeAdapter() {
return {
setRangeStart: rangeStart => this.setState({
rangeStart
}),
setRangeEnd: rangeEnd => this.setState({
rangeEnd
}),
setHoverDay: hoverDay => this.setState({
hoverDay
}),
setWeeksHeight: maxWeekNum => this.setState({
maxWeekNum
}),
setOffsetRangeStart: offsetRangeStart => this.setState({
offsetRangeStart
}),
setOffsetRangeEnd: offsetRangeEnd => this.setState({
offsetRangeEnd
})
};
}
get adapter() {
return Object.assign(Object.assign(Object.assign(Object.assign({}, super.adapter), this.dateAdapter), this.rangeAdapter), {
updateMonthOnLeft: v => this.setState({
monthLeft: v
}),
updateMonthOnRight: v => this.setState({
monthRight: v
}),
notifySelectedChange: (value, options) => this.props.onChange(value, options),
notifyMaxLimit: v => this.props.onMaxSelect(v),
notifyPanelChange: (date, dateString) => this.props.onPanelChange(date, dateString),
setRangeInputFocus: rangeInputFocus => this.props.setRangeInputFocus(rangeInputFocus),
isAnotherPanelHasOpened: currentRangeInput => this.props.isAnotherPanelHasOpened(currentRangeInput)
});
}
componentDidMount() {
super.componentDidMount();
}
componentDidUpdate(prevProps, prevState) {
const {
defaultValue,
defaultPickerValue
} = this.props;
if (prevProps.defaultValue !== defaultValue) {
// we should always update panel state when value changes
this.foundation.updateSelectedFromProps(defaultValue);
}
if (prevProps.defaultPickerValue !== defaultPickerValue) {
this.foundation.initDefaultPickerValue();
}
const isRange = this.foundation.isRangeType();
if (isRange) {
/**
* we have to add these code to ensure that scroll list's selector places center
*/
const prevAll = this.leftIsYearOrTime(prevState) && this.rightIsYearOrTime(prevState);
const prevSome = this.leftIsYearOrTime(prevState) && !this.rightIsYearOrTime(prevState) || !this.leftIsYearOrTime(prevState) && this.rightIsYearOrTime(prevState);
const nowAll = this.leftIsYearOrTime() && this.rightIsYearOrTime();
const nowSome = this.leftIsYearOrTime() && !this.rightIsYearOrTime() || !this.leftIsYearOrTime() && this.rightIsYearOrTime();
const prevAllToSome = prevAll && nowSome;
const prevSomeToAll = prevSome && nowAll;
if (prevSomeToAll) {
this.setState({
currentPanelHeight: this.calcScrollListHeight()
}, this.reselect);
} else if (prevAllToSome) {
this.reselect();
}
}
}
renderPanel(month, panelType) {
let monthCls = (0, _classnames.default)(`${prefixCls}-month-grid-${panelType}`);
const {
monthLeft,
monthRight,
currentPanelHeight
} = this.state;
const {
insetInput
} = this.props;
const panelDetail = panelType === _constants.strings.PANEL_TYPE_RIGHT ? monthRight : monthLeft;
const {
isTimePickerOpen,
isYearPickerOpen
} = panelDetail;
const panelContent = this.renderMonth(month, panelType);
const yearAndMonthLayer = isYearPickerOpen ? (/*#__PURE__*/_react.default.createElement("div", {
className: `${prefixCls}-yam`
}, this.renderYearAndMonth(panelType, panelDetail))) : null;
const timePickerLayer = isTimePickerOpen ? (/*#__PURE__*/_react.default.createElement("div", {
className: `${prefixCls}-tpk`
}, this.renderTimePicker(panelType, panelDetail))) : null;
const style = {};
const wrapLeft = this.adapter.getCache(`wrap-${_constants.strings.PANEL_TYPE_LEFT}`);
const wrapRight = this.adapter.getCache(`wrap-${_constants.strings.PANEL_TYPE_RIGHT}`);
const wrap = panelType === _constants.strings.PANEL_TYPE_RIGHT ? wrapRight : wrapLeft;
if (this.foundation.isRangeType()) {
if (isYearPickerOpen || isTimePickerOpen) {
style.minWidth = wrap.getBoundingClientRect().width;
}
if (this.leftIsYearOrTime() && this.rightIsYearOrTime() && !insetInput) {
/**
* left和right同时为tpk时,panel会有一个minHeight
* 如果缓存的currentPanelHeight为0,则需要计算滚动列表的高度
* 如果有缓存的值则使用currentPanelHeight(若此高度<实际值,则会影响ScrollList中渲染列表的循环次数)
* 详见 packages/semi-foundation/scrollList/itemFoundation.js initWheelList函数
*
* When left and right are tpk at the same time, the panel will have a minHeight
* If the cached currentPanelHeight is 0, you need to calculate the height of the scrolling list
* If there is a cached value, use currentPanelHeight (if this height is less than the actual value, it will affect the number of cycles in the ScrollList to render the list)
* See packages/semi-foundation/scrollList/itemFoundation.js initWheelList function
*/
style.minHeight = currentPanelHeight ? currentPanelHeight : this.calcScrollListHeight();
}
} else if (this.props.type !== 'year' && this.props.type !== 'month' && (isTimePickerOpen || isYearPickerOpen)) {
monthCls = (0, _classnames.default)(monthCls, `${prefixCls}-yam-showing`);
}
const _isDatePanelOpen = !(isYearPickerOpen || isTimePickerOpen);
const xOpenType = _isDatePanelOpen ? 'date' : isYearPickerOpen ? 'year' : 'time';
return /*#__PURE__*/_react.default.createElement("div", {
className: monthCls,
key: panelType,
style: style,
"x-open-type": xOpenType
}, yearAndMonthLayer, timePickerLayer, this.foundation.isRangeType() ? panelContent : isYearPickerOpen || isTimePickerOpen ? null : panelContent, this.renderSwitch(panelType));
}
showYearPicker(panelType, e) {
// e.stopPropagation();
// When switching to the year and month, the e.target at this time is generated from Navigation, and the Navigation module will be removed from the DOM after switching
// If you do not prevent the event from spreading to index.jsx, panel.contain (e.target) in clickOutSide will call closePanel because there is no Nav in the Panel and think this click is clickOutSide
// Cause the entire component pop-up window to be closed by mistake
// console.log(this.navRef.current.clientHeight, this.monthRef.current.clientHeight);
// this.wrapRef.current.style.height = this.wrapRef.current.clientHeight + 'px';
// this.wrapRef.current.style.overflow = 'hidden';
e.nativeEvent.stopImmediatePropagation();
this.foundation.showYearPicker(panelType);
}
renderMonth(month, panelType) {
const {
selected,
rangeStart,
rangeEnd,
hoverDay,
maxWeekNum,
offsetRangeStart,
offsetRangeEnd
} = this.state;
const {
weekStartsOn,
disabledDate,
locale,
localeCode,
renderDate,
renderFullDate,
startDateOffset,
endDateOffset,
density,
rangeInputFocus,
syncSwitchMonth,
multiple
} = this.props;
let monthText = '';
// i18n monthText
if (month) {
// Get the absolute value of the year and month
const yearNumber = month ? (0, _dateFns.format)(month, 'yyyy') : '';
const monthNumber = month ? (0, _dateFns.format)(month, 'L') : '';
// Display the month as the corresponding language text
const mText = locale.months[monthNumber];
const monthFormatToken = locale.monthText;
// Display the year and month in a specific language format order
monthText = monthFormatToken.replace('${year}', yearNumber).replace('${month}', mText);
}
let style = {};
const detail = panelType === _constants.strings.PANEL_TYPE_RIGHT ? this.state.monthRight : this.state.monthLeft;
// Whether to select type for range
const isRangeType = this.foundation.isRangeType();
// Whether to switch synchronously for two panels
const shouldBimonthSwitch = isRangeType && syncSwitchMonth;
if (isRangeType && detail && (detail.isYearPickerOpen || detail.isTimePickerOpen)) {
style = {
visibility: 'hidden',
position: 'absolute',
pointerEvents: 'none'
};
}
return /*#__PURE__*/_react.default.createElement("div", {
ref: current => this.cacheRefCurrent(`wrap-${panelType}`, current),
style: style
}, /*#__PURE__*/_react.default.createElement(_navigation.default, {
forwardRef: current => this.cacheRefCurrent(`nav-${panelType}`, current),
monthText: monthText,
density: density,
onMonthClick: e => this.showYearPicker(panelType, e),
onPrevMonth: () => this.foundation.prevMonth(panelType),
onNextMonth: () => this.foundation.nextMonth(panelType),
onNextYear: () => this.foundation.nextYear(panelType),
onPrevYear: () => this.foundation.prevYear(panelType),
shouldBimonthSwitch: shouldBimonthSwitch,
panelType: panelType
}), /*#__PURE__*/_react.default.createElement(_month.default, {
locale: locale,
localeCode: localeCode,
forwardRef: current => this.cacheRefCurrent(`month-${panelType}`, current),
disabledDate: disabledDate,
weekStartsOn: weekStartsOn,
month: month,
selected: selected,
rangeStart: rangeStart,
rangeEnd: rangeEnd,
rangeInputFocus: rangeInputFocus,
offsetRangeStart: offsetRangeStart,
offsetRangeEnd: offsetRangeEnd,
hoverDay: hoverDay,
weeksRowNum: maxWeekNum,
renderDate: renderDate,
renderFullDate: renderFullDate,
onDayClick: day => this.foundation.handleDayClick(day, panelType),
onDayHover: day => this.foundation.handleDayHover(day, panelType),
onWeeksRowNumChange: weeksRowNum => this.handleWeeksRowNumChange(weeksRowNum, panelType),
startDateOffset: startDateOffset,
endDateOffset: endDateOffset,
focusRecordsRef: this.props.focusRecordsRef,
multiple: multiple
}));
}
renderTimePicker(panelType, panelDetail) {
const {
type,
locale,
format,
hideDisabledOptions,
timePickerOpts,
dateFnsLocale
} = this.props;
const {
pickerDate
} = panelDetail;
const timePanelCls = (0, _classnames.default)(`${prefixCls}-time`);
const restProps = Object.assign(Object.assign({}, timePickerOpts), {
hideDisabledOptions
});
const disabledOptions = this.foundation.calcDisabledTime(panelType);
if (disabledOptions) {
['disabledHours', 'disabledMinutes', 'disabledSeconds'].forEach(key => {
if (disabledOptions[key]) {
restProps[key] = disabledOptions[key];
}
});
}
const {
rangeStart,
rangeEnd
} = this.state;
const dateFormat = this.foundation.getValidDateFormat();
let startDate, endDate;
if (type === 'dateTimeRange' && rangeStart && rangeEnd && (0, _dateFns.isSameDay)(startDate = (0, _parser.compatibleParse)(rangeStart, dateFormat, undefined, dateFnsLocale), endDate = (0, _parser.compatibleParse)(rangeEnd, dateFormat, undefined, dateFnsLocale))) {
if (panelType === _constants.strings.PANEL_TYPE_RIGHT) {
rangeStart && (restProps.startDate = startDate);
} else {
rangeEnd && (restProps.endDate = endDate);
}
}
// i18n placeholder
const placeholder = locale.selectTime;
return /*#__PURE__*/_react.default.createElement("div", {
className: timePanelCls
}, /*#__PURE__*/_react.default.createElement(_Combobox.default, Object.assign({
ref: current => this.cacheRefCurrent(`timepicker-${panelType}`, current),
panelHeader: placeholder,
format: format || _constants.strings.FORMAT_TIME_PICKER,
timeStampValue: pickerDate,
onChange: newTime => this.foundation.handleTimeChange(newTime, panelType)
}, restProps)));
}
renderYearAndMonth(panelType, panelDetail) {
const {
pickerDate
} = panelDetail;
const {
locale,
localeCode,
density,
yearAndMonthOpts,
startYear,
endYear
} = this.props;
const y = pickerDate.getFullYear();
const m = pickerDate.getMonth() + 1;
return /*#__PURE__*/_react.default.createElement(_yearAndMonth.default, {
ref: current => this.cacheRefCurrent(`yam-${panelType}`, current),
locale: locale,
localeCode: localeCode,
// currentYear={y}
// currentMonth={m}
currentYear: {
left: y,
right: 0
},
currentMonth: {
left: m,
right: 0
},
onSelect: item => this.foundation.toYearMonth(panelType, new Date(item.currentYear.left, item.currentMonth.left - 1)),
onBackToMain: () => {
this.foundation.showDatePanel(panelType);
const wrapCurrent = this.adapter.getCache(`wrap-${panelType}`);
if (wrapCurrent) {
wrapCurrent.style.height = 'auto';
}
},
density: density,
yearAndMonthOpts: yearAndMonthOpts,
startYear: startYear,
endYear: endYear
});
}
renderSwitch(panelType) {
const {
rangeStart,
rangeEnd,
monthLeft,
monthRight
} = this.state;
const {
type,
locale,
disabledTimePicker,
density,
dateFnsLocale,
insetInput
} = this.props;
// Type: date, dateRange, year, month, inset input no rendering required
if (!type.includes('Time') || insetInput) {
return null;
}
// switch year/month & time
let panelDetail, dateText;
// i18n
const {
FORMAT_SWITCH_DATE
} = locale.localeFormatToken;
// Timepicker format is constant and does not change with language
// const FORMAT_TIME_PICKER = strings.FORMAT_TIME_PICKER;
const formatTimePicker = this.foundation.getValidTimeFormat();
const dateFormat = this.foundation.getValidDateFormat();
if (panelType === _constants.strings.PANEL_TYPE_LEFT) {
panelDetail = monthLeft;
dateText = rangeStart ? (0, _dateFns.format)((0, _parser.compatibleParse)(rangeStart, dateFormat, undefined, dateFnsLocale), FORMAT_SWITCH_DATE) : '';
} else {
panelDetail = monthRight;
dateText = rangeEnd ? (0, _dateFns.format)((0, _parser.compatibleParse)(rangeEnd, dateFormat, undefined, dateFnsLocale), FORMAT_SWITCH_DATE) : '';
}
const {
isTimePickerOpen,
showDate
} = panelDetail;
const monthText = showDate ? (0, _dateFns.format)(showDate, FORMAT_SWITCH_DATE) : '';
const timeText = showDate ? (0, _dateFns.format)(showDate, formatTimePicker) : '';
const showSwitchIcon = ['default'].includes(density);
const switchCls = (0, _classnames.default)(`${prefixCls}-switch`);
const dateCls = (0, _classnames.default)({
[`${prefixCls}-switch-date`]: true,
[`${prefixCls}-switch-date-active`]: !isTimePickerOpen
});
const timeCls = (0, _classnames.default)({
[`${prefixCls}-switch-time`]: true,
[`${prefixCls}-switch-time-disabled`]: disabledTimePicker,
[`${prefixCls}-switch-date-active`]: isTimePickerOpen
});
const textCls = (0, _classnames.default)(`${prefixCls}-switch-text`);
return /*#__PURE__*/_react.default.createElement("div", {
className: switchCls,
ref: current => this.adapter.setCache(`switch-${panelType}`, current)
}, /*#__PURE__*/_react.default.createElement("div", {
role: "button",
"aria-label": "Switch to date panel",
className: dateCls,
onClick: e => this.foundation.showDatePanel(panelType)
}, showSwitchIcon && /*#__PURE__*/_react.default.createElement(_semiIcons.IconCalendar, {
"aria-hidden": true
}), /*#__PURE__*/_react.default.createElement("span", {
className: textCls
}, dateText || monthText)), /*#__PURE__*/_react.default.createElement("div", {
role: "button",
"aria-label": "Switch to time panel",
className: timeCls,
onClick: e => this.foundation.showTimePicker(panelType, true)
}, showSwitchIcon && /*#__PURE__*/_react.default.createElement(_semiIcons.IconClock, {
"aria-hidden": true
}), /*#__PURE__*/_react.default.createElement("span", {
className: textCls
}, timeText)));
}
render() {
const {
monthLeft,
monthRight
} = this.state;
const {
type,
insetInput,
presetPosition,
renderQuickControls,
renderDateInput
} = this.props;
const monthGridCls = (0, _classnames.default)({
[`${prefixCls}-month-grid`]: true
});
const panelTypeLeft = _constants.strings.PANEL_TYPE_LEFT;
const panelTypeRight = _constants.strings.PANEL_TYPE_RIGHT;
let content = null;
if (type === 'date' || type === 'dateTime') {
content = this.renderPanel(monthLeft.pickerDate, panelTypeLeft);
} else if (type === 'dateRange' || type === 'dateTimeRange') {
content = [this.renderPanel(monthLeft.pickerDate, panelTypeLeft), this.renderPanel(monthRight.pickerDate, panelTypeRight)];
} else if (type === 'year' || type === 'month') {
content = 'year month';
}
const yearOpenType = this.getYAMOpenType();
return /*#__PURE__*/_react.default.createElement("div", {
style: {
display: 'flex'
}
}, presetPosition === "left" && renderQuickControls, /*#__PURE__*/_react.default.createElement("div", null, renderDateInput, /*#__PURE__*/_react.default.createElement("div", {
className: monthGridCls,
"x-type": type,
"x-panel-yearandmonth-open-type": yearOpenType,
"x-insetinput": insetInput ? "true" : "false",
"x-preset-position": renderQuickControls === null ? 'null' : presetPosition,
ref: current => this.cacheRefCurrent('monthGrid', current)
}, content)), presetPosition === "right" && renderQuickControls);
}
}
exports.default = MonthsGrid;
MonthsGrid.propTypes = {
type: _propTypes.default.oneOf(_constants.strings.TYPE_SET),
defaultValue: _propTypes.default.array,
defaultPickerValue: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number, _propTypes.default.object, _propTypes.default.array]),
multiple: _propTypes.default.bool,
max: _propTypes.default.number,
weekStartsOn: _propTypes.default.number,
disabledDate: _propTypes.default.func,
disabledTime: _propTypes.default.func,
disabledTimePicker: _propTypes.default.bool,
hideDisabledOptions: _propTypes.default.bool,
navPrev: _propTypes.default.node,
navNext: _propTypes.default.node,
onMaxSelect: _propTypes.default.func,
timePickerOpts: _propTypes.default.object,
// Whether the outer datePicker is a controlled component
isControlledComponent: _propTypes.default.bool,
rangeStart: _propTypes.default.oneOfType([_propTypes.default.string]),
rangeInputFocus: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.string]),
locale: _propTypes.default.object,
localeCode: _propTypes.default.string,
format: _propTypes.default.string,
renderDate: _propTypes.default.func,
renderFullDate: _propTypes.default.func,
startDateOffset: _propTypes.default.func,
endDateOffset: _propTypes.default.func,
autoSwitchDate: _propTypes.default.bool,
density: _propTypes.default.string,
dateFnsLocale: _propTypes.default.object.isRequired,
timeZone: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
// Support synchronous switching of months
syncSwitchMonth: _propTypes.default.bool,
// Callback function for panel date switching
onPanelChange: _propTypes.default.func,
focusRecordsRef: _propTypes.default.object,
triggerRender: _propTypes.default.func,
presetPosition: _propTypes.default.oneOf(_constants.strings.PRESET_POSITION_SET),
renderQuickControls: _propTypes.default.node,
renderDateInput: _propTypes.default.node
};
MonthsGrid.defaultProps = {
type: 'date',
rangeStart: '',
multiple: false,
weekStartsOn: _constants.numbers.WEEK_START_ON,
disabledDate: _stubFalse2.default,
onMaxSelect: _noop2.default,
locale: {}
};