Components
Loading preview...
Stacked dialog component inspired by Radix UI Dialog. Accessible. Customizable. Open Source. Pre-styled for shadcn/ui. Features • Stacked dialog interface with smooth transitions • Keyboard navigation support • Accessible by default • Customizable styling • Previous/Next navigation controls • Responsive design • Fully typed with TypeScript Props DialogStack • open?: boolean - Controls the open state • onOpenChange?: (open: boolean) => void - Callback when open state changes • clickable?: boolean - Enables clicking on previous dialogs to navigate back DialogStackTrigger • asChild?: boolean - Merges props onto child element instead of rendering button DialogStackContent • className?: string - Additional CSS classes • children: ReactNode - Dialog content • index?: number - Dialog position in stack (auto-populated) • offset?: number - Visual offset between stacked dialogs DialogStackNext/Previous • asChild?: boolean - Merges props onto child element • children?: ReactNode - Button content • className?: string - Additional CSS classes Example Use Cases • Multi-step forms • Onboarding flows • Wizards • Sequential content presentation • Guided tutorials
@haydenbleasel
npx shadcn@latest add https://21st.dev/r/haydenbleasel/dialog-stack'use client';
import { Button } from '@/components/ui/button';
import {
DialogStack,
DialogStackBody,
DialogStackContent,
DialogStackDescription,
DialogStackNext,
DialogStackOverlay,
DialogStackPrevious,
DialogStackTitle,
DialogStackTrigger,
} from '@/components/ui/dialog-stack';
export function DialogStackDemo() {
return (
<DialogStack>
<DialogStackTrigger asChild>
<Button variant="outline">Open</Button>
</DialogStackTrigger>
<DialogStackOverlay />
<DialogStackBody>
<DialogStackContent className="h-auto w-full rounded-lg border bg-background p-6 shadow-lg">
<div className="flex flex-col space-y-1.5 text-center sm:text-left">
<DialogStackTitle className="font-semibold text-lg leading-none tracking-tight">
I'm the first dialog
</DialogStackTitle>
<DialogStackDescription className="text-muted-foreground text-sm">
With a fancy description
</DialogStackDescription>
</div>
<div className="flex items-center space-x-2 pt-4 justify-end">
<DialogStackNext asChild>
<Button variant="outline">Next</Button>
</DialogStackNext>
</div>
</DialogStackContent>
<DialogStackContent className="h-auto w-full rounded-lg border bg-background p-6 shadow-lg">
<div className="flex flex-col space-y-1.5 text-center sm:text-left">
<DialogStackTitle className="font-semibold text-lg leading-none tracking-tight">
I'm the second dialog
</DialogStackTitle>
<DialogStackDescription className="text-muted-foreground text-sm">
With a fancy description
</DialogStackDescription>
</div>
<div className="flex items-center space-x-2 pt-4 justify-between">
<DialogStackPrevious asChild>
<Button variant="outline">Previous</Button>
</DialogStackPrevious>
<DialogStackNext asChild>
<Button variant="outline">Next</Button>
</DialogStackNext>
</div>
</DialogStackContent>
<DialogStackContent className="h-auto w-full rounded-lg border bg-background p-6 shadow-lg">
<div className="flex flex-col space-y-1.5 text-center sm:text-left">
<DialogStackTitle className="font-semibold text-lg leading-none tracking-tight">
I'm the final dialog
</DialogStackTitle>
<DialogStackDescription className="text-muted-foreground text-sm">
With a fancy description
</DialogStackDescription>
</div>
<div className="flex items-center space-x-2 pt-4 justify-start">
<DialogStackPrevious asChild>
<Button variant="outline">Previous</Button>
</DialogStackPrevious>
</div>
</DialogStackContent>
</DialogStackBody>
</DialogStack>
);
}