Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/ComboboxInput/ComboboxInput.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ComboboxInput } from './ComboboxInput';
import Menu from '../Menu/Menu';
import MenuItem from '../Menu/MenuItem';
import MenuList from '../Menu/MenuList';
import { mount } from 'enzyme';
import React from 'react';
import renderer from 'react-test-renderer';
import { Menu, MenuItem, MenuList } from '../Menu/Menu';

describe('<ComboboxInput />', () => {
const defaultMenu = (
Expand Down
4 changes: 3 additions & 1 deletion src/Dropdown/Dropdown.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Button } from '../';
import { Dropdown } from './Dropdown';
import Menu from '../Menu/Menu';
import MenuItem from '../Menu/MenuItem';
import MenuList from '../Menu/MenuList';
import { mount } from 'enzyme';
import { Popover } from '../Popover/Popover';
import React from 'react';
import renderer from 'react-test-renderer';
import { Menu, MenuItem, MenuList } from '../Menu/Menu';

describe('<Dropdown />', () => {
const defaultMenu = (
Expand Down
112 changes: 3 additions & 109 deletions src/Menu/Menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import classnames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

// ------------------------------------------- Menu ------------------------------------------
export const Menu = ({ addonBefore, children, className, ...props }) => {
const Menu = ({ addonBefore, children, className, ...props }) => {
const menuClasses = classnames(
'fd-menu',
{
Expand All @@ -18,6 +17,7 @@ export const Menu = ({ addonBefore, children, className, ...props }) => {
</nav>
);
};

Menu.displayName = 'Menu';

Menu.propTypes = {
Expand All @@ -29,110 +29,4 @@ Menu.propDescriptions = {
addonBefore: 'Set to **true** enables menu items with add-on before.'
};

// ---------------------------------------- Menu List ----------------------------------------
export const MenuList = ({ children, className, ...props }) => {
const menuListClasses = classnames(
'fd-menu__list',
className
);

return <ul {...props} className={menuListClasses}>{children}</ul>;
};
MenuList.displayName = 'MenuList';

MenuList.propTypes = {
children: PropTypes.node,
className: PropTypes.string
};

// ---------------------------------------- Menu Item ----------------------------------------
export const MenuItem = ({ url, isLink, separator, addon, children, onclick, className, addonProps, urlProps, ...props }) => {
const menuItemLinkClasses = classnames(
'fd-menu__item',
{
'fd-menu__link': isLink
}
);

const renderLink = () => {
if (url) {
return (
<a {...urlProps}
className={menuItemLinkClasses}
href={url}
onClick={onclick}>
{children}
</a>
);
} else if (children && React.isValidElement(children)) {
const childrenClassnames = classnames(
menuItemLinkClasses,
children.props.className
);

return React.cloneElement(children, {
'className': childrenClassnames,
...urlProps
});
} else if (children) {
return (<a {...urlProps}
className='fd-menu__item'
onClick={onclick}>{children}</a>);
}
};

return (
<React.Fragment>
<li {...props} className={className}>
{addon &&
<div {...addonProps} className='fd-menu__addon-before'>{<span className={'sap-icon--' + addon} />}</div>
}
{renderLink()}
</li>
{separator && <hr />}
</React.Fragment>
);
};
MenuItem.displayName = 'MenuItem';

MenuItem.propTypes = {
addon: PropTypes.string,
addonProps: PropTypes.object,
className: PropTypes.string,
isLink: PropTypes.bool,
separator: PropTypes.bool,
url: PropTypes.string,
urlProps: PropTypes.object
};

MenuItem.propDescriptions = {
addon: 'Name of the SAP icon to be applied as an add-on before.',
addonProps: 'Additional props to be spread to the add-on section.',
children: 'component - can be used to pass React Router <Link> or any other component which emits an <a>.',
isLink: 'Set to **true** to style as a link.',
separator: 'Set to **true** to add a horizontal line (separator).',
url: 'Enables use of `<a>` element. Value to be applied to the anchor\'s `href` attribute. Should use either `link` or `url`, but not both.',
urlProps: 'Additional props to be spread to the Menu Item links (when using `url`).'
};

// ---------------------------------------- Menu Group ----------------------------------------
export const MenuGroup = ({ title, children, className, titleProps, ...props }) => {
const menuGroupClasses = classnames(
'fd-menu__group',
className
);

return (
<div {...props} className={menuGroupClasses}>
<h1 {...titleProps} className='fd-menu__title'>{title}</h1>
{children}
</div>
);
};
MenuGroup.displayName = 'MenuGroup';

MenuGroup.propTypes = {
title: PropTypes.string.isRequired,
className: PropTypes.string,
titleProps: PropTypes.object
};
export default Menu;
5 changes: 4 additions & 1 deletion src/Menu/Menu.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import Menu from './Menu';
import MenuGroup from './MenuGroup';
import MenuItem from './MenuItem';
import MenuList from './MenuList';
import { mount } from 'enzyme';
import React from 'react';
import renderer from 'react-test-renderer';
import { Link, MemoryRouter } from 'react-router-dom';
import { Menu, MenuGroup, MenuItem, MenuList } from './Menu';

describe('<Menu />', () => {
const basicMenuCode = (
Expand Down
27 changes: 27 additions & 0 deletions src/Menu/MenuGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import classnames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

const MenuGroup = ({ title, children, className, titleProps, ...props }) => {
const menuGroupClasses = classnames(
'fd-menu__group',
className
);

return (
<div {...props} className={menuGroupClasses}>
<h1 {...titleProps} className='fd-menu__title'>{title}</h1>
{children}
</div>
);
};

MenuGroup.displayName = 'MenuGroup';

MenuGroup.propTypes = {
title: PropTypes.string.isRequired,
className: PropTypes.string,
titleProps: PropTypes.object
};

export default MenuGroup;
75 changes: 75 additions & 0 deletions src/Menu/MenuItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import classnames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

const MenuItem = ({ url, isLink, separator, addon, children, onclick, className, addonProps, urlProps, ...props }) => {
const menuItemLinkClasses = classnames(
'fd-menu__item',
{
'fd-menu__link': isLink
}
);

const renderLink = () => {
if (url) {
return (
<a {...urlProps}
className={menuItemLinkClasses}
href={url}
onClick={onclick}>
{children}
</a>
);
} else if (children && React.isValidElement(children)) {
const childrenClassnames = classnames(
menuItemLinkClasses,
children.props.className
);

return React.cloneElement(children, {
'className': childrenClassnames,
...urlProps
});
} else if (children) {
return (<a {...urlProps}
className='fd-menu__item'
onClick={onclick}>{children}</a>);
}
};

return (
<React.Fragment>
<li {...props} className={className}>
{addon &&
<div {...addonProps} className='fd-menu__addon-before'>{<span className={'sap-icon--' + addon} />}</div>
}
{renderLink()}
</li>
{separator && <hr />}
</React.Fragment>
);
};

MenuItem.displayName = 'MenuItem';

MenuItem.propTypes = {
addon: PropTypes.string,
addonProps: PropTypes.object,
className: PropTypes.string,
isLink: PropTypes.bool,
separator: PropTypes.bool,
url: PropTypes.string,
urlProps: PropTypes.object
};

MenuItem.propDescriptions = {
addon: 'Name of the SAP icon to be applied as an add-on before.',
addonProps: 'Additional props to be spread to the add-on section.',
children: 'component - can be used to pass React Router <Link> or any other component which emits an <a>.',
isLink: 'Set to **true** to style as a link.',
separator: 'Set to **true** to add a horizontal line (separator).',
url: 'Enables use of `<a>` element. Value to be applied to the anchor\'s `href` attribute. Should use either `link` or `url`, but not both.',
urlProps: 'Additional props to be spread to the Menu Item links (when using `url`).'
};

export default MenuItem;
21 changes: 21 additions & 0 deletions src/Menu/MenuList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import classnames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

const MenuList = ({ children, className, ...props }) => {
const menuListClasses = classnames(
'fd-menu__list',
className
);

return <ul {...props} className={menuListClasses}>{children}</ul>;
};

MenuList.displayName = 'MenuList';

MenuList.propTypes = {
children: PropTypes.node,
className: PropTypes.string
};

export default MenuList;
4 changes: 3 additions & 1 deletion src/Popover/Popover.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Icon } from '../Icon/Icon';
import Menu from '../Menu/Menu';
import MenuItem from '../Menu/MenuItem';
import MenuList from '../Menu/MenuList';
import { mount } from 'enzyme';
import { Popover } from './Popover';
import React from 'react';
import renderer from 'react-test-renderer';
import { Menu, MenuItem, MenuList } from '../Menu/Menu';

describe('<Popover />', () => {
const popOver = (
Expand Down
4 changes: 3 additions & 1 deletion src/Shellbar/Shellbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import classnames from 'classnames';
import { Counter } from '../Badge/Badge';
import { Icon } from '../Icon/Icon';
import { Identifier } from '../Identifier/Identifier';
import Menu from '../Menu/Menu';
import MenuItem from '../Menu/MenuItem';
import MenuList from '../Menu/MenuList';
import { Popover } from '../Popover/Popover';
import PropTypes from 'prop-types';
import { SearchInput } from '../SearchInput/SearchInput';
import { Menu, MenuItem, MenuList } from '../Menu/Menu';
import React, { Component } from 'react';

export class Shellbar extends Component {
Expand Down
4 changes: 3 additions & 1 deletion src/Shellbar/Shellbar.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import Menu from '../Menu/Menu';
import MenuItem from '../Menu/MenuItem';
import MenuList from '../Menu/MenuList';
import { mount } from 'enzyme';
import React from 'react';
import renderer from 'react-test-renderer';
import { Shellbar } from './Shellbar';
import { Menu, MenuItem, MenuList } from '../Menu/Menu';

describe('<Shellbar />', () => {
const profile1 = {
Expand Down
4 changes: 3 additions & 1 deletion src/Tile/Tile.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Button } from '../';
import { Identifier } from '../Identifier/Identifier';
import Menu from '../Menu/Menu';
import MenuItem from '../Menu/MenuItem';
import MenuList from '../Menu/MenuList';
import { mount } from 'enzyme';
import { Popover } from '../Popover/Popover';
import React from 'react';
import renderer from 'react-test-renderer';
import { Menu, MenuItem, MenuList } from '../Menu/Menu';
import { ProductTile, ProductTileContent, ProductTileMedia, Tile, TileActions, TileContent, TileGrid, TileMedia } from './Tile';

describe('<Tile />', () => {
Expand Down
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export { default as InputGroup } from './InputGroup/InputGroup';
export { default as FormGroup } from './InputGroup/FormGroup';
export { ListGroup, ListGroupItem, ListGroupItemActions, ListGroupItemCheckbox } from './ListGroup/ListGroup';
export { LocalizationEditor } from './LocalizationEditor/LocalizationEditor';
export { Menu, MenuList, MenuItem, MenuGroup } from './Menu/Menu';
export { default as Menu } from './Menu/Menu';
export { default as MenuList } from './Menu/MenuList';
export { default as MenuItem } from './Menu/MenuItem';
export { default as MenuGroup } from './Menu/MenuGroup';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have expected to see all these as static references on Menu and then only Menu would be exported. Something like:

Menu.Item = MenuItem;
Menu.Group = MenuGroup;
Menu.List = MenuList;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, should've caught that. Moved to subcomponents in 8127fcc

export { Modal } from './Modal/Modal';
export { MultiInput } from './MultiInput/MultiInput';
export { Pagination } from './Pagination/Pagination';
Expand Down