UNPKG

11.2 kBJavaScriptView Raw
1import _extends from 'babel-runtime/helpers/extends';
2import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
3import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
4import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
5import _inherits from 'babel-runtime/helpers/inherits';
6
7var _class, _temp;
8
9import React from 'react';
10import { findDOMNode } from 'react-dom';
11import PropTypes from 'prop-types';
12import { polyfill } from 'react-lifecycles-compat';
13import classnames from 'classnames';
14import Icon from '../icon';
15import Button from '../button';
16import Overlay from '../overlay';
17import Menu from '../menu';
18import ConfigProvider from '../config-provider';
19import { dom, obj, func } from '../util';
20
21var Popup = Overlay.Popup;
22
23/**
24 * SplitButton
25 */
26
27var SplitButton = (_temp = _class = function (_React$Component) {
28 _inherits(SplitButton, _React$Component);
29
30 function SplitButton(props, context) {
31 _classCallCheck(this, SplitButton);
32
33 var _this = _possibleConstructorReturn(this, _React$Component.call(this, props, context));
34
35 _this.selectMenuItem = function (keys) {
36 var _this$props;
37
38 for (var _len = arguments.length, others = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
39 others[_key - 1] = arguments[_key];
40 }
41
42 if (!('selectedKeys' in _this.props)) {
43 _this.setState({
44 selectedKeys: keys
45 });
46 }
47 (_this$props = _this.props).onSelect.apply(_this$props, [keys].concat(others));
48 };
49
50 _this.clickMenuItem = function (key) {
51 var _this$props2;
52
53 for (var _len2 = arguments.length, others = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
54 others[_key2 - 1] = arguments[_key2];
55 }
56
57 (_this$props2 = _this.props).onItemClick.apply(_this$props2, [key].concat(others));
58 _this.onVisibleChange(false, 'menuSelect');
59 };
60
61 _this.onPopupOpen = function () {
62 if (_this.props.autoWidth && _this.wrapper && _this.menu) {
63 dom.setStyle(_this.menu, {
64 width: _this.wrapper.offsetWidth
65 });
66 }
67 };
68
69 _this.onVisibleChange = function (visible, reason) {
70 if (!('visible' in _this.props)) {
71 _this.setState({
72 visible: visible
73 });
74 }
75 _this.props.onVisibleChange(visible, reason);
76 };
77
78 _this._menuRefHandler = function (ref) {
79 _this.menu = findDOMNode(ref);
80
81 var refFn = _this.props.menuProps.ref;
82 if (typeof refFn === 'function') {
83 refFn(ref);
84 }
85 };
86
87 _this._wrapperRefHandler = function (ref) {
88 _this.wrapper = findDOMNode(ref);
89 };
90
91 _this.state = {
92 selectedKeys: props.defaultSelectedKeys,
93 visible: props.defaultVisible
94 };
95 return _this;
96 }
97
98 SplitButton.getDerivedStateFromProps = function getDerivedStateFromProps(props) {
99 var st = {};
100
101 if ('visible' in props) {
102 st.visible = props.visible;
103 }
104
105 if ('selectedKeys' in props) {
106 st.selectedKeys = props.selectedKeys;
107 }
108
109 return st;
110 };
111
112 SplitButton.prototype.componentDidMount = function componentDidMount() {
113 // 由于定位目标是 wrapper,如果弹层默认展开,wrapper 还未渲染,didMount 后强制再渲染一次,弹层重新定位
114 if (this.state.visible) {
115 this.forceUpdate();
116 }
117 };
118
119 SplitButton.prototype.render = function render() {
120 var _classnames,
121 _classnames2,
122 _classnames3,
123 _this2 = this;
124
125 var _props = this.props,
126 prefix = _props.prefix,
127 label = _props.label,
128 size = _props.size,
129 type = _props.type,
130 component = _props.component,
131 ghost = _props.ghost,
132 className = _props.className,
133 style = _props.style,
134 children = _props.children,
135 triggerProps = _props.triggerProps,
136 popupAlign = _props.popupAlign,
137 popupTriggerType = _props.popupTriggerType,
138 popupStyle = _props.popupStyle,
139 popupClassName = _props.popupClassName,
140 popupProps = _props.popupProps,
141 popupContainer = _props.popupContainer,
142 followTrigger = _props.followTrigger,
143 selectMode = _props.selectMode,
144 menuProps = _props.menuProps,
145 leftButtonProps = _props.leftButtonProps,
146 disabled = _props.disabled,
147 others = _objectWithoutProperties(_props, ['prefix', 'label', 'size', 'type', 'component', 'ghost', 'className', 'style', 'children', 'triggerProps', 'popupAlign', 'popupTriggerType', 'popupStyle', 'popupClassName', 'popupProps', 'popupContainer', 'followTrigger', 'selectMode', 'menuProps', 'leftButtonProps', 'disabled']);
148
149 var state = this.state;
150
151 var classNames = classnames((_classnames = {}, _classnames[prefix + 'split-btn'] = true, _classnames), className);
152
153 var sharedBtnProps = {
154 type: type,
155 size: size,
156 component: component,
157 ghost: ghost,
158 disabled: disabled
159 };
160
161 var triggerClassNames = classnames((_classnames2 = {}, _classnames2[prefix + 'split-btn-trigger'] = true, _classnames2[prefix + 'expand'] = state.visible, _classnames2.opened = state.visible, _classnames2));
162
163 var iconCls = classnames((_classnames3 = {}, _classnames3[prefix + 'split-btn-symbol-fold'] = true, _classnames3));
164
165 var trigger = React.createElement(
166 Button,
167 _extends({}, sharedBtnProps, triggerProps, { className: triggerClassNames }),
168 React.createElement(Icon, { type: 'arrow-down', className: iconCls })
169 );
170
171 return React.createElement(
172 Button.Group,
173 _extends({}, obj.pickOthers(SplitButton.propTypes, others), {
174 className: classNames,
175 style: style,
176 size: size,
177 ref: this._wrapperRefHandler
178 }),
179 React.createElement(
180 Button,
181 _extends({}, sharedBtnProps, leftButtonProps),
182 label
183 ),
184 React.createElement(
185 Popup,
186 _extends({}, popupProps, {
187 followTrigger: followTrigger,
188 visible: state.visible,
189 onVisibleChange: this.onVisibleChange,
190 trigger: trigger,
191 triggerType: popupTriggerType,
192 align: popupAlign,
193 container: popupContainer,
194 target: function target() {
195 return _this2.wrapper;
196 },
197 style: popupStyle,
198 shouldUpdatePosition: true,
199 className: popupClassName,
200 onOpen: this.onPopupOpen
201 }),
202 React.createElement(
203 'div',
204 { className: prefix + 'split-btn-spacing-tb' },
205 React.createElement(
206 Menu,
207 _extends({}, menuProps, {
208 selectMode: selectMode,
209 selectedKeys: state.selectedKeys,
210 onSelect: this.selectMenuItem,
211 onItemClick: this.clickMenuItem,
212 ref: this._menuRefHandler
213 }),
214 children
215 )
216 )
217 )
218 );
219 };
220
221 return SplitButton;
222}(React.Component), _class.propTypes = {
223 prefix: PropTypes.string,
224 style: PropTypes.object,
225 /**
226 * 按钮的类型
227 */
228 type: PropTypes.oneOf(['normal', 'primary', 'secondary']),
229 /**
230 * 按钮组的尺寸
231 */
232 size: PropTypes.oneOf(['small', 'medium', 'large']),
233 /**
234 * 主按钮的文案
235 */
236 label: PropTypes.node,
237 /**
238 * 设置标签类型
239 */
240 component: PropTypes.oneOf(['button', 'a']),
241 /**
242 * 是否为幽灵按钮
243 */
244 ghost: PropTypes.oneOf(['light', 'dark', false, true]),
245 /**
246 * 默认激活的菜单项(用法同 Menu 非受控)
247 */
248 defaultSelectedKeys: PropTypes.array,
249 /**
250 * 激活的菜单项(用法同 Menu 受控)
251 */
252 selectedKeys: PropTypes.array,
253 /**
254 * 菜单的选择模式
255 */
256 selectMode: PropTypes.oneOf(['single', 'multiple']),
257 /**
258 * 选择菜单项时的回调,参考 Menu
259 */
260 onSelect: PropTypes.func,
261 /**
262 * 点击菜单项时的回调,参考 Menu
263 */
264 onItemClick: PropTypes.func,
265 /**
266 * 触发按钮的属性(支持 Button 的所有属性透传)
267 */
268 triggerProps: PropTypes.object,
269 /**
270 * 弹层菜单的宽度是否与按钮组一致
271 */
272 autoWidth: PropTypes.bool,
273 /**
274 * 弹层是否显示
275 */
276 visible: PropTypes.bool,
277 /**
278 * 弹层默认是否显示
279 */
280 defaultVisible: PropTypes.bool,
281 /**
282 * 弹层显示状态变化时的回调函数
283 * @param {Boolean} visible 弹层显示状态
284 * @param {String} type 触发弹层显示或隐藏的来源 menuSelect 表示由menu触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发
285 */
286 onVisibleChange: PropTypes.func,
287 /**
288 * 弹层的触发方式
289 */
290 popupTriggerType: PropTypes.oneOf(['click', 'hover']),
291 /**
292 * 弹层对齐方式, 详情见Overlay align
293 */
294 popupAlign: PropTypes.string,
295 /**
296 * 弹层自定义样式
297 */
298 popupStyle: PropTypes.object,
299 /**
300 * 弹层自定义样式类
301 */
302 popupClassName: PropTypes.string,
303 /**
304 * 透传给弹层的属性
305 */
306 popupProps: PropTypes.object,
307 /**
308 * 弹层容器
309 */
310 popupContainer: PropTypes.any,
311 /**
312 * 是否跟随滚动
313 */
314 followTrigger: PropTypes.bool,
315 /**
316 * 透传给 Menu 的属性
317 */
318 menuProps: PropTypes.object,
319 /**
320 * 透传给 左侧按钮 的属性
321 */
322 leftButtonProps: PropTypes.object,
323 className: PropTypes.string,
324 children: PropTypes.any
325}, _class.defaultProps = {
326 prefix: 'next-',
327 type: 'normal',
328 size: 'medium',
329 autoWidth: true,
330 popupTriggerType: 'click',
331 onVisibleChange: func.noop,
332 onItemClick: func.noop,
333 onSelect: func.noop,
334 defaultSelectedKeys: [],
335 menuProps: {},
336 leftButtonProps: {}
337}, _temp);
338SplitButton.displayName = 'SplitButton';
339
340
341SplitButton.Item = Menu.Item;
342SplitButton.Divider = Menu.Divider;
343SplitButton.Group = Menu.Group;
344
345export default ConfigProvider.config(polyfill(SplitButton));
\No newline at end of file