diff --git a/src/App.js b/src/App.js
index af12737042..67fb8f9a0e 100644
--- a/src/App.js
+++ b/src/App.js
@@ -229,6 +229,7 @@ class AppMenu extends Component {
● TabMenu
● Breadcrumb
● TieredMenu
+ ● Menubarssss
this.openMenu(event, 7)} className={classNames({ 'active-menuitem': this.state.activeMenu === 7 })}>
diff --git a/src/components/menu/MenuItem.js b/src/components/menu/MenuItem.js
index 87256d5433..6cd537bae1 100644
--- a/src/components/menu/MenuItem.js
+++ b/src/components/menu/MenuItem.js
@@ -7,14 +7,16 @@ export class MenuItem extends Component{
index:null,
items:null,
menu:null,
- parentMenu:null
+ parentMenu:null,
+ root:false,
};
static propTypes = {
index:PropTypes.number,
items:PropTypes.any,
menu:PropTypes.any,
- parentMenu:PropTypes.string
+ parentMenu:PropTypes.string,
+ root:PropTypes.bool
};
constructor(props) {
@@ -25,14 +27,16 @@ export class MenuItem extends Component{
}
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)
+ 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);
+ var rootClass=classNames('ui-submenu-icon fa fa-fw',{' fa-caret-down':this.props.root},{' fa-caret-right':!this.props.root})
if(this.item.url){
return (
this.menu.itemClick(event,this.item)}>
{this.item.items && this.props.parentMenu==='TieredMenu' && }
{this.item.icon && }
{this.item.label}
+ {this.item.items && this.props.parentMenu==='Menubar' && }
);
}
@@ -42,6 +46,7 @@ export class MenuItem extends Component{
{this.item.items && this.props.parentMenu==='TieredMenu' && }
{this.item.icon && }
{this.item.label}
+ {this.item.items && this.props.parentMenu==='Menubar' && }
);
}
diff --git a/src/components/menubar/Menubar.js b/src/components/menubar/Menubar.js
new file mode 100644
index 0000000000..2bf907d101
--- /dev/null
+++ b/src/components/menubar/Menubar.js
@@ -0,0 +1,34 @@
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import {NestedMenu} from "../nestedmenu/NestedMenu";
+
+export class Menubar extends Component{
+ static defaultProps = {
+ model:null,
+ style:null,
+ styleClass:null,
+ };
+
+ static propTypes = {
+ model:PropTypes.array,
+ style:PropTypes.object,
+ styleClass:PropTypes.string,
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = {};
+ }
+ render() {
+
+ var styleClass=classNames('ui-menubar ui-menu ui-widget ui-widget-content ui-corner-all ui-helper-clearfix', this.props.styleClass);
+ var ulClass=classNames('ui-menu-list ui-menubar-root-list ui-helper-clearfix');
+
+ return(
+
+ {this.props.children}
+
+ );
+ }
+}
diff --git a/src/components/nestedmenu/NestedMenu.js b/src/components/nestedmenu/NestedMenu.js
new file mode 100644
index 0000000000..4d258bd68f
--- /dev/null
+++ b/src/components/nestedmenu/NestedMenu.js
@@ -0,0 +1,41 @@
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import {NestedMenuItem} from './NestedMenuItem'
+
+export class NestedMenu extends Component{
+ static defaultProps = {
+ styleClass:null,
+ style:null,
+ items:null,
+ parentMenu:null,
+ root:null,
+ index:null
+ };
+
+ static propTypes = {
+ styleClass:PropTypes.string,
+ style:PropTypes.object,
+ items:PropTypes.any,
+ parentMenu:PropTypes.string,
+ root:PropTypes.bool,
+ index:PropTypes.any
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = {};
+ }
+ render() {
+ return(
+
+ {this.props.items && this.props.items.map((item,index)=>
+ )}
+
+ {this.props.parentMenu==='Menubar' && -
+ {this.props.children}
+
}
+
+ )
+ }
+}
diff --git a/src/components/nestedmenu/NestedMenuItem.css b/src/components/nestedmenu/NestedMenuItem.css
new file mode 100644
index 0000000000..8bc55bfdab
--- /dev/null
+++ b/src/components/nestedmenu/NestedMenuItem.css
@@ -0,0 +1,4 @@
+.ui-tieredmenu-item{
+ left: 100%;
+ top:0px;
+}
\ No newline at end of file
diff --git a/src/components/nestedmenu/NestedMenuItem.js b/src/components/nestedmenu/NestedMenuItem.js
new file mode 100644
index 0000000000..3d2efa0854
--- /dev/null
+++ b/src/components/nestedmenu/NestedMenuItem.js
@@ -0,0 +1,87 @@
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import {MenuItem} from "../menu/MenuItem";
+import DomHandler from '../utils/DomHandler';
+import {NestedMenu} from "./NestedMenu";
+
+export class NestedMenuItem extends Component{
+ static defaultProps = {
+ item:null,
+ menu:null,
+ parentMenu:null,
+ root:null,
+ index:null
+ };
+
+ static propTypes = {
+ item:PropTypes.any,
+ menu:PropTypes.any,
+ parentMenu:PropTypes.string,
+ root:PropTypes.bool,
+ index:PropTypes.any
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = {activeItem:null};
+ this.onItemMouseLeave=this.onItemMouseLeave.bind(this);
+ }
+ onItemMouseEnter(event, menuitem) {
+ this.setState({activeItem: menuitem});
+ this.sublist=event.currentTarget.children[1];
+ if(this.sublist){
+ this.sublist.style.zIndex = DomHandler.getZindex();
+ if(this.props.parentMenu==='TieredMenu' || (this.props.parentMenu==='Menubar' && !this.props.root))
+ DomHandler.addClass(this.sublist,'ui-tieredmenu-item');
+ this.sublist.style.display='block';
+ }
+ }
+ onItemMouseLeave(event) {
+ this.setState({activeItem:null});
+ if(this.sublist){
+ DomHandler.removeClass(this.sublist,'ui-tieredmenu-item')
+ this.sublist.style.display='none';}
+ }
+ itemClick(event,item){
+ if(item.disabled) {
+ event.preventDefault();
+ return;
+ }
+
+ if(!item.url) {
+ event.preventDefault();
+ }
+
+ if(item.command) {
+ item.command({
+ originalEvent: event,
+ item: item
+ });
+ }
+ }
+ render() {
+
+
+ var listClass=classNames('ui-menuitem ui-widget ui-corner-all',{'ui-menu-parent':this.props.item.items},
+ {'ui-menuitem-active':this.state.activeItem===this.props.item});
+ return( this.props.item.separator?
+ :
+ this.onItemMouseEnter(event,this.props.item)}
+ onMouseLeave={this.onItemMouseLeave} onClick={()=>{
+ this.setState({activeItem: null});
+ if(this.sublist)
+ this.sublist.style.display='none';
+ }}>
+
+
+
+ {this.props.item.items?
+ :null}
+
+
+ )
+
+ }
+}
\ No newline at end of file
diff --git a/src/components/tieredmenu/TieredMenu.js b/src/components/tieredmenu/TieredMenu.js
index ca50db48dc..dc0a1f7be6 100644
--- a/src/components/tieredmenu/TieredMenu.js
+++ b/src/components/tieredmenu/TieredMenu.js
@@ -1,8 +1,8 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import {TieredMenuItem} from "./TieredMenuItem";
import DomHandler from '../utils/DomHandler';
+import {NestedMenu} from "../nestedmenu/NestedMenu";
export class TieredMenu extends Component{
static defaultProps = {
@@ -23,24 +23,14 @@ export class TieredMenu extends Component{
super(props);
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;
- })
- }
- }
toggle(event){
+ if(this.documentClickListener) {
+ this.dropdownClick = true;
+ }
if(this.container.offsetParent)
this.hide(event);
else
this.show(event);
-
- this.preventDocumentDefault = true;
}
show(event) {
@@ -49,20 +39,46 @@ export class TieredMenu extends Component{
this.container.style.display = 'block';
DomHandler.absolutePosition(this.container, target);
DomHandler.fadeIn(this.container, 250);
- this.preventDocumentDefault = true;
+ this.bindDocumentListener();
}
hide(event) {
if(this.container)
this.container.style.display = 'none';
+ this.unbindDocumentListener();
+ }
+ bindDocumentListener() {
+ if(!this.documentClickListener) {
+ this.documentClickListener = () => {
+ if(this.dropdownClick)
+ this.dropdownClick = false;
+ else
+ this.hide();
+ };
+
+ document.addEventListener('click', this.documentClickListener);
+ }
}
+
+ unbindDocumentListener() {
+ if(this.documentClickListener) {
+ document.removeEventListener('click', this.documentClickListener);
+ this.documentClickListener = null;
+ }
+ }
+
+ componentWillUnmount() {
+ this.unbindDocumentListener();
+ }
+
render() {
- var styleClass=classNames('ui-tieredmenu ui-menu ui-widget ui-widget-content ui-corner-all ui-helper-clearfix',
+ var divClass=classNames('ui-tieredmenu 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 ulClass=classNames('ui-menu-list ui-helper-reset');
return(
- this.container=el}>
-
+ this.container=el}>
+
);
}
diff --git a/src/components/tieredmenu/TieredMenuItem.js b/src/components/tieredmenu/TieredMenuItem.js
deleted file mode 100644
index 1f05dad08c..0000000000
--- a/src/components/tieredmenu/TieredMenuItem.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import React, {Component} from 'react';
-import PropTypes from 'prop-types';
-import classNames from 'classnames';
-import {MenuItem} from "../menu/MenuItem";
-import DomHandler from '../utils/DomHandler';
-
-export class TieredMenuItem extends Component{
- static defaultProps = {
- index:0,
- items:null,
- menu:null,
- root:false
- };
-
- static propTypes = {
- index:PropTypes.number,
- items:PropTypes.any,
- menu:PropTypes.any,
- root:PropTypes.bool
- };
-
- constructor(props) {
- super(props);
- this.state = {activeItem:null};
- this.listClick=this.listClick.bind(this);
- this.onItemMouseLeave=this.onItemMouseLeave.bind(this);
- }
- onItemMouseEnter(event, menuitem) {
- this.setState({activeItem: menuitem});
- this.sublist=event.currentTarget.children[1];
- if(this.sublist){
- this.sublist.style.zIndex = DomHandler.getZindex();
- this.sublist.style.top = '0px';
- this.sublist.style.display='block';
- this.sublist.style.left='100%'
- }
- }
- onItemMouseLeave(event) {
- this.setState({activeItem:null});
- if(this.sublist)
- this.sublist.style.display='none';
- }
- itemClick(event,item){
- if(item.disabled) {
- event.preventDefault();
- return;
- }
-
- if(!item.url) {
- event.preventDefault();
- }
-
- if(item.command) {
- item.command({
- originalEvent: event,
- item: item
- });
- }
- }
- listClick(event) {
- this.setState({activeItem: null});
- if(this.sublist)
- this.sublist.style.display='none';
- }
- render() {
-
- var styleClass=classNames('ui-menu-list',{'ui-helper-reset':this.props.root},
- {'ui-widget-content ui-corner-all ui-helper-clearfix ui-menu-child ui-shadow':!this.props.root})
- var mapElement=this.props.root?this.props.items:this.props.items.items;
- var childElement;
-
- childElement=mapElement && mapElement.map((child,index)=>{
- var listClass=classNames('ui-menuitem ui-widget ui-corner-all',{'ui-menu-parent':child.items},
- {'ui-menuitem-active':this.state.activeItem===child})
- var element=child.separator?
- :
- this.onItemMouseEnter(event,child)}
- onMouseLeave={this.onItemMouseLeave}>
-
-
- return element;
- })
-
- return(
- this.list=el} onClick={this.listClick}>
- {childElement}
-
- )
- }
-}
diff --git a/src/index.js b/src/index.js
index c7dfb4da54..e3b8e256be 100644
--- a/src/index.js
+++ b/src/index.js
@@ -70,6 +70,7 @@ import {MenuDemo} from './showcase/menu/MenuDemo';
import {TabMenuDemo} from './showcase/tabmenu/TabMenuDemo';
import {BreadcrumbDemo} from './showcase/breadcrumb/BreadcrumbDemo';
import {TieredMenuDemo} from './showcase/tieredmenu/TieredMenuDemo';
+import {MenubarDemo} from './showcase/menubar/MenubarDemo';
import {Router,Route,hashHistory} from 'react-router';
ReactDOM.render(
@@ -142,6 +143,7 @@ ReactDOM.render(
+
diff --git a/src/showcase/menubar/MenubarDemo.js b/src/showcase/menubar/MenubarDemo.js
new file mode 100644
index 0000000000..b15129a552
--- /dev/null
+++ b/src/showcase/menubar/MenubarDemo.js
@@ -0,0 +1,419 @@
+import React, {Component} from 'react';
+import {Link} from 'react-router';
+import {Menubar} from '../../components/menubar/Menubar';
+import {Button} from '../../components/button/Button';
+import {TabView,TabPanel} from '../../components/tabview/TabView';
+import {CodeHighlight} from '../../components/codehighlight/CodeHighlight';
+import {InputText} from "../../components/inputtext/InputText";
+
+export class MenubarDemo extends Component {
+
+ constructor() {
+ super();
+ this.state = {};
+ }
+
+ render() {
+ var items=[ {
+ label: 'File',
+ icon: 'fa-file-o',
+ items: [{
+ label: 'New',
+ icon: 'fa-plus',
+ items: [
+ {label: 'Project'},
+ {label: 'Other'},
+ ]
+ },
+ {label: 'Open'},
+ {separator:true},
+ {label: 'Quit'}
+ ]
+ },
+ {
+ label: 'Edit',
+ icon: 'fa-edit',
+ items: [
+ {label: 'Undo', icon: 'fa-mail-forward'},
+ {label: 'Redo', icon: 'fa-mail-reply'}
+ ]
+ },
+ {
+ label: 'Help',
+ icon: 'fa-question',
+ items: [
+ {
+ label: 'Contents'
+ },
+ {
+ label: 'Search',
+ icon: 'fa-search',
+ items: [
+ {
+ label: 'Text',
+ items: [
+ {
+ label: 'Workspace'
+ }
+ ]
+ },
+ {
+ label: 'File'
+ }
+ ]}
+ ]
+ },
+ {
+ label: 'Actions',
+ icon: 'fa-gear',
+ items: [
+ {
+ label: 'Edit',
+ icon: 'fa-refresh',
+ items: [
+ {label: 'Save', icon: 'fa-save'},
+ {label: 'Update', icon: 'fa-save'},
+ ]
+ },
+ {
+ label: 'Other',
+ icon: 'fa-phone',
+ items: [
+ {label: 'Delete', icon: 'fa-minus'}
+ ]
+ }
+ ]
+ },
+ {
+ label: 'Quit', icon: 'fa-minus'
+ }];
+ return (
+
+
+
+
Menubar
+
Menubar is an horizontal menu components with support for nested submenus.
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+class MenubarDoc extends Component {
+ render() {
+ return (
+
+
+
+ Import
+
+ {`
+import {Menubar} from 'primereact/components/menubar/Menubar';
+
+`}
+ MenuItem API
+ Menubar uses the common menu item api to define its items, visit Menu for details.
+
+ Getting Started
+ Menubar requires nested menuitems as its model.
+
+ {`
+
+
+`}
+
+ {`
+var items=[
+ {
+ label: 'File',
+ icon: 'fa-file-o',
+ items: [{
+ label: 'New',
+ icon: 'fa-plus',
+ items: [
+ {label: 'Project'},
+ {label: 'Other'},
+ ]
+ },
+ {label: 'Open'},
+ {separator:true},
+ {label: 'Quit'}
+ ]
+ },
+ {
+ label: 'Edit',
+ icon: 'fa-edit',
+ items: [
+ {label: 'Undo', icon: 'fa-mail-forward'},
+ {label: 'Redo', icon: 'fa-mail-reply'}
+ ]
+ },
+ {
+ label: 'Help',
+ icon: 'fa-question',
+ items: [
+ {
+ label: 'Contents'
+ },
+ {
+ label: 'Search',
+ icon: 'fa-search',
+ items: [
+ {
+ label: 'Text',
+ items: [
+ {
+ label: 'Workspace'
+ }
+ ]
+ },
+ {
+ label: 'File'
+ }
+ ]}
+ ]
+ },
+ {
+ label: 'Actions',
+ icon: 'fa-gear',
+ items: [
+ {
+ label: 'Edit',
+ icon: 'fa-refresh',
+ items: [
+ {label: 'Save', icon: 'fa-save'},
+ {label: 'Update', icon: 'fa-save'},
+ ]
+ },
+ {
+ label: 'Other',
+ icon: 'fa-phone',
+ items: [
+ {label: 'Delete', icon: 'fa-minus'}
+ ]
+ }
+ ]
+ },
+ {
+ label: 'Quit', icon: 'fa-minus'
+ }
+];
+
+`}
+
+ Custom Content
+ Custom content can be placed between Menubar tags.
+
+ {`
+
+
+
+
+`}
+
+ Attributes
+
+
+
+
+ Name |
+ Type |
+ Default |
+ Description |
+
+
+
+
+ model |
+ array |
+ null |
+ An array of menuitems. |
+
+
+ style |
+ string |
+ null |
+ Inline style of the component. |
+
+
+ styleClass |
+ string |
+ null |
+ Style class of the component. |
+
+
+
+
+
+ Styling
+ Following is the list of structural style classes, for theming classes visit theming page.
+
+
+
+
+ Name |
+ Element |
+
+
+
+
+ ui-menubar |
+ 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. |
+
+
+ ui-submenu-icon |
+ Arrow icon of a submenu. |
+
+
+
+
+
+ Dependencies
+ None.
+
+
+
+
+
+ View on GitHub
+
+
+ {`
+export class MenubarDemo extends Component {
+
+ constructor() {
+ super();
+ this.state = {};
+ }
+
+ render() {
+ var items=[ {
+ label: 'File',
+ icon: 'fa-file-o',
+ items: [{
+ label: 'New',
+ icon: 'fa-plus',
+ items: [
+ {label: 'Project'},
+ {label: 'Other'},
+ ]
+ },
+ {label: 'Open'},
+ {separator:true},
+ {label: 'Quit'}
+ ]
+ },
+ {
+ label: 'Edit',
+ icon: 'fa-edit',
+ items: [
+ {label: 'Undo', icon: 'fa-mail-forward'},
+ {label: 'Redo', icon: 'fa-mail-reply'}
+ ]
+ },
+ {
+ label: 'Help',
+ icon: 'fa-question',
+ items: [
+ {
+ label: 'Contents'
+ },
+ {
+ label: 'Search',
+ icon: 'fa-search',
+ items: [
+ {
+ label: 'Text',
+ items: [
+ {
+ label: 'Workspace'
+ }
+ ]
+ },
+ {
+ label: 'File'
+ }
+ ]}
+ ]
+ },
+ {
+ label: 'Actions',
+ icon: 'fa-gear',
+ items: [
+ {
+ label: 'Edit',
+ icon: 'fa-refresh',
+ items: [
+ {label: 'Save', icon: 'fa-save'},
+ {label: 'Update', icon: 'fa-save'},
+ ]
+ },
+ {
+ label: 'Other',
+ icon: 'fa-phone',
+ items: [
+ {label: 'Delete', icon: 'fa-minus'}
+ ]
+ }
+ ]
+ },
+ {
+ label: 'Quit', icon: 'fa-minus'
+ }];
+ return (
+
+
+
+
Menubar
+
Menubar is an horizontal menu components with support for nested submenus.
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+ `}
+
+
+
+
+ )
+ }
+
+}
\ No newline at end of file
diff --git a/src/showcase/tieredmenu/TieredMenuDemo.js b/src/showcase/tieredmenu/TieredMenuDemo.js
index 463a6ec9ee..76f45b2707 100644
--- a/src/showcase/tieredmenu/TieredMenuDemo.js
+++ b/src/showcase/tieredmenu/TieredMenuDemo.js
@@ -134,7 +134,7 @@ import {TieredMenu} from 'primereact/components/tieredmenu/TieredMenu';
`}
- Attributes
aa
+ Attributes