Skip to main content

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.5.0

πŸ“– Usage​

import {CreateProduct} from '@nodeblocks/frontend-create-product-block';
Live Editor
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) => {
        const values = getValues();
        console.log('Form values:', values);
      }}
      onAcceptAttachment={files => {
        console.log('File accepted:', files);
      }}
      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>
  );
}
Result
Loading...

πŸ”§ Props Reference​

Main Component Props​

PropTypeDefaultDescription
onSubmit(data: T, event?: React.BaseSyntheticEvent) => voidRequiredCallback function triggered when form is submitted with valid data
onChange(setError, getValues, clearErrors) => voidRequiredCallback function triggered when form values change
categoryOptionsArray<{value: string, label: string}>undefinedArray of category options for the category select field
onAcceptAttachment(files: File[]) => voidundefinedCallback fired when file is accepted for upload
onRejectAttachment(file: File, message: string) => voidundefinedCallback fired when file is rejected with error message
onClearAttachment() => voidundefinedCallback fired when attachment is cleared
defaultDataDefaultValues<T>undefinedDefault form values to populate fields on initial render
dataTundefinedControlled form values - use this for external form state management
classNamestringundefinedAdditional CSS class name for styling the form container
childrenBlocksOverrideundefinedCustom block components to override default rendering

Note: The main component extends MUI StackProps and renders as a form element using component="form". Default styling includes spacing={4}, direction="column", and p: 3 padding.

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.

PropTypeDefaultDescription
childrenBlocksOverrideundefinedCustom content to override default main info fields
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props. Default styling includes spacing={4}.

CreateProduct.MainInfo.SectionTitle​
PropTypeDefaultDescription
childrenReactNode"Create a Product"Title content for the main info section
variantTypographyProps['variant']"h6"MUI Typography variant
componentElementType"h3"HTML element to render
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Typography props.

CreateProduct.MainInfo.Dropzone​
PropTypeDefaultDescription
isDraggingMessagestring"Drop the image here..."Message displayed while dragging
beforeUploadMessagestring"Upload product image"Message displayed before file upload
beforeUploadSubtitlestring"PNG, JPG up to 2MB"Subtitle displayed before file upload
afterUploadOptionsButtonstring"Options"Text for options button after upload
replaceFileButtonstring"Select a new file"Text for replace file button
deleteFileButtonstring"Delete"Text for delete file button
requiredbooleanundefinedWhether file upload is required
maxSizenumber2000000Maximum file size in bytes (2MB)
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Box props and react-dropzone props. Accepts image/* files only, single file upload.

CreateProduct.MainInfo.NameField​
PropTypeDefaultDescription
namestring"name"Field name used for form data and validation
labelstring"Name"Field label displayed above the input
placeholderstring"Enter product name"Placeholder text
requiredbooleantrueWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props.

CreateProduct.BasicInfo​

Container for basic product information including category and description.

PropTypeDefaultDescription
childrenBlocksOverrideundefinedCustom content to override default basic info fields
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props. Default styling includes spacing={4}.

CreateProduct.BasicInfo.Title​
PropTypeDefaultDescription
childrenReactNode"Basic Information"Title content for the basic info section
variantTypographyProps['variant']"h6"MUI Typography variant
componentElementType"h3"HTML element to render
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Typography props.

CreateProduct.BasicInfo.CategoryField​
PropTypeDefaultDescription
namestring"categoryId"Field name for form data
labelstring"Categories"Field label
placeholderstring"Select product category"Placeholder text
optionsArray<{value: string, label: string}>From contextArray of category options
requiredbooleantrueWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props (select mode). Options are provided via categoryOptions prop on main component.

CreateProduct.BasicInfo.DescriptionField​
PropTypeDefaultDescription
namestring"description"Field name for form data
labelstring"Description"Label of the input field
placeholderstring"Describe the product"Placeholder text
inputTypestring"multiline"Input type (multiline for textarea)
requiredbooleantrueWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props. Renders as multiline textarea with 4 rows.

CreateProduct.AdditionalInfo​

Container for additional product information including location details.

PropTypeDefaultDescription
childrenBlocksOverrideundefinedCustom content to override default additional info fields
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props. Default styling includes spacing={4}.

CreateProduct.AdditionalInfo.Title​
PropTypeDefaultDescription
childrenReactNode"Additional Infomation"Title content for the additional info section
variantTypographyProps['variant']"h6"MUI Typography variant
componentElementType"h3"HTML element to render
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Typography props.

CreateProduct.AdditionalInfo.Subtitle​
PropTypeDefaultDescription
childrenReactNode"Location"Subtitle content for the location section
variantTypographyProps['variant']"body1"MUI Typography variant
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Typography props. Default styling includes fontWeight: 'bold'.

CreateProduct.AdditionalInfo.Address1Field​
PropTypeDefaultDescription
namestring"address1"Field name for form data
labelstring"Prefecture"Field label
placeholderstring"Select prefecture"Placeholder text
optionsArray<{value: string, label: string}>prefecturesArray of prefecture options (Japanese prefectures)
requiredbooleantrueWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props (select mode).

CreateProduct.AdditionalInfo.Address2Field​
PropTypeDefaultDescription
namestring"address2"Field name used for form data and validation
labelstring"Address"Field label displayed above the input
placeholderstring"Enter location address"Placeholder text
requiredbooleantrueWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props.

CreateProduct.Actions​

Container for form action buttons.

PropTypeDefaultDescription
childrenBlocksOverrideundefinedCustom content to override default action buttons
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props. Default styling includes direction="row", justifyContent: 'center', alignItems: 'center'.

CreateProduct.Actions.SubmitButton​
PropTypeDefaultDescription
childrenReactNode"Submit"Text to place inside the button
variantButtonProps['variant']"contained"MUI Button variant
sizeButtonProps['size']"large"MUI Button size
type"submit" | "button" | "reset""submit"HTML button type
disabledboolean!formState.isValidDisabled when form is invalid
startIconReactNode<TaskAlt />Icon displayed before button text
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Button props. Automatically disabled when form validation fails.

Additional Field Components​

The component also provides additional field types that can be used in custom forms:

CreateProduct.TextField​

PropTypeDefaultDescription
namePath<T>RequiredField name for form data
labelstringundefinedLabel of the input field
placeholderstringundefinedPlaceholder text
requiredbooleanundefinedWhether the field is required
inputType"multiline" | stringundefinedInput type (use "multiline" for textarea)
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props. Uses react-hook-form Controller for form integration.

CreateProduct.TimeField​

PropTypeDefaultDescription
namePath<T>RequiredField name for form data
labelstringundefinedLabel of the input field
requiredbooleanundefinedWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props with type="time". Uses react-hook-form Controller for form integration.

CreateProduct.CheckboxField​

PropTypeDefaultDescription
namePath<T>RequiredField name for form data
labelReactNodeRequiredCheckbox label
requiredbooleanundefinedWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI FormControlLabel props. Uses react-hook-form Controller for form integration.

CreateProduct.SelectField​

PropTypeDefaultDescription
namePath<T>RequiredField name for form data
labelstringundefinedField label
placeholderstringundefinedPlaceholder text when no option selected
optionsArray<{value: string, label: string}>undefinedArray of options
requiredbooleanundefinedWhether the field is required
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI TextField props (select mode). Uses react-hook-form Controller for form integration.


🎨 Configuration examples​

Custom Section Title Styling​

<CreateProduct.MainInfo.SectionTitle
variant="h5"
sx={{
color: 'primary.main',
fontWeight: 700,
borderBottom: '2px solid',
borderColor: 'primary.main',
pb: 1,
}}
>
Create Your Product
</CreateProduct.MainInfo.SectionTitle>

Custom Dropzone Styling​

<CreateProduct.MainInfo.Dropzone
beforeUploadMessage="Drop your product image here"
beforeUploadSubtitle="Supports PNG, JPG up to 2MB"
sx={{
borderColor: 'primary.main',
bgcolor: 'primary.50',
'&:hover': {bgcolor: 'primary.100'},
}}
/>

Custom Field Styling​

<CreateProduct.TextField
name="customField"
label="Custom Field"
sx={{
'& .MuiOutlinedInput-root': {
borderRadius: '12px',
},
}}
/>

Using Block Override Pattern​

<CreateProduct {...props}>
{({defaultBlocks, defaultBlockOrder}) => ({
blocks: {
...defaultBlocks,
mainInfo: {
...defaultBlocks.mainInfo,
props: {
...defaultBlocks.mainInfo.props,
sx: {
background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)',
borderRadius: '14px',
p: 3,
},
},
},
},
blockOrder: defaultBlockOrder,
})}
</CreateProduct>

πŸ”§ TypeScript Support​

Full TypeScript support with comprehensive type definitions:

import {CreateProduct} from '@nodeblocks/frontend-create-product-block';
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} | File;
customField?: string;
price?: string;
stock?: string;
sku?: string;
}

interface CategoryOption {
value: string;
label: string;
}

// Complete typed example
function TypedCreateProductExample() {
const categoryOptions: CategoryOption[] = [
{value: 'electronics', label: 'Electronics'},
{value: 'clothing', label: 'Clothing'},
{value: 'home', label: 'Home & Garden'},
];

const handleSubmit = (data: CustomProductFormData, event?: React.BaseSyntheticEvent): void => {
console.log('Product data:', data);
console.log('Event:', event);
};

const handleChange = (
setError: UseFormSetError<CustomProductFormData>,
getValues: UseFormGetValues<CustomProductFormData>,
clearErrors: UseFormClearErrors<CustomProductFormData>,
): void => {
const values = getValues();
// Validate form values and set errors if needed
if (!values.name) {
setError('name', {message: 'Product name is required'});
} else {
clearErrors('name');
}
};

return (
<CreateProduct<CustomProductFormData>
onSubmit={handleSubmit}
onChange={handleChange}
categoryOptions={categoryOptions}
onAcceptAttachment={files => console.log('Files accepted:', files)}
onRejectAttachment={(file, message) => console.log('File rejected:', file, message)}
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>
);
}

πŸ“ Notes​

  • The root component uses MUI's Stack with component="form" to create a semantic form element
  • Form state management is handled by react-hook-form with mode: 'onBlur' for validation
  • The onChange callback is triggered whenever form values change, providing setError, getValues, and clearErrors functions
  • SubmitButton is automatically disabled when formState.isValid is false
  • Default block order: mainInfo, basicInfo, additionalInfo, actions
  • All sub-components support the MUI sx prop for inline styling
  • Form fields use react-hook-form Controller for form state integration
  • The component supports generic typing for custom form data interfaces (must extend DefaultCreateProductFormData)
  • CSS classes follow BEM naming: nbb-create-product, nbb-create-product-main-info, etc.
  • Image dropzone uses react-dropzone with 2MB max file size and image/* accept filter
  • Prefecture options for Address1Field are pre-populated with Japanese prefectures
  • The data prop can be used for controlled form state, while defaultData sets initial values

Built with ❀️ using React, TypeScript, and MUI.