A flexible, customizable modal dialog component with keyboard shortcuts, backdrop blur, and smooth animations. Perfect for presenting important information, user interactions, or triggering actions while maintaining focus on modal content.
1"use client";
2
3import Dialog from '@/components/component-x/dialog';
4import { Button } from '@/components/ui/button';
5import { useState } from 'react';
6
7export function DialogPreview() {
8const [isDialogVisible, setIsDialogVisible] = useState(false);
9
10return (
11 <>
12 <Button onClick={() => setIsDialogVisible(true)}>Open Dialog</Button>
13 <Dialog
14 isDialogVisible={isDialogVisible}
15 setIsDialogVisible={setIsDialogVisible}
16 >
17 <div className="p-6 space-y-4">
18 <h2 className="text-2xl font-semibold">Dialog Title</h2>
19 <p className="text-muted-foreground">
20 This is a simple dialog component with backdrop blur and smooth
21 animations.
22 </p>
23 <Button onClick={() => setIsDialogVisible(false)}>Close Dialog</Button>
24 </div>
25 </Dialog>
26 </>
27);
28}
29Run the following command to add the component:
npx cx add dialog1"use client";
2
3import Dialog from '@/components/component-x/dialog';
4import { Button } from '@/components/ui/button';
5import { useState } from 'react';
6
7export function BasicDialog() {
8const [isDialogVisible, setIsDialogVisible] = useState(false);
9
10return (
11 <>
12 <Button variant="outline" onClick={() => setIsDialogVisible(true)}>
13 Open Dialog
14 </Button>
15 <Dialog
16 isDialogVisible={isDialogVisible}
17 setIsDialogVisible={setIsDialogVisible}
18 >
19 <div className="p-6">
20 <h2 className="text-xl font-semibold mb-2">Confirm Action</h2>
21 <p className="text-muted-foreground mb-6">
22 Are you sure you want to proceed with this action?
23 </p>
24 <div className="flex gap-3 justify-end">
25 <Button variant="outline" onClick={() => setIsDialogVisible(false)}>
26 Cancel
27 </Button>
28 <Button onClick={() => setIsDialogVisible(false)}>Confirm</Button>
29 </div>
30 </div>
31 </Dialog>
32 </>
33);
34}
351"use client";
2
3import Dialog from '@/components/component-x/dialog';
4import { Button } from '@/components/ui/button';
5import { Command } from 'lucide-react';
6import { useState } from 'react';
7
8export function DialogWithShortcut() {
9const [isDialogVisible, setIsDialogVisible] = useState(false);
10
11return (
12 <>
13 <Button variant="outline" onClick={() => setIsDialogVisible(true)}>
14 <span className="text-muted-foreground">Open</span>
15 <span className="flex items-center gap-1 bg-muted/60 p-1 rounded ml-2">
16 <Command size={14} /> K
17 </span>
18 </Button>
19 <Dialog
20 isDialogVisible={isDialogVisible}
21 setIsDialogVisible={setIsDialogVisible}
22 keyToMakeDialogVisible="k"
23 >
24 <div className="p-6 space-y-4">
25 <div>
26 <h2 className="text-xl font-semibold">Quick Search</h2>
27 <p className="text-sm text-muted-foreground">
28 Press Cmd/Ctrl + K to open this dialog anytime
29 </p>
30 </div>
31 <p className="text-muted-foreground">
32 This dialog can be opened with a keyboard shortcut for quick access.
33 </p>
34 </div>
35 </Dialog>
36 </>
37);
38}
391"use client";
2
3import Dialog from '@/components/component-x/dialog';
4import { Button } from '@/components/ui/button';
5import { useState } from 'react';
6
7export function DialogCustomSize() {
8const [smallOpen, setSmallOpen] = useState(false);
9const [largeOpen, setLargeOpen] = useState(false);
10
11return (
12 <div className="flex gap-4">
13 <Button variant="outline" onClick={() => setSmallOpen(true)}>
14 Small Dialog
15 </Button>
16 <Dialog
17 isDialogVisible={smallOpen}
18 setIsDialogVisible={setSmallOpen}
19 className="max-w-sm"
20 >
21 <div className="p-4">
22 <h2 className="text-lg font-semibold mb-2">Small Dialog</h2>
23 <p className="text-sm text-muted-foreground">
24 This is a compact dialog perfect for quick confirmations.
25 </p>
26 <Button
27 size="sm"
28 className="mt-4 w-full"
29 onClick={() => setSmallOpen(false)}
30 >
31 Close
32 </Button>
33 </div>
34 </Dialog>
35
36 <Button variant="outline" onClick={() => setLargeOpen(true)}>
37 Large Dialog
38 </Button>
39 <Dialog
40 isDialogVisible={largeOpen}
41 setIsDialogVisible={setLargeOpen}
42 className="max-w-2xl"
43 >
44 <div className="p-8">
45 <h2 className="text-2xl font-semibold mb-4">Large Dialog</h2>
46 <p className="text-muted-foreground mb-6">
47 This is a spacious dialog suitable for detailed content, forms, or
48 rich information displays.
49 </p>
50 <Button onClick={() => setLargeOpen(false)}>Close</Button>
51 </div>
52 </Dialog>
53 </div>
54);
55}
561"use client";
2
3import Dialog from '@/components/component-x/dialog';
4import { Button } from '@/components/ui/button';
5import { Input } from '@/components/ui/input';
6import { Command, Search } from 'lucide-react';
7import { useState } from 'react';
8
9export function SearchDialog() {
10const [isDialogVisible, setIsDialogVisible] = useState(false);
11const [query, setQuery] = useState("");
12
13const results = ["Home", "About", "Services", "Contact", "Blog"];
14const filtered = results.filter((item) =>
15 item.toLowerCase().includes(query.toLowerCase())
16);
17
18return (
19 <>
20 <Button variant="outline" onClick={() => setIsDialogVisible(true)}>
21 <span className="text-muted-foreground">Search</span>
22 <span className="flex items-center gap-1 bg-muted/60 p-1 rounded ml-2">
23 <Command size={14} /> M
24 </span>
25 </Button>
26 <Dialog
27 isDialogVisible={isDialogVisible}
28 setIsDialogVisible={setIsDialogVisible}
29 keyToMakeDialogVisible="m"
30 >
31 <div className="border-b p-4">
32 <div className="relative">
33 <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-muted-foreground" />
34 <Input
35 autoFocus
36 value={query}
37 onChange={(e) => setQuery(e.target.value)}
38 placeholder="Search..."
39 className="pl-10 border-0 bg-transparent focus-visible:ring-0"
40 />
41 </div>
42 </div>
43 <div className="max-h-64 overflow-y-auto p-2">
44 {filtered.length > 0 ? (
45 filtered.map((item) => (
46 <div
47 key={item}
48 className="p-3 hover:bg-muted/50 rounded cursor-pointer transition-colors"
49 onClick={() => setIsDialogVisible(false)}
50 >
51 {item}
52 </div>
53 ))
54 ) : (
55 <div className="p-8 text-center text-muted-foreground">
56 No results found
57 </div>
58 )}
59 </div>
60 </Dialog>
61 </>
62);
63}
641"use client";
2
3import Dialog from '@/components/component-x/dialog';
4import { Button } from '@/components/ui/button';
5import { Separator } from '@/components/ui/separator';
6import { Command } from 'lucide-react';
7import { useState } from 'react';
8import { FaGithub } from 'react-icons/fa';
9import Image from 'next/image';
10
11export function AuthDialog() {
12const [isDialogVisible, setIsDialogVisible] = useState(false);
13const [isLoading, setIsLoading] = useState(false);
14
15const handleAuth = async () => {
16 setIsLoading(true);
17 await new Promise((resolve) => setTimeout(resolve, 1000));
18 setIsLoading(false);
19 setIsDialogVisible(false);
20};
21
22return (
23 <>
24 <Button variant="outline" onClick={() => setIsDialogVisible(true)}>
25 <span className="text-muted-foreground">Sign In</span>
26 <span className="flex items-center gap-1 bg-muted/60 p-1 rounded ml-2">
27 <Command size={14} /> A
28 </span>
29 </Button>
30 <Dialog
31 isDialogVisible={isDialogVisible}
32 setIsDialogVisible={setIsDialogVisible}
33 keyToMakeDialogVisible="a"
34 className="max-w-[400px]"
35 >
36 <div className="space-y-4 p-6 text-center">
37 <div className="space-y-2 mb-6">
38 <h1 className="text-2xl font-semibold">Welcome Back</h1>
39 <p className="text-sm text-muted-foreground">
40 Sign in to your account to continue
41 </p>
42 </div>
43 <Button
44 onClick={handleAuth}
45 disabled={isLoading}
46 variant="outline"
47 className="w-full bg-transparent"
48 >
49 <FaGithub className="mr-2 h-4 w-4" />
50 {isLoading ? "Signing in..." : "Continue with GitHub"}
51 </Button>
52 <div className="relative flex gap-1">
53 <span className="flex-1 flex items-center">
54 <Separator />
55 </span>
56 <span className="text-muted-foreground text-sm">Or</span>
57 <span className="flex-1 flex items-center">
58 <Separator />
59 </span>
60 </div>
61 <Button onClick={handleAuth} disabled={isLoading} className="w-full">
62 <Image
63 src="https://www.gstatic.com/firebasejs/ui/2.0.0/images/auth/google.svg"
64 alt="Google"
65 width={16}
66 height={16}
67 className="mr-2"
68 />
69 {isLoading ? "Signing in..." : "Continue with Google"}
70 </Button>
71 </div>
72 </Dialog>
73 </>
74);
75}
76