@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
128 lines (127 loc) • 3.86 kB
JavaScript
"use client";
import Icon from "../../Icon/Icon.mjs";
import { useTranslation } from "../../i18n/useTranslation.mjs";
import datePicker_default from "../../i18n/resources/en/datePicker.mjs";
import { DEFAULT_FORMAT, clampToBounds, orderRange } from "./calendar.mjs";
import { styles } from "./style.mjs";
import CalendarPanel from "./CalendarPanel.mjs";
import PickerShell from "./PickerShell.mjs";
import { formatDate } from "./DatePicker.mjs";
import { memo, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import useMergeState from "use-merge-value";
import { ArrowRight, CalendarIcon } from "lucide-react";
import dayjs from "dayjs";
//#region src/base-ui/DatePicker/DateRangePicker.tsx
const EMPTY = [null, null];
const DateRangePicker = memo(({ allowClear = true, className, defaultValue = EMPTY, disabled, disabledDate, format, max, min, onChange, placeholder, shadow, size, style, value, variant }) => {
const { t } = useTranslation(datePicker_default);
const [current, setCurrent] = useMergeState(defaultValue, {
defaultValue,
onChange,
value
});
const [open, setOpen] = useState(false);
const [draft, setDraft] = useState(EMPTY);
const [hovered, setHovered] = useState(null);
const [month, setMonth] = useState(() => current[0] ?? /* @__PURE__ */ new Date());
const shown = open && draft[0] ? draft : current;
const nextMonth = dayjs(month).add(1, "month").toDate();
const bounds = {
disabledDate,
max,
min
};
const half = (date, fallback, active) => /* @__PURE__ */ jsx("span", {
className: styles.rangeHalf,
"data-active": active ? "" : void 0,
children: date ? formatDate(date, format, DEFAULT_FORMAT.date) : /* @__PURE__ */ jsx("span", {
className: styles.placeholder,
children: fallback
})
});
const select = (date) => {
if (!draft[0] || draft[1]) {
setDraft([date, null]);
return;
}
const ordered = orderRange(draft[0], date);
setDraft(EMPTY);
setCurrent(ordered);
setOpen(false);
};
return /* @__PURE__ */ jsx(PickerShell, {
className,
disabled,
open,
shadow,
showClear: allowClear && !!(current[0] || current[1]),
size,
style,
variant,
icon: /* @__PURE__ */ jsx("span", {
className: styles.icon,
children: /* @__PURE__ */ jsx(Icon, {
icon: CalendarIcon,
size: 14
})
}),
trigger: /* @__PURE__ */ jsx("button", {
className: styles.trigger,
disabled,
type: "button",
children: /* @__PURE__ */ jsxs("span", {
className: styles.rangeTrigger,
children: [
half(shown[0], placeholder?.[0] ?? t("datePicker.startPlaceholder"), open && !draft[0]),
/* @__PURE__ */ jsx("span", {
className: styles.icon,
children: /* @__PURE__ */ jsx(Icon, {
icon: ArrowRight,
size: 14
})
}),
half(shown[1], placeholder?.[1] ?? t("datePicker.endPlaceholder"), open && !!draft[0])
]
})
}),
onClear: () => setCurrent(EMPTY),
onOpenChange: (next) => {
if (next) {
setMonth(current[0] ?? clampToBounds(/* @__PURE__ */ new Date(), {
max,
min
}));
setDraft(EMPTY);
}
setOpen(next);
},
children: /* @__PURE__ */ jsxs("div", {
className: styles.range,
children: [/* @__PURE__ */ jsx(CalendarPanel, {
bounds,
hovered,
mode: "date",
month,
range: draft[0] ? draft : current,
showNav: false,
onHover: setHovered,
onMonthChange: setMonth,
onSelect: select
}), /* @__PURE__ */ jsx(CalendarPanel, {
bounds,
hovered,
mode: "date",
month: nextMonth,
range: draft[0] ? draft : current,
onHover: setHovered,
onMonthChange: (next) => setMonth(dayjs(next).subtract(1, "month").toDate()),
onSelect: select
})]
})
});
});
DateRangePicker.displayName = "DateRangePicker";
//#endregion
export { DateRangePicker as default };
//# sourceMappingURL=DateRangePicker.mjs.map