属性選択ブロック
AttributeSelection は、選択した { key, value } 属性を保存するための制御されたチェックボックス選択フォームです。
インストール
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-attribute-selection-block
yarn add @nodeblocks/frontend-attribute-selection-block
pnpm add @nodeblocks/frontend-attribute-selection-block
bun add @nodeblocks/frontend-attribute-selection-block
必要なもの
| 項目 | 理由 |
|---|---|
data | 制御されたフォームデータ。デフォルトの形は { attributes: [] } です |
onDataChange | チェックボックスが変更されるたびに次のデータオブジェクトを受け取ります |
options (optional) | デフォルトの CheckboxList によって描画されるチェックボックスの選択肢 |
labels (optional) | タイトル、サブタイトル、フィールド名、送信ボタンの文言 |
layout (optional) | チェックボックスリストのレイアウト: one-column またはレスポンシブな grid |
onSubmit (optional) | 継承されたフォーム送信ハンドラ |
AttributeSelection は選択状態を保持しません。data をアプリ内に保存し、ブロックへ渡し返し、onDataChange から更新してください。選択された項目は data.attributes に { key, value } のペアとして保存されます。
コード例
- クイックスタート
- ラベルとレイアウト
- コンパウンドコンポーネント
- ブロックのオーバーライド
function Example() { const defaultData = {attributes: []}; const [data, setData] = React.useState(defaultData); const options = [ {key: 'role', value: 'frontend', label: 'Frontend engineer'}, {key: 'role', value: 'backend', label: 'Backend engineer'}, {key: 'role', value: 'fullstack', label: 'Full-stack engineer'}, {key: 'role', value: 'data', label: 'Data engineer'}, ]; const labels = { attributeSelectionTitle: 'Role', subtitle: 'Select the roles that match your profile', fieldName: 'Role options', submitButton: 'Save', }; return ( <AttributeSelection data={data} onDataChange={setData} options={options} labels={labels} layout="grid" onSubmit={event => { event.preventDefault(); setData((current) => ({ ...current })); }} /> ); }
デフォルトの文言をカスタマイズし、チェックボックスリストを one-column と grid レイアウトの間で切り替えます。
function Example() { const defaultData = {attributes: [{key: 'department', value: 'engineering'}]}; const [data, setData] = React.useState(defaultData); return ( <AttributeSelection data={data} onDataChange={setData} layout="one-column" labels={{ attributeSelectionTitle: 'Department', subtitle: 'Choose the departments this user can work with', fieldName: 'Departments', submitButton: 'Continue', }} options={[ {key: 'department', value: 'engineering', label: 'Engineering'}, {key: 'department', value: 'design', label: 'Design'}, {key: 'department', value: 'operations', label: 'Operations'}, ]} onSubmit={event => event.preventDefault()} /> ); }
このブロックには URL props はありません。デフォルトブロックにはルートの labels を使い、独自のレイアウトを組むときは Title、Subtitle、FieldName、SubmitButton に直接 children を渡してください。
カスタムレイアウトや手動のチェックボックスグループが必要なときは、名前付きの子ブロックを使います。
function Example() { const defaultData = {attributes: []}; const [data, setData] = React.useState(defaultData); return ( <AttributeSelection data={data} onDataChange={setData} onSubmit={event => event.preventDefault()} sx={{maxWidth: 560, mx: 'auto'}} > <div style={{display: 'grid', gap: 32}}> <AttributeSelection.Title sx={{textAlign: 'left'}}> Skills </AttributeSelection.Title> <AttributeSelection.Subtitle> Select every skill that applies. </AttributeSelection.Subtitle> <div style={{display: 'grid', gap: 12}}> <AttributeSelection.FieldName>Engineering skills</AttributeSelection.FieldName> <div style={{display: 'grid', gap: 12}}> <AttributeSelection.CheckboxField name="skill" value="react" label="React" /> <AttributeSelection.CheckboxField name="skill" value="typescript" label="TypeScript" /> <AttributeSelection.CheckboxField name="skill" value="testing" label="Testing" /> </div> </div> <AttributeSelection.SubmitButton disabled={!data.attributes.length}> Save skills </AttributeSelection.SubmitButton> </div> </AttributeSelection> ); }
function child を使ってデフォルトブロックを置き換え、デフォルトのフィールド領域内に小さな補助ブロックを追加します。
function Example() { const defaultData = {attributes: []}; const [data, setData] = React.useState(defaultData); return ( <AttributeSelection data={data} onDataChange={setData} labels={{ attributeSelectionTitle: 'Profile attributes', subtitle: 'Pick the attributes that should be saved.', fieldName: 'Attributes', submitButton: 'Save', }} options={[ {key: 'profile', value: 'mentor', label: 'Mentor'}, {key: 'profile', value: 'reviewer', label: 'Reviewer'}, {key: 'profile', value: 'speaker', label: 'Speaker'}, ]} layout="grid" onSubmit={event => event.preventDefault()} > {({defaultBlocks}) => ({ blocks: { ...defaultBlocks, helperText: ( <div style={{fontSize: 13, color: '#666'}}> Selected attributes: {data.attributes.length} </div> ), submitButton: ( <AttributeSelection.SubmitButton disabled={!data.attributes.length}> Save profile </AttributeSelection.SubmitButton> ), }, blockOrder: ['attributeSelectionTitle', 'subtitle', 'fieldName', 'checkboxList', 'helperText', 'submitButton'], })} </AttributeSelection> ); }
ブロックのオーバーライドを使うタイミング
デフォルトのタイトル、チェックボックス一覧、送信ボタンが有用だが、1つのブロックを置き換えたり補助コンテンツを追加したりしたい場合にオーバーライドを使います。defaultBlockOrder は attributeSelectionTitle、subtitle、fieldName、checkboxField、checkboxList、submitButton です。ルートの描画では checkboxField が除外されるため、見えるデフォルトの流れはタイトル、サブタイトル、フィールド名、チェックボックス一覧、最後に送信ボタンです。
重要なプロパティ
コアプロパティ
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
data | AttributeSelectionFormData | はい | - | 制御されたデータオブジェクト: { attributes: { key: string; value: string }[] } |
onDataChange | (data: AttributeSelectionFormData, meta: { name: string; value: unknown; cause: 'input' | 'change' | 'blur' | 'clear' | 'reset' | 'programmatic'; event?: SyntheticEvent }) => void | はい | - | 選択が変更されたときに呼び出されます。CheckboxField は cause: 'change' と name: 'attributes' を使います |
options | AttributeSelectionOption[] | いいえ | undefined | CheckboxList によって描画されるオプション。各オプションは { key, value, label } です |
errors | { [fieldName: string]: string | string[] } | いいえ | undefined | カスタムブロック用にコンテキストへ保存されます。デフォルト UI ブロックはエラーを描画しません |
layout | 'one-column' | 'grid' | いいえ | 'one-column' | CheckboxList のレイアウトを制御します |
コンテンツプロパティ
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
labels | { attributeSelectionTitle?: ReactNode; subtitle?: ReactNode; fieldName?: ReactNode; submitButton?: ReactNode } | いいえ | undefined | デフォルトのタイトル、サブタイトル、フィールド名、送信ボタンで使われる文言 |
labels.attributeSelectionTitle | ReactNode | いいえ | undefined | AttributeSelection.Title によって描画されるタイトルテキスト |
labels.subtitle | ReactNode | いいえ | undefined | AttributeSelection.Subtitle によって描画されるサブタイトルテキスト |
labels.fieldName | ReactNode | いいえ | undefined | チェックボックス一覧の上に描画されるフィールドラベル |
labels.submitButton | ReactNode | いいえ | '保存' | children が渡されない場合の送信ボタンのコンテンツ |
サブコンポーネント:
| サブコンポーネント | 主な props | 継承元 | 基盤 |
|---|---|---|---|
AttributeSelection.Title | children、labels.attributeSelectionTitle | TypographyProps | Typography |
AttributeSelection.Subtitle | children、labels.subtitle | TypographyProps | Typography |
AttributeSelection.FieldName | children、labels.fieldName | TypographyProps | Typography |
AttributeSelection.CheckboxList | options、layout、children | StackProps | Stack |
AttributeSelection.SubmitButton | children、labels.submitButton | ButtonProps | Button |
レイアウトと構成のプロパティ
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
children | BlocksOverride | ReactNode | いいえ | undefined | コンパウンド子要素、または blocks と blockOrder を返す関数オーバーライド |
className | string | いいえ | undefined | ルートフォームのクラス名(nbb-attribute-selection が適用されます) |
sx | SxProps | いいえ | undefined | ルートフォーム用の MUI システムスタイル |
onSubmit | FormEventHandler | いいえ | undefined | 継承されたフォーム送信ハンドラ |
AttributeSelection は children を除く StackProps を継承します。ルートは component="form" として描画され、コンテキスト外の Stack/form props を引き渡します。
デフォルト UI ブロック
| ブロック | 基盤 | 備考 |
|---|---|---|
AttributeSelection(ルート) | Stack | component="form" のルートフォーム |
AttributeSelection.Title | Typography | labels.attributeSelectionTitle を使用します。組み込みのフォールバックテキストはありません |
AttributeSelection.Subtitle | Typography | labels.subtitle を使用します。組み込みのフォールバックテキストはありません |
AttributeSelection.FieldName | Typography | labels.fieldName を使用します。組み込みのフォールバックテキストはありません |
AttributeSelection.CheckboxList | Stack | options をチェックボックスに変換します。layout="grid" はレスポンシブな 2/3/4 列グリッドを使います |
AttributeSelection.SubmitButton | Button | variant="contained"、size="large"、fullWidth、type="submit"、デフォルトテキストは '保存' |
追加フィールドプリミティブ
| プリミティブ | 基盤 | 備考 |
|---|---|---|
AttributeSelection.CheckboxField | FormControlLabel + Checkbox | カスタムフロー用の手動チェックボックスプリミティブ。name、value、label を渡します。切り替えると data.attributes に { key: name, value } が追加・削除されます。デフォルトの control は sx={{ p: 0 }} の MUI チェックボックスです |
TypeScript
import {
AttributeSelection,
type AttributeSelectionFormData,
type AttributeSelectionOption,
} from '@nodeblocks/frontend-attribute-selection-block';
const options: AttributeSelectionOption[] = [
{key: 'role', value: 'frontend', label: 'Frontend engineer'},
{key: 'role', value: 'backend', label: 'Backend engineer'},
];
const [data, setData] = React.useState<AttributeSelectionFormData>({
attributes: [],
});
<AttributeSelection
data={data}
onDataChange={setData}
options={options}
labels={{attributeSelectionTitle: 'Role', fieldName: 'Roles', submitButton: 'Save'}}
/>;