UNPKG

@brizy/ui

Version:
103 lines (102 loc) 5.69 kB
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 })); };