Skip to content

Commit 34f3c69

Browse files
committed
refactor: do not use SearchController to keep reference to search input element
1 parent cb0ad05 commit 34f3c69

File tree

2 files changed

+11
-22
lines changed

2 files changed

+11
-22
lines changed

src/experimental/Search/SearchBar/SearchBar.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import clsx from 'clsx';
2-
import React, { useEffect } from 'react';
2+
import React, { useEffect, useState } from 'react';
33

44
import { useSearchContext } from '../SearchContext';
55
import { useSearchQueriesInProgress } from '../hooks';
@@ -9,7 +9,6 @@ import { useStateStore } from '../../../store';
99
import type { SearchControllerState } from 'stream-chat';
1010

1111
const searchControllerStateSelector = (nextValue: SearchControllerState) => ({
12-
input: nextValue.input,
1312
isActive: nextValue.isActive,
1413
searchQuery: nextValue.searchQuery,
1514
});
@@ -19,7 +18,8 @@ export const SearchBar = () => {
1918
const { disabled, exitSearchOnInputBlur, placeholder, searchController } = useSearchContext();
2019
const queriesInProgress = useSearchQueriesInProgress(searchController);
2120

22-
const { input, isActive, searchQuery } = useStateStore(
21+
const [input, setInput] = useState<HTMLInputElement | null>(null);
22+
const { isActive, searchQuery } = useStateStore(
2323
searchController.state,
2424
searchControllerStateSelector,
2525
);
@@ -63,7 +63,7 @@ export const SearchBar = () => {
6363
}}
6464
onFocus={searchController.activate}
6565
placeholder={placeholder ?? t('Search')}
66-
ref={searchController.setInputElement}
66+
ref={setInput}
6767
type='text'
6868
value={searchQuery}
6969
/>

src/experimental/Search/__tests__/SearchBar.test.js

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ jest.mock('../hooks', () => ({
1515
useSearchQueriesInProgress: jest.fn().mockReturnValue([]),
1616
}));
1717

18+
const INPUT_TEST_ID = 'search-input';
19+
1820
describe('SearchBar', () => {
1921
const mockSearchController = {
2022
activate: jest.fn(),
2123
clear: jest.fn(),
2224
exit: jest.fn(),
2325
search: jest.fn(),
24-
setInputElement: jest.fn(),
25-
state: { value: { input: null, isActive: false, searchQuery: '' } },
26+
state: { value: { isActive: false, searchQuery: '' } },
2627
};
2728

2829
const defaultProps = {
@@ -37,7 +38,6 @@ describe('SearchBar', () => {
3738
useSearchContext.mockReturnValue(defaultProps);
3839
useTranslationContext.mockReturnValue({ t: (key) => key });
3940
useStateStore.mockReturnValue({
40-
input: null,
4141
isActive: false,
4242
searchQuery: '',
4343
});
@@ -79,7 +79,6 @@ describe('SearchBar', () => {
7979

8080
it('clears search when input is emptied', () => {
8181
useStateStore.mockReturnValue({
82-
input: null,
8382
isActive: true,
8483
searchQuery: 'test',
8584
});
@@ -94,7 +93,6 @@ describe('SearchBar', () => {
9493

9594
it('shows clear button when there is a search query', () => {
9695
useStateStore.mockReturnValue({
97-
input: null,
9896
isActive: true,
9997
searchQuery: 'test',
10098
});
@@ -105,24 +103,21 @@ describe('SearchBar', () => {
105103
});
106104

107105
it('handles clear button click', () => {
108-
const mockInput = { focus: jest.fn() };
109-
useStateStore.mockReturnValue({
110-
input: mockInput,
106+
const state = {
111107
isActive: true,
112108
searchQuery: 'test',
113-
});
109+
};
110+
useStateStore.mockReturnValue(state);
114111

115112
render(<SearchBar />);
116-
113+
expect(screen.getByTestId(INPUT_TEST_ID)).toHaveValue(state.searchQuery);
117114
fireEvent.click(screen.getByTestId('clear-input-button'));
118115

119116
expect(mockSearchController.clear).toHaveBeenCalledWith();
120-
expect(mockInput.focus).toHaveBeenCalledWith();
121117
});
122118

123119
it('shows cancel button when search is active', () => {
124120
useStateStore.mockReturnValue({
125-
input: null,
126121
isActive: true,
127122
searchQuery: '',
128123
});
@@ -134,9 +129,7 @@ describe('SearchBar', () => {
134129
});
135130

136131
it('handles cancel button click', () => {
137-
const mockInput = { blur: jest.fn() };
138132
useStateStore.mockReturnValue({
139-
input: mockInput,
140133
isActive: true,
141134
searchQuery: '',
142135
});
@@ -145,14 +138,11 @@ describe('SearchBar', () => {
145138

146139
fireEvent.click(screen.getByTestId('search-bar-button'));
147140

148-
expect(mockInput.blur).toHaveBeenCalledWith();
149141
expect(mockSearchController.exit).toHaveBeenCalledWith();
150142
});
151143

152144
it('handles escape key press', () => {
153-
const mockInput = { blur: jest.fn() };
154145
useStateStore.mockReturnValue({
155-
input: mockInput,
156146
isActive: true,
157147
searchQuery: 'test',
158148
});
@@ -161,7 +151,6 @@ describe('SearchBar', () => {
161151

162152
fireEvent.keyDown(document, { key: 'Escape' });
163153

164-
expect(mockInput.blur).toHaveBeenCalledWith();
165154
expect(mockSearchController.exit).toHaveBeenCalledWith();
166155
});
167156

0 commit comments

Comments
 (0)