|
1 | 1 | import * as React from 'react';
|
2 | 2 | import classNames from 'classnames';
|
3 | 3 | import { DisabledTimes, PanelMode, PickerMode } from './interface';
|
4 |
| -import { PickerBaseProps, PickerDateProps, PickerTimeProps } from './Picker'; |
| 4 | +import { |
| 5 | + PickerBaseProps, |
| 6 | + PickerDateProps, |
| 7 | + PickerTimeProps, |
| 8 | + PickerRefConfig, |
| 9 | +} from './Picker'; |
5 | 10 | import { SharedTimeProps } from './panels/TimePanel';
|
6 | 11 | import useMergedState from './hooks/useMergeState';
|
7 | 12 | import PickerTrigger from './PickerTrigger';
|
8 | 13 | import PickerPanel from './PickerPanel';
|
9 | 14 | import usePickerInput from './hooks/usePickerInput';
|
10 | 15 | import getDataOrAriaProps, { toArray } from './utils/miscUtil';
|
11 | 16 | import { getDefaultFormat, getInputSize } from './utils/uiUtil';
|
12 |
| -import { ContextOperationRefProps } from './PanelContext'; |
| 17 | +import PanelContext, { ContextOperationRefProps } from './PanelContext'; |
13 | 18 | import { isEqual } from './utils/dateUtil';
|
14 | 19 | import useValueTexts from './hooks/useValueTexts';
|
15 | 20 | import useTextValueMapping from './hooks/useTextValueMapping';
|
@@ -142,7 +147,7 @@ interface MergedRangePickerProps<DateType>
|
142 | 147 | picker?: PickerMode;
|
143 | 148 | }
|
144 | 149 |
|
145 |
| -function RangePicker<DateType>(props: RangePickerProps<DateType>) { |
| 150 | +function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) { |
146 | 151 | const {
|
147 | 152 | prefixCls = 'rc-picker',
|
148 | 153 | style,
|
@@ -170,6 +175,7 @@ function RangePicker<DateType>(props: RangePickerProps<DateType>) {
|
170 | 175 | allowClear,
|
171 | 176 | suffixIcon,
|
172 | 177 | clearIcon,
|
| 178 | + pickerRef, |
173 | 179 | inputReadOnly,
|
174 | 180 | onChange,
|
175 | 181 | onOpenChange,
|
@@ -246,6 +252,7 @@ function RangePicker<DateType>(props: RangePickerProps<DateType>) {
|
246 | 252 | (!isEqual(generateConfig, getIndexValue(mergedValue, 0), startValue) ||
|
247 | 253 | !isEqual(generateConfig, getIndexValue(mergedValue, 1), endValue))
|
248 | 254 | ) {
|
| 255 | + console.warn('trigger change!!!!'); |
249 | 256 | onChange(values, [
|
250 | 257 | startValue
|
251 | 258 | ? generateConfig.locale.format(
|
@@ -393,7 +400,23 @@ function RangePicker<DateType>(props: RangePickerProps<DateType>) {
|
393 | 400 | }, [mergedValue]);
|
394 | 401 |
|
395 | 402 | // ============================ Private ============================
|
396 |
| - // TODO: pickerRef |
| 403 | + if (pickerRef) { |
| 404 | + pickerRef.current = { |
| 405 | + focus: () => { |
| 406 | + if (startInputRef.current) { |
| 407 | + startInputRef.current.focus(); |
| 408 | + } |
| 409 | + }, |
| 410 | + blur: () => { |
| 411 | + if (startInputRef.current) { |
| 412 | + startInputRef.current.blur(); |
| 413 | + } |
| 414 | + if (endInputRef.current) { |
| 415 | + endInputRef.current.blur(); |
| 416 | + } |
| 417 | + }, |
| 418 | + }; |
| 419 | + } |
397 | 420 |
|
398 | 421 | // ============================= Panel =============================
|
399 | 422 | const panelProps = {
|
@@ -449,53 +472,89 @@ function RangePicker<DateType>(props: RangePickerProps<DateType>) {
|
449 | 472 | };
|
450 | 473 |
|
451 | 474 | return (
|
452 |
| - <PickerTrigger |
453 |
| - visible={mergedOpen} |
454 |
| - popupElement={panel} |
455 |
| - popupStyle={popupStyle} |
456 |
| - prefixCls={prefixCls} |
457 |
| - dropdownClassName={dropdownClassName} |
458 |
| - dropdownAlign={dropdownAlign} |
459 |
| - getPopupContainer={getPopupContainer} |
460 |
| - transitionName={transitionName} |
| 475 | + <PanelContext.Provider |
| 476 | + value={{ |
| 477 | + operationRef, |
| 478 | + hideHeader: picker === 'time', |
| 479 | + panelRef: panelDivRef, |
| 480 | + }} |
461 | 481 | >
|
462 |
| - <div |
463 |
| - className={classNames(`${prefixCls}-range`, className, { |
464 |
| - [`${prefixCls}-range-disabled`]: disabled, |
465 |
| - [`${prefixCls}-range-focused`]: startFocused || endFocused, |
466 |
| - })} |
467 |
| - style={style} |
468 |
| - {...getDataOrAriaProps(props)} |
| 482 | + <PickerTrigger |
| 483 | + visible={mergedOpen} |
| 484 | + popupElement={panel} |
| 485 | + popupStyle={popupStyle} |
| 486 | + prefixCls={prefixCls} |
| 487 | + dropdownClassName={dropdownClassName} |
| 488 | + dropdownAlign={dropdownAlign} |
| 489 | + getPopupContainer={getPopupContainer} |
| 490 | + transitionName={transitionName} |
469 | 491 | >
|
470 |
| - <div className={`${prefixCls}-input`} ref={startInputDivRef}> |
471 |
| - <input |
472 |
| - readOnly={inputReadOnly || !startTyping} |
473 |
| - value={startText} |
474 |
| - onChange={triggerStartTextChange} |
475 |
| - autoFocus={autoFocus} |
476 |
| - placeholder={getIndexValue(placeholder, 0) || ''} |
477 |
| - ref={startInputRef} |
478 |
| - {...startInputProps} |
479 |
| - {...inputSharedProps} |
480 |
| - /> |
| 492 | + <div |
| 493 | + className={classNames(`${prefixCls}-range`, className, { |
| 494 | + [`${prefixCls}-range-disabled`]: disabled, |
| 495 | + [`${prefixCls}-range-focused`]: startFocused || endFocused, |
| 496 | + })} |
| 497 | + style={style} |
| 498 | + {...getDataOrAriaProps(props)} |
| 499 | + > |
| 500 | + <div className={`${prefixCls}-input`} ref={startInputDivRef}> |
| 501 | + <input |
| 502 | + readOnly={inputReadOnly || !startTyping} |
| 503 | + value={startText} |
| 504 | + onChange={triggerStartTextChange} |
| 505 | + autoFocus={autoFocus} |
| 506 | + placeholder={getIndexValue(placeholder, 0) || ''} |
| 507 | + ref={startInputRef} |
| 508 | + {...startInputProps} |
| 509 | + {...inputSharedProps} |
| 510 | + /> |
| 511 | + </div> |
| 512 | + {separator} |
| 513 | + <div className={`${prefixCls}-input`} ref={startInputDivRef}> |
| 514 | + <input |
| 515 | + readOnly={inputReadOnly || !startTyping} |
| 516 | + value={endText} |
| 517 | + onChange={triggerEndTextChange} |
| 518 | + placeholder={getIndexValue(placeholder, 1) || ''} |
| 519 | + ref={endInputRef} |
| 520 | + {...endInputProps} |
| 521 | + {...inputSharedProps} |
| 522 | + /> |
| 523 | + </div> |
| 524 | + {suffixNode} |
| 525 | + {clearNode} |
481 | 526 | </div>
|
482 |
| - {separator} |
483 |
| - <div className={`${prefixCls}-input`} ref={startInputDivRef}> |
484 |
| - <input |
485 |
| - readOnly={inputReadOnly || !startTyping} |
486 |
| - value={endText} |
487 |
| - onChange={triggerEndTextChange} |
488 |
| - placeholder={getIndexValue(placeholder, 1) || ''} |
489 |
| - ref={endInputRef} |
490 |
| - {...endInputProps} |
491 |
| - {...inputSharedProps} |
492 |
| - /> |
493 |
| - </div> |
494 |
| - {suffixNode} |
495 |
| - {clearNode} |
496 |
| - </div> |
497 |
| - </PickerTrigger> |
| 527 | + </PickerTrigger> |
| 528 | + </PanelContext.Provider> |
498 | 529 | );
|
499 | 530 | }
|
500 | 531 |
|
| 532 | +// Wrap with class component to enable pass generic with instance method |
| 533 | +class RangePicker<DateType> extends React.Component< |
| 534 | + RangePickerProps<DateType> |
| 535 | +> { |
| 536 | + pickerRef = React.createRef<PickerRefConfig>(); |
| 537 | + |
| 538 | + focus = () => { |
| 539 | + if (this.pickerRef.current) { |
| 540 | + this.pickerRef.current.focus(); |
| 541 | + } |
| 542 | + }; |
| 543 | + |
| 544 | + blur = () => { |
| 545 | + if (this.pickerRef.current) { |
| 546 | + this.pickerRef.current.blur(); |
| 547 | + } |
| 548 | + }; |
| 549 | + |
| 550 | + render() { |
| 551 | + return ( |
| 552 | + <InnerRangePicker<DateType> |
| 553 | + {...this.props} |
| 554 | + pickerRef={this.pickerRef as React.MutableRefObject<PickerRefConfig>} |
| 555 | + /> |
| 556 | + ); |
| 557 | + } |
| 558 | +} |
| 559 | + |
501 | 560 | export default RangePicker;
|
0 commit comments