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

属性選択ブロック

AttributeSelectionコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルな属性選択フォームです。フォームバリデーション、エラーハンドリング、モダンなデザインパターンを備えた属性選択のための完全なインターフェースを提供します。


🚀 インストール

npm install @nodeblocks/frontend-attribute-selection-block@0.2.0

📖 使用法

import {AttributeSelection} from '@nodeblocks/frontend-attribute-selection-block';
ライブエディター

function BasicAttributeSelection() {
  const [submittedData, setSubmittedData] = useState(null);

  const handleSubmit = (data) => {
    console.log('フォームが送信されました:', data);
    setSubmittedData(data);
  };

  const handleCancel = (reset) => {
    console.log('フォームがキャンセルされました');
    reset();
    setSubmittedData(null);
  };

  const handleChange = (_setError, getValues) => {
    console.log('フォームが変更されました:', getValues());
  };

  return (
    <div>
      <AttributeSelection
        onSubmit={handleSubmit}
        onCancel={handleCancel}
        onChange={handleChange}
        defaultValues={{admin: false, editor: true, viewer: false}}
      >
        <AttributeSelection.Title>ユーザーロールを選択</AttributeSelection.Title>
        <AttributeSelection.Subtitle>割り当てるロールを選択してください</AttributeSelection.Subtitle>
        <AttributeSelection.FieldName>ロール</AttributeSelection.FieldName>
        <AttributeSelection.Checkbox name="admin" label="管理者" value="admin" />
        <AttributeSelection.Checkbox name="editor" label="編集者" value="editor" />
        <AttributeSelection.Checkbox name="viewer" label="閲覧者" value="viewer" />
        <AttributeSelection.SubmitButton>ロールを保存</AttributeSelection.SubmitButton>
        <AttributeSelection.CancelButton>キャンセル</AttributeSelection.CancelButton>
      </AttributeSelection>

      {submittedData && (
        <div style={{marginTop: '16px', padding: '12px', background: '#f0f0f0', borderRadius: '8px'}}>
          <strong>送信されたデータ:</strong>
          <pre>{JSON.stringify(submittedData, null, 2)}</pre>
        </div>
      )}
    </div>
  );
}
結果
Loading...

🔧 プロパティリファレンス

メインコンポーネントのプロパティ

コンポーネントは2つの型パラメータを受け入れます: AttributeSelection<T, B> ここで:

  • T - フォームデータ型(インデックスシグネチャを持つ Record<string, unknown> を拡張する必要があります)
  • B - ブロック型(シンプルな使用の場合は Record<string, never>、ブロックオーバーライドの場合は Record<string, ReactNode>
PropTypeDefaultDescription
onSubmit(data: T) => voidRequiredCallback function triggered when form is submitted with valid data
onChange(setError: UseFormSetError<T>, getValues: UseFormGetValues<T>) => voidRequiredCallback function triggered when form values change
onCancel(reset: UseFormReset<T>) => voidRequiredCallback function triggered when cancel button is clicked
defaultValuesDefaultValues<T>undefinedDefault form values to populate fields on initial render
classNamestringundefinedAdditional CSS class name for styling the form container
childrenBlocksOverrideundefinedCustom blocks override for form components

注意: メインコンポーネントはMUI StackProps を拡張し、component="form" を使用してフォーム要素としてレンダリングします。デフォルトスタイリングにはStackレイアウトが含まれます。

サブコンポーネント

AttributeSelectionコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。

AttributeSelection.Title

プロパティデフォルト説明
childrenReactNode"職種"フォームヘッダーのタイトルテキストコンテンツ
variantTypographyProps['variant']"h4"MUI Typographyバリアント
componentElementType"h2"レンダリングするHTML要素
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Typography プロパティを継承します。デフォルトスタイリングには textAlign: 'center' が含まれます。

AttributeSelection.Subtitle

プロパティデフォルト説明
childrenReactNode"ご自身の職種を選択してください"フォーム説明を提供するサブタイトルテキストコンテンツ
variantTypographyProps['variant']"body2"MUI Typographyバリアント
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Typography プロパティを継承します。デフォルトスタイリングには fontWeight: 600 が含まれます。

AttributeSelection.FieldName

プロパティデフォルト説明
childrenReactNode"役割"フォーム入力の上に表示されるフィールド名テキストコンテンツ
variantTypographyProps['variant']"body2"MUI Typographyバリアント
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Typography プロパティを継承します。デフォルトスタイリングには fontWeight: 600 が含まれます。

AttributeSelection.Checkbox

プロパティデフォルト説明
namestring""フォームデータとバリデーションに使用されるフィールド名
labelstring""チェックボックスの横に表示されるラベルテキスト
valuestring""チェックボックスオプションの値識別子
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI FormControlLabel プロパティを継承します。フォーム統合には react-hook-form Controllerを使用します。デフォルトスタイリングには角丸の境界線付きコンテナが含まれます。デフォルトのチェック状態は、メインコンポーネントの defaultValues プロパティで制御されます。

AttributeSelection.SubmitButton

プロパティデフォルト説明
childrenReactNode"次へ"ボタンテキストコンテンツ
variantButtonProps['variant']"contained"MUI Buttonバリアント
sizeButtonProps['size']"large"MUI Buttonサイズ
fullWidthbooleantrueボタンが全幅に広がるかどうか
type"submit" | "button" | "reset""submit"HTMLボタンタイプ
disabledboolean!formState.isValidフォームが無効なときに無効化
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Button プロパティを継承します。フォームバリデーションが失敗すると自動的に無効化されます。

AttributeSelection.CancelButton

プロパティデフォルト説明
childrenReactNode"戻る"ボタンテキストコンテンツ
variantButtonProps['variant']"outlined"MUI Buttonバリアント
sizeButtonProps['size']"large"MUI Buttonサイズ
fullWidthbooleantrueボタンが全幅に広がるかどうか
type"submit" | "button" | "reset""button"HTMLボタンタイプ
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Button プロパティを継承します(onClick を除く)。クリック時に onCancel(reset) を呼び出します。


🎨 設定例

カスタムタイトルスタイリング

<AttributeSelection.Title 
variant="h3"
sx={{
color: 'primary.main',
fontWeight: 700,
textAlign: 'left'
}}
/>

カスタムチェックボックススタイリング

<AttributeSelection.Checkbox
name="option1"
label="カスタムオプション"
value="option1"
sx={{
border: '2px solid #3b82f6',
borderRadius: '12px',
'&:hover': { backgroundColor: '#f0f9ff' }
}}
/>

カスタムボタンスタイリング

<AttributeSelection.SubmitButton
variant="contained"
sx={{
background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)',
borderRadius: '12px',
py: 1.5
}}
>
続行
</AttributeSelection.SubmitButton>

ブロックオーバーライドパターンの使用

<AttributeSelection {...props}>
{({defaultBlocks, defaultBlockOrder}) => {
return {
blocks: {
...defaultBlocks,
customInfo: <Alert severity="info">少なくとも1つのオプションを選択してください</Alert>,
},
blockOrder: ['title', 'subtitle', 'customInfo', 'fieldName', 'checkbox', 'submitButton', 'cancelButton']
};
}}
</AttributeSelection>

🔧 TypeScriptサポート

包括的な型定義による完全なTypeScriptサポート:

import {AttributeSelection} from '@nodeblocks/frontend-attribute-selection-block';
import {StackProps} from '@mui/material';
import {DefaultValues, UseFormGetValues, UseFormReset, UseFormSetError} from 'react-hook-form';
import {ReactNode} from 'react';

// Form data interface must include index signature for react-hook-form compatibility
interface CustomAttributeFormData {
[key: string]: unknown;
role?: boolean;
department?: boolean;
experience?: boolean;
skills?: boolean;
}

// Main component props interface with two type parameters:
// T - Form data type
// B - Blocks type (Record<string, never> for simple usage, Record<string, ReactNode> for block override)
interface AttributeSelectionProps<T extends Record<string, unknown>, B extends Record<string, ReactNode>>
extends Omit<StackProps, 'onSubmit' | 'onChange' | 'children'> {
onSubmit: (data: T) => void;
onCancel: (reset: UseFormReset<T>) => void;
onChange: (setError: UseFormSetError<T>, getValues: UseFormGetValues<T>) => void;
defaultValues?: DefaultValues<T>;
children?: BlocksOverride;
}

// Type-safe submit handler
const handleSubmit = (formData: CustomAttributeFormData): void => {
console.log('フォームが送信されました:', formData.role, formData.department, formData.experience);
};

// Type-safe change handler with validation
const handleChange = (
_setError: UseFormSetError<CustomAttributeFormData>,
getValues: UseFormGetValues<CustomAttributeFormData>,
): void => {
const values = getValues();
const hasSelection = values.role || values.department || values.experience || values.skills;
if (!hasSelection) {
_setError('role', {message: '少なくとも1つのオプションを選択してください'});
}
};

// Type-safe cancel handler
const handleCancel = (reset: UseFormReset<CustomAttributeFormData>): void => {
reset();
console.log('フォームがキャンセルされました');
};

// Simple usage with two type parameters
const SimpleAttributeSelectionForm = () => {
return (
<AttributeSelection<CustomAttributeFormData, Record<string, never>>
onSubmit={handleSubmit}
onChange={handleChange}
onCancel={handleCancel}
defaultValues={{role: false, department: false, experience: false, skills: false}}
>
<AttributeSelection.Title>属性を選択</AttributeSelection.Title>
<AttributeSelection.Subtitle>該当するオプションを選択してください</AttributeSelection.Subtitle>
<AttributeSelection.FieldName>職業情報</AttributeSelection.FieldName>
<AttributeSelection.Checkbox name="role" label="管理職" value="role" />
<AttributeSelection.Checkbox name="department" label="技術部門" value="department" />
<AttributeSelection.Checkbox name="experience" label="5年以上の経験" value="experience" />
<AttributeSelection.Checkbox name="skills" label="リーダーシップスキル" value="skills" />
<AttributeSelection.SubmitButton>続行</AttributeSelection.SubmitButton>
<AttributeSelection.CancelButton>戻る</AttributeSelection.CancelButton>
</AttributeSelection>
);
};

// Block override pattern with ReactNode blocks type
const AdvancedAttributeSelectionForm = () => {
return (
<AttributeSelection<CustomAttributeFormData, Record<string, ReactNode>>
onSubmit={handleSubmit}
onChange={handleChange}
onCancel={handleCancel}
defaultValues={{role: false, department: false, experience: false, skills: false}}
>
{({defaultBlocks, defaultBlockOrder}) => {
return {
blocks: {
...defaultBlocks,
title: (
<AttributeSelection.Title sx={{color: 'primary.main'}}>
カスタムタイトル
</AttributeSelection.Title>
),
},
blockOrder: defaultBlockOrder,
};
}}
</AttributeSelection>
);
};

📝 注意事項

  • ルートコンポーネントはMUIの Stackcomponent="form" で使用してセマンティックなフォーム要素を作成します
  • フォーム状態管理は react-hook-form によって処理され、バリデーションには mode: 'onBlur' が使用されます
  • onChange コールバックはフォーム値が変更されるたびにトリガーされ、リアルタイムバリデーションを可能にします
  • SubmitButtonformState.isValidfalse の場合に自動的に無効化されます
  • CancelButton はフォームの reset 関数を引数として onCancel コールバックを呼び出します
  • デフォルトブロック順序: title, subtitle, fieldName, checkbox, submitButton, cancelButton
  • すべてのサブコンポーネントはインラインスタイリング用のMUI sx プロパティをサポートします
  • チェックボックスはフォーム状態統合に react-hook-form Controllerを使用します
  • コンポーネントは2つのジェネリック型パラメータをサポートします: <FormData, BlocksType> ここで FormData はフォーム値を定義し、BlocksType はブロック構造を制御します
  • フォームデータインターフェースには、react-hook-form互換性のために [key: string]: unknown インデックスシグネチャを含める必要があります
  • シンプルな使用の場合は Record<string, never> を、ブロックオーバーライドパターンの場合は Record<string, ReactNode> を2番目の型パラメータとして使用します
  • CSSクラスはBEM命名規則に従います: nbb-attribute-selection, nbb-attribute-selection-title など

React、TypeScript、MUIを使用して❤️で構築されました。