anubra266 / choc-autocomplete Goto Github PK
View Code? Open in Web Editor NEWπ Autocomplete Component Package for Chakra UI
Home Page: https://githubbox.com/anubra266/choc-autocomplete/tree/main/demo
License: MIT License
π Autocomplete Component Package for Chakra UI
Home Page: https://githubbox.com/anubra266/choc-autocomplete/tree/main/demo
License: MIT License
https://codesandbox.io/s/react-hook-form-v7-controller-forked-rb4sk?file=/src/Chakra.js
As you can see in that sandbox, you can't select any AutoCompleteFixedItem
option
When selecting the creatable, the render function is passed an object with only the remove function ({ onRemove }
)
I may be missing something, but a Codesandbox demo of creatable with tags would be great!
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.
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
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.
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.
Hello, This property is causing an error when rendering the input. I'm using NextJS.
In v4.5.5 latest version, when you select an option, you can not see the value.
Check the representation using demo with v4.5.5
Thanks
codesandbox: https://codesandbox.io/s/choc-ui-packages-codesandbox-forked-76vih?file=/src/App.js
Steps to reproduce:
Expected behaviour:
The state of the input is reset so when focus is regained a new selection can be made.
Actual behaviour:
The value of the input is populated in to the field on blur and the input is not cleared.
Automplete List is mispositioned in latest Chakra Version
I'd like to have an icon next to my input, which Chakra has a pattern for in InputGroup
: https://chakra-ui.com/docs/form/input#add-elements-inside-input
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
choc-autocomplete/src/use-autocomplete.ts
Line 160 in 932823f
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
The Package filters using the Items' value, so the text in the item is ignored
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?
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.
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.
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
}}
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>
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.
at this moment seems like there is not option to change the creatable prefix
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.
Hello and thank you for your effort.
Would be nice to allow closing the dropdown when pressing the ESC button.
Thank you in advance
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
If I put the FixedItem
Inside of the AutoCompleteGroup
I can't see none of those items
β 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
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
I think this stop to working recently
Reproduction https://codesandbox.io/s/react-hook-form-v7-controller-forked-rb4sk?file=/src/Chakra.js
I hope that <AutoComplete/>
can correctly trigger the Enter event
regardless of whether the option is selected or not
If you set the isReadOnly
prop to true in your AutoCompleteInput
and focus it, it will open the list of items
Highlighting with emphasis prop, does not work well with text transformation.
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;
https://codesandbox.io/s/choc-ui-autocomplete-undefined-tolowercase-error-wdsl1?file=/src/App.tsx
If defaultValue is set as undefined for some reason, it crashes the entire UI with an error "Cannot read property 'toLowerCase' of undefined".
Might not be the best experience for the user. Rather we could just make it show empty in case of any incorrect values.
@choc-ui/chakra-autocomplete: 4.4.3
Why don't you deploy the demo with the latest version after the new release?
I though it was going crazy. I am fetching the list and the already selected items from external API. Everything worked in localhost but not in build. In my case i use next with TS
I created this codesandbox with next and TS
https://codesandbox.io/s/k0qfj
values are hardcoded there. An it works fine.
This is the same code deployed to vercel directly from codesandbox
https://csb-k0qfj-subzero79.vercel.app/
Thanks again for your work
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.
<AutoCompleteInput>
component but it doesn't do anything.<AutoCompleteList>
, the value disappears.What is the right way to go about it?
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;
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.
<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' }}
/>
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
I need to do i18n support, but the hint here seems to be fixed, I canβt modify it
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)
Would be good to have multi selection, this is one of the features that even the chakra select component have missing
Use the tag component would be a good option
reference: https://material-ui.com/components/autocomplete/#multiple-values
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
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.
choc-autocomplete/src/helpers/input.ts
Line 25 in 069d49d
Seems like the autocompleteinput has a Wrap element with hardcoded props including wdith.
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
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.
Typing /
breaks the package
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.