2023-09-11 17:28:04 +08:00
|
|
|
import * as React from 'react';
|
|
|
|
import { forwardRef, useContext, useImperativeHandle } from 'react';
|
2020-04-02 15:46:07 +08:00
|
|
|
import CalendarOutlined from '@ant-design/icons/CalendarOutlined';
|
|
|
|
import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
|
2020-04-09 13:18:13 +08:00
|
|
|
import SwapRightOutlined from '@ant-design/icons/SwapRightOutlined';
|
2022-06-22 14:57:09 +08:00
|
|
|
import classNames from 'classnames';
|
2024-04-08 14:04:08 +08:00
|
|
|
import { RangePicker as RCRangePicker } from 'rc-picker';
|
|
|
|
import type { PickerRef } from 'rc-picker';
|
2022-05-07 14:31:54 +08:00
|
|
|
import type { GenerateConfig } from 'rc-picker/lib/generate/index';
|
2023-09-11 17:28:04 +08:00
|
|
|
|
2024-01-29 15:34:48 +08:00
|
|
|
import { useZIndex } from '../../_util/hooks/useZIndex';
|
2023-05-12 14:53:47 +08:00
|
|
|
import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils';
|
2024-01-29 15:34:48 +08:00
|
|
|
import type { AnyObject } from '../../_util/type';
|
2023-09-11 17:28:04 +08:00
|
|
|
import { devUseWarning } from '../../_util/warning';
|
2022-06-22 14:57:09 +08:00
|
|
|
import { ConfigContext } from '../../config-provider';
|
|
|
|
import DisabledContext from '../../config-provider/DisabledContext';
|
2024-01-29 15:34:48 +08:00
|
|
|
import useCSSVarCls from '../../config-provider/hooks/useCSSVarCls';
|
2023-05-12 14:53:47 +08:00
|
|
|
import useSize from '../../config-provider/hooks/useSize';
|
2022-03-24 21:54:20 +08:00
|
|
|
import { FormItemInputContext } from '../../form/context';
|
2024-01-29 15:34:48 +08:00
|
|
|
import useVariant from '../../form/hooks/useVariants';
|
2023-03-21 13:08:43 +08:00
|
|
|
import { useLocale } from '../../locale';
|
2024-01-16 14:02:31 +08:00
|
|
|
import { NoCompactStyle, useCompactItemContext } from '../../space/Compact';
|
2022-06-22 14:57:09 +08:00
|
|
|
import enUS from '../locale/en_US';
|
2023-05-12 14:53:47 +08:00
|
|
|
import useStyle from '../style';
|
2024-02-01 16:26:38 +08:00
|
|
|
import { getRangePlaceholder, transPlacement2DropdownAlign, useIcons } from '../util';
|
2024-01-29 15:34:48 +08:00
|
|
|
import type { RangePickerProps } from './interface';
|
|
|
|
import useComponents from './useComponents';
|
|
|
|
|
|
|
|
export default function generateRangePicker<DateType extends AnyObject>(
|
|
|
|
generateConfig: GenerateConfig<DateType>,
|
|
|
|
) {
|
|
|
|
type DateRangePickerProps = RangePickerProps<DateType>;
|
2020-04-02 15:46:07 +08:00
|
|
|
|
2024-01-29 15:34:48 +08:00
|
|
|
const RangePicker = forwardRef<PickerRef, DateRangePickerProps>((props, ref) => {
|
2022-05-14 16:34:35 +08:00
|
|
|
const {
|
|
|
|
prefixCls: customizePrefixCls,
|
|
|
|
getPopupContainer: customGetPopupContainer,
|
2024-01-29 15:34:48 +08:00
|
|
|
components,
|
2022-05-14 16:34:35 +08:00
|
|
|
className,
|
2023-10-24 00:57:38 +08:00
|
|
|
style,
|
2022-05-14 16:34:35 +08:00
|
|
|
placement,
|
|
|
|
size: customizeSize,
|
|
|
|
disabled: customDisabled,
|
|
|
|
bordered = true,
|
|
|
|
placeholder,
|
2022-08-05 11:21:07 +08:00
|
|
|
popupClassName,
|
2022-09-08 14:33:11 +08:00
|
|
|
dropdownClassName,
|
2022-05-14 16:34:35 +08:00
|
|
|
status: customStatus,
|
2023-08-07 18:05:34 +08:00
|
|
|
rootClassName,
|
2023-12-21 20:43:40 +08:00
|
|
|
variant: customVariant,
|
2022-05-14 16:34:35 +08:00
|
|
|
...restProps
|
|
|
|
} = props;
|
2020-04-02 15:46:07 +08:00
|
|
|
|
2024-01-29 15:34:48 +08:00
|
|
|
const innerRef = React.useRef<PickerRef>(null);
|
2023-10-24 00:57:38 +08:00
|
|
|
const { getPrefixCls, direction, getPopupContainer, rangePicker } = useContext(ConfigContext);
|
2022-05-14 16:34:35 +08:00
|
|
|
const prefixCls = getPrefixCls('picker', customizePrefixCls);
|
2022-10-18 16:23:10 +08:00
|
|
|
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
|
2024-01-29 15:34:48 +08:00
|
|
|
const { picker } = props;
|
2022-05-14 16:34:35 +08:00
|
|
|
const rootPrefixCls = getPrefixCls();
|
2020-04-02 15:46:07 +08:00
|
|
|
|
2024-06-21 17:47:09 +08:00
|
|
|
const [variant, enableVariantCls] = useVariant('rangePicker', customVariant, bordered);
|
2023-12-21 20:43:40 +08:00
|
|
|
|
2023-12-14 14:58:53 +08:00
|
|
|
const rootCls = useCSSVarCls(prefixCls);
|
|
|
|
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
|
2020-04-02 15:46:07 +08:00
|
|
|
|
2022-09-08 14:33:11 +08:00
|
|
|
// =================== Warning =====================
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
2023-09-13 22:07:33 +08:00
|
|
|
const warning = devUseWarning('DatePicker.RangePicker');
|
2023-09-11 17:28:04 +08:00
|
|
|
|
2023-09-13 22:07:33 +08:00
|
|
|
warning.deprecated(!dropdownClassName, 'dropdownClassName', 'popupClassName');
|
2023-12-21 20:43:40 +08:00
|
|
|
|
|
|
|
warning.deprecated(!('bordered' in props), 'bordered', 'variant');
|
2022-09-08 14:33:11 +08:00
|
|
|
}
|
|
|
|
|
2024-02-01 16:26:38 +08:00
|
|
|
// ===================== Icon =====================
|
|
|
|
const [mergedAllowClear] = useIcons(props, prefixCls);
|
|
|
|
|
2024-01-29 15:34:48 +08:00
|
|
|
// ================== components ==================
|
|
|
|
const mergedComponents = useComponents(components);
|
|
|
|
|
2022-05-14 16:34:35 +08:00
|
|
|
// ===================== Size =====================
|
2023-06-19 14:26:48 +08:00
|
|
|
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
|
2022-03-25 17:48:12 +08:00
|
|
|
|
2022-05-14 16:34:35 +08:00
|
|
|
// ===================== Disabled =====================
|
|
|
|
const disabled = React.useContext(DisabledContext);
|
2022-09-20 16:48:59 +08:00
|
|
|
const mergedDisabled = customDisabled ?? disabled;
|
2022-05-09 10:34:10 +08:00
|
|
|
|
2022-05-14 16:34:35 +08:00
|
|
|
// ===================== FormItemInput =====================
|
|
|
|
const formItemContext = useContext(FormItemInputContext);
|
|
|
|
const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext;
|
2020-04-02 15:46:07 +08:00
|
|
|
|
2022-05-14 16:34:35 +08:00
|
|
|
const suffixNode = (
|
|
|
|
<>
|
|
|
|
{picker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
|
|
|
|
{hasFeedback && feedbackIcon}
|
|
|
|
</>
|
|
|
|
);
|
2020-04-02 15:46:07 +08:00
|
|
|
|
2024-01-29 15:34:48 +08:00
|
|
|
useImperativeHandle(ref, () => innerRef.current!);
|
2022-04-15 10:45:20 +08:00
|
|
|
|
2023-02-24 10:51:59 +08:00
|
|
|
const [contextLocale] = useLocale('Calendar', enUS);
|
2023-02-22 18:18:26 +08:00
|
|
|
|
|
|
|
const locale = { ...contextLocale, ...props.locale! };
|
|
|
|
|
2023-10-24 21:54:36 +08:00
|
|
|
// ============================ zIndex ============================
|
|
|
|
const [zIndex] = useZIndex('DatePicker', props.popupStyle?.zIndex as number);
|
|
|
|
|
2023-11-09 16:48:45 +08:00
|
|
|
return wrapCSSVar(
|
2024-01-16 14:02:31 +08:00
|
|
|
<NoCompactStyle>
|
|
|
|
<RCRangePicker<DateType>
|
|
|
|
separator={
|
|
|
|
<span aria-label="to" className={`${prefixCls}-separator`}>
|
|
|
|
<SwapRightOutlined />
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
disabled={mergedDisabled}
|
2024-04-01 15:49:45 +08:00
|
|
|
ref={innerRef as any} // Need to modify PickerRef
|
2024-01-29 15:34:48 +08:00
|
|
|
popupAlign={transPlacement2DropdownAlign(direction, placement)}
|
2024-06-08 21:59:21 +08:00
|
|
|
placement={placement}
|
2024-01-16 14:02:31 +08:00
|
|
|
placeholder={getRangePlaceholder(locale, picker, placeholder)}
|
|
|
|
suffixIcon={suffixNode}
|
|
|
|
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
|
|
|
|
nextIcon={<span className={`${prefixCls}-next-icon`} />}
|
|
|
|
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
|
|
|
|
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
|
|
|
|
transitionName={`${rootPrefixCls}-slide-up`}
|
|
|
|
{...restProps}
|
|
|
|
className={classNames(
|
|
|
|
{
|
|
|
|
[`${prefixCls}-${mergedSize}`]: mergedSize,
|
|
|
|
[`${prefixCls}-${variant}`]: enableVariantCls,
|
|
|
|
},
|
|
|
|
getStatusClassNames(
|
|
|
|
prefixCls,
|
|
|
|
getMergedStatus(contextStatus, customStatus),
|
|
|
|
hasFeedback,
|
|
|
|
),
|
|
|
|
hashId,
|
|
|
|
compactItemClassnames,
|
|
|
|
className,
|
|
|
|
rangePicker?.className,
|
|
|
|
cssVarCls,
|
|
|
|
rootCls,
|
|
|
|
rootClassName,
|
|
|
|
)}
|
|
|
|
style={{ ...rangePicker?.style, ...style }}
|
|
|
|
locale={locale.lang}
|
|
|
|
prefixCls={prefixCls}
|
|
|
|
getPopupContainer={customGetPopupContainer || getPopupContainer}
|
|
|
|
generateConfig={generateConfig}
|
2024-01-29 15:34:48 +08:00
|
|
|
components={mergedComponents}
|
2024-01-16 14:02:31 +08:00
|
|
|
direction={direction}
|
2024-01-29 15:34:48 +08:00
|
|
|
classNames={{
|
|
|
|
popup: classNames(
|
|
|
|
hashId,
|
|
|
|
popupClassName || dropdownClassName,
|
|
|
|
cssVarCls,
|
|
|
|
rootCls,
|
|
|
|
rootClassName,
|
|
|
|
),
|
|
|
|
}}
|
|
|
|
styles={{
|
|
|
|
popup: {
|
|
|
|
...props.popupStyle,
|
|
|
|
zIndex,
|
|
|
|
},
|
2024-01-16 14:02:31 +08:00
|
|
|
}}
|
2024-02-01 16:26:38 +08:00
|
|
|
allowClear={mergedAllowClear}
|
2024-01-16 14:02:31 +08:00
|
|
|
/>
|
|
|
|
</NoCompactStyle>,
|
2022-05-14 16:34:35 +08:00
|
|
|
);
|
|
|
|
});
|
2022-04-19 16:54:52 +08:00
|
|
|
|
2023-07-17 23:43:32 +08:00
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
|
RangePicker.displayName = 'RangePicker';
|
|
|
|
}
|
|
|
|
|
2024-01-29 15:34:48 +08:00
|
|
|
return RangePicker;
|
2020-04-02 15:46:07 +08:00
|
|
|
}
|