
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
accessible-search-select
Advanced tools
Un componente de selección con buscador integrado, reutilizable y tipado en TypeScript. Soporta selección única o múltiple y filtrado en memoria.
Un componente de selección con buscador integrado, reutilizable y tipado en TypeScript.
Soporta selección única o múltiple y filtrado en memoria.

npm install accessible-search-select
# o
yarn add accessible-search-select
Esta librería utiliza React hooks, por lo que necesita que React esté instalado en tu proyecto.
npm install react react-dom
import { SelectSearch } from "accessible-search-select";
interface User {
id: number;
name: string;
}
const users: User[] = [
{ id: 1, name: "Juan" },
{ id: 2, name: "María" },
{ id: 3, name: "Pedro" },
];
export default function App() {
return (
<SelectSearch<User>
options={users}
optionLabel="name"
optionValue="id"
onChange={(value) => console.log("Seleccionado:", value)}
placeholder="Buscar usuario..."
noResultsText="Sin resultados"
/>
);
}
💡 Nota: El tipo
Useres solo un ejemplo. El componenteSelectSearches genérico (<T>) y funciona con cualquier estructura de datos.
| Prop | Tipo | Requerido | Descripción |
|---|---|---|---|
options | T[] | ✅ | Lista de opciones a mostrar. |
optionLabel | keyof T | ✅ | Clave del objeto que se mostrará como texto en la lista. |
optionLabel2 | keyof T | ❌ | Clave opcional del objeto que se mostrará como texto secundario (entre paréntesis). |
optionValue | keyof T | ✅ | Clave del objeto que se usará como valor único de la opción. |
value | T | T[] | ❌ | Valor actual (single o multiple). |
onChange | (value: T | T[] | null) => void | ✅ | Se ejecuta al seleccionar/deseleccionar opciones. |
multiple | boolean | ❌ | Habilita selección múltiple. Default: false. |
placeholder | string | ❌ | Texto del input de búsqueda. |
ariaInputLabel | string | ❌ | Texto accesible para el input. Default: "Buscar opción". |
ariaListboxLabel | string | ❌ | Texto accesible para el listbox. Default: "Opciones disponibles". |
noResultsText | string | ❌ | Texto mostrado si no hay coincidencias. |
className | string | ❌ | Clase CSS personalizada para el contenedor. |
import { useState } from "react";
import { SelectSearch } from "accessible-search-select";
interface User {
id: number;
name: string;
}
const users: User[] = [
{ id: 1, name: "Juan" },
{ id: 2, name: "María" },
{ id: 3, name: "Pedro" },
];
export default function App() {
const [selectedUsers, setSelectedUsers] = useState<User[] | null>([]);
return (
<div>
<SelectSearch<User>
options={users}
optionLabel="name"
optionValue="id"
multiple
value={selectedUsers}
onChange={setSelectedUsers}
placeholder="Buscar..."
noResultsText="Nada encontrado"
/>
{selectedUsers && selectedUsers.length > 0 && (
<p>
Usuarios seleccionados:{" "}
{selectedUsers.map(u => u.name).join(", ")}
</p>
)}
</div>
);
}
La búsqueda actualiza searchTerm, se filtran las opciones y se renderiza la lista.
Al seleccionar, se llama onChange devolviendo un elemento único o un array según multiple.
⚡ Accesibilidad:
El componente está diseñado para ser completamente accesible, compatible con lectores de pantalla y navegación con teclado.
aria-label (o ariaInputLabel) para describir su función.role="listbox" y aria-multiselectable si es selección múltiple.role="option" y aria-selected según su estado.aria-activedescendant apuntando al elemento resaltado (highlightedIndex), aunque no haya focus real en el li.Puedes pasar tu propia clase al componente usando la prop className para aplicar estilos externos a los elementos internos (input, ul, li).
import "accessible-search-select/style.css"; // Importa los estilos por defecto (opcional)
<SelectSearch<User>
className="mi-select-search"
options={users}
optionLabel="name"
optionValue="id"
onChange={(v) => console.log(v)}
placeholder="Buscar..."
/>
El componente utiliza las siguientes clases para aplicar estilos, siguiendo la convención BEM:
| Clase | Descripción |
|---|---|
select-search__container | Contenedor principal del componente. |
select-search__input | El input de búsqueda. |
select-search__list | Lista (ul) que contiene los elementos filtrados. |
select-search__item | Cada elemento (li) de la lista. |
select-search__label2 | Texto secundario opcional (derivado de optionLabel2). Aparece entre paréntesis junto al label principal. |
select-search__item--highlighted | Modificador visual para el elemento actualmente resaltado por navegación con teclado (no es focus real; se usa con aria-activedescendant). |
select-search__item--selected | Modificador para un elemento seleccionado. |
select-search-no-results | Mensaje que aparece cuando no hay resultados. |
💡 Nota: Las clases listadas arriba ya vienen preestilizadas en el CSS que exporta la librería, pero puedes sobrescribir sus estilos usando tu propia clase a través de la prop
className.
/* =============================
Contenedor principal (opcional)
============================= */
.mi-select-search {
/* Estilos para el contenedor principal */
}
/* =============================
Input de búsqueda
============================= */
.mi-select-search .select-search__input {
/* Sobrescribe estilos si lo deseas */
}
/* =============================
Lista de opciones
============================= */
.mi-select-search .select-search__list {
/* Sobrescribe estilos si lo deseas */
}
/* =============================
Elemento de lista
============================= */
.mi-select-search .select-search__item {
/* Estilos base para cada opción */
}
/* =============================
Segundo label opcional
============================= */
.mi-select-search .select-search__label2 {
/* Sobrescribe/resalta estilos si lo deseas */
}
/* =============================
Elemento actualmente resaltado
============================= */
.mi-select-search .select-search__item--highlighted {
/* Resalta el item seleccionado por teclado */
}
/* =============================
Elemento seleccionado
============================= */
.mi-select-search .select-search__item--selected {
/* Estilos para la opción seleccionada */
}
/* =============================
Mensaje de "sin resultados"
============================= */
.mi-select-search .select-search-no-results {
/* Estilos para el mensaje */
}
💡 Nota: Al pasar tu propia clase al componente mediante la prop
className, puedes sobrescribir los estilos de las clases internas (select-search__input,select-search__list,select-search__item, etc.) que ya vienen preestilizadas en el CSS de la librería.
Estructura interna

En la imagen puedes ver la estructura interna del componente: un input seguido por un ul con li para cada opción.
MIT
FAQs
Un componente de selección con buscador integrado, reutilizable y tipado en TypeScript. Soporta selección única o múltiple y filtrado en memoria.
We found that accessible-search-select demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.