UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

109 lines (86 loc) 6.12 kB
# PhoneInput `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 --> ![PhoneInput](assets/diagram/phone-input-diagram-0.jpg) <!-- DIAGRAM_IMAGE_END --> ## Props `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`ユーティリティが呼び出されます。 ## AddressFormとの統合 `PhoneInput`の真価は、`AddressForm`と併用することで発揮されます。両方のコンポーネントは同じ国フィールド(デフォルトでは`billing_address.country`)にリンクできるため、`AddressForm`で国を変更すると、`PhoneInput`の国旗と国番号が自動的に更新されます。 この統合の完全な例については、[`AddressForm`](./components-ui-form-elements-address-form.md)のドキュメントを参照してください。