mcpField
M
mantine-form

mantine-form

github.com/mantinedev開発642.7k 回インストール3 週間前に更新
リポジトリ

mantine-form について

Mantine 9.x 向けに、`@mantine/form` でフォームを構築する方法を説明するスキルです。入力の連携、検証方法、制御モードと非制御モード、複雑なフォームのパターンを扱います。

主な機能

  1. 01非制御・制御フォームモード
  2. 02入力プロパティとフィールドの連携
  3. 03ルール、スキーマ、関数による検証
  4. 04送信、変更、フォーカス離脱時の検証
  5. 05値の監視と再レンダリングの動作

活用シーン

  1. 01Mantine の入力でフォームを構築
  2. 02スキーマによるフィールド検証
  3. 03入力中の再レンダリングの抑制
  4. 04条件付きまたは入れ子のフォームの作成

MCP 対応

付属のリファレンスで回答が見つからない場合、Mantine MCP サーバーのドキュメントを参照する方法を案内します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mantinedev/skills --skill mantine-form

インストール後、Claude Code で/mantine-formを入力して読み込まれたか確認します。

同梱ファイルreferences/api.mdreferences/patterns.md

詳細

Mantine Form スキル

Mantine 9.x 向けに書かれています。

基本的なワークフロー

1. フォームを設定する

すべてのフォームで、非制御モードを使用することを推奨します。デフォルトは 'controlled' なので、明示的に設定してください。

const form = useForm({
  mode: 'uncontrolled',
  initialValues: {
    email: '',
    age: 0,
  },
  validate: {
    email: isEmail('Invalid email'),
    age: isInRange({ min: 18 }, 'Must be at least 18'),
  },
});
2. getInputProps で入力を接続する

非制御モードでは、すべての入力に key={form.key('path')} が必要です。これがないと、form.setFieldValue、form.setValues、または form.reset の後に入力が更新されません。

<TextInput label="Email" key={form.key('email')} {...form.getInputProps('email')} />
<NumberInput label="Age" key={form.key('age')} {...form.getInputProps('age')} />

チェックボックスとスイッチには { type: 'checkbox' } が必要です。

<Checkbox
  label="I agree"
  key={form.key('agreed')}
  {...form.getInputProps('agreed', { type: 'checkbox' })}
/>

Select、NumberInput、Radio.Group、Checkbox.Group など、value と onChange のペアを持つ Mantine の入力は、通常の getInputProps と key で動作します。

<Radio.Group label="Delivery" key={form.key('delivery')} {...form.getInputProps('delivery')}>
  <Radio value="standard" label="Standard" />
  <Radio value="express" label="Express" />
</Radio.Group>

Radio.Group を使わない単独のラジオボタンでは、form.getInputProps('color', { type: 'radio', value: 'red' }) を使用し、各ラジオボタンに key={form.key('color')} を追加してください。

error プロパティのないコンポーネント(Slider、RangeSlider、Rating、SegmentedControl、Chip.Group)では、{ withError: false } が必要です。エラーは自分で表示してください。

<Slider key={form.key('stock')} {...form.getInputProps('stock', { withError: false })} />
{form.errors.stock && <Text c="red" size="sm">{form.errors.stock}</Text>}
3. 送信を処理する
<form onSubmit={form.onSubmit((values) => console.log(values))}>
  ...
  <Button type="submit">Submit</Button>
</form>

onSubmit は、バリデーションに合格した場合のみハンドラーを呼び出します。ハンドラーが Promise を返す場合、処理が完了するまで form.submitting は true になります。失敗を処理するには、次のようにします。

form.onSubmit(
  (values, event) => save(values),
  (errors, values, event) => console.log('Validation failed', errors) // { 'user.email': 'Invalid email' }
);

バリデーション

ルールオブジェクト(最も一般的)
validate: {
  name: isNotEmpty('Required'),
  email: isEmail('Invalid email'),
  password: hasLength({ min: 8 }, 'Min 8 chars'),
  confirmPassword: matchesField('password', 'Passwords do not match'),
}
スキーマ(zod、valibot、arktype などの Standard Schema ライブラリ)
import { z } from 'zod/v4';
import { schemaResolver, useForm } from '@mantine/form';

const schema = z.object({
  email: z.email({ error: 'Invalid email' }),
  age: z.number().min(18, { error: 'Must be at least 18' }),
});

const form = useForm({
  mode: 'uncontrolled',
  initialValues: { email: '', age: 0 },
  validate: schemaResolver(schema, { sync: true }),
});

schemaResolver は組み込みなので、リゾルバーパッケージは必要ありません。同期スキーマでは { sync: true } を渡すと、form.validate() は Promise ではなく通常の結果を返します。

関数(フィールド間のロジック用)
validate: (values) => ({
  endDate: values.endDate < values.startDate ? 'End must be after start' : null,
});
バリデーションを実行するタイミング

デフォルトでは、フィールドのバリデーションは送信時のみ実行されます。

validateInputOnChange: true,            // also validate every field when it changes
validateInputOnChange: ['email'],       // only the listed fields
validateInputOnBlur: ['email'],         // same options, on blur
validateInputOnBlur: [`members.${FORM_INDEX}.email`], // list items, FORM_INDEX is exported from @mantine/form

フォーカスアウト時にバリデーションを実行すると、ユーザーが送信ボタンを押したときに表示されるエラーによってレイアウトがずれ、クリックがボタンに当たらないことがあります。エラーが表示されても動かない場所(たとえば固定位置のフッター)に送信ボタンを配置するか、変更時にバリデーションを実行してください。

モード

'uncontrolled'(推奨)'controlled'(デフォルト)
値の保存先RefReact state
form.values更新されません。form.getValues() を使用してください変更のたびに更新されます
値の変更時の再レンダリングなしあり
入力プロパティdefaultValue + onChangevalue + onChange
入力に key={form.key(path)} を指定必須不要

非制御モードで再レンダリングされるもの

  • 入力欄への入力では、フォームは再レンダリングされません。
  • レンダリング中の form.getValues() は、入力によって更新されません。値に基づいてフォームの一部を表示または非表示にするには、form.useWatchValue(path) を使用してください。ネストされたパスも使えます。例:form.useWatchValue('members.0.role')。
  • setFieldValue、setValues、insertListItem、removeListItem、reorderListItem、reset、initialize は再レンダリングを行うため、form.getValues().items.map(...) からリストをレンダリングしても問題ありません。
  • form.errors、form.isDirty()、form.isDirty('path')、form.isTouched()、form.submitting、form.validating は、どちらのモードでもレンダリング中に使用できます。これらが変化するとフォームは再レンダリングされます。
const shipsInternationally = form.useWatchValue('shipsInternationally');

リファレンス

基本的なフォームを超える内容については、コードを書く前に両方のリファレンスを読んでください。

  • references/patterns.md — 次の内容を確認する場合に読んでください:異なるレコードに同じフォームを再利用する(編集ダイアログ)、最初の無効なフィールドにフォーカスする、複数の送信ボタン、ユーザーの入力中に値を変更する、ネストされたオブジェクト、配列フィールド、リスト内のリストと formRootRule、非同期バリデーション(ルールと非同期スキーマ)、条件付きフィールド、条件付きバリデーション、複数ステップのフォーム、サーバーからの初期値の読み込み、保存と新しいベースラインの設定、コンポーネントの外部からのフォーム制御、カスタム入力、コンポーネント間でのフォームコンテキスト、transformValues、単独での useField の使用、送信後のサーバーエラー
  • references/api.md — それ以外のすべてを確認する場合に読んでください。すべての useForm オプションと戻り値のメンバー(watch、onValuesChange、enhanceGetInputProps、resetField、clearFieldError、touchTrigger など)に加え、useField、createFormContext、createFormActions、schemaResolver、組み込みバリデーター、型を一覧にしている唯一の場所です

情報の確認方法

リファレンスに必要な情報がない場合は、推測しないでください。

  • Mantine MCP サーバー(@mantine/mcp-server)が接続されている場合は、search_docs と get_item_doc を使用してください
  • そうでない場合は、https://mantine.dev/llms.txt を取得し、リンクされているフォームのページを開いてください

コメント