@fruits-chain/react-native-xiaoshu
Version:
🌈 React Native UI library
180 lines (179 loc) • 7.53 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _isUndefined = _interopRequireDefault(require("lodash/isUndefined"));
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _index = require("../helpers/index.js");
var _index2 = require("../hooks/index.js");
var _loadingCircular = _interopRequireDefault(require("../loading/loading-circular.js"));
var _style = require("../loading/style.js");
var _index3 = _interopRequireDefault(require("../theme/index.js"));
var _style2 = require("./style.js");
var _jsxRuntime = require("react/jsx-runtime");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Switch 开关
* @description 用于在打开和关闭状态之间进行切换。
*/function Switch({
theme,
size,
disabled = false,
loading = false,
activeValue = true,
inactiveValue = false,
activeColor,
inactiveColor,
activeChildren,
inactiveChildren,
onPress,
beforeChange,
testID,
...restProps
}) {
const translateX = (0, _react.useRef)(new _reactNative.Animated.Value(0));
const [value, onChange] = (0, _index2.useControllableValue)(restProps, {
defaultValue: inactiveValue
});
const [CV, STYLES] = _index3.default.useStyle({
varCreator: _style2.varCreator,
styleCreator: _style2.styleCreator,
theme
});
const [CV_LOADING] = _index3.default.useStyle({
varCreator: _style.varCreator
});
const unitSize = (0, _index.getDefaultValue)(size, CV.switch_size);
const nodeEdgeDistance = 2;
const [switchWidth, setSwitchWidth] = (0, _index2.useDifferentState)(unitSize * CV.switch_width_ratio);
const [switchHeight, nodeSize, translateXValueEnd, translateXValueStart] = (0, _react.useMemo)(() => {
const _switchHeight = unitSize * CV.switch_height_ratio;
const _nodeSize = unitSize * CV.switch_node_size_ratio;
const _isInnerNode = _switchHeight - _nodeSize < nodeEdgeDistance * 2;
const _nodeRealSize = _isInnerNode ? _nodeSize - nodeEdgeDistance * 2 : _nodeSize;
const _innerPadding = _isInnerNode ? nodeEdgeDistance : (_switchHeight - _nodeSize) / 2;
const _translateXValueEnd = switchWidth - _nodeRealSize - _innerPadding;
const _translateXValueStart = _innerPadding;
return [_switchHeight, _nodeRealSize, _translateXValueEnd, _translateXValueStart];
}, [CV.switch_height_ratio, CV.switch_node_size_ratio, switchWidth, unitSize]);
const active = value === activeValue;
const onPressTouchable = () => {
onPress?.();
if (!disabled && !loading) {
const newValue = active ? inactiveValue : activeValue;
(0, _index.callInterceptor)(beforeChange, {
args: [newValue],
done: () => {
onChange(newValue);
}
});
}
};
(0, _react.useEffect)(() => {
const actionValue = _reactNative.Animated.timing(translateX.current,
// 动画中的变量值
{
toValue: active ? 1 : 0,
duration: CV.switch_transition_duration,
useNativeDriver: true
});
actionValue.start();
return () => {
// 停止动画
if (actionValue) {
actionValue.stop();
}
};
}, [active, CV.switch_transition_duration]);
const switchStyles = [STYLES.switch, {
minWidth: switchWidth,
height: switchHeight,
borderRadius: switchHeight / 2,
// 当前过渡不支持 color/backgroundColor
// 参考:https://stackoverflow.com/a/60586628
backgroundColor: active ? activeColor || CV.switch_on_background_color : inactiveColor || CV.switch_background_color
}, disabled ? STYLES.disabled : {}];
const nodeStyleSummary = [STYLES.node, {
top: nodeEdgeDistance,
width: nodeSize,
height: nodeSize,
borderRadius: nodeSize / 2,
transform: [{
translateX: translateX.current.interpolate({
inputRange: [0, 1],
outputRange: [translateXValueStart, translateXValueEnd]
})
}]
}];
const childrenMinEdgeDistance = switchHeight / 3;
const childrenMaxEdgeDistance = nodeSize + nodeEdgeDistance * 3;
const activeChildrenStyle = {
height: switchHeight,
paddingLeft: childrenMinEdgeDistance,
paddingRight: childrenMaxEdgeDistance,
justifyContent: 'center',
alignItems: 'center',
transform: [{
translateX: translateX.current.interpolate({
inputRange: [0, 1],
outputRange: [-switchWidth, 0]
})
}]
};
const inactiveChildrenStyle = {
marginTop: -switchHeight,
height: switchHeight,
paddingLeft: childrenMaxEdgeDistance,
paddingRight: childrenMinEdgeDistance,
justifyContent: 'center',
alignItems: 'center',
transform: [{
translateX: translateX.current.interpolate({
inputRange: [0, 1],
outputRange: [0, switchWidth]
})
}]
};
const onLayoutChildren = (0, _index2.usePersistFn)(e => {
setSwitchWidth(v => Math.max(v, e.nativeEvent.layout.width));
});
const activeChildrenJSX = (0, _index.renderTextLikeJSX)(activeChildren, [STYLES.children_text]);
const inactiveChildrenJSX = (0, _index.renderTextLikeJSX)(inactiveChildren, [STYLES.children_text]);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableWithoutFeedback, {
onPress: onPressTouchable,
testID: testID,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: STYLES.switch_wrap,
collapsable: false,
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: switchStyles,
collapsable: false,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
style: nodeStyleSummary,
children: loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_loadingCircular.default, {
size: nodeSize / 4 * 3,
color: active ? !(0, _isUndefined.default)(activeColor) ? activeColor : CV.switch_on_background_color : !(0, _isUndefined.default)(inactiveColor) ? inactiveColor : CV_LOADING.loading_text_color
}) : null
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: STYLES.children_wrap,
collapsable: false,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
style: activeChildrenStyle,
onLayout: onLayoutChildren,
children: activeChildrenJSX
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
style: inactiveChildrenStyle,
onLayout: onLayoutChildren,
children: inactiveChildrenJSX
})]
})]
})
})
});
}
var _default = exports.default = /*#__PURE__*/(0, _react.memo)(Switch);
//# sourceMappingURL=switch.js.map