@crossed/ui
Version:
A universal & performant styling library for React Native, Next.js & React
184 lines (183 loc) • 6.41 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { InputPart } from "./InputPart";
import { Fragment, memo, useCallback, useId, useRef } from "react";
import { XBox } from "../../layout/XBox";
import { YBox } from "../../layout/YBox";
import { Text } from "../../typography/Text";
import { form } from "../../styles/form";
import { composeStyles, inlineStyle, isWeb } from "@crossed/styled";
import { useDateInput } from "./useDateInput";
import { useFloating } from "./useFloating";
import { Calendar } from "./Calendar";
import { growStyles, shrinkStyles } from "../../styles/flex";
import { useUncontrolled } from "@crossed/core";
import { useMedia } from "../../useMedia";
import { FormControl, FormField, FormLabel } from "../Form";
const convertToDate = (e) => {
if ((e == null ? void 0 : e.year) === void 0 || (e == null ? void 0 : e.month) === void 0 || (e == null ? void 0 : e.day) === void 0)
return void 0;
const dateArray = [e == null ? void 0 : e.year, (e == null ? void 0 : e.month) - 1, e == null ? void 0 : e.day];
const args = dateArray.filter((l) => typeof l === "number");
const date = args.length > 0 ? new Date(...args) : void 0;
if (!date || isNaN(date.getTime()))
return void 0;
return date;
};
const DateInput = memo(
({
value: valueProps,
onChange: onChangeProps,
format = "yyyy-mm-dd",
locale = "en",
picker,
placeholder = {},
minDate,
maxDate,
availableDates,
firstDayOfWeek,
events,
monthsToDisplay,
floatingProps,
id: idProps,
style,
label,
description,
extra,
formFieldStyle
}) => {
const { refs, floatingStyles } = useFloating();
const calendarRef = useRef(null);
const id = useId();
const isFocus = useRef(false);
const [valueBridge, setValueBridge] = useUncontrolled({
value: valueProps,
onChange: onChangeProps
});
const { inputs, separator, setWithDate, value, containerProps } = useDateInput({
locale,
format,
defaultValue: valueBridge && valueBridge instanceof Date ? {
day: valueBridge.getDate(),
month: valueBridge.getMonth() + 1,
year: valueBridge.getFullYear()
} : void 0,
placeholder,
onChange: (e) => {
const args = [e.year, e.month - 1, e.day];
const date = /* @__PURE__ */ new Date();
date.setFullYear(...args);
if (e.month > 0 && date.toString() !== "Invalid Date") {
setValueBridge == null ? void 0 : setValueBridge(date);
}
}
});
const { md } = useMedia();
const showFloating = isWeb && md;
const handleFocusInput = useCallback(
(e) => {
var _a, _b, _c, _d;
isFocus.current = true;
!showFloating && ((_b = (_a = e.target) == null ? void 0 : _a.blur) == null ? void 0 : _b.call(_a));
if (picker && !((_c = calendarRef.current) == null ? void 0 : _c.isOpen())) {
picker && ((_d = calendarRef.current) == null ? void 0 : _d.open());
}
},
[picker]
);
const handleBlurInput = useCallback(() => {
isFocus.current = false;
}, [picker]);
return /* @__PURE__ */ jsxs(FormField, { ...composeStyles(growStyles.on, formFieldStyle).rnw(), children: [
/* @__PURE__ */ jsxs(XBox, { alignItems: "center", space: "xxs", children: [
!!label && /* @__PURE__ */ jsx(FormLabel, { children: label }),
!!description && /* @__PURE__ */ jsx(Text, { style: form.labelDescription, children: description }),
!!extra && /* @__PURE__ */ jsx(Text, { style: form.labelExtra, textAlign: "right", children: extra })
] }),
/* @__PURE__ */ jsxs(
YBox,
{
pressable: true,
onPress: !showFloating ? () => {
var _a;
(_a = calendarRef.current) == null ? void 0 : _a.open();
} : !isFocus.current ? containerProps.onPress : void 0,
id: idProps,
ref: refs.setReference,
style: composeStyles(
form.input,
inlineStyle(() => ({
base: {
justifyContent: "flex-start",
paddingVertical: 0,
flex: void 0
}
})),
style
),
children: [
/* @__PURE__ */ jsx(
XBox,
{
style: composeStyles(growStyles.on, shrinkStyles.on),
alignItems: "stretch",
children: inputs.map(({ key, ...item }, i, a) => {
const Comp = i === 0 ? FormControl : Fragment;
return [
/* @__PURE__ */ jsx(Comp, { children: /* @__PURE__ */ jsx(
InputPart,
{
...item,
onBlur: handleBlurInput,
onFocus: handleFocusInput
},
`${id}-${key}`
) }, `${id}-${key}-control`),
i + 1 !== a.length ? /* @__PURE__ */ jsx(
Text,
{
style: composeStyles(
form.placeholder,
inlineStyle(() => ({
base: { marginTop: 1, alignSelf: "center" }
}))
),
children: separator
},
`${id}-${key}-separator`
) : null
];
})
}
),
picker && format === "yyyy-mm-dd" && /* @__PURE__ */ jsx(
Calendar,
{
ref: calendarRef,
selectedDate: convertToDate(value),
onDateSelected: (e) => {
setWithDate(e.date);
},
floatingStyles,
setFloating: refs.setFloating,
locale,
minDate,
maxDate,
availableDates,
firstDayOfWeek,
events,
monthsToDisplay,
floatingProps,
shards: [refs.reference]
}
)
]
}
)
] });
}
);
DateInput.displayName = "DateInput";
export {
DateInput
};
//# sourceMappingURL=DateInput.js.map