mirror of
https://github.com/HSLdevcom/digitransit-ui
synced 2025-07-06 01:00:37 +02:00
127 lines
3.6 KiB
JavaScript
127 lines
3.6 KiB
JavaScript
import PropTypes from 'prop-types';
|
|
import React, { useState } from 'react';
|
|
import { DateTime } from 'luxon';
|
|
import { intlShape } from 'react-intl';
|
|
|
|
import Select from 'react-select';
|
|
import Icon from '../Icon';
|
|
|
|
function DateSelect(props, context) {
|
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
|
|
const onMenuOpen = () => setIsMenuOpen(true);
|
|
const onMenuClose = () => setIsMenuOpen(false);
|
|
|
|
const dates = [];
|
|
const date = DateTime.fromFormat(props.startDate, props.dateFormat);
|
|
|
|
dates.push({
|
|
label: context.intl.formatMessage({ id: 'today', defaultMessage: 'Today' }),
|
|
value: date.toFormat(props.dateFormat),
|
|
});
|
|
|
|
dates.push({
|
|
label: context.intl.formatMessage({
|
|
id: 'tomorrow',
|
|
defaultMessage: 'Tomorrow',
|
|
}),
|
|
value: date.plus({ days: 1 }).toFormat(props.dateFormat),
|
|
});
|
|
|
|
for (let i = 2; i < 60; i++) {
|
|
const dateValue = date.plus({ days: i });
|
|
dates.push({
|
|
value: dateValue.toFormat(props.dateFormat),
|
|
label: dateValue.toFormat('ccc d.L.'),
|
|
});
|
|
}
|
|
const dateList = dates.map(option => {
|
|
return {
|
|
value: option.value,
|
|
textLabel: option.label,
|
|
label: (
|
|
<>
|
|
<span>{option.label}</span>
|
|
{option.value === props.selectedDate && (
|
|
<Icon img="icon-icon_check" height={1.1525} width={0.904375} />
|
|
)}
|
|
</>
|
|
),
|
|
};
|
|
});
|
|
const selectedDate = dateList.find(d => d.value === props.selectedDate);
|
|
const id = 'route-schedule-datepicker';
|
|
const classNamePrefix = 'route-schedule';
|
|
|
|
return (
|
|
<Select
|
|
aria-labelledby={`aria-label-${id}`}
|
|
ariaLiveMessages={{
|
|
guidance: () => '.', // this can't be empty for some reason
|
|
onChange: ({ value }) =>
|
|
`${context.intl.formatMessage({
|
|
id: 'route-page.pattern-chosen',
|
|
})} ${value.textLabel}`,
|
|
onFilter: () => '',
|
|
onFocus: ({ context: itemContext, focused }) => {
|
|
if (itemContext === 'menu') {
|
|
return focused.textLabel;
|
|
}
|
|
return '';
|
|
},
|
|
}}
|
|
className="date-select"
|
|
classNamePrefix={classNamePrefix}
|
|
components={{
|
|
DropdownIndicator: () => null,
|
|
IndicatorSeparator: () => null,
|
|
}}
|
|
inputId={`aria-input-${id}`}
|
|
aria-label={`
|
|
${context.intl.formatMessage({
|
|
id: 'select-date',
|
|
defaultMessage: 'Select date',
|
|
})}.
|
|
${context.intl.formatMessage({
|
|
id: 'route-page.pattern-chosen',
|
|
})} ${selectedDate.textLabel}`}
|
|
isSearchable={false}
|
|
name={id}
|
|
menuIsOpen={isMenuOpen}
|
|
onChange={e => {
|
|
props.onDateChange(e.value);
|
|
onMenuClose();
|
|
}}
|
|
closeMenuOnSelect
|
|
onMenuOpen={onMenuOpen}
|
|
onMenuClose={onMenuClose}
|
|
options={dateList}
|
|
placeholder={
|
|
<>
|
|
<span className="left-column">
|
|
<span className="combobox-label">
|
|
{context.intl.formatMessage({ id: 'day', defaultMessage: 'day' })}
|
|
</span>
|
|
<span className="selected-value">{selectedDate.textLabel}</span>
|
|
</span>
|
|
<div>
|
|
<Icon id="route-schedule-date-icon" img="icon-icon_calendar" />
|
|
</div>
|
|
</>
|
|
}
|
|
value={selectedDate.value}
|
|
/>
|
|
);
|
|
}
|
|
DateSelect.propTypes = {
|
|
startDate: PropTypes.string.isRequired,
|
|
selectedDate: PropTypes.string.isRequired,
|
|
dateFormat: PropTypes.string.isRequired,
|
|
onDateChange: PropTypes.func.isRequired,
|
|
};
|
|
DateSelect.contextTypes = {
|
|
intl: intlShape.isRequired, // eslint-disable-line react/no-typos
|
|
};
|
|
DateSelect.displayName = 'DateSelect';
|
|
|
|
export default DateSelect;
|