weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
576 lines (490 loc) • 16.6 kB
JavaScript
'use strict';
/** @jsx createElement */
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
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; }; }();
var _class, _temp;
// import Slip from 'nuke-slip';
var _rax = require('rax');
var _nukeView = require('../../View/index.js');
var _nukeView2 = _interopRequireDefault(_nukeView);
var _nukeText = require('../../Text/index.js');
var _nukeText2 = _interopRequireDefault(_nukeText);
var _nukeMask = require('../../Mask/index.js');
var _nukeMask2 = _interopRequireDefault(_nukeMask);
var _nukeHelper = require('../../Helper/index.js');
var _nukeThemeProvider = require('../../ThemeProvider/index.js');
var _nukeThemeProvider2 = _interopRequireDefault(_nukeThemeProvider);
var _column = require('./column.js');
var _column2 = _interopRequireDefault(_column);
var _util = require('./util.js');
var _styles = require('../styles/index.js');
var _styles2 = _interopRequireDefault(_styles);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
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 noop = function noop() {};
var connectStyle = _nukeThemeProvider2.default.connectStyle;
var Picker = (_temp = _class = function (_Component) {
_inherits(Picker, _Component);
function Picker(props) {
_classCallCheck(this, Picker);
var _this = _possibleConstructorReturn(this, (Picker.__proto__ || Object.getPrototypeOf(Picker)).call(this, props));
var visible = void 0;var value = void 0;
if ('visible' in props) {
visible = props.visible;
} else {
visible = props.defaultVisible;
}
if ('value' in props) {
value = props.value;
} else {
value = _this.handleSelectedKey();
}
_this.state = {
value: value,
visible: visible
};
_this.items = [];
_this.columns = null; // calculate at some time
['onDone', 'onCancel', 'onClose', 'onChange', 'onUpdate', 'onVisibleChange', 'afterOpen', 'maskPress', 'afterClose'].forEach(function (m) {
_this[m] = _this[m].bind(_this);
});
return _this;
}
_createClass(Picker, [{
key: 'handleSelectedKey',
value: function handleSelectedKey() {
var _props = this.props,
selectedKey = _props.selectedKey,
dataSource = _props.dataSource;
var val = void 0;
if (!selectedKey) {
if (dataSource[0].children) {
val = [dataSource[0].key, dataSource[0].children[0].key];
} else {
val = dataSource[0].key;
}
} else {
val = selectedKey;
}
if (!val) {
if (dataSource[0].children) {
val = [dataSource[0].key, dataSource[0].children[0].key];
} else {
val = [dataSource[0].key];
}
}
if (typeof val === 'string') {
val = [val];
}
return val;
}
}, {
key: 'getChildContext',
value: function getChildContext() {
return {
__picker__: true,
onUpdate: this.onUpdate,
onChange: this.onChange,
selectedValue: this.state.value
};
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
// controlled component
// sync state from props
if ('visible' in nextProps) {
this.setState({
visible: nextProps.visible
});
}
if ('value' in nextProps) {
this.setState({
value: nextProps.value
});
}
}
}, {
key: 'componentWillUpdate',
value: function componentWillUpdate(nextProps, nextState) {
if (nextState.value !== this.state.value || nextProps.dataSource !== this.props.dataSource || JSON.stringify(nextState.value) !== JSON.stringify(this.state.value) || JSON.stringify(nextProps.dataSource) !== JSON.stringify(this.props.dataSource)) {
this.changed = true;
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
this.changed = false;
}
}, {
key: 'getColumns',
value: function getColumns(value) {
// debugger;
var dataSource = this.props.dataSource;
var columns = [];
value = value || this.state.value;
// normal data
if ('children' in dataSource[0]) {
// cascade data
var cols = dataSource;
var flag = false;
if (cols.length > 0) {
if (value === '') {
value = [];
}
columns.push(cols);
}
for (var i = 0;; i++) {
for (var j = 0, l = cols.length; j < l; j++) {
var col = cols[j];
var colValue = value[i];
if ((0, _util.keyMap)(col) === colValue) {
cols = childrenMap(col);
flag = true;
break;
}
}
if (!flag) {
if (cols.length > 0) {
value[i] = (0, _util.keyMap)(cols[0]);
cols = childrenMap(cols[0]);
} else {
cols = null;
value[i] = null;
}
}
if (!cols || !cols.length) {
break;
} else {
columns.push(cols);
flag = false;
}
}
} else {
columns = [dataSource];
}
// column change -> value change
// dont setState() re-render
if (value instanceof Array) {
value.splice(columns.length);
}
this.columns = columns;
return columns;
}
}, {
key: 'show',
value: function show() {
this.setState({
visible: true
});
this.picker && this.picker.show();
}
}, {
key: 'hide',
value: function hide() {
this.picker && this.picker.hide();
this.setState({
visible: false
});
}
}, {
key: 'setVisible',
value: function setVisible(visible, cb) {
if (this.state.visible === visible) {
return;
}
var callback = this.props['' + cb];
// if (!('visible' in this.props)) {
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
if (callback && callback.apply(undefined, args) !== false) {
if (visible) {
this.show();
} else {
this.hide();
}
this.setState({ visible: visible });
}
// } else {
// callback.apply(null, args);
// }
}
}, {
key: 'onDone',
value: function onDone(e) {
this.setVisible(false, 'onDone', this.items, e);
}
}, {
key: 'onCancel',
value: function onCancel(e) {
this.setVisible(false, 'onCancel', e);
}
}, {
key: 'onClose',
value: function onClose(e) {
this.setVisible(false, 'onClose', e);
}
}, {
key: 'onUpdate',
value: function onUpdate(item, index) {
// debugger;
this.items[index] = item;
// console.log(this.items);
}
}, {
key: 'onChange',
value: function onChange(v, item, i) {
var _this2 = this;
var items = this.items;
var value = this.state.value;
var newValue = void 0;var newItems = void 0;
var _props2 = this.props,
dataSource = _props2.dataSource,
onChange = _props2.onChange;
newValue = [].concat(_toConsumableArray(value));
newValue[i] = v;
newItems = [].concat(_toConsumableArray(items));
newItems[i] = item;
if (!('value' in this.props)) {
this.setState({
value: newValue
}, function () {
// use callback beacuse of dynamic data
if (onChange && onChange(newItems) === false) {
// reset
_this2.setState({
value: value
});
}
});
} else {
// cascade data normalize value
if (!(this.props.dataSource[0] instanceof Array)) {
this.getColumns(value);
}
onChange(newItems);
}
}
}, {
key: 'onVisibleChange',
value: function onVisibleChange(visible) {
this.setVisible(visible, 'onVisibleChange', visible);
}
}, {
key: 'afterOpen',
value: function afterOpen() {
// debugger;
this.props.afterOpen && this.props.afterOpen(this);
}
}, {
key: 'afterClose',
value: function afterClose() {
this.props.afterClose();
}
}, {
key: 'getPickerEl',
value: function getPickerEl() {
var _props3 = this.props,
hasToolbar = _props3.hasToolbar,
hasToolbarButton = _props3.hasToolbarButton,
hasBottomButton = _props3.hasBottomButton,
buttonStyle = _props3.buttonStyle,
title = _props3.title,
childrenMap = _props3.childrenMap,
_props3$style = _props3.style,
style = _props3$style === undefined ? {} : _props3$style,
locale = _props3.locale;
var styles = this.props.themeStyle;
var children = this.props.children;
var columns = this.columns;
var toolbar = (0, _rax.createElement)(
_nukeView2.default,
{ style: styles['picker-toolbar'] },
hasToolbarButton ? (0, _rax.createElement)(
_nukeView2.default,
{ style: styles['picker-cancel'], onClick: this.onCancel },
locale.cancel
) : null,
(0, _rax.createElement)(
_nukeView2.default,
{ style: styles['picker-title'] },
title
),
hasToolbarButton ? (0, _rax.createElement)(
_nukeView2.default,
{ style: styles['picker-done'], onClick: this.onDone },
locale.confirm
) : null
);
if (!children) {
if (!columns || this.changed) {
columns = this.getColumns();
}
children = columns.map(function (col, index) {
return (0, _rax.createElement)(_column2.default, {
key: index,
index: index,
dataSource: col,
labelMap: _util.labelMap,
valueMap: _util.valueMap,
keyMap: _util.keyMap
});
});
} else if (children.map) {
children = children.map(function (col, index) {
return (0, _rax.cloneElement)(col, { index: index });
});
} else {
var index = 0;
children = (0, _rax.cloneElement)(children, { index: index });
}
var bottomButtonStyle = Object.assign({}, styles['picker-bottom-button'], buttonStyle);
var bottomButtonTextStyle = Object.assign({}, styles['picker-bottom-button-text']);
_nukeHelper.textKeys.forEach(function (item) {
if (bottomButtonStyle[item]) {
bottomButtonTextStyle[item] = bottomButtonStyle[item];
}
// 也加上伪类继承
if (bottomButtonStyle[item + ':active']) {
bottomButtonTextStyle[item + ':active'] = bottomButtonStyle[item + ':active'];
}
});
var pickerWrapStyle = Object.assign({}, styles.picker, style);
return (0, _rax.createElement)(
_nukeView2.default,
{ x: 'picker-wrap', style: pickerWrapStyle },
hasToolbar ? toolbar : null,
(0, _rax.createElement)(
_nukeView2.default,
{ x: 'picker-content', style: styles['picker-content'] },
children
),
hasBottomButton ? (0, _rax.createElement)(
_nukeView2.default,
{ style: bottomButtonStyle, onClick: this.onDone },
(0, _rax.createElement)(
_nukeText2.default,
{ style: bottomButtonTextStyle },
locale.confirm
)
) : null
);
}
}, {
key: 'maskPress',
value: function maskPress() {
var onCancel = this.props.onCancel;
onCancel && onCancel();
}
}, {
key: 'touchMove',
value: function touchMove(e) {
e.preventDefault();
}
}, {
key: 'render',
value: function render() {
var _this3 = this;
var visible = this.state.visible;
var _props4 = this.props,
trigger = _props4.trigger,
renderMask = _props4.renderMask,
_props4$style = _props4.style,
style = _props4$style === undefined ? {} : _props4$style,
maskClosable = _props4.maskClosable;
var styles = this.props.themeStyle;
var picker = null;
picker = this.getPickerEl();
return renderMask ? (0, _rax.createElement)(
_nukeMask2.default,
{
style: styles.mask,
defaultVisible: false,
maskClosable: maskClosable,
animate: true,
onShow: this.afterOpen,
onHide: this.afterClose,
onMaskPress: this.maskPress,
onTouchmove: this.touchMove,
ref: function ref(n) {
_this3.picker = n;
}
},
picker
) : picker;
}
}]);
return Picker;
}(_rax.Component), _class.propTypes = {
title: _rax.PropTypes.node,
value: _rax.PropTypes.array,
visible: _rax.PropTypes.bool,
trigger: _rax.PropTypes.element,
selectedKey: _rax.PropTypes.array,
defaultVisible: _rax.PropTypes.bool,
toolbar: _rax.PropTypes.node,
hasToolbar: _rax.PropTypes.bool,
dataSource: _rax.PropTypes.array,
onDone: _rax.PropTypes.func,
onCancel: _rax.PropTypes.func,
onClose: _rax.PropTypes.func,
onChange: _rax.PropTypes.func,
afterOpen: _rax.PropTypes.func,
afterClose: _rax.PropTypes.func,
onVisibleChange: _rax.PropTypes.func,
labelMap: _rax.PropTypes.func,
valueMap: _rax.PropTypes.func,
childrenMap: _rax.PropTypes.func,
keyMap: _rax.PropTypes.func
}, _class.defaultProps = {
dataSource: [],
selectedKey: '',
defaultVisible: false,
hasToolbar: true,
title: '',
trigger: null,
onChange: noop,
onDone: noop,
onCancel: noop,
onClose: noop,
afterOpen: noop,
afterClose: noop,
onVisibleChange: noop,
labelMap: _util.labelMap,
valueMap: _util.valueMap,
childrenMap: childrenMap,
keyMap: _util.keyMap
}, _class.childContextTypes = {
onUpdate: _rax.PropTypes.func,
onChange: _rax.PropTypes.func,
__picker__: _rax.PropTypes.bool,
selectedValue: _rax.PropTypes.array
}, _temp);
// for cascade data,default key: children
function childrenMap(item) {
if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object') {
return item.children;
}
}
Picker.defaultProps = {
locale: {
cancel: 'Cancel',
confirm: 'Confirm'
},
renderMask: true
};
Picker.propTypes = {
locale: _rax.PropTypes.obj,
renderMask: _rax.PropTypes.boolean
};
Picker.displayName = 'Picker';
var StyledPicker = connectStyle(_styles2.default)(Picker);
exports.default = StyledPicker;
module.exports = exports['default'];