npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-dd-menu-portal

v0.0.13

Published

A fork of react-dd-menu built with React portals to hoist dropdown menus in the DOM.

Downloads

42

Readme

react-dd-menu-portal

A fork of the react-dd-menu project. With (hard-coded) support for React portals. Undocumented and very dirty implementation. Use at own risk.

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

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..

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

'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.1 - add React portal support