メインコンテンツまでスキップ

商品編集ブロック

EditProduct は、MUI 上に構築された制御された商品編集フォームブロックで、メディア、商品詳細、在庫、送信アクションのためのネストされたセクションを備えています。

インストール

npm install @nodeblocks/frontend-edit-product-block

必要なもの

項目理由
data制御されたフォーム状態。標準の形には titlecategoryIdtypeIdoptionIdquantitydescriptiondetailsprefecturecityonlineAvailabilityinventoryNotesavailableFromavailableUntiladditionalDetailsimagetags が含まれます。
onDataChange変更されたフィールドパス(meta.name)、最新の値(meta.value)、原因(meta.cause)、任意のイベント(meta.event)に関するメタデータとともに、次のデータスナップショットを受け取ります。
errors (optional)ブラケット記法のパスをキーにしたフィールドレベルのバリデーション。
onRejectAttachment (optional)画像ドロップゾーンから拒否されたアップロードファイルを DropzoneFileError とともに受け取ります。
labels (optional)セクションタイトル、フィールドラベル、ドロップゾーン、送信ボタンの文言です。
placeholders (optional)テキストフィールドとセレクトフィールドのプレースホルダーテキストです。
selectOptions (optional)カテゴリ、種別、オプション、都道府県フィールド用のドロップダウンオプションです。
tagTypes / tags (optional)basic-info セクションのタグピッカーを制御します。
children (optional)複合セクションまたはブロックのオーバーライド関数を使用します。
制御コンポーネント

EditProduct はフォーム状態を所有しません。data はアプリ側で保持し、更新は onDataChange 経由で渡してください。data.imageFile{ url, type?, id? }、または null にでき、data.tagsTag オブジェクトの配列です。

コード例

ライブエディター
function Example() {
  const defaultData = {
    title: '',
    categoryId: '',
    typeId: '',
    optionId: '',
    quantity: '',
    description: '',
    details: '',
    prefecture: '',
    city: '',
    onlineAvailability: false,
    inventoryNotes: '',
    availableFrom: '',
    availableUntil: '',
    additionalDetails: '',
    image: null,
    tags: [],
  };

  const [data, setData] = React.useState(defaultData);

  const selectOptions = {
    categoryOptions: [
      { value: 'electronics', label: 'Electronics' },
      { value: 'clothing', label: 'Clothing' },
      { value: 'home', label: 'Home & Garden' },
    ],
    typeOptions: [
      { value: 'physical', label: 'Physical' },
      { value: 'digital', label: 'Digital' },
      { value: 'service', label: 'Service' },
    ],
    optionOptions: [
      { value: 'standard', label: 'Standard' },
      { value: 'premium', label: 'Premium' },
      { value: 'custom', label: 'Custom' },
    ],
    prefectureOptions: [
      { value: 'Tokyo', label: 'Tokyo' },
      { value: 'Osaka', label: 'Osaka' },
      { value: 'Fukuoka', label: 'Fukuoka' },
    ],
  };

  const tagTypes = [
    { id: '100', label: 'Product highlights' },
    { id: '200', label: 'Materials & care' },
  ];

  const tags = [
    { id: '101', typeId: '100', label: 'Best seller' },
    { id: '102', typeId: '100', label: 'New arrival' },
    { id: '201', typeId: '200', label: 'Organic / natural materials' },
    { id: '202', typeId: '200', label: 'Contains recycled content' },
  ];

  return (
    <EditProduct
      data={data}
      selectOptions={selectOptions}
      tagTypes={tagTypes}
      tags={tags}
      onDataChange={(nextData) => {
        setData(nextData);
      }}
      onSubmit={(e) => {
        e.preventDefault();
      }}
    />
  );
}
結果
Loading...

重要な props

基本 props

Prop必須既定値説明
dataEditProductFormData ({ title, categoryId, typeId, optionId, quantity, description, details, tags, prefecture, city, onlineAvailability, inventoryNotes, availableFrom, availableUntil, additionalDetails, image } or extended Record<string, unknown>)Yes-制御されたフォーム状態。
onDataChange(data: EditProductFormData, meta: { name: string; value: unknown; cause: one of input, change, blur, clear, reset, programmatic; event?: React.SyntheticEvent }) => voidYes-フィールドが変更されるたびに呼び出されます。meta.name はブラケット記法のパスを使います。
errors{ [fieldPath: string]: string | string[] }Noundefined入れ子の配列パスを含む、フィールドパスをキーにしたバリデーションフィードバック。
onRejectAttachment(file: File, error: DropzoneFileError) => voidNoundefinedドロップゾーンがアップロードを拒否したときに呼び出されます。
tagTypesTagType[] ({ id: string; label: string }[])NoundefinedBasicInfo.TagsField で使われるタググループ。
tagsTag[] ({ id: string; typeId?: string; label: string }[])NoundefinedBasicInfo.TagsField で使われる利用可能なタグオプション。

コンテンツ props

Prop必須既定値説明
labels{ mainInfoSectionTitle?: string; titleField?: string; dropzoneDropHere?: string; dropzoneUploadImage?: string; dropzoneSubtitle?: string; dropzoneImageAlt?: string; dropzoneOptionsButton?: string; dropzoneReplaceFile?: string; dropzoneDeleteFile?: string; basicInfoSectionTitle?: string; categoryField?: string; typeField?: string; optionField?: string; quantityField?: string; quantityUnit?: string; descriptionField?: string; detailsField?: string; tagsField?: string; additionalInfoTitle?: string; additionalInfoSubtitle?: string; prefectureField?: string; cityField?: string; onlineAvailabilityField?: string; inventoryNotesField?: string; availableFromField?: string; availableUntilField?: string; additionalDetailsField?: string; submitButton?: string }Noundefinedセクションタイトル、フィールドラベル、ドロップゾーン文言、画像の alt 文言、数量単位の接尾辞、送信ボタンの文言です。
placeholders{ titleField?: string; categoryField?: string; typeField?: string; optionField?: string; quantityField?: string; descriptionField?: string; detailsField?: string; prefectureField?: string; cityField?: string; inventoryNotesField?: string; additionalDetailsField?: string }Noundefinedテキストフィールドとセレクトフィールドのプレースホルダー文言です。
selectOptions{ categoryOptions?: EditProductSelectOption[]; typeOptions?: EditProductSelectOption[]; optionOptions?: EditProductSelectOption[]; prefectureOptions?: EditProductSelectOption[] }Noundefinedセレクトフィールドで使われるドロップダウンオプションです。

レイアウトと構成 props

Prop必須既定値説明
componentStackProps<'form'>['component']No'form'外側の Stack によって描画されるルート要素。
childrenBlocksOverride<typeof defaultEditProductBlocks, CustomBlocks>NoundefinedJSX の複合セクション、または blocksblockOrder を返す関数を使用します。

継承される props は StackProps<'form'> 由来で、children がブロックのオーバーライド API に置き換えられているため、classNamesxidonSubmit などの標準的な form/container props を利用できます。

デフォルト UI ブロック

ブロック基盤備考
EditProductStackレスポンシブな余白と最大幅を持つルート form シェルです。
MainInfoStackアップロードドロップゾーンとタイトルフィールドのセクションです。
MainInfo.DropzoneBox + Menu + MenuItem + react-dropzoneimage 用のファイルアップロード面です。既定の文言には Drop the image here...Upload product imagePNG, JPG up to 2MBOptionsSelect a new fileDelete、alt テキスト Selected が含まれます。
MainInfo.TitleFieldTextField文字数カウンター付きの複数行タイトル入力です。既定のラベルは Title、プレースホルダーは Enter title です。
BasicInfoStackカテゴリ、種別、数量、説明、詳細、タグのための商品詳細セクションです。
BasicInfo.SectionTitleTypography既定値は Basic Information です。
BasicInfo.CategoryFieldSelectFieldcategoryId にバインドされたセレクトフィールドです。既定のラベルは Category、プレースホルダーは Select category です。
BasicInfo.TypeFieldSelectFieldtypeId にバインドされたセレクトフィールドです。既定のラベルは Type、プレースホルダーは Select type です。
BasicInfo.OptionFieldSelectFieldoptionId にバインドされたセレクトフィールドです。既定のラベルは Option、プレースホルダーは Select option です。
BasicInfo.QuantityFieldFormControl + OutlinedInputquantity にバインドされた数量入力で、単位テキスト付きです。既定のラベルは Quantity、プレースホルダーは Enter quantity、単位は pcs です。
BasicInfo.DescriptionFieldTextFielddescription にバインドされた複数行説明フィールドです。既定値は Description / Describe the product です。
BasicInfo.DetailsFieldTextFielddetails にバインドされた複数行詳細フィールドです。既定値は Details / Enter details です。
BasicInfo.TagsFieldFormControl + FormGroup + Checkboxグループ化されたタグのチェックボックスを描画します。tagTypestags が提供されたときだけ描画されます。既定値は Tags です。
AdditionalInfoStack在庫と所在地のセクションです。
AdditionalInfo.TitleTypography既定値は Inventory です。
AdditionalInfo.SubtitleTypography既定値は Location です。
AdditionalInfo.PrefectureFieldSelectFieldprefecture にバインドされたセレクトフィールドです。既定のラベルは Prefecture、プレースホルダーは Select prefecture です。
AdditionalInfo.CityFieldTextFieldcity にバインドされたテキストフィールドです。既定のラベルは City、プレースホルダーは Enter city です。
AdditionalInfo.OnlineAvailabilityFieldFormControlLabel + CheckboxonlineAvailability にバインドされた真偽値チェックボックスです。既定値は Online Availability です。
AdditionalInfo.InventoryNotesFieldTextFieldinventoryNotes にバインドされた複数行メモ欄です。既定値は Inventory Notes / Notes about inventory です。
AdditionalInfo.AvailableFromFieldTimePickeravailableFrom にバインドされた時刻フィールドで、HH:mm として保存されます。既定値は Available From です。
AdditionalInfo.AvailableUntilFieldTimePickeravailableUntil にバインドされた時刻フィールドで、HH:mm として保存されます。既定値は Available Until です。
AdditionalInfo.AdditionalDetailsFieldTextFieldadditionalDetails にバインドされた複数行フィールドです。既定値は Additional Details / Enter additional details です。
ActionsStack + Buttonフォーム下部中央に配置される送信領域です。
Actions.SubmitButtonButtonvariant="contained", size="large", type="submit"、チェックアイコン付きです。既定値は Submit です。

追加のフィールドプリミティブ

プリミティブ主な props継承基盤備考
TextFieldname, label, placeholder, requiredコンテキストの getValuesetValueerrors に加えて TextFieldPropsTextField標準レイアウトで使われる制御されたテキスト入力です。
NumberFieldname, label, placeholder, requiredコンテキストの getValuesetValueerrors に加えて TextFieldPropsTextFieldtype="number"min=0 を持つ数値テキストフィールドです。
SelectFieldname, options, placeholder, labelコンテキストの getValuesetValueerrors に加えて TextFieldPropsTextField値が選択されていないときにプレースホルダーテキストを表示するセレクト入力です。
CheckboxFieldname, labelcontrol が MUI Checkbox に固定された FormControlLabelPropsFormControlLabel + CheckboxOnlineAvailabilityField で使われる制御された真偽値フィールドです。
TimeFieldname, label, required, helperTextコンテキストの getValuesetValueerrors に加えて TimePickerPropsTimePickerDateTime 変換を通じて時刻値を HH:mm 文字列として保存します。

TypeScript

export type EditProductFormData =
| {
title: string;
categoryId: string;
typeId: string;
optionId: string;
quantity: string;
description: string;
details: string;
tags: Tag[];
prefecture: string;
city: string;
onlineAvailability: boolean;
inventoryNotes: string;
availableFrom: string;
availableUntil: string;
additionalDetails: string;
image: { url: string; type?: string; id?: string } | File | null;
}
| Record<string, unknown>;

export interface TagType {
id: string;
label: string;
}

export interface Tag {
id: string;
typeId?: string;
label: string;
}

export type EditProductSelectOption = {
value: string;
label: string;
};