From 663937ffae1e7fcc6daecfab6ee324a33c089190 Mon Sep 17 00:00:00 2001 From: Clayton Date: Wed, 4 Mar 2026 11:48:00 -0600 Subject: [PATCH 1/3] fix: holding left click breaks mask --- src/PickerInput/Selector/Input.tsx | 64 +++++++++++++++++------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/src/PickerInput/Selector/Input.tsx b/src/PickerInput/Selector/Input.tsx index 22051545c..aba53a74a 100644 --- a/src/PickerInput/Selector/Input.tsx +++ b/src/PickerInput/Selector/Input.tsx @@ -333,39 +333,47 @@ const Input = React.forwardRef((props, ref) => { // ======================== Format ======================== const rafRef = React.useRef(); - useLayoutEffect(() => { - if (!focused || !format || mouseDownRef.current) { - return; - } + useLayoutEffect( + function () { + if (!focused || !format) { + return; + } - // Reset with format if not match - if (!maskFormat.match(inputValue)) { - triggerInputChange(format); - return; - } + // Reset with format if not match (always apply when focused so mask works when focusing by mousedown) + if (!maskFormat.match(inputValue)) { + triggerInputChange(format); + return; + } - // Match the selection range - inputRef.current.setSelectionRange(selectionStart, selectionEnd); + // When mousedown get focus, defer selection to mouseUp so click position is used + if (mouseDownRef.current) { + return; + } - // Chrome has the bug anchor position looks not correct but actually correct - rafRef.current = raf(() => { + // Match the selection range inputRef.current.setSelectionRange(selectionStart, selectionEnd); - }); - return () => { - raf.cancel(rafRef.current); - }; - }, [ - maskFormat, - format, - focused, - inputValue, - focusCellIndex, - selectionStart, - selectionEnd, - forceSelectionSyncMark, - triggerInputChange, - ]); + // Chrome has the bug anchor position looks not correct but actually correct + rafRef.current = raf(() => { + inputRef.current.setSelectionRange(selectionStart, selectionEnd); + }); + + return () => { + raf.cancel(rafRef.current); + }; + }, + [ + maskFormat, + format, + focused, + inputValue, + focusCellIndex, + selectionStart, + selectionEnd, + forceSelectionSyncMark, + triggerInputChange, + ], + ); // ======================== Render ======================== // Input props for format From fde8fad2c5bf12e318c4c0b2150f20014e37b5c9 Mon Sep 17 00:00:00 2001 From: Clayton Date: Wed, 4 Mar 2026 17:49:38 -0600 Subject: [PATCH 2/3] fix: align practice --- src/PickerInput/Selector/Input.tsx | 69 ++++++++++++++---------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/src/PickerInput/Selector/Input.tsx b/src/PickerInput/Selector/Input.tsx index aba53a74a..a9caa8d8e 100644 --- a/src/PickerInput/Selector/Input.tsx +++ b/src/PickerInput/Selector/Input.tsx @@ -333,47 +333,44 @@ const Input = React.forwardRef((props, ref) => { // ======================== Format ======================== const rafRef = React.useRef(); - useLayoutEffect( - function () { - if (!focused || !format) { - return; - } + useLayoutEffect(() => { + if (!focused || !format) { + return; + } - // Reset with format if not match (always apply when focused so mask works when focusing by mousedown) - if (!maskFormat.match(inputValue)) { - triggerInputChange(format); - return; - } + // 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; - } + // 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); + // Match the selection range + inputRef.current.setSelectionRange(selectionStart, selectionEnd); - // Chrome has the bug anchor position looks not correct but actually correct - rafRef.current = raf(() => { - inputRef.current.setSelectionRange(selectionStart, selectionEnd); - }); + // Chrome has the bug anchor position looks not correct but actually correct + rafRef.current = raf(() => { + inputRef.current.setSelectionRange(selectionStart, selectionEnd); + }); - return () => { - raf.cancel(rafRef.current); - }; - }, - [ - maskFormat, - format, - focused, - inputValue, - focusCellIndex, - selectionStart, - selectionEnd, - forceSelectionSyncMark, - triggerInputChange, - ], - ); + return () => { + raf.cancel(rafRef.current); + }; + }, [ + maskFormat, + format, + focused, + inputValue, + focusCellIndex, + selectionStart, + selectionEnd, + forceSelectionSyncMark, + triggerInputChange, + ]); // ======================== Render ======================== // Input props for format From 5b1a920050f4270e95ffd4708421698de9cbf7f2 Mon Sep 17 00:00:00 2001 From: Clayton Date: Wed, 4 Mar 2026 21:47:23 -0600 Subject: [PATCH 3/3] fix: add test --- tests/new-range.spec.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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();