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

Commit

Permalink
feat(core): process completion as a state enhancer (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour authored Feb 24, 2020
1 parent 8bed5ce commit 53c2ef7
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 25 deletions.
5 changes: 2 additions & 3 deletions packages/autocomplete-core/src/autocomplete.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
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';

function createAutocomplete<TItem extends {}>(
options: PublicAutocompleteOptions<TItem>
): AutocompleteApi<TItem> {
const props = getDefaultProps(options);
const store = createStore(props);
const store = createStore(stateReducer, props);

const {
setHighlightedIndex,
Expand Down Expand Up @@ -53,7 +53,6 @@ function createAutocomplete<TItem extends {}>(
getItemProps,
getLabelProps,
getMenuProps,
getCompletion: () => getCompletion({ state: store.getState(), props }),
};
}

Expand Down
1 change: 1 addition & 0 deletions packages/autocomplete-core/src/defaultProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function getDefaultProps<TItem>(
initialState: {
highlightedIndex: null,
query: '',
completion: null,
suggestions: [],
isOpen: false,
status: 'idle',
Expand Down
15 changes: 3 additions & 12 deletions packages/autocomplete-core/src/stateReducer.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import { getItemsCount, getNextHighlightedIndex } from './utils';

import { AutocompleteState, AutocompleteOptions, ActionType } from './types';

interface Action {
type: ActionType;
value: any;
}

export const stateReducer = <TItem>(
action: Action,
state: AutocompleteState<TItem>,
props: AutocompleteOptions<TItem>
): AutocompleteState<TItem> => {
import { Reducer } from './types';

export const stateReducer: Reducer = (action, state, props) => {
switch (action.type) {
case 'setHighlightedIndex': {
return {
Expand Down
25 changes: 20 additions & 5 deletions packages/autocomplete-core/src/store.ts
Original file line number Diff line number Diff line change
@@ -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<TItem>(
reducer: Reducer,
props: AutocompleteOptions<TItem>
): AutocompleteStore<TItem> {
return {
Expand All @@ -11,13 +17,22 @@ export function createStore<TItem>(
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
);

props.onStateChange({ state: this.state });
},
};
}

function withCompletion<TItem>(
state: AutocompleteState<TItem>,
props: AutocompleteOptions<TItem>
) {
return {
...state,
completion: getCompletion({ state, props }),
};
}
4 changes: 1 addition & 3 deletions packages/autocomplete-core/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { AutocompleteState } from './state';

export interface AutocompleteApi<TItem>
extends AutocompleteSetters<TItem>,
AutocompleteAccessibilityGetters<TItem> {
getCompletion(): string | null;
}
AutocompleteAccessibilityGetters<TItem> {}

export interface AutocompleteSuggestion<TItem> {
source: AutocompleteSource<TItem>;
Expand Down
1 change: 1 addition & 0 deletions packages/autocomplete-core/src/types/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AutocompleteSuggestion } from './api';
export interface AutocompleteState<TItem> {
highlightedIndex: number | null;
query: string;
completion: string | null;
suggestions: Array<AutocompleteSuggestion<TItem>>;
isOpen: boolean;
status: 'idle' | 'loading' | 'stalled' | 'error';
Expand Down
14 changes: 13 additions & 1 deletion packages/autocomplete-core/src/types/store.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AutocompleteOptions } from './api';
import { AutocompleteState } from './state';

export interface AutocompleteStore<TItem> {
Expand All @@ -6,7 +7,18 @@ export interface AutocompleteStore<TItem> {
send(action: ActionType, payload: any): void;
}

export type ActionType =
export type Reducer = <TItem>(
action: Action,
state: AutocompleteState<TItem>,
props: AutocompleteOptions<TItem>
) => AutocompleteState<TItem>;

type Action = {
type: ActionType;
value: any;
};

type ActionType =
| 'setHighlightedIndex'
| 'setQuery'
| 'setSuggestions'
Expand Down
2 changes: 1 addition & 1 deletion packages/autocomplete-react/src/Autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ export function Autocomplete<TItem extends {}>(
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,
})}
Expand Down

0 comments on commit 53c2ef7

Please sign in to comment.