-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: adding multi-select component #1616
base: main
Are you sure you want to change the base?
Conversation
@dinogit is attempting to deploy a commit to the shadcn-pro Team on Vercel. A member of the Team first needs to authorize it. |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
This looks great. Adding it to the roadmap. @izakfilmalter has some feedback if you have a chance to look at it. |
@dinogit Looking a lot better. This interaction is still really awkward: I would probably disable the deselection of items while the dropdown is closed. |
Hi @izakfilmalter, thank you for your time and feedback. regarding the comment above, the update is that deselection is removed from the Badge and only available on the Close button when the dropdown is open. Close button in the Badge also apears and disapears when dropdown is open/closed. Delete will remove badge if Search is not populated, othervise it will delete letters in search input. Let me know what do you think |
For me this multi select has major bug. Having multiple fields in form will cause deletion of multi select tags once you modify other input fileds. Property is MultiSelect Using backspace to edit email / username will delete each selected tag one by one on every Backspace hit. This is inside Sheet component. |
<Command className={className}> | ||
<CommandInput | ||
onValueChange={(item) => { | ||
console.log("dd", item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove console.log
export type OptionType = Record<"value" | "label", string> | ||
|
||
interface MultiSelectProps { | ||
options: Record<"value" | "label", string>[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use the OptionType
here that is defined just above?
React.useEffect(() => { | ||
const handleKeyDown = (e: KeyboardEvent) => { | ||
if (e.key === "Backspace" && query === "" && selected.length > 0) { | ||
onChange(selected.filter((_, index) => index !== selected.length - 1)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This backspace act as soon as the component is loaded it should not remove an item if I am using backspace to remove text in another input field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should do the trick (works for me)
React.useEffect(() => { | |
const handleKeyDown = (e: KeyboardEvent) => { | |
if (e.key === "Backspace" && query === "" && selected.length > 0) { | |
onChange(selected.filter((_, index) => index !== selected.length - 1)) | |
} | |
React.useEffect(() => { | |
const handleKeyDown = (e: KeyboardEvent) => { | |
if (document.activeElement === commandInputRef.current) { | |
if (e.key === 'Backspace' && query === '' && selected.length > 0) { | |
onChange(selected.filter((_, index) => index !== selected.length - 1)); | |
} | |
} |
Plus declaring commandInputRef
const commandInputRef = React.useRef<HTMLInputElement>(null);
and adding ref={commandInputRef}
<CommandInput
ref={commandInputRef}
onValueChange={(item) => {
setQuery(item);
}}
placeholder="Search ..."
/>
{item.label} | ||
{open && ( | ||
<Button | ||
asChild |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why but this asChild
crashed my website with this error message:
Uncaught Error: React.Children.only expected to receive a single React element child.
at Object.onlyChild [as only] (react.development.js:1229:11)
at Slot.tsx:70:62
at renderWithHooks (react-dom.development.js:16305:18)
at updateForwardRef (react-dom.development.js:19226:20)
...
role="combobox" | ||
aria-expanded={open} | ||
className={`group w-full justify-between ${ | ||
selected.length > 1 ? "h-full" : "h-10" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This resulted in quite a buggy ui for me, i would sugest
min-h-[2.5rem] h-fit
Just asking the community to see what they'd like... Would you like an AutoComplete with Multiselect + FreeSolo capabilities in Shad, like the following? Screen.Recording.2023-12-06.at.00.08.03.mov(You can test this out at https://app.listen.dev) If yes, we can try making this generic enough to merge into shadcn mainnet. I think with some tweaks, it can be moulded to do whatever a user wants to within multiselect/freesolo/autocomplete as they want. Kinda like MUI's AutoComplete. |
I am getting the following Issue in Chrome when using the provided example
The issue is that For example, on the Input component, both the My website still works fine though and values are passed properly. |
variant="outline" | ||
size="icon" | ||
className={`border-none duration-300 ${ | ||
open ? "opacity-100 ease-in" : "opacity-0 ease-out" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary conditional, open
value is always truthy
because button only visible when open is true
open ? "opacity-100 ease-in" : "opacity-0 ease-out" | |
opacity-100 ease-in |
fyi: we have two multi-select components that we're looking into: #2773 |
Hi everyone, |
? selected.filter((item) => item.value !== option.value) | ||
: [...selected, option] | ||
) | ||
setOpen(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set it to open?
if you are clicking it, the popover is already open and visible, am i missing something?
<Command className={className}> | ||
<CommandInput | ||
onValueChange={(item) => { | ||
console.log("dd", item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove console.log
Any updates please? a lot of developer are waiting for this.. |
This PR creates a multi-select component from existing shadcn-ui components.