@blocklet/payment-react
Version:
Reusable react components for payment kit v2
109 lines (86 loc) • 6.12 kB
Markdown
`PhoneInput`コンポーネントは、ユーザーフレンドリーな国際電話番号入力フィールドを提供します。`react-hook-form`とシームレスに統合され、国旗と国番号付きの検索可能な国選択機能、自動番号フォーマット、および`google-libphonenumber`による強力な検証機能を備えています。
このコンポーネントは、選択された国を共有フォームフィールドと同期させることで、[`CountrySelect`](./components-ui-form-elements-country-select.md)や[`AddressForm`](./components-ui-form-elements-address-form.md)などの他のフォーム要素と連携して動作するように設計されています。
このコンポーネントは、`react-international-phone`ライブラリをコア機能として活用し、それをラップして`react-hook-form`およびMaterial-UIとの深い統合を提供します。ユーザーが国を選択したり番号を入力したりすると、コンポーネントはフォームの状態にある対応するフィールドを更新します。また、他のコンポーネントがフォーム内のリンクされた国フィールドを変更すると、自動的に国選択を更新します。
<!-- DIAGRAM_IMAGE_START:architecture:16:9 -->

<!-- DIAGRAM_IMAGE_END -->
`PhoneInput`コンポーネントは、すべての標準的なMaterial-UIの`TextField` propsに加えて、以下の特定のpropsを受け入れます:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| `name` | `string` | Yes | - | `react-hook-form`に電話番号を登録するためのフィールド名。 |
| `countryFieldName` | `string` | No | `'billing_address.country'` | 選択された国のISO2コードを保存するフォームフィールドの名前。これにより、電話番号入力の国を、アドレスコンポーネントなど、フォームの他の部分と同期させることができます。 |
`PhoneInput`コンポーネントを使用するには、`react-hook-form`の`FormProvider`でラップする必要があります。次の例は、検証機能を含む基本的な実装を示しています。
まず、ライブラリが提供する非同期検証関数が必要です。
```javascript phone-validator.js icon=logos:javascript
// src/libs/phone-validator.js
import { getPhoneUtil } from '@blocklet/payment-react/libs/phone-validator';
export const validatePhoneNumber = async (phoneNumber) => {
if (!phoneNumber) return true;
try {
const util = await getPhoneUtil();
const parsed = util.parseAndKeepRawInput(phoneNumber);
return util.isValidNumber(parsed);
} catch (err) {
console.error('Phone validation error:', err);
// ライブラリの読み込みに失敗した場合、単純な正規表現にフォールバックします
const pattern = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/im;
return pattern.test(phoneNumber) || 'Invalid phone number';
}
};
```
これで、このバリデータをフォームコンポーネントで使用できます。
```jsx MyPaymentForm.tsx icon=logos:react
import { FormProvider, useForm } from 'react-hook-form';
import { Button, Box } from '@mui/material';
import { PhoneInput } from '@blocklet/payment-react';
import { validatePhoneNumber } from '../libs/phone-validator'; // 必要に応じてパスを調整してください
export default function MyPaymentForm() {
const methods = useForm({
mode: 'onBlur',
defaultValues: {
phone: '',
'billing_address.country': 'us', // デフォルトの国
},
});
const onSubmit = (data) => {
alert(JSON.stringify(data, null, 2));
};
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<Box display="flex" flexDirection="column" gap={2}>
<PhoneInput
label="Phone Number"
name="phone"
// フォームの状態にある国フィールドへのリンク
countryFieldName="billing_address.country"
// 検証ルールを追加
rules={{
validate: async (value) => {
const isValid = await validatePhoneNumber(value);
return isValid || 'Please enter a valid phone number.';
},
}}
fullWidth
/>
<Button type="submit" variant="contained">
Submit
</Button>
</Box>
</form>
</FormProvider>
);
}
```
1. **`FormProvider`**: `PhoneInput`を含むフォーム全体が`FormProvider`でラップされ、必要なフォームコンテキストを提供します。
2. **`name="phone"`**: これにより、入力フィールドがフォームデータ内で`phone`という名前で登録されます。
3. **`countryFieldName="billing_address.country"`**: これは`PhoneInput`に、フォームの状態にある`billing_address.country`フィールドの読み書きを両方行うように指示します。これにより同期が保たれます。このフィールドのデフォルト値は`useForm`で`'us'`に設定されています。
4. **`rules`**: 非同期の`validate`関数を`rules` propに渡します。`react-hook-form`は検証中にこの関数が解決されるのを待ちます。チェックを実行するために`validatePhoneNumber`ユーティリティが呼び出されます。
`PhoneInput`の真価は、`AddressForm`と併用することで発揮されます。両方のコンポーネントは同じ国フィールド(デフォルトでは`billing_address.country`)にリンクできるため、`AddressForm`で国を変更すると、`PhoneInput`の国旗と国番号が自動的に更新されます。
この統合の完全な例については、[`AddressForm`](./components-ui-form-elements-address-form.md)のドキュメントを参照してください。