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

Commit

Permalink
feat: add openOnFocus and remove minLength (#31)
Browse files Browse the repository at this point in the history
* feat: add openOnFocus and remove minLength

* fix: adjust dropdown behavior after resetting based on openOnFocus prop

* Update README.md

Co-Authored-By: François Chalifour <francoischalifour@users.noreply.github.com>

* fix: reset the state on empty query

* fix: update conditions to check query length

* Update packages/autocomplete-core/src/types/api.ts

Co-Authored-By: François Chalifour <francoischalifour@users.noreply.github.com>

* fix: remove unnecessary condition

Co-authored-by: François Chalifour <francoischalifour@users.noreply.github.com>
  • Loading branch information
eunjae-lee and francoischalifour committed Feb 25, 2020
1 parent f771522 commit 553ea68
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 21 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ Whether to show the highlighted suggestion as completion in the input.

![`showCompletion` preview](https://user-images.githubusercontent.com/6137112/68124812-7e989800-ff10-11e9-88a5-f28c1466b665.png)

#### `minLength`
#### `openOnFocus`

> `number` | defaults to `1`
> `boolean` | defaults to `false`
The minimum number of characters long the autocomplete opens.
Whether to open the dropdown on focus when there's no query.

#### `autoFocus`

Expand Down
2 changes: 1 addition & 1 deletion examples/autocomplete.js/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const searchClient = algoliasearch(
autocomplete({
container: '#autocomplete',
placeholder: 'Search…',
minLength: 0,
openOnFocus: true,
showCompletion: true,
defaultHighlightedIndex: -1,
shouldDropdownOpen({ state }) {
Expand Down
2 changes: 1 addition & 1 deletion packages/autocomplete-core/src/defaultProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function getDefaultProps<TItem>(
: {}) as typeof window;

return {
minLength: 1,
openOnFocus: false,
placeholder: '',
autoFocus: false,
defaultHighlightedIndex: null,
Expand Down
4 changes: 2 additions & 2 deletions packages/autocomplete-core/src/onInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function onInput<TItem>({
setHighlightedIndex(props.defaultHighlightedIndex);
setQuery(query);

if (query.length < props.minLength) {
if (query.length === 0 && props.openOnFocus === false) {
setStatus('idle');
setSuggestions(
store.getState().suggestions.map(suggestion => ({
Expand Down Expand Up @@ -117,7 +117,7 @@ export function onInput<TItem>({
setSuggestions(suggestions as any);
setIsOpen(
nextState.isOpen ??
(query.length >= props.minLength &&
((query.length === 0 && props.openOnFocus) ||
props.shouldDropdownShow({ state: store.getState() }))
);
})
Expand Down
12 changes: 5 additions & 7 deletions packages/autocomplete-core/src/propGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export function getPropGetters<TItem>({
onReset: event => {
event.preventDefault();

if (props.minLength === 0) {
if (props.openOnFocus) {
onInput({
query: '',
store,
Expand All @@ -130,7 +130,6 @@ export function getPropGetters<TItem>({
setContext,
});
}

store.send('reset', null);

if (providedProps.inputElement) {
Expand All @@ -143,9 +142,9 @@ export function getPropGetters<TItem>({

const getInputProps: GetInputProps = providedProps => {
function onFocus() {
// We want to trigger a query when `minLength` is reached because the
// dropdown should open with the current query.
if (store.getState().query.length >= props.minLength) {
// We want to trigger a query when `openOnFocus` is true
// because the dropdown should open with the current query.
if (props.openOnFocus || store.getState().query.length > 0) {
onInput({
query: store.getState().query,
store,
Expand Down Expand Up @@ -227,8 +226,7 @@ export function getPropGetters<TItem>({
if (
providedProps.inputElement ===
props.environment.document.activeElement &&
!store.getState().isOpen &&
store.getState().query.length >= props.minLength
!store.getState().isOpen
) {
onFocus();
}
Expand Down
12 changes: 9 additions & 3 deletions packages/autocomplete-core/src/stateReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,14 @@ export const stateReducer: Reducer = (action, state, props) => {
case 'reset': {
return {
...state,
highlightedIndex: null,
isOpen: false,
highlightedIndex:
// Since we open the menu on reset when openOnFocus=true
// we need to restore the highlighted index to the defaultHighlightedIndex. (DocSearch use-case)

// Since we close the menu when openOnFocus=false
// we lose track of the highlighted index. (Query-suggestions use-case)
props.openOnFocus === true ? props.defaultHighlightedIndex : null,
isOpen: props.openOnFocus, // @TODO: Check with UX team if we want to close the menu on reset.
status: 'idle',
statusContext: {},
query: '',
Expand All @@ -115,7 +121,7 @@ export const stateReducer: Reducer = (action, state, props) => {
return {
...state,
highlightedIndex: props.defaultHighlightedIndex,
isOpen: state.query.length >= props.minLength,
isOpen: props.openOnFocus || state.query.length > 0,
};
}

Expand Down
8 changes: 4 additions & 4 deletions packages/autocomplete-core/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ export interface PublicAutocompleteOptions<TItem> {
*/
showCompletion?: boolean;
/**
* The minimum number of characters long the autocomplete opens.
* Whether to open the dropdown on focus when there's no query.
*
* @default 1
* @default false
*/
minLength?: number;
openOnFocus?: boolean;
/**
* The number of milliseconds that must elapse before the autocomplete
* experience is stalled.
Expand Down Expand Up @@ -229,7 +229,7 @@ export interface AutocompleteOptions<TItem> {
autoFocus: boolean;
defaultHighlightedIndex: number | null;
showCompletion: boolean;
minLength: number;
openOnFocus: boolean;
stallThreshold: number;
initialState: AutocompleteState<TItem>;
getSources: GetSources<TItem>;
Expand Down
40 changes: 40 additions & 0 deletions stories/react.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,46 @@ storiesOf('React', module)
container
);

return container;
})
)
.add(
'Open on focus',
withPlayground(({ container, dropdownContainer }) => {
render(
<Autocomplete
placeholder="Search items…"
showCompletion={true}
dropdownContainer={dropdownContainer}
defaultHighlightedIndex={0}
openOnFocus={true}
getSources={() => {
return [
{
getInputValue({ suggestion }) {
return suggestion.query;
},
getSuggestions({ query }) {
return getAlgoliaHits({
searchClient,
queries: [
{
indexName: 'instant_search_demo_query_suggestions',
query,
params: {
hitsPerPage: 4,
},
},
],
});
},
},
];
}}
/>,
container
);

return container;
})
);

0 comments on commit 553ea68

Please sign in to comment.