<br/>
🏇
<br />
@choc-ui/chakra-autocomplete
<br />
<br />
<br />
<br />
<a href="https://www.npmjs.com/package/@choc-ui/chakra-autocomplete?style=for-the-badge">
<img src="https://img.shields.io/npm/v/@choc-ui/chakra-autocomplete.svg?style=for-the-badge" alt="npm package" />
</a>
<a href="https://www.npmjs.com/package/@choc-ui/chakra-autocomplete?style=for-the-badge">
<img src="https://img.shields.io/npm/dw/@choc-ui/chakra-autocomplete.svg?style=for-the-badge" alt="npm downloads" />
</a>
<img alt="NPM" src="https://img.shields.io/npm/l/@choc-ui/chakra-autocomplete?style=for-the-badge">
<br />
AutoComplete Component for the <a href="https://chakra-ui.com">Chakra UI</a> Library.</em>
npm i @choc-ui/chakra-autocomplete
Install
```bash
npm i --save @choc-ui/chakra-autocomplete
or
yarn add @choc-ui/chakra-autocomplete
```
Preview
With Mouse
With Keyboard
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 (
<Flex pt="48" justify="center" align="center" w="full">
<FormControl w="60">
<FormLabel>Olympics Soccer Winner</FormLabel>
<AutoComplete openOnFocus>
<AutoCompleteInput variant="filled" />
<AutoCompleteList>
{countries.map((country, cid) => (
<AutoCompleteItem
key={`option-${cid}`}
value={country}
textTransform="capitalize"
>
{country}
</AutoCompleteItem>
))}
</AutoCompleteList>
</AutoComplete>
<FormHelperText>Who do you support.</FormHelperText>
</FormControl>
</Flex>
);
}
export default App;
```
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 (
<Flex pt="48" justify="center" align="center" w="full">
<FormControl w="60">
<FormLabel>Olympics Soccer Winner</FormLabel>
<AutoComplete openOnFocus>
<AutoCompleteInput variant="filled" />
<AutoCompleteList>
{Object.entries(continents).map(([continent, countries], co_id) => (
<AutoCompleteGroup key={co_id} showDivider>
<AutoCompleteGroupTitle textTransform="capitalize">
{continent}
</AutoCompleteGroupTitle>
{countries.map((country, c_id) => (
<AutoCompleteItem
key={c_id}
value={country}
textTransform="capitalize"
>
{country}
</AutoCompleteItem>
))}
</AutoCompleteGroup>
))}
</AutoCompleteList>
</AutoComplete>
<FormHelperText>Who do you support.</FormHelperText>
</FormControl>
</Flex>
);
}
export default App;
```
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 (
<Flex pt="48" justify="center" align="center" w="full">
<FormControl w="60">
<FormLabel>Olympics Soccer Winner</FormLabel>
<AutoComplete openOnFocus>
{({ isOpen }) => (
<>
<InputGroup>
<AutoCompleteInput variant="filled" placeholder="Search..." />
<InputRightElement
children={
<Icon as={isOpen ? FiChevronRight : FiChevronDown} />
}
/>
</InputGroup>
<AutoCompleteList>
{countries.map((country, cid) => (
<AutoCompleteItem
key={`option-${cid}`}
value={country}
textTransform="capitalize"
>
{country}
</AutoCompleteItem>
))}
</AutoCompleteList>
</>
)}
</AutoComplete>
<FormHelperText>Who do you support.</FormHelperText>
</FormControl>
</Flex>
);
}
export default App;
```
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 (
<Flex pt="48" justify="center" align="center" w="full" direction="column">
<FormControl id="email" w="60">
<FormLabel>Olympics Soccer Winner</FormLabel>
<AutoComplete openOnFocus>
<AutoCompleteInput variant="filled" />
<AutoCompleteList>
{people.map((person, oid) => (
<AutoCompleteItem
key={`option-${oid}`}
value={person.name}
textTransform="capitalize"
align="center"
>
<Avatar size="sm" name={person.name} src={person.image} />
<Text ml="4">{person.name}</Text>
</AutoCompleteItem>
))}
</AutoCompleteList>
</AutoComplete>
<FormHelperText>Who do you support.</FormHelperText>
</FormControl>
</Flex>
);
}
export default App;
```
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 (
<Flex pt="48" justify="center" align="center" w="full" direction="column">
<FormControl id="email" w="60">
<FormLabel>Olympics Soccer Winner</FormLabel>
<AutoComplete openOnFocus multiple onChange={vals => console.log(vals)}>
<AutoCompleteInput variant="filled">
{({ tags }) =>
tags.map((tag, tid) => (
<AutoCompleteTag
key={tid}
label={tag.label}
onRemove={tag.onRemove}
/>
))
}
</AutoCompleteInput>
<AutoCompleteList>
{countries.map((country, cid) => (
<AutoCompleteItem
key={`option-${cid}`}
value={country}
textTransform="capitalize"
_selected={{ bg: "whiteAlpha.50" }}
_focus={{ bg: "whiteAlpha.100" }}
>
{country}
</AutoCompleteItem>
))}
</AutoCompleteList>
</AutoComplete>
<FormHelperText>Who do you support.</FormHelperText>
</FormControl>
</Flex>
);
}
export default App;
```
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.
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
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
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
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 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
API Reference
NB: Feel free to request any additional
Prop
in
Issues.
AutoComplete
Wrapper and Provider for
AutoCompleteInput
and
AutoCompleteList
AutoComplete composes
Box so you can pass all Box props to change its style.
NB: None of the props passed to it are required.
<thead>
<tr>
<td>Prop</td>
<td>Type</td>
<td>Description</td>
<td>Default</td>
</tr>
</thead>
<tbody>
<tr>
<td>closeOnBlur</td>
<td>boolean</td>
<td>close suggestions when input is blurred </td>
<td>true</td>
</tr>
<tr>
<td>closeOnSelect</td>
<td>boolean</td>
<td>close suggestions when a suggestions is selected</td>
<td>true when multiple=false, false when multiple=true</td>
</tr>
<tr>
<td>creatable</td>
<td>boolean</td>
<td>Allow addition of arbitrary values not present in suggestions</td>
<td>false</td>
</tr>
<tr>
<td>defaultIsOpen</td>
<td>boolean</td>
<td>Suggestions list is open by default</td>
<td>false</td>
</tr>
<tr>
<td>prefocusFirstItem</td>
<td>boolean</td>
<td>Should prefocus first item intially, on query change, on open, and on filter out of current focused item</td>
<td>true</td>
</tr>
<tr>
<td>defaultValues</td>
<td>Array</td>
<td>Used to predefine tags, or value for the autocomplete component. Just pass an array of the values</td>
<td>———</td>
</tr>
<tr>
<td>disableFilter</td>
<td>boolean</td>
<td>disables filtering when set to true</td>
<td>false</td>
</tr>
<tr>
<td>emphasize</td>
<td>boolean | SystemStyleObject</td>
<td>Highlight matching characters in suggestions, you can pass the styles - false</td>
<td>false</td>
</tr>
<tr>
<td>emptyState</td>
<td>
```ts
boolean | MaybeRenderProp<{ value: Item"value" }>
```
<td>render message when no suggestions match query</td>
<td>true</td>
</tr>
<tr>
<td>filter</td>
<td>
```ts
(query: string, optionValue: Item"value", optionLabel: Item"label") =>
boolean;
```
<td>custom filter function</td>
<td>———</td>
</tr>
<tr>
<td>focusInputOnSelect</td>
<td>boolean</td>
<td>focus input after a suggestion is selected </td>
<td>true</td>
</tr>
<tr>
<td>freeSolo</td>
<td>boolean</td>
<td>allow entering of any arbitrary values</td>
<td>false</td>
</tr>
<tr>
<td>isReadOnly</td>
<td>boolean</td>
<td>Make the component read-only</td>
<td>false</td>
</tr>
<tr>
<td>isLoading</td>
<td>boolean</td>
<td>Display loading animation on both the input and list elements</td>
<td>false</td>
</tr>
<tr>
<td>listAllValuesOnFocus</td>
<td>boolean</td>
<td>Show all suggestions when user focuses the input, while it's not empty.</td>
<td>false</td>
</tr>
<tr>
<td>maxSelections</td>
<td>number</td>
<td>limit possible number of tag selections in multiple mode</td>
<td>———</td>
</tr>
<tr>
<td>maxSuggestions</td>
<td>number</td>
<td>limit number of suggestions in list</td>
<td>———</td>
</tr>
<tr>
<td>multiple</td>
<td>boolean</td>
<td>allow tags multi selection</td>
<td>false</td>
</tr>
<tr>
<td>onChange</td>
<td>
```ts
(value: string | Item"value", item: Item| Item) => void
```
<td>function to run whenever autocomplete value(s) changes</td>
<td>———</td>
</tr>
<tr>
<td>onSelectOption</td>
<td>
```ts
(params: {
item: Item;
selectMethod: "mouse" | "keyboard" | null;
isNewInput: boolean;
}) => boolean | void
```
<td>method to call whenever a suggestion is selected</td>
<td>———</td>
</tr>
<tr>
<td>onOptionFocus</td>
<td>
```ts
(params: {
item: Item;
focusMethod: "mouse" | "keyboard" | null;
isNewInput: boolean;
}) => boolean | void
```
<td>method to call whenever a suggestion is focused</td>
<td>———</td>
</tr>
<tr>
<td>onReady</td>
<td>
```ts
(props:{tags:ItemTag}) => void
```
<td>method that exposes variables used in component</td>
<td>———</td>
</tr>
<tr>
<td>onTagRemoved</td>
<td>
```ts
(removedTag: Item"value",item: Item, tags: Item"value") => void
```
<td>method to call whenever a tag is removed</td>
<td>———</td>
</tr>
<tr>
<td>openOnFocus</td>
<td>boolean</td>
<td>open suggestions when input is focuses</td>
<td>false</td>
</tr>
<tr>
<td>placement</td>
<td>PlacementWithLogical</td>
<td>where autocomplete list will display. Accepts any valid value from <a href="https://chakra-ui.com/docs/components/popover#popover-placements">Popover</a> component</td>
<td>bottom</td>
</tr>
<tr>
<td>restoreOnBlurIfEmpty</td>
<td>boolean</td>
<td>if false, clearing the value of the input field will also clear the selected option</td>
<td>true</td>
</tr>
<tr>
<td>rollNavigation</td>
<td>boolean</td>
<td>allow keyboard navigation to switch to alternate ends when one end is reached</td>
<td>false</td>
</tr>
<tr>
<td>selectOnFocus</td>
<td>boolean</td>
<td>select the text in input when it's focused</td>
<td>false</td>
</tr>
<tr>
<td>shouldRenderSuggestions</td>
<td>
```ts
(value: string) => boolean
```
<td>function to decide if suggestions should render, e.g. show suggestions only if there are at least two characters in the query value</td>
<td>———</td>
</tr>
<tr>
<td>submitKeys;
<td>
```ts
string
```
<td>A list of <a href="https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values">KeyboardEvent: key values</a>, except for the "Enter" key, that trigger the click event of the currently selected Item.</td>
<td>———</td>
</tr>
<tr>
<td>suggestWhenEmpty</td>
<td>boolean</td>
<td>show suggestions when input value is empty</td>
<td>false</td>
</tr>
<tr>
<td>value</td>
<td>any</td>
<td>value of the component in the controlled state</td>
<td>---</td>
</tr>
</tbody>
AutoCompleteTag
Tags for multiple mode
AutoCompleteTag composes
Tag so you can pass all Tag props to change its style.
<th>Prop<br></th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
<th>Default</th>
<td>disabled</td>
<td>
string
<td>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.</td>
<td>No<br></td>
<td>———</td>
<td>label</td>
<td>
string
<td>Label that is displayed on the tag</td>
<td>Yes<br></td>
<td>———</td>
<td>onRemove</td>
<td>
```ts
() => void
```
<td>Method to remove the tag from selected values</td>
<td>Yes<br></td>
<td>———</td>
AutoCompleteInput
Input for
AutoComplete
value.
AutoCompleteInput composes
Input so you can pass all Input props to change its style.
<th>Prop<br></th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
<th>Default</th>
<td>children</td>
<td>
```ts
type children = MaybeRenderProp<{
tags: Item & { onRemove: () => void };
}>;
```
<td>
callback that returns ReactNode
and is provided with tags in multiple
mode
e.g.
```js
{({ tags }) =>
tags.map((tag, tid) => (
<AutoCompleteTag key={tid} label={tag.label} onRemove={tag.onRemove} />
))
}
```
<td>No<br></td>
<td>———</td>
<td>ref</td>
<td>
```js
RefObject
```
<td>provides a ref to the input element so the value can be referenced in additional contexts</td>
<td>No<br></td>
<td>———</td>
<td>hidePlaceholder</td>
<td>boolean</td>
<td>hides the placeholder when children is not an empty array. intended usage for
```js
```
<td>No<br></td>
<td>false</td>
<td>loadingIcon</td>
<td>
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 so you can pass all Box props to change its style.
<th>Prop<br></th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
<th>Default</th>
<td>loadingState</td>
<td>React.ReactNode | JSX</td>
<td>Content displayed in list while isLoading is true. Content will be centered</td>
<td>No</td>
<td><a href="https://chakra-ui.com/docs/components/spinner">Spinner</a> from Chakra-UI with an md size</td>
AutoCompleteGroup
Wrapper for collections of
AutoCompleteItem
s
AutoCompleteGroup composes
Box so you can pass all Box props to change its style.
<th>Prop<br></th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
<th>Default</th>
<td>showDivider</td>
<td>boolean</td>
<td>If true, a divider is shown</td>
<td>No</td>
<td>false</td>
<td>dividerColor</td>
<td>string</td>
<td>Color for divider, if present</td>
<td>No</td>
<td>inherit</td>
AutoCompleteItem
This Composes your suggestions
AutoCompleteItem composes
Flex so you can pass all Flex props to change its style.
<th>Prop<br></th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
<th>Default</th>
<td>getValue</td>
<td>(value:any) => any</td>
<td>A method used to determine the key that holds the value, when the value prop is an object</td>
<td>no<br></td>
<td>
```js
val => val;
```
<td>label</td>
<td>string</td>
<td>The label for the Option</td>
<td>no<br></td>
<td>———</td>
<td>value</td>
<td>string or Object</td>
<td>The value of the Option</td>
<td>yes<br></td>
<td>———</td>
<td>fixed</td>
<td>
boolean
<td>Make an item visible at all times, regardless of filtering or maxSuggestions</td>
<td>No</td>
<td>———</td>
<td>_fixed</td>
<td>SystemStyleObject</td>
<td>Styles for fixed Itemm</td>
<td>No</td>
<td>
```js
{
fontWeight: 'extrabold',
}
```
<td>value</td>
<td>string</td>
<td>The value of the Option</td>
<td>yes<br></td>
<td>———</td>
<td>disabled</td>
<td>
boolean
<td>Make an item disabled, so it cannot be selected</td>
<td>No</td>
<td>———</td>
<td>_disabled</td>
<td>SystemStyleObject</td>
<td>Styles for disabled Item(s)</td>
<td>No</td>
<td>
```js
{
fontWeight: 'extrabold',
}
```
<td>_selected</td>
<td>SystemStyleObject</td>
<td>Styles for selected Item(s)</td>
<td>No</td>
<td>
```js
{
fontWeight: 'extrabold',
}
```
<td>_focus</td>
<td>SystemStyleObject</td>
<td>Styles for focused Item</td>
<td>No</td>
<td>
```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 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
.
<th>Prop<br></th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
<th>Default</th>
<td>children</td>
<td>
```ts
type children = MaybeRenderProp<{ value: any }>;
```
<td>
ReactNode
or callback that returns ReactNode
e.g.
```js
{({ value }) => Add {value} to List}
```
<td>No<br></td>
<td>———</td>
<td>alwaysDisplay</td>
<td>
```ts
boolean;
```
<td>
When true, AutoCompleteCreatable
is shown even when the AutoCompleteInput
is empty
<td>No<br></td>
<td>———</td>
Contribute
```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):
<img src='https://cdn.jsdelivr.net/gh/anubra266/static@main/sponsors.svg'/>
Contributors ✨
Thanks goes to these wonderful people (
emoji key):
<td align="center"><a href="https://anubra266.tk"><img src="https://avatars.githubusercontent.com/u/30869823?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maicon Carraro</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=anubra266" title="Code">💻</a></td>
<td align="center"><a href="http://margalit.com.au"><img src="https://avatars.githubusercontent.com/u/2268424?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sam Margalit</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=margalit" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/gepd"><img src="https://avatars.githubusercontent.com/u/7091609?v=4?s=100" width="100px;" alt=""/><br /><sub><b>gepd</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=gepd" title="Code">💻</a> <a href="https://github.com/anubra266/choc-autocomplete/issues?q=author%3Agepd" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://www.linkedin.com/in/spencerkaiser"><img src="https://avatars.githubusercontent.com/u/6445731?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Spencer Kaiser</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=SpencerKaiser" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/jcdogo"><img src="https://avatars.githubusercontent.com/u/70533701?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jcdogo</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=jcdogo" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/daliudzius"><img src="https://avatars.githubusercontent.com/u/46355846?v=4?s=100" width="100px;" alt=""/><br /><sub><b>daliudzius</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=daliudzius" title="Code">💻</a></td>
<td align="center"><a href="https://fabien0102.com"><img src="https://avatars.githubusercontent.com/u/1761469?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabien BERNARD</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=fabien0102" title="Code">💻</a></td>
<td align="center"><a href="https://riccardolorenzi.com/"><img src="https://avatars.githubusercontent.com/u/5848941?v=4" width="100px;" alt=""/><br /><sub><b>Riccardo Lorenzi</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=Richi2293" title="Bug fixes">🐛</a></td>
<td align="center"><a href="https://github.com/MathisFederico"><img src="https://avatars.githubusercontent.com/u/60117466?v=4" width="100px;" alt=""/><br /><sub><b>Mathis Federico</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=MathisFederico" title="Bug">🐛</a></td>
<td align="center"><a href="https://github.com/Kysluss"><img src="https://avatars.githubusercontent.com/u/29052043?v=4" width="100px;" alt=""/><br /><sub><b>Kyle Slusser</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=Kysluss" title="Code">💻🐛</a></td>
<td align="center"><a href="https://github.com/sakerhetspolisen"><img src="https://avatars.githubusercontent.com/u/68159964?v=4" width="100px;" alt=""/><br /><sub><b>Karl F. Sellergren</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=sakerhetspolisen" title="Code">🐛🔧</a></td>
<td align="center"><a href="https://github.com/JedBh"><img src="https://avatars.githubusercontent.com/u/44101778?v=4" width="100px;" alt=""/><br /><sub><b>Jedediah Benhod</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=jedBh" title="Code">🐛</a></td>
<td align="center"><a href="https://github.com/Janekk"><img src="https://avatars.githubusercontent.com/u/6827881?v=4" width="100px;" alt=""/><br /><sub><b>Janusz Kacalak</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=janekk" title="Code">🐛</a></td>
<td align="center"><a href="https://github.com/ThomasHickman"><img src="https://avatars.githubusercontent.com/u/6304200?v=4" width="100px;" alt=""/><br /><sub><b>Thomas Hickman</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=thomashickman" title="Bug">🐛</a></td>
<td align="center"><a href="https://github.com/chrisregner"><img src="https://avatars.githubusercontent.com/u/26005158?v=4" width="100px;" alt=""/><br /><sub><b>Christopher Regner</b></sub></a><br /><a href="https://github.com/anubra266/choc-autocomplete/commits?author=chrisregner" title="Code">📖🐛</a></td>
This project follows the
all-contributors specification. Contributions of any kind welcome!