Skip to content

Commit

Permalink
fix(Combobox): stop event propagation on enter (#1279)
Browse files Browse the repository at this point in the history
* fix(Combobox): stop propagation of enter when user makes a selection via keyboard in combobox

* fix: test for event bubbling instead of form submit
  • Loading branch information
ragulka authored Sep 17, 2024
1 parent 3f0f965 commit ff5abb0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
28 changes: 28 additions & 0 deletions packages/radix-vue/src/Combobox/Combobox.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,19 @@ describe('given combobox in a form', async () => {
props: { handleSubmit },
})

const valueBox = wrapper.find('input')

let enterEventBubbledToForm = false

beforeEach(() => {
enterEventBubbledToForm = false
wrapper.find('form').element.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
enterEventBubbledToForm = true
}
})
})

it('should have hidden input field', async () => {
expect(wrapper.find('[type="hidden"]').exists()).toBe(true)
})
Expand Down Expand Up @@ -327,6 +340,21 @@ describe('given combobox in a form', async () => {
expect(handleSubmit.mock.results[1].value).toStrictEqual({ test: 'Pineapple' })
})
})

describe('after selecting an option via keyboard', () => {
beforeEach(async () => {
await valueBox.setValue('B')
await valueBox.trigger('keydown', { key: 'Enter' })
})

it('should show value correctly', () => {
expect((valueBox.element).value).toBe('Banana')
})

it('should bubble up the Enter keydown event to the form', () => {
expect(enterEventBubbledToForm).toBe(false)
})
})
})

describe('given a Combobox with 1,000 options', async () => {
Expand Down
10 changes: 7 additions & 3 deletions packages/radix-vue/src/Combobox/ComboboxRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type ComboboxRootContext<T> = {
inputElement: Ref<HTMLInputElement | undefined>
onInputElementChange: (el: HTMLInputElement) => void
onInputNavigation: (dir: 'up' | 'down' | 'home' | 'end') => void
onInputEnter: () => void
onInputEnter: (event: InputEvent) => void
selectedValue: Ref<T | undefined>
selectedElement: ComputedRef<HTMLElement | undefined>
onSelectedValueChange: (val: T) => void
Expand Down Expand Up @@ -278,9 +278,13 @@ provideComboboxRootContext({
nextTick(() => inputElement.value?.focus({ preventScroll: true }))
},
onInputEnter: async () => {
if (filteredOptions.value.length && selectedValue.value && selectedElement.value instanceof Element)
onInputEnter: async (event) => {
if (filteredOptions.value.length && selectedValue.value && selectedElement.value instanceof Element) {
event.preventDefault()
event.stopPropagation()
selectedElement.value?.click()
}
},
selectedValue,
onSelectedValueChange: val => selectedValue.value = val as T,
Expand Down

0 comments on commit ff5abb0

Please sign in to comment.