|
import { chunk, isHTMLElement } from '../index.js'; |
|
import { startOfMonth, endOfMonth } from '@internationalized/date'; |
|
import { getDaysInMonth, getLastFirstDayOfWeek, getNextLastDayOfWeek, parseStringToDateValue, } from './index.js'; |
|
import { get } from 'svelte/store'; |
|
|
|
|
|
|
|
|
|
|
|
export function isCalendarCell(node) { |
|
if (!isHTMLElement(node)) |
|
return false; |
|
if (!node.hasAttribute('data-melt-calendar-cell')) |
|
return false; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
export function getDaysBetween(start, end) { |
|
const days = []; |
|
let dCurrent = start.add({ days: 1 }); |
|
const dEnd = end; |
|
while (dCurrent.compare(dEnd) < 0) { |
|
days.push(dCurrent); |
|
dCurrent = dCurrent.add({ days: 1 }); |
|
} |
|
return days; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createMonth(props) { |
|
const { dateObj, weekStartsOn, fixedWeeks, locale } = props; |
|
const daysInMonth = getDaysInMonth(dateObj); |
|
const datesArray = Array.from({ length: daysInMonth }, (_, i) => dateObj.set({ day: i + 1 })); |
|
const firstDayOfMonth = startOfMonth(dateObj); |
|
const lastDayOfMonth = endOfMonth(dateObj); |
|
const lastSunday = getLastFirstDayOfWeek(firstDayOfMonth, weekStartsOn, locale); |
|
const nextSaturday = getNextLastDayOfWeek(lastDayOfMonth, weekStartsOn, locale); |
|
const lastMonthDays = getDaysBetween(lastSunday.subtract({ days: 1 }), firstDayOfMonth); |
|
const nextMonthDays = getDaysBetween(lastDayOfMonth, nextSaturday.add({ days: 1 })); |
|
const totalDays = lastMonthDays.length + datesArray.length + nextMonthDays.length; |
|
if (fixedWeeks && totalDays < 42) { |
|
const extraDays = 42 - totalDays; |
|
let startFrom = nextMonthDays[nextMonthDays.length - 1]; |
|
if (!startFrom) { |
|
startFrom = dateObj.add({ months: 1 }).set({ day: 1 }); |
|
} |
|
const extraDaysArray = Array.from({ length: extraDays }, (_, i) => { |
|
const incr = i + 1; |
|
return startFrom.add({ days: incr }); |
|
}); |
|
nextMonthDays.push(...extraDaysArray); |
|
} |
|
const allDays = lastMonthDays.concat(datesArray, nextMonthDays); |
|
const weeks = chunk(allDays, 7); |
|
return { |
|
value: dateObj, |
|
dates: allDays, |
|
weeks, |
|
}; |
|
} |
|
export function createMonths(props) { |
|
const { numberOfMonths, dateObj, ...monthProps } = props; |
|
const months = []; |
|
if (!numberOfMonths || numberOfMonths === 1) { |
|
months.push(createMonth({ |
|
...monthProps, |
|
dateObj, |
|
})); |
|
return months; |
|
} |
|
months.push(createMonth({ |
|
...monthProps, |
|
dateObj, |
|
})); |
|
|
|
for (let i = 1; i < numberOfMonths; i++) { |
|
const nextMonth = dateObj.add({ months: i }); |
|
months.push(createMonth({ |
|
...monthProps, |
|
dateObj: nextMonth, |
|
})); |
|
} |
|
return months; |
|
} |
|
export function getSelectableCells(calendarId) { |
|
const node = document.getElementById(calendarId); |
|
if (!node) |
|
return []; |
|
const selectableSelector = `[data-melt-calendar-cell]:not([data-disabled]):not([data-outside-visible-months])`; |
|
return Array.from(node.querySelectorAll(selectableSelector)).filter((el) => isHTMLElement(el)); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function setPlaceholderToNodeValue(node, placeholder) { |
|
const cellValue = node.getAttribute('data-value'); |
|
if (!cellValue) |
|
return; |
|
placeholder.set(parseStringToDateValue(cellValue, get(placeholder))); |
|
} |
|
|