Skip to content

Commit

Permalink
Fix change event incorrectly getting called on blur (#2296)
Browse files Browse the repository at this point in the history
* drop `d.enqueue` & `d.workQueue`

This was only used in tests and doesn't seem to be necessary.

* drop `handleChange` from the `ComboboxInput` component

This only emitted a `change` event, which Vue already emits as well.

* drop `onChange` from incoming props

This is an odd one. In Chrome this means that the `@change` is still
being called, but if we keep it, then the `@change` is _also_ called on
blur resulting in odd bugs.

Droping it fixes that issue.

That said, the `@change` is _still_ emitted and therefore the callback
is properly called and the `ComboboxInput` still can interact with the
`@change` event.

* update changelog
  • Loading branch information
RobinMalfait authored Feb 21, 2023
1 parent b8c214e commit 569cec7
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 48 deletions.
16 changes: 6 additions & 10 deletions packages/@headlessui-react/src/test-utils/interactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,13 @@ export function shift(event: Partial<KeyboardEvent>) {
export function word(input: string): Partial<KeyboardEvent>[] {
let result = input.split('').map((key) => ({ key }))

d.enqueue(() => {
let element = document.activeElement
let element = document.activeElement

if (element instanceof HTMLInputElement) {
fireEvent.change(element, {
target: Object.assign({}, element, { value: input }),
})
}
})
if (element instanceof HTMLInputElement) {
fireEvent.change(element, {
target: Object.assign({}, element, { value: input }),
})
}

return result
}
Expand Down Expand Up @@ -209,8 +207,6 @@ export async function type(events: Partial<KeyboardEvent>[], element = document.
// We don't want to actually wait in our tests, so let's advance
jest.runAllTimers()

await d.workQueue()

await new Promise(nextFrame)
} catch (err) {
if (err instanceof Error) Error.captureStackTrace(err, type)
Expand Down
11 changes: 0 additions & 11 deletions packages/@headlessui-react/src/utils/disposables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@ export type Disposables = ReturnType<typeof disposables>

export function disposables() {
let disposables: Function[] = []
let queue: Function[] = []

let api = {
enqueue(fn: Function) {
queue.push(fn)
},

addEventListener<TEventName extends keyof WindowEventMap>(
element: HTMLElement | Window | Document,
name: TEventName,
Expand Down Expand Up @@ -66,12 +61,6 @@ export function disposables() {
}
},

async workQueue() {
for (let handle of queue.splice(0)) {
await handle()
}
},

style(node: HTMLElement, property: string, value: string) {
let previous = node.style.getPropertyValue(property)
Object.assign(node.style, { [property]: value })
Expand Down
1 change: 1 addition & 0 deletions packages/@headlessui-vue/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Ensure the main tree and parent `Dialog` components are marked as `inert` ([#2290](https://github.com/tailwindlabs/headlessui/pull/2290))
- Fix nested `Popover` components not opening ([#2293](https://github.com/tailwindlabs/headlessui/pull/2293))
- Fix `change` event incorrectly getting called on `blur` ([#2296](https://github.com/tailwindlabs/headlessui/pull/2296))

## [1.7.10] - 2023-02-15

Expand Down
7 changes: 1 addition & 6 deletions packages/@headlessui-vue/src/components/combobox/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -888,10 +888,6 @@ export let ComboboxInput = defineComponent({
}
}

function handleChange(event: Event & { target: HTMLInputElement }) {
emit('change', event)
}

function handleInput(event: Event & { target: HTMLInputElement }) {
api.openCombobox()
emit('change', event)
Expand All @@ -914,7 +910,7 @@ export let ComboboxInput = defineComponent({

return () => {
let slot = { open: api.comboboxState.value === ComboboxStates.Open }
let { id, displayValue, ...theirProps } = props
let { id, displayValue, onChange: _onChange, ...theirProps } = props
let ourProps = {
'aria-controls': api.optionsRef.value?.id,
'aria-expanded': api.disabled.value
Expand All @@ -930,7 +926,6 @@ export let ComboboxInput = defineComponent({
onCompositionstart: handleCompositionstart,
onCompositionend: handleCompositionend,
onKeydown: handleKeyDown,
onChange: handleChange,
onInput: handleInput,
onBlur: handleBlur,
role: 'combobox',
Expand Down
16 changes: 6 additions & 10 deletions packages/@headlessui-vue/src/test-utils/interactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@ export function shift(event: Partial<KeyboardEvent>) {
export function word(input: string): Partial<KeyboardEvent>[] {
let result = input.split('').map((key) => ({ key }))

d.enqueue(() => {
let element = document.activeElement
let element = document.activeElement

if (element instanceof HTMLInputElement) {
fireEvent.change(element, {
target: Object.assign({}, element, { value: input }),
})
}
})
if (element instanceof HTMLInputElement) {
fireEvent.change(element, {
target: Object.assign({}, element, { value: input }),
})
}

return result
}
Expand Down Expand Up @@ -207,8 +205,6 @@ export async function type(events: Partial<KeyboardEvent>[], element = document.
// We don't want to actually wait in our tests, so let's advance
jest.runAllTimers()

await d.workQueue()

await new Promise(nextFrame)
} catch (err) {
if (err instanceof Error) Error.captureStackTrace(err, type)
Expand Down
11 changes: 0 additions & 11 deletions packages/@headlessui-vue/src/utils/disposables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@ export type Disposables = ReturnType<typeof disposables>

export function disposables() {
let disposables: Function[] = []
let queue: Function[] = []

let api = {
enqueue(fn: Function) {
queue.push(fn)
},

addEventListener<TEventName extends keyof WindowEventMap>(
element: HTMLElement | Window | Document,
name: TEventName,
Expand Down Expand Up @@ -52,12 +47,6 @@ export function disposables() {
dispose()
}
},

async workQueue() {
for (let handle of queue.splice(0)) {
await handle()
}
},
}

return api
Expand Down

0 comments on commit 569cec7

Please sign in to comment.