Babelize Elements
Selectores de configuración regional

Selector de configuración regional

Selector de región con valores predeterminados derivados de la configuración regional: moneda, formatos de fecha y número, y primer día de la semana. Con búsqueda, accesible por teclado y compatible con RTL.

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

Instalación

npx shadcn@latest add @babelize/locale-picker

Uso

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

PropTipoObligatorioPredeterminadoDescripción
regionsstring[]Sí—Regiones entre las que elegir, en códigos ISO 3166-1 alpha-2
valuestringNo—Configuración regional seleccionada (BCP 47): pásala para controlar el componente
defaultValuestringNoen-<first region>Configuración regional inicial cuando no está controlada
onValueChange(locale: string) => voidNo—Callback que se ejecuta cuando cambia la región; recibe la nueva etiqueta BCP 47
label"native" | "english"No"english"Nombres de región en inglés o localizados según la configuración regional seleccionada
showFlagsbooleanNotrueMuestra el emoji de bandera de la región junto a su nombre
maxHeightnumber | stringNo"15rem"Altura máxima de la lista de opciones antes de que aparezca el desplazamiento
variant"outline" | "ghost" | "secondary"No"outline"Estilo del disparador
size"sm" | "default" | "lg"No"default"Tamaño del disparador
align"start" | "end"No"start"Borde del disparador con el que se alinea el popup
side"top" | "bottom"No"bottom"Lado preferido del popup; cambia de lado si el viewport no tiene espacio
searchablebooleanNotrueMuestra el campo de búsqueda
searchPlaceholderstringNo"Search regions..."Marcador de posición del campo de búsqueda
emptyMessageReact.ReactNodeNo"No results"Contenido que se muestra cuando la búsqueda no coincide con nada
disabledbooleanNofalseDesactiva el disparador
showSummarybooleanNotrueMuestra la tarjeta de resumen de los valores predeterminados derivados de la configuración regional
labelsPartial<LocalePickerLabels>No—Sustituye el texto de interfaz en inglés integrado (consulta más abajo)
classNamesLocalePickerClassNamesNo—Clases por parte: trigger, content, search, list, item, empty, summary
classNamestringNo—Clases CSS adicionales

El valor seleccionado es una etiqueta BCP 47 completa: su subetiqueta de región es la región elegida, y su subetiqueta de idioma se mantiene al cambiar de región. Elegir Alemania desde en-IN da como resultado en-DE; elegirla desde fr-JP da como resultado fr-DE.

Valores predeterminados derivados

La tarjeta de resumen deriva todo de la configuración regional seleccionada mediante Intl; no incluye más datos que una tabla de reserva de códigos ISO 4217 para el código de moneda:

FilaOrigen
MonedaRegión → código ISO 4217, con vista previa mediante Intl.NumberFormat (style: "currency")
Formato de fechaIntl.DateTimeFormat (dateStyle: "medium") con una fecha de ejemplo fija
Formato de númeroIntl.NumberFormat con un importe de ejemplo fijo
La semana empieza elIntl.Locale#getWeekInfo() cuando está disponible, con un valor regional de reserva

Las regiones sin asignación de moneda muestran un guion largo en lugar de una suposición.

Soporte de teclado

El popup sigue el patrón combobox de WAI-ARIA: el foco permanece en el campo de búsqueda, que se expone como role="combobox", y la opción resaltada se anuncia mediante aria-activedescendant.

ClaveAcción
Enter, Space o clicAbre el popup desde el disparador
ArrowDown / ArrowUp (cerrado)Abre con la primera / última región resaltada
ArrowDown / ArrowUpMueve el resaltado, dando la vuelta en ambos extremos
Home / EndResalta la primera / última región
EnterSelecciona la región resaltada y devuelve el foco al disparador
EscapeCierra el popup y devuelve el foco al disparador
EscrituraFiltra por nombre o código; el resaltado vuelve al principio

Características

  • Valores predeterminados derivados — moneda, formato de fecha, formato de número y primer día de la semana, resueltos en tiempo real mediante Intl
  • Desplegable con búsqueda — filtra regiones por nombre en inglés, nombre localizado o código de región, con un botón de borrado
  • Movimiento — el popup aparece y se desliza mediante motion/react, respetando prefers-reduced-motion, y sale del árbol de accesibilidad al cerrarse
  • Compatible con RTL — invierte la dirección para las configuraciones regionales RTL (ar, he, fa, ur) mediante dir en la raíz
  • Accesible con teclado — navegación con flechas, Inicio / Fin, Intro y Escape
  • Etiquetas ARIA — campo de búsqueda role="combobox" con aria-activedescendant, además de aria-expanded, aria-haspopup y aria-selected
  • Con tema de tokens de shadcn — bg-popover, border-input, bg-accent y similares, así que hereda tu tema; el modo oscuro viene de los tokens
  • Personalizable — disparadores variant / size más classNames por parte (LocalePickerClassNames se exporta desde el barrel), con iconos lucide-react en todo el componente
  • Controlado o no controlado — value / defaultValue / onValueChange

Ejemplos

Controlado

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

Nombres de región nativos

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

Con de-DE seleccionado, el disparador muestra «Deutschland» y las opciones muestran «Vereinigte Staaten», «Vereinigtes Königreich», etc.

Texto de interfaz traducido

El marcador de posición de búsqueda, el estado vacío, las etiquetas accesibles y las etiquetas de la fila de resumen usan inglés de forma predeterminada. Pasa labels para traducirlos: cualquier clave que omitas conserva su valor en inglés. Las props searchPlaceholder y emptyMessage siguen funcionando y tienen prioridad sobre labels cuando ambas están definidas.

"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",
      }}
    />
  );
}

Dependencias

Este componente usa:

  • clsx y tailwind-merge (incluidos como dependencias)
  • lucide-react (iconos)
  • motion (animación del popup)

Dependencias de pares:

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

Créditos

Creado por ujwalbajaj.

En esta página