ui
ui copied to clipboard
Sheet portal still displaying content in the body
I may have this wrong but does the SheetPortal allow the content to display within a div rather than the body? This is how I understand it from the Dialog docs. I'm passing the portal element through but it seems to still be mounting to the body.
return (
domReady ?
<div className='flex justify-end'>
<Sheet>
<SheetTrigger asChild>
<Button variant="outline"><ShoppingCart className='pr-2' />£{cartData.total}</Button>
</SheetTrigger>
<SheetPortal container={portal}>
<SheetContent>
<SheetHeader>
<SheetTitle>Cart</SheetTitle>
<SheetDescription>
Total: £{cartData.total}
</SheetDescription>
</SheetHeader>
{cartData.items.map(item => (
<div className='grid grid-cols-4 gap-4'>
<div className='col-span-3'>
<h3>{item.name}</h3>
<p>Quantity: {item.quantity}</p>
<p>£{item.price}</p>
</div>
<Button variant="destructive" className='col-span-1' onClick={(e) => handleDeleteCartItem(e, item)}>Delete</Button>
</div>
))}
<SheetFooter>
<SheetClose asChild>
<Button type="submit">Save changes</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</SheetPortal>
</Sheet>
</div>
:
null
);
```
The portal:
```
const ShopUI: React.FC<ShopUIProps> = ({ shopData, cartData, setCartData }) => {
const [container, setContainer] = useState<HTMLDivElement | null>(null);
return (
<div className="bg-zinc-700 p-4 rounded-lg shadow-lg max-w-3xl h-[80vh]">
<div ref={setContainer}></div>
<h3 className="text-lg text-white font-medium mb-2">SHOP</h3>
<span>
<Cart cartData={cartData} setCartData={setCartData} portal={container} />
</span>
<ScrollArea className='h-[85%] w-full pr-2 mt-2'>
<div className="grid grid-cols-4 gap-4">
{shopData.items.map(item => (
<Item key={item.id} item={item} cartData={cartData} setCartData={setCartData} />
))}
</div>
</ScrollArea>
</div>
);
}
Expected output:
Could you reproduce the code? It would be much easier to help that way. But from the first glance I'd say that you should use useRef instead of useState and assign it to your div
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.
@T3mpu5 were you able to resolve this?
No I didn't. I ended up using ant design instead
I had the same problem, passed the container element, like this:
<SheetContent side="right" container={document.getElementById('YourDivID')}>
and updated my shadcn component to add the container inside it (sheet.tsx)
<SheetPortal container={props?.container}>
sorry if this comment is useless, this was just my case
Is there any solution to this issue? I tried different combinations following the Dialog docs (not working), however didn't succeed. If anybody solved that: I would be really happy to hear about it. @SukiDivine did you solve it? If yes, can you elaborate please?
The portal works as expected, but the problem is caused by the styling.
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
},
);
Your SheetContent
has the style "fixed inset-y-0", which makes it cover the full screen as if it were rendered in 'document.body'.
I had the same problem, passed the container element, like this:
<SheetContent side="right" container={document.getElementById('YourDivID')}>
and updated my shadcn component to add the container inside it (sheet.tsx)<SheetPortal container={props?.container}>
sorry if this comment is useless, this was just my case
In my case, I achieved the desired result by adding the styles transform: translateZ(0)
(tailwind: transform transform-z-0
) to the container (#YourDivID). This creates a new stacking context and forces the element with fixed positioning to be contained within the specified container.
However, you might want to try solving the issue using more conventional methods. You could give the container a position: relative
property and change the positioning of the element itself from fixed
to absolute
.
Both approaches can work, but the second method is generally more predictable and widely supported across browsers. Choose the one that best fits your specific use case and layout requirements.