Code Monkey home page Code Monkey logo

menu's Introduction

rc-menu


React Menu Component. port from https://github.com/kissyteam/menu

NPM version npm download build status Codecov bundle size dumi

Install

rc-menu

Usage

import Menu, { SubMenu, MenuItem } from 'rc-menu';

ReactDOM.render(
  <Menu>
    <MenuItem>1</MenuItem>
    <SubMenu title="2">
      <MenuItem>2-1</MenuItem>
    </SubMenu>
  </Menu>,
  container,
);

Compatibility

IE / Edge
IE / Edge
Firefox
Firefox
Chrome
Chrome
Safari
Safari
Electron
Electron
IE11, Edge last 2 versions last 2 versions last 2 versions last 2 versions

API

Menu props

name type default description
ref React.HTMLLIElement get dom node
className String additional css class of root dom node
mode String vertical one of ["horizontal","inline","vertical-left","vertical-right"]
activeKey String initial and current active menu item's key.
defaultActiveFirst Boolean false whether active first menu item when show if activeKey is not set or invalid
multiple Boolean false whether allow multiple select
selectable Boolean true allow selecting menu items
selectedKeys String[] [] selected keys of items
defaultSelectedKeys String[] [] initial selected keys of items
openKeys String[] [] open keys of SubMenuItem
defaultOpenKeys String[] [] initial open keys of SubMenuItem
onSelect function({key:String, item:ReactComponent, domEvent:Event, selectedKeys:String[]}) called when select a menu item
onClick function({key:String, item:ReactComponent, domEvent:Event, keyPath: String[]}) called when click a menu item
onOpenChange (openKeys:String[]) => void called when open/close sub menu
onDeselect function({key:String, item:ReactComponent, domEvent:Event, selectedKeys:String[]}) called when deselect a menu item. only called when allow multiple
triggerSubMenuAction Enum { hover, click } hover which action can trigger submenu open/close
openAnimation {enter:function,leave:function}|String animate when sub menu open or close. see rc-motion for object type.
openTransition String css transitionName when sub menu open or close
subMenuOpenDelay Number 0 delay time to show popup sub menu. unit: s
subMenuCloseDelay Number 0.1 delay time to hide popup sub menu. unit: s
forceSubMenuRender Boolean false whether to render submenu even if it is not visible
getPopupContainer Function(menuDOMNode): HTMLElement () => document.body Where to render the DOM node of popup menu when the mode is horizontal or vertical
builtinPlacements Object of alignConfigs for dom-align see placements.ts Describes how the popup menus should be positioned
itemIcon ReactNode | (props: MenuItemProps) => ReactNode Specify the menu item icon.
expandIcon ReactNode | (props: SubMenuProps & { isSubMenu: boolean }) => ReactNode Specify the menu item icon.
direction String Layout direction of menu component, it supports RTL direction too.
inlineIndent Number 24 Padding level multiplier. Right or left padding depends on param "direction".

Menu.Item props

name type default description
className String additional css class of root dom node
disabled Boolean false no effect for click or keydown for this item
key Object corresponding to activeKey
onMouseEnter Function({eventKey, domEvent})
onMouseLeave Function({eventKey, domEvent})
itemIcon ReactNode | (props: MenuItemProps) => ReactNode Specify the menu item icon.

Menu.SubMenu props

name type default description
ref React.HTMLLIElement get dom node
popupClassName String additional css class of root dom node
popupStyle CSSProperties additional css style of root dom node
title String/ReactElement sub menu's content
overflowedIndicator String/ReactElement ··· overflow indicator when menu overlows in horizontal mode
key Object corresponding to activeKey
disabled Boolean false no effect for click or keydown for this item
onMouseEnter Function({eventKey, domEvent})
onMouseLeave Function({eventKey, domEvent})
onTitleMouseEnter Function({eventKey, domEvent})
onTitleMouseLeave Function({eventKey, domEvent})
onTitleClick Function({eventKey, domEvent})
popupOffset Array The offset of the popup submenu, in an x, y coordinate array. e.g.: `[0,15]`
expandIcon ReactNode | (props: SubMenuProps) => ReactNode Specify the menu item icon.
itemIcon ReactNode | (props: SubMenuProps & { isSubMenu: boolean }) => ReactNode Specify the menu item icon.

Menu.Divider props

none

Menu.ItemGroup props

name type default description
ref React.HTMLLIElement get dom node
title String|React.Element title of item group
children React.Element[] MenuItems belonged to this group

Development

npm install
npm start

Example

http://localhost:8001/examples/index.md

online example: http://react-component.github.io/menu/examples/

Test Case

npm test
npm run chrome-test

Coverage

npm run coverage

open coverage/ dir

License

rc-menu is released under the MIT license.

menu's People

Contributors

afc163 avatar antoinm avatar benjycui avatar blog-lyn avatar cdeutsch avatar chenshuai2144 avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar jarvisart avatar jljsj33 avatar jwmann avatar kerm1it avatar kiner-tang avatar ldabiralai avatar madccc avatar madocto avatar micate avatar nuintun avatar paranoidjk avatar picodoth avatar s0 avatar saeedrahimi avatar shaodahong avatar superraytin avatar warmhug avatar yesmeck avatar yiminghe avatar zombiej avatar ztplz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

menu's Issues

isMounted is deprecated in MenuItem.jsx and subMenu

Warning: Component: isMounted is deprecated. Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks.

in two files:

  • parentMenu.menuItemMouseLeaveFn @ MenuItem.jsx:59
  • parentMenu.subMenuTitleLeaveFn @ SubMenu.jsx:167

actions:

use state instead ?

 getInitialState() {
    this.isSubMenu = 1;
    return {
      _isMounted: false,
      defaultActiveFirst: false,
    };
  },

componentWillMount() {
    this.setState({
      _isMounted: true,
    });
  },
componentWillUnmount() {
    this.setState({
      _isMounted: false,
    });
  },
onMouseLeave(e) {
    const { props } = this;
    const { parentMenu, eventKey } = props;
    parentMenu.subMenuInstance = this;
    parentMenu.subMenuLeaveFn = () => {
      if (this.state._isMounted) {
        // leave whole sub tree
        // still active
      ....
   }
}

Touch Support

I am using your menu component for a web application which is used on desktops but also on mobile devices. But for devices which only have touch support the menu handling is very counter intuitive und buggy.

One bug would be that sometimes some Submenu-Items are not clickable or they don't open the Submenu. This always happens if a props-change triggers the addition of a new Submenu in which case this Submenu cannot be opened until either another menu item was opened or clicked or you click somewhere else on the menu (I think this is a focus problem).

Furthermore if a submenu is opened it is very buggy and hard to close it again without clicking another menu item and for some browser / mobile versions (I had the problem with an iOS device) its not possible at all (so one submenu must always be open which blocks the main view).

Also in this context it would be good to close a submenu if a menu item got clicked (see #65).

I understand that this component does not focus on touch devices but still will there be an improvement for this devices in near future, or should I use another menu component for touch devices?

Setting id on Menu.Item

Is it possible to set the id on Menu.Item?
This doesn't seem to work

<Menu.Item id="edit-profile-link" key={1}>Edit Profile</Menu.Item>

review - 2014.12.25

细节参见: 529707f

目前结构不对: 应该是 dropdown 使用 menu 做下拉菜单,之后 combobox 也使用 menu 做下拉菜单

Would you consider adding typeahead support?

Looking for a replacement version of our existing Angular Select directive and this looks quite sufficient. However, we do have a need for typeahead? Would you consider adding typeahead support to this project?

support onClick

onSelect will not trigger if MenuItem is already selected.

onClick will always trigger

能否给 menu.item 增加“是否保留选中状态”开关?

hello,
我在使用 Antd 的 Dropdown 组件时,有这么一种情形:鼠标移到触发按钮上->下拉菜单出现->点击某一项 menu.item ->弹出模态框->鼠标移走->点击的 menu.item 仍处于选中状态。

在这种情形下,menu.item 不再是导航链接的角色,而是一个触发按钮的角色,鼠标移走之后应该去掉 selected 状态。 所以我在想能不能给 menu.item 组件添加一个属性 deselectOnMouseLeave ,默认为 false ,当设置为 true 时鼠标移走就移除 selected 状态。

what the relationship between react's props key and rc-menu's props eventKey

i really can not figure out how you get the react's props key to your menuItem's props eventKey, or where your eventKey can be get.
like this:

<Menu>
    <MenuItem key="m1">一级菜单</MenuItem>
    <SubMenu key="sbm1" title="二级菜单">
        <MenuItem key="sbm1-m1">2级菜单子选项</MenuItem>
        <SubMenu key="sbm2" title="三级菜单">
            <MenuItem key="sbm2-m1">3级菜单子选项</MenuItem>
        </SubMenu>
   </SubMenu>
</Menu>

and how the relationship between the key and the rc-menu's props eventKey, because l'm learning making a menu component by modeling your code, may I ask you for a favor?

openKeys becomes undefined in Menu.componentWillReceiveProps

I have got a SubMenu like this:

      <div>
        <Menu mode="horizontal" id="nav">
          <SubMenu title="John">
            <MenuItemGroup key="actions" title="Actions">
              <Menu.Item key="createCompany">
                <a href="#" >Create Company</a>
              </Menu.Item>
              <Menu.Item key="signOut">
                <a href="#" >Sign Out</a>
              </Menu.Item>
            </MenuItemGroup>
          </SubMenu>
        </Menu>
      </div>

For some reason it triggers the componentWillReceiveProps immediately after it first render, and openKeys is undefined in nextProps so it passes on causing an error in isOpen in SubMenu
screen shot 2017-01-22 at 5 09 43 am

I spent a couple of hours and still cannot reproduce in it online. Adding a guard clause against undefined openKeys (and for selectedKeys, just in case) should solve the issue.

I will submit a PR now.

Click subMenu element gets no responses when set openKeys on Menu element.

Click subMenu element gets no responses when set openKeys on Menu element in inline mode.

Bug Scene: jsfiddle

After digging in source code, i found following code cause the bug on line 163 in /src/menu.jsx

  if (!('openKeys' in this.props)) {
    this.setState({ openKeys });
  }

It's seems that you don't change the openKeys when it's set. That cause the click event not work.

Is there an issue or a special purpose?

选中后,active 状态消失

active 是 hover 中的状态,目前选中后,hover 状态会消失。需要重新移出移入后才能激活 active

active 选中 => selected

选中后,hover 状态应该保持。

active 选中 => active selected

15.5版本下 DOMWrap: React.createClass is deprecated

15.5 会警告不要从react import,不升级到15.5 其他dependencies 又会报unmet

Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
DOMWrap: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.

src/DOMWrap.jsx 中需要修正:

// After (15.5)
import React from 'react';
import PropTypes from 'prop-types';
var createReactClass = require('create-react-class');
var Component = createReactClass({})

看到一天前修改了package.json lockdown to 15.4 是有什么计划么?
有升级的计划么? 还是可以提mr?

SubMenu does not work with Universal/Isomorphic apps

Due to the automatically generated Menu ID for aria-owns, server and client generate different html:

vendor.js?cacheHash=919053d…:38404 Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) aria-owns="1474721378027_0" aria-haspopu
(server) aria-owns="1474721377705_1" aria-haspopu

As a quick way to fix this I was thinking it should be possible to add an optional AriaID or MenuID property that gets used if set, otherwise it will still be auto generated like it is now?

How to dismiss the menu on selection - (Question)

I am integrating the menu component as an element in a table cell, and would like the menu to dismiss when one of the items is selected. Is there a property that enables dismiss on select?

I see the following in the examples which destroys the menu, but when I capture the event, I do not have the container.
function destroy() {
ReactDOM.unmountComponentAtNode(container);
}

support Menu.ItemGroup

<Menu>
<MenuItemGroup>
<MenuItem>1</MenuItem>
<MenuItem>2</MenuItem>
</MenuItemGroup>
</Menu>

Importing the css file produces error

I am using https://github.com/gaearon/react-transform-boilerplate for my app. When I include the css file using

import 'rc-menu/assets/index.css';

, I get the following error:

ERROR in ./~/rc-menu/assets/index.css
Module parse failed: /home/purezen/workspace/react-transform-boilerplate/node_modules/rc-menu/assets/index.css Line 1: Unexpected token .
You may need an appropriate loader to handle this file type.
| .rc-menu {
|   outline: none;
|   margin-bottom: 0;
 @ ./src/Header.js 30:0-35

Have installed less-loader and patched the webpack config as well.

Issue with using conditional `disabled` attribute on MenuItems

I have a requirement that selected MenuItems should appear disabled. I tried this:

        <MenuItem
          key={id}
          disabled={ id === this.state.selectedId } >
            {menuItemName}
        </MenuItem>

This causes issues on this line: https://github.com/react-component/menu/blob/master/lib/Menu.js#L155

since this code causes onDeselect not to be defined: https://github.com/react-component/menu/blob/master/lib/Menu.js#L218-L221

I've disabled the disabled check and it seems to fix my menu. Is this premature return necessary?

Demo Page Failing

The demo page doesn't have any working examples of this plug-in. When I checked the console, it seemed to be an error with how React was defined:

Uncaught TypeError: Cannot read property 'createClass' of undefined

Inspecting the code led me to this line in Menu.js:

var React = window.window.React;

Fixing that could be enough to restore functionality. An additional issue is that when I tried to inspect with React dev-tools, it complained saying the current version of React was outdated.

You are using a version of React with limited support in this version of the devtools. Please upgrade to use at least 0.13, or you can downgrade to use the old version of the devtools: instructions here https://github.com/facebook/react-devtools/tree/devtools-next#how-do-i-use-this-for-react--013

Any chance you can update this plug-in? The nested menus look great, I'd love to use them!

菜单变化时 defaultOpenKeys 被修改

当菜单内容(children)被修改时 defaultOpenKeys 也被删除了
相关代码:

// Menu.jsx line 69
onDestroy(key) {
  // ...
  selectedKeys.splice(index, 1);
  openKeys.splice(index, 1);
}

为什么要这么做,并且是直接 splice ?
另外项目依赖 PhantomJS, 想编译一下都不知道如何入手。

Debounced open

Hi there,

Great work on this. I'd like to be able to delay the opening of a menu by a small amount - say, 200ms - so that quick, unintentional mouseovers don't cause a menu to open. I don't think this is currently possible, though I may be wrong. Chances are this would best be achieved with manual hooks to show/hide the menu and listen on mousenter/leave events, though I certainly wouldn't complain about a delay prop.

Thoughts?

export onSubMenuHover props to use

I want to control this menu open state in mode vertical, but now I must use onMouseEnter, onMouseLeave,onTitleMouseLeave,onTitleMouseLeave to control, but the onXXXLeave is not trigger when mouse leave title

Scrollable Menu with max-height

Hi again,

This is a bit of a long shot but thought I'd throw it out there. It'd be really awesome to be able to have menus with max-height and overflow-y: auto; that support submenus. This works no-problem as long as a menu has no submenus, but the overflow swallows the children if you try to add a submenu.

Note that this is a fundamental problem with this kind of approach. Here is an article outlining why this won't work. tl;dr, the submenu must be rendered as a sibling (or higher) to the scrollable menu, and positioned with javascript. Obviously, this would be a lot more involved than the current implementation.

Thoughts?

Thanks!

Mouse leave behavior change on 4.13+

The behavior of openSubMenuOnMouseEnter and closeSubMenuOnMouseLeave seems to have changed between 4.12.4 and 4.13.0

Run the antd example at https://github.com/pward123/menu/tree/hover-4.12.4 then click on the horizontal 'submenu' item and slide your mouse back and forth over the two submenu titles. The dropdown should stay open.

Try the same thing with https://github.com/pward123/menu/tree/hover-5.0.0. The submenu will close when your mouse moves across the title boundary.

I'd like the user to click on the title to open a submenu, but want the behavior of 4.12.4 when the user is moving between submenus.

The code that appears to be causing the menu to close is https://github.com/react-component/menu/blob/master/src/MenuMixin.js#L172.

子菜单选中而所属父菜单未选中

<Menu theme="dark" mode="horizontal" selectedKeys={['2', '2-1']}>
  <Menu.Item key='1'>1</Menu.Item>
  <SubMenu key='2' title='2'>
    <Menu.Item key='2-1'>2-1</Menu.Item>
    <Menu.Item key='2-2'>2-2</Menu.Item>
  </SubMenu>
</Menu>

以上代码我设置selectedKeys['2','2-1'],结果没有生效,只有 '2-1' 增加了 selected,按道理 horizontal 模式下面应该父菜单也应该是 selected 的吧?或者我如何修改可以实现

SubMenu 不能嵌套其他组件

#SubMenu 嵌套其他组件会导致 isSelected 这个函数错误, 但是当我想去控制这个 SubMenu下的 menuItem 是否显示时使用了自定义组件, 这个时候组件就不起作用了

## Authentication.jsx
import React from 'react';

const Authentication = ({ children }) => {
  return <span>{children}</span>;
};

export default Authentication;

## Sidebar.jsx
import React, { Component, PropTypes } from 'react';
import { Link, IndexLink } from 'react-router';
import { connect } from 'react-redux';
import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu;
.......
class Sidebar extends Component {
.....
  render() {
    const { collapse, onCollapseChange, onCollapseClose, selectedKeys, loginInfo } = this.props;
    return (
      <aside className="ant-layout-sider">
        <div className="ant-layout-sider-backdrop" />
        <Menu
          mode={collapse ? 'vertical' : 'inline'}
          theme="dark"
          defaultSelectedKeys={['home']}
          selectedKeys={[selectedKeys]}
        >
          <SubMenu
            key={permData.userManage.key}
          >
            <authentication>
              <Menu.Item key={item.key}>
                <span className="nav-text">{item.name}</span>
              </Menu.Item>
            </authentication>
          </SubMenu>
        </Menu>
      </aside>
    );
  }
......
}

warning about wrong nest structure

const A = React.createClass({
  render() {
    return <MenuItem />
  }
});

const B = React.createClass({
  render() {
    return <Menu><A /><A /></Menu>;
  }
});

服务器端渲染报警告

warning.js:45Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) aria-owns="1469171077731_0" aria-haspopu
(server) aria-owns="1469171076562_0" aria-haspopu

Using css file instead of less one

As far as I understand, you provide less file for styling. I mean,
import 'rc-menu/assets/index.less';
Is it possible to provide css file, because SASS couldn't be a default CSS Preprocessor somewhere? =)

Menu chokes when passed a child of ''

See the line {(Meteor.userId()) ? '' : <MenuItem key="/signup">Join</MenuItem>}

I took a quick look at the source and did not see anything obvious. I will dig deeper latter as for now I fixed it with the following {(Meteor.userId()) ? <MenuItem key="/logout"></MenuItem> : <MenuItem key="/signup">Join</MenuItem>} Which shows up as a 2px high menu item that you cant see unless you hover over it. Reminds me of that move 'The Net' 😀

export const MainMenuComp = ({list}) => {
  let items = list.map((item) => <MenuItem key={item.url}>{item.name}</MenuItem>);
  items.unshift(<Divider key="divider"/>);
  items.unshift(<MenuItem key="/createshow">Added A New Show</MenuItem>);

  return (
    <Menu className="main-menu" onSelect={handleSelect} onOpen={console.log} mode="horizontal">
      <MenuItem key="/">Home</MenuItem>
      <SubMenu title={<span>Categories</span>} key="categories" mode="vertical">
        {items}
      </SubMenu>
      <SubMenu title={<span>My Account</span>} key="myaccount" mode="vertical">
        <MenuItem key="/myshows">My Shows</MenuItem>
        <MenuItem key="/createshow">Added A New Show</MenuItem>
        <MenuItem key="/createepisode">Added A New Episode</MenuItem>
      </SubMenu>
      <MenuItem key="/community">Community</MenuItem>
      <MenuItem key="/faqs">FAQs</MenuItem>
      {/* todo fix this better - issue menu does not like having '' as a menu item */}
      {(Meteor.userId()) ? '' : <MenuItem key="/signup">Join</MenuItem>}
    </Menu>
  )
};

Menu theming

What's the recommended way to implement another theme for the menu?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.