UNPKG

daily-toolset

Version:

A lightweight, versatile collection of TypeScript utility functions for everyday development needs. Simplify and streamline your Node.js, React, and Next.js projects with a powerful suite of well-organized helpers for strings, arrays, dates, objects, and

149 lines (148 loc) 8.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DateInput = DateInput; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const FormLabel_1 = require("./FormLabel"); const ClearInput_1 = require("./ClearInput"); const popover_1 = require("../../components/ui/popover"); const Button_1 = require("./Button"); const lu_1 = require("react-icons/lu"); const calendar_1 = require("../../components/ui/calendar"); const InputError_1 = require("./InputError"); const scroll_area_1 = require("../../components/ui/scroll-area"); const formProvider_1 = require("../../form/formProvider"); const dateUtils_1 = require("../../dateUtils"); function DateInput({ isRequired = true, isDisabled = false, isClearable = true, defaultValue, label, name, error, startDate, endDate, placeholder = "dd/mm/yyyy", onChange, }) { const { formValues, formErrors, updateValue, validateField } = (0, formProvider_1.useForm)(); const [value, setValue] = (0, react_1.useState)(defaultValue); const [open, setOpen] = (0, react_1.useState)(false); const id = (0, react_1.useId)(); (0, react_1.useEffect)(() => { const inputValue = name && formValues[name] ? formValues[name] : undefined; if (name && inputValue) { setValue(inputValue); } }, [formValues, name]); const handleChange = (0, react_1.useCallback)((inputValue) => { const formatted = (0, dateUtils_1.formatDate)(inputValue, { format: "YYYY-MM-DD" }); const selected = inputValue === value || !inputValue ? undefined : formatted; validateField(name, selected !== null && selected !== void 0 ? selected : ""); setValue(selected); onChange ? onChange(selected || "") : updateValue(name, selected); }, [name, onChange, updateValue, validateField]); const handleYearAndMonthChange = (0, react_1.useCallback)((year, month) => { const date = value ? new Date(value) : new Date(); date.setFullYear(year); date.setMonth(month); handleChange(date); }, [handleChange, value]); const errorData = error ? error : name ? (formErrors === null || formErrors === void 0 ? void 0 : formErrors[name]) || "" : ""; return ((0, jsx_runtime_1.jsxs)("div", { className: "explita-input-root", children: [(0, jsx_runtime_1.jsx)(FormLabel_1.Label, { id: id, label: label, isRequired: isRequired }), (0, jsx_runtime_1.jsxs)(popover_1.Popover, { open: open, onOpenChange: setOpen, children: [(0, jsx_runtime_1.jsxs)("div", { children: [isClearable && value && !isDisabled && ((0, jsx_runtime_1.jsx)(ClearInput_1.Clear, { onClick: () => handleChange(undefined) })), (0, jsx_runtime_1.jsx)(popover_1.PopoverTrigger, { asChild: true, children: (0, jsx_runtime_1.jsxs)(Button_1.Button, { variant: "outline", "data-error": errorData.length > 0, "data-empty": !value, "data-clearable": isClearable, className: "date-input", disabled: isDisabled, children: [(0, jsx_runtime_1.jsx)(lu_1.LuCalendar, { size: 16 }), (0, jsx_runtime_1.jsx)("span", { children: value ? (0, dateUtils_1.formatDate)(value, { format: "Month DD, YYYY" }) : placeholder })] }) })] }), (0, jsx_runtime_1.jsx)(popover_1.PopoverContent, { className: "explita-calendar-content explita-popover-content", align: "start", children: (0, jsx_runtime_1.jsx)(calendar_1.Calendar, { mode: "single", selected: value ? new Date(value) : undefined, onSelect: (currentValue) => { handleChange(currentValue); setOpen(false); }, initialFocus: true, fromDate: startDate, toDate: endDate, disabled: isDisabled, defaultMonth: value ? new Date(value) : undefined, classNames: { root: "explita-calendar-root", }, captionLabelRenderer: (props) => ((0, jsx_runtime_1.jsx)(YearPicker, { displayMonth: props.displayMonth, startYear: startDate === null || startDate === void 0 ? void 0 : startDate.getFullYear(), endYear: endDate === null || endDate === void 0 ? void 0 : endDate.getFullYear(), handleYearAndMonthChange: handleYearAndMonthChange })) }, value === null || value === void 0 ? void 0 : value.toString()) })] }), (0, jsx_runtime_1.jsx)(InputError_1.InputError, { message: errorData }), (0, jsx_runtime_1.jsx)("input", { type: "hidden", name: name, value: value ? (0, dateUtils_1.formatDate)(value, { format: "YYYY-MM-DD" }) : "", id: id })] })); } function YearPicker({ displayMonth, startYear, endYear, handleYearAndMonthChange, }) { const [isYearOpen, setIsYearOpen] = (0, react_1.useState)(false); const [isMonthOpen, setIsMonthOpen] = (0, react_1.useState)(false); const [selectedYear, setSelectedYear] = (0, react_1.useState)(displayMonth ? new Date(displayMonth).getFullYear() : new Date().getFullYear()); if (typeof displayMonth === "string") { displayMonth = new Date(displayMonth); } if (displayMonth === undefined) { displayMonth = new Date(); } const years = (0, react_1.useMemo)(() => { const start = Number(startYear) || 1950; const end = Number(endYear) || new Date().getFullYear() + 10; const yearsList = []; for (let i = end; i >= start; i--) { yearsList.push(i); } return yearsList; }, [startYear, endYear]); function handleSelectYear(year) { setSelectedYear(year); setIsYearOpen(!isYearOpen); setIsMonthOpen(!isMonthOpen); } function handleSelectMonth(month) { handleYearAndMonthChange(selectedYear, month); setIsMonthOpen(!isMonthOpen); } return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("span", { role: "button", className: "year-picker-label", "aria-expanded": isYearOpen, onClick: () => setIsYearOpen(!isYearOpen), children: [months[displayMonth.getMonth()].label, " ", displayMonth.getFullYear()] }), (0, jsx_runtime_1.jsxs)("div", { className: "year-picker-root", "data-open": isYearOpen, children: [(0, jsx_runtime_1.jsx)("span", { role: "button", className: "title", onClick: () => setIsYearOpen(!isYearOpen), children: "Select Year" }), (0, jsx_runtime_1.jsx)(scroll_area_1.ScrollArea, { className: "year-picker-scroll-area", children: (0, jsx_runtime_1.jsx)("div", { className: "items", children: years.map((year) => ((0, jsx_runtime_1.jsx)("span", { role: "button", className: "item", "data-active": displayMonth.getFullYear() === year, onClick: () => handleSelectYear(year), children: year }, year))) }) })] }), (0, jsx_runtime_1.jsx)(MonthPicker, { displayMonth: displayMonth, handleSelectMonth: handleSelectMonth, isMonthOpen: isMonthOpen })] })); } const months = [ { value: 0, label: "Jan", }, { value: 1, label: "Feb", }, { value: 2, label: "Mar", }, { value: 3, label: "Apr", }, { value: 4, label: "May", }, { value: 5, label: "Jun", }, { value: 6, label: "Jul", }, { value: 7, label: "Aug", }, { value: 8, label: "Sep", }, { value: 9, label: "Oct", }, { value: 10, label: "Nov", }, { value: 11, label: "Dec", }, ]; function MonthPicker({ displayMonth, handleSelectMonth, isMonthOpen = false, }) { if (typeof displayMonth === "string") { displayMonth = new Date(displayMonth); } if (displayMonth === undefined) { displayMonth = new Date(); } return ((0, jsx_runtime_1.jsxs)("div", { className: "year-picker-root", "data-open": isMonthOpen, children: [(0, jsx_runtime_1.jsx)("span", { role: "button", className: "title", children: "Select Month" }), (0, jsx_runtime_1.jsx)(scroll_area_1.ScrollArea, { className: "year-picker-scroll-area", children: (0, jsx_runtime_1.jsx)("div", { className: "items", children: months.map((month) => ((0, jsx_runtime_1.jsx)("span", { role: "button", className: "item", "data-active": (displayMonth === null || displayMonth === void 0 ? void 0 : displayMonth.getMonth()) === month.value, onClick: () => { handleSelectMonth(month.value); }, children: month.label }, month.value))) }) })] })); }