-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
/
generateRangePicker.tsx
160 lines (145 loc) · 6.21 KB
/
generateRangePicker.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import CalendarOutlined from '@ant-design/icons/CalendarOutlined';
import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import SwapRightOutlined from '@ant-design/icons/SwapRightOutlined';
import classNames from 'classnames';
import { RangePicker as RCRangePicker } from 'rc-picker';
import type { GenerateConfig } from 'rc-picker/lib/generate/index';
import * as React from 'react';
import { forwardRef, useContext, useImperativeHandle } from 'react';
import type { RangePickerProps } from '.';
import { Components, getTimeProps } from '.';
import { ConfigContext } from '../../config-provider';
import DisabledContext from '../../config-provider/DisabledContext';
import SizeContext from '../../config-provider/SizeContext';
import { FormItemInputContext } from '../../form/context';
import { useCompactItemContext } from '../../space/Compact';
import LocaleReceiver from '../../locale-provider/LocaleReceiver';
import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils';
import enUS from '../locale/en_US';
import { getRangePlaceholder, transPlacement2DropdownAlign } from '../util';
import type { CommonPickerMethods, PickerComponentClass } from './interface';
import warning from '../../_util/warning';
import useStyle from '../style';
export default function generateRangePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
type InternalRangePickerProps = RangePickerProps<DateType> & {};
type DateRangePickerProps = RangePickerProps<DateType> & {
/**
* @deprecated `dropdownClassName` is deprecated which will be removed in next major
* version.Please use `popupClassName` instead.
*/
dropdownClassName?: string;
popupClassName?: string;
};
const RangePicker = forwardRef<
InternalRangePickerProps | CommonPickerMethods,
DateRangePickerProps
>((props, ref) => {
const {
prefixCls: customizePrefixCls,
getPopupContainer: customGetPopupContainer,
className,
placement,
size: customizeSize,
disabled: customDisabled,
bordered = true,
placeholder,
popupClassName,
dropdownClassName,
status: customStatus,
...restProps
} = props;
const innerRef = React.useRef<RCRangePicker<DateType>>(null);
const { getPrefixCls, direction, getPopupContainer } = useContext(ConfigContext);
const prefixCls = getPrefixCls('picker', customizePrefixCls);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const { format, showTime, picker } = props as any;
const rootPrefixCls = getPrefixCls();
const [wrapSSR, hashId] = useStyle(prefixCls);
let additionalOverrideProps: any = {};
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...props, picker }) : {}),
};
// =================== Warning =====================
if (process.env.NODE_ENV !== 'production') {
warning(
!dropdownClassName,
'DatePicker.RangePicker',
'`dropdownClassName` is deprecated. Please use `popupClassName` instead.',
);
}
// ===================== Size =====================
const size = React.useContext(SizeContext);
const mergedSize = compactSize || customizeSize || size;
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);
const mergedDisabled = customDisabled ?? disabled;
// ===================== FormItemInput =====================
const formItemContext = useContext(FormItemInputContext);
const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext;
const suffixNode = (
<>
{picker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
{hasFeedback && feedbackIcon}
</>
);
useImperativeHandle(ref, () => ({
focus: () => innerRef.current?.focus(),
blur: () => innerRef.current?.blur(),
}));
return wrapSSR(
<LocaleReceiver componentName="DatePicker" defaultLocale={enUS}>
{(contextLocale) => {
const locale = { ...contextLocale, ...props.locale };
return (
<RCRangePicker<DateType>
separator={
<span aria-label="to" className={`${prefixCls}-separator`}>
<SwapRightOutlined />
</span>
}
disabled={mergedDisabled}
ref={innerRef}
dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
placeholder={getRangePlaceholder(picker, locale, placeholder)}
suffixIcon={suffixNode}
clearIcon={<CloseCircleFilled />}
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`} />}
allowClear
transitionName={`${rootPrefixCls}-slide-up`}
{...restProps}
{...additionalOverrideProps}
className={classNames(
{
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-borderless`]: !bordered,
},
getStatusClassNames(
prefixCls as string,
getMergedStatus(contextStatus, customStatus),
hasFeedback,
),
hashId,
compactItemClassnames,
className,
)}
locale={locale.lang}
prefixCls={prefixCls}
getPopupContainer={customGetPopupContainer || getPopupContainer}
generateConfig={generateConfig}
components={Components}
direction={direction}
dropdownClassName={classNames(hashId, popupClassName || dropdownClassName)}
/>
);
}}
</LocaleReceiver>,
);
});
return RangePicker as unknown as PickerComponentClass<DateRangePickerProps>;
}