Uma trilha de categorias para sua loja, em React
Trilhas de categorias — a fileira tocável de departamentos acima da grade de uma loja — são os contêineres de rolagem de maior tráfego no e-commerce, e são menus, não carrosséis: cada bloco é um link, nada se encaixa, e meio bloco espiando na borda é o que convida à rolagem.
Arraste a trilha ou use as setas — elas se desativam nas extremidades reais da fileira.
Edite este exemplo ao vivo no Storybook
Por que a rolagem nativa vence em uma vitrine
Trilhas de vitrine ficam acima da dobra em páginas nas quais você briga por cada ponto do Lighthouse. Um motor de carrossel entrega dezenas de kilobytes de emulação de gestos para fazer o que o navegador já faz nativamente; esta biblioteca tem ≈5,7 kB min+gzip e deixa a rolagem por conta da plataforma, então não há travamento (jank) de hidratação — a trilha rola antes mesmo do seu JavaScript carregar, o que também significa que ela funciona no HTML renderizado no servidor que seus crawlers veem. Esta própria página é a prova renderizada no servidor: a demo acima rola com o JavaScript desativado.
A página de comparação tem a tabela completa contra Swiper, Embla, keen-slider e react-slick.
Rastreamento de visibilidade é uma funcionalidade de vitrine
Visibilidade por item soa como um detalhe de implementação até você mapeá-la para o merchandising:
- Imagens preguiçosas (lazy) — renderize um bloco placeholder até que
useIsVisibleinforme que ele está na tela. - Analytics de impressão —
getVisible()(ao vivo na demo do hero na página inicial) diz exatamente quais categorias foram vistas, não só que a trilha foi renderizada. - Setas sensíveis às bordas — desativam ou se escondem nas extremidades reais, mesmo depois que categorias carregam de forma assíncrona, como no exemplo add-items.
Encaixe no seu design system
Os blocos são seus componentes — cards de imagem, círculos, pílulas de texto — cada um carregando um itemId. Altura e largura vêm do seu CSS; o menu não impõe nenhuma dimensão. Avance um item por vez, como um slider de produto, com one-item-scroll, mostre um indicador de progresso de rolagem, ou entregue em RTL para lojas em árabe e hebraico com o exemplo RTL — a trilha é composição, não configuração.
O padrão, no mínimo
Blocos com um itemId, setas vindas dos hooks de visibilidade — a trilha inteira tem menos de quarenta linhas.
function CategoryRail({ categories }: { categories: Category[] }) {
return (
<ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
{categories.map((category) => (
<CategoryTile itemId={category.id} key={category.id} {...category} />
))}
</ScrollMenu>
);
}
function CategoryTile({ itemId, name, image }: CategoryTileProps) {
// Lazy images for free: placeholders until the tile is on screen.
const visibility = React.useContext<publicApiType>(VisibilityContext);
const isVisible = visibility.useIsVisible(itemId, false);
return (
<a href={`/category/${itemId}`} className="rail-tile">
{isVisible ? <img src={image} alt="" /> : <div className="ph" />}
<span>{name}</span>
</a>
);
}
function LeftArrow() {
const visibility = React.useContext<publicApiType>(VisibilityContext);
const atStart = visibility.useLeftArrowVisible();
return (
<button disabled={atStart} onClick={() => visibility.scrollPrev()}>
←
</button>
);
}Ou instale como um componente shadcn
O item de registro base scroll-menu é essa mesma trilha — setas estilizadas pelo shadcn, arraste para rolar, barra de rolagem escondida — instalado no seu components/ui/ e estilizado pelos seus tokens:
npx shadcn@latest add https://react-horizontal-scrolling-menu.dev/r/scroll-menu.json