Closed neo773 closed 11 months ago
You can make a couple of things:
Portal
component in popover (Maybe you have z-index
issues)modal={false}
on Dialog (The overlay will no be rendered)Dialog.Content
with Dialog.Overlay
(You can not set modal={false}
because the overlay will not be rendered)You can make a couple of things:
- Not render the
Portal
component in popover (Maybe you havez-index
issues)- Set
modal={false}
on Dialog (The overlay will no be rendered)- Wrap
Dialog.Content
withDialog.Overlay
(You can not setmodal={false}
because the overlay will not be rendered)
The 3rd option worked, Thanks.
could you post the working code
I am having the same issue.
<FormField
control={form.control}
name="timezone"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Timezone</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
role="combobox"
className={cn(
"w-[200px] justify-between",
!field.value && "text-muted-foreground"
)}
>
{field.value
? TimeZones.find((timezone) => timezone === field.value)
: "Select timezone"}
<CaretSortIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandInput placeholder="Search timezone..." />
<CommandEmpty>No timezone found.</CommandEmpty>
<ScrollArea className="h-60">
<CommandGroup>
{TimeZones.map((timezone) => (
<CommandItem
value={timezone}
key={timezone}
onSelect={() => {
form.setValue("timezone", timezone);
}}
>
<CheckIcon
className={cn(
"mr-2 h-4 w-4",
timezone === field.value
? "opacity-100"
: "opacity-0"
)}
/>
{timezone}
</CommandItem>
))}
</CommandGroup>
</ScrollArea>
</Command>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
In order to make the ScrollArea
work inside of a Dialog
, I ended up having to add a container
prop to my PopoverContent
, like so:
interface PopoverContentProps {
container?: HTMLElement
}
const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & PopoverContentProps
>(({ className, container, align = 'center', sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal container={container}>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
...
Then I wrapped all <CommandItem />
's inside of a ScrollArea
with a className
of h-[300px]
so that the search will remain at the top while I can scroll through all of the options.
Finally, in the component where I define the Dialog
that wraps everything, I defined a dialogRef
, like so:
const dialogRef = React.useRef<HTMLDivElement>(null)
return (
<Dialog defaultOpen>
<DialogContent
ref={dialogRef}
...
I also had to add the dialogRef
to my ComboBox
props.
interface ComboboxProps {
// All my other props are defined above here...
dialogRef?: React.RefObject<HTMLElement>
}
const Combobox: FC<ComboboxProps> = ({
dialogRef,
...
Lastly, add your dialogRef
to the PopoverContent
inside of the ComboBox
:
<PopoverContent
container={dialogRef?.current === null ? undefined : dialogRef?.current}
className="w-[350px] p-0"
>
So now you should be able to use your ComboBox
and the ScrollArea
should do its magic:
<Combobox dialogRef={dialogRef} />
Hope this helps!
I am having the same issue.
@KaramveerSinghSidhu Instead of ScrollArea, use the CommandList component like so:
<Command>
<CommandInput placeholder="Search language..." />
<CommandList>
<CommandEmpty>No language found.</CommandEmpty>
<CommandGroup>
{countryOptions.map((country) => {
console.log("COUNTRY>>>>", country)
return (
<CommandItem
value={country.label}
key={country.value}
onSelect={() => {
form.setValue("country", country.value)
}}
>
<CheckIcon
className={cn(
"mr-2 h-4 w-4",
country.value === field.value
? "opacity-100"
: "opacity-0"
)}
/>
{country.label}
</CommandItem>
)
})}
</CommandGroup>
</CommandList>
</Command>
@desiboli still not working.
<FormField
control={form.control}
name="timezone"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Timezone</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
role="combobox"
className={cn(
"w-[200px] justify-between",
!field.value && "text-muted-foreground"
)}
>
{field.value
? TimeZones.find((timezone) => timezone === field.value)
: "Select timezone"}
<CaretSortIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandInput placeholder="Search language..." />
<CommandList>
<CommandEmpty>No language found.</CommandEmpty>
<CommandGroup>
{TimeZones.map((timezone) => {
return (
<CommandItem
value={timezone}
key={timezone}
onSelect={() => {
form.setValue("timezone", timezone);
}}
>
<CheckIcon
className={cn(
"mr-2 h-4 w-4",
timezone === field.value
? "opacity-100"
: "opacity-0"
)}
/>
{timezone}
</CommandItem>
);
})}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
@KaramveerSinghSidhu That's weird it works for me, see video.
https://github.com/shadcn-ui/ui/assets/6296494/fdf647fe-5f0a-4e19-b163-37d43bbb3a77
Could you setup a sandbox where you can reproduce this ?
Set modal={true}
in popover like this
<Popover open={open} modal={true}>
✔
Thanks 😎
Isn't there a straightforward way to show a scroll bar on a Dialog
if it contains too much content or is too big for the screen to fit?
PS: I am not using popover just pure input fields in the dialog
I had this issue with the DropdownMenu component. In the end I managed to get this working by simply setting max-h- and overflow-scroll as tailwind classes on the DropdownMenuContent element, also tried it with the PopOverContent and it works, so i would assume this would also work on dialog and commandList
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="px-4">
{itemId > 0 ? 'Selected: ' + itemId : 'Select Range Item'}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="max-h-80 overflow-scroll">
{rangeItems.map((item) => (
<DropdownMenuItem
className={'text-sm' + (item.id == itemId ? ' bg-gray-200' : '')}
onClick={() => {
setItemId(item.id);
}}
>
{item.id + ' | ' + item.allocation}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
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>
));
When using
ScrollArea
insideDialog
gesture scrolling doesn't work only way to navigate is by grabbing the scroll indicatorhttps://github.com/shadcn/ui/assets/62795688/ea1abc45-19f7-4969-812e-5b376e1a3f9a
To reproduce this bug
index.ts
ComboBox.ts