UNPKG

@talend/react-components

Version:
231 lines 7.4 kB
import { Component } from 'react'; import classNames from 'classnames'; import { getMonth } from 'date-fns/getMonth'; import { getYear } from 'date-fns/getYear'; import { startOfDay } from 'date-fns/startOfDay'; import PropTypes from 'prop-types'; import { focus } from '@talend/react-a11y'; import Action from '../../../../Actions/Action/Action.component'; import getDefaultT from '../../../../translate'; import DateTimeView from '../../views/DateTimeView'; import MonthYearView from '../../views/MonthYearView'; import theme from './DateTimePicker.module.scss'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; class DateTimePicker extends Component { constructor(props) { super(props); const selectedDate = props.selection.date; const selectedTime = props.selection.time; const initialCalendarDate = selectedDate === undefined ? new Date() : selectedDate; this.state = { isDateTimeView: true, calendar: { monthIndex: getMonth(initialCalendarDate), year: getYear(initialCalendarDate) }, selectedDate, selectedTime, allowFocus: !props.manageFocus }; this.onSelectCalendarMonth = this.onSelectCalendarMonth.bind(this); this.onSelectCalendarYear = this.onSelectCalendarYear.bind(this); this.onSelectCalendarMonthYear = this.onSelectCalendarMonthYear.bind(this); this.onSelectDate = this.onSelectDate.bind(this); this.onSelectTime = this.onSelectTime.bind(this); this.allowFocus = this.setAllowFocus.bind(this, true); this.disallowFocus = this.setAllowFocus.bind(this, false); this.setDateTimeView = this.setView.bind(this, true); this.setMonthYearView = this.setView.bind(this, false); this.onClickToday = this.onClickToday.bind(this); } componentDidMount() { if (this.props.manageFocus) { this.pickerRef.addEventListener('focusin', this.allowFocus); this.pickerRef.addEventListener('focusout', this.disallowFocus); } } componentDidUpdate(prevProps) { const newSelectedDate = this.props.selection.date; const newSelectedTime = this.props.selection.time; const datePropsHasChanged = prevProps.selection.date !== newSelectedDate; const timePropsHasChanged = prevProps.selection.time !== newSelectedTime; const needToUpdateDate = datePropsHasChanged && newSelectedDate !== this.state.selectedDate; const needToUpdateTime = timePropsHasChanged && newSelectedTime !== this.state.selectedTime; if (!needToUpdateDate && !needToUpdateTime) { return; } const newState = { selectedDate: newSelectedDate, selectedTime: newSelectedTime }; if (needToUpdateDate && newSelectedDate) { newState.calendar = { monthIndex: getMonth(newSelectedDate), year: getYear(newSelectedDate) }; } this.setState(newState); } componentWillUnmount() { if (this.props.manageFocus) { this.pickerRef.removeEventListener('focusin', this.allowFocus); this.pickerRef.removeEventListener('focusout', this.disallowFocus); } } onSelectDate(event, selectedDate) { event.persist(); this.setState({ selectedDate }, () => { this.submit(event); }); } onSelectTime(event, selectedTime, field) { event.persist(); this.setState({ selectedTime }, () => { this.submit(event, field); }); } onSelectCalendarMonthYear(newCalendar, callback) { this.setState(previousState => ({ calendar: { ...previousState.calendar, ...newCalendar } }), callback); } onSelectCalendarMonth(event, monthIndex) { this.onSelectCalendarMonthYear({ monthIndex }); } onSelectCalendarYear(event, year) { this.onSelectCalendarMonthYear({ year }); } onClickToday(event) { const now = new Date(); if (!this.state.isDateTimeView) { this.onSelectCalendarYear(event, getYear(now)); this.onSelectCalendarMonth(event, getMonth(now)); this.setView(true); } this.onSelectDate(event, startOfDay(now)); } setAllowFocus(value) { this.setState({ allowFocus: value }); } setView(isDateTimeView) { this.setState({ isDateTimeView }, () => { focus.focusOnCalendar(this.pickerRef); }); } submit(event, field) { this.props.onSubmit(event, { date: this.state.selectedDate, time: this.state.selectedTime, field }); } render() { let viewElement; if (this.state.isDateTimeView) { viewElement = /*#__PURE__*/_jsx(DateTimeView, { allowFocus: this.state.allowFocus, calendar: this.state.calendar, onSelectDate: this.onSelectDate, onSelectMonthYear: this.onSelectCalendarMonthYear, onSelectTime: this.onSelectTime, onTitleClick: this.setMonthYearView, selectedDate: this.state.selectedDate, selectedTime: this.state.selectedTime, useSeconds: this.props.useSeconds, useTime: this.props.useTime, useUTC: this.props.useUTC }); } else { viewElement = /*#__PURE__*/_jsx(MonthYearView, { allowFocus: this.state.allowFocus, onBackClick: this.setDateTimeView, onSelectMonth: this.onSelectCalendarMonth, onSelectYear: this.onSelectCalendarYear, selectedMonthIndex: this.state.calendar.monthIndex, selectedYear: this.state.calendar.year }); } return /*#__PURE__*/_jsxs("div", { className: theme.container, ref: ref => { this.pickerRef = ref; } // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex , tabIndex: this.state.allowFocus ? 0 : -1, "aria-label": "Date picker", children: [viewElement, /*#__PURE__*/_jsx("div", { className: classNames(theme.footer, { [theme['date-padding']]: this.state.isDateTimeView }), children: /*#__PURE__*/_jsx(Action, { label: this.props.t('DATEPICKER_TODAY', { defaultValue: 'Today' }), "aria-label": this.props.t('DATEPICKER_PICK_TODAY', { defaultValue: 'Pick Today' }), onClick: this.onClickToday, className: "btn-tertiary btn-info" }) })] }); } } DateTimePicker.propTypes = { /** * By default, element in picker are focusable. So it is usable as is. * But when we want to disable focus to not interact with a form flow, * this option must be turned on. * It allows to disable focus, and activate it when the focus is set in the picker. */ manageFocus: PropTypes.bool, /** * Current selected date/time */ selection: PropTypes.shape({ date: PropTypes.instanceOf(Date), time: PropTypes.shape({ hours: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), minutes: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }) }), /** * Callback triggered when date and time are selected */ onSubmit: PropTypes.func.isRequired, /** * Display the seconds */ useSeconds: PropTypes.bool, /** * Display time picker */ useTime: PropTypes.bool, /** * Timezone is UTC */ useUTC: PropTypes.bool, t: PropTypes.func }; DateTimePicker.defaultProps = { t: getDefaultT(), selection: {} }; export default DateTimePicker; //# sourceMappingURL=DateTimePicker.component.js.map