Create Product Block
The CreateProduct Component is a fully customizable and accessible product creation form built with React and TypeScript. It provides a complete interface for product registration with image upload, category selection, location information, and modern design patterns.
π Installationβ
npm install @nodeblocks/frontend-create-product-block@0.4.3
π Usageβ
import {CreateProduct} from '@nodeblocks/frontend-create-product-block';
- Basic Usage
- Advanced Usage
function BasicCreateProduct() {
const categoryOptions = [
{ value: 'electronics', label: 'Electronics' },
{ value: 'clothing', label: 'Clothing' },
{ value: 'home', label: 'Home & Garden' }
];
return (
<CreateProduct
categoryOptions={categoryOptions}
onSubmit={(formData) => {
console.log('Product created:', formData);
}}
onChange={(setError, getValues, clearErrors) => {
const values = getValues();
console.log('Form values:', values);
}}
onAcceptAttachment={(files) => {
console.log('File accepted:', files);
}}
onUploadAttachment={(file) => {
console.log('Uploading file:', file);
// Handle file upload logic
}}
onClearAttachment={() => {
console.log('Attachment cleared');
}}>
<CreateProduct.MainInfo>
<CreateProduct.MainInfo.SectionTitle>Product Information</CreateProduct.MainInfo.SectionTitle>
<CreateProduct.MainInfo.Dropzone />
<CreateProduct.MainInfo.NameField />
</CreateProduct.MainInfo>
<CreateProduct.BasicInfo>
<CreateProduct.BasicInfo.Title />
<CreateProduct.BasicInfo.CategoryField />
<CreateProduct.BasicInfo.DescriptionField />
</CreateProduct.BasicInfo>
<CreateProduct.AdditionalInfo>
<CreateProduct.AdditionalInfo.Title />
<CreateProduct.AdditionalInfo.Subtitle />
<CreateProduct.AdditionalInfo.Address1Field />
<CreateProduct.AdditionalInfo.Address2Field />
</CreateProduct.AdditionalInfo>
<CreateProduct.Actions>
<CreateProduct.Actions.SubmitButton>Create Product</CreateProduct.Actions.SubmitButton>
</CreateProduct.Actions>
</CreateProduct>
);
}
function AdvancedCreateProduct() {
const categoryOptions = [
{ value: 'electronics', label: 'Electronics' },
{ value: 'clothing', label: 'Clothing' },
{ value: 'home', label: 'Home & Garden' },
{ value: 'sports', label: 'Sports & Outdoor' },
{ value: 'automotive', label: 'Automotive' }
];
return (
<CreateProduct
categoryOptions={categoryOptions}
onSubmit={(formData) => {
console.log('Advanced product created:', formData);
}}
onChange={(setError, getValues, clearErrors) => {
const values = getValues();
console.log('Form validation:', values);
}}
onAcceptAttachment={(files) => {
console.log('Files accepted:', files);
}}
onUploadAttachment={(file) => {
console.log('Uploading:', file);
}}
onClearAttachment={() => {
console.log('Attachment cleared');
}}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
// Override Main Info section with custom styling
mainInfo: {
...defaultBlocks.mainInfo,
props: {
...defaultBlocks.mainInfo.props,
style: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
borderRadius: '16px',
padding: '32px',
color: 'white',
marginBottom: '24px'
}
}
},
// Override Basic Info section with enhanced styling
basicInfo: {
...defaultBlocks.basicInfo,
props: {
...defaultBlocks.basicInfo.props,
style: {
background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
borderRadius: '16px',
padding: '28px',
color: 'white',
marginBottom: '24px',
boxShadow: '0 10px 30px rgba(0,0,0,0.1)'
}
}
},
// Full override of Additional Info section
additionalInfo: (
<div style={{
background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
borderRadius: '16px',
padding: '32px',
color: 'white',
marginBottom: '24px',
boxShadow: '0 15px 35px rgba(0,0,0,0.1)'
}}>
<h3 style={{
fontSize: '24px',
fontWeight: 'bold',
marginBottom: '8px',
background: 'linear-gradient(45deg, #ffffff, #e8f4f8)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text'
}}>
π Product Location Details
</h3>
<p style={{
fontSize: '14px',
marginBottom: '24px',
opacity: 0.9
}}>
Specify where your product is located for better visibility
</p>
<div style={{ display: 'grid', gap: '20px' }}>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '12px',
padding: '20px',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255,255,255,0.2)'
}}>
<CreateProduct.AdditionalInfo.Address1Field
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '12px',
padding: '20px',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255,255,255,0.2)'
}}>
<CreateProduct.AdditionalInfo.Address2Field
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
{/* Custom additional fields */}
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '12px',
padding: '20px',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255,255,255,0.2)'
}}>
<CreateProduct.TextField
name="coordinates"
label="GPS Coordinates (Optional)"
placeholder="e.g., 35.6762, 139.6503"
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
</div>
</div>
),
// Enhanced actions section
actions: {
...defaultBlocks.actions,
props: {
...defaultBlocks.actions.props,
style: {
background: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
padding: '24px',
textAlign: 'center',
boxShadow: '0 10px 30px rgba(0,0,0,0.15)'
}
}
}
},
blockOrder: defaultBlockOrder
})}
</CreateProduct>
);
}
Example with Complete Form Override:
function CustomCreateProduct() {
const categoryOptions = [
{ value: 'premium', label: 'π Premium Products' },
{ value: 'limited', label: 'β Limited Edition' },
{ value: 'exclusive', label: 'π₯ Exclusive Items' }
];
return (
<CreateProduct
categoryOptions={categoryOptions}
onSubmit={(formData) => {
console.log('Custom product created:', formData);
}}
onChange={(setError, getValues, clearErrors) => {
console.log('Custom form validation:', getValues());
}}
onAcceptAttachment={(files) => {
console.log('Custom file handling:', files);
}}
onUploadAttachment={(file) => {
console.log('Custom upload:', file);
}}
onClearAttachment={() => {
console.log('Custom clear');
}}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
// Complete override of main info
mainInfo: (
<div style={{
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
borderRadius: '20px',
padding: '40px',
color: 'white',
marginBottom: '30px',
position: 'relative',
overflow: 'hidden'
}}>
<div style={{
position: 'absolute',
top: '-50%',
right: '-50%',
width: '200%',
height: '200%',
background: 'radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%)',
transform: 'rotate(45deg)'
}}></div>
<div style={{ position: 'relative', zIndex: 1 }}>
<h2 style={{
fontSize: '28px',
fontWeight: 'bold',
marginBottom: '16px',
display: 'flex',
alignItems: 'center',
gap: '12px'
}}>
π Product Showcase
</h2>
<p style={{ fontSize: '16px', marginBottom: '32px', opacity: 0.9 }}>
Create an amazing product listing that stands out from the crowd
</p>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 2fr', gap: '24px', alignItems: 'start' }}>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '16px',
padding: '24px',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255,255,255,0.2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
textAlign: 'center'
}}>
<CreateProduct.MainInfo.Dropzone
beforeUploadMessage="πΈ Upload Image"
beforeUploadSubtitle="Drag & drop or click to select"
style={{
background: 'rgba(255,255,255,0.1)',
border: '2px dashed rgba(255,255,255,0.3)',
borderRadius: '12px'
}}
/>
</div>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '16px',
padding: '24px',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255,255,255,0.2)'
}}>
<CreateProduct.MainInfo.NameField
label="β¨ Product Name"
placeholder="Enter an amazing product name..."
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333',
marginBottom: '20px'
}}
/>
<CreateProduct.TextField
name="subtitle"
label="π Product Subtitle"
placeholder="A catchy subtitle that describes your product"
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
</div>
</div>
</div>
),
// Enhanced basic info with product features
basicInfo: (
<div style={{
background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
borderRadius: '20px',
padding: '32px',
color: 'white',
marginBottom: '30px'
}}>
<h3 style={{
fontSize: '24px',
fontWeight: 'bold',
marginBottom: '24px',
display: 'flex',
alignItems: 'center',
gap: '12px'
}}>
π Product Details
</h3>
<div style={{ display: 'grid', gap: '24px' }}>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '12px',
padding: '20px',
backdropFilter: 'blur(10px)'
}}>
<CreateProduct.BasicInfo.CategoryField
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '12px',
padding: '20px',
backdropFilter: 'blur(10px)'
}}>
<CreateProduct.BasicInfo.DescriptionField
placeholder="Describe your product's features, benefits, and what makes it special..."
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333',
minHeight: '120px'
}}
/>
</div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '16px' }}>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '12px',
padding: '20px',
backdropFilter: 'blur(10px)'
}}>
<CreateProduct.TextField
name="price"
label="π° Price"
placeholder="0.00"
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
<div style={{
background: 'rgba(255,255,255,0.15)',
borderRadius: '12px',
padding: '20px',
backdropFilter: 'blur(10px)'
}}>
<CreateProduct.SelectField
name="condition"
label="π Condition"
selectOptionValues={[
{ value: 'new', label: 'Brand New' },
{ value: 'excellent', label: 'Excellent' },
{ value: 'good', label: 'Good' },
{ value: 'fair', label: 'Fair' }
]}
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
</div>
</div>
</div>
),
// Keep enhanced additional info
additionalInfo: defaultBlocks.additionalInfo,
// Enhanced action buttons
actions: (
<div style={{
background: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
borderRadius: '20px',
padding: '32px',
textAlign: 'center',
marginTop: '30px'
}}>
<div style={{ display: 'flex', gap: '16px', justifyContent: 'center', alignItems: 'center' }}>
<button
type="button"
style={{
background: 'rgba(255,255,255,0.2)',
border: '2px solid rgba(255,255,255,0.3)',
borderRadius: '12px',
padding: '12px 24px',
color: 'white',
fontSize: '16px',
fontWeight: '600',
cursor: 'pointer',
backdropFilter: 'blur(10px)',
transition: 'all 0.3s ease'
}}
onMouseOver={(e) => {
e.target.style.background = 'rgba(255,255,255,0.3)';
e.target.style.transform = 'translateY(-2px)';
}}
onMouseOut={(e) => {
e.target.style.background = 'rgba(255,255,255,0.2)';
e.target.style.transform = 'translateY(0)';
}}
>
πΎ Save Draft
</button>
<CreateProduct.Actions.SubmitButton
style={{
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
border: 'none',
borderRadius: '12px',
padding: '12px 32px',
color: 'white',
fontSize: '16px',
fontWeight: '600',
boxShadow: '0 6px 20px rgba(0,0,0,0.2)',
transition: 'all 0.3s ease'
}}
>
π Launch Product
</CreateProduct.Actions.SubmitButton>
<button
type="button"
style={{
background: 'rgba(255,255,255,0.2)',
border: '2px solid rgba(255,255,255,0.3)',
borderRadius: '12px',
padding: '12px 24px',
color: 'white',
fontSize: '16px',
fontWeight: '600',
cursor: 'pointer',
backdropFilter: 'blur(10px)',
transition: 'all 0.3s ease'
}}
onMouseOver={(e) => {
e.target.style.background = 'rgba(255,255,255,0.3)';
e.target.style.transform = 'translateY(-2px)';
}}
onMouseOut={(e) => {
e.target.style.background = 'rgba(255,255,255,0.2)';
e.target.style.transform = 'translateY(0)';
}}
>
ποΈ Preview
</button>
</div>
</div>
)
},
blockOrder: ['mainInfo', 'basicInfo', 'additionalInfo', 'actions']
})}
</CreateProduct>
);
}
π§ Props Referenceβ
Main Component Propsβ
| Prop | Type | Default | Description |
|---|---|---|---|
onSubmit | (data: T, event?: React.BaseSyntheticEvent) => void | Required | Callback function triggered when form is submitted with valid data |
onChange | (setError, getValues, clearErrors) => void | Required | Callback function triggered when form values change |
categoryOptions | OptionValue[] | undefined | Array of category options for the category select field |
onAcceptAttachment | (files: File[]) => void | undefined | Callback fired when file is accepted for upload |
onUploadAttachment | (file: File) => void | undefined | Callback fired when file upload is triggered |
onRejectAttachment | (files: File[]) => void | undefined | Callback fired when file is rejected |
onClearAttachment | () => void | undefined | Callback fired when attachment is cleared |
defaultData | DefaultValues<T> | undefined | Default form values to populate fields on initial render |
data | T | undefined | Controlled form values - use this for external form state management |
className | string | undefined | Additional CSS class name for styling the form container |
children | BlocksOverride | undefined | Custom block components to override default rendering |
Note: This component inherits all HTML div element props.
Sub-Componentsβ
The CreateProduct component provides several sub-components. All sub-components receive their default values from the main component's context and can override these values through props.
CreateProduct.MainInfoβ
Container for main product information including image upload and product name.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | undefined | Custom content to override default main info fields |
direction | enum | "column" | Flex direction for action buttons |
alignItems | enum | "stretch" | Alignment of items in the container |
gapSize | enum | "S" | Gap between items in the container |
CreateProduct.MainInfo.SectionTitleβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | "Main Info" | Title content for the main info section |
size | enum | "L" | Typography size for the title |
type | enum | "heading" | Typography type |
color | enum | "low-emphasis" | Color theme for the title |
weight | enum | "bold" | Typography weight |
className | string | undefined | Additional CSS class name for styling |
CreateProduct.MainInfo.Dropzoneβ
| Prop | Type | Default | Description |
|---|---|---|---|
beforeUploadMessage | string | "Upload" | Message displayed before file upload |
beforeUploadSubtitle | string | "Select a file to upload." | Subtitle displayed before file upload |
afterUploadOptionsButton | string | "Options" | Text for options button after upload |
replaceFileButton | string | "Select a new file" | Text for replace file button |
deleteFileButton | string | "Delete" | Text for delete file button |
maxFiles | number | 1 | Maximum number of files allowed |
accept | string | "image/*" | File types accepted |
maxSize | number | 5242880 | Maximum file size in bytes (5MB) |
className | string | undefined | Additional CSS class name for styling |
CreateProduct.MainInfo.NameFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "name" | Field name used for form data and validation |
label | string | "Name" | Field label displayed above the input |
labelWeight | enum | "regular" | Weight of the field label |
name | string | "applicationUserEmail" | Field name for form data |
className | string | undefined | Additional CSS class name for styling |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
Note: This component additional inherits some common HTML input element props.
CreateProduct.BasicInfoβ
Container for basic product information including category and description.
| Prop | Type | Default | Description |
|---|---|---|---|
children | BlocksOverride | undefined | Custom content to override default basic info fields |
className | string | undefined | Additional CSS class name for styling |
direction | enum | "column" | Flex direction for action buttons |
alignItems | enum | "stretch" | Alignment of items in the container |
gapSize | enum | "S" | Gap between items in the container |
CreateProduct.BasicInfo.Titleβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | "Basic Information" | Title content for the basic info section |
size | enum | "L" | Typography size for the title |
type | enum | "heading" | Typography type |
color | enum | "low-emphasis" | Color theme for the title |
weight | enum | "bold" | Typography weight |
className | string | undefined | Additional CSS class name for styling |
CreateProduct.BasicInfo.CategoryFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "categoryId" | Field name for form data |
label | string | "Categories" | Field label |
labelWeight | enum | "regular" | Label weight |
selectOptionValues | Array<{value: string, label: string}> | [] | Array of category options |
isRequired | boolean | undefined | Whether the field is required |
isDisabled | boolean | undefined | Whether the input is disabled |
errorText | string | undefined | Error text for the input |
className | string | undefined | Additional CSS class name for styling |
Note: This component additional inherits some common HTML select element props.
CreateProduct.BasicInfo.DescriptionFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "description" | Field name for form data |
label | string | "Description" | Label of the input field |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
labelWeight | `enum | ||
className | string | undefined | Additional CSS class name for styling |
Note: This component additional inherits some common HTML textarea element props.
CreateProduct.AdditionalInfoβ
Container for additional product information including location details.
| Prop | Type | Default | Description |
|---|---|---|---|
children | BlocksOverride | undefined | Custom content to override default additional info fields |
className | string | undefined | Additional CSS class name for styling |
direction | enum | "column" | Flex direction for action buttons |
alignItems | enum | "stretch" | Alignment of items in the container |
gapSize | enum | "S" | Gap between items in the container |
CreateProduct.AdditionalInfo.Titleβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | BlockReasOverride | "Additional Information" | Title content for the additional info section |
size | enum | "L" | Typography size for the title |
type | enum | "heading" | Typography type |
color | enum | "low-emphasis" | Color theme for the title |
weight | enum | "bold" | Typography weight |
className | string | undefined | Additional CSS class name for styling |
CreateProduct.AdditionalInfo.Subtitleβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | "Location" | Subtitle content for the location section |
size | enum | "S" | Typography size for the title |
type | enum | "heading" | Typography type |
color | enum | "low-emphasis" | Color theme for the title |
weight | enum | "regular" | Typography weight |
className | string | undefined | Additional CSS class name for styling |
CreateProduct.AdditionalInfo.Address1Fieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "address1" | Field name for form data |
label | string | "Prefecture" | Field label |
labelWeight | enum | "regular" | Label weight |
selectOptionValues | Array<{value: string, label: string}> | [] | Array of prefecture options |
isRequired | boolean | undefined | Whether the field is required |
isDisabled | boolean | undefined | Whether the input is disabled |
errorText | string | undefined | Error text for the input |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML select element props.
CreateProduct.AdditionalInfo.Address2Fieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "address2" | Field name used for form data and validation |
label | string | "Town" | Field label displayed above the input |
labelWeight | enum | "regular" | Weight of the field label |
className | string | undefined | Additional CSS class name for styling |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
Note: This component additional inherits some common HTML input element props.
CreateProduct.Actionsβ
Container for form action buttons.
| Prop | Type | Default | Description |
|---|---|---|---|
children | BlocksOverride | undefined | Custom content to override default action buttons |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML div element props.
CreateProduct.Actions.SubmitButtonβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | "Submit" | Text to place inside the button |
className | string | undefined | Additional CSS class name for styling |
fill | enum | "fill" | Button fill style |
icon | enum | undefined | Optional icon for the left-hand side of the button |
iconColor | enum | undefined | Color for the left-hand side icon. When not provided, a default color for the fill type will be used. |
isDisabled | boolean | false | Whether the button is disabled and cannot be used |
onClick | function | undefined | Function to handle button click |
size | enum | "M" | Button vertical size |
textAlign | enum | "center" | Button icon and text positioning within the button |
textColor | enum | "default" | Button text color |
textEmphasis | boolean | false | Button text weight |
textSize | enum | "M" | Button text size |
type | enum | "submit" | Button purpose (affects html type) |
Note: This component additional inherits some common HTML button element props.
Additional Field Componentsβ
The component also provides additional field types that can be used in custom forms:
CreateProduct.TextFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | Required | Field name for form data |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
label | string | Required | Label of the input field |
labelWeight | enum | "regular" | Label weight |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
Note: This component additional inherits some common HTML input element props.
CreateProduct.TimeFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | Required | Field name for form data |
label | string | Required | Label of the input field |
labelWeight | enum | "regular" | Label weight |
isRequired | boolean | undefined | Whether the input is required |
isDisabled | boolean | undefined | Whether the input is disabled |
errorText | string | undefined | Error text for the input |
className | string | undefined | Additional CSS class name for styling |
Note: This component additional inherits some common HTML input element props.
CreateProduct.CheckboxFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | Required | Field name for form data |
label | string | Required | Checkbox label |
message | string | undefined | Checkbox description message |
showMessage | boolean | true | Whether to show the message |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML checkbox element props.
CreateProduct.SelectFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "required" | Field name for form data |
label | string | "Required" | Field label |
labelWeight | enum | "regular" | Label weight |
selectOptionValues | Array<{value: string, label: string}> | [] | Array of options |
isRequired | boolean | undefined | Whether the field is required |
isDisabled | boolean | undefined | Whether the input is disabled |
errorText | string | undefined | Error text for the input |
className | string | undefined | Additional CSS class name for styling |
Note: This component additional inherits some common HTML select element props.
π§ TypeScript Supportβ
Full TypeScript support with comprehensive type definitions:
import {CreateProduct} from '@nodeblocks/frontend-create-product-block';
//in future we will not use react-hook-form, we will use our own form handling
import {UseFormClearErrors, UseFormGetValues, UseFormSetError} from 'react-hook-form';
interface CustomProductFormData extends Record<string, unknown> {
name: string;
description: string;
address1: string;
address2: string;
categoryId: string;
image: {url: string; type?: string; id?: string};
customField?: string;
}
const handleSubmit = (data: CustomProductFormData, event?: React.BaseSyntheticEvent) => {
// Type-safe form handling
console.log('Product data:', data);
console.log('Event:', event);
};
const handleChange = (
setError: UseFormSetError<CustomProductFormData>,
getValues: UseFormGetValues<CustomProductFormData>,
clearErrors: UseFormClearErrors<CustomProductFormData>,
) => {
const values = getValues();
// Validate form values and set errors if needed
if (!values.name) {
setError('name', {message: 'Product name is required'});
} else {
clearErrors('name');
}
};
const categoryOptions = [
{value: 'electronics', label: 'Electronics'},
{value: 'clothing', label: 'Clothing'},
{value: 'home', label: 'Home & Garden'},
];
const CreateProductForm = () => {
return (
<CreateProduct<CustomProductFormData>
onSubmit={handleSubmit}
onChange={handleChange}
categoryOptions={categoryOptions}
onAcceptAttachment={files => console.log('Files accepted:', files)}
onUploadAttachment={file => console.log('Uploading:', file)}
onClearAttachment={() => console.log('Attachment cleared')}>
<CreateProduct.MainInfo>
<CreateProduct.MainInfo.SectionTitle>Product Details</CreateProduct.MainInfo.SectionTitle>
<CreateProduct.MainInfo.Dropzone />
<CreateProduct.MainInfo.NameField name="name" />
</CreateProduct.MainInfo>
<CreateProduct.BasicInfo>
<CreateProduct.BasicInfo.Title />
<CreateProduct.BasicInfo.CategoryField />
<CreateProduct.BasicInfo.DescriptionField />
</CreateProduct.BasicInfo>
<CreateProduct.AdditionalInfo>
<CreateProduct.AdditionalInfo.Title />
<CreateProduct.AdditionalInfo.Subtitle />
<CreateProduct.AdditionalInfo.Address1Field />
<CreateProduct.AdditionalInfo.Address2Field />
</CreateProduct.AdditionalInfo>
<CreateProduct.Actions>
<CreateProduct.Actions.SubmitButton>Create Product</CreateProduct.Actions.SubmitButton>
</CreateProduct.Actions>
</CreateProduct>
);
};
Built with β€οΈ using React, TypeScript, and modern web standards.