(
+
+
+
+
+);
+
+export default MenuExampleDisable;
diff --git a/docs/src/app/components/pages/components/Menu/ExampleIcons.jsx b/docs/src/app/components/pages/components/Menu/ExampleIcons.jsx
new file mode 100644
index 00000000000000..ed4a368a4923fa
--- /dev/null
+++ b/docs/src/app/components/pages/components/Menu/ExampleIcons.jsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import Menu from 'material-ui/lib/menus/menu';
+import MenuItem from 'material-ui/lib/menus/menu-item';
+import Divider from 'material-ui/lib/divider';
+import FontIcon from 'material-ui/lib/font-icon';
+import ContentCopy from 'material-ui/lib/svg-icons/content/content-copy';
+import ContentLink from 'material-ui/lib/svg-icons/content/link';
+import Delete from 'material-ui/lib/svg-icons/action/delete';
+import Download from 'material-ui/lib/svg-icons/file/file-download';
+import PersonAdd from 'material-ui/lib/svg-icons/social/person-add';
+import RemoveRedEye from 'material-ui/lib/svg-icons/image/remove-red-eye';
+
+const style = {
+ marginRight: 32,
+ marginBottom: 32,
+ float: 'left',
+ position: 'relative',
+ zIndex: 0,
+};
+
+const MenuExampleIcons = () => (
+
+
+
+
+);
+
+export default MenuExampleIcons;
diff --git a/docs/src/app/components/pages/components/Menu/ExampleNested.jsx b/docs/src/app/components/pages/components/Menu/ExampleNested.jsx
new file mode 100644
index 00000000000000..3e694ef3bb3479
--- /dev/null
+++ b/docs/src/app/components/pages/components/Menu/ExampleNested.jsx
@@ -0,0 +1,41 @@
+import React from 'react';
+import Menu from 'material-ui/lib/menus/menu';
+import MenuItem from 'material-ui/lib/menus/menu-item';
+import Divider from 'material-ui/lib/divider';
+import ArrowDropRight from 'material-ui/lib/svg-icons/navigation-arrow-drop-right';
+
+const style = {
+ marginRight: 32,
+ marginBottom: 32,
+ float: 'left',
+ position: 'relative',
+ zIndex: 0,
+};
+
+const MenuExampleNested = () => (
+
+
+
+);
+
+export default MenuExampleNested;
diff --git a/docs/src/app/components/pages/components/Menu/ExampleSecondary.jsx b/docs/src/app/components/pages/components/Menu/ExampleSecondary.jsx
new file mode 100644
index 00000000000000..0311bc4e868ba3
--- /dev/null
+++ b/docs/src/app/components/pages/components/Menu/ExampleSecondary.jsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import Menu from 'material-ui/lib/menus/menu';
+import MenuItem from 'material-ui/lib/menus/menu-item';
+import Divider from 'material-ui/lib/divider';
+import ArrowDropRight from 'material-ui/lib/svg-icons/navigation-arrow-drop-right';
+
+const style = {
+ marginRight: 32,
+ marginBottom: 32,
+ float: 'left',
+ position: 'relative',
+ zIndex: 0,
+};
+
+const MenuExampleSecondary = () => (
+
+
+
+
+
+);
+
+export default MenuExampleSecondary;
diff --git a/docs/src/app/components/pages/components/Menu/ExampleSimple.jsx b/docs/src/app/components/pages/components/Menu/ExampleSimple.jsx
new file mode 100644
index 00000000000000..f2e7d9c1c9e29e
--- /dev/null
+++ b/docs/src/app/components/pages/components/Menu/ExampleSimple.jsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import Menu from 'material-ui/lib/menus/menu';
+import MenuItem from 'material-ui/lib/menus/menu-item';
+
+const style = {
+ marginRight: 32,
+ marginBottom: 32,
+ float: 'left',
+ position: 'relative',
+ zIndex: 0,
+};
+
+const MenuExampleSimple = () => (
+
+
+
+
+);
+
+export default MenuExampleSimple;
diff --git a/docs/src/app/components/pages/components/Menu/Page.jsx b/docs/src/app/components/pages/components/Menu/Page.jsx
new file mode 100644
index 00000000000000..81816ae8b46794
--- /dev/null
+++ b/docs/src/app/components/pages/components/Menu/Page.jsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import CodeExample from '../../../CodeExample';
+import PropTypeDescription from '../../../PropTypeDescription';
+import MarkdownElement from '../../../MarkdownElement';
+
+import menuReadmeText from './README';
+import menuCode from '!raw!material-ui/lib/menus/menu';
+import menuItemCode from '!raw!material-ui/lib/menus/menu-item';
+import MenuExampleSimple from './ExampleSimple';
+import menuExampleSimpleCode from '!raw!./ExampleSimple';
+import MenuExampleDisable from './ExampleDisable';
+import menuExampleDisableCode from '!raw!./ExampleDisable';
+import MenuExampleIcons from './ExampleIcons';
+import menuExampleIconsCode from '!raw!./ExampleIcons';
+import MenuExampleSecondary from './ExampleSecondary';
+import menuExampleSecondaryCode from '!raw!./ExampleSecondary';
+import MenuExampleNested from './ExampleNested';
+import menuExampleNestedCode from '!raw!./ExampleNested';
+
+const MenuPage = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+export default MenuPage;
diff --git a/docs/src/app/components/pages/components/Menu/README.md b/docs/src/app/components/pages/components/Menu/README.md
new file mode 100644
index 00000000000000..6145d4fe0d9906
--- /dev/null
+++ b/docs/src/app/components/pages/components/Menu/README.md
@@ -0,0 +1,6 @@
+## Menu
+[Menus](https://www.google.com/design/spec/components/menus.html) allow you to
+take an action by selecting from a list revealed upon opening a temporary,
+new sheet of material.
+
+### Examples
diff --git a/docs/src/app/components/pages/components/menus.jsx b/docs/src/app/components/pages/components/menus.jsx
deleted file mode 100644
index 0dac5e9de03724..00000000000000
--- a/docs/src/app/components/pages/components/menus.jsx
+++ /dev/null
@@ -1,375 +0,0 @@
-import React from 'react';
-import Paper from 'paper';
-import Menu from 'menus/menu';
-import MenuItem from 'menus/menu-item';
-import Divider from 'divider';
-import ComponentDoc from '../../component-doc';
-import FontIcon from 'font-icon';
-
-import ArrowDropRight from 'material-ui/svg-icons/navigation-arrow-drop-right';
-import ContentCopy from 'material-ui/svg-icons/content/content-copy';
-import ContentLink from 'material-ui/svg-icons/content/link';
-import Delete from 'material-ui/svg-icons/action/delete';
-import Download from 'material-ui/svg-icons/file/file-download';
-import PersonAdd from 'material-ui/svg-icons/social/person-add';
-import RemoveRedEye from 'material-ui/svg-icons/image/remove-red-eye';
-import Code from 'menus-code';
-import CodeExample from '../../CodeExample';
-import CodeBlock from '../../CodeExample/CodeBlock';
-
-export default class MenusPage extends React.Component {
-
- render() {
-
- let desc = null;
-
- let componentInfo = [
- {
- name: 'Menu Props',
- infoArray: [
- {
- name: 'animated',
- type: 'bool',
- header: 'default: false',
- desc: `If true, the menu will apply transitions when added it gets added to the DOM.
- In order for transitions to work, wrap the menu inside a ReactTransitionGroup.`,
- },
- {
- name: 'autoWidth',
- type: 'bool',
- header: 'default: true',
- desc: 'If true, the width will automatically be set according to the items inside the menu using the ' +
- 'proper keyline increment.',
- },
- {
- name: 'desktop',
- type: 'bool',
- header: 'default: false',
- desc: 'Indicates if the menu should render with compact desktop styles.',
- },
- {
- name: 'style',
- type: 'object',
- header: 'optional',
- desc: 'Override the inline-styles of the menu\'s root element.',
- },
- {
- name: 'listStyle',
- type: 'object',
- header: 'optional',
- desc: 'The style object to use to override underlying list style.',
- },
- {
- name: 'maxHeight',
- type: 'number',
- header: 'optional',
- desc: `The maxHeight of the menu in pixels.
- If specified, the menu will scroll if larger than the maxHeight.`,
- },
- {
- name: 'multiple',
- type: 'bool',
- header: 'default: false',
- desc: 'If true, the value can an array and allow the menu to be a multi-select.',
- },
- {
- name: 'openDirection',
- type: 'oneOf ["bottom-left", "bottom-right", "top-left", "top-right"]',
- header: 'default: bottom-left',
- desc: 'This is the placement of the menu relative to the IconButton.',
- },
- {
- name: 'value',
- type: 'oneOfType [string, array]',
- header: 'optional',
- desc: 'The value of the selected menu item. If passed in, this will make the menu ' +
- 'a controlled component. This component also supports valueLink.',
- },
- {
- name: 'width',
- type: 'oneOfType [string, integer]',
- header: 'optional',
- desc: 'Sets the width of the menu. If not specified, the menu width will be dictated by its ' +
- 'children. The rendered width will always be a keyline increment (64px for desktop, 56px otherwise).',
- },
- {
- name: 'zDepth',
- type: 'oneOf [0,1,2,3,4,5]',
- header: 'optional',
- desc: 'Sets the width of the menu. If not specified, the menu width will be dictated by its ' +
- 'children. The rendered width will always be a keyline increment (64px for desktop, 56px otherwise).',
- },
- ],
- },
- {
- name: 'Menu Events',
- infoArray: [
- {
- name: 'onEscKeyDown',
- header: 'function(event)',
- desc: 'Fired when an Esc key is keyed down.',
- },
- {
- name: 'onItemTouchTap',
- header: 'function(event, item)',
- desc: 'Fired when a menu item is touchTapped.',
- },
- {
- name: 'onChange',
- header: 'function(event, value)',
- desc: 'Fired when a menu item is touchTapped and the menu item value ' +
- 'is not equal to the current menu value.',
- },
- ],
- },
- {
- name: 'MenuItem Props',
- infoArray: [
- {
- name: 'checked',
- type: 'bool',
- header: 'default: false',
- desc: 'If true, a left check mark will be rendered',
- },
- {
- name: 'desktop',
- type: 'bool',
- header: 'default: false',
- desc: 'Indicates if the menu should render with compact desktop styles.',
- },
- {
- name: 'disabled',
- type: 'bool',
- header: 'default: false',
- desc: 'Disables a menu item.',
- },
- {
- name: 'style',
- type: 'object',
- header: 'optional',
- desc: 'Override the inline-styles of the menu item\'s root element.',
- },
- {
- name: 'innerDivStyle',
- type: 'object',
- header: 'optional',
- desc: 'Style overrides for the inner div.',
- },
- {
- name: 'insetChildren',
- type: 'bool',
- header: 'default: false',
- desc: 'If true, the children will be indented. Only needed when there is no leftIcon.',
- },
- {
- name: 'leftIcon',
- type: 'element',
- header: 'optional',
- desc: 'This is the SvgIcon or FontIcon to be displayed on the left side.',
- },
- {
- name: 'primaryText',
- type: 'node',
- header: 'optional',
- desc: 'This is the block element that contains the primary text. If a string is passed in, a ' +
- 'div tag will be rendered.',
- },
- {
- name: 'rightIcon',
- type: 'element',
- header: 'optional',
- desc: 'This is the SvgIcon or FontIcon to be displayed on the right side.',
- },
- {
- name: 'secondaryText',
- type: 'node',
- header: 'optional',
- desc: 'This is the block element that contains the secondary text. If a string is passed in, a ' +
- 'div tag will be rendered.',
- },
- {
- name: 'value',
- type: 'string',
- header: 'optional',
- desc: 'The value of the menu item.',
- },
- ],
- },
- {
- name: 'Menu Item Events',
- infoArray: [
- {
- name: 'onTouchTap',
- header: 'function(event, item)',
- desc: 'Fired when a menu item is touchTapped.',
- },
- ],
- },
- ];
-
- let styles = {
- menu: {
- marginRight: 32,
- marginBottom: 32,
- float: 'left',
- position: 'relative',
- zIndex: 0,
- },
-
- hr: {
- clear: 'both',
- border: 'none',
- },
- };
-
- return (
-
-
-
-
- {
- `//Import statement:
-import Menu from 'material-ui/lib/menus/menu';
-import MenuItem from 'material-ui/lib/menus/menu-item';
-import Divider from 'material-ui/lib/divider';
-
-//See material-ui/lib/index.js for more
- `
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-
- }
-
-}
diff --git a/docs/src/app/components/raw-code/menus-code.txt b/docs/src/app/components/raw-code/menus-code.txt
deleted file mode 100644
index 16022b56a06631..00000000000000
--- a/docs/src/app/components/raw-code/menus-code.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-//We're working on migrating some of our components to use a new implementation of menus.
-//If you'd like to use the new menu before our migration is complete, please directly
-//require them like this:
-
-import Menu from 'material-ui/lib/menus/menu';
-import MenuItem from 'material-ui/lib/menus/menu-item';
-import Divider from 'material-ui/lib/divider';
-
-
-
-
-
-// With Nested SubMenus
-
diff --git a/src/menus/menu-item.jsx b/src/menus/menu-item.jsx
index 0e439691150fad..db78708ca9b549 100644
--- a/src/menus/menu-item.jsx
+++ b/src/menus/menu-item.jsx
@@ -17,27 +17,80 @@ const nestedMenuStyle = {
const MenuItem = React.createClass({
propTypes: {
+ /**
+ * If true, a left check mark will be rendered
+ */
checked: React.PropTypes.bool,
+
+ /**
+ * Elements passed as children to inner ListItem.
+ */
children: React.PropTypes.node,
+
+ /**
+ * Indicates if the menu should render with compact desktop styles.
+ */
desktop: React.PropTypes.bool,
+
+ /**
+ * Disables a menu item.
+ */
disabled: React.PropTypes.bool,
+
+ /**
+ * Prop passed down to ListItem that tells it what kind of focus it has.
+ */
focusState: React.PropTypes.oneOf([
'none',
'focused',
'keyboard-focused',
]),
+
+ /**
+ * Style overrides for the inner div.
+ */
innerDivStyle: React.PropTypes.object,
+
+ /**
+ * If true, the children will be indented.
+ * Only needed when there is no leftIcon.
+ */
insetChildren: React.PropTypes.bool,
+
+ /**
+ * This is the SvgIcon or FontIcon to be displayed on the left side.
+ */
leftIcon: React.PropTypes.element,
+
+ /**
+ * Nested MenuItems for this MenuItem. Used to make nested menus.
+ */
menuItems: React.PropTypes.node,
+
+ /**
+ * Fired when the element is touchTapped.
+ */
onTouchTap: React.PropTypes.func,
+
+ /**
+ * This is the SvgIcon or FontIcon to be displayed on the right side.
+ */
rightIcon: React.PropTypes.element,
+
+ /**
+ * This is the block element that contains the secondary text.
+ * If a string is passed in, a div tag will be rendered.
+ */
secondaryText: React.PropTypes.node,
/**
* Override the inline-styles of the root element.
*/
style: React.PropTypes.object,
+
+ /**
+ * The value of the menu item.
+ */
value: React.PropTypes.any,
},
@@ -57,7 +110,11 @@ const MenuItem = React.createClass({
getDefaultProps() {
return {
+ checked: false,
+ desktop: false,
+ disabled: false,
focusState: 'none',
+ insetChildren: false,
};
},
diff --git a/src/menus/menu.jsx b/src/menus/menu.jsx
index 84161211e73de7..7d516255419b53 100644
--- a/src/menus/menu.jsx
+++ b/src/menus/menu.jsx
@@ -16,27 +16,113 @@ import ThemeManager from '../styles/theme-manager';
const Menu = React.createClass({
propTypes: {
+ /**
+ * If true, the menu will apply transitions when added it
+ * gets added to the DOM. In order for transitions to
+ * work, wrap the menu inside a ReactTransitionGroup.
+ */
animated: React.PropTypes.bool,
+
+ /**
+ * If true, the width will automatically be
+ * set according to the items inside the menu
+ * using the proper keyline increment.
+ */
autoWidth: React.PropTypes.bool,
+
+ /**
+ * Children for the Menu. Usually MenuItems.
+ */
children: React.PropTypes.node,
+
+ /**
+ * Indicates if the menu should render with compact desktop styles.
+ */
desktop: React.PropTypes.bool,
+
+ /**
+ * True if this item should be focused by the keyboard initially.
+ */
initiallyKeyboardFocused: React.PropTypes.bool,
+
+ /**
+ * The style object to use to override underlying list style.
+ */
listStyle: React.PropTypes.object,
+
+ /**
+ * The maxHeight of the menu in pixels. If
+ * specified, the menu will scroll if larger than the maxHeight.
+ */
maxHeight: React.PropTypes.number,
+
+ /**
+ * If true, the value can an array and allow the menu to be a multi-select.
+ */
multiple: React.PropTypes.bool,
+
+ /**
+ * Fired when a menu item is touchTapped and the menu item
+ * value is not equal to the current menu value.
+ */
+ onChange: React.PropTypes.func,
+
+ /**
+ * Fired when an Esc key is keyed down.
+ */
onEscKeyDown: React.PropTypes.func,
+
+ /**
+ * Fired when a menu item is touchTapped.
+ */
onItemTouchTap: React.PropTypes.func,
+
+ /**
+ * Fired when a key is pressed.
+ */
onKeyDown: React.PropTypes.func,
+
+ /**
+ * This is the placement of the menu relative to the IconButton.
+ */
openDirection: PropTypes.corners,
+
+ /**
+ * Style for the selected Menu Item.
+ */
selectedMenuItemStyle: React.PropTypes.object,
/**
* Override the inline-styles of the root element.
*/
style: React.PropTypes.object,
+
+ /**
+ * The value of the selected menu item. If passed in,
+ * this will make the menu a controlled component.
+ * This component also supports valueLink.
+ */
value: React.PropTypes.any,
+
+ /**
+ * ValueLink for this component when controlled.
+ */
valueLink: React.PropTypes.object,
+
+ /**
+ * Sets the width of the menu. If not specified, the menu
+ * width will be dictated by its children. The rendered
+ * width will always be a keyline increment
+ * (64px for desktop, 56px otherwise).
+ */
width: PropTypes.stringOrNumber,
+
+ /**
+ * Sets the width of the menu. If not specified,
+ * the menu width will be dictated by its children.
+ * The rendered width will always be a keyline increment
+ * (64px for desktop, 56px otherwise).
+ */
zDepth: PropTypes.zDepth,
},
@@ -59,7 +145,10 @@ const Menu = React.createClass({
return {
animated: false,
autoWidth: true,
+ desktop: false,
+ initiallyKeyboardFocused: false,
maxHeight: null,
+ multiple: false,
onEscKeyDown: () => {},
onItemTouchTap: () => {},
onKeyDown: () => {},