Skip to content

Commit

Permalink
fix(core): extend TItem to object
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour committed Nov 23, 2020
1 parent beea835 commit fcf94ff
Show file tree
Hide file tree
Showing 26 changed files with 137 additions and 85 deletions.
6 changes: 4 additions & 2 deletions packages/autocomplete-core/src/checkOptions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { warn } from '@algolia/autocomplete-shared';

import { AutocompleteOptions } from './types';
import { AutocompleteOptions, BaseItem } from './types';

export function checkOptions<TItem>(option: AutocompleteOptions<TItem>) {
export function checkOptions<TItem extends BaseItem>(
option: AutocompleteOptions<TItem>
) {
warn(
!option.debug,
'The `debug` option is meant for development debugging and should not be used in production.'
Expand Down
4 changes: 2 additions & 2 deletions packages/autocomplete-core/src/createAutocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { getDefaultProps } from './getDefaultProps';
import { getPropGetters } from './getPropGetters';
import { onInput } from './onInput';
import { stateReducer } from './stateReducer';
import { AutocompleteApi, AutocompleteOptions } from './types';
import { AutocompleteApi, AutocompleteOptions, BaseItem } from './types';

export function createAutocomplete<
TItem extends {},
TItem extends BaseItem,
TEvent = Event,
TMouseEvent = MouseEvent,
TKeyboardEvent = KeyboardEvent
Expand Down
3 changes: 2 additions & 1 deletion packages/autocomplete-core/src/createStore.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
AutocompleteStore,
BaseItem,
InternalAutocompleteOptions,
Reducer,
} from './types';

export function createStore<TItem>(
export function createStore<TItem extends BaseItem>(
reducer: Reducer,
props: InternalAutocompleteOptions<TItem>
): AutocompleteStore<TItem> {
Expand Down
15 changes: 10 additions & 5 deletions packages/autocomplete-core/src/getAutocompleteSetters.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { AutocompleteApi, AutocompleteStore } from './types';
import {
AutocompleteApi,
AutocompleteCollection,
AutocompleteStore,
BaseItem,
} from './types';
import { flatten } from './utils';

interface GetAutocompleteSettersOptions<TItem> {
interface GetAutocompleteSettersOptions<TItem extends BaseItem> {
store: AutocompleteStore<TItem>;
}

export function getAutocompleteSetters<TItem>({
export function getAutocompleteSetters<TItem extends BaseItem>({
store,
}: GetAutocompleteSettersOptions<TItem>) {
const setSelectedItemId: AutocompleteApi<TItem>['setSelectedItemId'] = (
Expand All @@ -22,11 +27,11 @@ export function getAutocompleteSetters<TItem>({
rawValue
) => {
let baseItemId = 0;
const value = rawValue.map((collection) => ({
const value = rawValue.map<AutocompleteCollection<TItem>>((collection) => ({
...collection,
// We flatten the stored items to support calling `getAlgoliaHits`
// from the source itself.
items: flatten(collection.items).map((item) => ({
items: flatten(collection.items as any).map((item: any) => ({
...item,
__autocomplete_id: baseItemId++,
})),
Expand Down
6 changes: 3 additions & 3 deletions packages/autocomplete-core/src/getCompletion.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { AutocompleteState } from './types';
import { AutocompleteState, BaseItem } from './types';
import { getSelectedItem } from './utils';

interface GetCompletionProps<TItem> {
interface GetCompletionProps<TItem extends BaseItem> {
state: AutocompleteState<TItem>;
}

export function getCompletion<TItem>({
export function getCompletion<TItem extends BaseItem>({
state,
}: GetCompletionProps<TItem>): string | null {
if (state.isOpen === false || state.selectedItemId === null) {
Expand Down
10 changes: 7 additions & 3 deletions packages/autocomplete-core/src/getDefaultProps.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { getNavigator } from './getNavigator';
import { InternalAutocompleteOptions, AutocompleteOptions } from './types';
import {
AutocompleteOptions,
BaseItem,
InternalAutocompleteOptions,
} from './types';
import {
generateAutocompleteId,
getItemsCount,
getNormalizedSources,
flatten,
} from './utils';

export function getDefaultProps<TItem>(
export function getDefaultProps<TItem extends BaseItem>(
props: AutocompleteOptions<TItem>
): InternalAutocompleteOptions<TItem> {
const environment: InternalAutocompleteOptions<
unknown
TItem
>['environment'] = (typeof window !== 'undefined'
? window
: {}) as typeof window;
Expand Down
8 changes: 4 additions & 4 deletions packages/autocomplete-core/src/getNavigator.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { InternalAutocompleteOptions } from './types';
import { BaseItem, InternalAutocompleteOptions } from './types';

export function getNavigator({
export function getNavigator<TItem extends BaseItem>({
environment,
}: Pick<
InternalAutocompleteOptions<unknown>,
InternalAutocompleteOptions<TItem>,
'environment'
>): InternalAutocompleteOptions<unknown>['navigator'] {
>): InternalAutocompleteOptions<TItem>['navigator'] {
return {
navigate({ itemUrl }) {
environment.location.assign(itemUrl);
Expand Down
11 changes: 9 additions & 2 deletions packages/autocomplete-core/src/getPropGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ import {
GetLabelProps,
GetListProps,
GetRootProps,
BaseItem,
} from './types';
import { getSelectedItem, isOrContainsNode } from './utils';

interface GetPropGettersOptions<TItem> extends AutocompleteSetters<TItem> {
interface GetPropGettersOptions<TItem extends BaseItem>
extends AutocompleteSetters<TItem> {
store: AutocompleteStore<TItem>;
props: InternalAutocompleteOptions<TItem>;
refresh: AutocompleteRefresh;
}

export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
export function getPropGetters<
TItem extends BaseItem,
TEvent,
TMouseEvent,
TKeyboardEvent
>({
store,
props,
setSelectedItemId,
Expand Down
10 changes: 6 additions & 4 deletions packages/autocomplete-core/src/onInput.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import {
InternalAutocompleteOptions,
AutocompleteSetters,
AutocompleteState,
AutocompleteStore,
AutocompleteRefresh,
BaseItem,
InternalAutocompleteOptions,
} from './types';
import { getSelectedItem } from './utils';

let lastStalledId: number | null = null;

interface OnInputParams<TItem> extends AutocompleteSetters<TItem> {
interface OnInputParams<TItem extends BaseItem>
extends AutocompleteSetters<TItem> {
query: string;
event: any;
store: AutocompleteStore<TItem>;
Expand All @@ -25,7 +27,7 @@ interface OnInputParams<TItem> extends AutocompleteSetters<TItem> {
refresh: AutocompleteRefresh;
}

export function onInput<TItem>({
export function onInput<TItem extends BaseItem>({
query,
event,
store,
Expand Down Expand Up @@ -123,7 +125,7 @@ export function onInput<TItem>({
)
.then((collections) => {
setStatus('idle');
setCollections(collections);
setCollections(collections as any);
setIsOpen(
nextState.isOpen ??
((query.length === 0 && props.openOnFocus) ||
Expand Down
8 changes: 5 additions & 3 deletions packages/autocomplete-core/src/onKeyDown.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { onInput } from './onInput';
import {
InternalAutocompleteOptions,
AutocompleteSetters,
AutocompleteStore,
AutocompleteRefresh,
BaseItem,
InternalAutocompleteOptions,
} from './types';
import { getSelectedItem } from './utils';

interface OnKeyDownOptions<TItem> extends AutocompleteSetters<TItem> {
interface OnKeyDownOptions<TItem extends BaseItem>
extends AutocompleteSetters<TItem> {
event: KeyboardEvent;
store: AutocompleteStore<TItem>;
props: InternalAutocompleteOptions<TItem>;
refresh: AutocompleteRefresh;
}

export function onKeyDown<TItem>({
export function onKeyDown<TItem extends BaseItem>({
event,
store,
props,
Expand Down
43 changes: 26 additions & 17 deletions packages/autocomplete-core/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import { AutocompletePlugin } from './plugins';
import { AutocompleteSetters } from './setters';
import { AutocompleteState } from './state';

export type BaseItem = Record<string, unknown>;

export interface AutocompleteApi<
TItem,
TItem extends BaseItem,
TEvent = Event,
TMouseEvent = MouseEvent,
TKeyboardEvent = KeyboardEvent
Expand All @@ -25,18 +27,23 @@ export interface AutocompleteApi<

export type AutocompleteRefresh = () => Promise<void>;

export interface AutocompleteCollection<TItem> {
export interface AutocompleteCollection<TItem extends BaseItem> {
source: InternalAutocompleteSource<TItem>;
items: TItem[];
}
export interface AutocompleteCollectionItemsArray<TItem extends BaseItem> {
source: InternalAutocompleteSource<TItem>;
items: TItem[][];
}

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

interface ItemParams<TItem> {
interface ItemParams<TItem extends BaseItem> {
item: TItem;
itemInputValue: ReturnType<
InternalAutocompleteSource<TItem>['getItemInputValue']
Expand All @@ -45,30 +52,32 @@ interface ItemParams<TItem> {
source: InternalAutocompleteSource<TItem>;
}

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

type OnHighlightParams<TItem> = OnSelectParams<TItem>;
type OnHighlightParams<TItem extends BaseItem> = OnSelectParams<TItem>;

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

interface OnInputParams<TItem> extends AutocompleteSetters<TItem> {
interface OnInputParams<TItem extends BaseItem>
extends AutocompleteSetters<TItem> {
query: string;
state: AutocompleteState<TItem>;
refresh: AutocompleteRefresh;
}

export interface AutocompleteSource<TItem> {
export interface AutocompleteSource<TItem extends BaseItem> {
// This allows flavors to pass other keys to their source.
// Example: `templates` in the JavaScript API
[key: string]: unknown;
// [key: string]: unknown;
/**
* Get the string value of the item. The value is used to fill the search box.
*/
Expand Down Expand Up @@ -107,13 +116,13 @@ export interface AutocompleteSource<TItem> {
onHighlight?(params: OnHighlightParams<TItem>): void;
}

export type InternalAutocompleteSource<TItem> = {
export type InternalAutocompleteSource<TItem extends BaseItem> = {
[KParam in keyof AutocompleteSource<TItem>]-?: AutocompleteSource<
TItem
>[KParam];
};

export type GetSources<TItem> = (
export type GetSources<TItem extends BaseItem> = (
params: GetSourcesParams<TItem>
) => Promise<Array<InternalAutocompleteSource<TItem>>>;

Expand All @@ -131,7 +140,7 @@ export type Environment =
open: Window['open'];
};

interface Navigator<TItem> {
interface Navigator<TItem extends BaseItem> {
/**
* Called when a URL should be open in the current page.
*/
Expand All @@ -158,7 +167,7 @@ interface Navigator<TItem> {
}): void;
}

export interface AutocompleteOptions<TItem> {
export interface AutocompleteOptions<TItem extends BaseItem> {
/**
* Whether to consider the experience in debug mode.
*
Expand All @@ -179,7 +188,7 @@ export interface AutocompleteOptions<TItem> {
/**
* Function called when the internal state changes.
*/
onStateChange?<TItem>(props: {
onStateChange?(props: {
state: AutocompleteState<TItem>;
prevState: AutocompleteState<TItem>;
}): void;
Expand Down Expand Up @@ -256,11 +265,11 @@ export interface AutocompleteOptions<TItem> {
}

// Props manipulated internally with default values.
export interface InternalAutocompleteOptions<TItem>
export interface InternalAutocompleteOptions<TItem extends BaseItem>
extends AutocompleteOptions<TItem> {
debug: boolean;
id: string;
onStateChange<TItem>(props: {
onStateChange(props: {
state: AutocompleteState<TItem>;
prevState: AutocompleteState<TItem>;
}): void;
Expand Down
9 changes: 6 additions & 3 deletions packages/autocomplete-core/src/types/getters.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InternalAutocompleteSource } from './api';
import { BaseItem, InternalAutocompleteSource } from './api';

export interface AutocompleteAccessibilityGetters<
TItem,
TItem extends BaseItem,
TEvent = Event,
TMouseEvent = MouseEvent,
TKeyboardEvent = KeyboardEvent
Expand Down Expand Up @@ -104,7 +104,10 @@ export type GetListProps = (props?: {
id: string;
};

export type GetItemProps<TItem, TMouseEvent = MouseEvent> = (props: {
export type GetItemProps<
TItem extends BaseItem,
TMouseEvent = MouseEvent
> = (props: {
[key: string]: unknown;
item: TItem;
source: InternalAutocompleteSource<TItem>;
Expand Down
7 changes: 5 additions & 2 deletions packages/autocomplete-core/src/types/plugins.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { AutocompleteOptions, AutocompleteSource } from './api';
import { AutocompleteOptions, AutocompleteSource, BaseItem } from './api';

export type AutocompletePlugin<TItem, TData = unknown> = Partial<
export type AutocompletePlugin<
TItem extends BaseItem,
TData = unknown
> = Partial<
Pick<AutocompleteOptions<TItem>, 'onStateChange' | 'onSubmit' | 'getSources'>
> & {
/**
Expand Down

0 comments on commit fcf94ff

Please sign in to comment.