diff --git a/.all-contributorsrc b/.all-contributorsrc index 1a80539a..a621a1e6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1189,6 +1189,15 @@ "contributions": [ "bug" ] + }, + { + "login": "wKovacs64", + "name": "Justin Hall", + "avatar_url": "https://avatars.githubusercontent.com/u/1288694?v=4", + "profile": "https://justinrhall.dev", + "contributions": [ + "bug" + ] } ], "commitConvention": "none", diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 13bdb5c7..2411fb2a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -163,6 +163,7 @@ Thanks goes to these wonderful people ([emoji key][emojis]):
Josh Unger

🐛
Rob Caldecott

🐛 💻
Tom Bertrand

🐛 +
Justin Hall

🐛 diff --git a/src/pointer/pointerPress.ts b/src/pointer/pointerPress.ts index da101fa4..8730f917 100644 --- a/src/pointer/pointerPress.ts +++ b/src/pointer/pointerPress.ts @@ -266,13 +266,6 @@ function mousedownDefaultBehavior({ node?: Node offset?: number }) { - // The closest focusable element is focused when a `mousedown` would have been fired. - // Even if there was no `mousedown` because the element was disabled. - // A `mousedown` that preventsDefault cancels this though. - focus(target) - - // TODO: What happens if a focus event handler interfers? - // An unprevented mousedown moves the cursor to the closest character. // We try to approximate the behavior for a no-layout environment. if (!targetIsDisabled) { @@ -326,6 +319,11 @@ function mousedownDefaultBehavior({ selection.addRange(range.cloneRange()) } } + + // The closest focusable element is focused when a `mousedown` would have been fired. + // Even if there was no `mousedown` because the element was disabled. + // A `mousedown` that preventsDefault cancels this though. + focus(target) } function getTextRange( diff --git a/tests/pointer/select.ts b/tests/pointer/select.ts index 7e2fc45a..83104663 100644 --- a/tests/pointer/select.ts +++ b/tests/pointer/select.ts @@ -368,3 +368,17 @@ describe('focus control when clicking label', () => { expect(input).not.toHaveFocus() }) }) + +test('focus event handler can override selection', async () => { + const {element, user} = setup(``, { + focus: false, + }) + element.addEventListener('focus', e => + (e.target as HTMLInputElement).select(), + ) + + await user.click(element) + + expect(element).toHaveProperty('selectionStart', 0) + expect(element).toHaveProperty('selectionEnd', 5) +}) diff --git a/tests/utility/type.ts b/tests/utility/type.ts index 1e4380c9..26e73131 100644 --- a/tests/utility/type.ts +++ b/tests/utility/type.ts @@ -19,9 +19,9 @@ test('type into input', async () => { input[value="foo"] - mousemove input[value="foo"] - pointerdown input[value="foo"] - mousedown: primary + input[value="foo"] - select input[value="foo"] - focus input[value="foo"] - focusin - input[value="foo"] - select input[value="foo"] - pointerup input[value="foo"] - mouseup: primary input[value="foo"] - click: primary