UNPKG

@mantine/dates

Version:

Calendars, date and time pickers based on Mantine components

222 lines (221 loc) 7.75 kB
"use client"; import { useDatesContext } from "../DatesProvider/use-dates-context.mjs"; import { HiddenDatesInput } from "../HiddenDatesInput/HiddenDatesInput.mjs"; import { isSameMonth } from "../Month/is-same-month/is-same-month.mjs"; import { useUncontrolledDates } from "../../hooks/use-uncontrolled-dates/use-uncontrolled-dates.mjs"; import { Calendar } from "../Calendar/Calendar.mjs"; import { pickCalendarProps } from "../Calendar/pick-calendar-levels-props/pick-calendar-levels-props.mjs"; import { dateStringParser } from "./date-string-parser/date-string-parser.mjs"; import { isDateValid } from "./is-date-valid/is-date-valid.mjs"; import DateInput_module_default from "./DateInput.module.mjs"; import dayjs from "dayjs"; import { useEffect, useRef, useState } from "react"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { Box, Input, Popover, UnstyledButton, factory, getFontSize, useInputProps, useStyles } from "@mantine/core"; import { useClickOutside, useDidUpdate } from "@mantine/hooks"; //#region packages/@mantine/dates/src/components/DateInput/DateInput.tsx const defaultProps = { valueFormat: "MMMM D, YYYY", fixOnBlur: true, size: "sm" }; const DateInput = factory((_props) => { const props = useInputProps("DateInput", defaultProps, _props); const { inputProps, wrapperProps, value, defaultValue, onChange, clearable, clearSectionMode, clearButtonProps, popoverProps, getDayProps, locale, valueFormat, withTime, dateParser, minDate, maxDate, fixOnBlur, onFocus, onBlur, onClick, onKeyDown, readOnly, name, form, rightSection, unstyled, classNames, styles, allowDeselect, date, defaultDate, onDateChange, getMonthControlProps, getYearControlProps, disabled, presets, ...rest } = props; const getStyles = useStyles({ name: "DateInput", classes: DateInput_module_default, props, classNames, styles, unstyled, attributes: wrapperProps.attributes }); const _wrapperRef = useRef(null); const _dropdownRef = useRef(null); const [dropdownOpened, setDropdownOpened] = useState(false); const { calendarProps, others } = pickCalendarProps(rest); const ctx = useDatesContext(); const defaultDateParser = (val) => { const parsedDate = dayjs(val, valueFormat, ctx.getLocale(locale)).toDate(); return Number.isNaN(parsedDate.getTime()) ? dateStringParser(val) : dayjs(parsedDate).format(withTime ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD"); }; const _dateParser = dateParser || defaultDateParser; const _allowDeselect = allowDeselect !== void 0 ? allowDeselect : clearable; const formatValue = (val) => val ? dayjs(val).locale(ctx.getLocale(locale)).format(valueFormat) : ""; const [_value, setValue, controlled] = useUncontrolledDates({ type: "default", value, defaultValue, onChange, withTime }); const [_date, setDate] = useUncontrolledDates({ type: "default", value: date, defaultValue: defaultValue || defaultDate, onChange: onDateChange }); useEffect(() => { if (controlled && value !== null) setDate(value); }, [controlled, value]); const [inputValue, setInputValue] = useState(formatValue(_value)); useEffect(() => { setInputValue(formatValue(_value)); }, [ctx.getLocale(locale)]); const handleInputChange = (event) => { const val = event.currentTarget.value; setInputValue(val); setDropdownOpened(true); if (val.trim() === "" && (allowDeselect || clearable)) setValue(null); else { const dateValue = _dateParser(val); if (dateValue && isDateValid({ date: dateValue, minDate, maxDate })) { setValue(dateValue); setDate(dateValue); } } }; const handleInputBlur = (event) => { onBlur?.(event); setDropdownOpened(false); fixOnBlur && setInputValue(formatValue(_value)); }; const handleInputFocus = (event) => { onFocus?.(event); setDropdownOpened(true); }; const handleInputClick = (event) => { onClick?.(event); setDropdownOpened(true); }; const handleInputKeyDown = (event) => { if (event.key === "Escape") setDropdownOpened(false); onKeyDown?.(event); }; const _getDayProps = (day) => ({ ...getDayProps?.(day), selected: dayjs(_value).isSame(day, "day"), onClick: (event) => { getDayProps?.(day).onClick?.(event); const val = _allowDeselect ? dayjs(_value).isSame(day, "day") ? null : day : day; setValue(val); !controlled && val && setInputValue(formatValue(val)); setDropdownOpened(false); } }); const handlePresetSelect = (val) => { setValue(val); if (val) setDate(val); if (!controlled) setInputValue(val ? formatValue(val) : ""); setDropdownOpened(false); }; const presetButtons = presets?.map((preset, index) => /* @__PURE__ */ jsx(UnstyledButton, { ...getStyles("presetButton"), onClick: () => handlePresetSelect(preset.value), onMouseDown: (event) => event.preventDefault(), children: preset.label }, index)); const clearButton = /* @__PURE__ */ jsx(Input.ClearButton, { onClick: () => { setValue(null); !controlled && setInputValue(""); setDropdownOpened(false); }, unstyled, ...clearButtonProps }); const _clearable = clearable && !!_value && !readOnly && !disabled; useDidUpdate(() => { _value !== void 0 && !dropdownOpened && setInputValue(formatValue(_value)); }, [_value]); useClickOutside(() => setDropdownOpened(false), void 0, [_wrapperRef.current, _dropdownRef.current]); const calendar = /* @__PURE__ */ jsx(Calendar, { __staticSelector: "DateInput", ...calendarProps, classNames, styles, unstyled, __preventFocus: true, minDate, maxDate, locale, getDayProps: _getDayProps, size: inputProps.size, date: _date, onDateChange: setDate, getMonthControlProps: (date) => ({ selected: typeof _value === "string" ? isSameMonth(date, _value) : false, ...getMonthControlProps?.(date) }), getYearControlProps: (date) => ({ selected: typeof _value === "string" ? dayjs(date).isSame(_value, "year") : false, ...getYearControlProps?.(date) }), attributes: wrapperProps.attributes }); return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Input.Wrapper, { ...wrapperProps, __staticSelector: "DateInput", ref: _wrapperRef, children: /* @__PURE__ */ jsxs(Popover, { opened: dropdownOpened, trapFocus: false, position: "bottom-start", disabled: readOnly || disabled, withRoles: false, unstyled, ...popoverProps, children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(Input, { "data-dates-input": true, "data-read-only": readOnly || void 0, autoComplete: "off", value: inputValue, onChange: handleInputChange, onBlur: handleInputBlur, onFocus: handleInputFocus, onClick: handleInputClick, onKeyDown: handleInputKeyDown, readOnly, rightSection, __clearSection: clearButton, __clearable: _clearable, __clearSectionMode: clearSectionMode, ...inputProps, ...others, disabled, __staticSelector: "DateInput" }) }), /* @__PURE__ */ jsx(Popover.Dropdown, { onMouseDown: (event) => event.preventDefault(), "data-dates-dropdown": true, ref: _dropdownRef, children: presets ? /* @__PURE__ */ jsxs(Box, { ...getStyles("presetsRoot", { style: { "--preset-font-size": getFontSize(inputProps.size) } }), children: [/* @__PURE__ */ jsx("div", { ...getStyles("presetsList"), children: presetButtons }), calendar] }) : calendar })] }) }), /* @__PURE__ */ jsx(HiddenDatesInput, { name, form, value: _value, type: "default", withTime })] }); }); DateInput.classes = { ...Input.classes, ...Calendar.classes, ...DateInput_module_default }; DateInput.displayName = "@mantine/dates/DateInput"; //#endregion export { DateInput }; //# sourceMappingURL=DateInput.mjs.map