商品作成ブロック
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: '電子機器' },
{ value: 'clothing', label: '衣類' },
{ value: 'home', label: 'ホーム・ガーデン' }
];
return (
<CreateProduct
categoryOptions={categoryOptions}
onSubmit={(formData) => {
console.log('商品が作成されました:', formData);
}}
onChange={(setError, getValues, clearErrors) => {
const values = getValues();
console.log('フォーム値:', values);
}}
onAcceptAttachment={(files) => {
console.log('ファイルが承認されました:', files);
}}
onUploadAttachment={(file) => {
console.log('ファイルをアップロード中:', file);
// ファイルアップロードロジックを処理
}}
onClearAttachment={() => {
console.log('添付ファイルがクリアされました');
}}>
<CreateProduct.MainInfo>
<CreateProduct.MainInfo.SectionTitle>商品情報</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>商品を作成</CreateProduct.Actions.SubmitButton>
</CreateProduct.Actions>
</CreateProduct>
);
}
function AdvancedCreateProduct() {
const categoryOptions = [
{ value: 'electronics', label: '電子機器' },
{ value: 'clothing', label: '衣類' },
{ value: 'home', label: 'ホーム・ガーデン' },
{ value: 'sports', label: 'スポーツ・アウトドア' },
{ value: 'automotive', label: '自動車' }
];
return (
<CreateProduct
categoryOptions={categoryOptions}
onSubmit={(formData) => {
console.log('高度な商品が作成されました:', formData);
}}
onChange={(setError, getValues, clearErrors) => {
const values = getValues();
console.log('フォーム検証:', values);
}}
onAcceptAttachment={(files) => {
console.log('ファイルが承認されました:', files);
}}
onUploadAttachment={(file) => {
console.log('アップロード中:', file);
}}
onClearAttachment={() => {
console.log('添付ファイルがクリアされました');
}}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
// カスタムスタイリングでメイン情報セクションをオーバーライド
mainInfo: {
...defaultBlocks.mainInfo,
props: {
...defaultBlocks.mainInfo.props,
style: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
borderRadius: '16px',
padding: '32px',
color: 'white',
marginBottom: '24px'
}
}
},
// 強化されたスタイリングで基本情報セクションをオーバーライド
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)'
}
}
},
// 追加情報セクションの完全オーバーライド
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'
}}>
📍 商品位置詳細
</h3>
<p style={{
fontSize: '14px',
marginBottom: '24px',
opacity: 0.9
}}>
商品の所在地を指定して、視認性を向上させましょう
</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>
{/* カスタム追加フィールド */}
<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座標(任意)"
placeholder="例: 35.6762, 139.6503"
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
</div>
</div>
),
// 強化されたアクションセクション
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: '💎 プレミアム商品' },
{ value: 'limited', label: '⭐ 限定版' },
{ value: 'exclusive', label: '🔥 限定アイテム' }
];
return (
<CreateProduct
categoryOptions={categoryOptions}
onSubmit={(formData) => {
console.log('カスタム商品が作成されました:', formData);
}}
onChange={(setError, getValues, clearErrors) => {
console.log('カスタムフォーム検証:', getValues());
}}
onAcceptAttachment={(files) => {
console.log('カスタムファイル処理:', files);
}}
onUploadAttachment={(file) => {
console.log('カスタムアップロード:', file);
}}
onClearAttachment={() => {
console.log('カスタムクリア');
}}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
// メイン情報の完全オーバーライド
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'
}}>
🚀 商品ショーケース
</h2>
<p style={{ fontSize: '16px', marginBottom: '32px', opacity: 0.9 }}>
群衆から際立つ素晴らしい商品リストを作成しましょう
</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="📸 画像をアップロード"
beforeUploadSubtitle="ドラッグ&ドロップまたはクリックして選択"
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="✨ 商品名"
placeholder="素晴らしい商品名を入力してください..."
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333',
marginBottom: '20px'
}}
/>
<CreateProduct.TextField
name="subtitle"
label="📝 商品サブタイトル"
placeholder="商品を説明するキャッチーなサブタイトル"
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
</div>
</div>
</div>
),
// 商品機能付きで強化された基本情報
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'
}}>
📋 商品詳細
</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="商品の特徴、利点、そして何がそれを特別にするかを説明してください..."
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="💰 価格"
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="🔍 状態"
selectOptionValues={[
{ value: 'new', label: '新品' },
{ value: 'excellent', label: '優良' },
{ value: 'good', label: '良好' },
{ value: 'fair', label: '普通' }
]}
style={{
background: 'rgba(255,255,255,0.9)',
borderRadius: '8px',
color: '#333'
}}
/>
</div>
</div>
</div>
</div>
),
// 強化された追加情報を維持
additionalInfo: defaultBlocks.additionalInfo,
// 強化されたアクションボタン
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)';
}}
>
💾 下書き保存
</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'
}}
>
🚀 商品を公開
</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)';
}}
>
👁️ プレビュー
</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 要素プロパティを継承します。
サブコンポーネント
CreateProductコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
CreateProduct.MainInfo
画像アップロードと商品名を含むメイン商品情報のコンテナ。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | undefined | デフォルトメイン情報フィールドをオーバーライドするカスタムコンテンツ |
direction | enum | "column" | アクションボタンのフレックス方向 |
alignItems | enum | "stretch" | コンテナ内のアイテムの整列 |
gapSize | enum | "S" | コンテナ内のアイテム間のギャップ |
CreateProduct.MainInfo.SectionTitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Main Info" | メイン情報セクションのタイトルコンテンツ |
size | enum | "L" | タイトルのタイポグラフィサイズ |
type | enum | "heading" | タイポグラフィタイプ |
color | enum | "low-emphasis" | タイトルのカラーテーマ |
weight | enum | "bold" | タイポグラフィの太さ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
CreateProduct.MainInfo.Dropzone
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
beforeUploadMessage | string | "Upload" | ファイルアップロード前に表示されるメッセージ |
beforeUploadSubtitle | string | "Select a file to upload." | ファイルアップロード前に表示されるサブタイトル |
afterUploadOptionsButton | string | "Options" | アップロード後のオプションボタンのテキスト |
replaceFileButton | string | "Select a new file" | ファイル置換ボタンのテキスト |
deleteFileButton | string | "Delete" | ファイル削除ボタンのテキスト |
maxFiles | number | 1 | 許可される最大ファイル数 |
accept | string | "image/*" | 受け入れるファイルタイプ |
maxSize | number | 5242880 | 最大ファイルサイズ(バイト単位、5MB) |
className | string | undefined | スタイリング用の追加CSSクラス名 |
CreateProduct.MainInfo.NameField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "name" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Name" | 入力の上に表示されるフィールドラベル |
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 | パスワードを表示するかどうか |
注意: このコンポーネントは追加で一般的なHTML input 要素プロパティを継承します。
CreateProduct.BasicInfo
カテゴリと説明を含む基本商品情報のコンテナ。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | BlocksOverride | undefined | デフォルト基本情報フィールドをオーバーライドするカスタムコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
direction | enum | "column" | アクションボタンのフレックス方向 |
alignItems | enum | "stretch" | コンテナ内のアイテムの整列 |
gapSize | enum | "S" | コンテナ内のアイテム間のギャップ |
CreateProduct.BasicInfo.Title
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Basic Information" | 基本情報セクションのタイトルコンテンツ |
size | enum | "L" | タイトルのタイポグラフィサイズ |
type | enum | "heading" | タイポグラフィタイプ |
color | enum | "low-emphasis" | タイトルのカラーテーマ |
weight | enum | "bold" | タイポグラフィの太さ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
CreateProduct.BasicInfo.CategoryField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "categoryId" | フォームデータのフィールド名 |
label | string | "Categories" | フィールドラベル |
labelWeight | enum | "regular" | ラベルの太さ |
selectOptionValues | Array<{value: string, label: string}> | [] | カテゴリオプションの配列 |
isRequired | boolean | undefined | フィールドが必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントは追加で一般的なHTML select 要素プロパティを継承します。
CreateProduct.BasicInfo.DescriptionField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "description" | フォームデータのフィールド名 |
label | string | "Description" | 入力フィールドのラベル |
errorText | string | undefined | 入力のエラーテキスト |
isDisabled | boolean | undefined | 入力が無効かどうか |
isRequired | boolean | undefined | 入力が必須かどうか |
labelWeight | enum | undefined | ラベルの太さ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントは追加で一般的なHTML textarea 要素プロパティを継承します。
CreateProduct.AdditionalInfo
位置詳細を含む追加商品情報のコンテナ。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | BlocksOverride | undefined | デフォルト追加情報フィールドをオーバーライドするカスタムコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
direction | enum | "column" | アクションボタンのフレックス方向 |
alignItems | enum | "stretch" | コンテナ内のアイテムの整列 |
gapSize | enum | "S" | コンテナ内のアイテム間のギャップ |
CreateProduct.AdditionalInfo.Title
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Additional Information" | 追加情報セクションのタイトルコンテンツ |
size | enum | "L" | タイトルのタイポグラフィサイズ |
type | enum | "heading" | タイポグラフィタイプ |
color | enum | "low-emphasis" | タイトルのカラーテーマ |
weight | enum | "bold" | タイポグラフィの太さ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
CreateProduct.AdditionalInfo.Subtitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Location" | 位置セクションのサブタイトルコンテンツ |
size | enum | "S" | タイトルのタイポグラフィサイズ |
type | enum | "heading" | タイポグラフィタイプ |
color | enum | "low-emphasis" | タイトルのカラーテーマ |
weight | enum | "regular" | タイポグラフィの太さ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
CreateProduct.AdditionalInfo.Address1Field
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "address1" | フォームデータのフィールド名 |
label | string | "Prefecture" | フィールドラベル |
labelWeight | enum | "regular" | ラベルの太さ |
selectOptionValues | Array<{value: string, label: string}> | [] | 都道府県オプションの配列 |
isRequired | boolean | undefined | フィールドが必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはすべてのHTML select 要素プロパティを継承します。
CreateProduct.AdditionalInfo.Address2Field
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "address2" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Town" | 入力の上に表示されるフィールドラベル |
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 | パスワードを表示するかどうか |
注意: このコンポーネントは追加で一般的なHTML input 要素プロパティを継承します。
CreateProduct.Actions
フォームアクションボタンのコンテナ。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | BlocksOverride | undefined | デフォルトアクションボタンをオーバーライドするカスタムコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはすべてのHTML div 要素プロパティを継承します。
CreateProduct.Actions.SubmitButton
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Submit" | ボタン内に配置するテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
fill | enum | "fill" | ボタンフィルスタイル |
icon | enum | undefined | ボタン左側のオプションアイコン |
iconColor | enum | undefined | 左側アイコンの色。提供されない場合、フィルタイプのデフォルト色が使用されます。 |
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タイプに影響) |
注意: このコンポーネントは追加で一般的なHTML button 要素プロパティを継承します。
追加フィールドコンポーネント
コンポーネントは、カスタムフォームで使用できる追加のフィールドタイプも提供します:
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 | パスワードを表示するかどうか |
注意: このコンポーネントは追加で一般的なHTML input 要素プロパティを継承します。
CreateProduct.TimeField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | 必須 | フォームデータのフィールド名 |
label | string | 必須 | 入力フィールドのラベル |
labelWeight | enum | "regular" | ラベルの太さ |
isRequired | boolean | undefined | 入力が必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントは追加で一般的なHTML input 要素プロパティを継承します。
CreateProduct.CheckboxField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | 必須 | フォームデータのフィールド名 |
label | string | 必須 | チェックボックスラベル |
message | string | undefined | チェックボックス説明メッセージ |
showMessage | boolean | true | メッセージを表示するかどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはすべてのHTML checkbox 要素プロパティを継承します。
CreateProduct.SelectField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "required" | フォームデータのフィールド名 |
label | string | "Required" | フィールドラベル |
labelWeight | enum | "regular" | ラベルの太さ |
selectOptionValues | Array<{value: string, label: string}> | [] | オプションの配列 |
isRequired | boolean | undefined | フィールドが必須かどうか |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントは追加で一般的なHTML select 要素プロパティを継承します。
🔧 TypeScript サポート
包括的な型定義による完全なTypeScriptサポート:
import {CreateProduct} from '@nodeblocks/frontend-create-product-block';
//将来的にはreact-hook-formを使用せず、独自のフォーム処理を使用します
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) => {
// 型安全なフォーム処理
console.log('商品データ:', data);
console.log('イベント:', event);
};
const handleChange = (
setError: UseFormSetError<CustomProductFormData>,
getValues: UseFormGetValues<CustomProductFormData>,
clearErrors: UseFormClearErrors<CustomProductFormData>,
) => {
const values = getValues();
// フォーム値をバリデーションし、必要に応じてエラーを設定
if (!values.name) {
setError('name', {message: '商品名は必須です'});
} else {
clearErrors('name');
}
};
const categoryOptions = [
{value: 'electronics', label: '電子機器'},
{value: 'clothing', label: '衣類'},
{value: 'home', label: 'ホーム・ガーデン'},
];
const CreateProductForm = () => {
return (
<CreateProduct<CustomProductFormData>
onSubmit={handleSubmit}
onChange={handleChange}
categoryOptions={categoryOptions}
onAcceptAttachment={files => console.log('ファイルが承認されました:', files)}
onUploadAttachment={file => console.log('アップロード中:', file)}
onClearAttachment={() => console.log('添付ファイルがクリアされました')}>
<CreateProduct.MainInfo>
<CreateProduct.MainInfo.SectionTitle>商品詳細</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>商品を作成</CreateProduct.Actions.SubmitButton>
</CreateProduct.Actions>
</CreateProduct>
);
};
React、TypeScript、モダンなウェブ標準を使用して❤️で構築されました。