diff --git a/src/App.js b/src/App.js
index cc8efb466c..5abf658fc8 100644
--- a/src/App.js
+++ b/src/App.js
@@ -27,19 +27,19 @@ class Home extends Component {
-
+
+ ● Menu
this.openMenu(event, 7)} className={classNames({ 'active-menuitem': this.state.activeMenu === 7 })}>
diff --git a/src/components/menu/Menu.css b/src/components/menu/Menu.css
new file mode 100644
index 0000000000..955a45e540
--- /dev/null
+++ b/src/components/menu/Menu.css
@@ -0,0 +1,328 @@
+.ui-menu {
+ width: 12.5em;
+ padding: .25em;
+ position:relative;
+}
+
+.ui-menu-separator {
+ border-width: 1px 0 0 0;
+}
+
+.ui-menu.ui-menu-dynamic {
+ position: absolute;
+ display: none;
+ z-index: 100000;
+}
+
+.ui-menu-list {
+ position: static;
+}
+
+.ui-menu .ui-menu-list .ui-menuitem {
+ border: none;
+}
+
+.ui-menu .ui-menu-list .ui-widget-header {
+ clear:both;
+ float:left;
+ width: 100%;
+ margin: .125em 0;
+ padding: .25em .5em;
+}
+
+.ui-menu .ui-menuitem-parent,
+.ui-menu .ui-menuitem {
+ width: 100%;
+ clear: both;
+ margin: .125em 0;
+ padding: 0;
+}
+
+.ui-menu .ui-menuitem-link {
+ display: block;
+ width: 100%;
+ text-decoration: none;
+ font-weight: normal;
+ border: 1px solid transparent;
+ line-height: 1em;
+ padding: .25em;
+ cursor: pointer;
+}
+
+.ui-menu .ui-menuitem-link .ui-menuitem-icon {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.ui-menu .ui-menuitem-text {
+ vertical-align: middle;
+}
+
+.ui-menu .ui-widget-header h1,
+.ui-menu .ui-widget-header h2,
+.ui-menu .ui-widget-header h3,
+.ui-menu .ui-widget-header h4,
+.ui-menu .ui-widget-header h5,
+.ui-menu .ui-widget-header h6 {
+ font-size: 1em;
+ margin: 0 auto;
+}
+
+/* Tiered Menu */
+.ui-menu .ui-menu-parent .ui-menu-child {
+ display: none;
+ width: 12.5em;
+ padding: .25em;
+ position:absolute;
+ margin: 0;
+ text-decoration:none;
+ list-style:none;
+}
+
+.ui-menu .ui-menu-parent {
+ position: relative;
+}
+
+.ui-menu .ui-menu-parent .ui-submenu-icon {
+ float: right;
+ margin-right: -.25em;
+}
+
+/** MenuButton **/
+.ui-menubutton {
+ padding: 0;
+}
+
+.ui-menubutton .ui-button {
+ margin: 0;
+}
+
+/** Menubar **/
+.ui-menu.ui-menubar .ui-menubar-root-list > li > a > .ui-submenu-icon {
+ float: none;
+}
+
+.ui-menubar {
+ width:auto;
+}
+
+.ui-menubar .ui-menubar-root-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.ui-menubar .ui-menubar-root-list > .ui-menuitem {
+ display: inline-block;
+ width: auto;
+}
+
+.ui-menubar:not(.ui-megamenu-vertical) .ui-menubar-root-list > .ui-menu-separator {
+ display: inline-block;
+ border-width: 0 0 0 1px;
+ width: 1px;
+ text-indent: -9999999px;
+}
+
+.ui-menubar:not(.ui-megamenu-vertical) .ui-menubar-root-list > .ui-menu-separator:before {
+ content: 'ui-menu-separator';
+}
+
+.ui-menubar .ui-menu-child .ui-menuitem {
+ width: 100%;
+}
+
+.ui-menubar .ui-menuitem.ui-menuitem-custom {
+ float: right;
+ margin-top: 0.25em;
+}
+
+.ui-menubar .ui-menubar-options {
+ float: right;
+}
+
+/** SlideMenu **/
+.ui-slidemenu .ui-slidemenu-wrapper {
+ position: relative;
+}
+
+.ui-slidemenu .ui-slidemenu-content {
+ overflow-x: hidden;
+ overflow-y: auto;
+ position: relative;
+}
+
+.ui-slidemenu .ui-menu-list {
+ position: absolute;
+ top: 0;
+}
+
+.ui-slidemenu .ui-menu-parent {
+ position: static;
+}
+
+.ui-slidemenu .ui-menu-child {
+ box-shadow : none;
+ border: 0 none;
+ background: none repeat scroll 0 0 transparent;
+}
+
+.ui-slidemenu-backward {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ padding: 0.2em;
+ cursor: pointer;
+ display: none;
+}
+
+.ui-slidemenu-backward .fa {
+ vertical-align: middle;
+}
+
+.ui-slidemenu-backward span {
+ vertical-align: middle;
+}
+
+.ui-slidemenu .ui-slidemenuitem-active > .ui-submenu > ul {
+ display: block !important;
+}
+
+/** MegaMenu **/
+.ui-megamenu .ui-g {
+ flex-wrap: nowrap;
+}
+
+.ui-megamenu .ui-megamenu-panel.ui-menu-child {
+ width: auto;
+}
+
+.ui-megamenu .ui-megamenu-panel .ui-menu-list {
+ width: 12.5em;
+}
+
+.ui-megamenu-vertical {
+ width: 12.5em;
+}
+
+.ui-megamenu-vertical .ui-menuitem-link,
+.ui-megamenu-vertical .ui-menu-list .ui-menuitem {
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.ui-megamenu-vertical > .ui-menubar-root-list > .ui-menuitem > .ui-menuitem-link > .ui-submenu-icon {
+ float: right;
+}
+
+/** PanelMenu **/
+.ui-panelmenu {
+ width: auto;
+}
+
+.ui-panelmenu .ui-panelmenu-panel {
+ padding: 0;
+ margin: 0;
+}
+
+.ui-panelmenu .ui-panelmenu-header {
+ cursor: pointer;
+ position: relative;
+ margin: -1px 0 0 0;
+ zoom: 1;
+}
+
+.ui-panelmenu .ui-panelmenu-header a {
+ display: block;
+ padding: .25em .5em;
+}
+
+.ui-panelmenu span {
+ vertical-align: middle;
+}
+
+.ui-panelmenu .fa {
+ width: 1em;
+ text-align: center;
+ vertical-align: middle;
+ margin-right: .25em;
+}
+
+.ui-panelmenu .ui-menuitem-text {
+ margin-left: .125em;
+}
+
+.ui-panelmenu span {
+ vertical-align: middle;
+}
+
+.ui-panelmenu .ui-panelmenu-content {
+ padding: 0.2em 0;
+ border-top: 0;
+ overflow: auto;
+ zoom: 1;
+ outline: none;
+ margin-bottom: 1px;
+}
+
+.ui-panelmenu .ui-panelmenu-content .ui-menu-parent {
+ overflow: hidden;
+}
+
+.ui-panelmenu .ui-panelmenu-content-wrapper {
+ box-sizing: border-box;
+}
+
+.ui-panelmenu .ui-panelmenu-content-wrapper-overflown {
+ overflow: hidden;
+}
+
+.ui-panelmenu .ui-panelmenu-header.ui-state-disabled,
+.ui-panelmenu .ui-panelmenu-header.ui-state-disabled a {
+ cursor: default;
+}
+
+.ui-panelmenu .ui-menu-list {
+ position: static;
+}
+
+.ui-panelmenu .ui-menuitem {
+ margin: 1px 0;
+ padding: 0;
+}
+
+.ui-panelmenu .ui-menu-separator {
+ width: 95%;
+ margin: 0 auto;
+}
+
+.ui-panelmenu .ui-menuitem-link {
+ display: block;
+ text-decoration: none;
+ font-weight: normal;
+ border: 1px solid transparent;
+ line-height: 1em;
+ cursor: pointer;
+ position: relative;
+ padding: .25em .5em;
+}
+
+.ui-panelmenu .ui-menu-parent .ui-menu-list {
+ margin-left: 1.5em;
+}
+
+/** MegaMenu and TieredMenus **/
+.ui-menuitem-active > .ui-submenu > ul,
+.ui-menuitem-active > .ui-megamenu-panel {
+ display: block !important;
+}
+
+.ui-menuitem-outline {
+ outline: 1px dotted;
+ z-index: 1;
+}
+
+/** Fluid **/
+.ui-fluid .ui-menu {
+ width: 100%;
+}
\ No newline at end of file
diff --git a/src/components/menu/Menu.js b/src/components/menu/Menu.js
new file mode 100644
index 0000000000..d46f95cae8
--- /dev/null
+++ b/src/components/menu/Menu.js
@@ -0,0 +1,189 @@
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import DomHandler from '../utils/DomHandler';
+import classNames from 'classnames';
+
+export class MenuItem extends Component{
+ static defaultProps = {
+ index:null,
+ items:null,
+ menu:null,
+ };
+
+ static propTypes = {
+ index:PropTypes.number,
+ items:PropTypes.any,
+ menu:PropTypes.any
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = {};
+ this.item=this.props.items;
+ this.menu=this.props.menu
+ }
+
+ render() {
+ var styleClass=classNames('ui-menuitem-link ui-corner-all',{'ui-state-disabled':this.item.disabled})
+ var iconClass=classNames('ui-menuitem-icon fa fa-fw',this.item.icon?this.item.icon:null)
+ if(this.item.url){
+ return (
+ this.menu.itemClick(event,this.item)}>
+ {this.item.icon? :null}
+ {this.item.label}
+
+ );
+ }
+ else{
+ return (
+
this.menu.itemClick(event,this.item)}>
+ {this.item.icon? :null}
+ {this.item.label}
+
+ );
+ }
+ }
+}
+
+export class Menu extends Component {
+
+ static defaultProps = {
+ model:null,
+ popup:false,
+ style:null,
+ styleClass:null,
+ onShow:null,
+ onHide:null
+ };
+
+ static propTypes = {
+ model:PropTypes.array,
+ popup:PropTypes.bool,
+ style:PropTypes.object,
+ styleClass:PropTypes.string,
+ onShow:PropTypes.func,
+ onHide:PropTypes.func
+ };
+
+ constructor() {
+ super();
+ this.state = {};
+ }
+ componentDidMount(){
+ if(this.props.popup){
+ document.body.appendChild(this.container);
+ this.documentClickListener=document.addEventListener('click',(event)=>{
+ if(!this.preventDocumentDefault) {
+ this.hide(event);
+ }
+ this.preventDocumentDefault = false;
+ })
+ }
+ window.addEventListener('resize',()=>{
+ if(this.onResizeTarget && this.container.offsetParent) {
+ DomHandler.absolutePosition(this.container, this.onResizeTarget);
+ }
+ })
+ }
+ hasSubMenu(){
+ if(this.props.model){
+ for(var items of this.props.model){
+ if(items.items)
+ return true;
+ }
+ }
+ return false;
+ }
+ itemClick(event,item){
+ if(item.disabled) {
+ event.preventDefault();
+ return;
+ }
+
+ if(!item.url) {
+ event.preventDefault();
+ }
+
+ if(item.command) {
+ item.command({
+ originalEvent: event,
+ item: item
+ });
+ }
+
+ if(this.props.popup) {
+ this.hide(event);
+ }
+ }
+ toggle(event){
+ if(this.container.offsetParent)
+ this.hide(event);
+ else
+ this.show(event);
+
+ this.preventDocumentDefault = true;
+ }
+
+ show(event) {
+ let target = event.currentTarget;
+ this.onResizeTarget = event.currentTarget;
+ this.container.style.display = 'block';
+ DomHandler.absolutePosition(this.container, target);
+ DomHandler.fadeIn(this.container, 250);
+ this.preventDocumentDefault = true;
+ if(this.props.onShow){
+ this.props.onShow({
+ originalEvent:event
+ })
+ }
+ }
+ hide(event) {
+ if(this.container)
+ this.container.style.display = 'none';
+ if(this.props.onHide){
+ this.props.onHide({
+ originalEvent:event
+ })
+ }
+ }
+
+ render() {
+ var styleClass=classNames('ui-menu ui-widget ui-widget-content ui-corner-all ui-helper-clearfix',this.props.styleClass,
+ {'ui-menu-dynamic ui-shadow':this.props.popup})
+ var itemSubMenu,itemMenu;
+
+ if(this.hasSubMenu()){
+ itemSubMenu=this.props.model && this.props.model.map((submenu,indexSub)=>{
+ var subMenu=
+
+ {submenu.label}
+
+ {submenu.items && submenu.items.map((item,indexItem)=>{
+ var menu=
+
+
+ return menu;
+ })}
+ return subMenu})
+ }
+ else{
+ itemMenu=this.props.model && this.props.model.map((item,index)=>{
+ var menu=
+
+
+ return menu
+ })
+ }
+
+ return (
+
this.container=el} onClick={()=>this.preventDocumentDefault=true}>
+
+ {itemSubMenu}
+ {itemMenu}
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 30ad33a13d..e4e54940ea 100644
--- a/src/index.js
+++ b/src/index.js
@@ -57,6 +57,7 @@ import {DataScrollerDemo} from './showcase/datascroller/DataScrollerDemo';
import {DataScrollerInlineDemo} from './showcase/datascroller/DataScrollerInlineDemo';
import {DataScrollerLoaderDemo} from './showcase/datascroller/DataScrollerLoaderDemo';
import {DataScrollerInfiniteDemo} from './showcase/datascroller/DataScrollerInfiniteDemo';
+import {MenuDemo} from './showcase/menu/MenuDemo';
import {Router,Route,hashHistory} from 'react-router';
ReactDOM.render(
@@ -117,6 +118,7 @@ ReactDOM.render(
+
,
diff --git a/src/showcase/menu/MenuDemo.js b/src/showcase/menu/MenuDemo.js
new file mode 100644
index 0000000000..e5580b1fdd
--- /dev/null
+++ b/src/showcase/menu/MenuDemo.js
@@ -0,0 +1,356 @@
+import React, {Component} from 'react';
+import {Link} from 'react-router';
+import {Menu} from '../../components/menu/Menu';
+import {TabView,TabPanel} from '../../components/tabview/TabView';
+import {CodeHighlight} from '../../components/codehighlight/CodeHighlight';
+import {Button} from "../../components/button/Button";
+
+export class MenuDemo extends Component {
+
+ constructor() {
+ super();
+ this.state = {};
+ }
+
+ render() {
+ var items=[ {
+ label: 'File',
+ items: [{label: 'New', icon: 'fa-plus',command:()=>{ window.location.hash="/fileupload"; }},
+ {label: 'Open', icon: 'fa-download', url: 'http://primetek.com.tr'}]
+ }, {
+ label: 'Edit',
+ items: [{label: 'Undo', icon: 'fa-refresh',command:()=>{ window.location.hash="/"; }},
+ {label: 'Redo', icon: 'fa-repeat'} ]
+ }];
+ return (
+
+
+
+
Menu
+
Menu is a navigation/command component that supports dynamic and static positioning.
+
+
+
+
+
Basic
+
+
+ Popup
+ this.menu=el}/>
+ this.menu.toggle(event)}/>
+
+
+
+
+
+ )
+ }
+}
+
+class MenuDoc extends Component {
+
+ render() {
+ return (
+
+
+
+ Import
+
+ {`
+import {Menu} from 'primereact/components/menu/Menu';
+
+`}
+
+
+ Getting Started
+ Menu requires a collection of menuitems as its model.Core of the api is MenuItem class that defines various options such as the label, icon and children of an item in a menu.MenuItem provides the following properties. Note that not all of them may be utilized by the menu component.
+
+
+
+
+ Name
+ Type
+ Default
+ Description
+
+
+
+
+ label
+ string
+ null
+ Text of the item.
+
+
+ icon
+ string
+ null
+ Icon of the item.
+
+
+ command
+ function
+ null
+ Callback to execute when item is clicked.
+
+
+ url
+ string
+ null
+ External link to navigate when item is clicked.
+
+
+ items
+ array
+ null
+ An array of children menuitems.
+
+
+ disabled
+ boolean
+ false
+ When set as true, disables the menuitem.
+
+
+ target
+ string
+ null
+ Specifies where to open the linked document.
+
+
+ separator
+ boolean
+ false
+ Defines the item as a separator.
+
+
+ style
+ object
+ null
+ Inline style of the menuitem.
+
+
+ styleClass
+ string
+ null
+ Style class of the menuitem.
+
+
+
+
+
+ Navigation
+ Navigation is specified using url property for external links and command function to invoke when an item is clicked is defined using the command property.
+
+ {`
+render() {
+ var items=[ {
+ label: 'File',
+ items: [{label: 'New', icon: 'fa-plus',command:()=>{ window.location.hash="/fileupload"; }},
+ {label: 'Open', icon: 'fa-download', url: 'http://primetek.com.tr'}]
+ }, {
+ label: 'Edit',
+ items: [{label: 'Undo', icon: 'fa-refresh',command:()=>{ window.location.hash="/"; }},
+ {label: 'Redo', icon: 'fa-repeat'} ]
+ }];
+}
+
+`}
+
+
+ Popup Mode
+ Menu is inline by default, popup mode is also supported by enabling popup property and calling toggle method by passing the event from the anchor element.
+
+ {`
+this.menu=el} />
+this.menu.toggle(event)}/>
+
+`}
+
+
+ Attributes
+
+
+
+
+ Name
+ Type
+ Default
+ Description
+
+
+
+
+ model
+ array
+ null
+ An array of menuitems.
+
+
+ popup
+ boolean
+ false
+ Defines if menu would displayed as a popup.
+
+
+ style
+ string
+ null
+ Inline style of the component.
+
+
+ styleClass
+ string
+ null
+ Style class of the component.
+
+
+
+
+
+ Methods
+
+
+
+
+ Name
+ Parameters
+ Description
+
+
+
+
+ toggle
+ event: browser event
+ Toggles the visibility of the popup menu.
+
+
+ show
+ event: browser event
+ Displays the popup menu.
+
+
+ hide
+ -
+ Hides the popup menu.
+
+
+
+
+
+ Events
+
+
+
+
+ Name
+ Parameters
+ Description
+
+
+
+
+ onShow
+ event.originalEvent: browser event
+ Displays the popup menu.
+
+
+ onHide
+ -
+ Hides the popup menu.
+
+
+
+
+
+ Styling
+ Following is the list of structural style classes, for theming classes visit theming page.
+
+
+
+
+ Name
+ Element
+
+
+
+
+ ui-menu
+ Container element.
+
+
+ ui-menu-list
+ List element.
+
+
+ ui-menuitem
+ Menuitem element.
+
+
+ ui-menuitem-text
+ Label of a menuitem.
+
+
+ ui-menuitem-icon
+ Icon of a menuitem.
+
+
+
+
+
+ Dependencies
+ None.
+
+
+
+
+ {`
+export class MenuDemo extends Component {
+
+ constructor() {
+ super();
+ this.state = {};
+ }
+
+ render() {
+ var items=[ {
+ label: 'File',
+ items: [{label: 'New', icon: 'fa-plus',command:()=>{ window.location.hash="/fileupload"; }},
+ {label: 'Open', icon: 'fa-download', url: 'http://primetek.com.tr'}]
+ }, {
+ label: 'Edit',
+ items: [{label: 'Undo', icon: 'fa-refresh',command:()=>{ window.location.hash="/"; }},
+ {label: 'Redo', icon: 'fa-repeat'} ]
+ }];
+ return (
+
+
+
+
Menu
+
Menu is a navigation/command component that supports dynamic and static positioning.
+
+
+
+
+
Basic
+
+
+ Popup
+ this.menu=el}/>
+ this.menu.toggle(event)}/>
+
+
+
+
+
+ )
+ }
+}
+`}
+
+
+
+
+ )
+ }
+}
\ No newline at end of file