ui icon indicating copy to clipboard operation
ui copied to clipboard

`ScrollArea` doesn't work inside `Combobox`

Open hisamafahri opened this issue 1 year ago • 27 comments

Problem

Can't scroll the contents inside the CommandGroup of the Combobox component.

image

However, the scroll only works in the tiny scrollbar.

image

Expected

Can scroll if cursor on top of the items

Reproducable

Codesandbox: link

hisamafahri avatar Jun 17 '23 12:06 hisamafahri

It's an issue with Radix https://github.com/radix-ui/primitives/issues/1159. In the meantime, you can remove the portal part from Popover

joaom00 avatar Jun 17 '23 15:06 joaom00

Hey can you try this? I tried editing in the sandbox but it lagged so bad.

<Popover open={open} onOpenChange={setOpen}> <PopoverTrigger asChild> <Button variant='outline' role='combobox' aria-expanded={open} className='w-[200px] justify-between'> {value ? frameworks.find((framework) => framework.value === value)?.label : 'Select framework...'} <ChevronsUpDown className='ml-2 h-4 w-4 shrink-0 opacity-50' /> </Button> </PopoverTrigger> <PopoverContent className='w-[200px] p-0'> <Command> <CommandInput placeholder='Search framework...' /> <CommandEmpty>No framework found.</CommandEmpty> <ScrollArea className='h-24 overflow-auto'> <CommandGroup> {frameworks.map((framework) => ( <CommandItem key={framework.value} onSelect={(currentValue) => { setValue(currentValue === value ? '' : currentValue); setOpen(false); }}> <Check className={cn( 'mr-2 h-4 w-4', value === framework.value + 'a' ? 'opacity-100' : 'opacity-0' )} /> {framework.label + ' '} </CommandItem> ))} </CommandGroup> </ScrollArea> </Command> </PopoverContent> </Popover>

jacksonnadar avatar Jun 21 '23 07:06 jacksonnadar

<Popover open={open} onOpenChange={setOpen}> <PopoverTrigger asChild> <Button variant='outline' role='combobox' aria-expanded={open} className='w-[200px] justify-between'> {value ? frameworks.find((framework) => framework.value === value)?.label : 'Select framework...'} <ChevronsUpDown className='ml-2 h-4 w-4 shrink-0 opacity-50' /> </Button> </PopoverTrigger> <PopoverContent className='w-[200px] p-0'> <Command> <CommandInput placeholder='Search framework...' /> <CommandEmpty>No framework found.</CommandEmpty> <ScrollArea className='h-24 overflow-auto'> <CommandGroup> {frameworks.map((framework) => ( <CommandItem key={framework.value} onSelect={(currentValue) => { setValue(currentValue === value ? '' : currentValue); setOpen(false); }}> <Check className={cn( 'mr-2 h-4 w-4', value === framework.value + 'a' ? 'opacity-100' : 'opacity-0' )} /> {framework.label + ' '} </CommandItem> ))} </CommandGroup> </ScrollArea> </Command> </PopoverContent> </Popover>

Hey! Sorry but what do you mean by removing the portal part from Popover?

PirexDEV avatar Jun 27 '23 17:06 PirexDEV

Hey! Sorry but what do you mean by removing the portal part from Popover?

I mean just not render the PopoverPrimitive.Portal component

joaom00 avatar Jun 27 '23 20:06 joaom00

I am not sure if it's the same issue from radix, but I also am not getting a working scroll area in the following setup:

<Sheet>
  <SheetContent>
    <Tabs>
      <ScrollArea>
        <TabsContent>        <-- this is not scrolling

using overflow-auto on TabsContent instead does work but does not have the benefits of ScrollArea

chasedavis avatar Jul 12 '23 04:07 chasedavis

I mean just not render the PopoverPrimitive.Portal component

The same issue persists if there's no Portal component. For example, I'm not able to scroll inside the combobox here:

<FormItem className="flex flex-col">
                        <FormLabel>Options</FormLabel>
                        <Popover>
                          <PopoverTrigger asChild>
                            <FormControl>
                              <Button
                                variant="outline"
                                role="combobox"
                                className={cn(
                                  "justify-between",
                                  !field.value && "text-muted-foreground"
                                )}
                              >
                                {field.value
                                  ? options.find(
                                      (option) => option.value === field.value
                                    )?.label
                                  : "Select option"}
                                <Icon
                                  name="chevrons-up-down"
                                  className="ml-1 h-4 w-4 shrink-0 opacity-50"
                                />
                              </Button>
                            </FormControl>
                          </PopoverTrigger>
                          <PopoverContent
                            className="max-h-[150px] overflow-y-scroll w-[110px] p-0" //trying to set a max height and overflow but no luck
                            sticky="always"
                            side="bottom"
                          >
                            <Command>
                              <CommandInput
                                placeholder="Search..."
                                className="h-9"
                              />
                              <CommandEmpty>Nothing found.</CommandEmpty>
                              <CommandGroup>
                                {options.map((option) => (
                                  <CommandItem
                                    value={option.value}
                                    key={option.value}
                                    onSelect={(value) => {
                                      form.setValue("option", value);
                                    }}
                                  >
                                    {option.label}
                                    <Icon
                                      name="check"
                                      asSpan={false}
                                      className={cn(
                                        "ml-auto h-4 w-4",
                                        option.value === field.value
                                          ? "opacity-100"
                                          : "opacity-0"
                                      )}
                                    />
                                  </CommandItem>
                                ))}
                              </CommandGroup>
                            </Command>
                          </PopoverContent>
                        </Popover>
                        <FormMessage />
                      </FormItem>
                    )}
/>

sp88011 avatar Jul 14 '23 20:07 sp88011

Wrap the <CommandEmpty /> and the <CommandGroup /> with the <ScrollArea />

Something like this, it works for me:

<ScrollArea className="h-96">
  <CommandEmpty>Not found</CommandEmpty>
  <CommandGroup>
    {data.map((item) => (
        <CommandItem
          key={item.value}
          value={item.value}
          onSelect={handleOnChange}
        >
          {item.label}
          <CheckIcon
            className={cn(
              "ml-auto h-4 w-4",
              selected === item.value ? "opacity-100" : "opacity-0"
            )}
          />
        </CommandItem>
      ))
    }
  </CommandGroup>
</ScrollArea>

atleugim avatar Aug 08 '23 20:08 atleugim

thanks @atleugim it works fine.

I had to remove the PopoverPrimitive.Portal from the Popover component, too ( replaced it with <> - source: https://github.com/shadcn-ui/ui/issues/607#issuecomment-1610187963 )

noxify avatar Aug 09 '23 20:08 noxify

I wanted a solution that allows the ComboBox to use a portal unless it's inside a Dialog. To avoid passing props through consumers, I added a DialogContext that communicates down-tree that a Dialog is present. This allows the Popover to render the portal or not accordingly.

I assume there's a downside to this approach I can't see, but it seems less destructive than globally removing the popover portal just for the ComboBox in some less common scenarios. Thanks to @noxify and @atleugim for the pointers.

// popover

const PopoverContent = React.forwardRef<
  React.ElementRef<typeof PopoverPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => {
  // do not want to render portals inside dialogs
  // this causes scroll problems
  // ref: https://github.com/shadcn-ui/ui/issues/607

  const isInsideDialog = React.useContext(DialogContext);
  const shouldRenderWithoutPortal = isInsideDialog;

  const content = (
    <PopoverPrimitive.Content
      ref={ref}
      align={align}
      sideOffset={sideOffset}
      className={cn(
        "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
        className
      )}
      {...props}
    />
  );

  if (shouldRenderWithoutPortal) {
    return content;
  }

  return <PopoverPrimitive.Portal>{content}</PopoverPrimitive.Portal>;
});
// dialog

const Dialog: typeof DialogPrimitive.Root = (props) => (
  // this provider exists to tell downstream consumers (like Popover) that they
  // are inside a dialog and should render themselves accordingly

  <DialogProvider isInsideDialog={true}>
    <DialogPrimitive.Root {...props} />
  </DialogProvider>
);

// ... same as reference for other comps

type DialogContextValue = {
  isInsideDialog: boolean;
};

export const DialogContext = React.createContext<DialogContextValue>({
  isInsideDialog: false,
});

const DialogProvider = ({
  children,
}: React.PropsWithChildren<DialogContextValue>) => (
  <DialogContext.Provider value={{ isInsideDialog: true }}>
    {children}
  </DialogContext.Provider>
);

My combo box code is the same as the reference except I added classes for max height and overflow. I am not using a ScrollArea.

// combo box
// ... same as ref except for:

 <CommandGroup className="max-h-60 overflow-y-auto">

// .. same

byronwall avatar Oct 08 '23 13:10 byronwall

If it's helpful for anyone, I'm using it inside a Popover similar to the example given in the docs, the installed component using npx for popover, the PopoverContent component is returning it wrapped in <PopoverPrimitive.Portal> I just removed the portal and instead wrapped it with <></> and now scrolling works. I haven't yet figured out if it breaks anything else, I'll update here if I find an issue with my solution.

jad-eljerdy avatar Oct 17 '23 16:10 jad-eljerdy

I could fix the error adding className="h-48 overflow-auto" to the className of the ScrollArea

                    <ScrollArea className="h-48 overflow-auto">
                      <CommandGroup>
                        {ingredients.map((ingredient) => (
                          <CommandItem
                            value={ingredient.name}
                            key={ingredient.id}
                            onSelect={() => {
                              form.setValue("ingredient_id", ingredient.id);
                            }}
                          >
                            {ingredient.name}
                            <CheckIcon
                              className={cn(
                                "ml-auto h-4 w-4",
                                ingredient.id === field.value
                                  ? "opacity-100"
                                  : "opacity-0"
                              )}
                            />
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </ScrollArea>

Now I can scroll the items of the CommandGroup

jhcueva avatar Nov 16 '23 14:11 jhcueva

https://github.com/shadcn-ui/ui/issues/542#issuecomment-1587142689

Setting modal={true} as suggested by ^ helped fix for me w/o the need of <ScrollArea />

taochu avatar Nov 20 '23 06:11 taochu

#542 (comment)

This works for me too! Thanks!

mununki avatar Nov 28 '23 07:11 mununki

Wrap the <CommandEmpty /> and the <CommandGroup /> with the <ScrollArea />

Something like this, it works for me:

<ScrollArea className="h-96">
  <CommandEmpty>Not found</CommandEmpty>
  <CommandGroup>
    {data.map((item) => (
        <CommandItem
          key={item.value}
          value={item.value}
          onSelect={handleOnChange}
        >
          {item.label}
          <CheckIcon
            className={cn(
              "ml-auto h-4 w-4",
              selected === item.value ? "opacity-100" : "opacity-0"
            )}
          />
        </CommandItem>
      ))
    }
  </CommandGroup>
</ScrollArea>

Works great!

doriandevelops avatar Dec 03 '23 00:12 doriandevelops

Here is a nice workaround, which simulates arrow-up and arrow-down when you using the muse wheel over the the <PopoverContent /> component. Replace the relevant lines in your ui/popover.tsx file with these:

const PopoverContent = React.forwardRef<
	React.ElementRef<typeof PopoverPrimitive.Content>,
	React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
	<PopoverPrimitive.Portal>
		<PopoverPrimitive.Content
			ref={ref}
			align={align}
			className={cn(
				"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
				className
			)}
			sideOffset={sideOffset}
			/**
			 * Fix for issue with scrolling:
			 * @see https://github.com/shadcn-ui/ui/issues/607
			 */
			onWheel={(e) => {
				e.stopPropagation();

				const isScrollingDown = e.deltaY > 0;

				if (isScrollingDown) {
					// Simulate arrow down key press
					e.currentTarget.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowDown" }));
				} else {
					// Simulate arrow up key press
					e.currentTarget.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowUp" }));
				}
			}}
			{...props}
		/>
	</PopoverPrimitive.Portal>
));

pa4080 avatar Dec 17 '23 13:12 pa4080

Here is a nice workaround, which simulates arrow-up and arrow-down when you using the muse wheel over the the <PopoverContent /> component. Replace the relevant lines in your ui/popover.tsx file with these:

const PopoverContent = React.forwardRef<
	React.ElementRef<typeof PopoverPrimitive.Content>,
	React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
	<PopoverPrimitive.Portal>
		<PopoverPrimitive.Content
			ref={ref}
			align={align}
			className={cn(
				"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
				className
			)}
			sideOffset={sideOffset}
			/**
			 * Fix for issue with scrolling:
			 * @see https://github.com/shadcn-ui/ui/issues/607
			 */
			onWheel={(e) => {
				e.stopPropagation();

				const isScrollingDown = e.deltaY > 0;

				if (isScrollingDown) {
					// Simulate arrow down key press
					e.currentTarget.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowDown" }));
				} else {
					// Simulate arrow up key press
					e.currentTarget.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowUp" }));
				}
			}}
			{...props}
		/>
	</PopoverPrimitive.Portal>
));

This works great! Hopefully this gets fixed soon!

LightBounded avatar Dec 30 '23 16:12 LightBounded

#542 (comment)

This also worked me. No need to scrollarea

dwolrdcojp avatar Jan 09 '24 21:01 dwolrdcojp

For me 2 solutions worked:

  1. Remove PopoverPrimitive.Portal - Simpler but may affect operation

  2. Use the onWheel configuration in PopoverPrimitive.Content mentioned above by @pa4080 in conjunction with the ScrollArea around CommandEmpty and CommandGroup - More complex but does not need to remove PopoverPrimitive.Portal

  • ScrollArea Captura de Tela 2024-01-30 às 18 59 25
  • PopoverPrimitive.Content

code23

Aszurar avatar Jan 30 '24 22:01 Aszurar

For anyone who just wants to make the combobox scrollable, you can also use CommandList. Example: https://github.com/shadcn-ui/ui/blob/main/apps/www/components/command-menu.tsx#L77

krisantuswanandi avatar Feb 06 '24 16:02 krisantuswanandi

There are 2 solutions outlined and they both work but the styling is not what I expect.

  1. Like @krisantuswanandi mentioned, you can use CommandList from cmdk to create a scrollbar in ComboBox. ComboBox uses the Command component and uses cmdk.

  2. Use ScrollArea to create a scrollbar in ComboBox and pass in overflow-y-auto like everyone else that has mentioned.

This is the scrollbar styling I expect from shadcn ScrollArea here. Screenshot 2024-02-08 at 1 44 04 pm

However, both solutions creates a Scrollbar that gives me this and the styling can be found from cmdk here. Screenshot 2024-02-08 at 1 43 22 pm

Is there a fix for this issue? / Can we have a version of the component without using cmdk?

DerekWang98 avatar Feb 08 '24 02:02 DerekWang98

I wanted a solution that allows the ComboBox to use a portal unless it's inside a Dialog. To avoid passing props through consumers, I added a DialogContext that communicates down-tree that a Dialog is present. This allows the Popover to render the portal or not accordingly.

I assume there's a downside to this approach I can't see, but it seems less destructive than globally removing the popover portal just for the ComboBox in some less common scenarios. Thanks to @noxify and @atleugim for the pointers.

// popover

const PopoverContent = React.forwardRef<
  React.ElementRef<typeof PopoverPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => {
  // do not want to render portals inside dialogs
  // this causes scroll problems
  // ref: https://github.com/shadcn-ui/ui/issues/607

  const isInsideDialog = React.useContext(DialogContext);
  const shouldRenderWithoutPortal = isInsideDialog;

  const content = (
    <PopoverPrimitive.Content
      ref={ref}
      align={align}
      sideOffset={sideOffset}
      className={cn(
        "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
        className
      )}
      {...props}
    />
  );

  if (shouldRenderWithoutPortal) {
    return content;
  }

  return <PopoverPrimitive.Portal>{content}</PopoverPrimitive.Portal>;
});
// dialog

const Dialog: typeof DialogPrimitive.Root = (props) => (
  // this provider exists to tell downstream consumers (like Popover) that they
  // are inside a dialog and should render themselves accordingly

  <DialogProvider isInsideDialog={true}>
    <DialogPrimitive.Root {...props} />
  </DialogProvider>
);

// ... same as reference for other comps

type DialogContextValue = {
  isInsideDialog: boolean;
};

export const DialogContext = React.createContext<DialogContextValue>({
  isInsideDialog: false,
});

const DialogProvider = ({
  children,
}: React.PropsWithChildren<DialogContextValue>) => (
  <DialogContext.Provider value={{ isInsideDialog: true }}>
    {children}
  </DialogContext.Provider>
);

My combo box code is the same as the reference except I added classes for max height and overflow. I am not using a ScrollArea.

// combo box
// ... same as ref except for:

 <CommandGroup className="max-h-60 overflow-y-auto">

// .. same

I like your idea but i think removing the portal isn't the best solution i found that you just have to put modal={true} in popover so i made this change to the popover component:

import { DialogContext } from '@/components/ui/dialog'

const Popover: typeof PopoverPrimitive.Root = (props) => {
  const isInsideDialog = React.useContext(DialogContext)
  return <PopoverPrimitive.Root {...props} modal={Boolean(isInsideDialog)} />
}

victorcesae avatar Feb 08 '24 13:02 victorcesae

For me, setting max height for Command component and ScrollArea's overflow to auto worked:

<Command className="max-h-96">
   <CommandInput placeholder="Search region..." />
   <CommandEmpty>No region found.</CommandEmpty>
   <ScrollArea className="overflow-auto">
      <CommandGroup>
         {regions.map((region) => (...
          )}
      </CommandGroup>
   </ScrollArea>
</Command>

rodrigolalbuquerque avatar Mar 05 '24 13:03 rodrigolalbuquerque

Oh wow, this did it for me:

https://github.com/shadcn-ui/ui/issues/607#issuecomment-1672111729

Also adding a scroll area made this work too. What's the portal for?

divmgl avatar Mar 08 '24 05:03 divmgl

How can I focus on the selected value when open the combobox again? Select component has the behavior, need to achieve it with combobox.

kayumuzzaman avatar Mar 19 '24 19:03 kayumuzzaman

Hey! Sorry but what do you mean by removing the portal part from Popover?

I mean just not render the PopoverPrimitive.Portal component

it worked with select if removed </SelectPrimitive.Portal> thx👌

HzDev3628 avatar Apr 04 '24 19:04 HzDev3628

#542 (comment)

Setting modal={true} as suggested by ^ helped fix for me w/o the need of <ScrollArea />

This is much simpler solution than any of above. You can go even simpler by ignoring ={true} as JSX will interpreter it as true by default <Popover modal>

Cybermb avatar Apr 20 '24 21:04 Cybermb

I was trying to use Shadcnui's ScrollArea, but with popover and dialog it wasn't working, it didn't generate the vertical bar, what helped me was indicating the ref in the Scroll within the ComandList, maybe it will work for someone else, remembering that they didn't want the bar system scrolling. I tested it with Popover and it doesn't work, but with Dialog it works fine. my code modification:

  React.ElementRef<typeof CommandPrimitive.List>,
  React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
  >(({ className, ...props }, ref) => (
    <ScrollArea ref={ref}>
    <CommandPrimitive.List
      ref={ref}
      className={cn('h-[400px] overflow-hidden overflow-x-hidden', className)}
      {...props}
      />
      <ScrollBar orientation='vertical'/>
    </ScrollArea>
));

projetos-sidnei avatar Apr 28 '24 21:04 projetos-sidnei

Thankyou it really worked for me !!

Inside popover.tsx just replace PopoverContent with below one :-

`const PopoverContent = React.forwardRef< React.ElementRef<typeof PopoverPrimitive.Content>, React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>

(({ className, align = 'center', sideOffset = 4, ...props }, ref) => ( <> <PopoverPrimitive.Content ref={ref} align={align} sideOffset={sideOffset} className={cn( 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', className )} {...props} /> </> ))`

subr1oto avatar May 01 '24 07:05 subr1oto

I mean just not render the PopoverPrimitive.Portal component

The same issue persists if there's no Portal component. For example, I'm not able to scroll inside the combobox here:

<FormItem className="flex flex-col">
                        <FormLabel>Options</FormLabel>
                        <Popover>
                          <PopoverTrigger asChild>
                            <FormControl>
                              <Button
                                variant="outline"
                                role="combobox"
                                className={cn(
                                  "justify-between",
                                  !field.value && "text-muted-foreground"
                                )}
                              >
                                {field.value
                                  ? options.find(
                                      (option) => option.value === field.value
                                    )?.label
                                  : "Select option"}
                                <Icon
                                  name="chevrons-up-down"
                                  className="ml-1 h-4 w-4 shrink-0 opacity-50"
                                />
                              </Button>
                            </FormControl>
                          </PopoverTrigger>
                          <PopoverContent
                            className="max-h-[150px] overflow-y-scroll w-[110px] p-0" //trying to set a max height and overflow but no luck
                            sticky="always"
                            side="bottom"
                          >
                            <Command>
                              <CommandInput
                                placeholder="Search..."
                                className="h-9"
                              />
                              <CommandEmpty>Nothing found.</CommandEmpty>
                              <CommandGroup>
                                {options.map((option) => (
                                  <CommandItem
                                    value={option.value}
                                    key={option.value}
                                    onSelect={(value) => {
                                      form.setValue("option", value);
                                    }}
                                  >
                                    {option.label}
                                    <Icon
                                      name="check"
                                      asSpan={false}
                                      className={cn(
                                        "ml-auto h-4 w-4",
                                        option.value === field.value
                                          ? "opacity-100"
                                          : "opacity-0"
                                      )}
                                    />
                                  </CommandItem>
                                ))}
                              </CommandGroup>
                            </Command>
                          </PopoverContent>
                        </Popover>
                        <FormMessage />
                      </FormItem>
                    )}
/>

For anyone still having this issue, the Shad PopoverContent component automatically wraps it's children in the questionable Portal component. Just change your Popover file to this:

const PopoverContentNoPortal = React.forwardRef<
  React.ElementRef<typeof PopoverPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
    <PopoverPrimitive.Content
      ref={ref}
      align={align}
      sideOffset={sideOffset}
      className={cn(
        "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
        className
      )}
      {...props}
    />
))


const PopoverContent = React.forwardRef<
  React.ElementRef<typeof PopoverPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>((props, ref) => (
  <PopoverPrimitive.Portal>
        <PopoverContentNoPortal {...props} ref={ref} />
  </PopoverPrimitive.Portal>
))

and use the PopoverContentNoPortal component instead of the PopoverContent in places where you're having issues with scrolling.

igloo1505 avatar Jun 15 '24 17:06 igloo1505

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.

shadcn avatar Jul 08 '24 23:07 shadcn