Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const propTypes = {
isOpen: PropTypes.bool,
/** Display the toggle with no border or background */
isPlain: PropTypes.bool,
/** Indicates where menu will be alligned horizontally */
/** Indicates where menu will be aligned horizontally */
position: PropTypes.oneOf(Object.values(DropdownPosition)),
/** Display menu above or below dropdown toggle */
direction: PropTypes.oneOf(Object.values(DropdownDirection)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FunctionComponent, HTMLProps, ReactNode } from 'react';
import { DropdownDirection, DropdownPosition } from '../Dropdown';
import { OneOf } from '../../helpers';

export interface OptionsMenuProps extends HTMLProps<HTMLDivElement> {
className?: string;
id: string;
menuItems: ReactNode[];
toggle: ReactNode;
isPlain?: boolean;
isOpen?: boolean;
ariaLabelMenu?: string;
position?: OneOf<typeof DropdownPosition, keyof typeof DropdownPosition>;
direction?: OneOf<typeof DropdownDirection, keyof typeof DropdownDirection>;
}

declare const OptionsMenu: FunctionComponent<OptionsMenuProps>;

export default OptionsMenu;
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { Children, cloneElement, Component } from 'react';
import PropTypes from 'prop-types';
import styles from '@patternfly/patternfly/components/OptionsMenu/options-menu.css';
import { css, getModifier } from '@patternfly/react-styles';
import { OptionsMenuDirection, OptionsMenuPosition } from './optionsMenuConstants';

const propTypes = {
/** Classes applied to root element of the Options menu */
className: PropTypes.string,
/** Id of the root element of the Options menu */
id: PropTypes.string.isRequired,
/** Array of OptionsMenuItem and/or OptionMenuItemGroup nodes that will be rendered in the Options menu list */
menuItems: PropTypes.arrayOf(PropTypes.node).isRequired,
/** Either an OptionsMenuToggle or an OptionsMenuToggleWithText to use to toggle the Options menu */
toggle: PropTypes.node.isRequired,
/** Flag to indicate if menu is open */
isOpen: PropTypes.bool,
/** Flag to indicate the toggle has no border or background */
isPlain: PropTypes.bool,
/** Provides an accessible name for the Options menu */
ariaLabelMenu: PropTypes.string,
/** Display menu above or below Options menu toggle */
direction: PropTypes.oneOf(Object.values(OptionsMenuDirection)),
/** Indicates where menu will be aligned horizontally */
position: PropTypes.oneOf(Object.values(OptionsMenuPosition)),
};

const defaultProps = {
className: '',
isOpen: false,
isPlain: false,
ariaLabelMenu: '',
direction: OptionsMenuDirection.down,
position: OptionsMenuPosition.left,
};

class OptionsMenu extends Component {

render() {
const {
className,
direction,
position,
id,
isOpen,
isPlain,
ariaLabelMenu,
menuItems,
toggle } = this.props;
return (
<div id={id}
className={
css(styles.optionsMenu,
direction === OptionsMenuDirection.up && getModifier(styles, 'top'),
position === OptionsMenuPosition.right && getModifier(styles, 'align-right'),
isOpen && getModifier(styles, 'expanded'),
className)}>
{Children.map(toggle, oneToggle =>
cloneElement(oneToggle, {
parentId: id,
isOpen,
isPlain,
}))}
{isOpen &&
<ul className={css(styles.optionsMenuMenu,
position === OptionsMenuPosition.right && getModifier(styles, 'align-right'))}
{...ariaLabelMenu ? {'aria-label': ariaLabelMenu} : {'aria-labelledby': `${id}-toggle`}}>
{menuItems.map((item) => {
return item;
})}
</ul>}
</div>
)
}
}

OptionsMenu.propTypes = propTypes;
OptionsMenu.defaultProps = defaultProps;

export default OptionsMenu;
Loading