Innovations
modals /

Standard Dialog

Accessible modal dialog with a form input, cancel and confirm actions, and a success state.

Preview

Source

tsx
"use client";

import { useState } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

export default function DialogStandard() {
  const [email, setEmail] = useState("");
  const [submitted, setSubmitted] = useState(false);
  const [open, setOpen] = useState(false);

  function handleConfirm() {
    if (!email) return;
    setSubmitted(true);
    setTimeout(() => {
      setOpen(false);
      setEmail("");
      setSubmitted(false);
    }, 1200);
  }

  return (
    <div className="flex min-h-[200px] items-center justify-center p-8">
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogTrigger asChild>
          <Button size="lg">Open dialog</Button>
        </DialogTrigger>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Stay in the loop</DialogTitle>
            <DialogDescription>
              Enter your email to receive updates. You can unsubscribe at any time.
            </DialogDescription>
          </DialogHeader>

          {submitted ? (
            <div className="py-6 text-center">
              <div className="text-3xl mb-2">✓</div>
              <p className="font-semibold text-foreground">You're subscribed!</p>
              <p className="text-sm text-muted-foreground mt-1">Check your inbox for a confirmation.</p>
            </div>
          ) : (
            <>
              <div className="py-2">
                <label htmlFor="email-input" className="text-sm font-medium text-foreground block mb-1.5">
                  Email address
                </label>
                <Input
                  id="email-input"
                  type="email"
                  placeholder="you@example.com"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  onKeyDown={(e) => e.key === "Enter" && handleConfirm()}
                />
              </div>

              <DialogFooter>
                <Button variant="outline" onClick={() => setOpen(false)}>
                  Cancel
                </Button>
                <Button onClick={handleConfirm} disabled={!email}>
                  Confirm
                </Button>
              </DialogFooter>
            </>
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}
Claude Code Instructions

CLI Install

npx innovations add dialog-standard

Where to use it

Use this pattern for any modal that captures user input or confirms an action. Import and compose the Dialog primitives from @/components/ui/dialog: import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogTrigger } from '@/components/ui/dialog'; Wrap your trigger element with <DialogTrigger asChild> to avoid extra DOM nodes. Control open state with useState and pass open + onOpenChange to <Dialog>.