UNPKG

@zag-js/date-utils

Version:

Date utilities for zag.js

124 lines (123 loc) 3.74 kB
// 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 };