Socket
Socket
Sign inDemoInstall

@choc-ui/chakra-autocomplete

Package Overview
Dependencies
Maintainers
2
Versions
120
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@choc-ui/chakra-autocomplete


Version published
Weekly downloads
12K
decreased by-14.41%
Maintainers
2
Weekly downloads
ย 
Created
Source


๐Ÿ‡
@choc-ui/chakra-autocomplete



npm package npm  downloads NPM

GitHub Repo stars

All Contributors


AutoComplete Component for the Chakra UI Library.

Install

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

Preview

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;
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.

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;
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.

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;
CleanShot 2021-07-29 at 01 29 46@2x

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;
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.

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;

Kapture 2021-07-29 at 02 05 53

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

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:

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

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.

PropTypeDescriptionDefault
closeOnBlurbooleanclose suggestions when input is blurred true
closeOnSelectbooleanclose suggestions when a suggestions is selectedtrue when multiple=false, false when multiple=true
creatablebooleanAllow addition of arbitrary values not present in suggestionsfalse
defaultIsOpenbooleanSuggestions list is open by defaultfalse
prefocusFirstItembooleanShould prefocus first item intially, on query change, on open, and on filter out of current focused itemtrue
defaultValuesArrayUsed to predefine tags, or value for the autocomplete component. Just pass an array of the valuesโ€”โ€”โ€”
disableFilterbooleandisables filtering when set to truefalse
emphasizeboolean | SystemStyleObjectHighlight matching characters in suggestions, you can pass the styles - falsefalse
emptyState
boolean | MaybeRenderProp<{ value: Item["value"] }>
render message when no suggestions match querytrue
filter
(query: string, optionValue: Item["value"], optionLabel: Item["label"]) =>
  boolean;
custom filter functionโ€”โ€”โ€”
focusInputOnSelectbooleanfocus input after a suggestion is selected true
freeSolobooleanallow entering of any arbitrary valuesfalse
isReadOnlybooleanMake the component read-onlyfalse
isLoadingbooleanDisplay loading animation on both the input and list elementsfalse
listAllValuesOnFocusbooleanShow all suggestions when user focuses the input, while it's not empty.false
maxSelectionsnumberlimit possible number of tag selections in multiple modeโ€”โ€”โ€”
maxSuggestionsnumberlimit number of suggestions in listโ€”โ€”โ€”
multiplebooleanallow tags multi selectionfalse
onChange
(value: string | Item["value"][], item: Item| Item[]) => void
function to run whenever autocomplete value(s) changesโ€”โ€”โ€”
onSelectOption
(params: {
    item: Item;
    selectMethod: "mouse" | "keyboard" | null;
    isNewInput: boolean;
  }) => boolean | void
method to call whenever a suggestion is selectedโ€”โ€”โ€”
onOptionFocus
(params: {
    item: Item;
    focusMethod: "mouse" | "keyboard" | null;
    isNewInput: boolean;
  }) => boolean | void
method to call whenever a suggestion is focusedโ€”โ€”โ€”
onReady
(props:{tags:ItemTag[]}) => void
method that exposes variables used in componentโ€”โ€”โ€”
onTagRemoved
(removedTag: Item["value"],item: Item, tags: Item["value"][]) => void
method to call whenever a tag is removedโ€”โ€”โ€”
openOnFocusbooleanopen suggestions when input is focusesfalse
placementPlacementWithLogicalwhere autocomplete list will display. Accepts any valid value from Popover componentbottom
restoreOnBlurIfEmptybooleanif false, clearing the value of the input field will also clear the selected optiontrue
rollNavigationbooleanallow keyboard navigation to switch to alternate ends when one end is reachedfalse
selectOnFocusbooleanselect the text in input when it's focusedfalse
shouldRenderSuggestions
(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;
string[]
A list of KeyboardEvent: key values, except for the "Enter" key, that trigger the click event of the currently selected Item.โ€”โ€”โ€”
suggestWhenEmptybooleanshow suggestions when input value is emptyfalse
valueanyvalue of the component in the controlled state---

AutoCompleteTag

Tags for multiple mode

AutoCompleteTag composes Tag so you can pass all Tag props to change its style.

Prop
TypeDescriptionRequiredDefault
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 tagYes
โ€”โ€”โ€”
onRemove
() => void
Method to remove the tag from selected valuesYes
โ€”โ€”โ€”

AutoCompleteInput

Input for AutoComplete value.

AutoCompleteInput composes Input so you can pass all Input props to change its style.

Prop
TypeDescriptionRequiredDefault
children
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>
No
โ€”โ€”โ€”
ref
RefObject<HTMLInputElement>
provides a ref to the input element so the value can be referenced in additional contextsNo
โ€”โ€”โ€”
hidePlaceholderbooleanhides the placeholder when children is not an empty array. intended usage for
<AutoComplete multiple creatable />
No
false
loadingIcon
React.ReactNode | JSX
Element that will be displayed when isLoading is trueNoSpinner from Chakra-UI

AutoCompleteList

Wrapper for AutoCompleteGroup and AutoCompleteItem

AutoCompleteList composes Box so you can pass all Box props to change its style.

Prop
TypeDescriptionRequiredDefault
loadingStateReact.ReactNode | JSXContent displayed in list while isLoading is true. Content will be centeredNoSpinner from Chakra-UI with an md size

AutoCompleteGroup

Wrapper for collections of AutoCompleteItems

AutoCompleteGroup composes Box so you can pass all Box props to change its style.

Prop
TypeDescriptionRequiredDefault
showDividerbooleanIf true, a divider is shownNofalse
dividerColorstringColor for divider, if presentNoinherit

AutoCompleteItem

This Composes your suggestions

AutoCompleteItem composes Flex so you can pass all Flex props to change its style.

Prop
TypeDescriptionRequiredDefault
getValue(value:any) => anyA method used to determine the key that holds the value, when the value prop is an objectno
val => val;
labelstringThe label for the Optionno
โ€”โ€”โ€”
valuestring or ObjectThe value of the Optionyes
โ€”โ€”โ€”
fixed
boolean
Make an item visible at all times, regardless of filtering or maxSuggestionsNoโ€”โ€”โ€”
_fixedSystemStyleObjectStyles for fixed ItemmNo
{
  fontWeight: 'extrabold',
}
valuestringThe value of the Optionyes
โ€”โ€”โ€”
disabled
boolean
Make an item disabled, so it cannot be selectedNoโ€”โ€”โ€”
_disabledSystemStyleObjectStyles for disabled Item(s)No
{
  fontWeight: 'extrabold',
}
_selectedSystemStyleObjectStyles for selected Item(s)No
{
  fontWeight: 'extrabold',
}
_focusSystemStyleObjectStyles for focused ItemNo
{
  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.

Prop
TypeDescriptionRequiredDefault
children
type children = MaybeRenderProp<{ value: any }>;

ReactNode or callback that returns ReactNode e.g.

<AutoCompleteCreatable>
  {({ value }) => <span>Add {value} to List</span>}
</AutoCompleteCreatable>
No
โ€”โ€”โ€”
alwaysDisplay
boolean;

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

No
โ€”โ€”โ€”

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
yarn

Start the package server, and the example server

# root directory
yarn start

# example directory with (cd example)
yarn dev

Sponsors โœจ

Thanks goes to these wonderful people (emoji key):

Contributors โœจ

Thanks goes to these wonderful people (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

๐Ÿ“–๐Ÿ›

This project follows the all-contributors specification. Contributions of any kind welcome!

FAQs

Package last updated on 22 May 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with โšก๏ธ by Socket Inc