# 表单元素

`@blocklet/payment-react` 库提供了一系列精细的输入组件，旨在简化自定义支付和联系信息表单的创建。这些元素在构建时充分考虑了验证和用户体验，能够与 `react-hook-form` 顺畅集成，为数据收集提供了一个强大而灵活的解决方案。

每个组件都被设计为一个独立的单元，让你可以将它们组合成满足你特定需求的复杂表单。以下是可用的表单元素概览。

<x-cards data-columns="2">
  <x-card data-title="AddressForm" data-icon="lucide:map-pin" data-href="/components/ui/form-elements/address-form">
    一个预构建的表单，用于收集账单地址详情，并带有特定国家/地区的验证功能。
  </x-card>
  <x-card data-title="PhoneInput" data-icon="lucide:phone" data-href="/components/ui/form-elements/phone-input">
    一个国际电话号码输入框，集成了国家/地区代码选择器和验证功能。
  </x-card>
  <x-card data-title="CountrySelect" data-icon="lucide:globe" data-href="/components/ui/form-elements/country-select">
    一个可搜索的下拉菜单，用于选择国家/地区，配有国旗和移动端友好的用户界面。
  </x-card>
  <x-card data-title="CurrencySelector" data-icon="lucide:coins" data-href="/components/ui/form-elements/currency-selector">
    一个允许用户从可用选项中选择其偏好支付货币的组件。
  </x-card>
</x-cards>

## 通用使用模式

这些表单元素旨在与 `react-hook-form` 的 `FormProvider` 一起使用。你可以组合它们来构建全面的表单，以捕获交易所需的所有必要信息。虽然每个组件都有其自己的一套属性，但它们共享一个通用的集成模式。

下面是一个基本示例，展示了如何组合多个表单元素来创建一个用户信息表单：

```jsx MyCustomForm.tsx icon=logos:react
import { FormProvider, useForm } from 'react-hook-form';
import { AddressForm, PhoneInput, CurrencySelector } from '@blocklet/payment-react';
import { Button, Stack } from '@mui/material';

// 假设 `availableCurrencies` 是从你的后端获取的
const availableCurrencies = [
  {
    id: 'usd_xxx',
    name: 'USD',
    symbol: 'USD',
    logo: 'url/to/usd_logo.png',
    method: { id: 'stripe', name: 'Stripe' },
  },
  // ... 其他货币
];

function MyCustomForm() {
  const methods = useForm({
    defaultValues: {
      currency: 'usd_xxx',
      phone_number: '',
      billing_address: {
        line1: '',
        city: '',
        state: '',
        postal_code: '',
        country: 'US', // 使用 ISO2 代码
      },
    },
  });

  const onSubmit = (data) => {
    console.log('表单数据已提交：', data);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <Stack spacing={2}>
          <CurrencySelector
            value={methods.watch('currency')}
            currencies={availableCurrencies}
            onChange={(currencyId) => methods.setValue('currency', currencyId)}
          />
          <PhoneInput name="phone_number" label="Phone Number" required />
          <AddressForm mode="required" stripe={false} />
          <Button type="submit" variant="contained">
            Submit
          </Button>
        </Stack>
      </form>
    </FormProvider>
  );
}
```

在此示例中，`CurrencySelector`、`PhoneInput` 和 `AddressForm` 组合在同一个表单中。`CurrencySelector` 用作与表单状态绑定的受控组件，而 `PhoneInput` 和 `AddressForm` 是非受控组件，它们会自动将其字段和验证规则注册到 `react-hook-form` 的上下文中。

## 后续步骤

要了解每个组件的具体属性和实现细节，请浏览它们各自的文档页面。

从 [AddressForm](./components-ui-form-elements-address-form.md) 开始，了解如何收集账单信息。
