From 0e550bf236b50077f3560a22bf1f17ec65c495eb Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 5 Dec 2022 14:02:05 -0500 Subject: [PATCH 01/12] =?UTF-8?q?Ignore=20mouse=20move/leave=20events=20wh?= =?UTF-8?q?en=20the=20cursor=20hasn=E2=80=99t=20moved?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A mouse enter / leave event where the cursor hasn’t moved happen only because of: - Scrolling - The container moved --- .../src/components/combobox/combobox.tsx | 13 +++++++-- .../src/components/listbox/listbox.tsx | 13 +++++++-- .../src/components/menu/menu.tsx | 13 +++++++-- .../src/hooks/use-tracked-pointer.ts | 28 +++++++++++++++++++ .../src/components/combobox/combobox.ts | 15 ++++++++-- .../src/components/listbox/listbox.ts | 15 ++++++++-- .../src/components/menu/menu.ts | 15 ++++++++-- .../src/hooks/use-tracked-pointer.ts | 28 +++++++++++++++++++ 8 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 packages/@headlessui-react/src/hooks/use-tracked-pointer.ts create mode 100644 packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts diff --git a/packages/@headlessui-react/src/components/combobox/combobox.tsx b/packages/@headlessui-react/src/components/combobox/combobox.tsx index ea2309838..3f19691be 100644 --- a/packages/@headlessui-react/src/components/combobox/combobox.tsx +++ b/packages/@headlessui-react/src/components/combobox/combobox.tsx @@ -43,6 +43,7 @@ import { useOpenClosed, State, OpenClosedProvider } from '../../internal/open-cl import { Keys } from '../keyboard' import { useControllable } from '../../hooks/use-controllable' import { useWatch } from '../../hooks/use-watch' +import { useTrackedPointer } from 'hooks/use-tracked-pointer' enum ComboboxState { Open, @@ -1255,13 +1256,19 @@ let Option = forwardRefWithAs(function Option< actions.goToOption(Focus.Specific, id) }) - let handleMove = useEvent(() => { + let pointer = useTrackedPointer(); + + let handleEnter = useEvent((evt) => pointer.update(evt)) + + let handleMove = useEvent((evt) => { + if (! pointer.wasMoved(evt)) return; if (disabled) return if (active) return actions.goToOption(Focus.Specific, id, ActivationTrigger.Pointer) }) - let handleLeave = useEvent(() => { + let handleLeave = useEvent((evt) => { + if (! pointer.wasMoved(evt)) return; if (disabled) return if (!active) return if (data.optionsPropsRef.current.hold) return @@ -1286,6 +1293,8 @@ let Option = forwardRefWithAs(function Option< disabled: undefined, // Never forward the `disabled` prop onClick: handleClick, onFocus: handleFocus, + onPointerEnter: handleEnter, + onMouseEnter: handleEnter, onPointerMove: handleMove, onMouseMove: handleMove, onPointerLeave: handleLeave, diff --git a/packages/@headlessui-react/src/components/listbox/listbox.tsx b/packages/@headlessui-react/src/components/listbox/listbox.tsx index 6311113af..f1d399bc1 100644 --- a/packages/@headlessui-react/src/components/listbox/listbox.tsx +++ b/packages/@headlessui-react/src/components/listbox/listbox.tsx @@ -39,6 +39,7 @@ import { getOwnerDocument } from '../../utils/owner' import { useEvent } from '../../hooks/use-event' import { useControllable } from '../../hooks/use-controllable' import { useLatestValue } from '../../hooks/use-latest-value' +import { useTrackedPointer } from 'hooks/use-tracked-pointer' enum ListboxStates { Open, @@ -957,13 +958,19 @@ let Option = forwardRefWithAs(function Option< actions.goToOption(Focus.Specific, id) }) - let handleMove = useEvent(() => { + let pointer = useTrackedPointer(); + + let handleEnter = useEvent((evt) => pointer.update(evt)) + + let handleMove = useEvent((evt) => { + if (! pointer.wasMoved(evt)) return; if (disabled) return if (active) return actions.goToOption(Focus.Specific, id, ActivationTrigger.Pointer) }) - let handleLeave = useEvent(() => { + let handleLeave = useEvent((evt) => { + if (! pointer.wasMoved(evt)) return; if (disabled) return if (!active) return actions.goToOption(Focus.Nothing) @@ -986,6 +993,8 @@ let Option = forwardRefWithAs(function Option< disabled: undefined, // Never forward the `disabled` prop onClick: handleClick, onFocus: handleFocus, + onPointerEnter: handleEnter, + onMouseEnter: handleEnter, onPointerMove: handleMove, onMouseMove: handleMove, onPointerLeave: handleLeave, diff --git a/packages/@headlessui-react/src/components/menu/menu.tsx b/packages/@headlessui-react/src/components/menu/menu.tsx index b94fbdaf4..4d4158f14 100644 --- a/packages/@headlessui-react/src/components/menu/menu.tsx +++ b/packages/@headlessui-react/src/components/menu/menu.tsx @@ -43,6 +43,7 @@ import { useOpenClosed, State, OpenClosedProvider } from '../../internal/open-cl import { useResolveButtonType } from '../../hooks/use-resolve-button-type' import { useOwnerDocument } from '../../hooks/use-owner' import { useEvent } from '../../hooks/use-event' +import { useTrackedPointer } from 'hooks/use-tracked-pointer' enum MenuStates { Open, @@ -631,7 +632,12 @@ let Item = forwardRefWithAs(function Item { + let pointer = useTrackedPointer(); + + let handleEnter = useEvent((evt) => pointer.update(evt)); + + let handleMove = useEvent((evt) => { + if (!pointer.wasMoved(evt)) return; if (disabled) return if (active) return dispatch({ @@ -642,7 +648,8 @@ let Item = forwardRefWithAs(function Item { + let handleLeave = useEvent((evt) => { + if (!pointer.wasMoved(evt)) return; if (disabled) return if (!active) return dispatch({ type: ActionTypes.GoToItem, focus: Focus.Nothing }) @@ -661,6 +668,8 @@ let Item = forwardRefWithAs(function Item([-1, -1]); + + return { + wasMoved(evt: PointerEvent) { + let newPos = eventToPosition(evt); + + if (lastPos.current[0] === newPos[0] && lastPos.current[1] === newPos[1]) { + return false; + } + + lastPos.current = newPos; + return false; + }, + + update(evt: PointerEvent) { + lastPos.current = eventToPosition(evt); + }, + } +} diff --git a/packages/@headlessui-vue/src/components/combobox/combobox.ts b/packages/@headlessui-vue/src/components/combobox/combobox.ts index 8805957e0..671945290 100644 --- a/packages/@headlessui-vue/src/components/combobox/combobox.ts +++ b/packages/@headlessui-vue/src/components/combobox/combobox.ts @@ -35,6 +35,7 @@ import { useOutsideClick } from '../../hooks/use-outside-click' import { Hidden, Features as HiddenFeatures } from '../../internal/hidden' import { objectToFormEntries } from '../../utils/form' import { useControllable } from '../../hooks/use-controllable' +import { useTrackedPointer } from 'hooks/use-tracked-pointer' function defaultComparator(a: T, z: T): boolean { return a === z @@ -1057,13 +1058,21 @@ export let ComboboxOption = defineComponent({ api.goToOption(Focus.Specific, id) } - function handleMove() { + let pointer = useTrackedPointer(); + + function handleEnter(evt: PointerEvent) { + pointer.update(evt) + } + + function handleMove(evt: PointerEvent) { + if (! pointer.wasMoved(evt)) return; if (props.disabled) return if (active.value) return api.goToOption(Focus.Specific, id, ActivationTrigger.Pointer) } - function handleLeave() { + function handleLeave(evt: PointerEvent) { + if (! pointer.wasMoved(evt)) return; if (props.disabled) return if (!active.value) return if (api.optionsPropsRef.value.hold) return @@ -1086,6 +1095,8 @@ export let ComboboxOption = defineComponent({ disabled: undefined, // Never forward the `disabled` prop onClick: handleClick, onFocus: handleFocus, + onPointerenter: handleEnter, + onMouseenter: handleEnter, onPointermove: handleMove, onMousemove: handleMove, onPointerleave: handleLeave, diff --git a/packages/@headlessui-vue/src/components/listbox/listbox.ts b/packages/@headlessui-vue/src/components/listbox/listbox.ts index 48fb4df82..1bcbfa9a3 100644 --- a/packages/@headlessui-vue/src/components/listbox/listbox.ts +++ b/packages/@headlessui-vue/src/components/listbox/listbox.ts @@ -34,6 +34,7 @@ import { useOutsideClick } from '../../hooks/use-outside-click' import { Hidden, Features as HiddenFeatures } from '../../internal/hidden' import { objectToFormEntries } from '../../utils/form' import { useControllable } from '../../hooks/use-controllable' +import { useTrackedPointer } from 'hooks/use-tracked-pointer' function defaultComparator(a: T, z: T): boolean { return a === z @@ -783,13 +784,21 @@ export let ListboxOption = defineComponent({ api.goToOption(Focus.Specific, props.id) } - function handleMove() { + let pointer = useTrackedPointer(); + + function handleEnter(evt: PointerEvent) { + pointer.update(evt) + } + + function handleMove(evt: PointerEvent) { + if (! pointer.wasMoved(evt)) return; if (props.disabled) return if (active.value) return api.goToOption(Focus.Specific, props.id, ActivationTrigger.Pointer) } - function handleLeave() { + function handleLeave(evt: PointerEvent) { + if (! pointer.wasMoved(evt)) return; if (props.disabled) return if (!active.value) return api.goToOption(Focus.Nothing) @@ -812,6 +821,8 @@ export let ListboxOption = defineComponent({ disabled: undefined, // Never forward the `disabled` prop onClick: handleClick, onFocus: handleFocus, + onPointerenter: handleEnter, + onMouseenter: handleEnter, onPointermove: handleMove, onMousemove: handleMove, onPointerleave: handleLeave, diff --git a/packages/@headlessui-vue/src/components/menu/menu.ts b/packages/@headlessui-vue/src/components/menu/menu.ts index b58dce9df..081db7a27 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.ts +++ b/packages/@headlessui-vue/src/components/menu/menu.ts @@ -31,6 +31,7 @@ import { restoreFocusIfNecessary, } from '../../utils/focus-management' import { useOutsideClick } from '../../hooks/use-outside-click' +import { useTrackedPointer } from 'hooks/use-tracked-pointer' enum MenuStates { Open, @@ -540,13 +541,21 @@ export let MenuItem = defineComponent({ api.goToItem(Focus.Specific, props.id) } - function handleMove() { + let pointer = useTrackedPointer(); + + function handleEnter(evt: PointerEvent) { + pointer.update(evt) + } + + function handleMove(evt: PointerEvent) { + if (! pointer.wasMoved(evt)) return; if (props.disabled) return if (active.value) return api.goToItem(Focus.Specific, props.id, ActivationTrigger.Pointer) } - function handleLeave() { + function handleLeave(evt: PointerEvent) { + if (! pointer.wasMoved(evt)) return; if (props.disabled) return if (!active.value) return api.goToItem(Focus.Nothing) @@ -566,6 +575,8 @@ export let MenuItem = defineComponent({ onFocus: handleFocus, onPointermove: handleMove, onMousemove: handleMove, + onPointerenter: handleEnter, + onMouseenter: handleEnter, onPointerleave: handleLeave, onMouseleave: handleLeave, } diff --git a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts new file mode 100644 index 000000000..4d7c875ba --- /dev/null +++ b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts @@ -0,0 +1,28 @@ +import { ref } from "vue" + +type PointerPosition = [x: number, y: number]; + +function eventToPosition(evt: PointerEvent): PointerPosition { + return [evt.screenX, evt.screenY]; +} + +export function useTrackedPointer() { + let lastPos = ref([-1, -1]); + + return { + wasMoved(evt: PointerEvent) { + let newPos = eventToPosition(evt); + + if (lastPos.value[0] === newPos[0] && lastPos.value[1] === newPos[1]) { + return false; + } + + lastPos.value = newPos; + return false; + }, + + update(evt: PointerEvent) { + lastPos.value = eventToPosition(evt); + }, + } +} From 5da8dff1cdbbad11c93df5c14448b06267717f98 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 5 Dec 2022 14:13:51 -0500 Subject: [PATCH 02/12] Fix linting errors --- .../src/components/combobox/combobox.tsx | 6 +++--- .../src/components/listbox/listbox.tsx | 6 +++--- .../src/components/menu/menu.tsx | 8 ++++---- .../src/hooks/use-tracked-pointer.ts | 18 +++++++++--------- .../src/components/combobox/combobox.ts | 6 +++--- .../src/components/listbox/listbox.ts | 6 +++--- .../src/components/menu/menu.ts | 6 +++--- .../src/hooks/use-tracked-pointer.ts | 18 +++++++++--------- 8 files changed, 37 insertions(+), 37 deletions(-) diff --git a/packages/@headlessui-react/src/components/combobox/combobox.tsx b/packages/@headlessui-react/src/components/combobox/combobox.tsx index 3f19691be..6eb71abb3 100644 --- a/packages/@headlessui-react/src/components/combobox/combobox.tsx +++ b/packages/@headlessui-react/src/components/combobox/combobox.tsx @@ -1256,19 +1256,19 @@ let Option = forwardRefWithAs(function Option< actions.goToOption(Focus.Specific, id) }) - let pointer = useTrackedPointer(); + let pointer = useTrackedPointer() let handleEnter = useEvent((evt) => pointer.update(evt)) let handleMove = useEvent((evt) => { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (disabled) return if (active) return actions.goToOption(Focus.Specific, id, ActivationTrigger.Pointer) }) let handleLeave = useEvent((evt) => { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (disabled) return if (!active) return if (data.optionsPropsRef.current.hold) return diff --git a/packages/@headlessui-react/src/components/listbox/listbox.tsx b/packages/@headlessui-react/src/components/listbox/listbox.tsx index f1d399bc1..316f58e43 100644 --- a/packages/@headlessui-react/src/components/listbox/listbox.tsx +++ b/packages/@headlessui-react/src/components/listbox/listbox.tsx @@ -958,19 +958,19 @@ let Option = forwardRefWithAs(function Option< actions.goToOption(Focus.Specific, id) }) - let pointer = useTrackedPointer(); + let pointer = useTrackedPointer() let handleEnter = useEvent((evt) => pointer.update(evt)) let handleMove = useEvent((evt) => { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (disabled) return if (active) return actions.goToOption(Focus.Specific, id, ActivationTrigger.Pointer) }) let handleLeave = useEvent((evt) => { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (disabled) return if (!active) return actions.goToOption(Focus.Nothing) diff --git a/packages/@headlessui-react/src/components/menu/menu.tsx b/packages/@headlessui-react/src/components/menu/menu.tsx index 4d4158f14..ccf3b9099 100644 --- a/packages/@headlessui-react/src/components/menu/menu.tsx +++ b/packages/@headlessui-react/src/components/menu/menu.tsx @@ -632,12 +632,12 @@ let Item = forwardRefWithAs(function Item pointer.update(evt)); + let handleEnter = useEvent((evt) => pointer.update(evt)) let handleMove = useEvent((evt) => { - if (!pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (disabled) return if (active) return dispatch({ @@ -649,7 +649,7 @@ let Item = forwardRefWithAs(function Item { - if (!pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (disabled) return if (!active) return dispatch({ type: ActionTypes.GoToItem, focus: Focus.Nothing }) diff --git a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts index d36067594..e8e2aa9eb 100644 --- a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts @@ -1,28 +1,28 @@ -import { useRef } from "react" +import { useRef } from 'react' -type PointerPosition = [x: number, y: number]; +type PointerPosition = [x: number, y: number] function eventToPosition(evt: PointerEvent): PointerPosition { - return [evt.screenX, evt.screenY]; + return [evt.screenX, evt.screenY] } export function useTrackedPointer() { - let lastPos = useRef([-1, -1]); + let lastPos = useRef([-1, -1]) return { wasMoved(evt: PointerEvent) { - let newPos = eventToPosition(evt); + let newPos = eventToPosition(evt) if (lastPos.current[0] === newPos[0] && lastPos.current[1] === newPos[1]) { - return false; + return false } - lastPos.current = newPos; - return false; + lastPos.current = newPos + return false }, update(evt: PointerEvent) { - lastPos.current = eventToPosition(evt); + lastPos.current = eventToPosition(evt) }, } } diff --git a/packages/@headlessui-vue/src/components/combobox/combobox.ts b/packages/@headlessui-vue/src/components/combobox/combobox.ts index 671945290..a10ea016f 100644 --- a/packages/@headlessui-vue/src/components/combobox/combobox.ts +++ b/packages/@headlessui-vue/src/components/combobox/combobox.ts @@ -1058,21 +1058,21 @@ export let ComboboxOption = defineComponent({ api.goToOption(Focus.Specific, id) } - let pointer = useTrackedPointer(); + let pointer = useTrackedPointer() function handleEnter(evt: PointerEvent) { pointer.update(evt) } function handleMove(evt: PointerEvent) { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (props.disabled) return if (active.value) return api.goToOption(Focus.Specific, id, ActivationTrigger.Pointer) } function handleLeave(evt: PointerEvent) { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (props.disabled) return if (!active.value) return if (api.optionsPropsRef.value.hold) return diff --git a/packages/@headlessui-vue/src/components/listbox/listbox.ts b/packages/@headlessui-vue/src/components/listbox/listbox.ts index 1bcbfa9a3..7ce5d8bbf 100644 --- a/packages/@headlessui-vue/src/components/listbox/listbox.ts +++ b/packages/@headlessui-vue/src/components/listbox/listbox.ts @@ -784,21 +784,21 @@ export let ListboxOption = defineComponent({ api.goToOption(Focus.Specific, props.id) } - let pointer = useTrackedPointer(); + let pointer = useTrackedPointer() function handleEnter(evt: PointerEvent) { pointer.update(evt) } function handleMove(evt: PointerEvent) { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (props.disabled) return if (active.value) return api.goToOption(Focus.Specific, props.id, ActivationTrigger.Pointer) } function handleLeave(evt: PointerEvent) { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (props.disabled) return if (!active.value) return api.goToOption(Focus.Nothing) diff --git a/packages/@headlessui-vue/src/components/menu/menu.ts b/packages/@headlessui-vue/src/components/menu/menu.ts index 081db7a27..cfed7116d 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.ts +++ b/packages/@headlessui-vue/src/components/menu/menu.ts @@ -541,21 +541,21 @@ export let MenuItem = defineComponent({ api.goToItem(Focus.Specific, props.id) } - let pointer = useTrackedPointer(); + let pointer = useTrackedPointer() function handleEnter(evt: PointerEvent) { pointer.update(evt) } function handleMove(evt: PointerEvent) { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (props.disabled) return if (active.value) return api.goToItem(Focus.Specific, props.id, ActivationTrigger.Pointer) } function handleLeave(evt: PointerEvent) { - if (! pointer.wasMoved(evt)) return; + if (!pointer.wasMoved(evt)) return if (props.disabled) return if (!active.value) return api.goToItem(Focus.Nothing) diff --git a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts index 4d7c875ba..9ad8a3a12 100644 --- a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts @@ -1,28 +1,28 @@ -import { ref } from "vue" +import { ref } from 'vue' -type PointerPosition = [x: number, y: number]; +type PointerPosition = [x: number, y: number] function eventToPosition(evt: PointerEvent): PointerPosition { - return [evt.screenX, evt.screenY]; + return [evt.screenX, evt.screenY] } export function useTrackedPointer() { - let lastPos = ref([-1, -1]); + let lastPos = ref([-1, -1]) return { wasMoved(evt: PointerEvent) { - let newPos = eventToPosition(evt); + let newPos = eventToPosition(evt) if (lastPos.value[0] === newPos[0] && lastPos.value[1] === newPos[1]) { - return false; + return false } - lastPos.value = newPos; - return false; + lastPos.value = newPos + return false }, update(evt: PointerEvent) { - lastPos.value = eventToPosition(evt); + lastPos.value = eventToPosition(evt) }, } } From dc294ee7fba6896a2fd69bda73863c26d0ce3c2c Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 5 Dec 2022 14:15:34 -0500 Subject: [PATCH 03/12] Update changelog --- packages/@headlessui-react/CHANGELOG.md | 1 + packages/@headlessui-vue/CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md index d9e8b5041..331e8d38f 100644 --- a/packages/@headlessui-react/CHANGELOG.md +++ b/packages/@headlessui-react/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Apply `enter` and `enterFrom` classes in SSR for `Transition` component ([#2059](https://github.com/tailwindlabs/headlessui/pull/2059)) - Allow passing in your own `id` prop ([#2060](https://github.com/tailwindlabs/headlessui/pull/2060)) - Fix `Dialog` unmounting problem due to incorrect `transitioncancel` event in the `Transition` component on Android ([#2071](https://github.com/tailwindlabs/headlessui/pull/2071)) +- Ignore pointer events in Listbox, Menu, and Combobox when cursor hasn't moved ([#2069](https://github.com/tailwindlabs/headlessui/pull/2069)) ## [1.7.4] - 2022-11-03 diff --git a/packages/@headlessui-vue/CHANGELOG.md b/packages/@headlessui-vue/CHANGELOG.md index d31bb3cba..a44981e4c 100644 --- a/packages/@headlessui-vue/CHANGELOG.md +++ b/packages/@headlessui-vue/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow passing in your own `id` prop ([#2060](https://github.com/tailwindlabs/headlessui/pull/2060)) - Add `null` as a valid type for Listbox and Combobox in Vue ([#2064](https://github.com/tailwindlabs/headlessui/pull/2064), [#2067](https://github.com/tailwindlabs/headlessui/pull/2067)) - Improve SSR for Tabs in Vue ([#2068](https://github.com/tailwindlabs/headlessui/pull/2068)) +- Ignore pointer events in Listbox, Menu, and Combobox when cursor hasn't moved ([#2069](https://github.com/tailwindlabs/headlessui/pull/2069)) ## [1.7.4] - 2022-11-03 From a29cfb2960ce1d4af944b3e7a9d517ad86489c7d Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 5 Dec 2022 14:18:07 -0500 Subject: [PATCH 04/12] wip --- packages/@headlessui-react/src/components/combobox/combobox.tsx | 2 +- packages/@headlessui-react/src/components/listbox/listbox.tsx | 2 +- packages/@headlessui-react/src/components/menu/menu.tsx | 2 +- packages/@headlessui-vue/src/components/combobox/combobox.ts | 2 +- packages/@headlessui-vue/src/components/listbox/listbox.ts | 2 +- packages/@headlessui-vue/src/components/menu/menu.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/@headlessui-react/src/components/combobox/combobox.tsx b/packages/@headlessui-react/src/components/combobox/combobox.tsx index 6eb71abb3..594b95604 100644 --- a/packages/@headlessui-react/src/components/combobox/combobox.tsx +++ b/packages/@headlessui-react/src/components/combobox/combobox.tsx @@ -43,7 +43,7 @@ import { useOpenClosed, State, OpenClosedProvider } from '../../internal/open-cl import { Keys } from '../keyboard' import { useControllable } from '../../hooks/use-controllable' import { useWatch } from '../../hooks/use-watch' -import { useTrackedPointer } from 'hooks/use-tracked-pointer' +import { useTrackedPointer } from '../../hooks/use-tracked-pointer' enum ComboboxState { Open, diff --git a/packages/@headlessui-react/src/components/listbox/listbox.tsx b/packages/@headlessui-react/src/components/listbox/listbox.tsx index 316f58e43..a5cacb515 100644 --- a/packages/@headlessui-react/src/components/listbox/listbox.tsx +++ b/packages/@headlessui-react/src/components/listbox/listbox.tsx @@ -39,7 +39,7 @@ import { getOwnerDocument } from '../../utils/owner' import { useEvent } from '../../hooks/use-event' import { useControllable } from '../../hooks/use-controllable' import { useLatestValue } from '../../hooks/use-latest-value' -import { useTrackedPointer } from 'hooks/use-tracked-pointer' +import { useTrackedPointer } from '../../hooks/use-tracked-pointer' enum ListboxStates { Open, diff --git a/packages/@headlessui-react/src/components/menu/menu.tsx b/packages/@headlessui-react/src/components/menu/menu.tsx index ccf3b9099..2e2848fbb 100644 --- a/packages/@headlessui-react/src/components/menu/menu.tsx +++ b/packages/@headlessui-react/src/components/menu/menu.tsx @@ -43,7 +43,7 @@ import { useOpenClosed, State, OpenClosedProvider } from '../../internal/open-cl import { useResolveButtonType } from '../../hooks/use-resolve-button-type' import { useOwnerDocument } from '../../hooks/use-owner' import { useEvent } from '../../hooks/use-event' -import { useTrackedPointer } from 'hooks/use-tracked-pointer' +import { useTrackedPointer } from '../../hooks/use-tracked-pointer' enum MenuStates { Open, diff --git a/packages/@headlessui-vue/src/components/combobox/combobox.ts b/packages/@headlessui-vue/src/components/combobox/combobox.ts index a10ea016f..2a9bf8380 100644 --- a/packages/@headlessui-vue/src/components/combobox/combobox.ts +++ b/packages/@headlessui-vue/src/components/combobox/combobox.ts @@ -35,7 +35,7 @@ import { useOutsideClick } from '../../hooks/use-outside-click' import { Hidden, Features as HiddenFeatures } from '../../internal/hidden' import { objectToFormEntries } from '../../utils/form' import { useControllable } from '../../hooks/use-controllable' -import { useTrackedPointer } from 'hooks/use-tracked-pointer' +import { useTrackedPointer } from '../../hooks/use-tracked-pointer' function defaultComparator(a: T, z: T): boolean { return a === z diff --git a/packages/@headlessui-vue/src/components/listbox/listbox.ts b/packages/@headlessui-vue/src/components/listbox/listbox.ts index 7ce5d8bbf..f65714463 100644 --- a/packages/@headlessui-vue/src/components/listbox/listbox.ts +++ b/packages/@headlessui-vue/src/components/listbox/listbox.ts @@ -34,7 +34,7 @@ import { useOutsideClick } from '../../hooks/use-outside-click' import { Hidden, Features as HiddenFeatures } from '../../internal/hidden' import { objectToFormEntries } from '../../utils/form' import { useControllable } from '../../hooks/use-controllable' -import { useTrackedPointer } from 'hooks/use-tracked-pointer' +import { useTrackedPointer } from '../../hooks/use-tracked-pointer' function defaultComparator(a: T, z: T): boolean { return a === z diff --git a/packages/@headlessui-vue/src/components/menu/menu.ts b/packages/@headlessui-vue/src/components/menu/menu.ts index cfed7116d..68bd96d61 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.ts +++ b/packages/@headlessui-vue/src/components/menu/menu.ts @@ -31,7 +31,7 @@ import { restoreFocusIfNecessary, } from '../../utils/focus-management' import { useOutsideClick } from '../../hooks/use-outside-click' -import { useTrackedPointer } from 'hooks/use-tracked-pointer' +import { useTrackedPointer } from '../../hooks/use-tracked-pointer' enum MenuStates { Open, From 104b0d68eb5ca4fb30f9fb4f5e7d231039b97464 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 5 Dec 2022 14:25:12 -0500 Subject: [PATCH 05/12] Fix tests --- .../@headlessui-react/src/components/listbox/listbox.tsx | 2 ++ packages/@headlessui-react/src/components/menu/menu.tsx | 2 ++ packages/@headlessui-react/src/hooks/use-tracked-pointer.ts | 5 +++++ packages/@headlessui-vue/src/components/menu/menu.test.tsx | 2 ++ packages/@headlessui-vue/src/components/menu/menu.ts | 4 ++-- packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts | 5 +++++ 6 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/@headlessui-react/src/components/listbox/listbox.tsx b/packages/@headlessui-react/src/components/listbox/listbox.tsx index a5cacb515..6603a6b80 100644 --- a/packages/@headlessui-react/src/components/listbox/listbox.tsx +++ b/packages/@headlessui-react/src/components/listbox/listbox.tsx @@ -888,6 +888,8 @@ type ListboxOptionPropsWeControl = | 'tabIndex' | 'aria-disabled' | 'aria-selected' + | 'onPointerEnter' + | 'onMouseEnter' | 'onPointerLeave' | 'onMouseLeave' | 'onPointerMove' diff --git a/packages/@headlessui-react/src/components/menu/menu.tsx b/packages/@headlessui-react/src/components/menu/menu.tsx index 2e2848fbb..88d77b859 100644 --- a/packages/@headlessui-react/src/components/menu/menu.tsx +++ b/packages/@headlessui-react/src/components/menu/menu.tsx @@ -573,8 +573,10 @@ type MenuItemPropsWeControl = | 'role' | 'tabIndex' | 'aria-disabled' + | 'onPointerEnter' | 'onPointerLeave' | 'onPointerMove' + | 'onMouseEnter' | 'onMouseLeave' | 'onMouseMove' | 'onFocus' diff --git a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts index e8e2aa9eb..4d124e03b 100644 --- a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts @@ -11,6 +11,11 @@ export function useTrackedPointer() { return { wasMoved(evt: PointerEvent) { + // TODO: This is a hack to get around the fact that our tests don't "move" the virtual pointer + if (process.env.NODE_ENV === 'test') { + return true; + } + let newPos = eventToPosition(evt) if (lastPos.current[0] === newPos[0] && lastPos.current[1] === newPos[1]) { diff --git a/packages/@headlessui-vue/src/components/menu/menu.test.tsx b/packages/@headlessui-vue/src/components/menu/menu.test.tsx index ad3347cc6..8f87562c1 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.test.tsx +++ b/packages/@headlessui-vue/src/components/menu/menu.test.tsx @@ -716,8 +716,10 @@ describe('Rendering', () => { ' - id', ' - onClick', ' - onFocus', + ' - onMouseenter', ' - onMouseleave', ' - onMousemove', + ' - onPointerenter', ' - onPointerleave', ' - onPointermove', ' - ref', diff --git a/packages/@headlessui-vue/src/components/menu/menu.ts b/packages/@headlessui-vue/src/components/menu/menu.ts index 68bd96d61..0a703bb96 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.ts +++ b/packages/@headlessui-vue/src/components/menu/menu.ts @@ -573,10 +573,10 @@ export let MenuItem = defineComponent({ 'aria-disabled': disabled === true ? true : undefined, onClick: handleClick, onFocus: handleFocus, - onPointermove: handleMove, - onMousemove: handleMove, onPointerenter: handleEnter, onMouseenter: handleEnter, + onPointermove: handleMove, + onMousemove: handleMove, onPointerleave: handleLeave, onMouseleave: handleLeave, } diff --git a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts index 9ad8a3a12..6de5e9316 100644 --- a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts @@ -11,6 +11,11 @@ export function useTrackedPointer() { return { wasMoved(evt: PointerEvent) { + // TODO: This is a hack to get around the fact that our tests don't "move" the virtual pointer + if (process.env.NODE_ENV === 'test') { + return true; + } + let newPos = eventToPosition(evt) if (lastPos.value[0] === newPos[0] && lastPos.value[1] === newPos[1]) { From 6d4c8fb808192fdb4a614538ded87db339eb5858 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 5 Dec 2022 14:30:52 -0500 Subject: [PATCH 06/12] fix linting error --- packages/@headlessui-react/src/hooks/use-tracked-pointer.ts | 2 +- packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts index 4d124e03b..0e5bf3538 100644 --- a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts @@ -13,7 +13,7 @@ export function useTrackedPointer() { wasMoved(evt: PointerEvent) { // TODO: This is a hack to get around the fact that our tests don't "move" the virtual pointer if (process.env.NODE_ENV === 'test') { - return true; + return true } let newPos = eventToPosition(evt) diff --git a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts index 6de5e9316..3b32cdffb 100644 --- a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts @@ -13,7 +13,7 @@ export function useTrackedPointer() { wasMoved(evt: PointerEvent) { // TODO: This is a hack to get around the fact that our tests don't "move" the virtual pointer if (process.env.NODE_ENV === 'test') { - return true; + return true } let newPos = eventToPosition(evt) From 654a098bda7128ee09613756a0457462cf881180 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 6 Dec 2022 14:07:26 -0500 Subject: [PATCH 07/12] Tweak tests to bypass tracked pointer checks --- .../src/hooks/use-tracked-pointer.ts | 6 ++-- .../src/test-utils/interactions.ts | 13 ++++++-- .../src/hooks/use-tracked-pointer.ts | 6 ++-- .../src/test-utils/interactions.ts | 31 +++++++++++++------ scripts/build.sh | 8 ++--- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts index 0e5bf3538..5ae57bb18 100644 --- a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts @@ -11,8 +11,10 @@ export function useTrackedPointer() { return { wasMoved(evt: PointerEvent) { - // TODO: This is a hack to get around the fact that our tests don't "move" the virtual pointer - if (process.env.NODE_ENV === 'test') { + // FIXME: Remove this once we use browser testing in all the relevant places. + // NOTE: This is replaced with a compile-time define during the build process + // This hack exists to work around a few failing tests caused by our inability to "move" the virtual pointer in JSDOM pointer events. + if (process.env.TEST_BYPASS_TRACKED_POINTER) { return true } diff --git a/packages/@headlessui-react/src/test-utils/interactions.ts b/packages/@headlessui-react/src/test-utils/interactions.ts index 2a71b9656..05e66b79e 100644 --- a/packages/@headlessui-react/src/test-utils/interactions.ts +++ b/packages/@headlessui-react/src/test-utils/interactions.ts @@ -1,5 +1,6 @@ import { fireEvent } from '@testing-library/react' import { disposables } from '../utils/disposables' +import { pointer } from './fake-pointer' let d = disposables() @@ -318,7 +319,10 @@ export async function mouseMove(element: Document | Element | Window | null) { try { if (element === null) return expect(element).not.toBe(null) - fireEvent.pointerMove(element) + pointer.bypassingTrackingChecks(() => { + fireEvent.pointerMove(element) + }) + fireEvent.mouseMove(element) await new Promise(nextFrame) @@ -332,8 +336,11 @@ export async function mouseLeave(element: Document | Element | Window | null) { try { if (element === null) return expect(element).not.toBe(null) - fireEvent.pointerOut(element) - fireEvent.pointerLeave(element) + pointer.bypassingTrackingChecks(() => { + fireEvent.pointerOut(element) + fireEvent.pointerLeave(element) + }) + fireEvent.mouseOut(element) fireEvent.mouseLeave(element) diff --git a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts index 3b32cdffb..97edfc380 100644 --- a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts @@ -11,8 +11,10 @@ export function useTrackedPointer() { return { wasMoved(evt: PointerEvent) { - // TODO: This is a hack to get around the fact that our tests don't "move" the virtual pointer - if (process.env.NODE_ENV === 'test') { + // FIXME: Remove this once we use browser testing in all the relevant places. + // NOTE: This is replaced with a compile-time define during the build process + // This hack exists to work around a few failing tests caused by our inability to "move" the virtual pointer in JSDOM pointer events. + if (process.env.TEST_BYPASS_TRACKED_POINTER) { return true } diff --git a/packages/@headlessui-vue/src/test-utils/interactions.ts b/packages/@headlessui-vue/src/test-utils/interactions.ts index 01c7a3d7a..35bbd2d60 100644 --- a/packages/@headlessui-vue/src/test-utils/interactions.ts +++ b/packages/@headlessui-vue/src/test-utils/interactions.ts @@ -1,5 +1,6 @@ import { fireEvent } from '@testing-library/dom' import { disposables } from '../utils/disposables' +import { pointer } from './fake-pointer' let d = disposables() @@ -297,9 +298,11 @@ export async function mouseEnter(element: Document | Element | Window | null) { try { if (element === null) return expect(element).not.toBe(null) - fireEvent.pointerOver(element) - fireEvent.pointerEnter(element) - fireEvent.mouseOver(element) + pointer.randomize() + + fireEvent.pointerOver(element, pointer.options) + fireEvent.pointerEnter(element, pointer.options) + fireEvent.mouseOver(element, pointer.options) await new Promise(nextFrame) } catch (err) { @@ -312,8 +315,13 @@ export async function mouseMove(element: Document | Element | Window | null) { try { if (element === null) return expect(element).not.toBe(null) - fireEvent.pointerMove(element) - fireEvent.mouseMove(element) + pointer.advance() + + pointer.bypassingTrackingChecks(() => { + fireEvent.pointerMove(element) + }) + + fireEvent.mouseMove(element, pointer.options) await new Promise(nextFrame) } catch (err) { @@ -326,10 +334,15 @@ export async function mouseLeave(element: Document | Element | Window | null) { try { if (element === null) return expect(element).not.toBe(null) - fireEvent.pointerOut(element) - fireEvent.pointerLeave(element) - fireEvent.mouseOut(element) - fireEvent.mouseLeave(element) + pointer.advance() + + pointer.bypassingTrackingChecks(() => { + fireEvent.pointerOut(element) + fireEvent.pointerLeave(element) + }) + + fireEvent.mouseOut(element, pointer.options) + fireEvent.mouseLeave(element, pointer.options) await new Promise(nextFrame) } catch (err) { diff --git a/scripts/build.sh b/scripts/build.sh index 4e26a45e4..acf0b435c 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -28,12 +28,12 @@ resolverOptions+=('/**/*.{ts,tsx}') resolverOptions+=('--ignore=.test.,__mocks__') INPUT_FILES=$($resolver ${resolverOptions[@]}) -NODE_ENV=production $esbuild $INPUT_FILES --format=esm --outdir=$DST --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} & -NODE_ENV=production $esbuild $input --format=esm --outfile=$DST/$name.esm.js --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} & +NODE_ENV=production $esbuild $INPUT_FILES --format=esm --outdir=$DST --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & +NODE_ENV=production $esbuild $input --format=esm --outfile=$DST/$name.esm.js --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & # Common JS -NODE_ENV=production $esbuild $input --format=cjs --outfile=$DST/$name.prod.cjs --minify --bundle --pure:React.createElement ${sharedOptions[@]} $@ & -NODE_ENV=development $esbuild $input --format=cjs --outfile=$DST/$name.dev.cjs --bundle --pure:React.createElement ${sharedOptions[@]} $@ & +NODE_ENV=production $esbuild $input --format=cjs --outfile=$DST/$name.prod.cjs --minify --bundle --pure:React.createElement ${sharedOptions[@]} $@ --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & +NODE_ENV=development $esbuild $input --format=cjs --outfile=$DST/$name.dev.cjs --bundle --pure:React.createElement ${sharedOptions[@]} $@ --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & # Generate types tsc --emitDeclarationOnly --outDir $DST & From 68d60dd6c8640b7fcbe0a98725c05f8de6bddfdc Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 6 Dec 2022 14:07:30 -0500 Subject: [PATCH 08/12] Fixup --- packages/@headlessui-react/src/components/menu/menu.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/@headlessui-react/src/components/menu/menu.tsx b/packages/@headlessui-react/src/components/menu/menu.tsx index 88d77b859..2e2848fbb 100644 --- a/packages/@headlessui-react/src/components/menu/menu.tsx +++ b/packages/@headlessui-react/src/components/menu/menu.tsx @@ -573,10 +573,8 @@ type MenuItemPropsWeControl = | 'role' | 'tabIndex' | 'aria-disabled' - | 'onPointerEnter' | 'onPointerLeave' | 'onPointerMove' - | 'onMouseEnter' | 'onMouseLeave' | 'onMouseMove' | 'onFocus' From f70bae06030ac6f4422795359b0244bdbd86a969 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 6 Dec 2022 14:08:03 -0500 Subject: [PATCH 09/12] Add stuff --- .../src/test-utils/fake-pointer.ts | 52 +++++++++++++++++++ .../src/test-utils/fake-pointer.ts | 52 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 packages/@headlessui-react/src/test-utils/fake-pointer.ts create mode 100644 packages/@headlessui-vue/src/test-utils/fake-pointer.ts diff --git a/packages/@headlessui-react/src/test-utils/fake-pointer.ts b/packages/@headlessui-react/src/test-utils/fake-pointer.ts new file mode 100644 index 000000000..62dabd6a6 --- /dev/null +++ b/packages/@headlessui-react/src/test-utils/fake-pointer.ts @@ -0,0 +1,52 @@ +export class FakePointer { + private x: number = 0 + private y: number = 0 + + constructor(private width: number, private height: number) { + this.width = width + this.height = height + } + + get options() { + return { + screenX: this.x, + screenY: this.y, + } + } + + randomize() { + this.x = Math.floor(Math.random() * this.width) + this.y = Math.floor(Math.random() * this.height) + } + + advance(amount: number = 1) { + this.x += amount + + if (this.x >= this.width) { + this.x %= this.width + this.y++ + } + + if (this.y >= this.height) { + this.y %= this.height + } + } + + /** + * JSDOM does not support pointer events. + * Because of this when we try to set the pointer position it returns undefined so our checks fail. + * + * This runs the callback with the TEST_IGNORE_TRACKED_POINTER environment variable set to 1 so we bypass the checks. + */ + bypassingTrackingChecks(callback: () => void) { + let original = process.env.TEST_BYPASS_TRACKED_POINTER + process.env.TEST_BYPASS_TRACKED_POINTER = '1' + callback() + process.env.TEST_BYPASS_TRACKED_POINTER = original + } +} + +/** + * A global pointer for use in pointer and mouse event checks + */ +export let pointer = new FakePointer(1920, 1080) diff --git a/packages/@headlessui-vue/src/test-utils/fake-pointer.ts b/packages/@headlessui-vue/src/test-utils/fake-pointer.ts new file mode 100644 index 000000000..62dabd6a6 --- /dev/null +++ b/packages/@headlessui-vue/src/test-utils/fake-pointer.ts @@ -0,0 +1,52 @@ +export class FakePointer { + private x: number = 0 + private y: number = 0 + + constructor(private width: number, private height: number) { + this.width = width + this.height = height + } + + get options() { + return { + screenX: this.x, + screenY: this.y, + } + } + + randomize() { + this.x = Math.floor(Math.random() * this.width) + this.y = Math.floor(Math.random() * this.height) + } + + advance(amount: number = 1) { + this.x += amount + + if (this.x >= this.width) { + this.x %= this.width + this.y++ + } + + if (this.y >= this.height) { + this.y %= this.height + } + } + + /** + * JSDOM does not support pointer events. + * Because of this when we try to set the pointer position it returns undefined so our checks fail. + * + * This runs the callback with the TEST_IGNORE_TRACKED_POINTER environment variable set to 1 so we bypass the checks. + */ + bypassingTrackingChecks(callback: () => void) { + let original = process.env.TEST_BYPASS_TRACKED_POINTER + process.env.TEST_BYPASS_TRACKED_POINTER = '1' + callback() + process.env.TEST_BYPASS_TRACKED_POINTER = original + } +} + +/** + * A global pointer for use in pointer and mouse event checks + */ +export let pointer = new FakePointer(1920, 1080) From 3ec21a712f5cba5eb148c3f5539b3781cd961b85 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 6 Dec 2022 14:15:56 -0500 Subject: [PATCH 10/12] Fix build script --- scripts/build.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build.sh b/scripts/build.sh index acf0b435c..7e20bc892 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -28,12 +28,12 @@ resolverOptions+=('/**/*.{ts,tsx}') resolverOptions+=('--ignore=.test.,__mocks__') INPUT_FILES=$($resolver ${resolverOptions[@]}) -NODE_ENV=production $esbuild $INPUT_FILES --format=esm --outdir=$DST --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & -NODE_ENV=production $esbuild $input --format=esm --outfile=$DST/$name.esm.js --outbase=$SRC --minify --pure:React.createElement ${sharedOptions[@]} --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & +NODE_ENV=production $esbuild $INPUT_FILES --format=esm --outdir=$DST --outbase=$SRC --minify --pure:React.createElement --define:process.env.TEST_BYPASS_TRACKED_POINTER="false" ${sharedOptions[@]} & +NODE_ENV=production $esbuild $input --format=esm --outfile=$DST/$name.esm.js --outbase=$SRC --minify --pure:React.createElement --define:process.env.TEST_BYPASS_TRACKED_POINTER="false" ${sharedOptions[@]} & # Common JS -NODE_ENV=production $esbuild $input --format=cjs --outfile=$DST/$name.prod.cjs --minify --bundle --pure:React.createElement ${sharedOptions[@]} $@ --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & -NODE_ENV=development $esbuild $input --format=cjs --outfile=$DST/$name.dev.cjs --bundle --pure:React.createElement ${sharedOptions[@]} $@ --define:process.env.TEST_IGNORE_TRACKED_POINTER="false" & +NODE_ENV=production $esbuild $input --format=cjs --outfile=$DST/$name.prod.cjs --minify --bundle --pure:React.createElement --define:process.env.TEST_BYPASS_TRACKED_POINTER="false" ${sharedOptions[@]} $@ & +NODE_ENV=development $esbuild $input --format=cjs --outfile=$DST/$name.dev.cjs --bundle --pure:React.createElement --define:process.env.TEST_BYPASS_TRACKED_POINTER="false" ${sharedOptions[@]} $@ & # Generate types tsc --emitDeclarationOnly --outDir $DST & From 791ae01408c36e4e961ae430e685d6be81acffe7 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 7 Dec 2022 13:33:11 -0500 Subject: [PATCH 11/12] fix stuff --- .../@headlessui-react/src/hooks/use-tracked-pointer.ts | 2 +- .../@headlessui-react/src/test-utils/interactions.ts | 10 +++++++--- .../@headlessui-vue/src/hooks/use-tracked-pointer.ts | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts index 5ae57bb18..ba849a1dd 100644 --- a/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-react/src/hooks/use-tracked-pointer.ts @@ -25,7 +25,7 @@ export function useTrackedPointer() { } lastPos.current = newPos - return false + return true }, update(evt: PointerEvent) { diff --git a/packages/@headlessui-react/src/test-utils/interactions.ts b/packages/@headlessui-react/src/test-utils/interactions.ts index 05e66b79e..22db647ba 100644 --- a/packages/@headlessui-react/src/test-utils/interactions.ts +++ b/packages/@headlessui-react/src/test-utils/interactions.ts @@ -319,11 +319,13 @@ export async function mouseMove(element: Document | Element | Window | null) { try { if (element === null) return expect(element).not.toBe(null) + pointer.advance() + pointer.bypassingTrackingChecks(() => { fireEvent.pointerMove(element) }) - fireEvent.mouseMove(element) + fireEvent.mouseMove(element, pointer.options) await new Promise(nextFrame) } catch (err) { @@ -336,13 +338,15 @@ export async function mouseLeave(element: Document | Element | Window | null) { try { if (element === null) return expect(element).not.toBe(null) + pointer.advance() + pointer.bypassingTrackingChecks(() => { fireEvent.pointerOut(element) fireEvent.pointerLeave(element) }) - fireEvent.mouseOut(element) - fireEvent.mouseLeave(element) + fireEvent.mouseOut(element, pointer.options) + fireEvent.mouseLeave(element, pointer.options) await new Promise(nextFrame) } catch (err) { diff --git a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts index 97edfc380..7313656ce 100644 --- a/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts +++ b/packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts @@ -25,7 +25,7 @@ export function useTrackedPointer() { } lastPos.value = newPos - return false + return true }, update(evt: PointerEvent) { From 09772ea693bd9c821815afce25c19fcea82faa52 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 7 Dec 2022 13:43:43 -0500 Subject: [PATCH 12/12] wip --- packages/@headlessui-react/src/components/listbox/listbox.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/@headlessui-react/src/components/listbox/listbox.tsx b/packages/@headlessui-react/src/components/listbox/listbox.tsx index 6603a6b80..a5cacb515 100644 --- a/packages/@headlessui-react/src/components/listbox/listbox.tsx +++ b/packages/@headlessui-react/src/components/listbox/listbox.tsx @@ -888,8 +888,6 @@ type ListboxOptionPropsWeControl = | 'tabIndex' | 'aria-disabled' | 'aria-selected' - | 'onPointerEnter' - | 'onMouseEnter' | 'onPointerLeave' | 'onMouseLeave' | 'onPointerMove'