-
Notifications
You must be signed in to change notification settings - Fork 326
/
createAutocomplete.ts
108 lines (97 loc) 路 2.79 KB
/
createAutocomplete.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { createAlgoliaInsightsPlugin } from '@algolia/autocomplete-plugin-algolia-insights';
import { checkOptions } from './checkOptions';
import { createStore } from './createStore';
import { getAutocompleteSetters } from './getAutocompleteSetters';
import { getDefaultProps } from './getDefaultProps';
import { getPropGetters } from './getPropGetters';
import { getMetadata, injectMetadata } from './metadata';
import { onInput } from './onInput';
import { stateReducer } from './stateReducer';
import {
AutocompleteApi,
AutocompleteOptions as AutocompleteCoreOptions,
BaseItem,
AutocompleteSubscribers,
} from './types';
export interface AutocompleteOptionsWithMetadata<TItem extends BaseItem>
extends AutocompleteCoreOptions<TItem> {
/**
* @internal
*/
__autocomplete_metadata?: Record<string, unknown>;
}
export function createAutocomplete<
TItem extends BaseItem,
TEvent = Event,
TMouseEvent = MouseEvent,
TKeyboardEvent = KeyboardEvent
>(
options: AutocompleteOptionsWithMetadata<TItem>
): AutocompleteApi<TItem, TEvent, TMouseEvent, TKeyboardEvent> {
checkOptions(options);
const subscribers: AutocompleteSubscribers<TItem> = [];
const props = getDefaultProps(options, subscribers);
const store = createStore(stateReducer, props, onStoreStateChange);
const setters = getAutocompleteSetters({ store });
const propGetters = getPropGetters<
TItem,
TEvent,
TMouseEvent,
TKeyboardEvent
>({ props, refresh, store, navigator: props.navigator, ...setters });
function onStoreStateChange({ prevState, state }) {
props.onStateChange({
prevState,
state,
refresh,
navigator: props.navigator,
...setters,
});
}
function refresh() {
return onInput({
event: new Event('input'),
nextState: { isOpen: store.getState().isOpen },
props,
navigator: props.navigator,
query: store.getState().query,
refresh,
store,
...setters,
});
}
if (
props.insights &&
!props.plugins.some((plugin) => plugin.name === 'aa.algoliaInsightsPlugin')
) {
const insightsParams =
typeof props.insights === 'boolean' ? {} : props.insights;
props.plugins.push(createAlgoliaInsightsPlugin(insightsParams));
}
props.plugins.forEach((plugin) =>
plugin.subscribe?.({
...setters,
navigator: props.navigator,
refresh,
onSelect(fn) {
subscribers.push({ onSelect: fn });
},
onActive(fn) {
subscribers.push({ onActive: fn });
},
onResolve(fn) {
subscribers.push({ onResolve: fn });
},
})
);
injectMetadata({
metadata: getMetadata({ plugins: props.plugins, options }),
environment: props.environment,
});
return {
refresh,
navigator: props.navigator,
...propGetters,
...setters,
};
}