Wondering what’s next for npm?Check out our public roadmap! »

    react-horizontal-scrolling-menu
    TypeScript icon, indicating that this package has built-in type declarations

    0.7.10 • Public • Published

    React horizontal scrolling menu

    example

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

    Demo

    Demo on Codesandbox

    Sorry, don't have much time to fix existing bugs, have full-time job and life, but working on v2 on free time, it's on early stages for now.

    This is a horizontal scrolling menu component for React. Menu component has adaptive width, just set width for parent container. Items width will be determined from CSS styles.

    Note: I don't have much time for project support. Any help is appreciated.

    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.

    if you like the 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' : ''}`}
        >{text}</div>;
    };
    
    // 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 (
        <div
          className={className}
        >{text}</div>
      );
    };
    
    
    const ArrowLeft = Arrow({ text: '<', className: 'arrow-prev' });
    const ArrowRight = Arrow({ text: '>', className: 'arrow-next' });
    
    const selected = 'item1';
    
    class App extends Component {
      constructor(props) {
        super(props);
        // call it again if items count changes
        this.menuItems = Menu(list, selected);
      }
    
      state = {
        selected
      };
    
      onSelect = key => {
        this.setState({ selected: key });
      }
    
    
      render() {
        const { selected } = this.state;
        // Create menu from items
        const menu = this.menuItems;
    
        return (
          <div className="App">
            <ScrollMenu
              data={menu}
              arrowLeft={ArrowLeft}
              arrowRight={ArrowRight}
              selected={selected}
              onSelect={this.onSelect}
            />
          </div>
        );
      }
    }

    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;
    }

    Example

    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
    arrowRight React component React component for right 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
    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'
    innerWrapperStyle Object Styles inner wrapper false {textAlign: 'left'}
    innerWrapperClass String Class for inner wrapper false 'menu-wrapper--inner'
    itemStyle Object Styles for item wrapper false {display: 'inline-block'}
    itemClass String Class for item wrapper false 'menu-item-wrapper'
    itemClassActive String Class for active item wrapper false 'active'
    menuStyle Object Styles for root menu component false {display: 'flex', alignItems: 'center', userSelect: 'none'}
    wrapperStyle Object Style for outer wrapper false {overflow: 'hidden', userSelect: 'none'}
    onFirstItemVisible Function Callback for first item visible false () => false
    onLastItemVisible Function Callback for last item visible (for example for LazyLoad more items) false () => false
    onSelect Function Callback when item selected, return item key false null
    onUpdate Function Callback when menu position changed, return { translate: 0 } false null
    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
    inertiaScrolling Boolean Use inertia for scrolling, duration depends on transition and slowdown false false
    inertiaScrollingSlowdown Float Number Slow down factor for inertia scrolling false 0.25
    useButtonRole Boolean Adding role="button" to every item false true
    disableTabindex Boolean Removing tabindex="0" false false
    rtl Boolean Reverse the scroll direction (component should have a parent with dir="rtl" in the DOM tree false false

    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')

    Gotchas

    • Menu items must have width. If items contain images and images are not loaded yet it can be a problem. Generally component will try to determine the width of items, if it can't you can assign ref to component and call $ref.setInitial() manually when items have the width for sure.
    • Browser must support requestAnimationFrame or use polyfill.
    • It may not work in IE. (if you need it you can make a PR, I will merge)

    About

    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.

    Contributing

    1 Fork the repo:

    • Run npm install in root folder
    • In root folder run npm link
    • Go to example project folder (examples)
    • Run npm install && npm link react-horizontal-scrolling-menu
    • Run npm run start in root folder and after that 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 Make commit and Pull Request

    Contributors

    Thanks goes to these wonderful people (emoji key):

    Federico D. Ferrari
    Federico D. Ferrari

    💻
    Alex Oxrud
    Alex Oxrud

    💻 📖
    Francisco
    Francisco

    💻 ⚠️
    entkenntnis
    entkenntnis

    💻 📖
    Brandon Apanui
    Brandon Apanui

    💻
    Yevhenii Melikov
    Yevhenii Melikov

    💻
    Burak Targaç
    Burak Targaç

    💻
    Bogdan
    Bogdan

    💻 ⚠️
    Rob Gordon
    Rob Gordon

    💻
    Denis Lukov
    Denis Lukov

    💻
    Gustavo Ribeiro
    Gustavo Ribeiro

    🐛 💻 ⚠️
    Dragoș Străinu
    Dragoș Străinu

    📖 🤔 🌍

    This project follows the all-contributors specification. Contributions of any kind welcome!

    Install

    npm i react-horizontal-scrolling-menu

    DownloadsWeekly Downloads

    26,880

    Version

    0.7.10

    License

    ISC

    Unpacked Size

    79.4 kB

    Total Files

    17

    Last publish

    Collaborators

    • avatar