UNPKG

@tamagui/react-native-web-lite

Version:
361 lines (360 loc) 13 kB
import { NativeAnimatedNonTurboModule } from "./NativeAnimatedModule.mjs"; import { NativeAnimatedTurboModule } from "./NativeAnimatedTurboModule.mjs"; import { NativeEventEmitter } from "../EventEmitter/NativeEventEmitter.mjs"; import { Platform } from "../Utilities/Platform.mjs"; import { ReactNativeFeatureFlags } from "../ReactNative/ReactNativeFeatureFlags.mjs"; import { invariant } from "@tamagui/react-native-web-internals"; import { RCTDeviceEventEmitter } from "../EventEmitter/RCTDeviceEventEmitter.mjs"; const NativeAnimatedModule = Platform.OS === "ios" && global.RN$Bridgeless === true ? NativeAnimatedTurboModule : NativeAnimatedNonTurboModule; let __nativeAnimatedNodeTagCount = 1; let __nativeAnimationIdCount = 1; let nativeEventEmitter; let waitingForQueuedOperations = /* @__PURE__ */new Set(); let queueOperations = false; let queue = []; let singleOpQueue = []; const useSingleOpBatching = false; Platform.OS === "android" && !!NativeAnimatedModule?.queueAndExecuteBatchedOperations && ReactNativeFeatureFlags.animatedShouldUseSingleOp(); let flushQueueTimeout = null; const eventListenerGetValueCallbacks = {}; const eventListenerAnimationFinishedCallbacks = {}; const nativeOps = useSingleOpBatching ? function () { const apis = ["createAnimatedNode", // 1 "updateAnimatedNodeConfig", // 2 "getValue", // 3 "startListeningToAnimatedNodeValue", // 4 "stopListeningToAnimatedNodeValue", // 5 "connectAnimatedNodes", // 6 "disconnectAnimatedNodes", // 7 "startAnimatingNode", // 8 "stopAnimation", // 9 "setAnimatedNodeValue", // 10 "setAnimatedNodeOffset", // 11 "flattenAnimatedNodeOffset", // 12 "extractAnimatedNodeOffset", // 13 "connectAnimatedNodeToView", // 14 "disconnectAnimatedNodeFromView", // 15 "restoreDefaultValues", // 16 "dropAnimatedNode", // 17 "addAnimatedEventToView", // 18 "removeAnimatedEventFromView", // 19 "addListener", // 20 "removeListener" // 21 ]; return apis.reduce((acc, functionName, i) => { acc[functionName] = i + 1; return acc; }, {}); }() : NativeAnimatedModule; const API = { getValue: function (tag, saveValueCallback) { invariant(nativeOps, "Native animated module is not available"); if (useSingleOpBatching) { if (saveValueCallback) { eventListenerGetValueCallbacks[tag] = saveValueCallback; } API.queueOperation(nativeOps.getValue, tag); } else { API.queueOperation(nativeOps.getValue, tag, saveValueCallback); } }, setWaitingForIdentifier: function (id) { waitingForQueuedOperations.add(id); queueOperations = true; if (ReactNativeFeatureFlags.animatedShouldDebounceQueueFlush() && flushQueueTimeout) { clearTimeout(flushQueueTimeout); } }, unsetWaitingForIdentifier: function (id) { waitingForQueuedOperations.delete(id); if (waitingForQueuedOperations.size === 0) { queueOperations = false; API.disableQueue(); } }, disableQueue: function () { invariant(nativeOps, "Native animated module is not available"); if (ReactNativeFeatureFlags.animatedShouldDebounceQueueFlush()) { const prevTimeout = flushQueueTimeout; clearImmediate(prevTimeout); flushQueueTimeout = setImmediate(API.flushQueue); } else { API.flushQueue(); } }, flushQueue: function () {}, queueOperation: (fn, ...args) => { if (useSingleOpBatching) { singleOpQueue.push(fn, ...args); return; } if (queueOperations || queue.length !== 0) { queue.push(() => fn(...args)); } else { fn(...args); } }, createAnimatedNode: function (tag, config) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.createAnimatedNode, tag, config); }, updateAnimatedNodeConfig: function (tag, config) { invariant(nativeOps, "Native animated module is not available"); }, startListeningToAnimatedNodeValue: function (tag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.startListeningToAnimatedNodeValue, tag); }, stopListeningToAnimatedNodeValue: function (tag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.stopListeningToAnimatedNodeValue, tag); }, connectAnimatedNodes: function (parentTag, childTag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.connectAnimatedNodes, parentTag, childTag); }, disconnectAnimatedNodes: function (parentTag, childTag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.disconnectAnimatedNodes, parentTag, childTag); }, startAnimatingNode: function (animationId, nodeTag, config, endCallback) { invariant(nativeOps, "Native animated module is not available"); if (useSingleOpBatching) { if (endCallback) { eventListenerAnimationFinishedCallbacks[animationId] = endCallback; } API.queueOperation(nativeOps.startAnimatingNode, animationId, nodeTag, config); } else { API.queueOperation(nativeOps.startAnimatingNode, animationId, nodeTag, config, endCallback); } }, stopAnimation: function (animationId) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.stopAnimation, animationId); }, setAnimatedNodeValue: function (nodeTag, value) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.setAnimatedNodeValue, nodeTag, value); }, setAnimatedNodeOffset: function (nodeTag, offset) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.setAnimatedNodeOffset, nodeTag, offset); }, flattenAnimatedNodeOffset: function (nodeTag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.flattenAnimatedNodeOffset, nodeTag); }, extractAnimatedNodeOffset: function (nodeTag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.extractAnimatedNodeOffset, nodeTag); }, connectAnimatedNodeToView: function (nodeTag, viewTag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.connectAnimatedNodeToView, nodeTag, viewTag); }, disconnectAnimatedNodeFromView: function (nodeTag, viewTag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.disconnectAnimatedNodeFromView, nodeTag, viewTag); }, restoreDefaultValues: function (nodeTag) { invariant(nativeOps, "Native animated module is not available"); if (nativeOps.restoreDefaultValues != null) { API.queueOperation(nativeOps.restoreDefaultValues, nodeTag); } }, dropAnimatedNode: function (tag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.dropAnimatedNode, tag); }, addAnimatedEventToView: function (viewTag, eventName, eventMapping) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.addAnimatedEventToView, viewTag, eventName, eventMapping); }, removeAnimatedEventFromView(viewTag, eventName, animatedNodeTag) { invariant(nativeOps, "Native animated module is not available"); API.queueOperation(nativeOps.removeAnimatedEventFromView, viewTag, eventName, animatedNodeTag); } }; const SUPPORTED_COLOR_STYLES = { backgroundColor: true, borderBottomColor: true, borderColor: true, borderEndColor: true, borderLeftColor: true, borderRightColor: true, borderStartColor: true, borderTopColor: true, color: true, tintColor: true }; const SUPPORTED_STYLES = { ...SUPPORTED_COLOR_STYLES, borderBottomEndRadius: true, borderBottomLeftRadius: true, borderBottomRightRadius: true, borderBottomStartRadius: true, borderRadius: true, borderTopEndRadius: true, borderTopLeftRadius: true, borderTopRightRadius: true, borderTopStartRadius: true, elevation: true, opacity: true, transform: true, zIndex: true, /* ios styles */ shadowOpacity: true, shadowRadius: true, /* legacy android transform properties */ scaleX: true, scaleY: true, translateX: true, translateY: true }; const SUPPORTED_TRANSFORMS = { translateX: true, translateY: true, scale: true, scaleX: true, scaleY: true, rotate: true, rotateX: true, rotateY: true, rotateZ: true, perspective: true }; const SUPPORTED_INTERPOLATION_PARAMS = { inputRange: true, outputRange: true, extrapolate: true, extrapolateRight: true, extrapolateLeft: true }; function addWhitelistedStyleProp(prop) { SUPPORTED_STYLES[prop] = true; } function addWhitelistedTransformProp(prop) { SUPPORTED_TRANSFORMS[prop] = true; } function addWhitelistedInterpolationParam(param) { SUPPORTED_INTERPOLATION_PARAMS[param] = true; } function isSupportedColorStyleProp(prop) { return SUPPORTED_COLOR_STYLES.hasOwnProperty(prop); } function isSupportedStyleProp(prop) { return SUPPORTED_STYLES.hasOwnProperty(prop); } function isSupportedTransformProp(prop) { return SUPPORTED_TRANSFORMS.hasOwnProperty(prop); } function isSupportedInterpolationParam(param) { return SUPPORTED_INTERPOLATION_PARAMS.hasOwnProperty(param); } function validateTransform(configs) { configs.forEach(config => { if (!isSupportedTransformProp(config.property)) { throw new Error(`Property '${config.property}' is not supported by native animated module`); } }); } function validateStyles(styles) { for (const key in styles) { if (!isSupportedStyleProp(key)) { throw new Error(`Style property '${key}' is not supported by native animated module`); } } } function validateInterpolation(config) { for (const key in config) { if (!isSupportedInterpolationParam(key)) { throw new Error(`Interpolation property '${key}' is not supported by native animated module`); } } } function generateNewNodeTag() { return __nativeAnimatedNodeTagCount++; } function generateNewAnimationId() { return __nativeAnimationIdCount++; } function assertNativeAnimatedModule() { invariant(NativeAnimatedModule, "Native animated module is not available"); } let _warnedMissingNativeAnimated = false; function shouldUseNativeDriver(config) { if (config.useNativeDriver == null) { console.warn("Animated: `useNativeDriver` was not specified. This is a required option and must be explicitly set to `true` or `false`"); } if (config.useNativeDriver === true && !NativeAnimatedModule) { if (!_warnedMissingNativeAnimated) { console.warn("Animated: `useNativeDriver` is not supported because the native animated module is missing. Falling back to JS-based animation. To resolve this, add `RCTAnimation` module to this app, or remove `useNativeDriver`. Make sure to run `bundle exec pod install` first. Read more about autolinking: https://github.com/react-native-community/cli/blob/master/docs/autolinking.md"); _warnedMissingNativeAnimated = true; } return false; } return config.useNativeDriver || false; } function transformDataType(value) { if (typeof value !== "string") { return value; } if (/deg$/.test(value)) { const degrees = parseFloat(value) || 0; const radians = degrees * Math.PI / 180; return radians; } else { return value; } } const NativeAnimatedHelper = { API, isSupportedColorStyleProp, isSupportedStyleProp, isSupportedTransformProp, isSupportedInterpolationParam, addWhitelistedStyleProp, addWhitelistedTransformProp, addWhitelistedInterpolationParam, validateStyles, validateTransform, validateInterpolation, generateNewNodeTag, generateNewAnimationId, assertNativeAnimatedModule, shouldUseNativeDriver, transformDataType, get nativeEventEmitter() { if (!nativeEventEmitter) { nativeEventEmitter = new NativeEventEmitter( // T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior // If you want to use the native module on other platforms, please remove this condition and test its behavior Platform.OS !== "ios" ? null : NativeAnimatedModule); } return nativeEventEmitter; } }; var NativeAnimatedHelper_default = NativeAnimatedHelper; export { API, NativeAnimatedHelper, addWhitelistedInterpolationParam, addWhitelistedStyleProp, addWhitelistedTransformProp, assertNativeAnimatedModule, NativeAnimatedHelper_default as default, generateNewAnimationId, generateNewNodeTag, isSupportedColorStyleProp, isSupportedInterpolationParam, isSupportedStyleProp, isSupportedTransformProp, shouldUseNativeDriver, transformDataType, validateInterpolation, validateStyles, validateTransform }; //# sourceMappingURL=NativeAnimatedHelper.mjs.map