Skip to content
This repository has been archived by the owner on Jun 11, 2021. It is now read-only.

Commit

Permalink
feat(core): support onSelect on sources
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour committed Feb 14, 2020
1 parent f2c3eb2 commit 0cf0a93
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 83 deletions.
6 changes: 3 additions & 3 deletions packages/autocomplete-core/onInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function onInput<TItem>({
setStatus,
setContext,
nextState = {},
}: OnInputOptions<TItem>): void {
}: OnInputOptions<TItem>): Promise<void> {
if (lastStalledId) {
clearTimeout(lastStalledId);
}
Expand All @@ -52,7 +52,7 @@ export function onInput<TItem>({
nextState.isOpen ?? props.shouldDropdownShow({ state: store.getState() })
);

return;
return Promise.resolve();
}

setStatus('loading');
Expand All @@ -61,7 +61,7 @@ export function onInput<TItem>({
setStatus('stalled');
}, props.stallThreshold);

props
return props
.getSources({
query,
state: store.getState(),
Expand Down
18 changes: 16 additions & 2 deletions packages/autocomplete-core/onKeyDown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,23 @@ export function onKeyDown<TItem>({
nextState: {
isOpen: false,
},
});
}).then(() => {
suggestion.source.onSelect({
suggestion: item,
suggestionValue: inputValue,
suggestionUrl: itemUrl,
source: suggestion.source,
state: store.getState(),
setHighlightedIndex,
setQuery,
setSuggestions,
setIsOpen,
setStatus,
setContext,
});

props.onStateChange({ state: store.getState() });
props.onStateChange({ state: store.getState() });
});

if (itemUrl !== undefined) {
props.navigator.navigate({
Expand Down
31 changes: 25 additions & 6 deletions packages/autocomplete-core/propGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,13 @@ export function getPropGetters<TItem>({
return;
}

const inputValue = source.getInputValue({
suggestion: item,
state: store.getState(),
});

onInput({
query: source.getInputValue({
suggestion: item,
state: store.getState(),
}),
query: inputValue,
store,
props,
setHighlightedIndex,
Expand All @@ -255,9 +257,26 @@ export function getPropGetters<TItem>({
nextState: {
isOpen: false,
},
});
}).then(() => {
source.onSelect({
suggestion: item,
suggestionValue: inputValue,
suggestionUrl: source.getSuggestionUrl({
suggestion: item,
state: store.getState(),
}),
source,
state: store.getState(),
setHighlightedIndex,
setQuery,
setSuggestions,
setIsOpen,
setStatus,
setContext,
});

props.onStateChange({ state: store.getState() });
props.onStateChange({ state: store.getState() });
});
},
...rest,
};
Expand Down
43 changes: 28 additions & 15 deletions packages/autocomplete-core/types/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AutocompleteAccessibilityGetters } from './propGetters';
import { AutocompleteAccessibilityGetters } from './getters';
import { AutocompleteSetters } from './setters';
import { AutocompleteState } from './state';
import { EventHandlerParams, ItemEventHandlerParams } from './events';

export interface AutocompleteApi<TItem>
extends AutocompleteSetters<TItem>,
Expand All @@ -14,11 +13,29 @@ export interface AutocompleteSuggestion<TItem> {
items: TItem[];
}

export interface GetSourcesOptions<TItem> extends AutocompleteSetters<TItem> {
export interface GetSourcesParams<TItem> extends AutocompleteSetters<TItem> {
query: string;
state: AutocompleteState<TItem>;
}

interface ItemParams<TItem> {
suggestion: TItem;
suggestionValue: ReturnType<AutocompleteSource<TItem>['getInputValue']>;
suggestionUrl: ReturnType<AutocompleteSource<TItem>['getSuggestionUrl']>;
source: AutocompleteSource<TItem>;
}

interface OnSelectParams<TItem>
extends AutocompleteSetters<TItem>,
ItemParams<TItem> {
state: AutocompleteState<TItem>;
}

interface OnSubmitParams<TItem> extends AutocompleteSetters<TItem> {
state: AutocompleteState<TItem>;
event: Event;
}

export interface PublicAutocompleteSource<TItem> {
/**
* Get the string value of the suggestion. The value is used to fill the search box.
Expand All @@ -45,14 +62,14 @@ export interface PublicAutocompleteSource<TItem> {
* Function called when the input changes. You can use this function to filter/search the items based on the query.
*/
getSuggestions(
options: GetSourcesOptions<TItem>
params: GetSourcesParams<TItem>
):
| Array<AutocompleteSuggestion<TItem>>
| Promise<Array<AutocompleteSuggestion<TItem>>>;
/**
* Called when an item is selected.
*/
onSelect?: (options: ItemEventHandlerParams<TItem>) => void;
onSelect?(params: OnSelectParams<TItem>): void;
}

export type AutocompleteSource<TItem> = {
Expand All @@ -62,7 +79,7 @@ export type AutocompleteSource<TItem> = {
};

export type GetSources<TItem> = (
options: GetSourcesOptions<TItem>
params: GetSourcesParams<TItem>
) => Promise<Array<AutocompleteSource<TItem>>>;

export interface Environment {
Expand Down Expand Up @@ -131,10 +148,6 @@ export interface PublicAutocompleteOptions<TItem> {
* @default 0
*/
defaultHighlightedIndex?: number;
/**
* The function called when an item is selected.
*/
// onSelect(): void;
/**
* Whether to show the highlighted suggestion as completion in the input.
*
Expand Down Expand Up @@ -162,7 +175,7 @@ export interface PublicAutocompleteOptions<TItem> {
* The sources to get the suggestions from.
*/
getSources(
options: GetSourcesOptions<TItem>
params: GetSourcesParams<TItem>
):
| Array<PublicAutocompleteSource<TItem>>
| Promise<Array<PublicAutocompleteSource<TItem>>>;
Expand All @@ -181,11 +194,11 @@ export interface PublicAutocompleteOptions<TItem> {
/**
* The function called to determine whether the dropdown should open.
*/
shouldDropdownShow?(options: { state: AutocompleteState<TItem> }): boolean;
shouldDropdownShow?(params: { state: AutocompleteState<TItem> }): boolean;
/**
* The function called when the autocomplete form is submitted.
*/
onSubmit?(params: EventHandlerParams<TItem>): void;
onSubmit?(params: OnSubmitParams<TItem>): void;
}

// Props manipulated internally with default values.
Expand All @@ -202,6 +215,6 @@ export interface AutocompleteOptions<TItem> {
getSources: GetSources<TItem>;
environment: Environment;
navigator: Navigator<TItem>;
shouldDropdownShow(options: { state: AutocompleteState<TItem> }): boolean;
onSubmit(params: EventHandlerParams<TItem>): void;
shouldDropdownShow(params: { state: AutocompleteState<TItem> }): boolean;
onSubmit(params: OnSubmitParams<TItem>): void;
}
16 changes: 0 additions & 16 deletions packages/autocomplete-core/types/events.ts

This file was deleted.

3 changes: 1 addition & 2 deletions packages/autocomplete-core/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export * from './api';
export * from './events';
export * from './propGetters';
export * from './getters';
export * from './setters';
export * from './state';
export * from './store';
8 changes: 4 additions & 4 deletions packages/autocomplete-presets/results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ interface SearchParameters {
params?: QueryParameters;
}

interface GetAlgoliaSourceOptions {
interface GetAlgoliaSourceParams {
searchClient: SearchClient;
queries: SearchParameters[];
}

export function getAlgoliaSource({
searchClient,
queries,
}: GetAlgoliaSourceOptions) {
}: GetAlgoliaSourceParams) {
if (typeof (searchClient as Client).addAlgoliaAgent === 'function') {
if (__DEV__) {
(searchClient as Client).addAlgoliaAgent(
Expand Down Expand Up @@ -52,7 +52,7 @@ export function getAlgoliaSource({
export function getAlgoliaResults({
searchClient,
queries,
}: GetAlgoliaSourceOptions): Promise<SearchResponse['results']> {
}: GetAlgoliaSourceParams): Promise<SearchResponse['results']> {
return getAlgoliaSource({ searchClient, queries }).then(response => {
return response.results;
});
Expand All @@ -61,7 +61,7 @@ export function getAlgoliaResults({
export function getAlgoliaHits({
searchClient,
queries,
}: GetAlgoliaSourceOptions): Promise<SearchResponse['hits']> {
}: GetAlgoliaSourceParams): Promise<SearchResponse['hits']> {
return getAlgoliaSource({ searchClient, queries }).then(response => {
const results = response.results;

Expand Down
113 changes: 78 additions & 35 deletions stories/react.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,85 @@ const searchClient = algoliasearch(
'6be0576ff61c053d5f9a3225e2a90f76'
);

storiesOf('React', module).add(
'Component',
withPlayground(({ container, dropdownContainer }) => {
render(
<Autocomplete
placeholder="Search items…"
showCompletion={true}
defaultHighlightedIndex={-1}
dropdownContainer={dropdownContainer}
getSources={() => {
return [
{
getInputValue({ suggestion }) {
return suggestion.query;
storiesOf('React', module)
.add(
'Component',
withPlayground(({ container, dropdownContainer }) => {
render(
<Autocomplete
placeholder="Search items…"
showCompletion={true}
defaultHighlightedIndex={-1}
dropdownContainer={dropdownContainer}
getSources={() => {
return [
{
getInputValue({ suggestion }) {
return suggestion.query;
},
getSuggestions({ query }) {
return getAlgoliaHits({
searchClient,
queries: [
{
indexName: 'instant_search_demo_query_suggestions',
query,
params: {
hitsPerPage: 4,
},
},
],
});
},
},
getSuggestions({ query }) {
return getAlgoliaHits({
searchClient,
queries: [
{
indexName: 'instant_search_demo_query_suggestions',
query,
params: {
hitsPerPage: 4,
];
}}
/>,
container
);

return container;
})
)
.add(
'Dropdown stays open onSelect',
withPlayground(({ container, dropdownContainer }) => {
render(
<Autocomplete
placeholder="Search items…"
showCompletion={true}
defaultHighlightedIndex={-1}
dropdownContainer={dropdownContainer}
getSources={() => {
return [
{
getInputValue({ suggestion }) {
return suggestion.query;
},
onSelect(props) {
props.setIsOpen(true);
},
getSuggestions({ query }) {
return getAlgoliaHits({
searchClient,
queries: [
{
indexName: 'instant_search_demo_query_suggestions',
query,
params: {
hitsPerPage: 4,
},
},
},
],
});
],
});
},
},
},
];
}}
/>,
container
);
];
}}
/>,
container
);

return container;
})
);
return container;
})
);

0 comments on commit 0cf0a93

Please sign in to comment.