Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
fix(searchbox): prevent concurrent query updates from state while inp…
Browse files Browse the repository at this point in the history
…ut is focused (#1133)
  • Loading branch information
dhayab authored Jul 19, 2022
1 parent 9ed3802 commit c468c0a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/components/SearchBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
:reset-title="resetTitle"
:class-names="classNames"
v-model="currentRefinement"
ref="searchInput"
>
<template
v-slot:loading-indicator
Expand Down Expand Up @@ -148,6 +149,14 @@ export default {
this.$emit('update:modelValue', this.model);
this.state.refine(this.model);
}
// we return the local value if the input is focused to avoid
// concurrent updates when typing
const { searchInput } = this.$refs;
if (searchInput && searchInput.isFocused()) {
return this.localValue;
}
return this.model || this.state.query || '';
},
set(val) {
Expand Down
3 changes: 3 additions & 0 deletions src/components/SearchInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ export default {
};
},
methods: {
isFocused() {
return document.activeElement === this.$refs.input;
},
onFormSubmit() {
const input = this.$refs.input;
input.blur();
Expand Down
15 changes: 15 additions & 0 deletions src/components/__tests__/SearchBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,21 @@ test('refine on empty string on form reset', async () => {
expect(state.refine).toHaveBeenCalledWith('');
});

test('keep local query when out of sync and input is focused', async () => {
const state = { ...defaultState, refine: jest.fn() };
__setState(state);

const wrapper = mount(SearchBox, { attachTo: document.body });
const input = wrapper.find('.ais-SearchBox-input');
input.element.focus();
await input.setValue('hello');

await wrapper.setData({ state: { query: 'hel' } });

expect(input.element.value).toBe('hello');
expect(state.refine).toHaveBeenLastCalledWith('hello');
});

test('overriding slots', () => {
__setState({
...defaultState,
Expand Down

0 comments on commit c468c0a

Please sign in to comment.