Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/anubra266/choc-autocomplete

🏇 Autocomplete Component Package for Chakra UI
https://github.com/anubra266/choc-autocomplete

anubra266 autocomplete chakra-ui choc-ui combobox dropdown hacktoberfest react select

Last synced: 18 days ago
JSON representation

🏇 Autocomplete Component Package for Chakra UI

Awesome Lists containing this project

README

        




🏇


@choc-ui/chakra-autocomplete











npm package


npm  downloads


NPM

GitHub Repo stars

[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors-)




AutoComplete Component for the Chakra UI Library.


## Install

```bash
npm i --save @choc-ui/chakra-autocomplete
#or
yarn add @choc-ui/chakra-autocomplete
```

## Preview

### With Mouse

![](./assets/mouse.gif)

### With Keyboard

![](./assets/keyboard.gif)

## Usage

### Basic Usage

```js
import { Flex, FormControl, FormHelperText, FormLabel } from "@chakra-ui/react";
import * as React from "react";
import {
AutoComplete,
AutoCompleteInput,
AutoCompleteItem,
AutoCompleteList,
} from "@choc-ui/chakra-autocomplete";

function App() {
const countries = [
"nigeria",
"japan",
"india",
"united states",
"south korea",
];

return (


Olympics Soccer Winner



{countries.map((country, cid) => (

{country}

))}


Who do you support.


);
}

export default App;
```

CleanShot 2021-07-28 at 23 47 57@2x

### Creating Groups

You can create groups with the `AutoCompleteGroup` Component, and add a title with the `AutoCompleteGroupTitle` component.

```js
import { Flex, FormControl, FormHelperText, FormLabel } from "@chakra-ui/react";
import * as React from "react";
import {
AutoComplete,
AutoCompleteGroup,
AutoCompleteGroupTitle,
AutoCompleteInput,
AutoCompleteItem,
AutoCompleteList,
} from "@choc-ui/chakra-autocomplete";

function App() {
const continents = {
africa: ["nigeria", "south africa"],
asia: ["japan", "south korea"],
europe: ["united kingdom", "russia"],
};

return (


Olympics Soccer Winner



{Object.entries(continents).map(([continent, countries], co_id) => (


{continent}

{countries.map((country, c_id) => (

{country}

))}

))}


Who do you support.


);
}

export default App;
```

CleanShot 2021-07-29 at 01 18 47@2x

## Accessing the internal state

To access the internal state of the `AutoComplete`, use a function as children (commonly known as a render prop). You'll get access to the internal state `isOpen`, with the `onOpen` and `onClose` methods.

```js
import {
Flex,
FormControl,
FormHelperText,
FormLabel,
Icon,
InputGroup,
InputRightElement,
} from "@chakra-ui/react";
import * as React from "react";
import {
AutoComplete,
AutoCompleteInput,
AutoCompleteItem,
AutoCompleteList,
} from "@choc-ui/chakra-autocomplete";
import { FiChevronRight, FiChevronDown } from "react-icons/fi";

function App() {
const countries = [
"nigeria",
"japan",
"india",
"united states",
"south korea",
];

return (


Olympics Soccer Winner

{({ isOpen }) => (
<>



}
/>


{countries.map((country, cid) => (

{country}

))}

>
)}

Who do you support.


);
}

export default App;
```

CleanShot 2021-07-29 at 01 29 46@2x

## Custom Rendering

You can Render whatever you want. The `AutoComplete` Items are regular `Chakra` Boxes.

```js
import {
Avatar,
Flex,
FormControl,
FormHelperText,
FormLabel,
Text,
} from "@chakra-ui/react";
import * as React from "react";
import {
AutoComplete,
AutoCompleteInput,
AutoCompleteItem,
AutoCompleteList,
} from "@choc-ui/chakra-autocomplete";

function App() {
const people = [
{ name: "Dan Abramov", image: "https://bit.ly/dan-abramov" },
{ name: "Kent Dodds", image: "https://bit.ly/kent-c-dodds" },
{ name: "Segun Adebayo", image: "https://bit.ly/sage-adebayo" },
{ name: "Prosper Otemuyiwa", image: "https://bit.ly/prosper-baba" },
{ name: "Ryan Florence", image: "https://bit.ly/ryan-florence" },
];

return (


Olympics Soccer Winner



{people.map((person, oid) => (


{person.name}

))}


Who do you support.


);
}

export default App;
```

CleanShot 2021-07-29 at 01 35 03@2x

## Multi Select with Tags

Add the `multiple` prop to `AutoComplete` component, the `AutoCompleteInput` will now expose the tags in it's children function.
The `onChange` prop now returns an array of the chosen `values`

Now you can map the tags with the `AutoCompleteTag` component or any other component of your choice. The `label` and the `onRemove` method are now exposed.

```js
import { Flex, FormControl, FormHelperText, FormLabel } from "@chakra-ui/react";
import * as React from "react";
import {
AutoComplete,
AutoCompleteInput,
AutoCompleteItem,
AutoCompleteList,
AutoCompleteTag,
} from "@choc-ui/chakra-autocomplete";

function App() {
const countries = [
"nigeria",
"japan",
"india",
"united states",
"south korea",
];

return (


Olympics Soccer Winner
console.log(vals)}>

{({ tags }) =>
tags.map((tag, tid) => (

))
}


{countries.map((country, cid) => (

{country}

))}


Who do you support.


);
}

export default App;
```

![Kapture 2021-07-29 at 02 05 53](https://user-images.githubusercontent.com/30869823/127415996-09a5df7c-a356-4a22-ad9c-60d09963cfc6.gif)

## Creatable Items

I know that title hardly expresses the point, but yeah, naming is tough. You might want your users to be able to add extra items when their options are not available in the provided options. e.g. adding a new tag to your Polywork profile.

First add the `creatable` prop to the `AutoComplete` component.
Then add the `AutoCompleteCreatable` component to the bottom of the list. Refer to the references for more info on this component.

CleanShot 2021-07-29 at 02 29 20@2x

## Loading State

Need to pull data from API, but don't want your users to see a blank screen? You can enable the loading state by passing the `isLoading` prop to `AutoComplete`. By doing this, 2 other props will be enabled

1. `loadingIcon` on `AutoCompleteInput` will display some sort of loading icon on the right side of the input. By default, a `Spinner` will be displayed, but you can pass in any custom element to be rendered

2. `loadingState` on `AutoCompleteList` can display custom loading content when `isLoading` is `true`. All content will be rendered in the center of the list. By default, a `Spinner` will be displayed, but you can pass in any custom element to be rendered.

Best practice is to combine `setTimeout` and `useEffect` to create a debounce effect. This will prevent un-necessary API calls if your user types relatively quickly.

A working code demo can be found [here](https://codesandbox.io/s/choc-ui-chakra-autocomplete-loading-tfc8jz)

## Integration with Form Libraries

It is relatively easy to integrate with form libaries such as `React Hook Form`, `Formik`, and others. Working examples can be found in the `demos` folder of this repo. See the [Contributing](#contribute) section of this doc on how to clone and set it up for testing.

Does your favorite form library not have a working example? Submit a PR to get it added and help others using this library quickly get up and running.

## Autocomplete methods

Assign a ref to the `AutoComplete` component and call the available methods with:

```js
ref.current?.resetItems();
ref.current?.removeItem(itemValue);
```

### Codesandbox Link [Here](https://githubbox.com/anubra266/choc-autocomplete/tree/main/demo)

## API Reference

**NB**: Feel free to request any additional `Prop` in [Issues](https://github.com/anubra266/choc-autocomplete/issues/new/).

### **AutoComplete**

Wrapper and Provider for `AutoCompleteInput` and `AutoCompleteList`

**AutoComplete** composes [**Box**](https://chakra-ui.com/docs/layout/box) so you can pass all Box props to change its style.

**NB:** None of the props passed to it are required.



Prop
Type
Description
Default




closeOnBlur
boolean
close suggestions when input is blurred
true


closeOnSelect
boolean
close suggestions when a suggestions is selected
true when multiple=false, false when multiple=true


creatable
boolean
Allow addition of arbitrary values not present in suggestions
false


defaultIsOpen
boolean
Suggestions list is open by default
false


prefocusFirstItem
boolean
Should prefocus first item intially, on query change, on open, and on filter out of current focused item
true


defaultValues
Array
Used to predefine tags, or value for the autocomplete component. Just pass an array of the values
———


disableFilter
boolean
disables filtering when set to true
false


emphasize
boolean | SystemStyleObject
Highlight matching characters in suggestions, you can pass the styles - false
false


defaultEmptyStateProps
FlexProps
Props to pass into the `Flex` component when using the default empty state. Does not apply when you supply your own custom `emptyState`
———


emptyState

```ts
boolean | MaybeRenderProp<{ value: Item["value"] }>
```

render message when no suggestions match query
true


filter

```ts
(query: string, optionValue: Item["value"], optionLabel: Item["label"]) =>
boolean;
```

custom filter function
———


focusInputOnSelect
boolean
focus input after a suggestion is selected
true


freeSolo
boolean
allow entering of any arbitrary values
false


isReadOnly
boolean
Make the component read-only
false


isLoading
boolean
Display loading animation on both the input and list elements
false


listAllValuesOnFocus
boolean
Show all suggestions when user focuses the input, while it's not empty.
false


matchWidth
boolean
Chakra UI Popover.matchWidth property to match the popover content's width to the width of the container
true


maxSelections
number
limit possible number of tag selections in multiple mode
———


maxSuggestions
number
limit number of suggestions in list
———


multiple
boolean
allow tags multi selection
false


onChange

```ts
(value: string | Item["value"][], item: Item| Item[]) => void
```

function to run whenever autocomplete value(s) changes
———


onSelectOption

```ts
(params: {
item: Item;
selectMethod: "mouse" | "keyboard" | null;
isNewInput: boolean;
}) => boolean | void
```

method to call whenever a suggestion is selected
———


onOptionFocus

```ts
(params: {
item: Item;
focusMethod: "mouse" | "keyboard" | null;
isNewInput: boolean;
}) => boolean | void
```

method to call whenever a suggestion is focused
———


onReady

```ts
(props:{tags:ItemTag[]}) => void
```

method that exposes variables used in component
———


onTagRemoved

```ts
(removedTag: Item["value"],item: Item, tags: Item["value"][]) => void
```

method to call whenever a tag is removed
———


openOnFocus
boolean
open suggestions when input is focuses
false


placement
PlacementWithLogical
where autocomplete list will display. Accepts any valid value from Popover component
bottom


restoreOnBlurIfEmpty
boolean
if false, clearing the value of the input field will also clear the selected option
true


rollNavigation
boolean
allow keyboard navigation to switch to alternate ends when one end is reached
false


selectOnFocus
boolean
select the text in input when it's focused
false


shouldRenderSuggestions

```ts
(value: string) => boolean
```

function to decide if suggestions should render, e.g. show suggestions only if there are at least two characters in the query value
———


submitKeys;

```ts
string[]
```

A list of KeyboardEvent: key values, except for the "Enter" key, that trigger the click event of the currently selected Item.
———


suggestWhenEmpty
boolean
show suggestions when input value is empty
false


value
any
value of the component in the controlled state
---

### **AutoCompleteTag**

Tags for multiple mode

**AutoCompleteTag** composes [**Tag**](https://chakra-ui.com/docs/data-display/tag) so you can pass all Tag props to change its style.


Prop

Type
Description
Required
Default


disabled

string


In the event that you need to lock certain tag so that they can't be removed in the interface, you can set the tags disabled.
No

———


label

string


Label that is displayed on the tag
Yes

———


onRemove

```ts
() => void
```


Method to remove the tag from selected values
Yes

———

### **AutoCompleteInput**

Input for `AutoComplete` value.

**AutoCompleteInput** composes [**Input**](https://chakra-ui.com/docs/form/input) so you can pass all Input props to change its style.


Prop

Type
Description
Required
Default


children

```ts
type children = MaybeRenderProp<{
tags: Item & { onRemove: () => void }[];
}>;
```


callback that returns `ReactNode` and is provided with tags in `multiple` mode
e.g.

```js

{({ tags }) =>
tags.map((tag, tid) => (

))
}

```


No

———


ref

```js
RefObject
```


provides a ref to the input element so the value can be referenced in additional contexts
No

———


hidePlaceholder
boolean
hides the placeholder when children is not an empty array. intended usage for

```js

```


No

false



loadingIcon

React.ReactNode | JSX


Element that will be displayed when isLoading is true
No
Spinner from Chakra-UI

### **AutoCompleteList**

Wrapper for `AutoCompleteGroup` and `AutoCompleteItem`

**AutoCompleteList** composes [**Box**](https://chakra-ui.com/docs/layout/box) so you can pass all Box props to change its style.


Prop

Type
Description
Required
Default


loadingState
React.ReactNode | JSX
Content displayed in list while isLoading is true. Content will be centered
No
Spinner from Chakra-UI with an md size

### **AutoCompleteGroup**

Wrapper for collections of `AutoCompleteItem`s

**AutoCompleteGroup** composes [**Box**](https://chakra-ui.com/docs/layout/box) so you can pass all Box props to change its style.


Prop

Type
Description
Required
Default


showDivider
boolean
If true, a divider is shown
No
false


dividerColor
string
Color for divider, if present
No
inherit

### **AutoCompleteItem**

This Composes your suggestions

**AutoCompleteItem** composes [**Flex**](https://chakra-ui.com/docs/layout/flex) so you can pass all Flex props to change its style.


Prop

Type
Description
Required
Default


getValue
(value:any) => any
A method used to determine the key that holds the value, when the value prop is an object
no

```js
val => val;
```



label
string
The label for the Option
no

———


value
string or Object
The value of the Option
yes

———


fixed

boolean

Make an item visible at all times, regardless of filtering or maxSuggestions
No
———

_fixed
SystemStyleObject
Styles for fixed Itemm
No

```js
{
fontWeight: 'extrabold',
}
```

value
string
The value of the Option
yes

———


disabled

boolean

Make an item disabled, so it cannot be selected
No
———

_disabled
SystemStyleObject
Styles for disabled Item(s)
No

```js
{
fontWeight: 'extrabold',
}
```

_selected
SystemStyleObject
Styles for selected Item(s)
No

```js
{
fontWeight: 'extrabold',
}
```

_focus
SystemStyleObject
Styles for focused Item
No

```js
{
fontWeight: 'extrabold',
}
```

### **AutoCompleteCreatable**

Used with the `AutoComplete` component's `creatable` prop, to allow users enter arbitrary values, not available in the provided options.

**AutoCompleteCreatable** composes [**Flex**](https://chakra-ui.com/docs/layout/flex) so you can pass all Flex props to change its style.

It also accepts a function as its `children` prop which is provided with the current `inputValue`.


Prop

Type
Description
Required
Default


children

```ts
type children = MaybeRenderProp<{ value: any }>;
```


`ReactNode` or callback that returns `ReactNode`
e.g.

```js

{({ value }) => Add {value} to List}

```


No

———


alwaysDisplay

```ts
boolean;
```


When true, `AutoCompleteCreatable` is shown even when the `AutoCompleteInput` is empty


No

———

## Contribute

- Clone this repository

```sh
git clone https://github.com/anubra266/choc-autocomplete.git
```

- Install all dependencies (with yarn)

```sh
yarn
```

- Install package example dependencies (with yarn)

```sh
cd example
yarn
```

Start the package server, and the example server

```sh
# root directory
yarn start

# example directory with (cd example)
yarn dev
```

## Sponsors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):





## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):



Maicon Carraro

💻

Sam Margalit

📖

gepd

💻 🐛

Spencer Kaiser

📖

jcdogo

💻

daliudzius

💻

Fabien BERNARD

💻



Riccardo Lorenzi

🐛

Mathis Federico

🐛

Kyle Slusser

💻🐛

Karl F. Sellergren

🐛🔧

Jedediah Benhod

🐛

Janusz Kacalak

🐛

Thomas Hickman

🐛



Christopher Regner

📖🐛

EinarSnorrason

💻🐛🔧

gbermudez1992

💻🐛🔧

ido213

💻🐛🔧

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!