React Dropdown Menu

Related tags

Menu react-dd-menu
Overview

react-dd-menu

A React dropdown menu

Live Example: React Dropdown Menu

NOTE: I am no longer actively developing this project since it has met most of the initial goals and I will be spending most of my time developing the bigger project react-md. I am more than happy to keep review/accepting pull requests with new features/bugfixes though.

Installation

$ npm install -S react-dd-menu \
                 # If you haven't installed already
                 react \
                 react-dom \
                 react-transition-group

Props

DropdownMenu
  static MENU_SIZES = ['sm', 'md', 'lg', 'xl']
  static ALIGNMENTS = ['center', 'right', 'left']

  static propTypes = {
    isOpen: PropTypes.bool.isRequired,
    close: PropTypes.func.isRequired,
    toggle: PropTypes.node.isRequired,
    children: PropTypes.node,
    inverse: PropTypes.bool,
    align: PropTypes.oneOf(ALIGNMENTS),
    animAlign: PropTypes.oneOf(ALIGNMENTS),
    textAlign: PropTypes.oneOf(ALIGNMENTS),
    menuAlign: PropTypes.oneOf(ALIGNMENTS),
    className: PropTypes.string,
    size: PropTypes.oneOf(MENU_SIZES),
    upwards: PropTypes.bool,
    animate: PropTypes.bool,
    enterTimeout: PropTypes.number,
    leaveTimeout: PropTypes.number,
    closeOnInsideClick: PropTypes.bool,
    closeOnOutsideClick: PropTypes.bool,
  }

  static defaultProps = {
    inverse: false,
    align: 'center',
    animAlign: null,
    textAlign: null,
    menuAlign: null,
    className: null,
    size: null,
    upwards: false,
    animate: true,
    enterTimeout: 150,
    leaveTimeout: 150,
    closeOnInsideClick: true,
    closeOnOutsideClick: true,
  }
  • isOpen - Boolean for telling if the menu is open. This was passed in as a prop instead of having the component's own state so you can decide when to close the menu on your own.
  • close - a function to call that turns the isOpen boolean to false
  • toggle - any renderable item that will be used to toggle the menu open. So normally a button or any other content.
  • inverse - boolean if it is an inversed color menu
  • align - the alignment for the animation, text, and menu if the specific props are not given. Defaults to center
  • animAlign - the alignment/direction that the menu will appear from
  • textAlign - the alignment of each list item's text
  • menuAlign - the alignment of the menu to the toggle element
  • size - the size of the menu. Defaults to auto size.
  • className - any additional css classes to add the the dropdown menu container. (.dd-menu)
  • upwards - boolean if the menu should go upwards. Defaults to false
  • animate - boolean if the menu should animate on open and close. Defaults to true
  • enterTimeout - the amount of time in ms to end the CSSTransitionGroup. Defaults to 150
  • leaveTimeout - the amount of time in ms to end the CSSTransitionGroup. Defaults to 150
  • closeOnInsideClick - a boolean if the menu should close when you click inside the menu. Defaults to true
  • closeOnOutsideClick - a boolean if the menu should close when you click elsewhere on the page. Defaults to true
NestedDropdownMenu
  static propTypes = {
    toggle: PropTypes.node.isRequired,
    children: PropTypes.node,
    nested: PropTypes.oneOf(['inherit', 'reverse', 'left', 'right']),
    animate: PropTypes.bool,
    direction: PropTypes.oneOf(['left', 'right']),
    upwards: PropTypes.bool,
    delay: PropTypes.number,
    enterTimeout: PropTypes.number,
    leaveTimeout: PropTypes.number,
    openOnMouseover: PropTypes.bool,
  }

  static defaultProps = {
    nested: 'reverse',
    animate: false,
    direction: 'right',
    upwards: false,
    delay: 500,
    enterTimeout: 150,
    leaveTimeout: 150,
    openOnMouseover: true,
  }
  • toggle - an renderable item that will open the nested menu on hover. It gets wrapped in a li element, so it might be best to have a button or a link tag.
  • nested - the nested menu's expansion direction. The default case should hopefully be the only used case.
    • Inherit - If the main dropdown menu is aligned left, the nested menu will appear to the left as well.
    • Reverse - If the main dropdown menu is aligned left, the nested menu will appear to the right.
    • Left - Force the menu to appear to the left of the menu.
    • Right - Force the menu to appear to the right of the menu.
  • animate - boolean if the nested menu should animate when appearing. Defaults to false
  • direction - The animation direction.
  • upwards - boolean if the nested menu should render upwards. Defaults to false
  • delay - A number in ms to allow the mouse to be off of the dropdown menu to close it. Defaults to 500ms
  • enterTimeout - the amount of time in ms to end the CSSTransitionGroup. Defaults to 150
  • leaveTimeout - the amount of time in ms to end the CSSTransitionGroup. Defaults to 150
  • openOnMouseover - boolean if the menu can be opened/close by mouseover/mouseleave events

Styling

In the dist folder, there is a react-dd-menu.css and a react-dd-menu.min.css with the default css stylings. If you have SASS, the source is located in src/scss.

If you don't want the default css or to edit the default, the layout is this:

.dd-menu
| -- toggle component
| -- .dd-menu-items
|    | -- ul
|    |    | [role="separator"], .separator

The separator can be any element with a classname of .separator or any element with a role of separator (or both). To get the best styling, it should probably be applied to an li element.

Usage

Click me!, align: 'right' }; return (
  • Example 1
  • ); } } ">
    import React from 'react';
    import DropdownMenu from 'react-dd-menu';
    
    export default class Example extends React.Component {
      constructor() {
        super();
        this.state = {
            isMenuOpen: false
        };
        this.click = this.click.bind(this);
        this.toggle = this.toggle.bind(this);
        this.close = this.close.bind(this);
      }
    
      toggle() {
        this.setState({ isMenuOpen: !this.state.isMenuOpen });
      }
    
      close() {
        this.setState({ isMenuOpen: false });
      }
    
      click() {
        console.log('You clicked an item');
      }
    
      render() {
        const menuOptions = {
          isOpen: this.state.isMenuOpen,
          close: this.close,
          toggle: <button type="button" onClick={this.toggle}>Click me!</button>,
          align: 'right'
        };
        return (
          <DropdownMenu {...menuOptions}>
            <li><a href="#">Example 1</a></li>
            <li><button type="button" onClick={this.click}>Example 2</button></li>
          </DropdownMenu>
        );
      }
    }

    or..

    Click me!, align: 'right' } return (
  • Example 1
  • ); } }); ">
    var React = require('react');
    var DropdownMenu = require('react-dd-menu');
    
    var Example = React.createClass({
      getInitialState: function() {
        return { isMenuOpen: false };
      },
    
      toggle: function() {
        this.setState({ isMenuOpen: !this.state.isMenuOpen });
      },
    
      close: function() {
        this.setState({ isMenuOpen: false });
      },
    
      click: function() {
        console.log('You clicked an item');
      },
    
      render: function() {
        var menuOptions = {
          isOpen: this.state.isMenuOpen,
          close: this.close,
          toggle: <button type="button" onClick={this.toggle}>Click me!</button>,
          align: 'right'
        }
        return (
          <DropdownMenu {...menuOptions}>
            <li><a href="#">Example 1</a></li>
            <li><button type="button" onClick={this.click}>Example 2</button></li>
          </DropdownMenu>
        );
      }
    });

    Nested Menu Example

    Click me!, align: 'right', }; const nestedProps = { toggle: Hover me for Nested Menu!, animate: true, }; return (
  • Example 1
  • I am in a Nested Menu!
  • ); } } ">
    'use strict';
    
    import React from 'react';
    import DropdownMenu, { NestedDropdownMenu } from 'react-dd-menu';
    
    class Example extends React.Component {
      state = { isMenuOpen: false };
    
      toggle = () => {
        this.setState({ isMenuOpen: !this.state.isMenuOpen });
      }
    
      close = () => {
        this.setState({ isMenuOpen: false });
      };
    
      click = () => {
        console.log('You clicked an item');
      };
    
      render() {
        const menuOptions = {
          isOpen: this.state.isMenuOpen,
          close: this.close,
          toggle: <button type="button" onClick={this.toggle}>Click me!</button>,
          align: 'right',
        };
    
        const nestedProps = {
          toggle: <a href="#">Hover me for Nested Menu!</a>,
          animate: true,
        };
    
        return (
          <DropdownMenu {...menuOptions}>
            <li><a href="#">Example 1</a></li>
            <li><button type="button" onClick={this.click}>Example 2</button></li>
            <li role="separator" className="separator" />
            <NestedDropdownMenu {...nestedProps}>
              <li><a href="#">I am in a Nested Menu!</a></li>
            </NestedDropdownMenu>
          </DropdownMenu>
        );
      }
    }

    Contributors/Local Changes

    To rebuild the source:

    $ npm run build

    This will output all the css and js files into ./dist;

    Versions

    • 0.0.2 - Fixed removing the click event listener
    • 0.0.3 - Positioning fixes and convenience props for different dropdown menu configs
    • 0.0.4 - Fixed width for firefox and added convenience props for sizes
    • 0.0.5 - Fixed Button font size, added examples
    • 1.0.0 - Added nested dropdown menus, a separator class, drop-up? menus.
    • 1.0.1 - Fixed exports for ES5 :(
    • 1.0.2 - Added delay to nested dropdown menu closing and added github page for examples.
    • 1.0.3 - Fixed problem with multiple menus and added ability to disable animation
    • 1.0.4 - Upgraded to React 0.14.0
    • 1.0.5 - Added ability to disable onClickInside and onClickOutside close of the menus. Added Touch/click support for nested menus.
    • 1.0.6 - No new features. Upgraded dev stuff to babel 6 and separated example
    • 1.0.7 - Updated to support React 15 as peer dependencies. No real changes needed
    • 2.0.0 - Removed PureRenderMixin peerDependecy and switched to PureComponent instead.
    • 2.0.1 - Updated for React 15.5
    • 2.0.2 - Small bugfix for any child elements that had onClick handlers. [#52]
    Comments
    • Replace PureRenderMixin with PureComponent

      Replace PureRenderMixin with PureComponent

      Hi, thanks for creating this component!

      The only thing I dislike is that it requires me to add an extra dependency to my package.json: react-addons-pure-render-mixin. Also, the React team are now discouraging this in favor of React.PureComponent:

      The PureRenderMixin mixin predates React.PureComponent. This reference doc is provided for legacy purposes, and you should consider using React.PureComponent instead.

      https://facebook.github.io/react/docs/pure-render-mixin.html

      I'd be happy to make a pull request, but PureComponent was only introduced this July in 15.3.0, and so it would cause problems for anyone who hasn't updated React since July, so I guess it would also require a version bump. I was wondering if/how you would like to handle this?

      enhancement 
      opened by evoyy 3
    • Update to react 15

      Update to react 15

      Hi,

      We are looking to upgrade to react 15, but this library doesn't like that as a peer dependency. Any objections to a pull request making that change?

      opened by jtadmor 3
    • Allow user to control click handling

      Allow user to control click handling

      I added the ability to pass in two props:

      closeOnInsideClick closeOnOutsideClick

      These would allow the user to control whether clicks close the menu, as sometimes this behavior is not desired (e.g. I was trying to have a dropdown menu with a search bar in it, but clicking on the search bar to focus it would close the menu).

      I was also unable to build using the existing build file because I don't have the Ruby Sass Gem, so I updated that to use gulp-sass instead of gulp-ruby-sass in case others were having the same issue. If you don't want to change that, we could just move the new dist / index files over.

      enhancement 
      opened by jtadmor 3
    • Handle Multiple Nested Menus Closing at the Same TIme (Animated Only)

      Handle Multiple Nested Menus Closing at the Same TIme (Animated Only)

      If there are multiple nested dropdown menus open, and the entire menu is closed (either moving the mouse off the menu, clicking somewhere on the screen, or the toggle) There is an error "Unable to access componentDidLeave on null component". This happens with the ReactCSSTransitionGroup.

      Solution: Either figure out how to close menus in order from farthest nested up, possibly disable transition for closing, or find some other solution.

      This actually causes no problem wioth the menu, would just be nice to eliminate any console error messages..

      bug 
      opened by mlaursen 1
    • Updated ES6 example to be valid and contain no linting errors

      Updated ES6 example to be valid and contain no linting errors

      The ES6 example used a few unrecommended JS techniques (binding in the render method etc). I've updated the code to remove all these issues and any accompanying linting errors.

      opened by richardwillars 0
    • Removed the PureRenderMixin Peer Dependency #34

      Removed the PureRenderMixin Peer Dependency #34

      Ever since React 15.3.0, there has been a PureComponent implementation that makes the PureRenderMixin obsolute. And since mixins were already a thing of the past, I removed it from this library.

      opened by mlaursen 0
    • Added #16: Nested Dropdown Menu Delay

      Added #16: Nested Dropdown Menu Delay

      Added the nested dropdown menu delay to have a default time of 500ms. Removed the examples from the git repo since it isn't really helpful to view those babelified files. Updated readme with new info.

      opened by mlaursen 0
    • Add a Delay to NestedDropdownMenu blur/leave

      Add a Delay to NestedDropdownMenu blur/leave

      Need to add some sort of delay so that the nested dropdown menu doesn't close instantly if the user accidentally moves the mouse outside of the menus. A good default is 500ms.

      enhancement 
      opened by mlaursen 0
    • Align property does not work

      Align property does not work

      I can't get the align property (other than center) to function. Using either right or left option is always left aligned.

      Also tested with the Options example and the issue is present there too.

      opened by replaysMike 2
    • How to deal with dropdown being hidden

      How to deal with dropdown being hidden

      I want to add a menu to a fixed header. The header CSS is basically:

      position: fixed;
      top: 0;
      left: 0;
      height: 60px;
      width: 100%;
      z-index: 2;
      

      If I try to add a <DropdownMenu> to an element in the header, most of the menu itself will be hidden because obviously the parent element is only 60px tall.

      Is there some mechanism in react-dd-menu or some workaround to get around this?

      opened by denchen 1
    • Invoke `props.close` on unmount

      Invoke `props.close` on unmount

      Would it make sense to invoke props.close in componentWillUnmount? Currently I render x amount of dropdowns in a component. These dropdowns' open/closed state are kept in global state. These dropdowns can also be arbitrarily removed in real-time via websocket events. When they are removed when they are open, it'll keep its global state as open. By having DropdownMenu invoke props.close in unmount I can "circumvent" this.

      I can work around this by creating a wrapper component for DropdownMenu that handles this, but was wondering if you thought it'd be a good idea to keep it in this component?

      opened by williamboman 1
    • onClick event not triggered

      onClick event not triggered

      Hi,

      I try to use an onClick event for the menu items in my menu, but none of these events ever get fired (console.log('You clicked an item');)

      I tried the exact same code from the example at https://github.com/mlaursen/react-dd-menu but without luck. Any idea why these events are not triggered? Thanks in advance!

      opened by emwee 2
    Owner
    Mikkel Laursen
    Maintainer of react-md
    Mikkel Laursen
    React dropdown menu components

    react-menu-list This project is a set of components for building menus. This project works well for dropdown and autocomplete menus. The menus are cor

    Streak 79 Nov 16, 2022
    Left navigation menu. Get data from JSON file and display simple form menu.

    Left Navbar Menu Left navigation menu. Get data from JSON file and display simple form menu. User Interface created using React and Typescript. App st

    Wojtek 5 May 24, 2021
    A simple Hook for creating fully accessible dropdown menus in React

    This Hook handles all the accessibility logic when building a dropdown menu, dropdown button, etc., and leaves the design completely up to you. It also handles the logic for closing the menu when you click outside of it.

    Sparksuite 111 Dec 22, 2022
    Customizable and responsive react sidebar library with dropdown menus and unlimited number of nested submenus

    React Pro Sidebar Customizable and responsive react sidebar library with dropdown menus and unlimited number of nested submenus Demo Live preview Scre

    Mohamed Azouaoui 946 Jan 1, 2023
    Animated hamburger menu icons for React (1.5 KB) 🍔

    ‌ ‌ Animated hamburger menu icons for React Hamburger menu icons for React, with CSS-driven transitions. Created to be as elegant and performant as po

    Luuk de Vlieger 709 Dec 31, 2022
    Hamburger Menu React JS Using Third Party Package ReactJS - Popup

    In this project, let's build a Hamburger Menu app by applying the concepts we have learned till now. Refer to the image below: Design Files Click to v

    null 2 Dec 6, 2021
    Simple Context menu component for react showing all parent's node menus in theirs contexts.

    Simple Context menu component for react showing all inherited parents menu with SSR compatibility.

    Nathan Braun 6 Nov 13, 2022
    A simple, data-driven, light-weight React Tree Menu component

    React Simple Tree Menu Inspired by Downshift, a simple, data-driven, light-weight React Tree Menu component that: does not depend on any UI framework

    Huang-Ming Chang 120 Dec 1, 2022
    A simple sliding side menu component for React

    Cheeseburger Menu A simple sliding side menu component for React. This component provides the sliding menu only, not the hamburger button. For your bu

    Eddie McLean 19 May 27, 2022
    Add a context menu to your react app with ease

    Documentation Go here. Installation Using yarn $ yarn add react-contexify Using npm $ npm install --save react-contexify The gist import React from 'r

    Fadi Khadra 868 Jan 8, 2023
    A react component that displays an unlimited deep menu

    react-infinity-menu An unlimited deep side menu Live Demo Demo Installation npm install react-infinity-menu How to use import InfinityMenu from "react

    Social Tables 58 Dec 5, 2022
    Radial Menu for FiveM,built with React

    BCS Radial Menu This project is to freshen up the options for free radial menu f

    BagusCodeStudio 13 Nov 7, 2022
    🍪 A stylized command menu for React.

    ?? Superkey is under development and is not ready for production. If you have any bugs or problems please create an issue. ?? Website (working ?? ) •

    Pablo Hdez 57 Dec 31, 2022
    📱 A performant, easy to use hold to open context menu for React Native powered by Reanimated 🚀

    React Native Hold Menu A performant, easy to use hold to open context menu for React Native powered by Reanimated. ?? This package is experimental and

    Enes 1k Jan 6, 2023
    Smart data-driven menu rendered in an overlay

    React Data Menu Smart data-driven menu rendered in an overlay. Hints-based aligning with custom renderers and factories. Never clipped by other compon

    Danko Kozar 106 Sep 11, 2022
    :art: Off-canvas menus for React.

    React Off-Canvas Off-canvas menus for React. Installation $ npm install --save react-offcanvas Usage Basic Usage <OffCanvas width={300} transition

    Vu Tran 38 Nov 10, 2022
    A react lib for building circular menus in a very easy and handy way.

    react-planet A react lib for building circular menus in a very easy and handy way. Live-Demo: STORYBOOK Read the full story @ Medium or innFactory-Blo

    innFactory 140 Nov 16, 2022
    React dismissable context and hook with layers (nesting) support

    Context and hook to add support for nested, auto-dismissable layers. State can be globally controlled through context. Best used with react-popper.

    Voiceflow 13 Nov 15, 2022
    Tiny react library for building tooltips, flyovers, menus and more

    Postel ?? Postel is a single component that you can easily extend into customized tooltips, dropdowns, flyovers – any type of UI which would make sens

    Tim 77 Dec 7, 2022