# CountrySelect

`CountrySelect` 元件提供了一個方便使用者選擇國家的下拉式選單。它具有可搜尋的列表、顯示國旗，並提供響應式設計，能適應桌面和行動裝置的視窗。它設計用於在 `react-hook-form` 管理的表單中使用。

## Props

| Prop         | Type                             | Description                                                                                 | Required | Default |
|--------------|----------------------------------|---------------------------------------------------------------------------------------------|----------|---------|
| `value`      | `CountryIso2`                    | 所選國家的 ISO2 代碼（例如 'us'）。                                         | Yes      |         |
| `onChange`   | `(value: CountryIso2) => void`   | 選擇國家時叫用的回呼函式。                             | Yes      |         |
| `name`       | `string`                         | 輸入框的 name 屬性，用於與 `react-hook-form` 整合。              | Yes      |         |
| `sx`         | `SxProps`                        | 應用於根元素的自訂樣式。                                            | No       | `{}`    |
| `showDialCode` | `boolean`                        | 如果為 `true`，國家的撥號代碼將與其名稱一起顯示在列表中。        | No       | `false` |

## 基本用法

要使用 `CountrySelect` 元件，您必須將其包裝在 `react-hook-form` 的 `FormProvider` 中。元件的狀態應透過表單上下文進行管理。

```tsx Basic CountrySelect Example icon=logos:react
import { FormProvider, useForm } from 'react-hook-form';
import { Box, Button, Typography } from '@mui/material';
import CountrySelect from '@blocklet/payment-react/src/components/country-select'; // 根據需要調整路徑
import type { CountryIso2 } from 'react-international-phone';

export default function BasicCountrySelect() {
  const methods = useForm<{ country: CountryIso2 }>({
    defaultValues: {
      country: 'us',
    },
  });

  const { handleSubmit, watch, setValue } = methods;
  const countryValue = watch('country'); // 監聽變更以更新受控元件

  const onSubmit = (data: { country: CountryIso2 }) => {
    alert(`表單已提交，國家：${data.country}`);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, maxWidth: 400 }}>
          <Typography variant="h6">選擇您的國家</Typography>
          <CountrySelect
            name="country"
            value={countryValue}
            onChange={(newCountry) => {
              setValue('country', newCountry, { shouldValidate: true });
            }}
          />
          <Button type="submit" variant="contained">
            提交
          </Button>
          <Typography>
            目前表單值：{countryValue}
          </Typography>
        </Box>
      </form>
    </FormProvider>
  );
}
```

## 功能

### 搜尋與篩選
元件在下拉列表頂部包含一個搜尋欄，讓使用者可以透過國家名稱、ISO2 代碼或撥號代碼快速找到國家。例如，搜尋「+1」將會顯示美國和加拿大。

### 響應式 UI
在桌面裝置上，`CountrySelect` 會渲染為標準的下拉式選單。在行動裝置上，它會轉換成一個從螢幕底部滑出的全寬對話方塊，為小型裝置提供最佳化的使用者體驗。

### 鍵盤可及性
`CountrySelect` 支援完整的鍵盤導覽。使用者可以使用 `ArrowUp` 和 `ArrowDown` 鍵在列表中導覽，`Enter` 鍵選擇國家，`Escape` 鍵關閉下拉選單。`Tab` 和 `Shift+Tab` 也可以在列表項目之間循環。

### 表單整合
設計用於與 `react-hook-form` 無縫協作。當做出選擇時，它會自動更新表單狀態，因此需要將其包裝在 `FormProvider` 內。

## 進階用法

### 顯示撥號代碼

您可以透過將 `showDialCode` 屬性設定為 `true`，在列表中顯示每個國家的電話撥號代碼。

```tsx CountrySelect with Dial Code icon=logos:react
import { FormProvider, useForm } from 'react-hook-form';
import { Box, Button } from '@mui/material';
import CountrySelect from '@blocklet/payment-react/src/components/country-select'; // 根據需要調整路徑
import type { CountryIso2 } from 'react-international-phone';

export default function CountrySelectWithDialCode() {
  const methods = useForm<{ country: CountryIso2 }>({
    defaultValues: {
      country: 'gb',
    },
  });

  const { handleSubmit, watch, setValue } = methods;
  const countryValue = watch('country');

  const onSubmit = (data: { country: CountryIso2 }) => {
    alert(`表單已提交，國家：${data.country}`);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, maxWidth: 400 }}>
          <CountrySelect
            name="country"
            value={countryValue}
            onChange={(newCountry) => setValue('country', newCountry)}
            showDialCode={true}
          />
          <Button type="submit" variant="contained">
            提交
          </Button>
        </Box>
      </form>
    </FormProvider>
  );
}
```

## 後續步驟

此元件是建構更複雜表單元素的基礎。查看它如何整合到 [PhoneInput](./components-ui-form-elements-phone-input.md) 元件中，以建立一個完整的國際電話號碼欄位。