Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apps/dokploy/components/ui/alert-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { AlertDialog as AlertDialogPrimitive } from "radix-ui";
import type * as React from "react";
import { Button } from "@/components/ui/button";
import { wasNestedPopupJustClosed } from "@/components/ui/nested-popup-context";
import { cn } from "@/lib/utils";

function AlertDialog({
Expand Down Expand Up @@ -46,6 +47,7 @@ function AlertDialogOverlay({
function AlertDialogContent({
className,
size = "default",
onEscapeKeyDown,
...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
size?: "default" | "sm";
Expand All @@ -60,6 +62,13 @@ function AlertDialogContent({
"group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-6 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-lg data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className,
)}
onEscapeKeyDown={(event) => {
if (wasNestedPopupJustClosed()) {
event.preventDefault();
return;
}
onEscapeKeyDown?.(event);
}}
Comment thread
Simciutoja marked this conversation as resolved.
{...props}
/>
</AlertDialogPortal>
Expand Down
21 changes: 20 additions & 1 deletion apps/dokploy/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { XIcon } from "lucide-react";
import { Dialog as DialogPrimitive } from "radix-ui";
import type * as React from "react";
import { Button } from "@/components/ui/button";
import { wasNestedPopupJustClosed } from "@/components/ui/nested-popup-context";
import {
wasNestedPopupJustClosed,
wasWindowRecentlyBlurred,
} from "@/components/ui/nested-popup-context";
import { cn } from "@/lib/utils";

function Dialog({
Expand Down Expand Up @@ -51,6 +54,8 @@ function DialogContent({
showCloseButton = true,
onPointerDownOutside,
onEscapeKeyDown,
onInteractOutside,
onFocusOutside,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
showCloseButton?: boolean;
Expand Down Expand Up @@ -78,6 +83,20 @@ function DialogContent({
}
onEscapeKeyDown?.(event);
}}
onFocusOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onFocusOutside?.(event);
}}
onInteractOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onInteractOutside?.(event);
}}
{...props}
>
{children}
Expand Down
21 changes: 20 additions & 1 deletion apps/dokploy/components/ui/dropdown-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { CheckIcon, ChevronRightIcon } from "lucide-react";
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
import type * as React from "react";
import { markNestedPopupClosed } from "@/components/ui/nested-popup-context";
import {
markNestedPopupClosed,
wasWindowRecentlyBlurred,
} from "@/components/ui/nested-popup-context";
import { cn } from "@/lib/utils";

function DropdownMenu({
Expand Down Expand Up @@ -45,6 +48,8 @@ function DropdownMenuContent({
className,
align = "start",
sideOffset = 4,
onInteractOutside,
onFocusOutside,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
return (
Expand All @@ -57,6 +62,20 @@ function DropdownMenuContent({
"z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className,
)}
onFocusOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onFocusOutside?.(event);
}}
onInteractOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onInteractOutside?.(event);
}}
{...props}
/>
</DropdownMenuPrimitive.Portal>
Expand Down
16 changes: 16 additions & 0 deletions apps/dokploy/components/ui/nested-popup-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,19 @@ export function markNestedPopupClosed() {
export function wasNestedPopupJustClosed() {
return performance.now() - lastNestedPopupCloseAt < 100;
}


let lastWindowFocusChangeAt = 0;

if (typeof window !== "undefined") {
const markWindowFocusChange = () => {
lastWindowFocusChangeAt = performance.now();
};
window.addEventListener("blur", markWindowFocusChange);
window.addEventListener("focus", markWindowFocusChange);
document.addEventListener("visibilitychange", markWindowFocusChange);
}

export function wasWindowRecentlyBlurred() {
return performance.now() - lastWindowFocusChangeAt < 150;
}
21 changes: 20 additions & 1 deletion apps/dokploy/components/ui/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import { Popover as PopoverPrimitive } from "radix-ui";
import type * as React from "react";
import { markNestedPopupClosed } from "@/components/ui/nested-popup-context";
import {
markNestedPopupClosed,
wasWindowRecentlyBlurred,
} from "@/components/ui/nested-popup-context";
import { cn } from "@/lib/utils";

function Popover({
Expand Down Expand Up @@ -33,6 +36,8 @@ function PopoverContent({
className,
align = "center",
sideOffset = 4,
onInteractOutside,
onFocusOutside,
...props
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
return (
Expand All @@ -45,6 +50,20 @@ function PopoverContent({
"z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className,
)}
onFocusOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onFocusOutside?.(event);
}}
onInteractOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onInteractOutside?.(event);
}}
{...props}
/>
</PopoverPrimitive.Portal>
Expand Down
28 changes: 28 additions & 0 deletions apps/dokploy/components/ui/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { XIcon } from "lucide-react";
import { Dialog as SheetPrimitive } from "radix-ui";
import type * as React from "react";
import { Button } from "@/components/ui/button";
import {
wasNestedPopupJustClosed,
wasWindowRecentlyBlurred,
} from "@/components/ui/nested-popup-context";
import { cn } from "@/lib/utils";

function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
Expand Down Expand Up @@ -47,6 +51,9 @@ function SheetContent({
children,
side = "right",
showCloseButton = true,
onEscapeKeyDown,
onInteractOutside,
onFocusOutside,
...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
side?: "top" | "right" | "bottom" | "left";
Expand All @@ -62,6 +69,27 @@ function SheetContent({
"fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10",
className,
)}
onEscapeKeyDown={(event) => {
if (wasNestedPopupJustClosed()) {
event.preventDefault();
return;
}
onEscapeKeyDown?.(event);
}}
onFocusOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onFocusOutside?.(event);
}}
onInteractOutside={(event) => {
if (wasWindowRecentlyBlurred()) {
event.preventDefault();
return;
}
onInteractOutside?.(event);
}}
{...props}
>
{children}
Expand Down