fix: Dropdown menus rendering outside SPA container
- Add getPortalContainer to DropdownMenuContent (like Dialog) - Portal container created inside #woonoow-admin-app - Copy theme class (light/dark) for proper CSS variable inheritance - Fixes Add Section dropdown styling in Page Editor
This commit is contained in:
@@ -57,20 +57,46 @@ DropdownMenuSubContent.displayName =
|
||||
const DropdownMenuContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Portal>
|
||||
<DropdownMenuPrimitive.Content
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
||||
"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 origin-[--radix-dropdown-menu-content-transform-origin]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
))
|
||||
>(({ className, sideOffset = 4, ...props }, ref) => {
|
||||
// Get or create portal container inside the app for proper CSS scoping
|
||||
const getPortalContainer = () => {
|
||||
const appContainer = document.getElementById('woonoow-admin-app');
|
||||
if (!appContainer) return document.body;
|
||||
|
||||
let portalRoot = document.getElementById('woonoow-dropdown-portal');
|
||||
if (!portalRoot) {
|
||||
portalRoot = document.createElement('div');
|
||||
portalRoot.id = 'woonoow-dropdown-portal';
|
||||
// Copy theme class from documentElement for proper CSS variable inheritance
|
||||
const themeClass = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
|
||||
portalRoot.className = themeClass;
|
||||
appContainer.appendChild(portalRoot);
|
||||
} else {
|
||||
// Update theme class in case it changed
|
||||
const themeClass = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
|
||||
if (!portalRoot.classList.contains(themeClass)) {
|
||||
portalRoot.classList.remove('light', 'dark');
|
||||
portalRoot.classList.add(themeClass);
|
||||
}
|
||||
}
|
||||
return portalRoot;
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal container={getPortalContainer()}>
|
||||
<DropdownMenuPrimitive.Content
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
||||
"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 origin-[--radix-dropdown-menu-content-transform-origin]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
);
|
||||
})
|
||||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
||||
|
||||
const DropdownMenuItem = React.forwardRef<
|
||||
|
||||
Reference in New Issue
Block a user