UNPKG

@hitachivantara/uikit-react-core

Version:

Core React components for the NEXT Design System.

155 lines (154 loc) 5.2 kB
import { jsxs, jsx, Fragment } from "react/jsx-runtime"; import { useState, useMemo } from "react"; import { isKey } from "../../utils/keyboardUtils.js"; import { setId } from "../../utils/setId.js"; import { HvCalendarHeader } from "../CalendarHeader/CalendarHeader.js"; import { generateCalendarModel } from "../model.js"; import { isDate, getWeekdayNamesList, DEFAULT_LOCALE, isRange } from "../utils.js"; import { HvCalendarCell } from "./CalendarCell.js"; import { useClasses } from "./SingleCalendar.styles.js"; import { staticClasses } from "./SingleCalendar.styles.js"; import { HvComposedNavigation } from "../CalendarNavigation/ComposedNavigation/ComposedNavigation.js"; import { HvMonthSelector } from "../CalendarNavigation/MonthSelector/MonthSelector.js"; import { HvPanel } from "../../Panel/Panel.js"; import { HvTypography } from "../../Typography/Typography.js"; const HvSingleCalendar = ({ classes: classesProp, className, id, locale = DEFAULT_LOCALE, value, visibleMonth, visibleYear, minimumDate, maximumDate, onChange, onInputChange, onVisibleDateChange, showEndDate, showDayOfWeek, invalidDateLabel, children, ...others }) => { const { classes, cx } = useClasses(classesProp); const today = /* @__PURE__ */ new Date(); const localValue = value ?? today; const [calViewMode, setCalViewMode] = useState("calendar"); const rangeMode = isRange(localValue); const isDateSelectionMode = rangeMode && !isDate(localValue.endDate); const calModel = rangeMode ? generateCalendarModel(localValue.startDate, visibleMonth, visibleYear) : generateCalendarModel(localValue, visibleMonth, visibleYear); const firstDayOfCurrentMonth = new Date(calModel.year, calModel.month - 1, 1); const firstDayOfCurrentMonthTime = firstDayOfCurrentMonth.getTime(); const listWeekdayNames = useMemo(() => getWeekdayNamesList(locale), [locale]); const handleChange = (event, date) => { event?.preventDefault(); onChange?.(event, date); }; const handleInputChange = (event, date) => { event?.preventDefault(); onInputChange?.(event, date); }; const getNavChild = (event, siblings, i) => { if (isKey(event, "ArrowLeft")) return siblings[i - 1]; if (isKey(event, "ArrowRight")) return siblings[i + 1]; if (isKey(event, "ArrowUp")) return siblings[i - 7]; if (isKey(event, "ArrowDown")) return siblings[i + 7]; return void 0; }; const handleKeyDown = (event) => { const el = document?.activeElement; const parent = el?.parentElement?.parentElement; const siblings = parent != null ? Array.from( parent.getElementsByClassName(classes.cellContainer) ) : []; const elIndex = el ? siblings.indexOf(el) : 0; if (isKey(event, "Enter")) { el.focus(); return; } const child = getNavChild(event, siblings, elIndex); if (child) { const inMonth = child.getAttribute("data-in-month"); if (inMonth === "true") { event?.preventDefault(); child?.focus(); } } }; const renderWeekLabel = (dayName, index) => /* @__PURE__ */ jsx(HvTypography, { variant: "label", className: classes.calendarDay, children: dayName }, index); const renderCalendarDate = (currentDate) => { return /* @__PURE__ */ jsx( HvCalendarCell, { classes, tabIndex: currentDate.getTime() === firstDayOfCurrentMonthTime ? 0 : -1, onChange: handleChange, onKeyDown: handleKeyDown, value: currentDate, today, calendarValue: localValue, rangeMode, isDateSelectionMode, locale, firstDayOfCurrentMonth, maximumDate, minimumDate }, currentDate.toString() ); }; return /* @__PURE__ */ jsxs(HvPanel, { id, className: cx(classes.root, className), ...others, children: [ /* @__PURE__ */ jsx( HvCalendarHeader, { id: setId(id, "header"), locale, value, onChange: handleInputChange, showEndDate: showEndDate && !isDateSelectionMode, showDayOfWeek, invalidDateLabel } ), calViewMode === "calendar" && /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( HvComposedNavigation, { id, locale, onChange: onVisibleDateChange, onViewModeChange: setCalViewMode, visibleYear: visibleYear || today.getFullYear(), visibleMonth: visibleMonth || today.getMonth() + 1 } ), /* @__PURE__ */ jsxs( "div", { className: classes.calendarGrid, "aria-controls": HvCalendarHeader?.[0]?.id, children: [ listWeekdayNames.map(renderWeekLabel), calModel.dates.map(renderCalendarDate) ] } ) ] }), calViewMode === "monthly" && /* @__PURE__ */ jsx( HvMonthSelector, { id, locale, onChange: onVisibleDateChange, onViewModeChange: setCalViewMode, visibleMonth: visibleMonth || today.getMonth() + 1, rangeMode } ) ] }); }; export { HvSingleCalendar, staticClasses as singleCalendarClasses };