ui
ui copied to clipboard
Theme Provider: validateDOMNesting(...): <button> cannot appear as a descendant of <button>.
Hi everyone,
The error message "validateDOMNesting(...):
To reproduce the same error:
- Setup dark mode by shadcn/ui
- Switch the theme, you'll notice warning is showing into your console.
Warning:
Code:
where the warning is initiating...
Hi @aloksharma10, the ModeToggle example that you mentioned (it can also be seen here) doesn't nest buttons since the DropdownMenuTrigger has the asChild prop that changes the default rendered element to the one passed as a child.
You most likely forgot to add the asChild prop.
Hi @aloksharma10, the ModeToggle example that you mentioned (it can also be seen here) doesn't nest buttons since the
DropdownMenuTriggerhas theasChildprop that changes the default rendered element to the one passed as a child.You most likely forgot to add the
asChildprop.
I appreciate your reply, i already added 'asChild' prop in my codebase as you can see in my issue #2764,
To reproduce the same issue
- Create new next app, configure shadcn with your app
- Configure Dark Mode with your app, you'll see the same warning in your console
Hi @aloksharma10, I'm considering wrapping lines 26 to 30 into a separate component and then passing children as props from outside. This approach has proven effective for me.
im actually having the same issue, used asChild, this issues just started to come up
<TooltipProvider delayDuration={0}>
<Tooltip>
<TooltipTrigger>
<TooltipContent className="hidden sm:flex">Theme</TooltipContent>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TooltipTrigger>
</Tooltip>
</TooltipProvider>
The issue seems to be with Tooltip, wherever i use Tooltip i get this issue
same to me
The issue seems to be with Tooltip, wherever i use Tooltip i get this issue
I had the same problem with tooltips and when I added asChild to the <TooltipTrigger> tag, the problem went away.
<TooltipTrigger asChild>
</TooltipTrigger>
Hello!
I'm facing issues with using DropdownMenuTrigger with asChild prop as well.
So, I have this code that works just fine.
<DropdownMenuTrigger asChild>
<Button
variant='outline'
className='flex max-lg:p-0 max-lg:w-9'
>
<MixerHorizontalIcon className='lg:mr-2 h-4 w-4' />
<span className='max-lg:hidden lg:flex'>View</span>
</Button>
</DropdownMenuTrigger>
But when I refactor the Button into another component it doesn't work.
Refactored Button:
type IResponsiveButtonWithIconProps = {
text?: string;
icon?: React.FC;
buttonProps?: React.ComponentPropsWithoutRef<typeof Button>;
textProps?: React.ComponentPropsWithoutRef<'span'>;
iconProps?: React.ComponentPropsWithoutRef<'svg'>;
};
export const ResponsiveButtonWithIcon = forwardRef<
HTMLButtonElement,
IResponsiveButtonWithIconProps
>(
(
{
buttonProps = {},
textProps = {},
text = 'Actions',
icon: IconComponent = MoreVertical,
iconProps = {},
},
ref
) => {
const {className: buttonClassName, ...restButtonProps} = buttonProps;
const {className: spanClassName, ...restSpanProps} = textProps;
const {className: iconClassName, ...restIconProps} = iconProps;
return (
<Button
variant='outline'
className={cn('flex max-lg:p-0 max-lg:w-9', buttonClassName)}
{...restButtonProps}
ref={ref}
>
{IconComponent && (
<IconComponent
className={cn('lg:mr-2 h-4 w-4', iconClassName)}
{...restIconProps}
/>
)}
<span
className={cn('max-lg:hidden lg:flex', spanClassName)}
{...restSpanProps}
>
{text}
</span>
</Button>
);
}
);
The modified code:
<DropdownMenuTrigger /* asChild */>
<ResponsiveButtonWithIcon
buttonProps={
{
// option2: render as something elese
// as: 'div',
}
}
text='Actions'
icon={MoreVertical}
/>
Using asChild is not fixing the issue for me.
I want the tooltip for my buttons
const MyButton = (
<Button disabled={disable} className={className} style={style} onClick={onClick} variant="outline">
{text}
</Button>
);
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{MyButton}</TooltipTrigger>
<TooltipContent>
<p>{title}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
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.
Still same problem:
I cant nest an dialog in <TooltipTrigger> like this:
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Dialog>
<DialogTrigger asChild>
<Button variant="outline" size="icon">
<Pencil className="h-4 w-4" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit user infos</DialogTitle>
<DialogDescription> Change user infos and save changes </DialogDescription>
</DialogHeader>
<div>
</div>
<DialogFooter>
<DialogClose asChild>
<Button type="button" variant="secondary">Close</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
</TooltipTrigger>
<TooltipContent>Miau</TooltipContent>
</Tooltip>
</TooltipProvider>
Depending where i set asChild i get the error:
Warning: validateDOMNesting(...): <button> cannot appear as a descendant of <button>. or
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
same issue here, i have the issue DropdownMenuTrigger
same issue here, any updates?
Nope, it is still present.
Still occurring throughout the library.
This still happens inside the library, confirmed with Tooltip. Why is this issue closed?
Yup it still happens.
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<Badge
variant={type === "version" ? "outline" : "secondary"}
className="flex items-center gap-1"
>
{Icon && <Icon className="w-3 h-3" />}
{value}
</Badge>
</TooltipTrigger>
<TooltipContent>{description}</TooltipContent>
</Tooltip>
</TooltipProvider>
Adding asChild solves that but throws a different warning in my case:
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
simply forwarding ref in badge solved the warning
const Badge = React.forwardRef<HTMLDivElement, BadgeProps>(
({ className, variant, ...props }, ref) => {
return (
<div
ref={ref}
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
);
},
);
Oh god that's why I love shadcn, I can just go in the file and adjust it for my needs ❤️