Babelize Elements
ロケールピッカー

ロケールピッカー

ロケールから導出されるデフォルト値(通貨、日付と数値の書式、週の開始曜日)を備えた地域ピッカーです。検索、キーボード操作、RTL に対応しています。

Currency
INR₹12,34,567.89
Date format
15 Jan 2026
Number format
12,34,567.89
Week starts on
Sunday

インストール

npx shadcn@latest add @babelize/locale-picker

使い方

import { LocalePicker } from "@/components/ui/locale-picker";
<LocalePicker
  regions={["IN", "US", "GB", "DE", "JP"]} // your ISO 3166-1 alpha-2 regions
  defaultValue="en-IN"
  onValueChange={(locale) => console.log("Selected locale:", locale)}
  label="english" // native, english
  variant="outline" // outline, ghost, secondary
  size="default" // sm, default, lg
/>

Props

Prop型必須デフォルト説明
regionsstring[]はい—選択できる地域。ISO 3166-1 alpha-2 コードで指定します
valuestringいいえ—選択中のロケール(BCP 47)。コンポーネントを制御するにはこの値を渡します
defaultValuestringいいえen-<first region>非制御時の初期選択ロケール
onValueChange(locale: string) => voidいいえ—地域が変更されたときのコールバック。新しい BCP 47 タグを受け取ります
label"native" | "english"いいえ"english"地域名を英語で表示するか、選択中のロケールに合わせてローカライズして表示します
showFlagsbooleanいいえtrue地域名の横に国旗の絵文字を表示します
maxHeightnumber | stringいいえ"15rem"スクロールが始まるまでの、スクロールする選択肢一覧の最大の高さ
variant"outline" | "ghost" | "secondary"いいえ"outline"トリガーのスタイル
size"sm" | "default" | "lg"いいえ"default"トリガーのサイズ
align"start" | "end"いいえ"start"ポップアップを揃えるトリガーの辺
side"top" | "bottom"いいえ"bottom"ポップアップの優先表示側。ビューポートに十分なスペースがない場合は反転します
searchablebooleanいいえtrue検索欄を表示します
searchPlaceholderstringいいえ"Search regions..."検索欄のプレースホルダー
emptyMessageReact.ReactNodeいいえ"No results"検索に一致する項目がない場合に表示される内容
disabledbooleanいいえfalseトリガーを無効にします
showSummarybooleanいいえtrue導出されたロケールのデフォルト値のサマリーカードを表示します
labelsPartial<LocalePickerLabels>いいえ—組み込みの英語 UI テキストを上書きします(下記参照)
classNamesLocalePickerClassNamesいいえ—パーツごとのクラス: trigger、content、search、list、item、empty、summary
classNamestringいいえ—追加の CSS クラス

選択された値は完全な BCP 47 タグです。 その 地域 サブタグは選んだ地域になり、言語 サブタグは地域を変更しても保持されます。 en-IN からドイツを選ぶと en-DE になり、fr-JP から選ぶと fr-DE になります。

導出されるデフォルト値

サマリーカードは、選択中のロケールから Intl を通じてすべての値を導出します。 通貨コードには ISO 4217 のフォールバックテーブルのみを同梱しており、それ以外のデータは同梱していません:

行取得元
通貨地域 → ISO 4217 コード。Intl.NumberFormat(style: "currency")でプレビュー
日付の書式固定のサンプル日付における Intl.DateTimeFormat(dateStyle: "medium")
数値の書式固定のサンプル金額における Intl.NumberFormat
週の開始曜日利用可能な場合は Intl.Locale#getWeekInfo()、それ以外は地域のフォールバック

通貨の対応付けがない地域では、推測せずにダッシュ(—)を表示します。

キーボード操作

ポップアップは WAI-ARIA のコンボボックスパターンに従います。 フォーカスは検索欄に留まり、検索欄は role="combobox" として公開されます。 ハイライトされた選択肢は aria-activedescendant を通じて読み上げられます。

キー操作
Enter、Space、またはクリックトリガーからポップアップを開きます
ArrowDown / ArrowUp(閉じている状態)最初または最後の地域がハイライトされた状態で開きます
ArrowDown / ArrowUpハイライトを移動します。両端で循環します
Home / End最初または最後の地域をハイライトします
Enterハイライトされた地域を選択し、フォーカスをトリガーに戻します
Escapeポップアップを閉じ、フォーカスをトリガーに戻します
入力名前またはコードで絞り込みます。ハイライトは先頭に戻ります

機能

  • 導出されるデフォルト値 — 通貨、日付の書式、数値の書式、週の開始曜日を Intl を通じてリアルタイムに解決します
  • 検索付きドロップダウン — 英語名、ローカライズされた名前、地域コードで絞り込めます。クリアボタン付き
  • モーション — ポップアップは motion/react を介してフェードとスライドで表示され、prefers-reduced-motion を尊重します。閉じるときはアクセシビリティツリーから削除されます
  • RTL 対応 — ルートの dir を通じて、RTL のロケール(ar、he、fa、ur)の方向を切り替えます
  • キーボードでの操作に対応 — 矢印キー、Home / End、Enter、Escape で操作可能
  • ARIA ラベル — aria-activedescendant を持つ role="combobox" 検索欄に加え、aria-expanded、aria-haspopup、aria-selected
  • shadcn のトークンでテーマ設定 — bg-popover、border-input、bg-accent など。お使いのテーマを継承します。ダークモードはトークンから適用されます
  • カスタマイズ可能 — variant / size のトリガーと、パーツごとの classNames(LocalePickerClassNames はバレルファイルからエクスポートされています)。アイコンはすべて lucide-react を使用します
  • 制御または非制御 — value / defaultValue / onValueChange

使用例

制御

<LocalePicker regions={["IN", "US", "GB", "DE", "JP"]} value={locale} onValueChange={setLocale} />

ネイティブの地域名

<LocalePicker regions={["IN", "US", "GB", "DE", "JP"]} defaultValue="de-DE" label="native" />

de-DE を選択すると、トリガーには「Deutschland」と表示され、選択肢には「Vereinigte Staaten」「Vereinigtes Königreich」などと表示されます。

翻訳された UI テキスト

検索欄のプレースホルダー、空の状態、アクセシブルなラベル、サマリー行のラベルは、デフォルトで英語です。 翻訳するには labels を渡します。 省略したキーは英語のデフォルトのままになります。 searchPlaceholder と emptyMessage の props も引き続き使用でき、両方が設定されている場合は labels より優先されます。

"use client";

import { LocalePicker } from "@/components/ui/locale-picker";

export default function App() {
  return (
    <LocalePicker
      regions={["IN", "US", "GB", "DE", "JP"]}
      defaultValue="en-IN"
      labels={{
        searchPlaceholder: "Rechercher une région…",
        searchLabel: "Rechercher une région",
        clearSearch: "Effacer la recherche",
        emptyMessage: "Aucune région trouvée.",
        listbox: "Choisir la région",
        current: (name) => `Région actuelle : ${name}`,
        currency: "Devise",
        dateFormat: "Format de date",
        numberFormat: "Format de nombre",
        weekStart: "La semaine commence le",
      }}
    />
  );
}

依存関係

このコンポーネントは次を使用しています:

  • clsx と tailwind-merge(dependencies としてバンドル)
  • lucide-react(アイコン)
  • motion(ポップアップのアニメーション)

peerDependencies:

  • react >= 18
  • react-dom >= 18
  • tailwindcss >= 3

クレジット

作成者: ujwalbajaj。

このページの内容