MenuChevron Down
Select Selector - Docs - Artefact

Select Selector

Forms
Auto-interactivo

Introducción

Un control desplegable para elegir una o varias opciones de una lista — una alternativa accesible y personalizable al elemento nativo <select>.

Cuándo optar por otra cosa:

  • Con menos de ~5 opciones, un RadioGroup suele ser más claro.
  • Si el usuario debe poder escribir para filtrar las opciones, usa Combobox.

El componente renderiza un <select> nativo visualmente oculto junto a la interfaz personalizada, de modo que una prop name hace que participe en el envío de formularios normal sin cableado adicional.

Interacción por teclado

El disparador es un botón role="combobox"; el foco permanece en él mientras la opción resaltada se comunica mediante aria-activedescendant.

KeyBehavior
Enter / SpaceAbre la lista; cuando está abierta, selecciona la opción resaltada.
ArrowDown / ArrowUpAbre la lista, o mueve el resaltado (cíclico, salta opciones deshabilitadas).
Home / EndResalta la primera / última opción habilitada.
EscapeCierra la lista.
TabCierra la lista y mueve el foco a otro lugar.
Printable charactersPredicción de escritura (typeahead): salta a la primera opción cuya etiqueta coincida con el prefijo escrito. Cuando la lista está cerrada (modo simple), la coincidencia se selecciona directamente, como en un <select> nativo.

Abrir la lista resalta la opción actualmente seleccionada (o la primera habilitada), y la navegación por teclado mantiene la opción resaltada visible dentro del área de desplazamiento.

Hidratación

Nivel 1 — automáticamente interactivo. Abrir el desplegable y seleccionar una opción requieren JS del cliente, y no existe un respaldo estático (el <select> nativo está visualmente oculto y solo existe para el envío de formularios), por lo que Select se hidrata por defecto. Pasa interactive={false} para forzar un renderizado puramente estático.

interactive propResult
omitidoSe hidrata como isla
trueSe hidrata como isla
falseEstático — sin JS del cliente

Todas las decisiones de interactividad en la biblioteca pasan por el ayudante compartido shouldHydrate() en app/components/ui/island-utils.ts.

Uso

React
Solid
Svelte
Vue
Hono
import { Select } from "../components/ui";

const items = [
  { label: "React", value: "react" },
  { label: "Solid", value: "solid" },
  { label: "Svelte", value: "svelte", disabled: true },
  { label: "Vue", value: "vue" },
  { label: "Hono", value: "hono" },
];

export default function MyPage() {
  return (
    <Select
      items={items}
      label="Framework"
      placeholder="Select a framework"
      allowClear
    />
  );
}

Selección múltiple

La lista permanece abierta mientras se alternan las opciones, y el disparador muestra las etiquetas seleccionadas unidas por comas.

<Select
  multiple
  items={items}
  label="Frameworks"
  placeholder="Select frameworks"
  defaultValue={["hono"]}
/>

En un formulario

El <select> nativo oculto conserva la selección, por lo que un envío de formulario simple funciona:

<form method="post" action="/frameworks">
  <Select name="framework" items={items} label="Framework" required />
  <Button type="submit">Save</Button>
</form>

Tamaños y variantes

<Select items={items} size="sm" placeholder="Small" />
<Select items={items} size="lg" variant="surface" placeholder="Large surface" />
<Select items={items} invalid placeholder="Invalid state" />

Constructor de páginas del CMS

Este componente está disponible como un bloque select en el Constructor de páginas (content/pages/*.json):

{
  "type": "select",
  "label": "Framework",
  "placeholder": "Select a framework",
  "items": [
    { "label": "React", "value": "react" },
    { "label": "Hono", "value": "hono" }
  ]
}

Propiedades

PropTypeDescription
itemsSelectItem[]Las opciones a mostrar en la lista.
labelChildEtiqueta renderizada sobre el disparador y asociada a él.
placeholderstringTexto mostrado en el disparador mientras no hay nada seleccionado.
allowClearbooleanMuestra un botón de limpiar una vez que existe una selección.
multiplebooleanPermite seleccionar varias opciones; la lista permanece abierta mientras se alternan.
defaultValuestring[]Selección inicial (no controlada). Alias de selectedValues.
selectedValuesstring[]Selección inicial (igual que defaultValue).
deselectablebooleanEn modo simple, hacer clic de nuevo en la opción seleccionada la deselecciona.
namestringNombre del <select> nativo oculto, para el envío de formularios.
disabledbooleanDeshabilita todo el control.
invalidbooleanMarca el control como inválido (aria-invalid, borde de error).
readOnlybooleanLa selección es visible pero la lista no se puede abrir.
requiredbooleanMarca el control como obligatorio (aria-required, required del select oculto).
openbooleanEstado de apertura controlado del desplegable.

| size | `"xs" \ | "sm" \ | "md" \ | "lg" \ | "xl"` | Tamaño del disparador y la lista. Por defecto md. |

| variant | `"outline" \ | "surface"` | Variante visual del disparador. Por defecto outline. |

| interactive | boolean | Sobrescribe la decisión de hidratación (ver abajo). | | onValueChange | (values: string[]) => void | Se llama con la selección completa cada vez que cambia (seleccionar, deseleccionar, limpiar). | | onItemSelect | (value: string) => void | Se llama con el valor de la opción con la que se interactuó. | | onClear | () => void | Se llama cuando el botón de limpiar vacía la selección. | | onOpenChange | (open: boolean) => void | Se llama cuando el desplegable se abre o se cierra. |

Las props de callback solo funcionan cuando el Select se compone desde código del lado del cliente (dentro de otra isla). Las props serializadas desde una ruta renderizada en el servidor deben ser datos simples.

SelectItem

PropTypeDescription
labelstringEl texto visible de la opción. También se usa para la coincidencia por predicción de escritura.
valuestringEl valor único de la opción.
disabledbooleanSi la opción se puede seleccionar.