@vimeo/iris
Version:
Vimeo Design System
185 lines (180 loc) • 10.5 kB
JavaScript
'use strict';
var tslib_es6 = require('./tslib.es6-3ec409b7.js');
var components_inputs_Dates_DateRange_DateFormat = require('./components/inputs/Dates/DateRange/DateFormat.js');
var initialState = {
startLabel: null,
startDateError: null,
endLabel: null,
endDateError: null,
range: [null, null],
draft: [null, null],
hoverDraft: [null, null],
viewportDate: null,
open: false,
};
/**
* Internal component state
*/
var dateFormat = components_inputs_Dates_DateRange_DateFormat.getDateFormat();
var dateFormatRegex = components_inputs_Dates_DateRange_DateFormat.getDateFormatRegex(dateFormat);
function init(state) {
// Get the month starting at Day 1 that includes are current date
// this will be the date object that represents our viewport.
var now = new Date();
var viewportDate = state.viewportDate ||
new Date(now.getFullYear(), now.getMonth(), 1);
return tslib_es6.__assign(tslib_es6.__assign({}, state), { viewportDate: viewportDate });
}
// Define and implement the reducer for internal state management
function reducer(state, action) {
switch (action.type) {
case 'OPEN': {
var _a = tslib_es6.__read(state.range, 1), rangeStart = _a[0];
// Set the month at which the calendar initially renders to
// as the start of the current date range.
var viewportDate = rangeStart
? new Date(rangeStart.getFullYear(), rangeStart.getMonth(), 1)
: state.viewportDate;
return tslib_es6.__assign(tslib_es6.__assign({}, state), { open: true, viewportDate: viewportDate,
// Copy (immutably) the current range into a draft state
// this is what renders to the calendar as we make changes
// to the date selection
draft: [state.range[0], state.range[1]] });
}
case 'SAVE':
return tslib_es6.__assign(tslib_es6.__assign({}, state), { open: false,
// When saving, copy (immutably) the draft back into the selected
// range, and set the draft range to null values.
range: [state.draft[0], state.draft[1]] });
case 'CLOSE':
return tslib_es6.__assign(tslib_es6.__assign({}, state), { open: false,
// When cancelling, we want to set the draft to null,
// and do not commit anything to the range value.
draft: [null, null], startLabel: null, startDateError: null, endLabel: null, endDateError: null });
case 'CLEAR':
return tslib_es6.__assign(tslib_es6.__assign({}, initialState), { open: true, viewportDate: state.viewportDate });
case 'CHANGE_VIEWPORT':
return tslib_es6.__assign(tslib_es6.__assign({}, state), { viewportDate: action.payload });
case 'CHANGE_START': {
var draftEnd = state.draft[1];
var viewportDate = state.viewportDate;
var label_1 = action.payload.label;
if (!dateFormatRegex.test(label_1)) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { startLabel: label_1, startDateError: "Try this format: ".concat(dateFormat) });
}
var newStartDate = new Date(dateFormat === components_inputs_Dates_DateRange_DateFormat.DD_MM_YY_FORMAT
? components_inputs_Dates_DateRange_DateFormat.convertDDMMYYYToYYYYMMDD(label_1)
: label_1);
var minDate = action.payload.minDate;
// If the date entered is not a valid date only update the label and set error
if (isNaN(newStartDate.getTime())) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { startLabel: action.payload.label, startDateError: 'Invalid date' });
}
// If the date entered is before the minimum date requirement update label and set error
if (minDate &&
new Date(minDate.toDateString()) >
new Date(newStartDate.toDateString())) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { startLabel: action.payload.label, startDateError: "You can't start in the past :(" });
}
var newViewportDate = new Date(viewportDate);
var tempViewportDate = new Date(newStartDate.getFullYear(), newStartDate.getMonth(), 1);
// If chosen date is in a previous month switch viewport to that month
if (tempViewportDate < viewportDate) {
newViewportDate = tempViewportDate;
}
// If chosen date is in a future month outside viewport switch to that month
viewportDate.setUTCMonth(viewportDate.getUTCMonth() + 1);
if (tempViewportDate > viewportDate) {
newViewportDate = tempViewportDate;
}
// If the new date is greater than the current end range
// start a new range at the given point and auto fill end date
if (newStartDate > draftEnd) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { startLabel: action.payload.label, startDateError: null, draft: [newStartDate, newStartDate], viewportDate: newViewportDate });
}
// Otherwise, update start date
return tslib_es6.__assign(tslib_es6.__assign({}, state), { startLabel: action.payload.label, startDateError: null, draft: [newStartDate, draftEnd], viewportDate: newViewportDate });
}
case 'CHANGE_END':
var draftStart = state.draft[0];
var newEndDate = new Date(action.payload.label);
var maxDate = action.payload.maxDate;
var label = action.payload.label;
if (!draftStart) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { endDateError: 'Must select start date first' });
}
if (!dateFormatRegex.test(label)) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { endLabel: label, endDateError: "Try this format: ".concat(dateFormat) });
}
// If the date entered is not a valid date only update the label
if (isNaN(newEndDate.getTime())) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { endLabel: label, endDateError: 'Invalid date' });
}
// If the date entered is after the maximum date requirement update label and set error
if (maxDate &&
new Date(maxDate.toDateString()) <
new Date(newEndDate.toDateString())) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { endLabel: action.payload.label, endDateError: 'Invalid end date :(' });
}
// If the new date is less than the current start range
// set error
if (newEndDate < draftStart) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { endLabel: label, endDateError: 'Make sure the start comes before the end.' });
}
// Otherwise, update end date
return tslib_es6.__assign(tslib_es6.__assign({}, state), { endLabel: label, endDateError: null, draft: [draftStart, newEndDate] });
case 'SELECT_DATE': {
var _b = tslib_es6.__read(state.draft, 2), draftStart_1 = _b[0], draftEnd = _b[1];
var _c = tslib_es6.__read(state.hoverDraft, 2), hoverStart = _c[0], hoverEnd = _c[1];
// If selected date is within an already selected range
// clear selection and set start date to selected
if (draftStart_1 &&
draftEnd &&
action.payload > draftStart_1 &&
action.payload < draftEnd) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { draft: [action.payload, null], startLabel: null, startDateError: null, endLabel: null, endDateError: null });
}
// Other wise set the date to the hover state
return tslib_es6.__assign(tslib_es6.__assign({}, state), { draft: [
hoverStart ? hoverStart : draftStart_1,
hoverEnd ? hoverEnd : draftEnd,
], startLabel: null, startDateError: null, endLabel: null, endDateError: null });
}
case 'SET_DATE_FROM_PRESET': {
var _d = tslib_es6.__read(action.payload, 2), start = _d[0], end = _d[1];
return tslib_es6.__assign(tslib_es6.__assign({}, state), { draft: [start, end ? end : start], startLabel: null, startDateError: null, endLabel: null, endDateError: null });
}
case 'HOVER_DATE': {
var _e = tslib_es6.__read(state.draft, 2), draftStart_2 = _e[0], draftEnd = _e[1];
var hoverDate = action.payload;
if (hoverDate === null) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { hoverDraft: [null, null] });
}
// If there is a selected start date AND no end date selected
// AND hover date is before start
// treat the hover date as start and the start as the end date
if (draftStart_2 && !draftEnd && hoverDate < draftStart_2) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { hoverDraft: [hoverDate, draftStart_2] });
}
// If no selected start date
// OR theres a selected end date AND hover date is before the end date
// show hover date instead of start date
if (!draftStart_2 || (draftEnd && hoverDate < draftEnd)) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { hoverDraft: [hoverDate, null] });
}
// If hoverDate is past selected start date and no end date selected
// OR end date is selected and hoverDate is past the end Date
// show hover date as end date
if ((draftStart_2 && !draftEnd && hoverDate > draftStart_2) ||
(draftEnd && hoverDate > draftEnd)) {
return tslib_es6.__assign(tslib_es6.__assign({}, state), { hoverDraft: [null, hoverDate] });
}
return tslib_es6.__assign(tslib_es6.__assign({}, state), { hoverDraft: [null, null] });
}
default:
return state;
}
}
exports.init = init;
exports.initialState = initialState;
exports.reducer = reducer;