Skip to content

Commit 66900e4

Browse files
feat(autocomplete): indices prop for React component
1 parent 0ec964b commit 66900e4

File tree

5 files changed

+84
-53
lines changed

5 files changed

+84
-53
lines changed

packages/react-instantsearch-core/src/components/AutocompleteWrapper.tsx

Lines changed: 0 additions & 27 deletions
This file was deleted.

packages/react-instantsearch-core/src/hooks/useAutocomplete.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

packages/react-instantsearch-core/src/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export { default as version } from './version';
2-
export * from './components/AutocompleteWrapper';
32
export * from './components/Configure';
43
export * from './components/DynamicWidgets';
54
export * from './components/Index';
@@ -31,7 +30,6 @@ export * from './connectors/useStats';
3130
export * from './connectors/useToggleRefinement';
3231
export * from './connectors/useTrendingItems';
3332
export * from './connectors/useLookingSimilar';
34-
export * from './hooks/useAutocomplete';
3533
export * from './hooks/useConnector';
3634
export * from './hooks/useInstantSearch';
3735
export * from './lib/wrapPromiseWithState';
Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
import React from 'react';
2-
import {
3-
EXPERIMENTAL_AutocompleteWrapper as AutocompleteWrapper,
4-
EXPERIMENTAL_useAutocomplete as useAutocomplete,
5-
} from 'react-instantsearch-core';
2+
import { Index } from 'react-instantsearch-core';
63

7-
export function EXPERIMENTAL_Autocomplete() {
8-
return (
9-
<AutocompleteWrapper>
10-
<AutocompleteInner />
11-
</AutocompleteWrapper>
12-
);
13-
}
4+
import { Hits, SearchBox } from '../widgets';
5+
6+
import type { BaseHit, Hit } from 'instantsearch.js';
147

15-
function AutocompleteInner() {
16-
useAutocomplete();
8+
type IndexConfig<TItem extends Hit<BaseHit> = Hit<BaseHit>> = {
9+
indexName: string;
10+
getQuery?: (item: TItem) => string;
11+
getURL?: (item: TItem) => string;
12+
itemComponent: React.ComponentType<TItem> | React.ComponentType<any>;
13+
};
1714

18-
return null;
15+
export type AutocompleteProps = {
16+
indices: IndexConfig[];
17+
};
18+
19+
export function EXPERIMENTAL_Autocomplete({ indices }: AutocompleteProps) {
20+
return (
21+
<Index EXPERIMENTAL_isolated>
22+
<SearchBox />
23+
{indices.map((index) => (
24+
<Index key={index.indexName} indexName={index.indexName}>
25+
<Hits hitComponent={({ hit }) => <index.itemComponent {...hit} />} />
26+
</Index>
27+
))}
28+
</Index>
29+
);
1930
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
5+
import {
6+
createMultiSearchResponse,
7+
createSearchClient,
8+
createSingleSearchResponse,
9+
} from '@instantsearch/mocks';
10+
import { InstantSearchTestWrapper } from '@instantsearch/testutils';
11+
import { render, screen } from '@testing-library/react';
12+
import React from 'react';
13+
14+
import { EXPERIMENTAL_Autocomplete } from '../Autocomplete';
15+
16+
describe('Autocomplete', () => {
17+
function createMockedSearchClient() {
18+
return createSearchClient({
19+
// @ts-expect-error - doesn't properly handle multi index, expects all responses to be of the same type
20+
search: jest.fn(() =>
21+
Promise.resolve(
22+
createMultiSearchResponse(
23+
createSingleSearchResponse({
24+
hits: [{ objectID: '1', name: 'Item 1' }],
25+
}),
26+
// @ts-expect-error - ignore second response type
27+
createSingleSearchResponse({
28+
hits: [{ objectID: '2', query: 'hello' }],
29+
})
30+
)
31+
)
32+
),
33+
});
34+
}
35+
36+
test('should render a searchbox and indices with hits', async () => {
37+
const searchClient = createMockedSearchClient();
38+
render(
39+
<InstantSearchTestWrapper searchClient={searchClient}>
40+
<EXPERIMENTAL_Autocomplete
41+
indices={[
42+
{
43+
indexName: 'indexName',
44+
itemComponent: (props: { name: string }) => props.name,
45+
},
46+
{
47+
indexName: 'indexName2',
48+
itemComponent: (props: { query: string }) => props.query,
49+
},
50+
]}
51+
/>
52+
</InstantSearchTestWrapper>
53+
);
54+
55+
expect(await screen.findByText('Item 1')).toBeInTheDocument();
56+
expect(await screen.findByText('hello')).toBeInTheDocument();
57+
expect(screen.getByRole('searchbox')).toBeInTheDocument();
58+
});
59+
});

0 commit comments

Comments
 (0)