{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "product-quickviews-02",
  "type": "registry:component",
  "title": "Product Quickviews",
  "author": "Toby Belhome",
  "description": "Allow shoppers to preview product details instantly with Tailwind CSS product quickview sections. These layouts showcase images, key features, pricing, and calls-to-action in a compact overlay, enhancing browsing efficiency. Perfect for online stores and marketplaces seeking modern, user-friendly, and conversion-focused shopping experiences.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "dialog",
    "button",
    "radio-group",
    "button-group",
    "input",
    "button"
  ],
  "files": [
    {
      "path": "examples/blocks/ecommerce/product-quickviews/02/components/product-quickview-modal.tsx",
      "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport { Dialog, DialogContent } from \"@/components/ui/dialog\";\nimport { Button } from \"@/components/ui/button\";\nimport { HeartIcon, MinusIcon, PlusIcon, Star } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\";\nimport { ButtonGroup } from \"@/components/ui/button-group\";\nimport { Input } from \"@/components/ui/input\";\n\ninterface ProductQuickviewProps {\n  open: boolean;\n  onOpenChange: (open: boolean) => void;\n  product: {\n    id: string;\n    title: string;\n    description: string;\n    price: string;\n    old_price: string;\n    rating: number;\n    reviewCount: number;\n    image: string;\n    colors: Array<{ name: string; value: string }>;\n    sizes: Array<{ name: string; available: boolean }>;\n  };\n}\n\nexport function ProductQuickviewDialog({ open, onOpenChange, product }: ProductQuickviewProps) {\n  const [selectedColor, setSelectedColor] = useState(product.colors[0]?.name);\n  const [selectedSize, setSelectedSize] = useState(\"S\");\n\n  const renderStars = (rating: number) => {\n    return Array(5)\n      .fill(\"\")\n      .map((_, i) =>\n        i < rating ? (\n          <Star key={i} className=\"size-4 fill-amber-500 text-amber-500\" />\n        ) : (\n          <Star key={i} className=\"text-muted-foreground size-4 opacity-70\" />\n        )\n      );\n  };\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent className=\"gap-0 overflow-hidden p-0 sm:max-w-md\">\n        <div className=\"flex flex-col gap-0\">\n          {/* Product Image */}\n          <figure className=\"relative flex items-center justify-center\">\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              className=\"absolute start-3 top-3\"\n              aria-label=\"Add to Wishlist\">\n              <HeartIcon />\n            </Button>\n            <img src={product.image} alt={product.title} className=\"h-96 w-full object-cover\" />\n          </figure>\n\n          {/* Product Details */}\n          <div className=\"flex flex-col p-4 md:p-6\">\n            <div className=\"flex-1\">\n              <div className=\"mb-4 flex justify-between\">\n                <h2 className=\"font-heading text-2xl text-balance lg:text-3xl\">{product.title}</h2>\n\n                <p className=\"flex items-center gap-2 text-2xl font-medium\">\n                  <span className=\"text-muted-foreground text-xl line-through\">\n                    {product.old_price}\n                  </span>\n                  {product.price}\n                </p>\n              </div>\n\n              {/* Rating */}\n              <div className=\"mb-4 flex items-center gap-3\">\n                <div className=\"flex gap-1\">{renderStars(product.rating)}</div>\n                <a href=\"#\" className=\"text-sm font-medium text-indigo-600 hover:text-indigo-700\">\n                  {product.reviewCount} reviews\n                </a>\n              </div>\n\n              <p className=\"text-muted-foreground mb-6 text-sm\">{product.description}</p>\n\n              {/* Color Selection */}\n              <fieldset className=\"mb-4 space-y-4 lg:mb-8\">\n                <legend className=\"text-foreground text-sm leading-none font-medium\">Color</legend>\n                <RadioGroup\n                  className=\"flex gap-1.5\"\n                  onValueChange={(value) => setSelectedColor(value)}\n                  defaultValue=\"blue\">\n                  {product.colors.map((color) => (\n                    <RadioGroupItem\n                      value={color.name}\n                      style={{ backgroundColor: color.value }}\n                      aria-label={`Select ${color.name} color`}\n                      className={cn(\n                        \"size-6 rounded-full border-1 transition-all\",\n                        selectedColor === color.name\n                          ? \"border-foreground ring-foreground ring ring-offset-2\"\n                          : \"border-border hover:border-foreground/50\"\n                      )}\n                    />\n                  ))}\n                </RadioGroup>\n              </fieldset>\n\n              {/* Size Selection */}\n              <fieldset className=\"mb-4 space-y-4 lg:mb-8\">\n                <legend className=\"text-foreground flex w-full items-center justify-between text-sm leading-none font-medium\">\n                  <span>Size</span>\n                  <a\n                    href=\"#size-guide\"\n                    className=\"text-sm font-medium text-indigo-600 hover:text-indigo-700\">\n                    Size guide\n                  </a>\n                </legend>\n                <RadioGroup\n                  className=\"grid grid-cols-4 gap-2\"\n                  onValueChange={(value) => setSelectedSize(value)}\n                  defaultValue=\"1\">\n                  {product.sizes.map((size) => (\n                    <label\n                      key={`${size.name}`}\n                      className=\"border-input has-focus-visible:border-ring has-focus-visible:ring-ring/50 has-data-[state=checked]:border-primary/50 relative flex cursor-pointer flex-col items-center gap-3 rounded-md border px-2 py-3 text-center shadow-xs transition-[color,box-shadow] outline-none has-focus-visible:ring-[3px] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50\">\n                      <RadioGroupItem\n                        id={`${size.name}`}\n                        value={size.name}\n                        className=\"sr-only after:absolute after:inset-0\"\n                      />\n                      <p className=\"text-foreground text-sm leading-none font-medium\">\n                        {size.name}\n                      </p>\n                    </label>\n                  ))}\n                </RadioGroup>\n              </fieldset>\n            </div>\n\n            {/* Add to Bag Button */}\n            <div className=\"flex gap-2\">\n              <ButtonGroup>\n                <Button variant=\"outline\" aria-label=\"\" disabled>\n                  <MinusIcon />\n                </Button>\n                <Input className=\"w-12 text-center\" placeholder=\"1\" />\n                <Button variant=\"outline\" aria-label=\"\">\n                  <PlusIcon />\n                </Button>\n              </ButtonGroup>\n              <Button className=\"grow\">Add to Cart</Button>\n            </div>\n          </div>\n        </div>\n      </DialogContent>\n    </Dialog>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/product-quickviews/components/product-quickview-modal.tsx"
    },
    {
      "path": "examples/blocks/ecommerce/product-quickviews/02/page.tsx",
      "content": "\"use client\";\n\nimport { ProductQuickviewDialog } from \"./components/product-quickview-modal\";\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport { useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\n\nconst productData = {\n  id: \"1\",\n  title: \"Skater Jeans\",\n  description:\n    \"This theme is designed to make your online store look stylish and professional while offering your customers an exceptional user experience.\",\n  old_price: \"$49\",\n  price: \"$39\",\n  rating: 4,\n  reviewCount: 117,\n  image: \"/images/products/list1.png\",\n  colors: [\n    { name: \"White\", value: \"#FFFFFF\" },\n    { name: \"Gray\", value: \"#9CA3AF\" },\n    { name: \"Crimson\", value: \"crimson\" },\n    { name: \"Navy\", value: \"#1E293B\" }\n  ],\n  sizes: [\n    { name: \"XS\", available: true },\n    { name: \"S\", available: true },\n    { name: \"M\", available: true }\n  ]\n};\n\nexport default function Page() {\n  const [open, setOpen] = useState(true);\n\n  return (\n    <>\n      <div className=\"mx-auto h-[900px] max-w-80 py-24\">\n        <Link href=\"#\" className=\"group\">\n          <figure className=\"relative aspect-square w-full overflow-hidden rounded-md object-cover\">\n            <Image\n              fill\n              className=\"object-cover transition-transform duration-300 group-hover:scale-105 group-hover:rotate-2\"\n              src={productData.image}\n              alt={productData.title}\n            />\n          </figure>\n          <div className=\"mt-3 space-y-2\">\n            <div className=\"flex items-center justify-between gap-1\">\n              <p className=\"font-medium\">{productData.title}</p>\n              <p className=\"text-muted-foreground\">{productData.price}</p>\n            </div>\n          </div>\n          <Button onClick={() => setOpen(true)} variant=\"secondary\" className=\"mt-4 w-full\">\n            Quick View\n          </Button>\n        </Link>\n      </div>\n      <ProductQuickviewDialog open={open} onOpenChange={setOpen} product={productData} />\n    </>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/product-quickviews/product-quickviews.tsx"
    }
  ],
  "meta": {
    "isPro": true
  }
}