Horizontal scrolling menu component for React

Horizontal scrolling menu component for React

This is horizontal scrolling menu component for React. Menu component has adaptive width, just set width for parent container.

React horizontal scrolling menu


Build Status Coverage Status npm codebeat badge npm bundle size (minified + gzip) Donate


Demo on Codesandbox

This is horizontal scrolling menu component for React. Menu component has adaptive width, just set width for parent container. Items width will be determinated from css styles. Note: don't set margin for item wrapper, use padding instead. Can use margin for item element those you pass as props.

For navigation you can use arrows, mouse wheel or just drag items.

Component return items position, selected item and click event from callbacks.

Possible set default position and selected item on initialization.

Add star if you like project :)

Quick start

npm install --save react-horizontal-scrolling-menu

In project:

import React, { Component } from 'react';
import ScrollMenu from 'react-horizontal-scrolling-menu';
import './App.css';

// list of items
const list = [
  { name: 'item1' },
  { name: 'item2' },
  { name: 'item3' },
  { name: 'item4' },
  { name: 'item5' },
  { name: 'item6' },
  { name: 'item7' },
  { name: 'item8' },
  { name: 'item9' }

// One item component
// selected prop will be passed
const MenuItem = ({text, selected}) => {
  return <div
    className={`menu-item ${selected ? 'active' : ''}`}

// All items component
// Important! add unique key
export const Menu = (list, selected) =>
  list.map(el => {
    const {name} = el;

    return <MenuItem text={name} key={name} selected={selected} />;

const Arrow = ({ text, className }) => {
  return (

const ArrowLeft = Arrow({ text: '<', className: 'arrow-prev' });
const ArrowRight = Arrow({ text: '>', className: 'arrow-next' });

const selected = 'item1';

class App extends Component {
  constructor(props) {
    // call it again if items count changes
    this.menuItems = Menu(list, selected);

  state = {

  onSelect = key => {
    this.setState({ selected: key });

  render() {
    const { selected } = this.state;
    // Create menu from items
    const menu = this.menuItems;

    return (
      <div className="App">

In App.css

.menu-item {
  padding: 0 40px;
  margin: 5px 10px;
  user-select: none;
  cursor: pointer;
  border: none;
.menu-item-wrapper.active {
  border: 1px blue solid;
.menu-item.active {
  border: 1px green solid;

.scroll-menu-arrow {
  padding: 20px;
  cursor: pointer;


You can clone repository and run demo project from examples folder.

git clone https://github.com/asmyshlyaev177/react-horizontal-scrolling-menu
cd react-horizontal-scrolling-menu/examples
npm install
npm run start

Properties and callbacks

Props Type Description Required Default Value
alignCenter Boolean Try to align items by center false true
alignOnResize Boolean Try to align items after resize window false true
clickWhenDrag Boolean After drag end select item under cursor( if any) false false
dragging Boolean Allow drag items by mouse(and touch) false true
wheel Boolean Scroll with mouse wheel false true
arrowLeft React component React component for left arrow false null
data Array of react components Menu items, if empy render null (note, component must have unique key!) true []
hideArrows Boolean hide arrows if items fit to one screen, (add class scroll-menu-arrow--disabled to arrows) false false
arrowDisabledClass String The class name to append when arrows are disabled false "scroll-menu-arrow--disabled"
hideSingleArrow Boolean hide left/right arrows on first/last pages false false
transition Float number How long animation last, 0 for disable false 0.4
selected String or Number Initial selected item false 0
translate Number Initial offset false 0
dragging Boolean Allow drag items by mouse(and touch) false true
clickWhenDrag Boolean After drag end select item under cursor( if any) false false
menuClass String Class for component false 'horizontal-menu'
arrowClass String Class for arrow false 'scroll-menu-arrow'
wrapperClass String Class for wrapper in component false 'menu-wrapper'
innerWrapperClass String Class for inner wrapper false 'menu-wrapper--inner'
itemClass String Class for item wrapper false 'menu-item-wrapper'
itemClassActive String Class for active item wrapper false 'active'
menuStyle Object Styles for item wrapper false {display: 'flex', alignItems: 'center', userSelect: 'none'}
wrapperStyle Object Class for active item wrapper false {overflow: 'hidden', userSelect: 'none'}
onSelect Function Callback when item selected, return item key false null
onUpdate Function Callback when menu position changed, return { translate: 0 } false null
forwardClick Boolean When enabled passes onClick as a prop to the arrow and item components. Each item and arrow should handle the onClick callback false false
scrollToSelected Boolean Scroll to selected props passed on mount and when props changed false false
scrollBy Number How many menu items to scroll, 0 for all visible false 0

Programmaticaly change things

You can scroll left/right via componentRef.handleArrowClick() and componentRef.handleArrowClickRight() functions.

Can get other properties in component state - const { leftArrowVisible, rightArrowVisible, selected, translate } = componentRef.state

Can simulate click with componentRef.onItemClick('item4')

Can select and scroll to item with componentRef.scrollTo('item14')


  • Menu items must have width, if items contains images and images don't loaded yeat it can be problem. Generally component will try to determine width of items, if it can't you can assign ref to component and call $ref.setInitial() manually when items have width for sure.

  • Browser must support requestAnimationFrame or use polyfill.

  • It can doesn't work in IE, and I don't care, I am not a necrophile.(if you need it you can make PR, I will merge)


My first npm project. Sorry for my english.

Any contribution and correction appreciated. Just fork repo, commit and make PR, don't forget about tests.


1 Fork the repo:

  • In root folder run npm link
  • Run npm install in root folder
  • Remove react-horizontal-scrolling-menu from package.json example project
  • Run npm link react-horizontal-scrolling-menu && npm install
  • Run npm run start in root and in examples folders

2 Write code! Add some feature or fix bug.

3 Check that all tests passed and add tests for your code.

  • You can use npm run test:watch for run tests in watch mode

4 Update readme and example(if needed)

5 Run npm run build , make commit and Pull Request


Thanks goes to these wonderful people (emoji key):

Federico D. Ferrari


Github Repository