tuya-panel-kit
Version:
a functional component library for developing tuya device panels!
496 lines (418 loc) • 17.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _jsxFileName = 'src/components/slider-with-line/index.js';
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 _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactNative = require('react-native');
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _utils = require('../../utils');
var _divider = require('../divider');
var _divider2 = _interopRequireDefault(_divider);
var _TYText = require('../TYText');
var _TYText2 = _interopRequireDefault(_TYText);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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 cx = _utils.RatioUtils.convertX;
var SliderWithLine = function (_React$Component) {
_inherits(SliderWithLine, _React$Component);
function SliderWithLine(props) {
_classCallCheck(this, SliderWithLine);
var _this = _possibleConstructorReturn(this, (SliderWithLine.__proto__ || Object.getPrototypeOf(SliderWithLine)).call(this, props));
_this._handleRealLocation = function (originLocation) {
var _this$props = _this.props,
min = _this$props.min,
max = _this$props.max,
stepValue = _this$props.stepValue,
horizontal = _this$props.horizontal;
var _this$style = _this.style,
width = _this$style.width,
height = _this$style.height;
if (stepValue && max !== min) {
var everyWidth = (horizontal ? width : height) * stepValue / (max - min);
return Math.round(originLocation / everyWidth) * everyWidth;
}
return originLocation;
};
_this._handleRangeNumber = function (val, min, max) {
return Math.max(Math.min(val, max), min);
};
_this._handleLocationToValue = function (location) {
var _this$props2 = _this.props,
min = _this$props2.min,
max = _this$props2.max,
stepValue = _this$props2.stepValue,
horizontal = _this$props2.horizontal;
var _this$style2 = _this.style,
width = _this$style2.width,
height = _this$style2.height;
var hasPoint = ('' + stepValue).indexOf('.') !== -1;
var pointNum = hasPoint ? ('' + stepValue).length - (('' + stepValue).indexOf('.') + 1) : 0;
return Math.min(max, Math.max(min, Number(location / (horizontal ? width : height) * (max - min) + min).toFixed(pointNum)));
};
_this._handleValueToWidth = function (value) {
var _this$props3 = _this.props,
min = _this$props3.min,
max = _this$props3.max,
horizontal = _this$props3.horizontal;
var _this$style3 = _this.style,
width = _this$style3.width,
height = _this$style3.height;
return value * (horizontal ? width : height) / (max - min);
};
_this._handleToValues = function () {
var leftVal = _this.leftVal,
rightVal = _this.rightVal;
var rightValue = _this._handleLocationToValue(rightVal);
var leftValue = _this._handleLocationToValue(leftVal);
return { minValue: leftValue, maxValue: rightValue };
};
_this.releaseMove = function () {
var onSlidingComplete = _this.props.onSlidingComplete;
setTimeout(function () {
_this.moving = false;
}, 500);
onSlidingComplete && onSlidingComplete(_this._handleToValues());
};
_this.renderExtraInfo = function (style, color) {
var _this$props4 = _this.props,
nounNumber = _this$props4.nounNumber,
nounWidth = _this$props4.nounWidth,
nounHeight = _this$props4.nounHeight,
nounRadius = _this$props4.nounRadius,
fontSize = _this$props4.fontSize,
startText = _this$props4.startText,
endText = _this$props4.endText,
horizontal = _this$props4.horizontal;
var _this$style4 = _this.style,
height = _this$style4.height,
width = _this$style4.width;
return _react2.default.createElement(
_reactNative.Animated.View,
{
style: [horizontal && { left: 0 }, style, { width: width, height: height, position: 'absolute' }],
__source: {
fileName: _jsxFileName,
lineNumber: 340
}
},
_react2.default.createElement(
_reactNative.View,
{
style: [styles.percentTextWrap, { height: height, width: width }, horizontal && { flexDirection: 'row' }],
__source: {
fileName: _jsxFileName,
lineNumber: 343
}
},
_react2.default.createElement(
_TYText2.default,
{
style: [styles.percentText, { color: color, fontSize: fontSize }, horizontal ? { left: Math.round(width * cx(12) / cx(327)) } : { bottom: Math.round(height * cx(12) / cx(327)) }],
__source: {
fileName: _jsxFileName,
lineNumber: 350
}
},
startText
),
_react2.default.createElement(
_TYText2.default,
{
style: [styles.percentText, { color: color, fontSize: fontSize }, horizontal ? { right: Math.round(width * cx(12) / cx(327)) } : { top: Math.round(height * cx(12) / cx(327)) }],
__source: {
fileName: _jsxFileName,
lineNumber: 361
}
},
endText
)
),
new Array(nounNumber).fill(0).map(function (_, index) {
var _left = Math.round((horizontal ? width : height) * cx(53) / cx(327)) + index * ((horizontal ? nounWidth : nounHeight) + Math.round(((horizontal ? width * cx(207) : height * cx(220)) / cx(327) - (horizontal ? nounWidth : nounHeight) * nounNumber) / (nounNumber - 1)));
return _react2.default.createElement(_divider2.default, {
key: '' + index,
width: nounWidth,
height: nounHeight,
color: color,
style: [styles.dividerStyle, {
borderRadius: nounRadius
}, horizontal ? { top: (height - nounHeight) / 2, left: _left } : { left: (width - nounWidth) / 2, bottom: _left }],
__source: {
fileName: _jsxFileName,
lineNumber: 384
}
});
})
);
};
_this.left = new _reactNative.Animated.Value(_this._handleValueToWidth(props.minValue));
_this.right = new _reactNative.Animated.Value(_this._handleValueToWidth(props.maxValue));
_this.leftVal = 0;
_this.rightVal = 100;
_this.left.addListener(function (_ref) {
var value = _ref.value;
return _this.leftVal = value;
});
_this.right.addListener(function (_ref2) {
var value = _ref2.value;
return _this.rightVal = value;
});
_this.leftNegative = _reactNative.Animated.multiply(_this.left, new _reactNative.Animated.Value(-1));
_this.width = _reactNative.Animated.add(_this.right, _this.leftNegative);
_this.createPanResponder();
_this.initSliderPosition(props);
return _this;
}
_createClass(SliderWithLine, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (this.moving) return;
this.initSliderPosition(nextProps);
}
}, {
key: 'initSliderPosition',
value: function initSliderPosition(props) {
var minValue = props.minValue,
maxValue = props.maxValue;
var leftVal = this._handleValueToWidth(minValue);
var rightVal = this._handleValueToWidth(maxValue);
this.left.setValue(leftVal);
this.right.setValue(rightVal);
}
}, {
key: 'createPanResponder',
value: function createPanResponder() {
var _this2 = this;
this._panResponder = _reactNative.PanResponder.create({
onStartShouldSetPanResponder: function onStartShouldSetPanResponder() {
return !_this2.props.disabled;
},
onStartShouldSetPanResponderCapture: function onStartShouldSetPanResponderCapture() {
return !_this2.props.disabled;
},
onPanResponderGrant: function onPanResponderGrant(_ref3) {
var nativeEvent = _ref3.nativeEvent;
var _props = _this2.props,
minDisabled = _props.minDisabled,
maxDisabled = _props.maxDisabled,
canTouchTrack = _props.canTouchTrack,
onSlidingStart = _props.onSlidingStart,
horizontal = _props.horizontal;
var locationX = nativeEvent.locationX,
locationY = nativeEvent.locationY;
var leftValue = _this2.leftVal,
rightValue = _this2.rightVal;
var height = _this2.style.height;
var direction = minDisabled ? 'max' : 'min';
if (horizontal && !maxDisabled && Math.abs(locationX - leftValue) > Math.abs(locationX - rightValue)) {
direction = 'max';
}
if (!horizontal && !maxDisabled && Math.abs(height - locationY - leftValue) > Math.abs(height - locationY - rightValue)) {
direction = 'max';
}
_this2.direction = direction;
_this2.cacheVal = direction === 'min' ? leftValue : rightValue;
_this2.moving = true;
if (canTouchTrack) {
var realLocation = _this2._handleRealLocation(horizontal ? locationX : height - locationY);
if (direction === 'min') {
_this2.left.setValue(realLocation);
} else {
_this2.right.setValue(realLocation);
}
}
onSlidingStart && onSlidingStart(_this2._handleToValues());
},
onPanResponderMove: function onPanResponderMove(_ref4, _ref5) {
var nativeEvent = _ref4.nativeEvent;
var dx = _ref5.dx,
dy = _ref5.dy;
var _props2 = _this2.props,
minDisabled = _props2.minDisabled,
onValueChange = _props2.onValueChange,
horizontal = _props2.horizontal,
stepValue = _props2.stepValue,
max = _props2.max,
min = _props2.min;
var direction = _this2.direction;
var locationX = nativeEvent.locationX,
locationY = nativeEvent.locationY;
var _style = _this2.style,
width = _style.width,
height = _style.height;
var moveLocation = horizontal ? locationX : locationY;
if (locationX > width) return;
moveLocation = Math.min(Math.max(0, horizontal ? moveLocation : height - moveLocation), horizontal ? width : height);
var everyWidth = 0;
if (stepValue && max !== min) {
everyWidth = (horizontal ? width : height) * stepValue / (max - min);
}
if (direction === 'min') {
moveLocation = _this2._handleRangeNumber(moveLocation, 0, _this2.rightVal - (minDisabled ? 0 : everyWidth));
_this2.left.setValue(_this2._handleRealLocation(moveLocation));
} else {
moveLocation = _this2._handleRangeNumber(moveLocation, _this2.leftVal + (minDisabled ? 0 : everyWidth), horizontal ? width : height);
_this2.right.setValue(_this2._handleRealLocation(moveLocation));
}
onValueChange && onValueChange(_this2._handleToValues());
},
onPanResponderTerminate: this.releaseMove,
onPanResponderRelease: this.releaseMove,
onPanResponderTerminationRequest: function onPanResponderTerminationRequest() {
return false;
}
});
}
}, {
key: 'render',
value: function render() {
var _props3 = this.props,
activeBackgroundColor = _props3.activeBackgroundColor,
disabled = _props3.disabled,
nounColor = _props3.nounColor,
activeNounColor = _props3.activeNounColor,
horizontal = _props3.horizontal,
style = _props3.style;
var height = this.style.height;
return _react2.default.createElement(
_reactNative.View,
{ style: [this.style, { opacity: disabled ? 0.7 : 1, overflow: 'hidden' }, style], __source: {
fileName: _jsxFileName,
lineNumber: 416
}
},
this.renderExtraInfo({}, nounColor),
_react2.default.createElement(
_reactNative.Animated.View,
{
style: [this.style, {
backgroundColor: activeBackgroundColor,
overflow: 'hidden'
}, horizontal ? { width: this.width, left: this.left } : {
height: this.width,
bottom: _reactNative.Animated.add(_reactNative.Animated.add(this.width, -height), this.left)
}],
__source: {
fileName: _jsxFileName,
lineNumber: 418
}
},
this.renderExtraInfo(horizontal ? { left: this.leftNegative } : { bottom: this.leftNegative }, activeNounColor)
),
_react2.default.createElement(_reactNative.View, _extends({
style: [this.style, styles.touchArea]
}, this._panResponder.panHandlers, {
pointerEvents: 'box-only',
__source: {
fileName: _jsxFileName,
lineNumber: 438
}
}))
);
}
}, {
key: 'style',
get: function get() {
var _props4 = this.props,
width = _props4.width,
height = _props4.height,
borderRadius = _props4.borderRadius,
backgroundColor = _props4.backgroundColor;
return {
width: width,
height: height,
borderRadius: borderRadius,
backgroundColor: backgroundColor
};
}
}]);
return SliderWithLine;
}(_react2.default.Component);
SliderWithLine.propTypes = {
maxValue: _propTypes2.default.number,
minValue: _propTypes2.default.number,
horizontal: _propTypes2.default.bool,
stepValue: _propTypes2.default.number,
canTouchTrack: _propTypes2.default.bool,
disabled: _propTypes2.default.bool,
nounWidth: _propTypes2.default.number,
nounHeight: _propTypes2.default.number,
nounRadius: _propTypes2.default.number,
nounColor: _propTypes2.default.string,
fontSize: _propTypes2.default.number,
activeNounColor: _propTypes2.default.string,
width: _propTypes2.default.number,
height: _propTypes2.default.number,
borderRadius: _propTypes2.default.number,
backgroundColor: _propTypes2.default.string,
activeBackgroundColor: _propTypes2.default.string,
nounNumber: _propTypes2.default.number,
startText: _propTypes2.default.string,
endText: _propTypes2.default.string,
minDisabled: _propTypes2.default.bool,
maxDisabled: _propTypes2.default.bool,
min: _propTypes2.default.number,
max: _propTypes2.default.number,
onSlidingStart: _propTypes2.default.func,
onValueChange: _propTypes2.default.func,
onSlidingComplete: _propTypes2.default.func,
style: _reactNative.ViewPropTypes.style
};
SliderWithLine.defaultProps = {
maxValue: 50,
minValue: 0,
horizontal: true,
nounColor: '#000',
disabled: false,
stepValue: 0,
min: 0,
max: 100,
canTouchTrack: true,
minDisabled: true,
maxDisabled: false,
width: cx(327),
height: cx(60),
borderRadius: cx(16),
backgroundColor: '#FFF',
activeBackgroundColor: '#57BCFB',
activeNounColor: '#FFF',
nounNumber: 9,
nounWidth: cx(1),
nounHeight: cx(14),
nounRadius: cx(0.5),
fontSize: cx(12),
startText: '0%',
endText: '100%',
onSlidingStart: null,
onValueChange: null,
onSlidingComplete: null,
style: null
};
exports.default = SliderWithLine;
var styles = _reactNative.StyleSheet.create({
touchArea: {
position: 'absolute',
zIndex: 10,
backgroundColor: 'transparent',
overflow: 'hidden'
},
percentTextWrap: {
justifyContent: 'space-between',
alignItems: 'center'
},
percentText: {
opacity: 0.5,
position: 'absolute',
fontWeight: '400'
},
dividerStyle: {
position: 'absolute',
opacity: 0.5
}
});