UNPKG

@crossed/ui

Version:

A universal & performant styling library for React Native, Next.js & React

184 lines (183 loc) 6.41 kB
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