Components
Loading preview...
Enhanced shadcn/ui dialog
npx shadcn@latest add https://21st.dev/r/originui/dialogimport { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Check, RefreshCcw } from "lucide-react";
import { useId } from "react";
function Component() {
const id = useId();
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Change plan</Button>
</DialogTrigger>
<DialogContent>
<div className="mb-2 flex flex-col gap-2">
<div
className="flex size-11 shrink-0 items-center justify-center rounded-full border border-border"
aria-hidden="true"
>
<RefreshCcw className="opacity-80" size={16} strokeWidth={2} />
</div>
<DialogHeader>
<DialogTitle className="text-left">Change your plan</DialogTitle>
<DialogDescription className="text-left">
Pick one of the following plans.
</DialogDescription>
</DialogHeader>
</div>
<form className="space-y-5">
<RadioGroup className="gap-2" defaultValue="2">
<div className="relative flex w-full items-center gap-2 rounded-lg border border-input px-4 py-3 shadow-sm shadow-black/5 has-[[data-state=checked]]:border-ring has-[[data-state=checked]]:bg-accent">
<RadioGroupItem
value="1"
id={`${id}-1`}
aria-describedby={`${id}-1-description`}
className="order-1 after:absolute after:inset-0"
/>
<div className="grid grow gap-1">
<Label htmlFor={`${id}-1`}>Essential</Label>
<p id={`${id}-1-description`} className="text-xs text-muted-foreground">
$4 per member/month
</p>
</div>
</div>
<div className="relative flex w-full items-center gap-2 rounded-lg border border-input px-4 py-3 shadow-sm shadow-black/5 has-[[data-state=checked]]:border-ring has-[[data-state=checked]]:bg-accent">
<RadioGroupItem
value="2"
id={`${id}-2`}
aria-describedby={`${id}-2-description`}
className="order-1 after:absolute after:inset-0"
/>
<div className="grid grow gap-1">
<Label htmlFor={`${id}-2`}>Standard</Label>
<p id={`${id}-2-description`} className="text-xs text-muted-foreground">
$19 per member/month
</p>
</div>
</div>
<div className="relative flex w-full items-center gap-2 rounded-lg border border-input px-4 py-3 shadow-sm shadow-black/5 has-[[data-state=checked]]:border-ring has-[[data-state=checked]]:bg-accent">
<RadioGroupItem
value="3"
id={`${id}-3`}
aria-describedby={`${id}-3-description`}
className="order-1 after:absolute after:inset-0"
/>
<div className="grid grow gap-1">
<Label htmlFor={`${id}-3`}>Enterprise</Label>
<p id={`${id}-3-description`} className="text-xs text-muted-foreground">
$32 per member/month
</p>
</div>
</div>
</RadioGroup>
<div className="space-y-3">
<p>
<strong className="text-sm font-medium">Features include:</strong>
</p>
<ul className="space-y-2 text-sm text-muted-foreground">
<li className="flex gap-2">
<Check
size={16}
strokeWidth={2}
className="mt-0.5 shrink-0 text-primary"
aria-hidden="true"
/>
Create unlimited projects.
</li>
<li className="flex gap-2">
<Check
size={16}
strokeWidth={2}
className="mt-0.5 shrink-0 text-primary"
aria-hidden="true"
/>
Remove watermarks.
</li>
<li className="flex gap-2">
<Check
size={16}
strokeWidth={2}
className="mt-0.5 shrink-0 text-primary"
aria-hidden="true"
/>
Add unlimited users and free viewers.
</li>
<li className="flex gap-2">
<Check
size={16}
strokeWidth={2}
className="mt-0.5 shrink-0 text-primary"
aria-hidden="true"
/>
Upload unlimited files.
</li>
<li className="flex gap-2">
<Check
size={16}
strokeWidth={2}
className="mt-0.5 shrink-0 text-primary"
aria-hidden="true"
/>
7-day money back guarantee.
</li>
<li className="flex gap-2">
<Check
size={16}
strokeWidth={2}
className="mt-0.5 shrink-0 text-primary"
aria-hidden="true"
/>
Advanced permissions.
</li>
</ul>
</div>
<div className="grid gap-2">
<Button type="button" className="w-full">
Change plan
</Button>
<DialogClose asChild>
<Button type="button" variant="ghost" className="w-full">
Cancel
</Button>
</DialogClose>
</div>
</form>
</DialogContent>
</Dialog>
);
}
export { Component };