INIT
This commit is contained in:
+232
@@ -0,0 +1,232 @@
|
||||
import { CalendarDate, CalendarDateTime, Time, ZonedDateTime, getDayOfWeek, getLocalTimeZone, parseDate, parseDateTime, parseZonedDateTime, toCalendar, } from "@internationalized/date";
|
||||
const defaultDateDefaults = {
|
||||
defaultValue: undefined,
|
||||
granularity: "day",
|
||||
};
|
||||
const defaultTimeDefaults = {
|
||||
defaultValue: undefined,
|
||||
granularity: "minute",
|
||||
};
|
||||
/**
|
||||
* A helper function used throughout the various date builders
|
||||
* to generate a default `DateValue` using the `defaultValue`,
|
||||
* `defaultPlaceholder`, `minValue`, `maxValue`, and `granularity` props.
|
||||
*
|
||||
* It's important to match the `DateValue` type being used
|
||||
* elsewhere in the builder, so they behave according to the
|
||||
* behavior the user expects based on the props they've provided.
|
||||
*
|
||||
*/
|
||||
export function getDefaultDate(opts) {
|
||||
const withDefaults = { ...defaultDateDefaults, ...opts };
|
||||
const { defaultValue, granularity, minValue, maxValue } = withDefaults;
|
||||
if (Array.isArray(defaultValue) && defaultValue.length) {
|
||||
return defaultValue[defaultValue.length - 1];
|
||||
}
|
||||
if (defaultValue && !Array.isArray(defaultValue)) {
|
||||
return defaultValue;
|
||||
}
|
||||
else {
|
||||
let date = new Date();
|
||||
if (minValue && date < minValue.toDate(getLocalTimeZone())) {
|
||||
date = minValue.toDate(getLocalTimeZone());
|
||||
}
|
||||
else if (maxValue && date > maxValue.toDate(getLocalTimeZone())) {
|
||||
date = maxValue.toDate(getLocalTimeZone());
|
||||
}
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
const calendarDateTimeGranularities = ["hour", "minute", "second"];
|
||||
if (calendarDateTimeGranularities.includes(granularity ?? "day")) {
|
||||
return new CalendarDateTime(year, month, day, 0, 0, 0);
|
||||
}
|
||||
return new CalendarDate(year, month, day);
|
||||
}
|
||||
}
|
||||
export function getDefaultTime(opts) {
|
||||
const withDefaults = { ...defaultTimeDefaults, ...opts };
|
||||
const { defaultValue } = withDefaults;
|
||||
if (defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
else {
|
||||
return new Time(0, 0, 0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given a date string and a reference `DateValue` object, parse the
|
||||
* string to the same type as the reference object.
|
||||
*
|
||||
* Useful for parsing strings from data attributes, which are always
|
||||
* strings, to the same type being used by the date component.
|
||||
*/
|
||||
export function parseStringToDateValue(dateStr, referenceVal) {
|
||||
let dateValue;
|
||||
if (referenceVal instanceof ZonedDateTime) {
|
||||
dateValue = parseZonedDateTime(dateStr);
|
||||
}
|
||||
else if (referenceVal instanceof CalendarDateTime) {
|
||||
dateValue = parseDateTime(dateStr);
|
||||
}
|
||||
else {
|
||||
dateValue = parseDate(dateStr);
|
||||
}
|
||||
// ensure the parsed date is in the same calendar as the reference date set by the user.
|
||||
return dateValue.calendar !== referenceVal.calendar
|
||||
? toCalendar(dateValue, referenceVal.calendar)
|
||||
: dateValue;
|
||||
}
|
||||
/**
|
||||
* Given a `DateValue` object, convert it to a native `Date` object.
|
||||
* If a timezone is provided, the date will be converted to that timezone.
|
||||
* If no timezone is provided, the date will be converted to the local timezone.
|
||||
*/
|
||||
export function toDate(dateValue, tz = getLocalTimeZone()) {
|
||||
if (dateValue instanceof ZonedDateTime) {
|
||||
return dateValue.toDate();
|
||||
}
|
||||
else {
|
||||
return dateValue.toDate(tz);
|
||||
}
|
||||
}
|
||||
export function getDateValueType(date) {
|
||||
if (date instanceof CalendarDate)
|
||||
return "date";
|
||||
if (date instanceof CalendarDateTime)
|
||||
return "datetime";
|
||||
if (date instanceof ZonedDateTime)
|
||||
return "zoneddatetime";
|
||||
throw new Error("Unknown date type");
|
||||
}
|
||||
export function parseAnyDateValue(value, type) {
|
||||
switch (type) {
|
||||
case "date":
|
||||
return parseDate(value);
|
||||
case "datetime":
|
||||
return parseDateTime(value);
|
||||
case "zoneddatetime":
|
||||
return parseZonedDateTime(value);
|
||||
default:
|
||||
throw new Error(`Unknown date type: ${type}`);
|
||||
}
|
||||
}
|
||||
function isCalendarDateTime(dateValue) {
|
||||
return dateValue instanceof CalendarDateTime;
|
||||
}
|
||||
export function isZonedDateTime(dateValue) {
|
||||
return dateValue instanceof ZonedDateTime;
|
||||
}
|
||||
export function hasTime(dateValue) {
|
||||
return isCalendarDateTime(dateValue) || isZonedDateTime(dateValue);
|
||||
}
|
||||
/**
|
||||
* Given a date, return the number of days in the month.
|
||||
*/
|
||||
export function getDaysInMonth(date) {
|
||||
if (date instanceof Date) {
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
/**
|
||||
* By using zero as the day, we get the
|
||||
* last day of the previous month, which
|
||||
* is the month we originally passed in.
|
||||
*/
|
||||
return new Date(year, month, 0).getDate();
|
||||
}
|
||||
else {
|
||||
return date.set({ day: 100 }).day;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Determine if a date is before the reference date.
|
||||
* @param dateToCompare - is this date before the `referenceDate`
|
||||
* @param referenceDate - is the `dateToCompare` before this date
|
||||
*
|
||||
* @see {@link isBeforeOrSame} for inclusive
|
||||
*/
|
||||
export function isBefore(dateToCompare, referenceDate) {
|
||||
return dateToCompare.compare(referenceDate) < 0;
|
||||
}
|
||||
/**
|
||||
* Determine if a date is after the reference date.
|
||||
* @param dateToCompare - is this date after the `referenceDate`
|
||||
* @param referenceDate - is the `dateToCompare` after this date
|
||||
*
|
||||
* @see {@link isAfterOrSame} for inclusive
|
||||
*/
|
||||
export function isAfter(dateToCompare, referenceDate) {
|
||||
return dateToCompare.compare(referenceDate) > 0;
|
||||
}
|
||||
/**
|
||||
* Determine if a date is before or the same as the reference date.
|
||||
*
|
||||
* @param dateToCompare - the date to compare
|
||||
* @param referenceDate - the reference date to make the comparison against
|
||||
*
|
||||
* @see {@link isBefore} for non-inclusive
|
||||
*/
|
||||
function isBeforeOrSame(dateToCompare, referenceDate) {
|
||||
return dateToCompare.compare(referenceDate) <= 0;
|
||||
}
|
||||
/**
|
||||
* Determine if a date is after or the same as the reference date.
|
||||
*
|
||||
* @param dateToCompare - is this date after or the same as the `referenceDate`
|
||||
* @param referenceDate - is the `dateToCompare` after or the same as this date
|
||||
*
|
||||
* @see {@link isAfter} for non-inclusive
|
||||
*/
|
||||
function isAfterOrSame(dateToCompare, referenceDate) {
|
||||
return dateToCompare.compare(referenceDate) >= 0;
|
||||
}
|
||||
/**
|
||||
* Determine if a date is inclusively between a start and end reference date.
|
||||
*
|
||||
* @param date - is this date inclusively between the `start` and `end` dates
|
||||
* @param start - the start reference date to make the comparison against
|
||||
* @param end - the end reference date to make the comparison against
|
||||
*
|
||||
* @see {@link isBetween} for non-inclusive
|
||||
*/
|
||||
export function isBetweenInclusive(date, start, end) {
|
||||
return isAfterOrSame(date, start) && isBeforeOrSame(date, end);
|
||||
}
|
||||
export function getLastFirstDayOfWeek(date, firstDayOfWeek, locale) {
|
||||
const day = getDayOfWeek(date, locale);
|
||||
if (firstDayOfWeek > day) {
|
||||
return date.subtract({ days: day + 7 - firstDayOfWeek });
|
||||
}
|
||||
if (firstDayOfWeek === day) {
|
||||
return date;
|
||||
}
|
||||
return date.subtract({ days: day - firstDayOfWeek });
|
||||
}
|
||||
export function getNextLastDayOfWeek(date, firstDayOfWeek, locale) {
|
||||
const day = getDayOfWeek(date, locale);
|
||||
const lastDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;
|
||||
if (day === lastDayOfWeek) {
|
||||
return date;
|
||||
}
|
||||
if (day > lastDayOfWeek) {
|
||||
return date.add({ days: 7 - day + lastDayOfWeek });
|
||||
}
|
||||
return date.add({ days: lastDayOfWeek - day });
|
||||
}
|
||||
export function areAllDaysBetweenValid(start, end, isUnavailable, isDisabled) {
|
||||
if (isUnavailable === undefined && isDisabled === undefined) {
|
||||
return true;
|
||||
}
|
||||
let dCurrent = start.add({ days: 1 });
|
||||
if (isDisabled?.(dCurrent) || isUnavailable?.(dCurrent)) {
|
||||
return false;
|
||||
}
|
||||
const dEnd = end;
|
||||
while (dCurrent.compare(dEnd) < 0) {
|
||||
dCurrent = dCurrent.add({ days: 1 });
|
||||
if (isDisabled?.(dCurrent) || isUnavailable?.(dCurrent)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user