diff --git a/src/PickerInput/Selector/Input.tsx b/src/PickerInput/Selector/Input.tsx index 22051545c..a9caa8d8e 100644 --- a/src/PickerInput/Selector/Input.tsx +++ b/src/PickerInput/Selector/Input.tsx @@ -334,16 +334,21 @@ const Input = React.forwardRef((props, ref) => { const rafRef = React.useRef(); useLayoutEffect(() => { - if (!focused || !format || mouseDownRef.current) { + if (!focused || !format) { return; } - // Reset with format if not match + // Reset with format if not match (always apply when focused so mask works when focusing by mousedown) if (!maskFormat.match(inputValue)) { triggerInputChange(format); return; } + // When mousedown get focus, defer selection to mouseUp so click position is used + if (mouseDownRef.current) { + return; + } + // Match the selection range inputRef.current.setSelectionRange(selectionStart, selectionEnd); diff --git a/tests/new-range.spec.tsx b/tests/new-range.spec.tsx index f9faa18ee..ede5a8b75 100644 --- a/tests/new-range.spec.tsx +++ b/tests/new-range.spec.tsx @@ -1010,6 +1010,19 @@ describe('NewPicker.Range', () => { expect(startInput.selectionEnd).toEqual(6); }); + it('focus by mousedown defers selection sync to mouseUp', () => { + const { container } = render(); + + const startInput = container.querySelectorAll('input')[0]; + + fireEvent.mouseDown(startInput); + fireEvent.focus(startInput); + + fireEvent.mouseUp(startInput); + expect(startInput.selectionStart).toBeDefined(); + expect(startInput.selectionEnd).toBeDefined(); + }); + it('blur to reset back text', async () => { const { container } = render();