Giter Site home page Giter Site logo

Dialog Overflow Behavior about ui HOT 35 OPEN

jnsdrssn avatar jnsdrssn commented on June 14, 2024 67
Dialog Overflow Behavior

from ui.

Comments (35)

adaptive-shield-matrix avatar adaptive-shield-matrix commented on June 14, 2024 216

Workaround:
I fixed this problem for myself by adding overflow-y-scroll max-h-screen classes to DialogContent

example usage:

<Dialog>
  <DialogTrigger asChild>
    <Button variant={"ghost"} title={"Text""} />
  </DialogTrigger>
  <DialogContent className={"lg:max-w-screen-lg overflow-y-scroll max-h-screen"}>
   todo...
  </DialogContent>
</Dialog>

from ui.

intuity-hans avatar intuity-hans commented on June 14, 2024 28

I started from a blank Next13 template and tried to recreate it. To make it overflow nicely I just had to adjust the components inside the dialog.tsx created by shadcn.
Your issues might be due to the way the dialog is positioned. It initially used some css-transform to center it on the screen. I couldnt find anything in your code on a first glance. Or you are using the Dialog inside some other element that is positioned relative affecting the way the absolute elements inside the dialog component are positioned?

Should we maybe add the Link to the radix documentation regarding overflow somewhere in the docs?

This is my dialog-component:

"use client";

import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react";

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

const Dialog = DialogPrimitive.Root;

const DialogTrigger = DialogPrimitive.Trigger;

const DialogPortal = ({
  className,
  ...props
}: DialogPrimitive.DialogPortalProps) => (
  <DialogPrimitive.Portal className={cn(className)} {...props} />
);
DialogPortal.displayName = DialogPrimitive.Portal.displayName;

const DialogOverlay = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Overlay>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
  <DialogPrimitive.Overlay
    ref={ref}
    className={cn(
      "fixed inset-0 z-50 bg-black/30 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 overflow-y-auto py-16 grid place-items-center",
      className
    )}
    {...props}
  />
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;

const DialogContent = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
  <DialogPortal>
    <DialogOverlay>
      <DialogPrimitive.Content
        ref={ref}
        className={cn(
          "z-50 grid w-full max-w-lg gap-4 bg-background p-6 shadow-lg duration-200 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 sm:rounded-lg md:w-full relative",
          className
        )}
        {...props}
      >
        {children}
        <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
          <X className="h-4 w-4" />
          <span className="sr-only">Close</span>
        </DialogPrimitive.Close>
      </DialogPrimitive.Content>
    </DialogOverlay>
  </DialogPortal>
));
DialogContent.displayName = DialogPrimitive.Content.displayName;

const DialogHeader = ({
  className,
  ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
  <div
    className={cn(
      "flex flex-col space-y-1.5 text-center sm:text-left",
      className
    )}
    {...props}
  />
);
DialogHeader.displayName = "DialogHeader";

const DialogFooter = ({
  className,
  ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
  <div
    className={cn(
      "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
      className
    )}
    {...props}
  />
);
DialogFooter.displayName = "DialogFooter";

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

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

export {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogFooter,
  DialogTitle,
  DialogDescription,
};

from ui.

murtaza-ahmad-khan avatar murtaza-ahmad-khan commented on June 14, 2024 20

Use shadcn ScrollArea component.

<Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg p-0">
        <ScrollArea className="max-h-[80vh] p-6">
          <DialogHeader>
            <DialogTitle>Title</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 mx-1">
          </div>

          <DialogFooter>
          </DialogFooter>
        </ScrollArea>
      </DialogContent>
    </Dialog>

from ui.

jeromevvb avatar jeromevvb commented on June 14, 2024 12

I found it quite frustrating that the footer and header are not fixed while the content is scrollable.
For everyone that wants to achieve something similar as on my attached video

Screen.Recording.2023-12-21.at.3.14.39.PM.mov

Switch grid for flex flex-col in the DialogPrimitive.Content classnames

 <DialogPrimitive.Content
        ref={ref}
        className={cn(
          "fixed left-[50%] top-[50%] z-50 flex w-full max-w-lg translate-x-[-50%] translate-y-[-50%] flex-col gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
          className,
        )}
        {...props}
      >

Example Dialog

<Dialog>
  <DialogTrigger asChild>
        Show Dialog
    </DialogTrigger>
    // adding max-h-[98%] so the modal is not sticking to the borders, but stays within the screen height
    <DialogContent className="max-h-[98%] overflow-hidden px-0">
      <DialogHeader className="px-6">
        <DialogTitle>Filters</DialogTitle>
      </DialogHeader>
      // making the content to take all height available with flex-1 and scrollable
      <div className="flex-1 overflow-y-auto px-6 py-6">
       // your content here
      </div>
      <DialogFooter className="px-6">
        <Button variant="secondary">Reset all filters</Button>
        <Button>Apply filters</Button>
      </DialogFooter>
    </DialogContent>
</Dialog>

Enjoy!

from ui.

anOatFlake avatar anOatFlake commented on June 14, 2024 5

I had a similar problem with the sheet component and too much content, but the overflow-y-scroll max-h-screen fix worked there too. Thanks a lot!

from ui.

max-hans avatar max-hans commented on June 14, 2024 5

I always had the issue with the scrollbar on the right side of the content.
Bildschirmfoto 2023-07-05 um 11 07 49

There is a solution by RadixUI that worked fine for me:
https://www.radix-ui.com/docs/primitives/components/dialog#scrollable-overlay

I enables scrolling the background thus "moving" the dialog instead of scrolling inside which I found to be a nicer interaction. You need to move the content inside the overlay and change the way it handles the positioning of the content.
(I removed some of the animations because I was too lazy to adjust them)

DialogOverlay

<DialogPrimitive.Overlay
    ref={ref}
    className={cn(
      "fixed inset-0 z-50 bg-black/30 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 overflow-y-auto max-h-screen grid place-items-center",
      className
    )}
    {...props}
  />

DialogContent

<DialogPortal>
    <DialogOverlay>
      <DialogPrimitive.Content
        ref={ref}
        className={cn(
          "z-50 relative grid w-full max-w-lg gap-4 bg-background p-6 shadow-lg duration-200 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 sm:rounded-lg md:w-full",
          className
        )}
        {...props}
      >
        {children}
        <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
          <X className="h-4 w-4" />
          <span className="sr-only">Close</span>
        </DialogPrimitive.Close>
      </DialogPrimitive.Content>
    </DialogOverlay>
  </DialogPortal>

edit: Content needs to be set to relative so the closing-button gets rendered on the content. otherwise its at the top right of the overlay

from ui.

squishydough avatar squishydough commented on June 14, 2024 2

I thought it might help to add a repo demonstrating the issue, so I threw one together. It's a fresh install, modifying the index page to have the Dialog component with an inline style of 5000px.

https://github.com/joshwaiam/ui.shadcn.com-dialog-overflow-issue

from ui.

askides avatar askides commented on June 14, 2024 2

This is the solution to make the entire overlay scrollable without errors, just change the Overlay and the Content as below.

const DialogOverlay = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Overlay>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
  <DialogPrimitive.Overlay
    ref={ref}
    className={cn(
      "fixed inset-0 z-50 bg-black/80 grid place-items-center overflow-y-auto data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
      className
    )}
    {...props}
  />
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;

const DialogContent = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
  <DialogPortal>
    <DialogOverlay className="p-16">
      <DialogPrimitive.Content
        ref={ref}
        className={cn(
          "relative border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 sm:rounded-lg",
          className
        )}
        {...props}
      >
        {children}
        <DialogPrimitive.Close asChild>
          <Button
            size="icon"
            variant="ghost"
            className="absolute top-3 right-3"
          >
            <X className="h-5 w-5" />
            <span className="sr-only">Close</span>
          </Button>
        </DialogPrimitive.Close>
      </DialogPrimitive.Content>
    </DialogOverlay>
  </DialogPortal>
));
DialogContent.displayName = DialogPrimitive.Content.displayName;

from ui.

Jared-Dahlke avatar Jared-Dahlke commented on June 14, 2024 1

hmmm. this is still an issue for me. I need to make the height of the dialog fit content and also have a max height. i reckon this is a common need.

from ui.

andfk avatar andfk commented on June 14, 2024 1
Screenshot 2024-02-11 at 2 20 40 PM does anyone know why I get this weird bar at the right side of Dialog? and what is the solution for it?

using overflow-auto will fix and only show the scrollbar if necessary.

from ui.

markpedong avatar markpedong commented on June 14, 2024 1

I had a similar problem with the sheet component and too much content, but the overflow-y-scroll max-h-screen fix worked there too. Thanks a lot!

hello, which component exactly did you put this code? I've been trying but doesn't work for me. Cheers!

from ui.

markpedong avatar markpedong commented on June 14, 2024 1

// sheet.tsx

   <SheetPrimitive.Content
      ref={ref}
      className={cn(sheetVariants({ side }), className)}
      // automatically scrolling up bug fixed
      onCloseAutoFocus={event => event.preventDefault()}
      {...props}

Go to sheet component and add the onCloseAutoFocus prop and the code I sent.

#this code is not my own, I also just found this #somewhere.

from ui.

Nhollas avatar Nhollas commented on June 14, 2024

Is this a Radix UI issue or?

from ui.

adaptive-shield-matrix avatar adaptive-shield-matrix commented on June 14, 2024

@max-hans
If I try to replicate your example -> I get a darkened screen without the Dialog being displayed at all.
I tried following https://www.radix-ui.com/docs/primitives/components/dialog#scrollable-overlay , but It did not show the Dialog too.
Maybe I'am doing something wrong?

DialogOverlay
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, children, ...props }, ref) => (
<DialogPrimitive.Overlay
  className={cn(
    "fixed inset-0 z-50 ", // overlay
    "bg-black/50 backdrop-blur-sm", // bg
    "transition-all duration-100 data-[state=closed]:animate-out data-[state=open]:fade-in data-[state=closed]:fade-out", // animations
    "grid place-items-center overflow-y-auto", // layout children
    className,
  )}
  {...props}
  ref={ref}
/>
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
DialogContent
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
  <DialogOverlay>
    <DialogPrimitive.Content
      ref={ref}
      // shadcn / Dialog Overflow Behavior - https://github.com/shadcn/ui/issues/16
      // radix-ui / Scrollable overlay - https://www.radix-ui.com/docs/primitives/components/dialog#scrollable-overlay
      // radix-ui / dialog src - https://github.com/radix-ui/primitives/blob/main/packages/react/dialog/src/Dialog.tsx
      className={cn(
        "z-50", // overlay
        "relative",
        "min-width-[300px]",
        "grid gap-4 ", // container
        "bg-white dark:bg-slate-900", // bg
        "p-6 rounded-b-lg sm:rounded-lg", // border
        "w-full sm:max-w-screen-sm md:max-w-screen-md", // width
        // "overflow-y-scroll max-h-screen", // prevent overflow / add scrolling -> produces scrollbar even if not needed
        "animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0", // animations
        className,
      )}
      {...props}
    >
      {children}
      <DialogPrimitive.Close className="absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 dark:data-[state=open]:bg-slate-800">
        <X className="h-4 w-4" />
        <span className="sr-only">Close</span>
      </DialogPrimitive.Close>
    </DialogPrimitive.Content>
  </DialogOverlay>
</DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName

from ui.

max-hans avatar max-hans commented on June 14, 2024

I will try to create something that works. Maybe I changes something else that seems unrelated at first. But I think I just followed the guide by radix

from ui.

adaptive-shield-matrix avatar adaptive-shield-matrix commented on June 14, 2024

thanks @intuity-hans
I can confirm your full version is working

Comparing mine and your version, I think you forgot to mention the changes in DialogPortal

DialogPortal
const DialogPortal = ({ className, children, ...props }: DialogPrimitive.DialogPortalProps) => (
  <DialogPrimitive.Portal className={cn(className)} {...props}>
    <div className="fixed inset-0 z-50 flex items-start justify-center sm:items-center">{children}</div>
  </DialogPrimitive.Portal>
)

from ui.

brandalx avatar brandalx commented on June 14, 2024

im have same issue

from ui.

brandalx avatar brandalx commented on June 14, 2024

i had same error so i tried to solve my way and this actually work
i did this by removing the style of pointer events like so:

` onClose: () => {
set({ type: null, isOpen: false });

// Delay restoring pointer events for 2 seconds
setTimeout(() => {
  document.body.style.pointerEvents = "auto";
}, 1000);

},
}));`

Note, i did it with small timeout to make sure that first all modal scripts are completed and then im manually removing that. Hope it helps!

from ui.

shadcn avatar shadcn commented on June 14, 2024

Is this still an issue? Does @intuity-hans solution fix this?

from ui.

wotschofsky avatar wotschofsky commented on June 14, 2024

I can confirm, that

  1. the current dialog component from the CLI is not scrollable
  2. @intuity-hans version fixed the issue for me

I however also found that the @intuity-hans dialog always leaves some space to the top border of the screen + it loses the fullscreen snapping functionality in general.

from ui.

max-hans avatar max-hans commented on June 14, 2024

I can look deeper into this and create a PR

from ui.

DeveloperMatheus avatar DeveloperMatheus commented on June 14, 2024

Workaround: I fixed this problem for myself by adding overflow-y-scroll max-h-screen classes to DialogContent

example usage:

<Dialog>
  <DialogTrigger asChild>
    <Button variant={"ghost"} title={"Text""} />
  </DialogTrigger>
  <DialogContent className={"lg:max-w-screen-lg overflow-y-scroll max-h-screen"}>
   todo...
  </DialogContent>
</Dialog>

This is a really nice workaround because it is not so much invasive, liked this approach!

from ui.

tomatoandbasil avatar tomatoandbasil commented on June 14, 2024
overflow-y-scroll

To complement this solution, you may want to hide the vertical scrollbars without compromising on the scroll functionality. To do so, declare the following two CSS classes and use them as an additional class.

`/* For Webkit-based browsers (Chrome, Safari and Opera) */
.scrollbar-hide::-webkit-scrollbar {
display: none;
}

/* For IE, Edge and Firefox /
.scrollbar-hide {
-ms-overflow-style: none; /
IE and Edge /
scrollbar-width: none; /
Firefox */
}`

from ui.

tinncdev avatar tinncdev commented on June 14, 2024

I'm having scroll issue with flexbox inside DialogContent

For example:

<DialogContent className='h-full'>
  <div className='h-full flex flex-col'>
    <div>Title</div>
    <div className='min-h-0 flex-1 overflow-y-auto'>
      <div className='h-[1000px]'>Long long long content</div>
    </div>
  </div>
</DialogContent>

The long content should be scollable when the screen is smaller than 1000px - Title height but it's not.

The most simple solution is making DialogContent block instead of grid

<DialogContent className='block h-full'>
  <div className='w-full h-full flex flex-col gap-4'>
    <div>Title</div>
    <div className='min-h-0 flex-1 overflow-y-auto'>
      <div className='h-[1000px]'>Long long long content</div>
    </div>
  </div>
</DialogContent>

Are there any specify reason why the DialogContent is grid?

since it's content only have 1 element {children} and also have no grid related styling.

from ui.

hanshs avatar hanshs commented on June 14, 2024

Managed to solve this based on the solution by @intuity-hans.
The small detail that made the difference was to render DialogContent inside DialogOverlay, instead of rendering them side-by-side as it is currently described in the docs:

const DialogContent = (...) => (
    <DialogPortal>
        <DialogOverlay />
        <DialogPrimitive.Content ... >
         ...
        </DialogPrimitive.Content>
    </DialogPortal>
)

so I changed to this:

const DialogContent = (...) => (
  <DialogPortal>
      <DialogOverlay>
          <DialogPrimitive.Content ... >
               ...
          </DialogPrimitive.Content>
      </DialogOverlay>
  </DialogPortal>
)

from ui.

JuanDa237 avatar JuanDa237 commented on June 14, 2024

I found it quite frustrating that the footer and header are not fixed while the content is scrollable. For everyone that wants to achieve something similar as on my attached video

Screen.Recording.2023-12-21.at.3.14.39.PM.mov
Switch grid for flex flex-col in the DialogPrimitive.Content classnames

 <DialogPrimitive.Content
        ref={ref}
        className={cn(
          "fixed left-[50%] top-[50%] z-50 flex w-full max-w-lg translate-x-[-50%] translate-y-[-50%] flex-col gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
          className,
        )}
        {...props}
      >

Example Dialog

<Dialog>
  <DialogTrigger asChild>
        Show Dialog
    </DialogTrigger>
    // adding max-h-[98%] so the modal is not sticking to the borders, but stays within the screen height
    <DialogContent className="max-h-[98%] overflow-hidden px-0">
      <DialogHeader className="px-6">
        <DialogTitle>Filters</DialogTitle>
      </DialogHeader>
      // making the content to take all height available with flex-1 and scrollable
      <div className="flex-1 overflow-y-auto px-6 py-6">
       // your content here
      </div>
      <DialogFooter className="px-6">
        <Button variant="secondary">Reset all filters</Button>
        <Button>Apply filters</Button>
      </DialogFooter>
    </DialogContent>
</Dialog>

Enjoy!

This is ok, but how can i use the styles for the scroll bar that are used in the ScollArea component?

from ui.

jaeyunha avatar jaeyunha commented on June 14, 2024
Screenshot 2024-02-11 at 2 20 40 PM

does anyone know why I get this weird bar at the right side of Dialog? and what is the solution for it?

from ui.

tomatoandbasil avatar tomatoandbasil commented on June 14, 2024
Screenshot 2024-02-11 at 2 20 40 PM does anyone know why I get this weird bar at the right side of Dialog? and what is the solution for it?

You can hide it like this: #16 (comment)

Hope it helps :)

from ui.

jaeyunha avatar jaeyunha commented on June 14, 2024
Screenshot 2024-02-11 at 2 20 40 PM does anyone know why I get this weird bar at the right side of Dialog? and what is the solution for it?

You can hide it like this: #16 (comment)

Hope it helps :)

I see, that completely hides the scroll bar even while scrolling, what if we want to show the bar only while scrolling?

from ui.

Psarmmiey avatar Psarmmiey commented on June 14, 2024

I had a similar problem with the sheet component and too much content, but the overflow-y-scroll max-h-screen fix worked there too. Thanks a lot!

hello, which component exactly did you put this code? I've been trying but doesn't work for me. Cheers!

Hello,
Were you able to get this to work?

from ui.

itxtoledo avatar itxtoledo commented on June 14, 2024

i think so @askides solution is better

from ui.

Josh-V-PAL avatar Josh-V-PAL commented on June 14, 2024

For anyone trying to get <ScrollArea> to work inside of the dialog content, remove grid from the class list and replace with flex flex-col
"fixed left-[50%] top-[50%] z-50 flex w-full max-w-lg translate-x-[-50%] translate-y-[-50%] flex-col gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",

Then also add flex flex-col to the scroll area.
<ScrollArea className="flex flex-col">

dialog_scroll.mp4

from ui.

SiriSollerud avatar SiriSollerud commented on June 14, 2024

Has anyone managed to make the dialog fixed position at top, but move the dialog scroll to the background scroll? Meaning that, if you have a dialog with content that can increase - the dialog will only expand downwards, not expand both up and down. This is similar to how dialogs at Trello work, I believe.

I tried @max-hans solution - which worked great for making the dialog scroll with the background scrollbar, but it doesn't fix the position of the dialog to the top.

edit: fixed the issue! You need to make sure that the overlay has place-items-start and then add a padding top for the overlay + add the suggestions Hans made to fix the background scroll. The following code has both background scroll and fixed placement of the dialog to the top so the dialog only expands downwards when the content in the dialog increases.

const DialogOverlay = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Overlay>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
  <DialogPrimitive.Overlay
    ref={ref}
    className={cn(
      `fixed inset-0 z-50 grid max-h-screen place-items-start justify-center overflow-y-auto 
      bg-darkGrey/90 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 
      data-[state=open]:fade-in-0 sm:pt-12`,
      className
    )}
    {...props}
  />
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName

const DialogContent = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
  <DialogPortal>
    <DialogOverlay>
      <DialogPrimitive.Content
        ref={ref}
        className={cn(
          `relative z-50 grid w-full min-w-screen p-0 gap-4 rounded-xl border-2 border-darkGrey bg-white shadow-lg 
          duration-200 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`,
          className
        )}
        {...props}
      >
        {children}
      </DialogPrimitive.Content>
    </DialogOverlay>
  </DialogPortal>
))

from ui.

Emyboy avatar Emyboy commented on June 14, 2024

Found this: https://www.youtube.com/watch?v=B8EgmMkI8n0

Hope it helps

from ui.

nrjdalal avatar nrjdalal commented on June 14, 2024

WASTED A WHOLE LOT TIME IMPLEMENTING SOLUTIONS PROVIDED ABOVE

  • no matter what is done as said above, some part is cropped or not aligned
  • in the end the only fix that worked for me was using "scroll-area"
  • I myself wouldn't want to club components
  • but have to, as my usecase is Stripe embedded payment using dialog

BUT STILL 100% WORKING FIX FOR NOW:

+ import { ScrollArea } from '@/components/ui/scroll-area'

<DialogPrimitive.Content className="max-h-dvh"> // add max-h-dvh to dialog content
+  <ScrollArea className="max-h-dvh">{children}</ScrollArea>
</ DialogPrimitive.Content>

Above works like magic. But if want the same with even better UI, try this:

+ import { ScrollArea } from '@/components/ui/scroll-area'

<DialogPrimitive.Content className="max-h-[calc(100dvh-1.5rem)] w-[calc(100dvw-1.5rem)]">
+  <ScrollArea className="max-h-[calc(100dvh-3rem)]>{children}</ScrollArea>
</ DialogPrimitive.Content>

Onset-ezgif com-video-to-gif-converter

from ui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.