基本情報編集ブロック
EditBasicInformation は、MUI 上に構築された制御された住所・プロフィールフォームブロックです。
インストール
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-edit-basic-information-block
yarn add @nodeblocks/frontend-edit-basic-information-block
pnpm add @nodeblocks/frontend-edit-basic-information-block
bun add @nodeblocks/frontend-edit-basic-information-block
必要なもの
| 項目 | 理由 |
|---|---|
data | 制御されたフォーム状態。既定の形では NameInput、FuriganaInput、PostalCodeInput、PrefectureSelect、CityInput、AddressInput、PhoneInput を使います。 |
onDataChange | 変更されたフィールドパスに関するメタデータとともに、次のデータスナップショットを受け取ります。 |
errors (optional) | フィールドパスをキーにしたフィールドレベルのバリデーションフィードバック。 |
labels (optional) | タイトル、サブタイトル、入力ラベル、検索ボタン、送信ボタンの文言です。 |
placeholders (optional) | テキスト入力と都道府県セレクトのプレースホルダーテキストです。 |
selectOptions (optional) | 都道府県セレクト用のカスタムオプション一覧です。 |
onSearchAddressClick (optional) | 郵便番号による住所検索ボタンを処理します。 |
blockSpacingBefore (optional) | 特定のデフォルトブロックまたはオーバーライドブロックの前の余白を調整します。 |
children (optional) | 複合コンポーネントまたはブロックのオーバーライド描画を使用します。 |
制御コンポーネント
EditBasicInformation はフォーム状態を所有しません。data はアプリ側で保持し、更新は onDataChange 経由で渡してください。標準の形は Storybook で使われている名前付きフィールドのオブジェクトで、後でネストしたバリデーションが必要な場合は FieldErrorMap がブラケット記法のパスを使います。
コード例
- クイックスタート
- ラベルと文言
- フォームエラー
- 複合コンポーネント
- ブロックのオーバーライド
ライブエディター
function Example() { const defaultData = { NameInput: '山田太郎', FuriganaInput: 'ヤマダタロウ', PostalCodeInput: '1234567', PrefectureSelect: '東京都', CityInput: '市区町村を入力', AddressInput: '町名・番地・建物を入力', PhoneInput: '電話番号を入力(ハイフンなしで入力)', }; const [data, setData] = React.useState(defaultData); return ( <EditBasicInformation data={data} onDataChange={(nextData) => { setData(nextData); }} onSearchAddressClick={() => { setData((current) => ({ ...current })); }} /> ); }
結果
Loading...
ライブエディター
function Example() { const defaultData = { NameInput: '山田太郎', FuriganaInput: 'ヤマダタロウ', PostalCodeInput: '1234567', PrefectureSelect: '東京都', CityInput: '市区町村を入力', AddressInput: '町名・番地・建物を入力', PhoneInput: '電話番号を入力(ハイフンなしで入力)', }; const [data, setData] = React.useState(defaultData); const labels = { title: 'Basic information', subtitle: 'Fields marked * are required.', nameInput: 'Full name', furiganaInput: 'Full name in kana', postalCodeInput: 'Postal code', searchAddressButton: 'Look up address', prefectureSelect: 'Prefecture', cityInput: 'City', addressInput: 'Street address', phoneInput: 'Phone number', submitButton: 'Save', }; const placeholders = { nameInput: 'Enter your full name', furiganaInput: 'Enter furigana', postalCodeInput: '1234567', prefectureSelect: 'Select a prefecture', cityInput: 'Enter city', addressInput: 'Enter street address', phoneInput: 'Enter phone number', }; const selectOptions = { prefectureSelect: [ { value: '東京都', label: '東京都' }, { value: '大阪府', label: '大阪府' }, { value: '福岡県', label: '福岡県' }, ], }; return ( <EditBasicInformation data={data} onDataChange={(nextData) => { setData(nextData); }} labels={labels} placeholders={placeholders} selectOptions={selectOptions} onSearchAddressClick={() => { setData((current) => ({ ...current })); }} /> ); }
結果
Loading...
ラベルと文言
このブロックには URL props はありません。テキストの上書きはルートの labels と placeholders に置くか、カスタムのレイアウトや文言が必要なら個別のサブコンポーネントをオーバーライドしてください。
ライブエディター
function Example() { const defaultData = { NameInput: '', FuriganaInput: '', PostalCodeInput: '', PrefectureSelect: '', CityInput: '', AddressInput: '', PhoneInput: '', }; const [data, setData] = React.useState(defaultData); const [errors, setErrors] = React.useState({}); const handleDataChange = (nextData, meta) => { const { [meta.name]: _removed, ...restErrors } = errors; let nextErrors = restErrors; // Validate required fields on blur (same pattern as storybook) if (meta.cause === 'blur') { nextErrors = { ...restErrors }; const value = nextData[meta.name]; if (value === '' || (typeof value === 'string' && !value.trim())) { nextErrors[meta.name] = 'This field is required.'; } } setErrors(nextErrors); setData(nextData); }; return ( <EditBasicInformation data={data} errors={Object.keys(errors).length ? errors : undefined} onDataChange={handleDataChange} onSearchAddressClick={() => { setData((current) => ({ ...current })); }} /> ); }
結果
Loading...
ライブエディター
function Example() { const defaultData = { NameInput: '山田太郎', FuriganaInput: 'ヤマダタロウ', PostalCodeInput: '1234567', PrefectureSelect: '東京都', CityInput: '市区町村を入力', AddressInput: '町名・番地・建物を入力', PhoneInput: '電話番号を入力(ハイフンなしで入力)', }; const [data, setData] = React.useState(defaultData); return ( <EditBasicInformation data={data} onDataChange={(nextData) => { setData(nextData); }} labels={{ searchAddressButton: '住所を検索' }} onSearchAddressClick={() => { setData((current) => ({ ...current })); }} > <EditBasicInformation.Title>Basic information</EditBasicInformation.Title> <Stack spacing={3}> <EditBasicInformation.Subtitle>Fields marked * are required.</EditBasicInformation.Subtitle> <EditBasicInformation.NameInput required={false} /> <EditBasicInformation.FuriganaInput required={false} /> <EditBasicInformation.PostalCodeInput required={false} /> <EditBasicInformation.PrefectureSelect required={false} /> <EditBasicInformation.CityInput required={false} /> <EditBasicInformation.AddressInput required={false} /> <EditBasicInformation.PhoneInput required={false} /> </Stack> <EditBasicInformation.SubmitButton>Save</EditBasicInformation.SubmitButton> </EditBasicInformation> ); }
結果
Loading...
ライブエディター
function Example() { const defaultData = { NameInput: '山田太郎', FuriganaInput: 'ヤマダタロウ', PostalCodeInput: '1234567', PrefectureSelect: '東京都', CityInput: '市区町村を入力', AddressInput: '町名・番地・建物を入力', PhoneInput: '電話番号を入力(ハイフンなしで入力)', }; const [data, setData] = React.useState(defaultData); return ( <EditBasicInformation data={data} onDataChange={(nextData) => { setData(nextData); }} onSearchAddressClick={() => { setData((current) => ({ ...current })); }} > {({ defaultBlocks, defaultBlockOrder }) => ({ blocks: { ...defaultBlocks, customBlock: <Alert severity="info">Custom notification</Alert>, }, blockOrder: ['customBlock', ...defaultBlockOrder], })} </EditBasicInformation> ); }
結果
Loading...
ブロックのオーバーライドに関する注意
defaultBlockOrder には、タイトル、サブタイトル、入力欄、送信ボタンの標準レイアウト順が含まれています。ルートレンダラーには defaultBlocks に内部の input プリミティブも含まれますが、表示される既定順からは除外されています。blockSpacingBefore はデフォルトブロックと関数ベースのオーバーライドに適用されますが、素の JSX の複合子要素には適用されません。
重要な props
基本 props
| Prop | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
data | EditBasicInformationFormData | Yes | - | 制御されたフォーム状態。既定のストーリー形状は、上に列挙した名前付きフィールドを使います。 |
onDataChange | (data: EditBasicInformationFormData, meta: { name: string; value: unknown; cause: one of input, change, blur, clear, reset, programmatic; event?: React.SyntheticEvent }) => void | Yes | - | フィールドが更新されるたびに呼び出されます。meta.name はブラケット記法のパスを使います。 |
errors | { [fieldPath: string]: string | string[] } | No | undefined | フィールドパスをキーにしたバリデーションフィードバック。 |
onSearchAddressClick | MouseEventHandler<HTMLButtonElement> | No | undefined | 指定すると、郵便番号検索アクションとして表示されます。 |
コンテンツ props
| Prop | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
labels | { title?: string; subtitle?: string; nameInput?: string; furiganaInput?: string; postalCodeInput?: string; searchAddressButton?: string; prefectureSelect?: string; cityInput?: string; addressInput?: string; phoneInput?: string; submitButton?: string } | No | undefined | タイトル、補助テキスト、入力ラベル、検索ボタン、送信ボタンの文言。 |
placeholders | { nameInput?: string; furiganaInput?: string; postalCodeInput?: string; prefectureSelect?: string; cityInput?: string; addressInput?: string; phoneInput?: string } | No | undefined | テキストフィールドと都道府県セレクトのプレースホルダー文言。 |
selectOptions | { prefectureSelect?: { value: string; label: string }[] } | No | undefined | 都道府県セレクト用のカスタムオプション。 |
レイアウトと構成 props
| Prop | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
component | StackProps<'form'>['component'] | No | 'form' | 外側の Stack によって描画されるルート要素。 |
blockSpacingBefore | Partial<Record<string, number | Partial<Record<'xs' | 'sm' | 'md' | 'lg' | 'xl', number>>>> | No | { subtitle: 4, nameInput: { xs: 4, sm: 3 }, submitButton: 4 } | 名前付きデフォルトブロックまたは関数ベースのオーバーライドブロックの前に追加する余白。 |
children | BlocksOverride<typeof defaultBlocks, CustomBlocks> | No | undefined | JSX の複合コンポーネント、または blocks と blockOrder を返す関数を使用します。 |
継承される props は StackProps<'form'> 由来で、children がブロックのオーバーライド API に置き換えられているため、className、sx、id などの標準的な form/container props を利用できます。
デフォルト UI ブロック
| ブロック | 基盤 | 備考 |
|---|---|---|
EditBasicInformation | Stack | パディングとレスポンシブレイアウトを備えたルート form シェルです。 |
Title | Typography | variant="h4", component="h2", 太字で中央揃え。既定値は 基本情報を編集 です。 |
Subtitle | Typography | variant="body2"。既定値は * は必須事項です です。 |
NameInput | TextField | 既定のラベルは 氏名、プレースホルダーは 氏名を入力 です。 |
FuriganaInput | TextField | 既定のラベルは フリガナ、プレースホルダーは フリガナを入力 です。 |
PostalCodeInput | TextField + Button | 既定のラベルは 郵便番号、プレースホルダーは 郵便番号を入力、検索ボタンは 住所を検索 です。 |
PrefectureSelect | FormControl + InputLabel + Select | 既定のラベルは 都道府県、プレースホルダーは 都道府県を選択、組み込みの都道府県オプションを使います。 |
CityInput | TextField | 既定のラベルは 市区町村、プレースホルダーは 市区町村を入力 です。 |
AddressInput | TextField | 既定のラベルは 町名・番地・建物、プレースホルダーは 町名・番地・建物を入力 です。 |
PhoneInput | TextField | 既定のラベルは 連絡先電話番号、プレースホルダーは 電話番号を入力(ハイフンなしで入力) です。 |
SubmitButton | Button | variant="contained", size="large", type="submit"、中央揃えでデスクトップでは広めの幅になります。既定値は 保存 です。 |
追加のフィールドプリミティブ
| プリミティブ | 主な props | 継承 | 基盤 | 備考 |
|---|---|---|---|---|
Input | name, label, placeholder, required | TextFieldProps plus getValue, setValue, and errors from context | TextField | 標準レイアウトで使われる制御されたテキストフィールドのプリミティブです。カスタムフローでは利用できますが、既定のブロック順では直接描画されません。 |
TypeScript
type EditBasicInformationFormData =
| {
NameInput: string;
FuriganaInput: string;
PostalCodeInput: string;
PrefectureSelect: string;
CityInput: string;
AddressInput: string;
PhoneInput: string;
}
| Record<string, unknown>;