Skip to content

Commit 4915ccf

Browse files
authored
Merge 9b843e9 into f6c6803
2 parents f6c6803 + 9b843e9 commit 4915ccf

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

src/Picker.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
196196
autoComplete = 'off',
197197
inputRender,
198198
changeOnBlur,
199+
renderExtraFooter,
199200
} = props as MergedPickerProps<DateType>;
200201

201202
const inputRef = React.useRef<HTMLInputElement>(null);
@@ -326,6 +327,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
326327
const [inputProps, { focused, typing }] = usePickerInput({
327328
blurToCancel: needConfirmButton,
328329
changeOnBlur,
330+
hasExtraFooter: !!renderExtraFooter,
329331
open: mergedOpen,
330332
value: text,
331333
triggerOpen,

src/RangePicker.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
599599
const getSharedInputHookProps = (index: 0 | 1, resetText: () => void) => ({
600600
blurToCancel: !changeOnBlur && needConfirmButton,
601601
changeOnBlur,
602+
hasExtraFooter: !!renderExtraFooter,
602603
forwardKeyDown,
603604
onBlur: onInternalBlur,
604605
isClickOutside: (target: EventTarget | null) => {

src/hooks/usePickerInput.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default function usePickerInput({
1313
onKeyDown,
1414
blurToCancel,
1515
changeOnBlur,
16+
hasExtraFooter,
1617
onSubmit,
1718
onCancel,
1819
onFocus,
@@ -25,14 +26,16 @@ export default function usePickerInput({
2526
forwardKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => boolean;
2627
onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>, preventDefault: () => void) => void;
2728
blurToCancel?: boolean;
28-
changeOnBlur?: boolean
29+
changeOnBlur?: boolean;
30+
hasExtraFooter?: boolean;
2931
onSubmit: () => void | boolean;
3032
onCancel: () => void;
3133
onFocus?: React.FocusEventHandler<HTMLInputElement>;
3234
onBlur?: React.FocusEventHandler<HTMLInputElement>;
3335
}): [React.DOMAttributes<HTMLInputElement>, { focused: boolean; typing: boolean }] {
3436
const [typing, setTyping] = useState(false);
3537
const [focused, setFocused] = useState(false);
38+
const [outside, setOutside] = useState(true);
3639

3740
/**
3841
* We will prevent blur to handle open event when user click outside,
@@ -108,7 +111,7 @@ export default function usePickerInput({
108111
},
109112

110113
onBlur: (e) => {
111-
if (preventBlurRef.current || !isClickOutside(document.activeElement)) {
114+
if (preventBlurRef.current || !isClickOutside(document.activeElement) || !outside) {
112115
preventBlurRef.current = false;
113116
return;
114117
}
@@ -152,6 +155,11 @@ export default function usePickerInput({
152155
const target = getTargetFromEvent(e);
153156
const clickedOutside = isClickOutside(target);
154157

158+
if (hasExtraFooter) {
159+
// Save whether the last click is inside the component when `extraFooter` exists.
160+
setOutside(clickedOutside);
161+
}
162+
155163
if (open) {
156164
if (!clickedOutside) {
157165
preventBlurRef.current = true;

tests/picker.spec.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,4 +1145,19 @@ describe('Picker.Basic', () => {
11451145

11461146
expect(container.querySelector('input')).toHaveValue('2023-09-04 21:05:10');
11471147
});
1148+
1149+
it('interacting with components within footer should not close the panel', () => {
1150+
const { container, baseElement } = render(
1151+
<MomentPicker renderExtraFooter={() => <button className="test-button">button</button>} />,
1152+
);
1153+
1154+
openPicker(container);
1155+
1156+
fireEvent.click(baseElement.querySelector('.test-button'));
1157+
1158+
// Simulate component behavior
1159+
fireEvent.blur(container.querySelector('input'));
1160+
1161+
expect(baseElement.querySelector('.rc-picker-dropdown-hidden')).toBeFalsy();
1162+
});
11481163
});

tests/range.spec.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,4 +1985,22 @@ describe('Picker.Range', () => {
19851985

19861986
expect(onOpenChange).toHaveBeenCalledWith(false);
19871987
});
1988+
1989+
// In line with the picker
1990+
it('interacting with components within footer should not close the panel', () => {
1991+
const { container, baseElement } = render(
1992+
<MomentRangePicker
1993+
renderExtraFooter={() => <button className="test-button">button</button>}
1994+
/>,
1995+
);
1996+
1997+
openPicker(container);
1998+
1999+
fireEvent.click(baseElement.querySelector('.test-button'));
2000+
2001+
// Simulate component behavior
2002+
fireEvent.blur(container.querySelector('input'));
2003+
2004+
expect(baseElement.querySelector('.rc-picker-dropdown-hidden')).toBeFalsy();
2005+
});
19882006
});

0 commit comments

Comments
 (0)