UNPKG

@crossed/ui

Version:

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

132 lines (131 loc) 3.96 kB
import { useUncontrolled } from "@crossed/core"; import { useCallback, useEffect, useMemo, useRef } from "react"; import { getOrderWithFormat, getSeparator } from "./utils"; import { match } from "ts-pattern"; import { isWeb } from "@crossed/styled"; const useDateInput = ({ value: valueProps, onChange: onChangeProps, defaultValue, locale = "en", format = "yyyy-mm-dd", placeholder = {} }) => { const order = getOrderWithFormat(locale, format); const separator = getSeparator(locale); const inputRef = useRef([]); useEffect(() => { if (isWeb) { inputRef.current = []; return () => { inputRef.current = []; }; } return () => { }; }, [locale]); const [value, setValue] = useUncontrolled({ value: valueProps, defaultValue, onChange: onChangeProps }); const add = useCallback((name, r) => { if (r) { const index = inputRef.current.findIndex(({ name: n }) => n === name); if (index >= 0) { inputRef.current[index] = { ref: r, name }; } else { inputRef.current.push({ ref: r, name }); } } }, []); const onChange = useCallback( (name, v) => { var _a; const valueNumber = Number(v); if (isNaN(valueNumber)) { setValue({ ...value, [name === "dd" ? "day" : name === "mm" ? "month" : "year"]: "" }); return; } if (name === "dd" && `${valueNumber}`.length <= 2) { setValue({ ...value, day: valueNumber }); } else if (name === "mm" && `${valueNumber}`.length <= 2) { setValue({ ...value, month: valueNumber }); } else if (name === "yyyy" && `${valueNumber}`.length <= 4) { setValue({ ...value, year: valueNumber }); } const index = inputRef.current.findIndex(({ name: n }) => n === name); if (index >= 0 && index < 2) { const shouldNext = ["dd", "mm"].includes(name) ? `${v}`.length >= 2 : `${v}`.length >= 4; shouldNext && ((_a = inputRef.current[index + 1]) == null ? void 0 : _a.ref.focus()); } }, [setValue, value] ); const setWithDate = useCallback( (date) => { if (date) setValue({ day: date.getDate(), month: date.getMonth() + 1, year: date.getFullYear() }); }, [setValue] ); const inputs = useMemo(() => { return order.map((e) => ({ key: e, ref: (ref) => add(e, ref), onChangeText: (v) => onChange(e, v), ...match(e).with("dd", (r) => { var _a, _b; return { value: (_a = value == null ? void 0 : value.day) == null ? void 0 : _a.toString().padStart(2, "0"), placeholder: placeholder.day ?? r, label: (_b = value == null ? void 0 : value.day) == null ? void 0 : _b.toLocaleString(locale, { minimumIntegerDigits: 2 }) }; }).with("mm", (r) => { var _a, _b; return { value: (_a = value == null ? void 0 : value.month) == null ? void 0 : _a.toString().padStart(2, "0"), placeholder: placeholder.month ?? r, label: (_b = value == null ? void 0 : value.month) == null ? void 0 : _b.toLocaleString(locale, { minimumIntegerDigits: 2 }) }; }).with("yyyy", (r) => { var _a; return { placeholder: placeholder.year ?? r, value: (_a = value == null ? void 0 : value.year) == null ? void 0 : _a.toString().padStart(4, "0") }; }).exhaustive() })); }, [value, order, add, onChange, placeholder, locale]); const containerProps = useMemo(() => { return { onPress: () => { var _a; (_a = inputRef.current[0]) == null ? void 0 : _a.ref.focus(); } }; }, []); return { containerProps, value, onChange, inputs, separator, setWithDate }; }; export { useDateInput }; //# sourceMappingURL=useDateInput.js.map