@veracity/vui
Version:
Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.
124 lines (122 loc) • 4.07 kB
JavaScript
import { cs } from "../utils/styles.js";
import { omitThemingProps, useStyleConfig } from "../core/theme.js";
import vui from "../core/vui.js";
import Box from "../box/box.js";
import { DayPicker } from "./components/dayPicker.js";
import { isDay, isExact, isFrom, isMonth, isTo, isYear, processSelectMonth, processSelectYear, processViewDate } from "./utils.js";
import { CalendarHeader } from "./components/calendarHeader.js";
import { MonthPicker } from "./components/monthPicker.js";
import { YearPicker } from "./components/yearPicker.js";
import { useCalendar } from "./hooks/useCalendar.js";
import { useDefaultViewMonth } from "./hooks/useDefaultViewMonth.js";
import { useEffect, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
//#region src/calendar/calendar.tsx
/** Displays calendar. */
const Calendar = vui((props, ref) => {
const { boundaries, className, fixedNumberOfWeeks = false, disabled, isStartDate, mode, onSelectDates, selectedDates, ...rest } = omitThemingProps(props);
const styles = useStyleConfig("Calendar", props);
const currentDateRef = useRef(isFrom(mode) || isExact(mode) ? selectedDates?.startDate : selectedDates?.endDate);
/**
* Effect to reset viewDate when selectedDates changes (onReset)
*/
useEffect(() => {
currentDateRef.current = isFrom(mode) || isExact(mode) ? selectedDates?.startDate : selectedDates?.endDate;
currentDateRef.current && setViewDate(currentDateRef.current);
}, [selectedDates]);
const calendarRef = useRef(null);
const defaultViewMonth = useDefaultViewMonth({
boundaries,
selectedDate: currentDateRef.current,
isStartDate
});
const [timeUnitMode, setTimeUnitMode] = useState("day");
const [viewDate, setViewDate] = useState(defaultViewMonth);
/**
* Handles clicking next/prev in header
*/
const onChangeViewItem = (direction) => {
const newViewMonth = processViewDate(viewDate, direction, timeUnitMode, calendarRef?.current?.items);
newViewMonth && setViewDate(newViewMonth);
};
/**
* Handles clicking on a day
*/
const onSelectDay = (clickedDate) => () => {
updateDateState(clickedDate);
setViewDate(clickedDate);
};
/**
* Handles clicking on a month
*/
const onSelectMonth = (clickedDate) => () => {
const processedNewDate = processSelectMonth(clickedDate, mode, boundaries);
updateDateState(processedNewDate);
setViewDate(processedNewDate);
setTimeUnitMode("day");
};
/**
* Handles clicking on a year
*/
const onSelectYear = (clickedDate) => () => {
const processedNewDate = processSelectYear(clickedDate, mode, boundaries);
updateDateState(processedNewDate);
setViewDate(processedNewDate);
setTimeUnitMode("month");
};
/**
* Send update date to parent component
*/
const updateDateState = (newDate) => {
const dateRange = { ...selectedDates };
if (dateRange) if (isTo(mode)) dateRange.endDate = newDate;
else dateRange.startDate = newDate;
if (newDate && !disabled) onSelectDates && onSelectDates(dateRange);
};
const calendar = calendarRef.current = useCalendar({
boundaries,
mode,
selectedDates,
timeUnitMode,
viewDate,
fixedNumberOfWeeks
});
return /* @__PURE__ */ jsxs(Box, {
className: cs("vui-calendar", className),
column: true,
cursor: "default",
minW: 280,
position: "relative",
ref,
w: "fit-content",
...styles,
...rest,
children: [
/* @__PURE__ */ jsx(CalendarHeader, {
nextDisabled: calendar.nextDisabled,
onChangeViewItem,
onSetTimeUnitMode: (mode) => setTimeUnitMode(mode),
prevDisabled: calendar.prevDisabled,
timeUnitMode,
viewMonth: viewDate
}),
isDay(timeUnitMode) && /* @__PURE__ */ jsx(DayPicker, {
calendar,
onSelectDay
}),
isMonth(timeUnitMode) && /* @__PURE__ */ jsx(MonthPicker, {
calendar,
onSelectMonth
}),
isYear(timeUnitMode) && /* @__PURE__ */ jsx(YearPicker, {
calendar,
onSelectYear
})
]
});
});
Calendar.displayName = "Calendar";
//#endregion
export { Calendar as default };
globalThis.__vuiVersion__ = "5.3.0-alpha.2"
//# sourceMappingURL=calendar.js.map