@talend/react-components
Version:
Set of react components.
165 lines • 6.01 kB
JavaScript
import { PureComponent } from 'react';
import classNames from 'classnames';
import { format } from 'date-fns/format';
import { getDate } from 'date-fns/getDate';
import { getMonth } from 'date-fns/getMonth';
import { getYear } from 'date-fns/getYear';
import { isSameDay } from 'date-fns/isSameDay';
import { isToday } from 'date-fns/isToday';
import { setMonth } from 'date-fns/setMonth';
import { startOfMonth } from 'date-fns/startOfMonth';
import PropTypes from 'prop-types';
import { Gesture } from '@talend/react-a11y';
import getDefaultT from '../../../../translate';
import { buildDayNames, buildWeeks, getPickerLocale } from '../../generator';
import theme from './DatePicker.module.scss';
import { memoize } from "lodash";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const getDayNames = memoize(buildDayNames);
class DatePicker extends PureComponent {
constructor(props) {
super(props);
this.getWeeks = memoize(buildWeeks, (year, monthIndex, firstDayOfWeek) => `${year}-${monthIndex}|${firstDayOfWeek}`);
}
isSelectedDate(date) {
return this.props.selectedDate !== undefined && isSameDay(this.props.selectedDate, date);
}
isDisabledDate(date) {
if (!this.props.isDisabledChecker) {
return false;
}
return this.props.isDisabledChecker(date);
}
isCurrentMonth(date) {
return getMonth(date) === this.props.calendar.monthIndex;
}
isCurrentYear(date) {
return getYear(date) === this.props.calendar.year;
}
isSelectedInCurrentCalendar() {
const {
selectedDate
} = this.props;
if (!selectedDate) {
return false;
}
return this.isCurrentYear(selectedDate) && this.isCurrentMonth(selectedDate);
}
selectDate(event, date, year, monthIndex) {
if (!this.isCurrentMonth(date)) {
if (date < startOfMonth(new Date(year, monthIndex))) {
this.props.goToPreviousMonth();
} else {
this.props.goToNextMonth();
}
}
this.props.onSelect(event, date);
}
render() {
const {
calendar,
t
} = this.props;
const {
year,
monthIndex
} = calendar;
const pickerLocale = getPickerLocale(t);
const weeks = this.getWeeks(year, monthIndex, 1);
const dayNames = getDayNames(undefined, this.props.t);
const selectedInCurrentCalendar = this.isSelectedInCurrentCalendar();
const monthStr = format(setMonth(new Date(0), monthIndex), 'MMMM', pickerLocale);
return /*#__PURE__*/_jsxs("table", {
className: theme.container,
ref: ref => {
this.calendarRef = ref;
},
children: [/*#__PURE__*/_jsx("caption", {
className: "sr-only",
children: `${monthStr} ${year}`
}), /*#__PURE__*/_jsx("thead", {
children: /*#__PURE__*/_jsx("tr", {
className: theme['calendar-header'],
children: dayNames.map((dayName, i) => /*#__PURE__*/_jsx("th", {
scope: "col",
children: /*#__PURE__*/_jsx("abbr", {
title: dayName.full,
children: dayName.abbr
}, i)
}, i))
})
}), /*#__PURE__*/_jsx("tbody", {
children: weeks.map((week, i) => /*#__PURE__*/_jsx("tr", {
className: classNames(theme['calendar-row'], 'tc-date-picker-calendar-row'),
children: week.map((date, j) => {
const day = getDate(date);
const disabled = this.isDisabledDate(date);
const selected = this.isSelectedDate(date);
const today = isToday(date);
const shouldBeFocussable = selectedInCurrentCalendar && selected || !selectedInCurrentCalendar && day === 1;
const className = classNames(theme['calendar-day'], {
[theme.selected]: selected,
[theme.today]: today,
[theme['not-current-month']]: !this.isCurrentMonth(date)
}, 'tc-date-picker-day', 'btn-tertiary', 'btn-default');
let ariaLabel = format(date, 'EEEE dd MMMM yyyy', pickerLocale);
const tdProps = {
key: j,
className: theme['calendar-col']
};
if (selected) {
tdProps['aria-current'] = 'date';
ariaLabel = t('DATEPICKER_DAY_SELECTED', {
defaultValue: '{{date}}, selected',
date: ariaLabel
});
}
if (today) {
ariaLabel = t('DATEPICKER_DAY_TODAY', {
defaultValue: 'Today, {{date}}',
date: ariaLabel
});
}
const buttonProps = this.isCurrentMonth(date) ? {
'data-value': day
} : undefined;
return /*#__PURE__*/_jsx("td", {
...tdProps,
children: /*#__PURE__*/_jsx("button", {
type: "button",
className: className,
onClick: event => this.selectDate(event, date, year, monthIndex),
disabled: disabled,
tabIndex: this.props.allowFocus && shouldBeFocussable ? 0 : -1,
onKeyDown: event => this.props.onKeyDown(event, this.calendarRef, day - 1),
"aria-label": ariaLabel,
...buttonProps,
children: day
})
});
})
}, i))
})]
});
}
}
DatePicker.displayName = 'DatePicker';
DatePicker.propTypes = {
allowFocus: PropTypes.bool,
calendar: PropTypes.shape({
monthIndex: PropTypes.number.isRequired,
year: PropTypes.number.isRequired
}).isRequired,
onSelect: PropTypes.func.isRequired,
selectedDate: PropTypes.instanceOf(Date),
isDisabledChecker: PropTypes.func,
onKeyDown: PropTypes.func.isRequired,
t: PropTypes.func,
goToPreviousMonth: PropTypes.func.isRequired,
goToNextMonth: PropTypes.func.isRequired
};
DatePicker.defaultProps = {
t: getDefaultT()
};
export default Gesture.withCalendarGesture(DatePicker);
//# sourceMappingURL=DatePicker.component.js.map