GithubHelp home page GithubHelp logo

anubra266 / choc-autocomplete Goto Github PK

View Code? Open in Web Editor NEW
390.0 2.0 46.0 3.59 MB

๐Ÿ‡ Autocomplete Component Package for Chakra UI

Home Page: https://githubbox.com/anubra266/choc-autocomplete/tree/main/demo

License: MIT License

HTML 0.80% TypeScript 95.56% CSS 2.12% JavaScript 1.52%
autocomplete combobox chakra-ui choc-ui anubra266 hacktoberfest react select dropdown

choc-autocomplete's Introduction


๐Ÿ‡
@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);

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.

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
emptyState
boolean | MaybeRenderProp<{ value: Item["value"] }>
render message when no suggestions match query true
filter
(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
(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 โ€”โ€”โ€”
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
(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. โ€”โ€”โ€”
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 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
() => void
Method to remove the tag from selected values Yes
โ€”โ€”โ€”

AutoCompleteInput

Input for AutoComplete value.

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

Prop
Type Description Required Default
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 contexts No
โ€”โ€”โ€”
hidePlaceholder boolean hides 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 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.

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 AutoCompleteItems

AutoCompleteGroup composes 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 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
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
{
  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
{
  fontWeight: 'extrabold',
}
_selected SystemStyleObject Styles for selected Item(s) No
{
  fontWeight: 'extrabold',
}
_focus SystemStyleObject Styles for focused Item No
{
  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
Type Description Required Default
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

๐Ÿ“–๐Ÿ›

EinarSnorrason

๐Ÿ’ป๐Ÿ›๐Ÿ”ง

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

choc-autocomplete's People

Contributors

allcontributors[bot] avatar anubra266 avatar chrisregner avatar daliudzius avatar dependabot[bot] avatar einarsnorrason avatar eric-hc avatar fabien0102 avatar jcdogo avatar kysluss avatar mathisfederico avatar naorpeled avatar richi2293 avatar sakerhetspolisen avatar spencerkaiser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

choc-autocomplete's Issues

Allow users to change the filter method

Should change this line for allowing a user to provide a custom function that filters the list.
Use case: I want a fuzzy search, so the function will receive the Input value, all options and the option value; perform the operation and return true to validate the option.

opt.value.toLowerCase().indexOf(inputValue.toLowerCase()) > -1 ||

use autocomplete with RHF

This is more a question than a issue. I'm trying to use this component with RHF

In my first try I did this:

     <Controller
        name={name}
        control={control}
        render={({ field: { onChange, onBlur, value } }) => (
            <AutoComplete freeSolo rollNavigation>
              <AutoCompleteInput onChange={onChange} onBlur={onBlur} value={value} />
            </AutoComplete>
        )}

I see the defaultValue in the input in the first render of the component, but if I select any item from the list, this is not updated in the input. Reading the docs, I think this is because is onChange in the AutoComplete component who handles that, so I have updated the code

     <Controller
        name={name}
        control={control}
        render={({ field: { onChange, onBlur, value } }) => (
            <AutoComplete onChange={onChange} freeSolo rollNavigation>
              <AutoCompleteInput onBlur={onBlur} value={value} />
            </AutoComplete>
        )}

In this case, I don't see the defaultValue on the first render and I can't select a new value from the list.

So do you know what would be the way to use the component in controlled mode with RHF?

Unable to set default value to the AutoCompleteInput


  let cats = [
    { id: 'CAT_1', label: 'Kitty 1' },
    { id: 'CAT_2', label: 'Kitty 2'},
  ];

  return
  <AutoComplete openOnFocus suggestWhenEmpty rollNavigation>
    <AutoCompleteInput variant="ghost" bgColor="transparent" />

    <AutoCompleteList fontStyle="normal">
      {cats.map((cat) => (
        <AutoCompleteItem
          key={cat.id}
          value={cat.label}
          textTransform="capitalize"
        >
          {cat.label}
        </AutoCompleteItem>
      ))}
    </AutoCompleteList>
  </AutoComplete>
}

Package version "@choc-ui/chakra-autocomplete": "^4.3.3",

I want the default value in the input box to be set to "Kitty 1" whenever the page loads.
With the above code, the input box is empty on page load which seems like the expected behaviour.

  • I tried setting defaultValue to the <AutoCompleteInput> component but it doesn't do anything.
  • I tried setting value to the component. It worked but whenever I focus on the input box first time and click outside the <AutoCompleteList>, the value disappears.

What is the right way to go about it?

Filtering not good

The Package filters using the Items' value, so the text in the item is ignored

[Question] The carriage return event will trigger an error (Cannot read property'disabled' of undefined)

demo: https://codesandbox.io/s/choc-ui-packages-codesandbox-forked-0ziuu?file=/src/App.js

Uncaught TypeError: Cannot read property 'disabled' of undefined

Open the demo link and enter some content at random, and press Enter, Don't use the mouse to select content

I donโ€™t know why this is caused. Iโ€™m trying to implement a search box with autocomplete, and then some keywords will be loaded from the backend to the user.

AutoCompleteTag resizes the AutoCompleteInput component

When using multiple prop in AutoComplete, if I choose multiple tags then it resizes the entire AutoCompleteInput component and makes it wider/longer. Can there be a way to solve this?

Alternatively, can we use tags outside AutoCompleteInput and above that component so that it does not resize the parent.

Do not need to release the src directory?

image

โžœ ls -al node_modules/@choc-ui/chakra-autocomplete
total 80
drwxr-xr-x   8 chenquan  staff    256  8 13 16:25 .
drwxr-xr-x   3 chenquan  staff     96  8 13 11:41 ..
-rw-r--r--   1 chenquan  staff   1228  8 13 16:25 Changelog.md
-rw-r--r--   1 chenquan  staff   1063  8 13 16:25 LICENSE
-rw-r--r--   1 chenquan  staff  25036  8 13 16:25 README.md
drwxr-xr-x  22 chenquan  staff    704  8 13 16:25 dist
-rw-r--r--   1 chenquan  staff   1691  8 13 16:25 package.json
drwxr-xr-x  15 chenquan  staff    480  8 13 16:25 src

Fix Emphasis prop

Highlighting with emphasis prop, does not work well with text transformation.

AutoCompleteCreatable is shown on empty input

When AutoCompleteCreatable is set with openOnFocus or suggestWhenEmpty the AutoCompleteCreatable is shown "empty"

{({ value }) => <span>Add {value} to List</span>}

It's not really empty but value is, so I will end with an item called Add to List

Also I noticed that if the list have an option called Apple for example, it won't be filtered when the input is Apple as well

image

I think this stop to working recently

Reproduction https://codesandbox.io/s/react-hook-form-v7-controller-forked-rb4sk?file=/src/Chakra.js

I updated to the latest version, input and select an option will appear the following error

I updated to the latest version, input and select an option will appear the following error

Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
     at input

Demo: https://codesandbox.io/s/choc-ui-packages-codesandbox-forked-0ziuu?file=/src/App.js

Can you tell me why this error is?
thank you.

Originally posted by @StringKe in #45 (comment)

Clicking enter throws an error

I use the autocomplete with list of google suggestions

say I type 'laptop' then click enter

image

Edit: This was on 3.5.4 btw, just updated

Edit: still happening on latest update

Props Request: Show menu when input field is focused

Because the select options aren't displayed when the user clicks the input field, they have to type random letters just to see what options are available. It would be helpful to have the option to see all available options before typing anything.

Bug using AutoCompleteFixedItem and AutoCompleteGroup

I have this list:

<AutoCompleteList>
  <AutoCompleteGroup title="Title" showDivider>
    <AutoCompleteItem value="1">Apple</AutoCompleteItem>
    <AutoCompleteItem value="2">Appoint</AutoCompleteItem>
  </AutoCompleteGroup>
  <AutoCompleteFixedItem value="F1">Fixed Item 1</AutoCompleteFixedItem>
  <AutoCompleteFixedItem value="F2">Fixed Item 2</AutoCompleteFixedItem>
</AutoCompleteList>

And this is what I see, as you can see The Fixed item 1 is duplicated

image

If I put the FixedItem Inside of the AutoCompleteGroup I can't see none of those items

bug(creatable): cannot render AutoCompleteCreatable

Following these docs:

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.

I was not able to render the <AutoCompleteCreatable> component within the AutoCompleteList

<AutoCompleteInput> should be able to access the value but render the label instead


  let cats = [
    { value: 'CAT_1', label: 'Kitty 1' },
    { value: 'CAT_2', label: 'Kitty 2'},
  ];

  return
  <AutoComplete openOnFocus suggestWhenEmpty rollNavigation>
    <AutoCompleteInput variant="ghost" bgColor="transparent" />

    <AutoCompleteList fontStyle="normal">
      {cats.map((cat) => (
        <AutoCompleteItem
          key={cat.value}
          value={cat.value}
          textTransform="capitalize"
        >
          {cat.label}
        </AutoCompleteItem>
      ))}
    </AutoCompleteList>
  </AutoComplete>
}

Package version "@choc-ui/chakra-autocomplete": "^4.3.4",

In the above example, I want the AutoCompleteList items to show up options like "Kitty 1", "Kitty 2" and so on. Now when I select any option, the value that gets set in the <AutoCompleteInput> is CAT_1 whereas I wanted "Kitty 1" to get set because that is what I chose.
The only way to get around this is to make sure the value and label (child of <AutoCompleteItem>) is set as the same thing i.e. cat.label in this case, but this breaks the point of having the ability to pass a different value and child to <AutoCompleteItem>

The behaviour that is expected is similar to how any <Menu> component would work.

tldr: the value maintained internally and the value displayed/rendered should be different for the input box.

feature request: non-filterable item

I'll like to have an option to avoid filter a item from the list

I'm using the creatable option, but I want to add an aditional option that will be always available in the list

- Option 1
- Option 2
---
- Add "Text"
- Create and Edit

I need to always show the Create and Edit option, so I was thinking in something like this:

<AutoCompleteItem
  value="createAndEdit"
  textTransform="capitalize"
  alwaysShow
>
create and edit
</AutoCompleteItem>

Default value not working in v.4.3.0

I'm having problems to get the default value in v4.3.0, the problem is I'm not able to replicate it in the codeSandbox but when I switch to v4.2.0 it's working, I have looked the changes in the lastest version and I saw you added a defaultValue prop

const defaultValue = useParseDefaultValue(

I put console.log(autoCompleteProps.defaultValue) and it's undefined so the return of useParseDefaultValue is undefined as well, as I'm using the input in controlled mode I think it should get value as default value, I think that is the way how this was working before

Bug using useState and onOptionHighlight

Hi, I'm trying to set a flag when there not options to show, but if I use the useState hook in onOptionHighlight the component stops working; it doesn't show any option.

if I use console.log it works as expected, I'm missing something?

const [extraOptions, setExtraOptions] = useState(false);

  return (
    <AutoComplete
      onOptionHighlight={(value) => setExtraOptions(!value)} <!---
    >
    ...
    </AutoComplete>

EDIT:

using the onChange prop with useState have the same behavior

EDIT2:

I think the problem is I'm using the component as uncontrolled, I tried to use it with react-hook-form but I couldn't. AutoComplete or AutoCompleteInput does not exposes the value prop

Feature Request: Prop to Show unfiltered items with input defaultValue

As per @TaylorFacen 's request in #14

I see that if I provide a default value, the menu is already filtered. Is there a way to show all options even when there's a default value and only filter once the input has changed? The use case is, the user is able to manage financial transactions and assign a category to each transaction. I want them to be able to edit a transaction's category. So when they go to edit the transaction, there's already a pre-filled category that they have the option to change. I want them to be able to see all options even if there's already a category value.

Long option values getting cut

image

Values that are longer than the <AutoCompleteInput> component width should have an ellipses at the end of the text instead of getting cut abruptly.

Not able to change borderRadius on AutoCompleteList

I have the following implementation:

<AutoComplete openOnFocus>
  <AutoCompleteInput variant="filled" />
  <AutoCompleteList borderRadius="none">

However, border radius is not registering. I can confirm, other style props (e.g. fontSize) work.

Allow passing an entire object to AutoCompleteItem as the value

Overview

It's very common to use a component like this with a list of objects. While the input value is always a string, it would be nice to also pass the entire object to AutoComplete and invoke the onSelectOption with that value.

Example

<AutoComplete
  // This is a hack to reset the internal state of the component
  key={instanceCount}
  ...
  onSelectOption={(selection) => {
    // selection is { email: '[email protected]', id: 's3e8d' }
  }}
>
  ...
  <AutoCompleteItem
    key={item.email}
    value={{ email: '[email protected]', id: 's3e8d' }}
  />

isNewInput always false

Seems like there is a bug isNewInput is always false, as I understand, using the creatable option should return true if I select the creatable option but that is not working

style props on <AutoCompleteInput> seem janky

Hi, so everything seems great with this library now except for styling inputs

					<AutoCompleteInput
						autoFocus
						width='50rem'
						display='inline-flex'
						flexGrow={1}
						variant='filled'
						size='md'
						bg='white'
						value={query}
						onFocus={onFocused}
						onBlur={onBlur}
						onChange={onChangeSearch}
						zIndex={searchBarZIndex}
						bg='gray.50'
						color='gray.700'
					/>

I have the input in a grid like think airbnb or amazon, so I want it to flexgrow but using flex in any way on it doesnt seem to work because I have a left and right element attached to it, using width works but then it isn't responsive.

My entire searchbar component is

import React, { useEffect, useState, useRef } from 'react';
import { useRouter } from 'next/router';
import {
	Box,
	Flex,
	InputGroup,
	InputLeftElement,
	InputRightElement,
	Select,
	IconButton,
} from '@chakra-ui/react';
import {
	AutoComplete,
	AutoCompleteInput,
	AutoCompleteItem,
	AutoCompleteList,
  } from '@choc-ui/chakra-autocomplete';
import { SearchIcon } from '@chakra-ui/icons';
import { useQuery } from '@apollo/client';

import { GQL_GET_ALL_CATEGORIES } from '@/gql';

const getSuggestions = async text => {
	const
		res = await fetch('/api/suggestions?' + new URLSearchParams({
			text,
		}))
	;
	//console.log('res', await res.json());
	return await res.json();
};

const SearchBar = props => {
	const router = useRouter();

	const [category, setCategory] = useState(null);
	const [categories, setCategories] = useState([]);

	useQuery(GQL_GET_ALL_CATEGORIES, {
		notifyOnNetworkStatusChange: true,
		onCompleted: data => {
			setCategories(data?.categories);
			//console.log(data?.categories);
		},
		onError: data => {
			console.log(data);
		},
	});

	const renderCategories = () => categories?.map(e => (<option key={e?.name} value={e?.name}>{e?.title}</option>)) ?? null;

	const [searchBarZIndex, setSearchBarZIndex] = useState(2);

	const onFocused = () => setSearchBarZIndex(999);
	const onBlur = () => setSearchBarZIndex(2);

	const [query, setQuery] = useState('');
	const [suggestions, setSuggestions] = useState([]);

	const onChangeSearch = async event => {
		const
			query = event?.target?.value
		;
		setQuery(query);
	};

	useEffect(() => {
		const handle = async () => {
			if(query.length) {
				const
					results = await getSuggestions(query)
				;
				if(Array.isArray(results)) {
					if(results?.[0] !== query) {
						results.unshift(query);
					}
					setSuggestions(results);
					//console.log(results);
				}
			}
			else if(suggestions.length) {
				setSuggestions([]);
			}
		};
		handle();
	}, [query]);

	const handleSearchClick = event => {
		if(query.length) {
			console.log('handleSearchClick', query);
			router?.push('/s?' + new URLSearchParams({
				query,
			}));
		}
	};

	const renderSuggestions = () => {
		if(suggestions?.length) {
			const handleSuggestionClick = event => {
				const
					query = event?.target?.innerText
				;
				console.log('handleSuggestionClick', query);
				router?.push('/s?' + new URLSearchParams({
					query,
				}));
			};
			return (
				<AutoCompleteList>
					{suggestions.map((option, oid) => (
						<AutoCompleteItem
							key={`optio-${oid}`}
							value={option}
							textTransform='capitalize'
							align='center'
							color='black'
							onClick={handleSuggestionClick}
						>
							{option}
						</AutoCompleteItem>
					))}
				</AutoCompleteList>
			);
		}
	};

	const handleSearchKeyPress = event => {
		if(event.key === 'Enter') {
			handleSearchClick();
		}
	};

	const handleCategory = event => {
		//console.log('handleCategory:', event?.target?.value?.length ? event?.target?.value : null);
		setCategory(event?.target?.value?.length ? event?.target?.value : null);
	};

	return (
		<Flex
			justify='center'
			align='center'
			w='full'
		>
			<AutoComplete
				rollNavigation
				maxSuggestions={10}
				emphasize
				selectOnFocus={false}
				onKeyPress={handleSearchKeyPress} 
				suggestWhenEmpty={false}
			>
				<InputGroup
					maxWidth='60vw'
					width='auto'
					display='flex'
				>
					<InputLeftElement
						children={(
							<Select
								placeholder="All"
								borderColor="darkGray"
								color="#111111"
								size='md'
								bg='#eee'
								borderEndRadius={0}
								borderStartRadius={6}
								//overflow='ellipsis'
								onClick={handleCategory}
							>
								{ renderCategories() }
							</Select>
						)}
						display='inline-flex'
						flexGrow={0.5}
						width='auto'
						zIndex={searchBarZIndex + 1}
					/>
					<AutoCompleteInput
						autoFocus
						width='50rem'
						display='inline-flex'
						flexGrow={1}
						variant='filled'
						size='md'
						bg='white'
						value={query}
						onFocus={onFocused}
						onBlur={onBlur}
						onChange={onChangeSearch}
						zIndex={searchBarZIndex}
					/>
					<InputRightElement
						children={(
							<IconButton
								aria-label='Search'
								icon={(
									<SearchIcon
										color='black'
									/>
								)}
								borderEndRadius={6}
							/>)
						}
						display='inline-flex'
						zIndex={searchBarZIndex + 1}
						onClick={handleSearchClick}
					/>
					{ renderSuggestions() }
				</InputGroup>
			</AutoComplete>
		</Flex>
	);
};

export default SearchBar;

AutoComplete input does not obbey width props

Seems like the autocompleteinput has a Wrap element with hardcoded props including wdith.

<Wrap {...inputProps.wrapper}>

I couldn't not figure out how to override those. No matter what width i set in autocompleteinput it stays fixed at '80'. They are coming from here i think https://github.com/anubra266/choc-autocomplete/blob/main/src/helpers/input.ts

Is there a way expand the input width?

Thanks very much for your work

Possible to list all options when user focuses for the first time?

I am looking for a behaviour that material-ui autocomplete takes care off - Ability to view all the menu items when the user focuses on the input box. But when the user starts typing, it starts showing just the filtered options.

This is useful in order for the user to view all the options as there is no way to view them at the moment without having to erase the entire text in the input box.

AutoComplete.InputGroup does not respect InputLeftElement

import {
	InputGroup,
	InputLeftElement,
	InputRightElement,
	Icon,
} from '@chakra-ui/react';
import {
	AutoComplete,
	AutoCompleteInput,
	AutoCompleteItem,
	AutoCompleteList,
	AutoCompleteGroup,
	AutoCompleteFixedItem,
  } from '@choc-ui/chakra-autocomplete';
  import { SearchIcon, ChevronRightIcon, ChevronDownIcon } from '@chakra-ui/icons';

const SearchBar = props => {
	const options = ['apple', 'appoint', 'zap', 'cap', 'japan'];
  
	return (
		<AutoComplete rollNavigation>
			{({ isOpen }) => (
				<>
					<InputGroup>
						<InputLeftElement
							pointerEvents="none"
							children={<SearchIcon />}
						/>
						<AutoCompleteInput
							variant="filled"
							placeholder="    Search..."
						/>
						<InputRightElement
							pointerEvents="none"
							children={
								<Icon as={isOpen ? ChevronRightIcon : ChevronDownIcon} />
							}
						/>
					</InputGroup>
					<AutoCompleteList>
						{options.map((option, oid) => (
							<AutoCompleteItem
								key={`optio-${oid}`}
								value={option}
								textTransform="capitalize"
								align="center"
							>
								{option}
							</AutoCompleteItem>
						))}
					</AutoCompleteList>
				</>
			)}
		</AutoComplete>
	);
};

export default SearchBar;

Result is
image

image

Using Autocomplete with react-instantsearch-dom HOCs

I'm currently trying to implement a search field using react-instantsearch-dom and chakra-autocomplete. I seem to be hitting a wall when rendering the AutoCompleteList. I believe the issue is that the reference or context of AutoComplete is getting lost but I'm not sure how to solve it.

The search box part looks like this

  <AutoComplete rollNavigation id="autoTop" itemRef="auto">
    <AutoCompleteInput
        value={currentRefinement}
        variant="filled"
        placeholder="Search..."
        minW="500px"
        autoFocus
        onChange={(e) => handleQuery(e)}
        id="auto-input"
      />
      <SearchResults />
    </AutoComplete>

With the SearchResults component looking like this and then being wrapped in the instantsearch HOC with connectHits()

const HitBase = ({ hits, handleClick }: HitProps) => {
  console.log(hits)

  return (
    <AutoCompleteList >
      {hits.map((hit) => (
        <AutoCompleteItem key={hit.title} value={hit.title}>
          <Poster id={hit.id} slug={hit.poster_path} title={hit.title} />
          <Text>{hit.title}</Text>
        </AutoCompleteItem>
      ))}
    </AutoCompleteList>
  )
}
const SearchResults = connectHits(HitBase)

Is there a way to maintain the reference between the two components? My assumption is that the hits HOC is what actually breaks it but I am not sure how to get around it.

feat (multiselect): API methods for removing one item or all items

When using multi-select, it would be nice to have an API to remove a single selected item or to clear all items (reset) from outside the component.

I think the most idiomatic React way to do this in the current architecture of AutoComplete would be to expose an onReady or init callback which provides these methods.

<AutoComplete
  onReady={({ getItems, removeItem, reset }) => {
    // Store reference to API methods for later use
  }}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.