商品作成ブロック
CreateProduct コンポーネント は、React と TypeScript で構築された、完全にカスタマイズ可能でアクセシブルな商品作成フォームです。画像アップロード、カテゴリ選択、所在地情報、最新のデザインパターンを備えた、商品登録のための完全なインターフェースを提供します。
🚀 インストール
npm install @nodeblocks/frontend-create-product-block@0.4.3
📖 使用方法
import {CreateProduct} from '@nodeblocks/frontend-create-product-block';
- 基本使用
- 詳細使用
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>
);
}
完全なフォームオーバーライドの例:
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>
);
}
🔧 プロパティリファレンス
メインコンポーネントのプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
onSubmit | (data: T, event?: React.BaseSyntheticEvent) => void | 必須 | 有効なデータでフォームが送信されたときに呼び出されるコールバック関数 |
onChange | (setError, getValues, clearErrors) => void | 必須 | フォーム値が変化したときに呼び出されるコールバック関数 |
categoryOptions | OptionValue[] | undefined | カテゴリセレクトフィールド用のカテゴリ選択肢配列 |
onAcceptAttachment | (files: File[]) => void | undefined | ファイルのアップロードが受け入れられたときに呼び出されるコールバック |
onUploadAttachment | (file: File) => void | undefined | ファイルのアップロードが開始されたときに呼び出されるコールバック |
onRejectAttachment | (files: File[]) => void | undefined | ファイルが拒否されたときに呼び出されるコールバック |
onClearAttachment | () => void | undefined | 添付がクリアされたときに呼び出されるコールバック |
defaultData | DefaultValues<T> | undefined | 初回レンダリング時にフィールドへ設定するデフォルトのフォーム値 |
data | T | undefined | 制御されたフォーム値 - 外部のフォーム状態管理に使用します |
className | string | undefined | フォームコンテナのスタイル用の追加 CSS クラス名 |
children | BlocksOverride | undefined | デフォルト描画を上書きするカスタムブロックコンポーネント |
注: このコンポーネントは HTML div 要素のすべての props を継承します。
サブコンポーネント
CreateProduct コンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントはメインコンポーネントのコンテキストからデフォルト値を受け取り、props でそれらを上書きできます。
CreateProduct.MainInfo
画像アップロードと商品名を含むメイン商品情報のコンテナです。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | undefined | デフォルトのメイン情報フィールドを上書きするカスタム内容 |
direction | enum | "column" | アクションボタンの flex 方向 |
alignItems | enum | "stretch" | コンテナ内アイテムの配置 |
gapSize | enum | "S" | コンテナ内アイテム間の間隔 |
CreateProduct.MainInfo.SectionTitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "メイン情報" | メイン情報セクションのタイトル内容 |
size | enum | "L" | タイトルの Typography サイズ |
type | enum | "heading" | Typography の種類 |
color | enum | "low-emphasis" | タイトルの配色テーマ |
weight | enum | "bold" | Typography のウェイト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
CreateProduct.MainInfo.Dropzone
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
beforeUploadMessage | string | "アップロード" | ファイルアップロード前に表示されるメッセージ |
beforeUploadSubtitle | string | "アップロードするファイルを選択してください。" | ファイルアップロード前に表示されるサブタイトル |
afterUploadOptionsButton | string | "オプション" | アップロード後のオプションボタンの文言 |
replaceFileButton | string | "新しいファイルを選択" | ファイル置換ボタンの文言 |
deleteFileButton | string | "削除" | ファイル削除ボタンの文言 |
maxFiles | number | 1 | 許可される最大ファイル数 |
accept | string | "image/*" | 受け入れ可能なファイル प्रकार |
maxSize | number | 5242880 | 最大ファイルサイズ(バイト、5MB) |
className | string | undefined | スタイル用の追加 CSS クラス名 |
CreateProduct.MainInfo.NameField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "name" | フォームデータと検証に使用するフィールド名 |
label | string | "商品名" | 入力の上に表示されるフィールドラベル |
labelWeight | enum | "regular" | フィールドラベルの太さ |
name | string | "applicationUserEmail" | フォームデータのフィールド名 |
className | string | undefined | スタイル用の追加 CSS クラス名 |
errorText | string | undefined | 入力のエラーテキスト |
isDisabled | boolean | undefined | 入力が無効かどうか |
isRequired | boolean | undefined | 入力が必須かどうか |
onOperationClick | () => void | undefined | 操作用 onClick コールバック |
postfixText | string | undefined | コンポーネントの後ろに配置するテキスト |
showPassword | boolean | undefined | パスワードを表示するかどうか |
Note: 注: このコンポーネントは、共通の HTML input 要素 props も追加で継承します。
CreateProduct.BasicInfo
カテゴリと説明を含む基本商品情報のコンテナです。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | BlocksOverride | undefined | デフォルトの基本情報フィールドを上書きするカスタム内容 |
className | string | undefined | スタイル用の追加 CSS クラス名 |
direction | enum | "column" | アクションボタンの flex 方向 |
alignItems | enum | "stretch" | コンテナ内アイテムの配置 |
gapSize | enum | "S" | コンテナ内アイテム間の間隔 |
CreateProduct.BasicInfo.Title
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Basic Information" | 基本情報セクションのタイトル内容 |
size | enum | "L" | タイトルの Typography サイズ |
type | enum | "heading" | Typography の種類 |
color | enum | "low-emphasis" | タイトルの配色テーマ |
weight | enum | "bold" | Typography のウェイト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
CreateProduct.BasicInfo.CategoryField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "categoryId" | フォームデータのフィールド名 |
label | string | "カテゴリ" | フィールドラベル |
labelWeight | enum | "regular" | ラベルの太さ |
selectOptionValues | Array<{value: string, label: string}> | [] | カテゴリ選択肢の配列 |
isRequired | boolean | undefined | フィールドが必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
Note: 注: このコンポーネントは、共通の HTML select 要素 props も追加で継承します。
CreateProduct.BasicInfo.DescriptionField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "description" | フォームデータのフィールド名 |
label | string | "説明" | 入力フィールドのラベル |
errorText | string | undefined | 入力のエラーテキスト |
isDisabled | boolean | undefined | 入力が無効かどうか |
isRequired | boolean | undefined | 入力が必須かどうか |
labelWeight | `enum | ||
className | string | undefined | スタイル用の追加 CSS クラス名 |
Note: 注: このコンポーネントは、共通の HTML textarea 要素 props も追加で継承します。
CreateProduct.AdditionalInfo
所在地の詳細を含む追加商品情報のコンテナです。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | BlocksOverride | undefined | デフォルトの追加情報フィールドを上書きするカスタム内容 |
className | string | undefined | スタイル用の追加 CSS クラス名 |
direction | enum | "column" | アクションボタンの flex 方向 |
alignItems | enum | "stretch" | コンテナ内アイテムの配置 |
gapSize | enum | "S" | コンテナ内アイテム間の間隔 |
CreateProduct.AdditionalInfo.Title
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | BlockReasOverride | "Additional Information" | 追加情報セクションのタイトル内容 |
size | enum | "L" | タイトルの Typography サイズ |
type | enum | "heading" | Typography の種類 |
color | enum | "low-emphasis" | タイトルの配色テーマ |
weight | enum | "bold" | Typography のウェイト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
CreateProduct.AdditionalInfo.Subtitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Location" | 所在地セクションのサブタイトル内容 |
size | enum | "S" | タイトルの Typography サイズ |
type | enum | "heading" | Typography の種類 |
color | enum | "low-emphasis" | タイトルの配色テーマ |
weight | enum | "regular" | Typography のウェイト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
CreateProduct.AdditionalInfo.Address1Field
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "address1" | フォームデータのフィールド名 |
label | string | "都道府県" | フィールドラベル |
labelWeight | enum | "regular" | ラベルの太さ |
selectOptionValues | Array<{value: string, label: string}> | [] | 都道府県オプションの配列 |
isRequired | boolean | undefined | フィールドが必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
Note: 注: このコンポーネントは HTML select 要素のすべての props を継承します。
CreateProduct.AdditionalInfo.Address2Field
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "address2" | フォームデータと検証に使用するフィールド名 |
label | string | "町名・番地・建物" | 入力の上に表示されるフィールドラベル |
labelWeight | enum | "regular" | フィールドラベルの太さ |
className | string | undefined | スタイル用の追加 CSS クラス名 |
errorText | string | undefined | 入力のエラーテキスト |
isDisabled | boolean | undefined | 入力が無効かどうか |
isRequired | boolean | undefined | 入力が必須かどうか |
onOperationClick | () => void | undefined | 操作用 onClick コールバック |
postfixText | string | undefined | コンポーネントの後ろに配置するテキスト |
showPassword | boolean | undefined | パスワードを表示するかどうか |
Note: 注: このコンポーネントは、共通の HTML input 要素 props も追加で継承します。
CreateProduct.Actions
フォーム操作ボタンのコンテナです。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | BlocksOverride | undefined | デフォルトのアクションボタンを上書きするカスタム内容 |
className | string | undefined | スタイル用の追加 CSS クラス名 |
注: このコンポーネントは HTML div 要素のすべての props を継承します。
CreateProduct.Actions.SubmitButton
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "送信" | ボタン内に配置するテキスト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
fill | enum | "fill" | ボタンの塗りつぶしスタイル |
icon | enum | undefined | ボタン左側に表示する任意のアイコン |
iconColor | enum | undefined | 左側アイコンの色。指定されない場合は、fill タイプのデフォルト色が使用されます。 |
isDisabled | boolean | false | ボタンが無効で使用できないかどうか |
onClick | function | undefined | ボタンクリックを処理する関数 |
size | enum | "M" | ボタンの縦サイズ |
textAlign | enum | "center" | ボタン内のアイコンとテキストの配置 |
textColor | enum | "default" | ボタンのテキスト色 |
textEmphasis | boolean | false | ボタンのテキストの太さ |
textSize | enum | "M" | ボタンのテキストサイズ |
type | enum | "submit" | ボタンの用途(HTML の type に影響します) |
Note: 注: このコンポーネントは、共通の HTML button 要素 props も追加で継承します。
追加フィールドコンポーネント
このコンポーネントは、カスタムフォームで使用できる追加のフィールドタイプも提供します:
CreateProduct.TextField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | 必須 | フォームデータのフィールド名 |
errorText | string | undefined | 入力のエラーテキスト |
isDisabled | boolean | undefined | 入力が無効かどうか |
isRequired | boolean | undefined | 入力が必須かどうか |
label | string | 必須 | 入力フィールドのラベル |
labelWeight | enum | "regular" | ラベルの太さ |
onOperationClick | () => void | undefined | 操作用 onClick コールバック |
postfixText | string | undefined | コンポーネントの後ろに配置するテキスト |
showPassword | boolean | undefined | パスワードを表示するかどうか |
Note: 注: このコンポーネントは、共通の HTML input 要素 props も追加で継承します。
CreateProduct.TimeField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | 必須 | フォームデータのフィールド名 |
label | string | 必須 | 入力フィールドのラベル |
labelWeight | enum | "regular" | ラベルの太さ |
isRequired | boolean | undefined | 入力が必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
Note: 注: このコンポーネントは、共通の HTML input 要素 props も追加で継承します。
CreateProduct.CheckboxField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | 必須 | フォームデータのフィールド名 |
label | string | Required | チェックボックスのラベル |
message | string | undefined | チェックボックスの説明メッセージ |
showMessage | boolean | true | Whether to show the message |
className | string | undefined | スタイル用の追加 CSS クラス名 |
Note: 注: このコンポーネントは HTML checkbox 要素のすべての props を継承します。
CreateProduct.SelectField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "required" | フォームデータのフィールド名 |
label | string | "必須" | フィールドラベル |
labelWeight | enum | "regular" | ラベルの太さ |
selectOptionValues | Array<{value: string, label: string}> | [] | 選択肢の配列 |
isRequired | boolean | undefined | フィールドが必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイル用の追加 CSS クラス名 |
Note: 注: このコンポーネントは、共通の HTML select 要素 props も追加で継承します。
🔧 TypeScript サポート
包括的な型定義を備えた完全な TypeScript サポート:
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>
);
};
React、TypeScript、そして最新の Web 標準で構築されています。