UNPKG

10.1 kBJavaScriptView Raw
1import React, { Component } from 'react';
2import './styles/all.scss';
3import DropButtonMain from './DropButtonMain/DropButtonMain';
4import CommonMount from '@beisen-platform/common-mount';
5import DropdownDisabledIcon from '@beisen-platform/react-icons/lib/icons/DropdownminDisabled.js';
6import DropdownNormalIcon from './icon/DropdownNormalIcon';
7//ci
8
9export default class DropDownButton extends Component {
10 static defaultProps = {
11 deviationLeft: 0,
12 panelWidth: 170
13 };
14
15 constructor(props) {
16 super(props);
17 let defaultState = {
18 btnStyle: '',
19 btnSize: '',
20 iconName: '',
21 maxWidth: 'none',
22 listShow: false,
23 ulHide: false,
24 shadowHide: true,
25 btnDisabled: false,
26 btnDirection: {},
27 scrollHeight: 0,
28 notBtnIcon: props.iconName,
29 listViewDirection: 'right-down'
30 };
31
32 this.CommonMount = new CommonMount({
33 containerId: 'common-mount-list', // 容器ID
34 follow: true, // 是否滚动跟随,默认true
35 fixed: true // 定位:fixed,false时为absolute
36 });
37 this.state = Object.assign({}, defaultState, props);
38 this.onClose = this.onClose.bind(this);
39 this.btnMouseMove = this.btnMouseMove.bind(this);
40 this.btnMouseOut = this.btnMouseOut.bind(this);
41 this.itemClick = this.itemClick.bind(this);
42 this.scrollUl = this.scrollUl.bind(this);
43 this.onClick = this.onClick.bind(this);
44 this.renderDOM = this.renderDOM.bind(this);
45 }
46
47 componentWillReceiveProps(nextProps) {
48 this.state = Object.assign({}, this.state, nextProps);
49 this.setState(this.state);
50 }
51
52 scrollUl(height) {
53 this.setState({ scrollHeight: height });
54 }
55
56 onClick(e) {
57 let self = this;
58 if (this.state.btnActive) {
59 this.CommonMount.unmountBox();
60 this.setState({ btnActive: false });
61 return false;
62 }
63 if (this.props.onDropDownIconClick) {
64 this.props.onDropDownIconClick(e);
65 }
66 let allFun = function() {
67 self.renderDOM(e.target);
68 document.removeEventListener('mousedown', self.onClose);
69 document.addEventListener('mousedown', self.onClose);
70 self.setState({ btnActive: true });
71 };
72 let retFun = function(children) {
73 if (children) {
74 self.state.children = children;
75 }
76 allFun();
77 };
78 if (!this.props.itemClick) {
79 allFun();
80 }
81 if (!self.state.children || self.state.children.length == 0) {
82 this.props.itemClick && this.props.itemClick(retFun);
83 } else {
84 allFun();
85 }
86 }
87
88 renderDOM(tar) {
89 const { autoDirection, direction, children, sideTip, hiddenTip } = this.state;
90 const { panelWidth, deviationLeft, rightAlign, disabledShowTips } = this.props;
91 let self = this;
92 let target = this.refs.dropDownView.getBoundingClientRect();
93 let length = this.state.children.length >= 10 ? 260 : this.state.children.length * 26;
94 let winHeight = window.innerHeight;
95 let winWidth = window.innerWidth;
96 let horizontal = winWidth - target.left > panelWidth ? 'right' : 'left';
97 var vertical =
98 winHeight - target.bottom > length
99 ? '-down'
100 : winHeight - target.top > length ? '-top' : winHeight - target.bottom > target.top ? '-down' : '-top';
101 if (this.state.disabled) {
102 return false;
103 }
104 let tempList = this.state.listShow == false ? true : false;
105 const showAutoUl = (
106 <DropButtonMain
107 data={children}
108 disabledShowTips={disabledShowTips}
109 sideTip={sideTip}
110 hiddenTip={hiddenTip}
111 panelWidth={panelWidth}
112 itemClick={this.itemClick}
113 ulHide={!tempList}
114 scrollUl={this.scrollUl}
115 direction={autoDirection || autoDirection == undefined ? horizontal + vertical : direction}
116 listShow={tempList}
117 dataUdcList={this.props.dataUdcList}
118 dataUdtList={this.props.dataUdtList}
119 />
120 );
121 this.CommonMount.renderDom(
122 'drop-down-list-not-active', // wrap's classname & id
123 showAutoUl, // content dom
124 self.refs.dropDownView, // 跟随目标
125 [
126 self.refs.dropDownView, //挂载目标节点
127 {
128 // 挂载元素宽高 {width: '', height: ''}
129 width: panelWidth, // 挂载宽度
130 height: length
131 },
132 40
133 ],
134 true,
135 deviationLeft,
136 rightAlign
137 );
138
139 let parent = document.getElementById('drop-down-list-ul');
140 setTimeout(function() {
141 parent.className = parent.className + ' drop-down-list-active';
142 }, 10);
143 }
144
145 onClose(event) {
146 let area = document.getElementById('common-mount-list');
147 if (area && !area.contains(event.target) && !this.refs.dropBtnComponent.contains(event.target)) {
148 this.CommonMount.unmountBox();
149 this.setState({ btnActive: false });
150 document.removeEventListener('mousedown', this.onClose);
151 }
152 }
153
154 itemClick(e, val) {
155 let self = this;
156 let stateData = this.state;
157 stateData.children.map((item) => {
158 if (item.value == val.value) item.active = true;
159 });
160
161 //背景效果展现,隐藏ul列表
162 this.setState({
163 shadowHide: false,
164 children: stateData.children,
165 ulHide: true,
166 iconName: this.props.iconName || ''
167 });
168
169 setTimeout(function() {
170 //延迟消失ul列表
171 let stateData = self.state;
172 stateData.children.map((item) => {
173 if (item.active) item.active = false;
174 });
175 self.CommonMount.unmountBox();
176 self.setState({ btnActive: false });
177 }, 300);
178 // 关闭之前先将弹层的zIndex调低,处理common-pop zIndex是999的情况导致的遮不住dropdown
179 if (this.CommonMount.containerStyleUpdater) {
180 this.CommonMount.containerStyleUpdater('zIndex', '998');
181 }
182 this.props.onClick && this.props.onClick(val, e, true, this.state, this.refs.dropdownbtn);
183 this.state.listShow = false;
184 document.removeEventListener('mousedown', this.onClose);
185 }
186
187 btnMouseMove() {
188 const { activeName, hoverName, isBtnStyle } = this.props;
189 if (this.state.disabled) {
190 return false;
191 }
192 if (isBtnStyle) {
193 let iconName = this.state.iconName.replace('nomal', 'active');
194 this.setState({
195 iconName: iconName
196 });
197 } else {
198 if (this.refs.dropDownIcon)
199 this.refs.dropDownIcon.className = this.refs.dropDownIcon.className.replace(
200 'nomal',
201 hoverName ? 'hover' : 'active'
202 );
203 this.setState({ notBtnIcon: hoverName ? hoverName : activeName, hovering: true });
204 }
205 }
206
207 btnMouseOut() {
208 const { iconName, hoverName, isBtnStyle } = this.props;
209 if (this.state.disabled) {
210 return false;
211 }
212 if (isBtnStyle) {
213 let iconName = this.state.iconName.replace('active', 'nomal');
214 !this.state.listShow &&
215 this.setState({
216 iconName: iconName
217 });
218 } else {
219 if (this.refs.dropDownIcon)
220 this.refs.dropDownIcon.className = this.refs.dropDownIcon.className.replace(
221 hoverName ? 'hover' : 'active',
222 'nomal'
223 );
224 this.setState({ notBtnIcon: iconName, hovering: false }, this.forceUpdate());
225 }
226 }
227
228 componentWillMount() {
229 let initData = {
230 bsSize: {
231 small: 'drop-btns-bgc-small ',
232 default: 'drop-btns-bgc-big '
233 },
234 bsStyle: {
235 weaken: 'drop-btns-weaken ',
236 default: ' ',
237 link: ' '
238 },
239 btnDisabled: {
240 weaken: 'drop-btns-bg-gray-weaken ',
241 default: 'drop-btns-bg-gray-defalult '
242 },
243 btnDirection: {
244 small: 'drop-down-btn-small',
245 default: 'drop-down-btn-big'
246 },
247 btnIcon: {
248 weaken: this.props.iconName ? this.props.iconName : 'pc-sys-arrowdown-nomal-svg',
249 default: 'pc-sys-arrowdownM7-nomal-svg'
250 }
251 };
252 const { bsStyle, bsSize, open, disabled, maxWidth, iconName } = this.props;
253 //初始化数据,为按钮添加样式
254 let btnActive = false;
255 let btnStyle = initData.bsStyle[bsStyle],
256 btnSize = initData.bsSize[bsSize],
257 listShow = open ? true : false,
258 btnDirection = initData.btnDirection[bsSize],
259 btnDisabled = disabled ? initData.btnDisabled[bsStyle] : (this.state.btnDisabled = ' '),
260 iconBtnName = disabled ? iconName.replace('nomal', 'disabled') : initData.btnIcon[bsStyle],
261 maxBtnWidth = maxWidth && maxWidth.length > 0 ? maxWidth : 'none';
262 this.setState({
263 maxWidth: maxBtnWidth,
264 btnActive: btnActive,
265 btnStyle: btnStyle,
266 btnSize: btnSize,
267 listShow: listShow,
268 btnDirection: btnDirection,
269 btnDisabled: btnDisabled,
270 iconName: iconBtnName
271 });
272 }
273
274 componentWillUnmount() {
275 this.CommonMount.unmountBox();
276 document.removeEventListener('mousedown', this.onClose);
277 }
278
279 render() {
280 const {
281 type,
282 btnSize,
283 btnStyle,
284 btnDisabled,
285 iconName,
286 hovering,
287 btnDirection,
288 maxWidth,
289 listShow,
290 notBtnIcon,
291 btnActive
292 } = this.state;
293 const { title, hidden, isBtnStyle, hoverName, activeName } = this.props;
294 let IconComponent = this.props.iconComponent;
295 let dropLabel, labelType, iconLabel, maxBtnWidth;
296 if (type == 'text') {
297 maxBtnWidth = maxWidth;
298 labelType = btnActive ? ' drop-down-btn-label drop-down-btn-actived ' : ' drop-down-btn-label ';
299 if (title.length > 0) {
300 dropLabel = (
301 <div>
302 <span className="drop-down-btn-title">{title}</span>
303 <span className="drop-down-btn-svg">
304 {/* { this.props.bsStyle=="default" ? <DropdownDisabledIcon width={6} height={5}/>: <DropdownNormalIcon width={6} height={5} /> } */}
305 <DropdownNormalIcon width={10} height={4} />
306 </span>
307 </div>
308 );
309 } else {
310 dropLabel = '';
311 }
312 } else {
313 labelType = ' drop-down-btn-icon ';
314 let hoverClass = hoverName && btnActive ? activeName : hovering ? this.props.iconName : notBtnIcon;
315 iconLabel = (
316 <span
317 ref="dropDownIcon"
318 className={'drop-down-icon ' + (isBtnStyle || isBtnStyle == undefined ? iconName : hoverClass)}
319 />
320 );
321 }
322
323 if (hidden) {
324 return <div />;
325 } else {
326 return (
327 <div ref="dropBtnComponent" className="feild drop-down-button">
328 <div
329 ref="dropDownView"
330 className={
331 'drop-down-btn-list ' +
332 (isBtnStyle || isBtnStyle == undefined ? '' : 'is-not-btn-style') +
333 (listShow ? 'drop-down-list-active ' : ' ') +
334 btnDirection
335 }
336 >
337 <div
338 ref="dropdownbtn"
339 style={{ maxWidth: maxBtnWidth }}
340 className={btnSize + btnStyle + btnDisabled + labelType}
341 onClick={this.onClick}
342 onMouseOver={this.btnMouseMove}
343 onMouseOut={this.btnMouseOut}
344 >
345 {dropLabel}
346 {IconComponent ? <IconComponent /> : iconLabel}
347 </div>
348 </div>
349 </div>
350 );
351 }
352 }
353}
354
\No newline at end of file