Skip to content

Instantly share code, notes, and snippets.

@shivkanthb
Last active November 7, 2024 10:42
Show Gist options
  • Save shivkanthb/ae464de828a919f13059c9e7e93ee0a1 to your computer and use it in GitHub Desktop.
Save shivkanthb/ae464de828a919f13059c9e7e93ee0a1 to your computer and use it in GitHub Desktop.
stacked dialog
"use client";
import React from "react";
import * as Dialog from "@radix-ui/react-dialog";
import { Skeleton } from "@/components/ui/skeleton";
import { useState } from "react";
function DialogContent({
onOpenNested,
isNested,
children,
stackIndex,
}: {
onOpenNested?: () => void;
isNested?: boolean;
children: React.ReactNode;
stackIndex?: number;
}) {
const style = isNested
? {
top: `calc(35% - ${(stackIndex || 1) * 15}px)`,
maxWidth: `${450 - (stackIndex || 1) * 20}px`,
backgroundColor: `rgba(249, 249, 249, ${1 - (stackIndex || 1) * 0.2})`,
}
: {
top: "35%",
maxWidth: "450px",
backgroundColor: "white",
};
return (
<Dialog.Content
style={style}
className={`z-10 flex flex-col fixed left-[50%] translate-x-[-50%] w-[90vw] p-[25px] shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none transition-all duration-300
${
isNested
? "rounded-lg max-h-[300px] overflow-hidden"
: "rounded-sm max-h-[85vh]"
}`}
>
{children}
{onOpenNested && (
<button
onClick={onOpenNested}
className="mt-4 py-2 px-3 h-[32px] bg-black text-white rounded-md text-sm text-center flex items-center justify-center w-fit"
>
open nested {stackIndex}
</button>
)}
</Dialog.Content>
);
}
function NestedModal({
isOpen,
onOpenChange,
onOpenNested,
isNested,
stackIndex,
children,
}: {
isOpen: boolean;
onOpenChange: (open: boolean) => void;
onOpenNested?: () => void;
isNested?: boolean;
stackIndex?: number;
children: React.ReactNode;
}) {
return (
<Dialog.Root open={isOpen} onOpenChange={onOpenChange}>
<Dialog.Portal>
{!isNested && (
<Dialog.Overlay className="fixed inset-0 bg-black/50 transition-opacity duration-300" />
)}
<DialogContent
onOpenNested={onOpenNested}
isNested={isNested}
stackIndex={stackIndex}
>
{children}
</DialogContent>
</Dialog.Portal>
</Dialog.Root>
);
}
export default function StackedPage() {
const [isModal1Open, setIsModal1Open] = useState(false);
const [isModal2Open, setIsModal2Open] = useState(false);
const [isModal3Open, setIsModal3Open] = useState(false);
return (
<>
<button
onClick={() => setIsModal1Open(true)}
className="m-4 py-2 px-3 h-[32px] bg-black text-white rounded-md text-sm text-center flex items-center justify-center"
>
open
</button>
<NestedModal
isOpen={isModal1Open}
onOpenChange={setIsModal1Open}
onOpenNested={() => setIsModal2Open(true)}
isNested={isModal2Open}
stackIndex={1}
>
<Dialog.Title className="text-[17px] font-medium mb-4">
<Skeleton className="h-[20px] w-[100px]" />
</Dialog.Title>
<Skeleton className="h-[200px] w-full" />
</NestedModal>
<NestedModal
isOpen={isModal2Open}
onOpenChange={setIsModal2Open}
onOpenNested={() => setIsModal3Open(true)}
isNested={isModal3Open}
stackIndex={2}
>
<Dialog.Title className="text-[17px] font-medium mb-4">
<Skeleton className="h-[20px] w-[100px]" />
<Skeleton className="mt-2 h-[20px] w-[150px]" />
</Dialog.Title>
<Skeleton className="h-[200px] w-full" />
</NestedModal>
<NestedModal
isOpen={isModal3Open}
onOpenChange={setIsModal3Open}
stackIndex={3}
>
<Dialog.Title className="text-[17px] font-medium mb-4">
<Skeleton className="h-[20px] w-[200px] mx-auto" />
</Dialog.Title>
<Skeleton className="h-[150px] w-full" />
<Skeleton className="mt-4 h-[100px] w-full" />
</NestedModal>
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment