Skip to content
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

[Bug]: Command/Combobox TypeError and Unclickable/Disabled items, cmdk breaking change #2944

Closed
2 tasks done
jhnguyen521 opened this issue Mar 8, 2024 · 62 comments · Fixed by #2945
Closed
2 tasks done
Labels
bug Something isn't working

Comments

@jhnguyen521
Copy link
Contributor

jhnguyen521 commented Mar 8, 2024

Describe the bug

When utilizing a Command component that has been added/updated as of 03/07/2024 ~6PM PST, items cannot be clicked and are disabled. (Additionally some examples using command in the docs are incorrect)

Additionally, <CommandItem>s that are not surrounded by a <CommandList> will crash the application and upon opening the Command component, the error: TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator)) will be thrown.

This is due to cmdk making a new release with breaking changes: https://github.com/pacocoursey/cmdk/releases

Workaround

This can be fixed by pinning cmdk version to 0.2.1 in package.json
See #2944 (comment)

Solution

#2944 (comment) for disabled items fix

#2944 (comment)
for error fix

Please see PR #2945 to fix these issues

Affected component/components

Command

How to reproduce

  1. Run npx shadcn-ui@latest add command after 03/07/2024
  2. Try to use command component

Codesandbox/StackBlitz link

https://codesandbox.io/p/devbox/shadcn-playground-forked-4xxqcw?workspaceId=2d1a1544-9936-4d36-a113-0092357e5e51

Logs

No response

System Info

cmdk v1.0.0

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues
@jhnguyen521 jhnguyen521 added the bug Something isn't working label Mar 8, 2024
@jhnguyen521
Copy link
Contributor Author

jhnguyen521 commented Mar 8, 2024

Some notes, seems like <CommandItem> needs to be contained somewhere within a <CommandList>. <CommandGroup> alone is no longer sufficient.
Upon doing this however, items are now disabled with shadcn/ui

Edit: Without a <CommandList>, the error is: TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

@abdasis
Copy link

abdasis commented Mar 8, 2024

I'm face same issue

@matowang
Copy link

matowang commented Mar 8, 2024

+1
Onclick interactions doesn't work

@jhnguyen521
Copy link
Contributor Author

jhnguyen521 commented Mar 8, 2024

Figured out the issue, in cmdk changenotes:
The aria-disabled and aria-selected props will now be set to false, instead of being undefined in https://github.com/pacocoursey/cmdk/commit/c57e6b7f81a5796395c7a016d6b1b2aac9591973

It seems that the data-disabled prop is also set to false whereas before the property would not exist at all until being disabled, and data-[disabled]:pointer-events-none will apply even for data-disabled="false".

The fix is to replace data-[disabled] with data-[disabled='true']. This should be backwards compatible too! :)
I see that shadcn/ui uses data-[disabled] in numerous places, may be worth fixing this behavior everywhere. Going to make a PR.

@jhnguyen521 jhnguyen521 changed the title [Bug]: Adding command [Bug]: Command items are not selectable with latest cmdk version Mar 8, 2024
@jhnguyen521 jhnguyen521 changed the title [Bug]: Command items are not selectable with latest cmdk version [Bug]: Command items are not selectable Mar 8, 2024
@jhnguyen521 jhnguyen521 changed the title [Bug]: Command items are not selectable [Bug]: Items not selectable for newly added Command component Mar 8, 2024
@collinversluis
Copy link

I encountered a similar problem when using the Combobox, but in my situation, the issue wasn't that it was unclickable or "disabled"; rather, the application would crash whenever the Combobox was opened. This is what I ran into for anyone googling this error:

TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

This is also solved by pinning cmdk version to 0.2.1 in package.json for now. Thanks @jhnguyen521

@jhnguyen521
Copy link
Contributor Author

jhnguyen521 commented Mar 8, 2024

I encountered a similar problem when using the Combobox, but in my situation, the issue wasn't that it was unclickable or "disabled"; rather, the application would crash whenever the Combobox was opened. This is what I ran into for anyone googling this error:

TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

This is also solved by pinning cmdk version to 0.2.1 in package.json for now. Thanks @jhnguyen521

Hey, I forgot to put in the error, but this is likely because you don't have a <CommandList> enclosing your <CommandItems> as I mentioned above, the cmdk version seems to have changed this behavior.

seems like <CommandItem> needs to be contained somewhere within a <CommandList>. <CommandGroup> alone is no longer sufficient. Upon doing this however, items are now disabled with shadcn/ui

Some of the examples for the Command component are incorrect (which I also copy-pastaed (: ) and don't use a <CommandList> which I've also updated in the PR.

tl;dr Try just putting a <CommandList> around your existing <CommandGroup>s like under the Usage example here: https://ui.shadcn.com/docs/components/command

@collinversluis
Copy link

collinversluis commented Mar 8, 2024

Hey, I forgot to put in the error, but this is likely because you don't have a <CommandList> enclosing your <CommandItems> as I mentioned above, the cmdk version seems to have changed this behavior.

Try just putting a <CommandList> around your existing <CommandGroup>s under the Usage example here: https://ui.shadcn.com/docs/components/command

This is totally the issue, adding the <CommandList> around your <CommandItem>'s resolves the TypeError.

Any thought on if we should be wrapping <CommandList> above <CommandGroup> or below?

Updating the examples will resolve the crash issue for future users, but the "aria-disabled" breaking change will still need to be updated so anyone with this issue should keep 0.2.1 pinned in their package.json until #2945 is merged by changing

"cmdk": "^1.0.0" or similar

to

"cmdk": "0.2.1"

Thanks again @jhnguyen521!

@shainegordon
Copy link

I also had to remove data-[disabled]:pointer-events-none data-[disabled]:opacity-50 from here

const CommandItem = React.forwardRef<
    React.ElementRef<typeof CommandPrimitive.Item>,
    React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
    <CommandPrimitive.Item
        ref={ref}
        className={cn(
            'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
            className,
        )}
        {...props}
    />
))

Which makes me then wonder, what was it doing in the first place :)

@jhnguyen521
Copy link
Contributor Author

jhnguyen521 commented Mar 8, 2024

Any thought on if we should be wrapping <CommandList> above <CommandGroup> or below?

I believe it should be above <CommandGroup> according to all the examples, additionally enclosing <CommandEmpty> but I think it works either way 🤷

"aria-disabled" breaking change will still need to be updated

I don't think so, the Command component doesn't do any special handling around aria-disabled and aria-selected. That should all be handled by the command primitives. Only place I saw that stuff referenced was in the Calendar component.

Edit: nvm, it has attributes for the aria-x. It's just styling, so it doesn't really matter, but I can just update this in my PR

@shainegordon
Copy link

I also had to remove data-[disabled]:pointer-events-none data-[disabled]:opacity-50 from here

const CommandItem = React.forwardRef<
    React.ElementRef<typeof CommandPrimitive.Item>,
    React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
    <CommandPrimitive.Item
        ref={ref}
        className={cn(
            'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
            className,
        )}
        {...props}
    />
))

Which makes me then wonder, what was it doing in the first place :)

Ignore this, I missed the post about changing to data-[disabled='true'], so I just replaced those classes accordingly

I''ve also moved the position of <CommandList> as per the examples, and my combo-box is working again as it should

@abolajibisiriyu
Copy link

like @shainegordon said, I had to adjust the styles to fix this

const CommandItem = React.forwardRef<
  React.ElementRef<typeof CommandPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
  <CommandPrimitive.Item
    ref={ref}
    className={cn(
      "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-base outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled='true']:pointer-events-none data-[disabled='true']:opacity-50",
      className
    )}
    {...props}
  />
));

note the change data-[disabled='true']

@tommerty
Copy link

+1 Onclick interactions doesn't work

@matowang onClick isn't working for me either, but looking at the PR I figured out to do onSelect instead! Helps me with my scenario, hopefully can do the same for you! For example I was trying to navigate with it, and got it working with something like this:

            <CommandDialog open={open} onOpenChange={setOpen}>
                <CommandInput placeholder="Search..." />
                <CommandList>
                    <CommandEmpty>No results found.</CommandEmpty>
                    <CommandGroup heading="Features">
                        {featureItems.map((item) => (
                            <CommandItem
                                key={item.url}
                                onSelect={() =>
                                    router.push(
                                        item.url.replaceAll(
                                            "$username",
                                            user.username
                                        )
                                    )
                                }
                            >
                                <IconArrowRight className="mr-2 h-4 w-4" />
                                <span>{item.title}</span>
                            </CommandItem>
                        ))}
etc etc

Taking into account the data-[disabled='true'] instead of data-[disabled] fix in the /ui/command component too!

@lloydrichards
Copy link
Contributor

lloydrichards commented Mar 11, 2024

This should be addressed with PR #2945 🤞

gularsson added a commit to ttab/elephant-ui that referenced this issue Mar 11, 2024
@jhnguyen521 jhnguyen521 changed the title [Bug]: Items not selectable for newly added Command component [Bug]: Command/Combobox TypeError and Unclickable/Disabled items Mar 12, 2024
@benjamin-guibert
Copy link

I had the same issue when updating to cmdk v1. I resolved the issue following your advices:

  • I added CommandList in the tree;
  • I replaced data-[disabled] by data-[disabled='true'].

Thank you! 🙏🏻

@bowen0110
Copy link

the scrollbar doesn't work

@iamisti
Copy link

iamisti commented Jul 19, 2024

I also had to remove data-[disabled]:pointer-events-none data-[disabled]:opacity-50 from here

const CommandItem = React.forwardRef<
    React.ElementRef<typeof CommandPrimitive.Item>,
    React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
    <CommandPrimitive.Item
        ref={ref}
        className={cn(
            'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
            className,
        )}
        {...props}
    />
))

Which makes me then wonder, what was it doing in the first place :)

This is very interesting, because in tailwind, you cannot add multiple classes to different states, like hover/active/focus/disabled

@paulofabiano
Copy link

Nothing is working for me: scroll, field focus, items mouse over. It is just static and I've applied all workaround suggested in here. I'm using react 18 and nextjs 14.2.4

@tjhoo
Copy link

tjhoo commented Jul 25, 2024

I'm on the same boat as @paulofabiano

May I know what else need to be done beside downgrading cmdk to 0.2.0?

@tjhoo
Copy link

tjhoo commented Jul 25, 2024

I'm on the same boat as @paulofabiano

May I know what else need to be done beside downgrading cmdk to 0.2It.0?

It should be working by downgrading cmdk to 0.2.0?

<Popover>
  <PopoverTrigger asChild>
    <Button>OK</Button>
  </PopoverTrigger>
  <PopoverContent>
    <Command>
      <CommandInput></CommandInput>
      <CommandList>
        <CommandItem key="1" onSelect={() => console.log("first")}>
          123
        </CommandItem>
        <CommandItem key="2" onSelect={() => console.log("second")}>
          456
        </CommandItem>
      </CommandList>
    </Command>
  </PopoverContent>

@tuanvt
Copy link

tuanvt commented Jul 27, 2024

replace data-[disabled]: with data-[disabled=true]: in components/ui/command.tsx

https://stackoverflow.com/a/78308802/11438881

This works well for me.
data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50

@othman316
Copy link

Figured out the issue, in cmdk changenotes: The aria-disabled and aria-selected props will now be set to false, instead of being undefined in https://github.com/pacocoursey/cmdk/commit/c57e6b7f81a5796395c7a016d6b1b2aac9591973

It seems that the data-disabled prop is also set to false whereas before the property would not exist at all until being disabled, and data-[disabled]:pointer-events-none will apply even for data-disabled="false".

The fix is to replace data-[disabled] with data-[disabled='true']. This should be backwards compatible too! :) I see that shadcn/ui uses data-[disabled] in numerous places, may be worth fixing this behavior everywhere. Going to make a PR.

Works perfectly. Thank you!

pwli0755 added a commit to pwli0755/ShadcnNextJSDemo that referenced this issue Aug 1, 2024
@televators
Copy link

Been hearing about Shadcn for a while, finally trying it out and one of the first components I try is buggy. Surprised this is still not fixed as of August. Thanks for the fix, though!

@RanitManik
Copy link

form.clearErrors('language')

saved me a lot of time. Thanks!

@OmarKhattab
Copy link

Seems like an issue still

@thomas-cruz
Copy link

I was playing around with the first example Combobox from the docs and even after applying the fixes it still breaks.

@rav291
Copy link

rav291 commented Oct 9, 2024

Tried going back to 0.2.0, still didn't work for me. Looks like I chose the wrong library

@shainegordon
Copy link

shainegordon commented Oct 9, 2024

Tried going back to 0.2.0, still didn't work for me. Looks like I chose the wrong library

It’s an extremely simple fix, just do this - #2944 (comment)

Rather don’t throw the baby out with the bath water, for a lot of use cases, this is actually an excellent “library”

agreed that it’s a bit annoying that this issue is closed, but apparently this isn’t resolved

@derrickstaten
Copy link

derrickstaten commented Oct 15, 2024

Still broken. I tried everything in this thread:

Removing data-[disabled=true]:pointer-events-none and data-[disabled=true]:opacity-50.

Pinning "cmdk": "0.2.1"

Using onSelect.

Now remembering that this is what caused me to drop shadcn on a previous project -- combobox is a nightmare. It's generally worked for me for everything else, so i'm not ready to abandon it yet. But I totally empathize with people who try out shadcn, can't get the boilerplate combobox to work, and abandon the library.

@bdlowery
Copy link

bdlowery commented Nov 1, 2024

Go into your command.tsx component and do this. Specifically adding <CommandList> This should allow you to use cmdk 1.0.0

const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
  return (
    <Dialog {...props}>
      <DialogContent className="overflow-hidden p-0">
        <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-zinc-500 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
          <CommandList>{children}</CommandList>
        </Command>
      </DialogContent>
    </Dialog>
 )
}

@javed24
Copy link

javed24 commented Nov 14, 2024

anybody got lucky with this issue? I'm well aware of the data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 workaround, which, upon installing the command component I see that it already had it, so I didn't need to make the change. However, it crashes the moment I select an option.

here's a sample usage:

   <FormField
          name="productTypes"
          render={({ field }) => (
            <FormItem>
              <FormLabel className="text-xs uppercase text-gray-400">
                Product Types
              </FormLabel>
              <FormControl>
                <div className="relative">
                  <Command onKeyDown={(e) => e.stopPropagation()}>
                    <CommandInput
                      placeholder="Select an option"
                      value={
                        options.find(
                          (opt) => opt.value === selectedOption,
                        )?.label || ''
                      }
                      onFocus={() => setIsOpen(true)}
                    />
                    {isOpen && (
                      <CommandList className="absolute z-10 w-full rounded-lg bg-white shadow-md">
                        <CommandEmpty>No options found.</CommandEmpty>
                        <CommandGroup>
                          {hardcodedOptions.map((option) => (
                            <CommandItem
                              key={option.value}
                              onSelect={() => handleSelectOption(option.value)}
                            >
                              {option.label}
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    )}
                  </Command>
                </div>
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

A bit strange to see that the issue is still there despite the particular cmdk related fixes being applied. Has anyone found a workaround? Not sure if downgrading to 0.2.1 is the right way to go here.

@seanpquig
Copy link

Any chance some of this behavior has resurfaced recently? These comboboxes were working fine for me a 1-2 weeks ago and now I can't select any of the options, despite not making any related code changes or library upgrades.

My command component already has the data-[disabled=true] fix. It had been working fine for me on cmdk 1.0.0 and downgrading to 0.2.1 doesn't seem to fix it.

@seanpquig
Copy link

Any chance some of this behavior has resurfaced recently? These comboboxes were working fine for me a 1-2 weeks ago and now I can't select any of the options, despite not making any related code changes or library upgrades.

My command component already has the data-[disabled=true] fix. It had been working fine for me on cmdk 1.0.0 and downgrading to 0.2.1 doesn't seem to fix it.

Still not sure what broke this for me, but I found a fix by adding the modal prop to the Popover component of my combobox:

<Popover modal open={open} onOpenChange={setOpen}>

@arvilmena
Copy link

if you have close() invocation inside the onBlur event, you need to delay it, or else your onClick side-effect won't run because the cmdk result is already removed due to the onBlur => close() trigger

@VietManh4112
Copy link

Any chance some of this behavior has resurfaced recently? These comboboxes were working fine for me a 1-2 weeks ago and now I can't select any of the options, despite not making any related code changes or library upgrades.
My command component already has the data-[disabled=true] fix. It had been working fine for me on cmdk 1.0.0 and downgrading to 0.2.1 doesn't seem to fix it.

Still not sure what broke this for me, but I found a fix by adding the modal prop to the Popover component of my combobox:

<Popover modal open={open} onOpenChange={setOpen}>

I managed to resolve the issue by removing the <PopoverPrimitive.Portal> inside popover.tsx

@unclebay143
Copy link

Any chance some of this behavior has resurfaced recently? These comboboxes were working fine for me a 1-2 weeks ago and now I can't select any of the options, despite not making any related code changes or library upgrades.
My command component already has the data-[disabled=true] fix. It had been working fine for me on cmdk 1.0.0 and downgrading to 0.2.1 doesn't seem to fix it.

Still not sure what broke this for me, but I found a fix by adding the modal prop to the Popover component of my combobox:

<Popover modal open={open} onOpenChange={setOpen}>

This fixed it for me! Thanks

@fullstackstef
Copy link

This resolved it for me:
<Popover modal open={open} onOpenChange={setOpen}>

But the issue I'm seeing now is the CommandInput component is not enabled nor does the search functionality work. Anyone else facing this issue? I'm using cmdk@1.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.