@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
128 lines (127 loc) • 4.63 kB
JavaScript
import { jsxs, jsx } from "react/jsx-runtime";
import { useContext, useState, useEffect } from "react";
import { useDefaultProps } from "@hitachivantara/uikit-react-utils";
import { isKey } from "../../utils/keyboardUtils.js";
import { setId } from "../../utils/setId.js";
import { DEFAULT_LOCALE, isRange, getLocaleDateFormat, isDate, getFormattedDate, getStringFromDate, parseDateString, isSameDay } from "../utils.js";
import { useClasses } from "./CalendarHeader.styles.js";
import { staticClasses } from "./CalendarHeader.styles.js";
import { HvInput } from "../../Input/Input.js";
import { HvFormElementContext, HvFormElementDescriptorsContext } from "../../FormElement/context.js";
import { HvTypography } from "../../Typography/Typography.js";
const HvCalendarHeader = (props) => {
const {
id: idProp,
value: valueProp,
locale = DEFAULT_LOCALE,
classes: classesProp,
onChange,
showEndDate,
showDayOfWeek = false,
onFocus,
invalidDateLabel = "Invalid Date"
} = useDefaultProps("HvCalendarHeader", props);
const { classes, cx } = useClasses(classesProp);
const context = useContext(HvFormElementContext);
const { label } = useContext(HvFormElementDescriptorsContext);
const localValue = isRange(valueProp) ? showEndDate ? valueProp.endDate : valueProp.startDate : valueProp;
const [dateValue, setDateValue] = useState(localValue);
const [editedValue, setEditedValue] = useState(null);
const [displayValue, setDisplayValue] = useState("");
const [weekdayDisplay, setWeekdayDisplay] = useState("");
const id = idProp ?? setId(context.id, "calendarHeader");
const inputValue = editedValue ?? displayValue;
const localeFormat = getLocaleDateFormat(locale);
const [isValidValue, setIsValidValue] = useState(
inputValue.length === 0 || inputValue && isDate(new Date(inputValue))
);
useEffect(() => {
const valid = !localValue || isDate(new Date(localValue));
setIsValidValue(valid);
if (valid) {
if (!localValue) {
setDisplayValue("");
setEditedValue(null);
setWeekdayDisplay("");
return;
}
const weekday = new Intl.DateTimeFormat(locale, {
weekday: "short"
}).format(isDate(localValue) ? localValue : 0);
setDisplayValue(getFormattedDate(localValue, locale));
setEditedValue(null);
setWeekdayDisplay(weekday);
}
}, [localValue, locale]);
const handleNewDate = (event, date) => {
const localeParsedDate = parseDateString(date, locale);
const isValidInput = isDate(localeParsedDate);
const dateParsed = isValidInput ? localeParsedDate : new Date(date);
if (!isSameDay(dateParsed, dateValue)) {
setDateValue(dateParsed);
onChange?.(event, dateParsed);
}
setIsValidValue(isValidInput);
if (isValidInput) {
setEditedValue(null);
}
};
const onBlurHandler = (event) => {
if (editedValue == null) return;
if (editedValue === "") {
setIsValidValue(true);
setEditedValue(null);
return;
}
handleNewDate(event, editedValue);
};
const keyDownHandler = (event) => {
if (!isKey(event, "Enter") || editedValue == null || editedValue === "")
return;
event.preventDefault();
handleNewDate(event, editedValue);
};
const onFocusHandler = (event) => {
if (!localValue) return;
const formattedDate = isValidValue && isDate(localValue) ? getStringFromDate(localValue, locale) : editedValue;
setEditedValue(formattedDate);
onFocus?.(event, formattedDate);
};
const onChangeHandler = (event, val) => {
setEditedValue(val);
};
const isInvalid = !isValidValue && inputValue !== "";
return /* @__PURE__ */ jsxs(
"div",
{
id,
className: cx(classes.root, {
[classes.invalid]: isInvalid
}),
children: [
showDayOfWeek && /* @__PURE__ */ jsx(HvTypography, { className: classes.headerDayOfWeek, children: weekdayDisplay || " " }),
/* @__PURE__ */ jsx(
HvInput,
{
type: "text",
id: setId(id, "header-input"),
placeholder: localeFormat,
value: inputValue,
"aria-labelledby": label?.[0]?.id,
onBlur: onBlurHandler,
onFocus: onFocusHandler,
onChange: onChangeHandler,
onKeyDown: keyDownHandler,
status: isInvalid ? "invalid" : "valid",
statusMessage: invalidDateLabel
}
)
]
}
);
};
HvCalendarHeader.formElementType = "HvCalendarHeader";
export {
HvCalendarHeader,
staticClasses as calendarHeaderClasses
};