Рейл категорий для вашего магазина на React

Рейлы категорий — тапабельный ряд разделов над сеткой витрины — это самые посещаемые контейнеры прокрутки в e-commerce, и они меню, а не карусели: каждая плитка — это ссылка, ничто не прилипает к позиции, а половина плитки, выглядывающая из-за края, и есть приглашение прокрутить.

Перетащите рейл или используйте стрелки — они отключаются на настоящих концах ряда.

Почему нативная прокрутка побеждает на витрине

Рейлы витрины живут в первом экране страниц, где вы боретесь за каждый балл Lighthouse. Карусельный движок поставляет десятки килобайт эмуляции жестов, чтобы делать то, что браузер делает нативно; эта библиотека — ≈5.7 kB min+gzip и оставляет прокрутку платформе, поэтому нет рывков гидратации — рейл прокручивается ещё до загрузки вашего JavaScript, а значит, работает и в серверно отрендеренном HTML, который видят краулеры. Эта страница сама служит серверным доказательством: демо выше прокручивается при отключённом JavaScript.

На странице сравнения есть полная таблица против Swiper, Embla, keen-slider и react-slick.

Отслеживание видимости — это функция витрины

Видимость по каждому элементу звучит как деталь реализации, пока вы не спроецируете её на мерчандайзинг:

Впишите его в вашу дизайн-систему

Плитки — это ваши компоненты: карточки с изображениями, круги, текстовые «пилюли» — каждая несёт itemId. Высота и ширина берутся из вашего CSS; меню не навязывает размеров. Шагайте по одному элементу за раз, как в товарном слайдере, с помощью one-item-scroll, покажите индикатор прогресса прокрутки или отправьте его в RTL для арабских и ивритских магазинов с помощью примера RTL — рейл это композиция, а не конфигурация.

Паттерн в минимальном виде

Плитки с itemId, стрелки из хуков видимости — весь рейл укладывается в сорок строк.

CategoryRail.tsx
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>
  );
}

Или установите как компонент shadcn

Базовый элемент реестра scroll-menu — это и есть данный рейл: стрелки в стиле shadcn, перетаскивание для прокрутки, скрытая полоса прокрутки — устанавливается в вашу components/ui/ и стилизуется вашими токенами:

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

Похожие примеры

Все примеры (21)