494 lines
15 KiB
JavaScript
494 lines
15 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _extends2 = require('babel-runtime/helpers/extends');
|
|
|
|
var _extends3 = _interopRequireDefault(_extends2);
|
|
|
|
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
|
|
|
|
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
|
|
|
|
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
|
|
|
|
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
|
|
|
|
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
|
|
|
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
|
|
|
var _createClass2 = require('babel-runtime/helpers/createClass');
|
|
|
|
var _createClass3 = _interopRequireDefault(_createClass2);
|
|
|
|
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
|
|
|
|
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
|
|
|
|
var _inherits2 = require('babel-runtime/helpers/inherits');
|
|
|
|
var _inherits3 = _interopRequireDefault(_inherits2);
|
|
|
|
var _simpleAssign = require('simple-assign');
|
|
|
|
var _simpleAssign2 = _interopRequireDefault(_simpleAssign);
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactDom = require('react-dom');
|
|
|
|
var _reactDom2 = _interopRequireDefault(_reactDom);
|
|
|
|
var _transitions = require('../styles/transitions');
|
|
|
|
var _transitions2 = _interopRequireDefault(_transitions);
|
|
|
|
var _arrowDropDown = require('../svg-icons/navigation/arrow-drop-down');
|
|
|
|
var _arrowDropDown2 = _interopRequireDefault(_arrowDropDown);
|
|
|
|
var _Menu = require('../Menu/Menu');
|
|
|
|
var _Menu2 = _interopRequireDefault(_Menu);
|
|
|
|
var _ClearFix = require('../internal/ClearFix');
|
|
|
|
var _ClearFix2 = _interopRequireDefault(_ClearFix);
|
|
|
|
var _Popover = require('../Popover/Popover');
|
|
|
|
var _Popover2 = _interopRequireDefault(_Popover);
|
|
|
|
var _PopoverAnimationVertical = require('../Popover/PopoverAnimationVertical');
|
|
|
|
var _PopoverAnimationVertical2 = _interopRequireDefault(_PopoverAnimationVertical);
|
|
|
|
var _keycode = require('keycode');
|
|
|
|
var _keycode2 = _interopRequireDefault(_keycode);
|
|
|
|
var _events = require('../utils/events');
|
|
|
|
var _events2 = _interopRequireDefault(_events);
|
|
|
|
var _IconButton = require('../IconButton');
|
|
|
|
var _IconButton2 = _interopRequireDefault(_IconButton);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var anchorOrigin = {
|
|
vertical: 'top',
|
|
horizontal: 'left'
|
|
};
|
|
|
|
function getStyles(props, context) {
|
|
var disabled = props.disabled;
|
|
|
|
var spacing = context.muiTheme.baseTheme.spacing;
|
|
var palette = context.muiTheme.baseTheme.palette;
|
|
var accentColor = context.muiTheme.dropDownMenu.accentColor;
|
|
return {
|
|
control: {
|
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
height: '100%',
|
|
position: 'relative',
|
|
width: '100%'
|
|
},
|
|
icon: {
|
|
fill: accentColor,
|
|
position: 'absolute',
|
|
right: spacing.desktopGutterLess,
|
|
top: (spacing.iconSize - 24) / 2 + spacing.desktopGutterMini / 2
|
|
},
|
|
iconChildren: {
|
|
fill: 'inherit'
|
|
},
|
|
label: {
|
|
color: disabled ? palette.disabledColor : palette.textColor,
|
|
lineHeight: spacing.desktopToolbarHeight + 'px',
|
|
overflow: 'hidden',
|
|
opacity: 1,
|
|
position: 'relative',
|
|
paddingLeft: spacing.desktopGutter,
|
|
paddingRight: spacing.iconSize * 2 + spacing.desktopGutterMini,
|
|
textOverflow: 'ellipsis',
|
|
top: 0,
|
|
whiteSpace: 'nowrap'
|
|
},
|
|
labelWhenOpen: {
|
|
opacity: 0,
|
|
top: spacing.desktopToolbarHeight / 8
|
|
},
|
|
root: {
|
|
display: 'inline-block',
|
|
fontSize: spacing.desktopDropDownMenuFontSize,
|
|
height: spacing.desktopSubheaderHeight,
|
|
fontFamily: context.muiTheme.baseTheme.fontFamily,
|
|
outline: 'none',
|
|
position: 'relative',
|
|
transition: _transitions2.default.easeOut()
|
|
},
|
|
rootWhenOpen: {
|
|
opacity: 1
|
|
},
|
|
underline: {
|
|
borderTop: 'solid 1px ' + accentColor,
|
|
bottom: 1,
|
|
left: 0,
|
|
margin: '-1px ' + spacing.desktopGutter + 'px',
|
|
right: 0,
|
|
position: 'absolute'
|
|
}
|
|
};
|
|
}
|
|
|
|
var DropDownMenu = function (_Component) {
|
|
(0, _inherits3.default)(DropDownMenu, _Component);
|
|
|
|
function DropDownMenu() {
|
|
var _ref;
|
|
|
|
var _temp, _this, _ret;
|
|
|
|
(0, _classCallCheck3.default)(this, DropDownMenu);
|
|
|
|
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
|
|
return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = DropDownMenu.__proto__ || (0, _getPrototypeOf2.default)(DropDownMenu)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
|
|
open: false
|
|
}, _this.rootNode = undefined, _this.arrowNode = undefined, _this.handleTouchTapControl = function (event) {
|
|
event.preventDefault();
|
|
if (!_this.props.disabled) {
|
|
_this.setState({
|
|
open: !_this.state.open,
|
|
anchorEl: _this.rootNode
|
|
});
|
|
}
|
|
}, _this.handleRequestCloseMenu = function () {
|
|
_this.close(false);
|
|
}, _this.handleEscKeyDownMenu = function () {
|
|
_this.close(true);
|
|
}, _this.handleKeyDown = function (event) {
|
|
switch ((0, _keycode2.default)(event)) {
|
|
case 'up':
|
|
case 'down':
|
|
case 'space':
|
|
case 'enter':
|
|
event.preventDefault();
|
|
_this.setState({
|
|
open: true,
|
|
anchorEl: _this.rootNode
|
|
});
|
|
break;
|
|
}
|
|
}, _this.handleItemTouchTap = function (event, child, index) {
|
|
event.persist();
|
|
_this.setState({
|
|
open: false
|
|
}, function () {
|
|
if (_this.props.onChange) {
|
|
_this.props.onChange(event, index, child.props.value);
|
|
}
|
|
|
|
_this.close(_events2.default.isKeyboard(event));
|
|
});
|
|
}, _this.close = function (isKeyboard) {
|
|
_this.setState({
|
|
open: false
|
|
}, function () {
|
|
if (_this.props.onClose) {
|
|
_this.props.onClose();
|
|
}
|
|
|
|
if (isKeyboard) {
|
|
var dropArrow = _this.arrowNode;
|
|
var dropNode = _reactDom2.default.findDOMNode(dropArrow);
|
|
dropNode.focus();
|
|
dropArrow.setKeyboardFocus(true);
|
|
}
|
|
});
|
|
}, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
|
|
}
|
|
|
|
// The nested styles for drop-down-menu are modified by toolbar and possibly
|
|
// other user components, so it will give full access to its js styles rather
|
|
// than just the parent.
|
|
|
|
|
|
(0, _createClass3.default)(DropDownMenu, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
var _this2 = this;
|
|
|
|
if (this.props.autoWidth) {
|
|
this.setWidth();
|
|
}
|
|
if (this.props.openImmediately) {
|
|
// TODO: Temporary fix to make openImmediately work with popover.
|
|
/* eslint-disable react/no-did-mount-set-state */
|
|
setTimeout(function () {
|
|
return _this2.setState({
|
|
open: true,
|
|
anchorEl: _this2.rootNode
|
|
});
|
|
}, 0);
|
|
/* eslint-enable react/no-did-mount-set-state */
|
|
}
|
|
}
|
|
}, {
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps() {
|
|
if (this.props.autoWidth) {
|
|
this.setWidth();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'getInputNode',
|
|
|
|
|
|
/**
|
|
* This method is deprecated but still here because the TextField
|
|
* need it in order to work. TODO: That will be addressed later.
|
|
*/
|
|
value: function getInputNode() {
|
|
var _this3 = this;
|
|
|
|
var rootNode = this.rootNode;
|
|
|
|
rootNode.focus = function () {
|
|
if (!_this3.props.disabled) {
|
|
_this3.setState({
|
|
open: !_this3.state.open,
|
|
anchorEl: _this3.rootNode
|
|
});
|
|
}
|
|
};
|
|
|
|
return rootNode;
|
|
}
|
|
}, {
|
|
key: 'setWidth',
|
|
value: function setWidth() {
|
|
var el = this.rootNode;
|
|
if (!this.props.style || !this.props.style.hasOwnProperty('width')) {
|
|
el.style.width = 'auto';
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _this4 = this;
|
|
|
|
var _props = this.props,
|
|
animated = _props.animated,
|
|
animation = _props.animation,
|
|
autoWidth = _props.autoWidth,
|
|
children = _props.children,
|
|
className = _props.className,
|
|
iconStyle = _props.iconStyle,
|
|
labelStyle = _props.labelStyle,
|
|
listStyle = _props.listStyle,
|
|
maxHeight = _props.maxHeight,
|
|
menuStyleProp = _props.menuStyle,
|
|
onClose = _props.onClose,
|
|
openImmediately = _props.openImmediately,
|
|
menuItemStyle = _props.menuItemStyle,
|
|
selectedMenuItemStyle = _props.selectedMenuItemStyle,
|
|
style = _props.style,
|
|
underlineStyle = _props.underlineStyle,
|
|
value = _props.value,
|
|
other = (0, _objectWithoutProperties3.default)(_props, ['animated', 'animation', 'autoWidth', 'children', 'className', 'iconStyle', 'labelStyle', 'listStyle', 'maxHeight', 'menuStyle', 'onClose', 'openImmediately', 'menuItemStyle', 'selectedMenuItemStyle', 'style', 'underlineStyle', 'value']);
|
|
var _state = this.state,
|
|
anchorEl = _state.anchorEl,
|
|
open = _state.open;
|
|
var prepareStyles = this.context.muiTheme.prepareStyles;
|
|
|
|
var styles = getStyles(this.props, this.context);
|
|
|
|
var displayValue = '';
|
|
_react2.default.Children.forEach(children, function (child) {
|
|
if (child && value === child.props.value) {
|
|
// This will need to be improved (in case primaryText is a node)
|
|
displayValue = child.props.label || child.props.primaryText;
|
|
}
|
|
});
|
|
|
|
var menuStyle = void 0;
|
|
if (anchorEl && !autoWidth) {
|
|
menuStyle = (0, _simpleAssign2.default)({
|
|
width: anchorEl.clientWidth
|
|
}, menuStyleProp);
|
|
} else {
|
|
menuStyle = menuStyleProp;
|
|
}
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
(0, _extends3.default)({}, other, {
|
|
ref: function ref(node) {
|
|
_this4.rootNode = node;
|
|
},
|
|
className: className,
|
|
style: prepareStyles((0, _simpleAssign2.default)({}, styles.root, open && styles.rootWhenOpen, style))
|
|
}),
|
|
_react2.default.createElement(
|
|
_ClearFix2.default,
|
|
{ style: styles.control, onTouchTap: this.handleTouchTapControl },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ style: prepareStyles((0, _simpleAssign2.default)({}, styles.label, open && styles.labelWhenOpen, labelStyle)) },
|
|
displayValue
|
|
),
|
|
_react2.default.createElement(
|
|
_IconButton2.default,
|
|
{
|
|
tabIndex: this.props.disabled ? -1 : undefined,
|
|
onKeyDown: this.handleKeyDown,
|
|
ref: function ref(node) {
|
|
_this4.arrowNode = node;
|
|
},
|
|
style: (0, _simpleAssign2.default)({}, styles.icon, iconStyle),
|
|
iconStyle: styles.iconChildren
|
|
},
|
|
_react2.default.createElement(_arrowDropDown2.default, null)
|
|
),
|
|
_react2.default.createElement('div', { style: prepareStyles((0, _simpleAssign2.default)({}, styles.underline, underlineStyle)) })
|
|
),
|
|
_react2.default.createElement(
|
|
_Popover2.default,
|
|
{
|
|
anchorOrigin: anchorOrigin,
|
|
anchorEl: anchorEl,
|
|
animation: animation || _PopoverAnimationVertical2.default,
|
|
open: open,
|
|
animated: animated,
|
|
onRequestClose: this.handleRequestCloseMenu
|
|
},
|
|
_react2.default.createElement(
|
|
_Menu2.default,
|
|
{
|
|
maxHeight: maxHeight,
|
|
desktop: true,
|
|
value: value,
|
|
onEscKeyDown: this.handleEscKeyDownMenu,
|
|
style: menuStyle,
|
|
listStyle: listStyle,
|
|
onItemTouchTap: this.handleItemTouchTap,
|
|
menuItemStyle: menuItemStyle,
|
|
selectedMenuItemStyle: selectedMenuItemStyle
|
|
},
|
|
children
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
return DropDownMenu;
|
|
}(_react.Component);
|
|
|
|
DropDownMenu.muiName = 'DropDownMenu';
|
|
DropDownMenu.defaultProps = {
|
|
animated: true,
|
|
autoWidth: true,
|
|
disabled: false,
|
|
openImmediately: false,
|
|
maxHeight: 500
|
|
};
|
|
DropDownMenu.contextTypes = {
|
|
muiTheme: _react.PropTypes.object.isRequired
|
|
};
|
|
process.env.NODE_ENV !== "production" ? DropDownMenu.propTypes = {
|
|
/**
|
|
* If true, the popover will apply transitions when
|
|
* it gets added to the DOM.
|
|
*/
|
|
animated: _react.PropTypes.bool,
|
|
/**
|
|
* Override the default animation component used.
|
|
*/
|
|
animation: _react.PropTypes.func,
|
|
/**
|
|
* The width will automatically be set according to the items inside the menu.
|
|
* To control this width in css instead, set this prop to `false`.
|
|
*/
|
|
autoWidth: _react.PropTypes.bool,
|
|
/**
|
|
* The `MenuItem`s to populate the `Menu` with. If the `MenuItems` have the
|
|
* prop `label` that value will be used to render the representation of that
|
|
* item within the field.
|
|
*/
|
|
children: _react.PropTypes.node,
|
|
/**
|
|
* The css class name of the root element.
|
|
*/
|
|
className: _react.PropTypes.string,
|
|
/**
|
|
* Disables the menu.
|
|
*/
|
|
disabled: _react.PropTypes.bool,
|
|
/**
|
|
* Overrides the styles of icon element.
|
|
*/
|
|
iconStyle: _react.PropTypes.object,
|
|
/**
|
|
* Overrides the styles of label when the `DropDownMenu` is inactive.
|
|
*/
|
|
labelStyle: _react.PropTypes.object,
|
|
/**
|
|
* The style object to use to override underlying list style.
|
|
*/
|
|
listStyle: _react.PropTypes.object,
|
|
/**
|
|
* The maximum height of the `Menu` when it is displayed.
|
|
*/
|
|
maxHeight: _react.PropTypes.number,
|
|
/**
|
|
* Override the inline-styles of menu items.
|
|
*/
|
|
menuItemStyle: _react.PropTypes.object,
|
|
/**
|
|
* Overrides the styles of `Menu` when the `DropDownMenu` is displayed.
|
|
*/
|
|
menuStyle: _react.PropTypes.object,
|
|
/**
|
|
* Callback function fired when a menu item is clicked, other than the one currently selected.
|
|
*
|
|
* @param {object} event TouchTap event targeting the menu item that was clicked.
|
|
* @param {number} key The index of the clicked menu item in the `children` collection.
|
|
* @param {any} payload The `value` prop of the clicked menu item.
|
|
*/
|
|
onChange: _react.PropTypes.func,
|
|
/**
|
|
* Callback function fired when the menu is closed.
|
|
*/
|
|
onClose: _react.PropTypes.func,
|
|
/**
|
|
* Set to true to have the `DropDownMenu` automatically open on mount.
|
|
*/
|
|
openImmediately: _react.PropTypes.bool,
|
|
/**
|
|
* Override the inline-styles of selected menu items.
|
|
*/
|
|
selectedMenuItemStyle: _react.PropTypes.object,
|
|
/**
|
|
* Override the inline-styles of the root element.
|
|
*/
|
|
style: _react.PropTypes.object,
|
|
/**
|
|
* Overrides the inline-styles of the underline.
|
|
*/
|
|
underlineStyle: _react.PropTypes.object,
|
|
/**
|
|
* The value that is currently selected.
|
|
*/
|
|
value: _react.PropTypes.any
|
|
} : void 0;
|
|
exports.default = DropDownMenu; |