UNPKG

@zohodesk/components

Version:

Dot UI is a customizable React component library built to deliver a clean, accessible, and developer-friendly UI experience. It offers a growing set of reusable components designed to align with modern design systems and streamline application development

595 lines (534 loc) • 14.8 kB
/* eslint-disable no-param-reassign */ /** * Libraries ** */ import datetime from '@zohodesk/datetimejs'; /** * Methods ** */ import { getDayEnd, convertYearToTwoDigit, addZero, getMonthDetails, getYearDetails, getDayDetails, getHourDetails, getMinuteDetails, getNoonDetails, getIsCurrentYear, removeYearPattern } from "./index"; import { getIsEmptyValue } from "../../utils/Common"; import { formatDate } from "../../utils/datetime/common"; /** * Constants ** */ import { defaultFormat, supportedPatterns, // patternChangeStr, patternSplitStr, INCONSTANT, flags } from "../constants"; function getDateFormatString(dateFormatArr = [], datePatternArr = []) { return dateFormatArr.reduce((res, dateStr, index) => { const patternStr = datePatternArr[index] || ''; res += dateStr + patternStr; return res; }, ''); } function getIsValidPattern(dateFormatArr = [], datePatternArr = []) { const isValueInArray = (possibleFormat = []) => possibleFormat.some(str => dateFormatArr.indexOf(str) >= 0); const haveDay = isValueInArray(flags.day); const haveMonth = isValueInArray(flags.month); const haveYear = isValueInArray(flags.year); const isValidPattern = datePatternArr.length && datePatternArr.length <= 2 && datePatternArr.every(patternStr => supportedPatterns.indexOf(patternStr) >= 0); return haveDay && haveMonth && (haveYear || !haveYear) && isValidPattern; } export function getDateFormatDetails(dateFormat = '', { isHideCurrentYear, value, timeZone, isDateTime }) { let dayInfo = {}; let monthInfo = {}; let yearInfo = {}; let dateFormatArr = []; let patternArr = []; const { isCurrentYear } = getIsCurrentYear({ value, timeZone, isDateTime }); const isHideYear = isHideCurrentYear ? isCurrentYear : false; function getDateFormat(dateFormat) { const token = /D{1,4}|M{1,4}|YY(?:YY)?|([HhmsA])\1?|[LloSZWN]|\[[^\]]*\]|'[^']*'/gi; dateFormatArr = []; patternArr = []; const newDateFormat = dateFormat.replace(token, match => { const dateFormatArrLen = dateFormatArr.length; if (match in flags) { dateFormatArr.push(match); const { type } = flags[match]; if (type === 'day') { dayInfo = Object.assign({}, flags[match], { index: dateFormatArrLen }); } else if (type === 'month') { monthInfo = Object.assign({}, flags[match], { index: dateFormatArrLen }); } else if (type === 'year') { yearInfo = Object.assign({}, flags[match], { index: dateFormatArrLen }); } return patternSplitStr; } return match.slice(1, match.length - 1); }); patternArr = newDateFormat.split(patternSplitStr).reduce((res, patternStr) => { if (patternStr) { res.push(patternStr); } return res; }, []); } getDateFormat(dateFormat); const isValidPattern = getIsValidPattern(dateFormatArr, patternArr); if (!isValidPattern) { getDateFormat(defaultFormat); } if (isHideYear) { ({ dateFormatArr, patternArr } = removeYearPattern(dateFormatArr, patternArr)); } return { dateFormat: getDateFormatString(dateFormatArr, patternArr), dateFormatArr, patternArr, dayInfo, monthInfo, yearInfo, isValidPattern }; } function getDisplayFormatValue(dateVal, formatVal, { i18nShortMonths = [], i18nMonths = [] } = {}) { const { length, type } = flags[formatVal] || {}; if (length === INCONSTANT) { if (dateVal && formatVal === 'MMM' && i18nShortMonths.length) { return i18nShortMonths[dateVal - 1]; } else if (dateVal && formatVal === 'MMMM' && i18nMonths.length) { return i18nMonths[dateVal - 1]; } return addZero(dateVal, formatVal.length ? formatVal.length : 1); } else if (type === 'year' && length === 2) { return addZero(convertYearToTwoDigit(dateVal), length); } return addZero(dateVal, length); } function concatDate(values, dateFormatArr, patternArr, fillPlaceHolder, { i18nShortMonths, i18nMonths } = {}) { const dateString = dateFormatArr.reduce((res, formatVal, index) => { const { type: dateFormatVal = '' } = flags[formatVal] || {}; let dateVal = values[dateFormatVal]; dateVal = !getIsEmptyValue(dateVal) ? getDisplayFormatValue(dateVal, formatVal, { i18nShortMonths, i18nMonths }) : fillPlaceHolder ? formatVal : ''; const patternVal = patternArr[index] || ''; res += dateVal + patternVal; return res; }, ''); return dateString; } export function getDateTimeString(values = {}, dateFormatDetails = {}, isDateTime, { i18nShortMonths, i18nMonths, is24Hour } = {}) { const { day, month, year, noon } = values; let { hour, minute } = values; const { dateFormatArr = [], patternArr = [] } = dateFormatDetails; const dateString = concatDate({ day, month, year }, dateFormatArr, patternArr, true, { i18nShortMonths, i18nMonths }); let timeString = ''; if (isDateTime) { hour = !getIsEmptyValue(hour) ? addZero(hour, 2) : is24Hour ? 'HH' : 'hh'; minute = !getIsEmptyValue(minute) ? addZero(minute, 2) : 'mm'; timeString = ` ${hour}:${minute} ${is24Hour ? '' : `${noon || '--'}`}`; } return `${dateString}${timeString}`; } export function getDateText(value, isDateTime, timeZone) { if (value && !timeZone) { value = value.replace('Z', ''); } return value ? isDateTime ? timeZone ? datetime.toDate(datetime.tz.utcToTz(value, timeZone)) : new Date(value) : timeZone ? datetime.toDate(value) : new Date(value) : new Date(); } export function getDateDetails(value, localValues, isDateTime, timeZone, { is24Hour }) { const { day, month, year, hour, minute, noon } = localValues; if (value) { const dateObj = getDateText(value, isDateTime, timeZone); const selectedDay = dateObj.getDate(); const selectedMonth = dateObj.getMonth(); const selectedYear = dateObj.getFullYear(); const newDay = day ? day : selectedDay; const newMonth = month ? month : selectedMonth + 1; const newYear = year ? year : selectedYear; if (isDateTime) { let selectedHour = dateObj.getHours(); const selectedMinute = dateObj.getMinutes(); const selectedNoon = selectedHour < 12 ? 'AM' : 'PM'; if (!is24Hour) { selectedHour = selectedHour === 0 ? 12 : selectedHour > 12 ? selectedHour - 12 : selectedHour; } const newHour = hour ? hour : selectedHour; const newMinute = minute ? minute : selectedMinute; const newNoon = noon ? noon : selectedNoon; return { day: newDay, month: newMonth, year: newYear, hour: newHour, minute: newMinute, noon: newNoon }; } return { day: newDay, month: newMonth, year: newYear }; } return localValues; } export function getIsValidDate(values, isDateTime, { is24Hour }) { const { day, month, year, hour, minute, noon } = values; let isError = false; let message = ''; const valuesArr = isDateTime ? is24Hour ? [day, month, year, hour, minute] : [day, month, year, hour, minute, noon] : [day, month, year]; const haveNotAllValues = valuesArr.every((val, index) => { if (index === 2) { //Year '00' to 0 const value = parseInt(val); return getIsEmptyValue(value); } return getIsEmptyValue(val); }); const haveAllValues = valuesArr.every((val, index) => { if (index === 4) { //minute 0 support return !getIsEmptyValue(val); } else if (is24Hour && index === 3) { //hour 0 support return !getIsEmptyValue(val); } else if (index === 2) { //Year '00' to 0 return parseInt(val) ? true : false; } else if (val) { return true; } return false; }); if (haveAllValues) { const dayEnd = getDayEnd(month, year); const { startPoint: monthStart, endPoint: monthEnd } = getMonthDetails(); const { startPoint: yearStart, endPoint: yearEnd } = getYearDetails(); const { startPoint: dayStart } = getDayDetails(); const { startPoint: hourStart, endPoint: hourEnd } = getHourDetails(is24Hour); const { startPoint: minuteStart, endPoint: minuteEnd } = getMinuteDetails(); const { allowedValues: noonAllowedValues } = getNoonDetails(); if (dayEnd < day || dayStart > day) { isError = true; message = 'Wrong Day'; } else if (monthEnd < month || monthStart > month) { isError = true; message = 'Wrong Month'; } else if (yearEnd < year || yearStart > year) { isError = true; message = 'Wrong Year'; } else if (isDateTime && (hourEnd < hour || hourStart > hour)) { isError = true; message = 'Wrong Hour'; } else if (isDateTime && (minuteEnd < minute || minuteStart > minute)) { isError = true; message = 'Wrong Minute'; } else if (isDateTime && !is24Hour && noonAllowedValues.indexOf(noon) === -1) { isError = true; message = 'Wrong Noon'; } } else { isError = true; message = 'Empty value'; } return { isError, message, isEmptyValError: haveNotAllValues }; } export function getSelectedDate(values, props) { let { month, hour } = values; const { year, day: date, minute: mins, noon } = values; const { min, max, timeZone, isDateTime, is24Hour } = props; if (!is24Hour) { if (parseInt(hour) === 12) { hour = noon === 'AM' ? 0 : 12; } if (noon === 'PM') { if (hour < 12) { hour = parseInt(hour) + 12; } } } month = parseInt(month) - 1; const minInMillis = min ? datetime.millis(min) : null, maxInMillis = max ? datetime.millis(max) : null; let selectedInMillis, selectedValue = ''; if (isDateTime) { if (timeZone) { selectedInMillis = datetime.tz.tzToUtc(Date.UTC(year, month, date, hour, mins), timeZone); } else { selectedInMillis = Date.UTC(year, month, date, hour, mins); } selectedValue = datetime.ISO(selectedInMillis); } else { selectedInMillis = Date.UTC(year, month, date); selectedValue = formatDate(new Date(year, month, date), 'YYYY-MM-DD'); } let isError = false; let errorType = ''; if (minInMillis && minInMillis > selectedInMillis) { isError = true; errorType = 'MIN'; } else if (maxInMillis && maxInMillis < selectedInMillis) { isError = true; errorType = 'MAX'; } return { isError, errorType, selectedValue: selectedValue }; } function getDateFormatLength(type, length, formatVal = '', { i18nShortMonths, i18nMonths, selectedValue, day, month, year, hour, minute, noon, timeZone, isDateTime, is24Hour }) { const { month: selectedMonth } = getDateDetails(selectedValue, { day, month, year, hour, minute, noon }, isDateTime, timeZone, { is24Hour }); if (length === INCONSTANT) { if (selectedMonth && formatVal === 'MMM' && i18nShortMonths.length) { return i18nShortMonths[selectedMonth - 1].length; } else if (selectedMonth && formatVal === 'MMMM' && i18nMonths.length) { return i18nMonths[selectedMonth - 1].length; } return formatVal.length ? formatVal.length : 1; } return length; } export function getDateFormatSelection(dateFormatDetails, isDateTime, { i18nShortMonths, i18nMonths, selectedValue, day, month, year, hour, minute, noon, timeZone, is24Hour } = {}) { const { dateFormatArr = [], patternArr = [] } = dateFormatDetails; const focusedIndex = {}; const clickIndex = {}; const order = []; let tempLength = 0; function addResult(type, length) { const startIndex = tempLength; const endIndex = tempLength + length; const orderLen = order.length; focusedIndex[`${startIndex}_${endIndex}`] = orderLen; for (let i = startIndex; i <= endIndex; i++) { clickIndex[i] = orderLen; } order.push({ type, index: [startIndex, endIndex] }); tempLength += length; } dateFormatArr.forEach((formatVal, index) => { const { type, length } = flags[formatVal] || ''; const patternVal = patternArr[index] || ''; const validLength = getDateFormatLength(type, length, formatVal, { i18nShortMonths, i18nMonths, selectedValue, day, month, year, hour, minute, noon, isDateTime, timeZone, is24Hour }); addResult(type, validLength); tempLength += patternVal.length; }); if (isDateTime) { //For space between date and time tempLength += 1; //hour addResult('hour', 2); //For : tempLength += 1; //minute addResult('minute', 2); //For space between time and noon tempLength += 1; //noon if (!is24Hour) { addResult('noon', 2); } } return { focusedIndex, clickIndex, order }; } // export function getDateValues(date = '', dateFormatDetails = {}) { // const { dateFormatArr, patternArr, dayInfo, monthInfo, yearInfo } = // dateFormatDetails; // const newDate = date.split('').reduce((res, str) => { // if (patternArr.indexOf(str) >= 0) { // res += patternChangeStr; // } else { // res += str; // } // return res; // }, ''); // const dateArr = newDate.split(patternChangeStr); // const { index: dayIndex, length: dayLength } = dayInfo; // let day = dateArr[dayIndex]; // day = addZero(day, dayLength); // const { index: monthIndex, length: monthLength } = monthInfo; // let month = dateArr[monthIndex]; // month = addZero(month, monthLength); // const { index: yearIndex, length: yearLength } = yearInfo; // let year = dateArr[yearIndex]; // year = addZero(year, yearLength); // return { // day, // month, // year, // dateString: concatDate({ day, month, year }, dateFormatArr, patternArr) // }; // } // export function getDateTimeValues(value = '', dateFormatDetails = {}) { // const [date, time = '', noon = ''] = value.split(' '); // let [hour = '', minute = ''] = time.split(':'); // hour = addZero(hour, 2); // minute = addZero(minute, 2); // const { day, month, year, dateString } = getDateValues( // date, // dateFormatDetails // ); // const timeString = `${hour}:${minute}`; // return { // day, // month, // year, // hour, // minute, // noon, // dateString, // timeString // }; // }