@fabien0102/chakra-autocomplete v4.20.1
Install
npm i --save @choc-ui/chakra-autocomplete
#or
yarn add @choc-ui/chakra-autocompletePreview
With Mouse

With Keyboard

Usage
Basic Usage
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.
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.
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.
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.
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.
Autocomplete methods
Assign a ref to the AutoComplete component and call the available methods with:
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.
boolean | MaybeRenderProp<{ value: Item["value"] }>(query: string, optionValue: Item["value"], optionLabel: Item["label"]) =>
boolean;(value: string | Item["value"][], item: Item| Item[]) => void(params: {
item: Item;
focusMethod: "mouse" | "keyboard" | null;
isNewInput: boolean;
}) => boolean | voidstring[]AutoCompleteTag
Tags for multiple mode
AutoCompleteTag composes Tag so you can pass all Tag props to change its style.
stringstring() => voidAutoCompleteInput
Input for AutoComplete value.
AutoCompleteInput composes Input so you can pass all Input props to change its style.
type children = MaybeRenderProp<{
tags: Item & { onRemove: () => void }[];
}>;callback that returns ReactNode and is provided with tags in multiple mode
e.g.
<AutoCompleteInput variant="filled">
{({ tags }) =>
tags.map((tag, tid) => (
<AutoCompleteTag key={tid} label={tag.label} onRemove={tag.onRemove} />
))
}
</AutoCompleteInput>RefObject<HTMLInputElement>AutoCompleteList
Wrapper for AutoCompleteGroup and AutoCompleteItem
AutoCompleteList composes Box so you can pass all Box props to change its style.
AutoCompleteGroup
Wrapper for collections of AutoCompleteItems
AutoCompleteGroup composes Box so you can pass all Box props to change its style.
AutoCompleteItem
This Composes your suggestions
AutoCompleteItem composes Flex so you can pass all Flex props to change its style.
val => val;booleanCSSObject{
fontWeight: 'extrabold',
}booleanCSSObject{
fontWeight: 'extrabold',
}CSSObject{
fontWeight: 'extrabold',
}CSSObject{
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.
type children = MaybeRenderProp<{ value: any }>;ReactNode or callback that returns ReactNode
e.g.
<AutoCompleteCreatable>
{({ value }) => <span>Add {value} to List</span>}
</AutoCompleteCreatable>booleanWhen true, AutoCompleteCreatable is shown even when the AutoCompleteInput is empty
Contribute
- Clone this repository
git clone https://github.com/anubra266/choc-autocomplete.git- Install all dependencies (with yarn)
yarn- Install package example dependencies (with yarn)
cd example
yarnStart the package server, and the example server
# root directory
yarn start
# example directory with (cd example)
yarn devContributors ✨
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
4 years ago