@brizy/ui
Version:
React elements in Brizy style
103 lines (102 loc) • 5.69 kB
JavaScript
import React, { useCallback, useContext, useState, useRef, useEffect, useMemo } from "react";
import { classNames } from "../classNamesFn";
import AntDatePicker from "antd/lib/date-picker";
import moment from "moment";
import { FrameContentContext } from "../Frame/FrameContent";
import { Icon } from "../Icon";
import { CmsIconDatePicker } from "../icons";
import { getFieldsStyleTheme } from "../utils/getFieldsTheme";
import { BRZ_PREFIX } from "../constants";
const getSuffixIcon = (icon) => {
return icon ? icon : React.createElement(Icon, { source: CmsIconDatePicker, size: "24px" });
};
export const DatePicker = ({ value, format, suffixIcon, picker, size, placeholder, showTime, showToday, autoClose = true, theme, disabled, disabledDate, disabledTime, onOk, getContainer, renderExtraFooter, onChange, onBlur, children, opened, onOpenedChange, closeExceptions, }) => {
const datePickerState = useRef("");
const context = useContext(FrameContentContext);
const [isOpen, setIsOpen] = useState(!!opened);
const containerRef = useRef(null);
const setState = useMemo(() => (opened === undefined ? setIsOpen : onOpenedChange), [opened, setIsOpen, onOpenedChange]);
const handleClick = useCallback(() => {
if (disabled) {
return;
}
// autoClose when select same value
if (datePickerState.current === "closed") {
datePickerState.current = "";
setState === null || setState === void 0 ? void 0 : setState(false);
}
else {
if (!isOpen) {
setState === null || setState === void 0 ? void 0 : setState(true);
}
}
}, [disabled, setState, isOpen]);
const handleClickWithoutChildren = useCallback((v) => {
if (!disabled)
setState === null || setState === void 0 ? void 0 : setState(v);
}, [setState, disabled]);
const handleWindow = useCallback((e) => {
if (datePickerState.current) {
datePickerState.current = "";
}
else {
// close if clicked outside of current node or inside datepicker dropdown
const target = e.target;
const node = containerRef.current;
if (node &&
!node.contains(target) &&
target.closest("body") &&
!target.closest(closeExceptions
? `.${BRZ_PREFIX}-datepicker__dropdown, ${closeExceptions.join()}`
: `.${BRZ_PREFIX}-datepicker__dropdown`)) {
setState === null || setState === void 0 ? void 0 : setState(false);
}
}
}, [setState, closeExceptions]);
useEffect(() => {
if (children) {
window.addEventListener("click", handleWindow);
return () => {
window.removeEventListener("click", handleWindow);
};
}
});
useEffect(() => {
if (opened !== undefined) {
setIsOpen(opened);
}
}, [opened]);
const datePickerClassName = classNames()("datepicker", {
datepicker__disabled: disabled,
});
//handlers for DisableDate and DisableTime
const handleDisabledDate = useMemo(() => (disabledDate ? (v) => disabledDate(v.toDate()) : undefined), [disabledDate]);
const handleDisabledTime = useMemo(() => (disabledTime ? (v) => disabledTime(v === null || v === void 0 ? void 0 : v.toDate()) : undefined), [disabledTime]);
const handleChange = useCallback((date) => {
if (!disabled && onChange) {
if (autoClose) {
datePickerState.current = "closed";
}
if (date)
onChange(date.toDate());
}
}, [onChange, disabled, autoClose]);
const handlePanelChange = useCallback((_, panel) => {
// specific check antPicker call panelChange after onChange
if (datePickerState.current !== "closed") {
datePickerState.current = panel;
}
}, []);
const handleGetContainer = () => {
if (typeof getContainer === "function") {
return getContainer();
}
if (context.node) {
return context.node;
}
return document.body;
};
return children ? (React.createElement("div", { ref: containerRef, onClick: handleClick, className: `${BRZ_PREFIX}-datepicker__wrapper` },
children,
React.createElement(AntDatePicker, { onBlur: onBlur, style: getFieldsStyleTheme(theme), value: value ? moment(value, format) : undefined, format: format, suffixIcon: getSuffixIcon(suffixIcon), onChange: handleChange, open: isOpen, onPanelChange: handlePanelChange, picker: picker, disabled: disabled, disabledTime: handleDisabledTime, disabledDate: handleDisabledDate, size: size, showToday: showToday, placeholder: placeholder, showTime: showTime, onOk: onOk, getPopupContainer: handleGetContainer, className: datePickerClassName, dropdownClassName: `${BRZ_PREFIX}-datepicker__dropdown`, renderExtraFooter: renderExtraFooter }))) : (React.createElement(AntDatePicker, { onBlur: onBlur, style: getFieldsStyleTheme(theme), value: value ? moment(value, format) : undefined, format: format, suffixIcon: getSuffixIcon(suffixIcon), onChange: handleChange, picker: picker, size: size, open: isOpen, onOpenChange: handleClickWithoutChildren, showToday: showToday, placeholder: placeholder, showTime: showTime, onOk: onOk, disabled: disabled, getPopupContainer: handleGetContainer, className: datePickerClassName, dropdownClassName: `${BRZ_PREFIX}-datepicker__dropdown`, renderExtraFooter: renderExtraFooter, disabledTime: handleDisabledTime, disabledDate: handleDisabledDate }));
};