react-ui-component
Version:
some component build with ReactJs
846 lines (736 loc) • 28.4 kB
JavaScript
'use strict';
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var React = require('react');
var Component = React.Component;
var PropTypes = require('prop-types');
var ReactDOM = require('react-dom');
var defaultCheckedCmp = require('./high-order/defaultCheckedCmp');
var documentClickCmp = require('./high-order/documentClickCmp');
var dropDownCmp = require('./high-order/dropDownCmp');
var BACKSPACE_KEYCODE = require('./util/constants').BACKSPACE_KEYCODE;
var klassName = require('./util/className');
var debounce = require('./util/debounce');
var DropDown = function (_Component) {
_inherits(DropDown, _Component);
function DropDown(props) {
_classCallCheck(this, DropDown);
var _this = _possibleConstructorReturn(this, (DropDown.__proto__ || Object.getPrototypeOf(DropDown)).call(this, props));
_this.toggleOpen = _this.toggleOpen.bind(_this);
_this.multiBarValChangeByIndex = _this.multiBarValChangeByIndex.bind(_this);
_this.handleChangeSelect = _this.handleChangeSelect.bind(_this);
_this.handleSearch = _this.handleSearch.bind(_this);
var multi = props.multi,
value = props.value;
var default_val = multi ? [] : '';
value = [undefined, null, ''].indexOf(value) === -1 ? value : default_val;
_this.state = {
value: value,
open: false,
filterText: ''
};
return _this;
}
_createClass(DropDown, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var _props2 = this.props,
defaultSelected = _props2.defaultSelected,
multi = _props2.multi;
this.optionsChangeReInitValue({
defaultChecked: defaultSelected,
nextProps: nextProps,
multi: multi
});
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var value = this.state.value;
var _props3 = this.props,
defaultSelected = _props3.defaultSelected,
multi = _props3.multi;
if (defaultSelected) {
if (!multi && !value) {
return this.initDefaultCheckedValue({ multi: multi });
}
if (multi && value.length === 0) {
this.initDefaultCheckedValue({ multi: multi });
}
}
}
// format value judge if is multi
}, {
key: 'formatValue',
value: function formatValue(val, callback) {
var newVal = val,
oldVal = this.state.value;
if (this.props.multi) {
var index = oldVal.indexOf(val);
if (index > -1) {
oldVal.splice(index, 1);
this.setState({ value: oldVal }, callback);
return;
}
newVal = oldVal.concat(val);
}
this.setState({ value: newVal }, callback);
}
// yield child type dropdown
}, {
key: 'formatYieldChildren',
value: function formatYieldChildren(children) {
var _this2 = this;
var _props4 = this.props,
labelName = _props4.labelName,
valueName = _props4.valueName,
placeHolder = _props4.placeHolder,
multi = _props4.multi,
style = _props4.style,
className = _props4.className;
var _state = this.state,
filterText = _state.filterText,
value = _state.value,
open = _state.open;
var nodes = [],
tags = [];
React.Children.map(children, function (item, index) {
var props = item.props;
var item_val = props[valueName];
var item_label = props[labelName];
var selected = false;
if (multi) {
var _index = value.indexOf(item_val);
selected = _index !== -1;
if (selected) tags[_index] = item_label;
} else {
selected = value === item_val;
if (selected) {
placeHolder = item_label;
}
}
if (_this2.filterTextMatched(filterText, item_label, item_val)) {
nodes.push(React.createElement(
DropDownOption,
{ key: index,
value: item_val,
label: item_label,
disabled: props.disabled,
onClick: function onClick() {
return _this2.handleChangeSelect(item_val);
},
selected: selected },
props.children
));
}
});
var labelNode = this.formatLabel(multi ? tags : placeHolder);
className = klassName('dropdown', className);
if (open) {
className = className + ' _active';
}
return React.createElement(
'div',
{ className: className, style: style },
labelNode,
React.createElement(
'span',
{ className: '_list' },
open ? nodes : null,
this.formatLoading()
)
);
}
// add loading to list
}, {
key: 'formatLoading',
value: function formatLoading() {
var loading = this.props.loading;
var open = this.state.open;
if (!open) {
return null;
}
return loading ? React.createElement(
'div',
{ className: '_overlay' },
React.createElement('div', { className: 'loader' })
) : null;
}
// dropdown label
}, {
key: 'formatLabel',
value: function formatLabel(labels) {
var _props5 = this.props,
multi = _props5.multi,
searchable = _props5.searchable;
var labelNode = null;
if (multi) {
labelNode = this.formatMultiInput(labels);
} else {
labelNode = searchable ? this.formatSearchBar(labels) : this.formatDefaultLabel(labels);
}
return labelNode;
}
// generate nodes and label by options prop
}, {
key: 'getNodesAndLabel',
value: function getNodesAndLabel() {
var _this3 = this;
var _props6 = this.props,
labelName = _props6.labelName,
valueName = _props6.valueName,
searchable = _props6.searchable,
multi = _props6.multi,
placeHolder = _props6.placeHolder,
options = _props6.options;
var _state2 = this.state,
filterText = _state2.filterText,
value = _state2.value;
var displayLabels = [],
node = null,
optionNodes = [];
if (!multi) displayLabels = placeHolder;
var _loop = function _loop(i) {
var pair = options[i];
var pair_val = pair[valueName];
var pair_label = pair[labelName];
var selected = false;
if (multi) {
for (var j = 0; j < value.length; j++) {
selected = value[j] === pair_val;
if (selected) {
if (displayLabels.indexOf(pair_label) === -1) displayLabels[value.indexOf(pair_val)] = pair_label;
break;
}
}
} else {
selected = value === pair_val;
if (selected) displayLabels = pair_label;
}
node = React.createElement(
DropDownOption,
{ key: i,
label: pair_label,
value: pair_val,
selected: selected,
onClick: function onClick() {
return _this3.handleChangeSelect(pair_val);
},
disabled: pair.disabled },
pair.children
);
if (multi || searchable) {
if (_this3.filterTextMatched(filterText, pair_val, pair_label)) optionNodes.push(node);
} else {
optionNodes.push(node);
}
};
for (var i = 0; i < options.length; i++) {
_loop(i);
}
return { optionNodes: optionNodes, displayLabels: displayLabels };
}
// options type dropdown
}, {
key: 'formatOptions',
value: function formatOptions() {
var _props7 = this.props,
className = _props7.className,
style = _props7.style;
var open = this.state.open;
className = klassName('dropdown', className);
if (open) {
className += ' _active';
}
var _getNodesAndLabel = this.getNodesAndLabel(),
optionNodes = _getNodesAndLabel.optionNodes,
displayLabels = _getNodesAndLabel.displayLabels;
return React.createElement(
'div',
{ className: className, style: style },
this.formatLabel(displayLabels),
React.createElement(
'span',
{ className: '_list' },
open ? optionNodes : null,
this.formatLoading()
)
);
}
// filter if text in fields, return true
}, {
key: 'filterTextMatched',
value: function filterTextMatched(text) {
var status = false;
for (var _len = arguments.length, fields = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
fields[_key - 1] = arguments[_key];
}
for (var i = 0; i < fields.length; i++) {
if (String(fields[i]).indexOf(text) !== -1) {
status = true;
break;
}
}
return status;
}
// default label for dropdown
}, {
key: 'formatDefaultLabel',
value: function formatDefaultLabel(text) {
var _this4 = this;
var _props8 = this.props,
disabled = _props8.disabled,
onFocus = _props8.onFocus,
onBlur = _props8.onBlur,
_onClick = _props8.onClick;
var _state3 = this.state,
value = _state3.value,
open = _state3.open;
return disabled ? React.createElement(
DropDownLabel,
{ disabled: true },
text
) : React.createElement(
DropDownLabel,
{
onFocus: onFocus,
onBlur: onBlur,
isPlaceHolder: value === '',
onClick: function onClick() {
_this4.toggleOpen(!open);
if (_onClick) _onClick();
} },
text
);
}
// searchable search bar
}, {
key: 'formatSearchBar',
value: function formatSearchBar(labels) {
var _this5 = this;
var _state4 = this.state,
filterText = _state4.filterText,
value = _state4.value;
var _props9 = this.props,
disabled = _props9.disabled,
_onClick2 = _props9.onClick,
onBlur = _props9.onBlur,
onFocus = _props9.onFocus;
return disabled ? React.createElement(DropDownSearchBar, {
placeHolder: labels,
text: filterText,
isPlaceHolder: value === '',
disabled: disabled,
onUserInput: function onUserInput() {
return void 0;
}
}) : React.createElement(DropDownSearchBar, {
placeHolder: labels,
text: filterText,
isPlaceHolder: value === '',
disabled: disabled,
onClick: function onClick() {
_this5.toggleOpen(true);
if (_onClick2) _onClick2();
},
onBlur: onBlur,
onFocus: onFocus,
onUserInput: this.handleSearch
});
}
// multi dropdown's input
}, {
key: 'formatMultiInput',
value: function formatMultiInput(tags) {
var _this6 = this;
var _props10 = this.props,
_onClick3 = _props10.onClick,
onBlur = _props10.onBlur,
onFocus = _props10.onFocus,
disabled = _props10.disabled;
return disabled ? React.createElement(MultiInput, {
disabled: disabled,
filterText: this.state.filterText,
onClick: function onClick() {
return void 0;
},
selectedTags: tags
}) : React.createElement(MultiInput, {
disabled: disabled,
filterText: this.state.filterText,
onSelectChange: this.multiBarValChangeByIndex,
onUserInputFocus: function onUserInputFocus() {
_this6.toggleOpen(true);
if (onFocus) onFocus();
},
onBlur: onBlur,
onFocus: onFocus,
onUserInput: this.handleSearch,
onClick: function onClick() {
_this6.toggleOpen(true);
if (_onClick3) _onClick3();
},
selectedTags: tags
});
}
// other context click to close dropdown
}, {
key: 'onOtherDomClick',
value: function onOtherDomClick() {
this.toggleOpen(false);
}
// multi dropdown, select value change
}, {
key: 'multiBarValChangeByIndex',
value: function multiBarValChangeByIndex(index) {
var value = this.state.value;
// remove specific value
if (index !== undefined) {
if (index > -1) value.splice(index, 1);
} else {
value.pop();
}
this.setState({
value: value
}, this.triggerDropValueChange());
}
// each option cell clicked handler
}, {
key: 'handleChangeSelect',
value: function handleChangeSelect(val) {
var _this7 = this;
this.formatValue(val, function () {
_this7.triggerDropValueChange();
_this7.toggleOpen(_this7.props.multi);
});
}
// value change, trigger onChange event
}, {
key: 'triggerDropValueChange',
value: function triggerDropValueChange() {
var _props11 = this.props,
multi = _props11.multi,
onChange = _props11.onChange;
var value = this.state.value;
if (multi) value = Object.assign([], value);
onChange(value);
}
// dropdown open or close, clean filter text
}, {
key: 'toggleOpen',
value: function toggleOpen(stat) {
var params = {
open: stat
};
if (this.state.value || this.props.autoClearText) {
params.filterText = '';
}
this.setState(params);
}
}, {
key: 'clearText',
value: function clearText() {
this.setState({
filterText: ''
});
}
// search
}, {
key: 'handleSearch',
value: function handleSearch(text) {
this.setState({
filterText: text
});
var onSearch = this.props.onSearch;
if (onSearch) {
debounce(onSearch)(text);
}
}
}, {
key: 'render',
value: function render() {
var children = this.props.children;
var node = children ? this.formatYieldChildren(children) : this.formatOptions();
return node;
}
}]);
return DropDown;
}(Component);
DropDown.propTypes = {
placeHolder: PropTypes.string,
options: PropTypes.array,
autoClearText: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onClick: PropTypes.func,
onSearch: PropTypes.func,
onBlur: PropTypes.func,
onFocus: PropTypes.func,
labelName: PropTypes.string,
valueName: PropTypes.string,
defaultSelected: PropTypes.bool,
searchable: PropTypes.bool,
multi: PropTypes.bool,
disabled: PropTypes.bool,
children: PropTypes.arrayOf(PropTypes.element)
};
DropDown.defaultProps = {
labelName: 'name',
valueName: 'value',
autoClearText: false,
multi: false,
disabled: false,
className: '',
placeHolder: 'click to select...'
};
var DropDownOption = function DropDownOption(props) {
var newProps = Object.assign({}, props);
var selected = newProps.selected,
disabled = newProps.disabled,
children = newProps.children;
var className = '_item';
if (disabled) {
className += ' _disabled';
delete newProps.onClick;
}
if (selected) {
className += ' _active';
}
return React.createElement(
'div',
_extends({ className: className }, newProps),
children ? children : newProps.label
);
};
// dropdown label
var DropDownLabel = function DropDownLabel(props) {
var _props = Object.assign({}, props);
var isPlaceHolder = _props.isPlaceHolder,
disabled = _props.disabled;
var className = klassName('_label', isPlaceHolder ? '_placeHolder' : '', disabled ? '_disabled' : '');
delete _props.onClick;
delete _props.disabled;
delete _props.onBlur;
delete _props.onFocus;
delete _props.isPlaceHolder;
return React.createElement(
'div',
_extends({}, _props, {
className: className,
onClick: props.onClick }),
React.createElement('input', { type: 'text',
className: '_transparent',
readOnly: true,
disabled: disabled,
onBlur: props.onBlur,
onFocus: props.onFocus }),
React.createElement('i', null),
React.createElement(
'div',
{ className: '_text' },
_props.children
)
);
};
var DropDownSearchBar = function DropDownSearchBar(props) {
var onClick = props.onClick,
onBlur = props.onBlur,
onFocus = props.onFocus,
text = props.text,
isPlaceHolder = props.isPlaceHolder,
placeHolder = props.placeHolder,
disabled = props.disabled;
var className = klassName('_text', isPlaceHolder ? '_placeHolder' : '');
return React.createElement(
'div',
{
className: klassName('_search', disabled ? '_disabled' : ''),
onClick: onClick },
text ? React.createElement('div', { className: '_text' }) : React.createElement(
'div',
{ className: className },
placeHolder
),
React.createElement('input', { type: 'text',
className: '_input',
value: text,
disabled: disabled,
onBlur: onBlur,
onFocus: onFocus,
onChange: function onChange(e) {
return props.onUserInput(e.target.value);
}
}),
React.createElement('i', null)
);
};
DropDownSearchBar.propTypes = {
onClick: PropTypes.func,
onBlur: PropTypes.func,
onFocus: PropTypes.func,
text: PropTypes.string,
placeHolder: PropTypes.string,
isPlaceHolder: PropTypes.bool,
onUserInput: PropTypes.func.isRequired
};
DropDownSearchBar.defaultProps = {
text: '',
placeHolder: '',
isPlaceHolder: false
// multi dropdown input field
};
var MultiInput = function (_Component2) {
_inherits(MultiInput, _Component2);
function MultiInput(props) {
_classCallCheck(this, MultiInput);
var _this8 = _possibleConstructorReturn(this, (MultiInput.__proto__ || Object.getPrototypeOf(MultiInput)).call(this, props));
_this8.handleClick = _this8.handleClick.bind(_this8);
_this8.handleKeyDown = _this8.handleKeyDown.bind(_this8);
_this8.handleBlur = _this8.handleBlur.bind(_this8);
_this8.removeSelected = _this8.removeSelected.bind(_this8);
_this8.state = {
hasInput: false
};
return _this8;
}
_createClass(MultiInput, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (nextProps.selectedTags.length !== this.props.selectedTags.length) {
this.inputFieldFocus();
}
}
}, {
key: 'handleClick',
value: function handleClick() {
this.inputFieldFocus();
this.props.onClick(true);
}
}, {
key: 'handleKeyDown',
value: function handleKeyDown(e) {
var keyCode = e.keyCode;
var value = this.inputField().value;
this.setState({
hasInput: true
});
if (keyCode === BACKSPACE_KEYCODE && value === '') this.props.onSelectChange();
e.target.style.width = (value.length + 1) * 12 + 'px';
}
}, {
key: 'handleBlur',
value: function handleBlur() {
var onBlur = this.props.onBlur;
this.setState({
hasInput: false
});
this.inputField().style.width = '9px';
if (onBlur) onBlur();
}
}, {
key: 'removeSelected',
value: function removeSelected(index) {
this.props.onSelectChange(index);
this.inputFieldFocus();
}
}, {
key: 'inputField',
value: function inputField() {
return ReactDOM.findDOMNode(this.userInput);
}
}, {
key: 'inputFieldFocus',
value: function inputFieldFocus() {
this.inputField().focus();
}
}, {
key: 'render',
value: function render() {
var _this9 = this;
var _props12 = this.props,
selectedTags = _props12.selectedTags,
filterText = _props12.filterText,
disabled = _props12.disabled;
var hasInput = this.state.hasInput;
var tagNodes = selectedTags.map(function (tag, index) {
return disabled ? React.createElement(
'span',
{
className: '_tag _disabled',
key: index },
React.createElement(
'span',
{ className: '_text' },
tag
),
React.createElement('a', { href: 'javascript:;',
className: '_delete' })
) : React.createElement(
'span',
{
className: '_tag',
key: index,
onClick: function onClick() {
return _this9.removeSelected(index);
} },
React.createElement(
'span',
{ className: '_text' },
tag
),
React.createElement('a', { href: 'javascript:;',
className: '_delete' })
);
});
var placeHolder = selectedTags.length === 0 && !hasInput ? React.createElement(
'span',
{ className: '_placeHolder' },
'search...'
) : React.createElement('span', { className: '_placeHolder' });
return React.createElement(
'div',
{
className: klassName('_multi', disabled ? '_disabled' : ''),
onClick: this.handleClick },
tagNodes,
disabled ? React.createElement('input', {
type: 'text',
className: '_input',
ref: function ref(_ref) {
_this9.userInput = _ref;
},
style: { 'width': '9px' },
value: filterText,
disabled: true
}) : React.createElement('input', { type: 'text',
className: '_input',
ref: function ref(_ref2) {
_this9.userInput = _ref2;
},
style: { 'width': '9px' },
value: filterText,
onBlur: this.handleBlur,
onFocus: function onFocus(e) {
return _this9.props.onUserInputFocus(e);
},
onChange: function onChange(e) {
return _this9.props.onUserInput(e.target.value);
},
onKeyDown: this.handleKeyDown
}),
placeHolder,
React.createElement('i', null)
);
}
}]);
return MultiInput;
}(Component);
MultiInput.propTypes = {
onUserInputFocus: PropTypes.func,
onUserInput: PropTypes.func,
filterText: PropTypes.string,
disabled: PropTypes.bool
};
module.exports = dropDownCmp(documentClickCmp(defaultCheckedCmp(DropDown)), ['top', 'bottom']);