Product Detail
Product detail form with variants and media
SaaSProducts
Overview
ProductDetailForm provides a complete product editing experience with tabbed sections for basic information (name, SKU, type, description, tags), variant management (size/tier/color with price adjustments), and media gallery (image upload and reordering). Supports create and edit modes with loading and error states.
Usage
import { ProductDetailForm } from "@leanicon/web-builder-library/saas";
<ProductDetailForm
product={existingProduct}
onSubmit={async (data) => await saveProduct(data)}
onCancel={() => router.back()}
onUploadMedia={async (files) => await uploadFiles(files)}
submitting={isSaving}
submitError={saveError}
/>;Variants
Create Mode
Submitting
With Submit Error
Dark
Edit Mode (code only)
<ProductDetailForm
product={{
id: "prod-123",
sku: "ENT-SUITE-001",
name: "Enterprise Suite",
description: "A comprehensive enterprise software suite.",
type: "digital",
status: "published",
tags: ["enterprise", "suite", "collaboration"],
variants: [
{ id: "var-1", type: "tier", name: "Standard", isDefault: true },
{
id: "var-2",
type: "tier",
name: "Professional",
priceAdjustment: { type: "fixed", value: 100 },
},
],
media: [
{
id: "media-1",
url: "/screenshot.png",
type: "image",
alt: "Screenshot",
order: 0,
isPrimary: true,
},
],
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-15T00:00:00Z",
}}
onSubmit={async (data) => await saveProduct(data)}
onCancel={() => router.back()}
onUploadMedia={async (files) => await uploadFiles(files)}
/>Physical Product (code only)
<ProductDetailForm
product={{
id: "prod-widget",
sku: "WIDGET-PRO-001",
name: "Premium Widget",
type: "physical",
status: "published",
variants: [
{ id: "size-s", type: "size", name: "Small", sku: "WIDGET-PRO-S", isDefault: true },
{
id: "size-m",
type: "size",
name: "Medium",
sku: "WIDGET-PRO-M",
priceAdjustment: { type: "fixed", value: 5 },
},
{
id: "size-l",
type: "size",
name: "Large",
sku: "WIDGET-PRO-L",
priceAdjustment: { type: "fixed", value: 10 },
},
],
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-15T00:00:00Z",
}}
onSubmit={async (data) => console.log("Submit:", data)}
onCancel={() => console.log("Cancel")}
onUploadMedia={async (files) => await uploadFiles(files)}
/>