0

To have the drawer open only within a specific div in my chat application built with Shadecdn/ui, how can I achieve this? I want the drawer to open within a specific div, meaning I want it to open only within the chat screen, not the entire page.

I want it to open only within the chat screen, not the entire page.

1 Answer 1

2
  1. In components/ui/drawer.tsx, replace the fixed className in <DrawerOverlay /> and <DrawerContent /> by absolute.

  2. Don't render <DrawerPortal>. change the line 31, 44 from <DrawerPortal> to <>.

  3. When rendering the drawer give the parent <Chat /> relative className.

export default function Page() {
  return (
    <div className="min-h-screen flex justify-center items-center">
      <div className="size-96 bg-sky-300 relative overflow-hidden">
        <Drawer>
          <DrawerTrigger>Trigger</DrawerTrigger>
          <DrawerContent>
            Content
          </DrawerContent>
        </Drawer>
      </div>
    </div>
  )
}

components/ui/drawer.tsx:

'use client';

import * as React from 'react';
import { Drawer as DrawerPrimitive } from 'vaul';

import { cn } from "@/lib/utils";

const Drawer = ({ shouldScaleBackground = true, ...props }: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
  <DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...props} />
);
Drawer.displayName = 'Drawer';

const DrawerTrigger = DrawerPrimitive.Trigger;

const DrawerPortal = DrawerPrimitive.Portal;

const DrawerClose = DrawerPrimitive.Close;

const DrawerOverlay = React.forwardRef<
  React.ElementRef<typeof DrawerPrimitive.Overlay>,
  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
>(({ className, ...props }, ref) => (
  <DrawerPrimitive.Overlay ref={ref} className={cn('absolute inset-0 z-50 bg-black/80', className)} {...props} />
));
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;

const DrawerContent = React.forwardRef<
  React.ElementRef<typeof DrawerPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
>(({ className, children, ...props }, ref) => (
  <>
    <DrawerOverlay />
    <DrawerPrimitive.Content
      ref={ref}
      className={cn(
        'absolute inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
        className,
      )}
      {...props}
    >
      <div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
      {children}
    </DrawerPrimitive.Content>
  </>
));
DrawerContent.displayName = 'DrawerContent';

const DrawerHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
  <div className={cn('grid gap-1.5 p-4 text-center sm:text-left', className)} {...props} />
);
DrawerHeader.displayName = 'DrawerHeader';

const DrawerFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
  <div className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...props} />
);
DrawerFooter.displayName = 'DrawerFooter';

const DrawerTitle = React.forwardRef<
  React.ElementRef<typeof DrawerPrimitive.Title>,
  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
>(({ className, ...props }, ref) => (
  <DrawerPrimitive.Title
    ref={ref}
    className={cn('text-lg font-semibold leading-none tracking-tight', className)}
    {...props}
  />
));
DrawerTitle.displayName = DrawerPrimitive.Title.displayName;

const DrawerDescription = React.forwardRef<
  React.ElementRef<typeof DrawerPrimitive.Description>,
  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
>(({ className, ...props }, ref) => (
  <DrawerPrimitive.Description ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />
));
DrawerDescription.displayName = DrawerPrimitive.Description.displayName;

export {
  Drawer,
  DrawerPortal,
  DrawerOverlay,
  DrawerTrigger,
  DrawerClose,
  DrawerContent,
  DrawerHeader,
  DrawerFooter,
  DrawerTitle,
  DrawerDescription,
};

That's it. You might need to change some styles to fit with your use case.

Sign up to request clarification or add additional context in comments.

8 Comments

Hello Ahmed, thank you very much, it worked for me. Your explanation step by step and explanation with code examples is very nice and thank you for your quick response.
Do you know how to prevent the default styling applied to HTML and body? There's a situation where HTML and body styles are being added, and I want to prevent that.
the styles is from vaul github.com/emilkowalski/vaul/blob/main/src/index.tsx You have the option to patch the package or copy it to your files and modify it (vaul is MIT license)
or override them by css !important
Thank you. When I looked at the vault references, I noticed that there is a "nested" property. When set to true, it stops the calculations and only shows the locked status. However, this still doesn't seem to be blocking me for now.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.