diff --git a/packages/autocomplete-core/src/autocomplete.ts b/packages/autocomplete-core/src/autocomplete.ts index 526584335..5bab57af2 100644 --- a/packages/autocomplete-core/src/autocomplete.ts +++ b/packages/autocomplete-core/src/autocomplete.ts @@ -1,8 +1,8 @@ +import { stateReducer } from './stateReducer'; import { getDefaultProps } from './defaultProps'; import { createStore } from './store'; import { getPropGetters } from './propGetters'; import { getAutocompleteSetters } from './setters'; -import { getCompletion } from './completion'; import { PublicAutocompleteOptions, AutocompleteApi } from './types'; @@ -10,7 +10,7 @@ function createAutocomplete( options: PublicAutocompleteOptions ): AutocompleteApi { const props = getDefaultProps(options); - const store = createStore(props); + const store = createStore(stateReducer, props); const { setHighlightedIndex, @@ -53,7 +53,6 @@ function createAutocomplete( getItemProps, getLabelProps, getMenuProps, - getCompletion: () => getCompletion({ state: store.getState(), props }), }; } diff --git a/packages/autocomplete-core/src/defaultProps.ts b/packages/autocomplete-core/src/defaultProps.ts index 2dbb2cd62..9a89f494c 100644 --- a/packages/autocomplete-core/src/defaultProps.ts +++ b/packages/autocomplete-core/src/defaultProps.ts @@ -33,6 +33,7 @@ export function getDefaultProps( initialState: { highlightedIndex: null, query: '', + completion: null, suggestions: [], isOpen: false, status: 'idle', diff --git a/packages/autocomplete-core/src/stateReducer.ts b/packages/autocomplete-core/src/stateReducer.ts index 444d82fd2..60ba1488b 100644 --- a/packages/autocomplete-core/src/stateReducer.ts +++ b/packages/autocomplete-core/src/stateReducer.ts @@ -1,17 +1,8 @@ import { getItemsCount, getNextHighlightedIndex } from './utils'; -import { AutocompleteState, AutocompleteOptions, ActionType } from './types'; - -interface Action { - type: ActionType; - value: any; -} - -export const stateReducer = ( - action: Action, - state: AutocompleteState, - props: AutocompleteOptions -): AutocompleteState => { +import { Reducer } from './types'; + +export const stateReducer: Reducer = (action, state, props) => { switch (action.type) { case 'setHighlightedIndex': { return { diff --git a/packages/autocomplete-core/src/store.ts b/packages/autocomplete-core/src/store.ts index 9101d6908..d42d7b2b5 100644 --- a/packages/autocomplete-core/src/store.ts +++ b/packages/autocomplete-core/src/store.ts @@ -1,8 +1,14 @@ -import { stateReducer } from './stateReducer'; +import { getCompletion } from './completion'; -import { AutocompleteOptions, AutocompleteStore } from './types'; +import { + AutocompleteOptions, + AutocompleteStore, + Reducer, + AutocompleteState, +} from './types'; export function createStore( + reducer: Reducer, props: AutocompleteOptions ): AutocompleteStore { return { @@ -11,9 +17,8 @@ export function createStore( return this.state; }, send(action, payload) { - this.state = stateReducer( - { type: action, value: payload }, - this.state, + this.state = withCompletion( + reducer({ type: action, value: payload }, this.state, props), props ); @@ -21,3 +26,13 @@ export function createStore( }, }; } + +function withCompletion( + state: AutocompleteState, + props: AutocompleteOptions +) { + return { + ...state, + completion: getCompletion({ state, props }), + }; +} diff --git a/packages/autocomplete-core/src/types/api.ts b/packages/autocomplete-core/src/types/api.ts index 3f1ada80f..3b6a53967 100644 --- a/packages/autocomplete-core/src/types/api.ts +++ b/packages/autocomplete-core/src/types/api.ts @@ -4,9 +4,7 @@ import { AutocompleteState } from './state'; export interface AutocompleteApi extends AutocompleteSetters, - AutocompleteAccessibilityGetters { - getCompletion(): string | null; -} + AutocompleteAccessibilityGetters {} export interface AutocompleteSuggestion { source: AutocompleteSource; diff --git a/packages/autocomplete-core/src/types/state.ts b/packages/autocomplete-core/src/types/state.ts index 12bed6e58..74a623e26 100644 --- a/packages/autocomplete-core/src/types/state.ts +++ b/packages/autocomplete-core/src/types/state.ts @@ -3,6 +3,7 @@ import { AutocompleteSuggestion } from './api'; export interface AutocompleteState { highlightedIndex: number | null; query: string; + completion: string | null; suggestions: Array>; isOpen: boolean; status: 'idle' | 'loading' | 'stalled' | 'error'; diff --git a/packages/autocomplete-core/src/types/store.ts b/packages/autocomplete-core/src/types/store.ts index 9915e5ba3..6dc9f4f20 100644 --- a/packages/autocomplete-core/src/types/store.ts +++ b/packages/autocomplete-core/src/types/store.ts @@ -1,3 +1,4 @@ +import { AutocompleteOptions } from './api'; import { AutocompleteState } from './state'; export interface AutocompleteStore { @@ -6,7 +7,18 @@ export interface AutocompleteStore { send(action: ActionType, payload: any): void; } -export type ActionType = +export type Reducer = ( + action: Action, + state: AutocompleteState, + props: AutocompleteOptions +) => AutocompleteState; + +type Action = { + type: ActionType; + value: any; +}; + +type ActionType = | 'setHighlightedIndex' | 'setQuery' | 'setSuggestions' diff --git a/packages/autocomplete-react/src/Autocomplete.tsx b/packages/autocomplete-react/src/Autocomplete.tsx index 30d8377b1..96228ecbb 100644 --- a/packages/autocomplete-react/src/Autocomplete.tsx +++ b/packages/autocomplete-react/src/Autocomplete.tsx @@ -110,9 +110,9 @@ export function Autocomplete( query={state.query} isOpen={state.isOpen} status={state.status} + completion={state.completion} getLabelProps={autocomplete.getLabelProps} getInputProps={autocomplete.getInputProps} - completion={autocomplete.getCompletion()} {...autocomplete.getFormProps({ inputElement: inputRef.current, })}