react-native-dates-picker
Version:
Customizable date picker for React Native
295 lines (285 loc) • 10.9 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.YEAR_PAGE_SIZE = exports.DATE_FORMAT = exports.CALENDAR_FORMAT = void 0;
exports.addColorAlpha = addColorAlpha;
exports.areDatesOnSameDay = areDatesOnSameDay;
exports.dateToUnix = dateToUnix;
exports.getDateYear = exports.getDateMonth = exports.getDate = void 0;
exports.getDaysInMonth = getDaysInMonth;
exports.getDaysNumInMonth = getDaysNumInMonth;
exports.getEndOfDay = getEndOfDay;
exports.getFirstDayOfMonth = getFirstDayOfMonth;
exports.getParsedDate = exports.getMonths = exports.getMonthName = exports.getMonthDays = exports.getFormattedDate = exports.getFormatted = void 0;
exports.getStartOfDay = getStartOfDay;
exports.getTimeRange = getTimeRange;
exports.getYearRange = exports.getWeekdaysShort = exports.getWeekdaysMin = exports.getWeekdays = exports.getToday = void 0;
exports.isDateBetween = isDateBetween;
exports.isEqual = void 0;
exports.throttle = throttle;
var _dayjs = _interopRequireDefault(require("dayjs"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const CALENDAR_FORMAT = exports.CALENDAR_FORMAT = 'YYYY-MM-DD HH:mm:ss';
const DATE_FORMAT = exports.DATE_FORMAT = 'YYYY-MM-DD';
const YEAR_PAGE_SIZE = exports.YEAR_PAGE_SIZE = 12;
const getMonths = () => _dayjs.default.months();
exports.getMonths = getMonths;
const getMonthName = month => _dayjs.default.months()[month];
exports.getMonthName = getMonthName;
const getWeekdays = () => _dayjs.default.weekdays();
exports.getWeekdays = getWeekdays;
const getWeekdaysShort = () => _dayjs.default.weekdaysShort();
exports.getWeekdaysShort = getWeekdaysShort;
const getWeekdaysMin = firstDayOfWeek => {
let days = _dayjs.default.weekdaysMin();
if (firstDayOfWeek > 0) days = [...days.slice(firstDayOfWeek, days.length), ...days.slice(0, firstDayOfWeek)];
return days;
};
exports.getWeekdaysMin = getWeekdaysMin;
const getFormatted = date => (0, _dayjs.default)(date).format(CALENDAR_FORMAT);
exports.getFormatted = getFormatted;
const getDateMonth = date => (0, _dayjs.default)(date).month();
exports.getDateMonth = getDateMonth;
const getDateYear = date => (0, _dayjs.default)(date).year();
exports.getDateYear = getDateYear;
const getToday = () => (0, _dayjs.default)().format(DATE_FORMAT);
exports.getToday = getToday;
function areDatesOnSameDay(a, b) {
if (!a || !b) return false;
const date_a = (0, _dayjs.default)(a).format(DATE_FORMAT);
const date_b = (0, _dayjs.default)(b).format(DATE_FORMAT);
return date_a === date_b;
}
function isDateBetween(date, {
startDate,
endDate
}) {
if (!startDate || !endDate) return false;
return (0, _dayjs.default)(date) <= endDate && (0, _dayjs.default)(date) >= startDate;
}
const getFormattedDate = (date, format) => (0, _dayjs.default)(date).format(format);
exports.getFormattedDate = getFormattedDate;
const getDate = date => (0, _dayjs.default)(date, DATE_FORMAT);
exports.getDate = getDate;
const getYearRange = year => {
const endYear = YEAR_PAGE_SIZE * Math.ceil(year / YEAR_PAGE_SIZE);
let startYear = endYear === year ? endYear : endYear - YEAR_PAGE_SIZE;
if (startYear < 0) startYear = 0;
return Array.from({
length: YEAR_PAGE_SIZE
}, (_, i) => startYear + i);
};
exports.getYearRange = getYearRange;
function getDaysInMonth(date, displayFullDays, firstDayOfWeek) {
const daysInCurrentMonth = (0, _dayjs.default)(date).daysInMonth();
const prevMonthDays = (0, _dayjs.default)(date).add(-1, 'month').daysInMonth();
const firstDay = (0, _dayjs.default)(date).date(1 - firstDayOfWeek);
const prevMonthOffset = firstDay.day() % 7;
const daysInPrevMonth = displayFullDays ? prevMonthOffset : 0;
const monthDaysOffset = prevMonthOffset + daysInCurrentMonth;
const daysInNextMonth = displayFullDays ? monthDaysOffset > 35 ? 42 - monthDaysOffset : 35 - monthDaysOffset : 0;
const fullDaysInMonth = daysInPrevMonth + daysInCurrentMonth + daysInNextMonth;
return {
prevMonthDays,
prevMonthOffset,
daysInCurrentMonth,
daysInNextMonth,
fullDaysInMonth
};
}
function getDaysNumInMonth(year, month, minDate, maxDate) {
const formattedMonth = String(month).padStart(2, '0');
const date = (0, _dayjs.default)(`${year}-${formattedMonth}-01`);
const daysInMonth = date.daysInMonth();
const minDay = (0, _dayjs.default)(minDate);
const maxDay = (0, _dayjs.default)(maxDate);
const daysArray = [];
for (let day = 1; day <= daysInMonth; day++) {
const currentDate = (0, _dayjs.default)(`${year}-${formattedMonth}-${String(day).padStart(2, '0')}`);
if ((currentDate.isAfter(minDay) || currentDate.isSame(minDay, 'day')) && (currentDate.isBefore(maxDay) || currentDate.isSame(maxDay, 'day'))) daysArray.push({
value: day,
text: String(day).padStart(2, '0')
});
}
return daysArray;
}
function getTimeRange(date, min, max, type) {
const formatStr = `YYYY-MM-DD${type === 'minute' ? ' HH' : type === 'second' ? ' HH:mm' : ''}`;
const current = getDate(date).format(formatStr);
const minDate = getDate(min).format(formatStr);
const maxDate = getDate(max).format(formatStr);
const range = [0, type === 'hour' ? 24 : 60];
if (current <= minDate) range[0] = getDate(min)[type]();
if (current >= maxDate) range[1] = getDate(max)[type]() + 1;
return range;
}
function getFirstDayOfMonth(date, firstDayOfWeek) {
const d = getDate(date);
return d.date(1 - firstDayOfWeek).day();
}
function getStartOfDay(date) {
return (0, _dayjs.default)(date).startOf('day');
}
function getEndOfDay(date) {
return (0, _dayjs.default)(date).endOf('day');
}
function dateToUnix(date) {
return (0, _dayjs.default)(date).unix();
}
/**
* Get detailed date object
*
* @param date Get detailed date object
*
* @returns parsed date object
*/
const getParsedDate = date => ({
year: (0, _dayjs.default)(date).year(),
month: (0, _dayjs.default)(date).month(),
hour: (0, _dayjs.default)(date).hour(),
minute: (0, _dayjs.default)(date).minute(),
second: (0, _dayjs.default)(date).second()
});
/**
* Calculate month days array based on current date
*
* @param datetime - The current date that selected
* @param displayFullDays
* @param minDate - min selectable date
* @param maxDate - max selectable date
* @param firstDayOfWeek - first day of week, number 0-6, 0 – Sunday, 6 – Saturday
*
* @returns days array based on current date
*/
exports.getParsedDate = getParsedDate;
const getMonthDays = (datetime = (0, _dayjs.default)(), displayFullDays, minDate, maxDate, firstDayOfWeek) => {
const date = getDate(datetime);
const {
prevMonthDays,
prevMonthOffset,
daysInCurrentMonth,
daysInNextMonth
} = getDaysInMonth(datetime, displayFullDays, firstDayOfWeek);
const prevDays = displayFullDays ? Array.from({
length: prevMonthOffset
}, (_, index) => {
const day = index + (prevMonthDays - prevMonthOffset + 1);
const thisDay = date.add(-1, 'month').date(day);
return generateDayObject(day, thisDay, minDate, maxDate, false, index + 1);
}) : Array(prevMonthOffset).fill(null);
const currentDays = Array.from({
length: daysInCurrentMonth
}, (_, index) => {
const day = index + 1;
const thisDay = date.date(day);
return generateDayObject(day, thisDay, minDate, maxDate, true, prevMonthOffset + day);
});
const nextDays = Array.from({
length: daysInNextMonth
}, (_, index) => {
const day = index + 1;
const thisDay = date.add(1, 'month').date(day);
return generateDayObject(day, thisDay, minDate, maxDate, false, daysInCurrentMonth + prevMonthOffset + day);
});
return [...prevDays, ...currentDays, ...nextDays];
};
/**
* Generate day object for displaying inside day cell
*
* @param day - number of day
* @param date - calculated date based on day, month, and year
* @param minDate - min selectable date
* @param maxDate - max selectable date
* @param isCurrentMonth - define the day is in the current month
*
* @returns days object based on current date
*/
exports.getMonthDays = getMonthDays;
const generateDayObject = (day, date, minDate, maxDate, isCurrentMonth, dayOfMonth) => {
let disabled = false;
if (minDate) disabled = date < getDate(minDate);
if (maxDate && !disabled) disabled = date > getDate(maxDate);
return {
text: day.toString(),
day: day,
date: getFormattedDate(date, DATE_FORMAT),
disabled,
isCurrentMonth,
dayOfMonth
};
};
function addColorAlpha(color, opacity) {
//if it has an alpha, remove it
if (!color) color = '#000000';
if (color.length > 7) color = color.substring(0, color.length - 2);
// coerce values so ti is between 0 and 1.
const _opacity = Math.round(Math.min(Math.max(opacity, 0), 1) * 255);
let opacityHex = _opacity.toString(16).toUpperCase();
// opacities near 0 need a trailing 0
if (opacityHex.length === 1) opacityHex = '0' + opacityHex;
return color + opacityHex;
}
/**
深度比较两个值是否相等
@param {any} value
@param {any} other
@returns {boolean}
*/
const isEqual = (value, other) => {
// 如果是同一个引用
if (value === other) {
// 排除 0 和 -0 的特殊情况
return value !== 0 || 1 / value === 1 / other;
}
// 如果有一个是 null/undefined,或者类型不同
if (value == null || other == null || typeof value !== typeof other) {
// 同时要特殊处理 NaN
return Number.isNaN(value) && Number.isNaN(other);
}
// 如果是对象或函数,则继续
if (typeof value === 'object' || typeof value === 'function') {
// Date
if (value instanceof Date && other instanceof Date) {
return value.getTime() === other.getTime();
}
// RegExp
if (value instanceof RegExp && other instanceof RegExp) {
return value.source === other.source && value.flags === other.flags;
}
// Array 或者普通对象
if (Array.isArray(value) && Array.isArray(other) || Object.prototype.toString.call(value) === '[object Object]' && Object.prototype.toString.call(other) === '[object Object]') {
// 先比较键的数量是否一致
const valueKeys = Object.keys(value);
const otherKeys = Object.keys(other);
if (valueKeys.length !== otherKeys.length) {
return false;
}
// 递归比较每个键对应的值
for (const key of valueKeys) {
if (!Object.prototype.hasOwnProperty.call(other, key) || !isEqual(value[key], other[key])) {
return false;
}
}
return true;
}
}
// 如果以上情况都不满足,则直接比较
return false;
};
exports.isEqual = isEqual;
function throttle(func, limit = 200) {
let inThrottle = false;
let lastResult;
return (...args) => {
if (!inThrottle) {
lastResult = func(...args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
return lastResult;
};
}
//# sourceMappingURL=utils.js.map
;