@zag-js/date-utils
Version:
Date utilities for zag.js
124 lines (123 loc) • 3.74 kB
JavaScript
// src/constrain.ts
import {
maxDate,
minDate,
startOfMonth,
startOfWeek,
startOfYear,
toCalendarDate
} from "@internationalized/date";
function alignCenter(date, duration, locale, min, max) {
const halfDuration = {};
for (let prop in duration) {
const key = prop;
const value = duration[key];
if (value == null) continue;
halfDuration[key] = Math.floor(value / 2);
if (halfDuration[key] > 0 && value % 2 === 0) {
halfDuration[key]--;
}
}
const aligned = alignStart(date, duration, locale).subtract(halfDuration);
return constrainStart(date, aligned, duration, locale, min, max);
}
function alignStart(date, duration, locale, min, max) {
let aligned = date;
if (duration.years) {
aligned = startOfYear(date);
} else if (duration.months) {
aligned = startOfMonth(date);
} else if (duration.weeks) {
aligned = startOfWeek(date, locale);
}
return constrainStart(date, aligned, duration, locale, min, max);
}
function alignEnd(date, duration, locale, min, max) {
let d = { ...duration };
if (d.days) {
d.days--;
} else if (d.weeks) {
d.weeks--;
} else if (d.months) {
d.months--;
} else if (d.years) {
d.years--;
}
let aligned = alignStart(date, duration, locale).subtract(d);
return constrainStart(date, aligned, duration, locale, min, max);
}
function constrainStart(date, aligned, duration, locale, min, max) {
if (min && date.compare(min) >= 0) {
aligned = maxDate(aligned, alignStart(toCalendarDate(min), duration, locale));
}
if (max && date.compare(max) <= 0) {
aligned = minDate(aligned, alignEnd(toCalendarDate(max), duration, locale));
}
return aligned;
}
function constrainValue(date, minValue, maxValue) {
const dateOnly = toCalendarDate(date);
const minOnly = minValue ? toCalendarDate(minValue) : void 0;
const maxOnly = maxValue ? toCalendarDate(maxValue) : void 0;
let constrainedDateOnly = dateOnly;
if (minOnly) {
constrainedDateOnly = maxDate(constrainedDateOnly, minOnly);
}
if (maxOnly) {
constrainedDateOnly = minDate(constrainedDateOnly, maxOnly);
}
if (constrainedDateOnly.compare(dateOnly) === 0) {
return date;
}
if ("hour" in date) {
return date.set({
year: constrainedDateOnly.year,
month: constrainedDateOnly.month,
day: constrainedDateOnly.day
});
}
return constrainedDateOnly;
}
function constrainSegments(date, minValue, maxValue) {
const dateOnly = toCalendarDate(date);
const minOnly = minValue ? toCalendarDate(minValue) : void 0;
const maxOnly = maxValue ? toCalendarDate(maxValue) : void 0;
let result = dateOnly;
if (minOnly && result.compare(minOnly) < 0) {
if (result.year < minOnly.year) {
result = result.set({ year: minOnly.year });
}
if (result.compare(minOnly) < 0 && result.month < minOnly.month) {
result = result.set({ month: minOnly.month });
}
if (result.compare(minOnly) < 0 && result.day < minOnly.day) {
result = result.set({ day: minOnly.day });
}
}
if (maxOnly && result.compare(maxOnly) > 0) {
if (result.year > maxOnly.year) {
result = result.set({ year: maxOnly.year });
}
if (result.compare(maxOnly) > 0 && result.month > maxOnly.month) {
result = result.set({ month: maxOnly.month });
}
if (result.compare(maxOnly) > 0 && result.day > maxOnly.day) {
result = result.set({ day: maxOnly.day });
}
}
if (result.compare(dateOnly) === 0) {
return date;
}
if ("hour" in date) {
return date.set({ year: result.year, month: result.month, day: result.day });
}
return result;
}
export {
alignCenter,
alignEnd,
alignStart,
constrainSegments,
constrainStart,
constrainValue
};