Todos los componentes (204)
Selector
Elección · Select · .amset-select
Qué es y cuándo usarlo
Un desplegable para elegir una opción de una lista. Cerrado enseña lo elegido (o el marcador); abierto, la lista con una marca en la opción elegida. Las opciones se pasan como datos (options, cada una con key y label), no como hijos: así ninguna se queda sin texto. La lista sale en la capa superior del navegador (popover), por encima de cualquier z-index y también dentro de un diálogo, y se cierra al pulsar fuera.
Cuándo usarlo
- Una opción entre muchas que no hace falta ver a la vez: la provincia, el metal de un anillo, la forma de envío.
- En un formulario: lleva etiqueta, ayuda (
hint), error (error) y asterisco de obligatorio (required) como el resto de campos; conname, el valor viaja en un formulario nativo. shortLabelen una opción cuando la etiqueta entera no cabe en la caja: «+34» en vez de «+34 · España».valueyonChangepara controlarlo (recibe lakeyelegida);placeholdercambia el «Elige una opción» de serie.groupen una opción la mete bajo un título («Europa», «Asia»): las de un mismo grupo tienen que ir juntas enoptions.
Cuándo no
- Pocas opciones que conviene ver sin abrir nada:
RadioGroup. - Una lista larga en la que hay que buscar escribiendo:
SearchField. - Elegir varias:
MultiSelect. - Una lista que en el móvil conviene elegir con el selector del sistema:
native, que pinta un<select>de verdad (pierde iconos y dos líneas por opción). - Idioma y moneda:
LocalePicker, que ya los escribe bien.
Teclado: Tab llega al disparador. Cerrado, Intro, Espacio o las flechas arriba y abajo abren la lista, y el foco pasa a ella. Abierto, las flechas se mueven, Inicio y Fin van a la primera y a la última, escribir salta a la opción que empieza por esas letras, Intro o Espacio eligen y cierran, y Escape cierra: en los dos casos el foco vuelve al disparador. Las opciones deshabilitadas se saltan y no se eligen.
Accesibilidad: el disparador se llama con la etiqueta y lo elegido; la ayuda y el error se leen como su descripción. hiddenLabel deja la etiqueta solo para el lector de pantalla: es para un campo que va dentro de otro que ya se explica (el prefijo de un teléfono), nunca para ahorrar sitio. readOnly deja enfocarlo y leerlo, pero la lista no se abre. Con loading, el disparador lleva aria-busy y un anillo de carga. Con el dedo, cada opción de la lista mide al menos 44 px.
Caja de campo: tres tamaños y tres variantes (outline, soft, ghost), con el mismo hover y el mismo anillo que un TextField. El anillo sigue puesto mientras la lista está abierta, y la flecha gira.
Aspecto fino: comparte las variables de los campos, --amset-field-* (alto, relleno, radio, fondo, borde y letra), así que se ve igual que un TextField a su lado; la flecha mide --amset-select-arrow. La lista se ajusta con amset-select__panel.
Cómo se ve
<Select
label="Plan"
placeholder="Elige una opcion"
options={[
{ key: 'basico', label: 'Basico' },
{ key: 'pro', label: 'Profesional', description: 'Soporte prioritario' },
{ key: 'empresa', label: 'Empresa' },
]}
/>Props
Se importa con import { Select } from '@amset/ui'. Las obligatorias van marcadas.
| Prop | Tipo | Para qué sirve |
|---|---|---|
labelobligatoria | string | — |
optionsobligatoria | readonly ListOption[] | — |
className | string | Se une a las clases de la biblioteca, no las sustituye. |
defaultOpen | boolean | La lista empieza abierta. Para fotografiar el panel en el banco. |
defaultValue | string | null | La clave elegida al empezar, sin controlarla desde fuera. |
disabled | boolean | — |
error | string | — |
excludeFromTabOrder | boolean | Fuera del orden del tabulador. Sigue siendo enfocable con la mano (`.focus()`), que es la diferencia con apagarlo: un control apagado no se puede enfocar de ninguna manera. |
hiddenLabel | boolean | La etiqueta solo para el lector de pantalla. Para cuando el campo va dentro de otro que ya se explica solo (el prefijo de un telefono), nunca para ahorrar espacio: sin etiqueta a la vista no se sabe que se elige. |
hint | string | — |
id | string | Va al DISPARADOR, que es el nodo enfocable y el que lleva el papel del campo: es a el a quien hay que poder apuntar desde fuera con un `aria-controls`, un paso de una visita guiada o un atajo. Lo de dentro (la etiqueta, la lista, la ayuda) sigue con sus `id` propios, derivados de este cuando se pasa, para que no se repitan con dos selectores en la misma pagina. |
invalid | boolean | — |
loading | boolean | Las opciones estan llegando. Marca el campo como ocupado, enseña un anillo y una fila `loadingText` en la lista; las opciones que ya hubiera se quedan. |
loadingText | string | Lo que dice la fila de carga. Por defecto, «Cargando…». |
name | string | Para que el valor viaje en un formulario nativo. |
native | boolean | Un `<select>` del SISTEMA en vez del panel propio. En un movil sale el selector de su sistema operativo, y es lo que se quiere cuando la lista es larga o se rellena con el dedo. Se pierden los iconos y las dos lineas por opcion (`renderOption`, `renderValue`, `icon`, `description`); los grupos (`group`) salen como `<optgroup>`. Mismo campo por fuera y mismas props. |
offset | number | Separación en píxeles entre el campo y la lista. Por defecto, ninguna. |
onBlur | () => void | Al salir del campo. Lo usa el formulario para marcar que se ha tocado. |
onChange | (key: string | null) => void | — |
onChangeEvent | (event: ChangeEvent<HTMLSelectElement>) => void | Con `native`: el evento del `<select>`, para migrar un manejador que lee `e.target.value`. `onChange` sigue entregando la clave, y se llaman los dos. |
onOpenChange | (open: boolean) => void | — |
open | boolean | Abierta o cerrada, mandado desde FUERA. Con esto el estado deja de vivir aqui: quien lo pasa decide, y `onOpenChange` le avisa de cada intento. Hace falta para abrir la lista desde otro sitio -un atajo de teclado, un paso de una visita guiada- sin tocar el disparador. |
panelWidth | "content" | "trigger" | Cuánto mide la lista de ancho. `trigger` (por defecto) la deja igual que el campo, que es lo que se espera de un selector normal. `content` la deja crecer hasta que quepan las opciones. Hace falta cuando el disparador es a propósito MÁS ESTRECHO que las opciones: el prefijo de un teléfono enseña «+34» y la lista dice «+34 · España». Medido antes de existir esto: el panel salía de 69 px y las 19 opciones aparecían cortadas a media palabra («Españ», «Portug»). |
placeholder | string | Texto cuando no hay nada elegido. No sustituye a la etiqueta. |
placement | Placement | Dónde sale la lista. Por defecto, pegada justo debajo del campo. |
readOnly | boolean | — |
renderOption | OptionRender<ListOption> | Pinta el interior de cada opcion de la lista: un avatar, dos lineas, un precio. El nombre que lee el lector de pantalla sigue siendo `label`. |
renderValue | (option: SelectOption) => ReactNode | Pinta lo elegido dentro del campo cerrado. Sin esto sale el icono y la etiqueta (o `shortLabel`). Lo que se anuncia es lo que se pinte, asi que conviene que lleve el texto. |
required | boolean | — |
shouldCloseOnSelect | boolean | Elegir una opcion NO cierra la lista. Por defecto la cierra, que es lo que espera cualquiera en un desplegable de una sola opcion; esto es para quien monta encima algo que deja seguir mirando. |
size | "sm" | "md" | "lg" | — |
validationBehavior | "aria" | "native" | — |
value | string | null | La clave elegida, controlada desde fuera. |
variant | FieldVariant | — |
Acepta además los atributos del elemento que pinta: className, style, data-*, aria-* y sus eventos.
Mandos
Estas variables CSS son la forma de adaptarlo. Se declaran sobre el selector del componente, no en :root: la hoja las redeclara en la propia regla y una declaración en el mismo elemento gana siempre.
| Variable | Por defecto |
|---|---|
--amset-select-arrow | 1rem |
Cómo se cambia
.amset-select {
--amset-select-arrow: ...;
}En el banco de pruebas
Cada estado y cada variante, para tocarlos de uno en uno, en su ficha de ui.amset.tech:
