---
title: "Chips de filtro en React en una barra desplazable"
description: "Una barra horizontal de chips de filtro en React: los chips se desplazan de forma nativa, añadir un chip lo lleva a la vista, arrastre sin romper los clics. Demo en vivo y código."
canonical: "https://react-horizontal-scrolling-menu.dev/es/filter-chips"
image: "https://react-horizontal-scrolling-menu.dev/og.png"
---

# Una barra de chips de filtro que se desplaza, en React

La fila de chips bajo cualquier barra de búsqueda —temas de YouTube, filtros de tienda, selectores de etiquetas— es un contenedor de scroll de una sola línea lleno de botones de alternar. El 10% difícil es lo que pasa en los bordes: chips nuevos que aparecen fuera de pantalla, arrastres que no deben activar nada y flechas que saben cuándo son inútiles.

react

typescript

scrolling

menu

gallery

tabs

carousel

slider

accordion

lightbox

Add filter

Añade un filtro: la fila desplaza sola el nuevo chip hasta que sea visible.

[Edita este ejemplo en vivo en Storybook](https://asmyshlyaev177.github.io/react-horizontal-scrolling-menu/?path=/story/examples-additemandscrolltoit--add-item-and-scroll-to-it)

## Los casos límite son la característica

Cualquier fila flex con `overflow-x: auto` se desplaza. Una barra de chips se gana el puesto en los detalles:

-   **Un chip añadido fuera de pantalla debe anunciarse.** La demo se desplaza hasta cada chip nuevo con `apiRef.current.scrollToItem(el, 'smooth', 'end')` tras el renderizado; el [ejemplo de añadir-elemento-y-desplazarse-hasta-él](https://react-horizontal-scrolling-menu.dev/es/examples/add-item-and-scroll-to-it.md) es exactamente este cableado.
-   **Arrastrar para desplazar, hacer clic para alternar, nunca ambos.** Los usuarios de escritorio arrastran la fila como una superficie táctil; soltar sobre un chip no debe activarlo. La [receta de arrastre](https://react-horizontal-scrolling-menu.dev/es/examples/mouse-drag.md) sigue el gesto y suprime justo ese clic.
-   **Flechas solo cuando son útiles.** `useLeftArrowVisible` / `useRightArrowVisible` están conectadas al mismo IntersectionObserver que todo lo demás, así que las flechas se desactivan en los bordes reales, incluso después de añadir o quitar chips.

## El estado queda en tus manos

La librería desplaza; no controla la selección. Los chips son tus botones —`aria-pressed` para alternar en selección múltiple, estado normal para selección única— y el menú solo necesita que cada uno lleve un `itemId`. Eso significa que el estado de los chips encaja con lo que ya tengas: parámetros de búsqueda en la URL, una librería de formularios, un modelo de filtro gestionado por el servidor. Eliminar un chip es [quitar un elemento](https://react-horizontal-scrolling-menu.dev/es/examples/add-items.md); animarlo al salir es el [ejemplo de animación de elementos](https://react-horizontal-scrolling-menu.dev/es/examples/items-animation.md).

## Móvil: un aviso sobre el scroll del body

En pantallas táctiles, un deslizamiento horizontal dentro de la barra puede arrastrar la página entera con él en algunos navegadores. Si ves eso, el [ejemplo de prevenir el scroll del body](https://react-horizontal-scrolling-menu.dev/es/examples/prevent-body-scroll.md) muestra el `touch-action` y la contención de overscroll para bloquearlo: solo CSS, sin librería de gestos.

## El patrón, en su forma mínima

Los chips son botones de alternar con un `itemId`; una ref a la API del menú desplaza un chip recién añadido hasta que sea visible.

ChipBar.tsx

```
function ChipBar({ options }: { options: string[] }) {
  const apiRef = React.useRef<publicApiType>(null);
  const [selected, setSelected] = React.useState<string[]>([]);

  const toggle = (id: string) =>
    setSelected((cur) =>
      cur.includes(id) ? cur.filter((c) => c !== id) : [...cur, id],
    );

  // A chip appended off-screen scrolls itself into view.
  const addChip = (id: string) => {
    toggle(id);
    requestAnimationFrame(() => {
      const el = apiRef.current?.getItemElementById(id);
      if (el) apiRef.current?.scrollToItem(el, 'smooth', 'end');
    });
  };

  return (
    <ScrollMenu apiRef={apiRef}>
      {options.map((id) => (
        <Chip itemId={id} key={id} pressed={selected.includes(id)}
          onToggle={() => toggle(id)} />
      ))}
    </ScrollMenu>
  );
}
```

## O instálalo como componente shadcn

El elemento del registro [chip-bar](https://react-horizontal-scrolling-menu.dev/r/chip-bar.json) lo distribuye como componente controlado —`options`, `selected`, `onSelectedChange`— con estilos Tailwind en tu `components/ui/`:

shadcn

```
npx shadcn@latest add https://react-horizontal-scrolling-menu.dev/r/chip-bar.json
```

## Ejemplos relacionados

-   [Añadir un elemento y desplazarse a élEl patrón de chips de filtro: añadir y luego traer a la vista.](https://react-horizontal-scrolling-menu.dev/es/examples/add-item-and-scroll-to-it.md)
-   [Cargar más cuando aparece el finalAñadido infinito impulsado por la visibilidad del último elemento.](https://react-horizontal-scrolling-menu.dev/es/examples/add-items.md)
-   [Evitar el desplazamiento del bodyLa rueda sobre el menú desplaza el menú, no la página.](https://react-horizontal-scrolling-menu.dev/es/examples/prevent-body-scroll.md)

[Todos los ejemplos (21)](https://react-horizontal-scrolling-menu.dev/es/examples.md)

---

More examples: <https://react-horizontal-scrolling-menu.dev/examples.md>
Library summary for LLMs: <https://react-horizontal-scrolling-menu.dev/llms.txt>
