react-native-reanimated 4.3.0-rc.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.cpp +8 -5
  2. package/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h +3 -5
  3. package/Common/cpp/reanimated/CSS/common/values/CSSValueVariant.cpp +2 -3
  4. package/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.cpp +2 -3
  5. package/Common/cpp/reanimated/CSS/registries/CSSAnimationsRegistry.cpp +7 -3
  6. package/Common/cpp/reanimated/CSS/registries/CSSAnimationsRegistry.h +9 -2
  7. package/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.cpp +6 -2
  8. package/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.h +8 -2
  9. package/Common/cpp/reanimated/CSS/utils/DelayedItemsManager.cpp +2 -2
  10. package/Common/cpp/reanimated/CSS/utils/DelayedItemsManager.h +2 -2
  11. package/Common/cpp/reanimated/Compat/WorkletsApi.h +13 -0
  12. package/Common/cpp/reanimated/Events/UIEventHandler.cpp +1 -1
  13. package/Common/cpp/reanimated/Events/UIEventHandler.h +3 -4
  14. package/Common/cpp/reanimated/Events/UIEventHandlerRegistry.cpp +3 -2
  15. package/Common/cpp/reanimated/Events/UIEventHandlerRegistry.h +1 -1
  16. package/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.cpp +2 -8
  17. package/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.h +2 -6
  18. package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +1 -6
  19. package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +1 -8
  20. package/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp +12 -7
  21. package/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h +6 -3
  22. package/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.cpp +4 -6
  23. package/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.h +25 -7
  24. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h +1 -2
  25. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h +1 -1
  26. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp +9 -9
  27. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h +2 -3
  28. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp +21 -21
  29. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h +3 -3
  30. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.h +3 -3
  31. package/Common/cpp/reanimated/LayoutAnimations/SharedTransitions.cpp +24 -20
  32. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +35 -53
  33. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +1 -2
  34. package/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.cpp +22 -22
  35. package/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.h +10 -10
  36. package/Common/cpp/reanimated/Tools/ReaJSIUtils.h +5 -5
  37. package/README.md +1 -1
  38. package/android/build.gradle +0 -21
  39. package/android/src/main/cpp/reanimated/android/NativeProxy.cpp +6 -10
  40. package/android/src/main/cpp/reanimated/android/NativeProxy.h +1 -2
  41. package/android/src/main/java/com/swmansion/reanimated/CopiedEvent.java +66 -9
  42. package/android/src/main/java/com/swmansion/reanimated/NodesManager.java +16 -11
  43. package/android/src/main/java/com/swmansion/reanimated/nativeProxy/EventHandler.java +34 -8
  44. package/android/src/main/java/com/swmansion/reanimated/nativeProxy/NoopEventHandler.java +27 -6
  45. package/apple/reanimated/apple/REANodesManager.mm +0 -8
  46. package/apple/reanimated/apple/ReanimatedModule.mm +6 -12
  47. package/apple/reanimated/apple/native/NativeProxy.h +1 -2
  48. package/apple/reanimated/apple/native/NativeProxy.mm +1 -1
  49. package/compatibility.json +7 -29
  50. package/lib/module/PropsRegistryGarbageCollector.js +3 -0
  51. package/lib/module/PropsRegistryGarbageCollector.js.map +1 -1
  52. package/lib/module/common/style/processors/colors.js +31 -4
  53. package/lib/module/common/style/processors/colors.js.map +1 -1
  54. package/lib/module/common/style/processors/filter.js +103 -61
  55. package/lib/module/common/style/processors/filter.js.map +1 -1
  56. package/lib/module/common/style/processors/font.js +7 -1
  57. package/lib/module/common/style/processors/font.js.map +1 -1
  58. package/lib/module/common/style/processors/insets.js +26 -14
  59. package/lib/module/common/style/processors/insets.js.map +1 -1
  60. package/lib/module/common/style/processors/others.js +15 -5
  61. package/lib/module/common/style/processors/others.js.map +1 -1
  62. package/lib/module/common/style/processors/shadows.js +14 -3
  63. package/lib/module/common/style/processors/shadows.js.map +1 -1
  64. package/lib/module/common/style/processors/transform.js +30 -1
  65. package/lib/module/common/style/processors/transform.js.map +1 -1
  66. package/lib/module/common/style/processors/transformOrigin.js +20 -3
  67. package/lib/module/common/style/processors/transformOrigin.js.map +1 -1
  68. package/lib/module/common/utils/guards.js +27 -7
  69. package/lib/module/common/utils/guards.js.map +1 -1
  70. package/lib/module/common/utils/parsers.js +2 -1
  71. package/lib/module/common/utils/parsers.js.map +1 -1
  72. package/lib/module/createAnimatedComponent/AnimatedComponent.js +1 -7
  73. package/lib/module/createAnimatedComponent/AnimatedComponent.js.map +1 -1
  74. package/lib/module/css/native/managers/CSSManager.js +16 -15
  75. package/lib/module/css/native/managers/CSSManager.js.map +1 -1
  76. package/lib/module/css/native/managers/CSSTransitionsManager.js +47 -44
  77. package/lib/module/css/native/managers/CSSTransitionsManager.js.map +1 -1
  78. package/lib/module/css/native/normalization/transition/config.js +35 -17
  79. package/lib/module/css/native/normalization/transition/config.js.map +1 -1
  80. package/lib/module/css/utils/props.js +6 -0
  81. package/lib/module/css/utils/props.js.map +1 -1
  82. package/lib/module/featureFlags/index.js +1 -1
  83. package/lib/module/featureFlags/staticFlags.json +1 -1
  84. package/lib/module/hook/useAnimatedRef.js +2 -2
  85. package/lib/module/hook/useAnimatedRef.js.map +1 -1
  86. package/lib/module/hook/useAnimatedStyle.js +7 -1
  87. package/lib/module/hook/useAnimatedStyle.js.map +1 -1
  88. package/lib/module/hook/useHandler.js +82 -28
  89. package/lib/module/hook/useHandler.js.map +1 -1
  90. package/lib/module/hook/utils.js +1 -74
  91. package/lib/module/hook/utils.js.map +1 -1
  92. package/lib/module/initializers.js +2 -0
  93. package/lib/module/initializers.js.map +1 -1
  94. package/lib/module/jestUtils/common.js +10 -0
  95. package/lib/module/jestUtils/common.js.map +1 -1
  96. package/lib/module/jestUtils/index.js +2 -5
  97. package/lib/module/jestUtils/index.js.map +1 -1
  98. package/lib/module/jestUtils/index.web.js +1 -1
  99. package/lib/module/jestUtils/index.web.js.map +1 -1
  100. package/lib/module/mutables.js +5 -1
  101. package/lib/module/mutables.js.map +1 -1
  102. package/lib/module/platform-specific/jsVersion.js +1 -1
  103. package/lib/module/platform-specific/jsVersion.js.map +1 -1
  104. package/lib/typescript/PropsRegistryGarbageCollector.d.ts.map +1 -1
  105. package/lib/typescript/common/style/processors/colors.d.ts +3 -3
  106. package/lib/typescript/common/style/processors/colors.d.ts.map +1 -1
  107. package/lib/typescript/common/style/processors/filter.d.ts +0 -4
  108. package/lib/typescript/common/style/processors/filter.d.ts.map +1 -1
  109. package/lib/typescript/common/style/processors/font.d.ts +1 -1
  110. package/lib/typescript/common/style/processors/font.d.ts.map +1 -1
  111. package/lib/typescript/common/style/processors/insets.d.ts.map +1 -1
  112. package/lib/typescript/common/style/processors/others.d.ts +1 -1
  113. package/lib/typescript/common/style/processors/others.d.ts.map +1 -1
  114. package/lib/typescript/common/style/processors/shadows.d.ts.map +1 -1
  115. package/lib/typescript/common/style/processors/transform.d.ts.map +1 -1
  116. package/lib/typescript/common/style/processors/transformOrigin.d.ts +2 -2
  117. package/lib/typescript/common/style/processors/transformOrigin.d.ts.map +1 -1
  118. package/lib/typescript/common/utils/guards.d.ts +0 -1
  119. package/lib/typescript/common/utils/guards.d.ts.map +1 -1
  120. package/lib/typescript/common/utils/parsers.d.ts.map +1 -1
  121. package/lib/typescript/commonTypes.d.ts +1 -1
  122. package/lib/typescript/commonTypes.d.ts.map +1 -1
  123. package/lib/typescript/createAnimatedComponent/AnimatedComponent.d.ts.map +1 -1
  124. package/lib/typescript/css/native/managers/CSSManager.d.ts +7 -1
  125. package/lib/typescript/css/native/managers/CSSManager.d.ts.map +1 -1
  126. package/lib/typescript/css/native/managers/CSSTransitionsManager.d.ts +5 -4
  127. package/lib/typescript/css/native/managers/CSSTransitionsManager.d.ts.map +1 -1
  128. package/lib/typescript/css/native/normalization/transition/config.d.ts.map +1 -1
  129. package/lib/typescript/css/native/types/transition.d.ts +15 -1
  130. package/lib/typescript/css/native/types/transition.d.ts.map +1 -1
  131. package/lib/typescript/css/utils/props.d.ts.map +1 -1
  132. package/lib/typescript/featureFlags/index.d.ts +1 -1
  133. package/lib/typescript/hook/useAnimatedStyle.d.ts.map +1 -1
  134. package/lib/typescript/hook/useHandler.d.ts +8 -9
  135. package/lib/typescript/hook/useHandler.d.ts.map +1 -1
  136. package/lib/typescript/hook/utils.d.ts +0 -5
  137. package/lib/typescript/hook/utils.d.ts.map +1 -1
  138. package/lib/typescript/jestUtils/common.d.ts +2 -0
  139. package/lib/typescript/jestUtils/common.d.ts.map +1 -1
  140. package/lib/typescript/jestUtils/index.d.ts +4 -3
  141. package/lib/typescript/jestUtils/index.d.ts.map +1 -1
  142. package/lib/typescript/mutables.d.ts.map +1 -1
  143. package/lib/typescript/platform-specific/jsVersion.d.ts +1 -1
  144. package/lib/typescript/platform-specific/jsVersion.d.ts.map +1 -1
  145. package/package.json +13 -10
  146. package/src/PropsRegistryGarbageCollector.ts +3 -0
  147. package/src/common/style/processors/colors.ts +20 -7
  148. package/src/common/style/processors/filter.ts +95 -70
  149. package/src/common/style/processors/font.ts +5 -2
  150. package/src/common/style/processors/insets.ts +23 -14
  151. package/src/common/style/processors/others.ts +12 -6
  152. package/src/common/style/processors/shadows.ts +10 -6
  153. package/src/common/style/processors/transform.ts +15 -1
  154. package/src/common/style/processors/transformOrigin.ts +40 -11
  155. package/src/common/utils/guards.ts +21 -16
  156. package/src/common/utils/parsers.ts +1 -1
  157. package/src/commonTypes.ts +1 -1
  158. package/src/createAnimatedComponent/AnimatedComponent.tsx +1 -7
  159. package/src/css/native/managers/CSSManager.ts +29 -14
  160. package/src/css/native/managers/CSSTransitionsManager.ts +52 -54
  161. package/src/css/native/normalization/transition/config.ts +35 -27
  162. package/src/css/native/types/transition.ts +15 -1
  163. package/src/css/utils/props.ts +7 -0
  164. package/src/featureFlags/index.ts +1 -1
  165. package/src/featureFlags/staticFlags.json +1 -1
  166. package/src/hook/useAnimatedRef.ts +2 -2
  167. package/src/hook/useAnimatedStyle.ts +15 -6
  168. package/src/hook/useHandler.ts +150 -64
  169. package/src/hook/utils.ts +1 -127
  170. package/src/initializers.ts +1 -0
  171. package/src/jestUtils/common.ts +10 -0
  172. package/src/jestUtils/index.ts +5 -8
  173. package/src/jestUtils/index.web.ts +1 -1
  174. package/src/mutables.ts +5 -1
  175. package/src/platform-specific/jsVersion.ts +1 -1
  176. package/src/privateGlobals.d.ts +4 -0
@@ -1,5 +1,4 @@
1
1
  'use strict';
2
- 'worklet';
3
2
  import type {
4
3
  DynamicColorIOS as RNDynamicColorIOS,
5
4
  OpaqueColorValue,
@@ -17,6 +16,7 @@ import { isRecord } from '../../utils';
17
16
  * https://github.com/facebook/react-native/blob/v0.81.0/packages/react-native/Libraries/StyleSheet/PlatformColorValueTypes.d.ts
18
17
  */
19
18
  export function PlatformColor(...names: string[]): OpaqueColorValue {
19
+ 'worklet';
20
20
  return (IS_IOS
21
21
  ? { semantic: names }
22
22
  : // eslint-disable-next-line camelcase
@@ -28,6 +28,7 @@ type PlatformColorObject =
28
28
  | { semantic?: never; resource_paths?: Array<string> };
29
29
 
30
30
  function isPlatformColorObject(value: unknown): value is PlatformColorObject {
31
+ 'worklet';
31
32
  return (
32
33
  isRecord(value) &&
33
34
  (Array.isArray(value.semantic) || Array.isArray(value.resource_paths))
@@ -40,6 +41,7 @@ function isPlatformColorObject(value: unknown): value is PlatformColorObject {
40
41
  type DynamicColorIOSTuple = Parameters<typeof RNDynamicColorIOS>[0];
41
42
 
42
43
  export function DynamicColorIOS(tuple: DynamicColorIOSTuple): OpaqueColorValue {
44
+ 'worklet';
43
45
  return {
44
46
  dynamic: {
45
47
  light: tuple.light,
@@ -57,6 +59,7 @@ type DynamicColorObjectIOS = {
57
59
  function isDynamicColorObjectIOS(
58
60
  value: unknown
59
61
  ): value is DynamicColorObjectIOS {
62
+ 'worklet';
60
63
  return (
61
64
  isRecord(value) &&
62
65
  isRecord(value.dynamic) &&
@@ -66,15 +69,22 @@ function isDynamicColorObjectIOS(
66
69
  }
67
70
 
68
71
  export const ERROR_MESSAGES = {
69
- invalidColor: (color: unknown) =>
70
- `Invalid color value: ${JSON.stringify(color)}`,
71
- invalidProcessedColor: (color: unknown) =>
72
- `Invalid processed color value: ${JSON.stringify(color)}`,
73
- dynamicNotAvailableOnPlatform: () =>
74
- 'DynamicColorIOS is not available on this platform.',
72
+ invalidColor(color: unknown) {
73
+ 'worklet';
74
+ return `Invalid color value: ${JSON.stringify(color)}`;
75
+ },
76
+ invalidProcessedColor(color: unknown) {
77
+ 'worklet';
78
+ return `Invalid processed color value: ${JSON.stringify(color)}`;
79
+ },
80
+ dynamicNotAvailableOnPlatform() {
81
+ 'worklet';
82
+ return 'DynamicColorIOS is not available on this platform.';
83
+ },
75
84
  };
76
85
 
77
86
  export function processColorNumber(value: unknown): number | null {
87
+ 'worklet';
78
88
  let normalizedColor = processColorInitially(value);
79
89
 
80
90
  if (IS_ANDROID && typeof normalizedColor == 'number') {
@@ -115,6 +125,7 @@ const DynamicColorIOSProperties = [
115
125
  function processDynamicColorObjectIOS(
116
126
  value: DynamicColorObjectIOS
117
127
  ): ProcessedDynamicColorObjectIOS | null {
128
+ 'worklet';
118
129
  const result = {} as ProcessedDynamicColorObjectIOS['dynamic'];
119
130
 
120
131
  for (const property of DynamicColorIOSProperties) {
@@ -176,6 +187,7 @@ export function processColor(
176
187
  value: unknown,
177
188
  context?: ValueProcessorContext
178
189
  ): ProcessedColor {
190
+ 'worklet';
179
191
  let result: ProcessedColor | null = processColorNumber(value); // try to convert to a number first (most common case)
180
192
 
181
193
  if (result) {
@@ -229,6 +241,7 @@ export function unprocessColor(
229
241
  }
230
242
 
231
243
  export function processColorsInProps(props: StyleProps) {
244
+ 'worklet';
232
245
  for (const key in props) {
233
246
  if (!ColorProperties.includes(key)) continue;
234
247
  const value = props[key];
@@ -1,8 +1,6 @@
1
1
  'use strict';
2
- 'worklet';
3
2
  import type { DropShadowValue, FilterFunction } from 'react-native';
4
3
 
5
- import { ReanimatedError } from '../../errors';
6
4
  import type {
7
5
  FilterArray,
8
6
  ParsedDropShadow,
@@ -20,67 +18,56 @@ const FILTER_VALUE_REGEX = /^([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)([a-z%]*)$/;
20
18
  // Capture drop-shadow parts "10px 5px 5px #888888" => ["10px", "5px", "5px", "#888888"]
21
19
  const DROP_SHADOW_REGEX = /[^,\s()]+(?:\([^()]*\))?/g;
22
20
 
23
- export const ERROR_MESSAGES = {
24
- invalidFilter: (filter: string) => `Invalid filter property: ${filter}`,
25
- invalidFilterType: (filter: readonly FilterFunction[]) =>
26
- `Invalid filter input type: ${typeof filter}. Expected string or array.`,
27
- };
28
-
29
21
  type SingleFilterValue = {
30
22
  numberValue: number;
31
23
  unit: string;
32
24
  };
33
25
 
34
- const parseHueRotate = (value: SingleFilterValue): number | undefined => {
26
+ const parseHueRotate = (value: SingleFilterValue): number | null => {
27
+ 'worklet';
35
28
  const { numberValue, unit } = value;
36
- if (numberValue === 0) {
37
- return 0;
38
- }
39
- if (unit !== 'deg' && unit !== 'rad') {
40
- throw new ReanimatedError(
41
- ERROR_MESSAGES.invalidFilter(`hueRotate(${numberValue}${unit})`)
42
- );
29
+ if (numberValue !== 0 && unit !== 'deg' && unit !== 'rad') {
30
+ return null;
43
31
  }
44
32
  return unit === 'rad' ? (180 * numberValue) / Math.PI : numberValue;
45
33
  };
46
34
 
47
- const parseBlur = (value: SingleFilterValue): number | undefined => {
35
+ const parseBlur = (value: SingleFilterValue): number | null => {
36
+ 'worklet';
48
37
  const { numberValue, unit } = value;
49
38
  if ((unit && unit !== 'px') || numberValue < 0) {
50
- return undefined;
39
+ return null;
51
40
  }
52
41
  return numberValue;
53
42
  };
54
43
 
55
- const parsePercentageFilter = (
56
- value: SingleFilterValue
57
- ): number | undefined => {
44
+ const parsePercentageFilter = (value: SingleFilterValue): number | null => {
45
+ 'worklet';
58
46
  const { numberValue, unit } = value;
59
47
  if ((unit && unit !== '%') || numberValue < 0) {
60
- return undefined;
48
+ return null;
61
49
  }
62
50
  return unit === '%' ? numberValue / 100 : numberValue;
63
51
  };
64
52
 
65
53
  const LENGTH_MAPPINGS = ['offsetX', 'offsetY', 'standardDeviation'] as const;
66
54
 
67
- const parseDropShadowString = (value: string) => {
55
+ const parseDropShadowString = (value: string): DropShadowValue | null => {
56
+ 'worklet';
68
57
  const match = value.match(DROP_SHADOW_REGEX) ?? [];
69
58
  const result: DropShadowValue = { offsetX: 0, offsetY: 0 };
70
59
  let foundLengthsCount = 0;
71
60
 
72
- match.forEach((part) => {
61
+ for (const part of match) {
73
62
  if (isLength(part)) {
74
- if (__DEV__ && !part.trim().match(FILTER_VALUE_REGEX)) {
75
- throw new ReanimatedError(
76
- ERROR_MESSAGES.invalidFilter(`dropShadow(${value})`)
77
- );
63
+ if (!part.trim().match(FILTER_VALUE_REGEX)) {
64
+ return null;
78
65
  }
79
66
  result[LENGTH_MAPPINGS[foundLengthsCount++]] = parseFloat(part);
80
67
  } else {
81
68
  result.color = part.trim();
82
69
  }
83
- });
70
+ }
84
71
 
85
72
  return result;
86
73
  };
@@ -88,9 +75,13 @@ const parseDropShadowString = (value: string) => {
88
75
  const parseDropShadow = (
89
76
  value: string | DropShadowValue,
90
77
  context: ValueProcessorContext | undefined
91
- ): ParsedDropShadow => {
78
+ ): ParsedDropShadow | null => {
79
+ 'worklet';
92
80
  const dropShadow =
93
81
  typeof value === 'string' ? parseDropShadowString(value) : value;
82
+ if (dropShadow === null) {
83
+ return null;
84
+ }
94
85
  const {
95
86
  color = '#000',
96
87
  offsetX = 0,
@@ -98,14 +89,22 @@ const parseDropShadow = (
98
89
  standardDeviation = 0,
99
90
  } = dropShadow;
100
91
 
92
+ const parsedStdDev = parseFloat(standardDeviation as string);
93
+ if (parsedStdDev < 0) {
94
+ return null;
95
+ }
96
+
101
97
  const processedColor = processColor(color, context);
98
+ if (processedColor === null) {
99
+ return null;
100
+ }
102
101
 
103
102
  return {
104
103
  // TODO - add support for IOS dynamic colors in CSS (for now we just assume that it's a number)
105
104
  color: processedColor as number,
106
105
  offsetX: parseFloat(offsetX as string),
107
106
  offsetY: parseFloat(offsetY as string),
108
- standardDeviation: parseFloat(standardDeviation as string),
107
+ standardDeviation: parsedStdDev,
109
108
  };
110
109
  };
111
110
 
@@ -113,37 +112,49 @@ const parseFilterProperty = (
113
112
  filterName: string,
114
113
  filterValue: string | number | DropShadowValue,
115
114
  context: ValueProcessorContext | undefined
116
- ): ParsedFilterFunction => {
115
+ ): ParsedFilterFunction | null => {
116
+ 'worklet';
117
117
  // We need to handle dropShadow separately because of its complex structure
118
- if (filterName == 'dropShadow') {
119
- return {
120
- dropShadow: parseDropShadow(
121
- filterValue as string | DropShadowValue,
122
- context
123
- ),
124
- };
118
+ if (filterName === 'dropShadow') {
119
+ const dropShadow = parseDropShadow(
120
+ filterValue as string | DropShadowValue,
121
+ context
122
+ );
123
+ if (dropShadow === null) {
124
+ return null;
125
+ }
126
+ return { dropShadow };
125
127
  }
126
128
 
127
- if (isNumber(filterValue)) {
128
- return { [filterName]: filterValue };
129
- }
129
+ let numberValue: number;
130
+ let unit: string;
130
131
 
131
- const stringValue = filterValue as string;
132
- const match = stringValue.match(FILTER_VALUE_REGEX);
133
- if (!match) {
134
- throw new ReanimatedError(
135
- ERROR_MESSAGES.invalidFilter(`${filterName}(${stringValue})`)
136
- );
132
+ if (isNumber(filterValue)) {
133
+ // Numeric hueRotate values are treated as degrees.
134
+ // Unit validation only applies to string values like 'hueRotate(90deg)'.
135
+ if (filterName === 'hueRotate') {
136
+ return { hueRotate: filterValue };
137
+ }
138
+ numberValue = filterValue;
139
+ unit = '';
140
+ } else {
141
+ const stringValue = filterValue as string;
142
+ const match = stringValue.match(FILTER_VALUE_REGEX);
143
+ if (!match) {
144
+ return null;
145
+ }
146
+ numberValue = parseFloat(match[1]);
147
+ unit = match[2];
137
148
  }
138
149
 
139
- const numberValue = parseFloat(match[1]);
140
- const unit = match[2];
141
-
150
+ let amount: number | null;
142
151
  switch (filterName) {
143
152
  case 'hueRotate':
144
- return { hueRotate: parseHueRotate({ numberValue, unit }) };
153
+ amount = parseHueRotate({ numberValue, unit });
154
+ break;
145
155
  case 'blur':
146
- return { blur: parseBlur({ numberValue, unit }) };
156
+ amount = parseBlur({ numberValue, unit });
157
+ break;
147
158
  case 'brightness':
148
159
  case 'contrast':
149
160
  case 'grayscale':
@@ -151,32 +162,39 @@ const parseFilterProperty = (
151
162
  case 'opacity':
152
163
  case 'saturate':
153
164
  case 'sepia':
154
- return { [filterName]: parsePercentageFilter({ numberValue, unit }) };
165
+ amount = parsePercentageFilter({ numberValue, unit });
166
+ break;
155
167
  default:
156
- throw new ReanimatedError(
157
- ERROR_MESSAGES.invalidFilter(`${filterName}(${stringValue})`)
158
- );
168
+ return null;
159
169
  }
170
+
171
+ if (amount === null) {
172
+ return null;
173
+ }
174
+
175
+ return { [filterName]: amount };
160
176
  };
161
177
 
162
178
  const parseFilterString = (
163
179
  value: string,
164
180
  context: ValueProcessorContext | undefined
165
181
  ): FilterArray => {
182
+ 'worklet';
166
183
  const matches = Array.from(value.matchAll(FILTER_REGEX));
167
184
 
168
- if (matches.length === 0) {
169
- throw new ReanimatedError(ERROR_MESSAGES.invalidFilter(value));
170
- }
171
-
172
- const filterArray = matches.map((match) => {
173
- const [filter, name, content] = match;
185
+ const filterArray: FilterArray = [];
186
+ for (const match of matches) {
187
+ const [, name, content] = match;
174
188
  if (!name || !content) {
175
- throw new ReanimatedError(ERROR_MESSAGES.invalidFilter(filter));
189
+ return [];
176
190
  }
177
191
 
178
- return parseFilterProperty(name, content, context);
179
- });
192
+ const parsed = parseFilterProperty(name, content, context);
193
+ if (parsed === null) {
194
+ return [];
195
+ }
196
+ filterArray.push(parsed);
197
+ }
180
198
  return filterArray;
181
199
  };
182
200
 
@@ -184,16 +202,23 @@ export const processFilter: ValueProcessor<
184
202
  ReadonlyArray<FilterFunction> | string,
185
203
  FilterArray
186
204
  > = (value, context) => {
205
+ 'worklet';
187
206
  if (typeof value === 'string') {
188
207
  return parseFilterString(value, context);
189
208
  }
190
209
 
191
210
  if (Array.isArray(value)) {
192
- return value.map((filter) => {
211
+ const filterArray: FilterArray = [];
212
+ for (const filter of value) {
193
213
  const filterKey = Object.keys(filter)[0];
194
- return parseFilterProperty(filterKey, filter[filterKey], context);
195
- });
214
+ const parsed = parseFilterProperty(filterKey, filter[filterKey], context);
215
+ if (parsed === null) {
216
+ return [];
217
+ }
218
+ filterArray.push(parsed);
219
+ }
220
+ return filterArray;
196
221
  }
197
222
 
198
- throw new ReanimatedError(ERROR_MESSAGES.invalidFilterType(value));
223
+ return [];
199
224
  };
@@ -4,8 +4,10 @@ import { ReanimatedError } from '../../errors';
4
4
  import type { ValueProcessor } from '../../types';
5
5
 
6
6
  export const ERROR_MESSAGES = {
7
- invalidFontWeight: (weight: string | number) =>
8
- `Invalid font weight value: ${weight}`,
7
+ invalidFontWeight(weight: string | number) {
8
+ 'worklet';
9
+ return `Invalid font weight value: ${weight}`;
10
+ },
9
11
  };
10
12
 
11
13
  const VALID_FONT_WEIGHTS = new Set<string>(Object.values(FONT_WEIGHT_MAPPINGS));
@@ -13,6 +15,7 @@ const VALID_FONT_WEIGHTS = new Set<string>(Object.values(FONT_WEIGHT_MAPPINGS));
13
15
  export const processFontWeight: ValueProcessor<string | number, string> = (
14
16
  value
15
17
  ) => {
18
+ 'worklet';
16
19
  const stringValue = value.toString();
17
20
 
18
21
  if (VALID_FONT_WEIGHTS.has(stringValue)) {
@@ -8,19 +8,28 @@ type InsetProcessor = ValueProcessor<
8
8
  Record<string, DimensionValue>
9
9
  >;
10
10
 
11
- export const processInset: InsetProcessor = (value) => ({
12
- top: value,
13
- bottom: value,
14
- left: value,
15
- right: value,
16
- });
11
+ export const processInset: InsetProcessor = (value) => {
12
+ 'worklet';
13
+ return {
14
+ top: value,
15
+ bottom: value,
16
+ left: value,
17
+ right: value,
18
+ };
19
+ };
17
20
 
18
- export const processInsetBlock: InsetProcessor = (value) => ({
19
- top: value,
20
- bottom: value,
21
- });
21
+ export const processInsetBlock: InsetProcessor = (value) => {
22
+ 'worklet';
23
+ return {
24
+ top: value,
25
+ bottom: value,
26
+ };
27
+ };
22
28
 
23
- export const processInsetInline: InsetProcessor = (value) => ({
24
- left: value,
25
- right: value,
26
- });
29
+ export const processInsetInline: InsetProcessor = (value) => {
30
+ 'worklet';
31
+ return {
32
+ left: value,
33
+ right: value,
34
+ };
35
+ };
@@ -3,11 +3,14 @@ import { ReanimatedError } from '../../errors';
3
3
  import type { ValueProcessor } from '../../types';
4
4
 
5
5
  export const ERROR_MESSAGES = {
6
- unsupportedAspectRatio: (ratio: string | number) =>
7
- `Unsupported aspect ratio: ${ratio}. Expected a number or a string in "a/b" format.`,
6
+ unsupportedAspectRatio(ratio: string | number) {
7
+ 'worklet';
8
+ return `Unsupported aspect ratio: ${ratio}. Expected a number or a string in "a/b" format.`;
9
+ },
8
10
  };
9
11
 
10
12
  export const processAspectRatio: ValueProcessor<number | string> = (value) => {
13
+ 'worklet';
11
14
  if (typeof value === 'number' || !isNaN(+value)) {
12
15
  return +value;
13
16
  } else if (typeof value === 'string') {
@@ -24,7 +27,10 @@ export const processAspectRatio: ValueProcessor<number | string> = (value) => {
24
27
  throw new ReanimatedError(ERROR_MESSAGES.unsupportedAspectRatio(value));
25
28
  };
26
29
 
27
- export const processGap: ValueProcessor<number | string> = (value) => ({
28
- rowGap: value,
29
- columnGap: value,
30
- });
30
+ export const processGap: ValueProcessor<number | string> = (value) => {
31
+ 'worklet';
32
+ return {
33
+ rowGap: value,
34
+ columnGap: value,
35
+ };
36
+ };
@@ -1,5 +1,4 @@
1
1
  'use strict';
2
- 'worklet';
3
2
  import type { BoxShadowValue } from 'react-native';
4
3
 
5
4
  import { IS_ANDROID } from '../../constants';
@@ -9,11 +8,14 @@ import { parseBoxShadowString } from '../../utils';
9
8
  import { processColor } from './colors';
10
9
 
11
10
  const ERROR_MESSAGES = {
12
- notArrayObject: (value: object) =>
13
- `Box shadow value must be a string or an array of shadow objects (e.g. [{ offsetX, offsetY, color }]). Received: ${JSON.stringify(value)}.`,
14
-
15
- invalidColor: (color: string, boxShadow: string) =>
16
- `Invalid color "${color}" in box shadow "${boxShadow}".`,
11
+ notArrayObject(value: object) {
12
+ 'worklet';
13
+ return `Box shadow value must be a string or an array of shadow objects (e.g. [{ offsetX, offsetY, color }]). Received: ${JSON.stringify(value)}.`;
14
+ },
15
+ invalidColor(color: string, boxShadow: string) {
16
+ 'worklet';
17
+ return `Invalid color "${color}" in box shadow "${boxShadow}".`;
18
+ },
17
19
  };
18
20
 
19
21
  export type ProcessedBoxShadowValue = {
@@ -26,6 +28,7 @@ export type ProcessedBoxShadowValue = {
26
28
  };
27
29
 
28
30
  const parseBlurRadius = (value: string) => {
31
+ 'worklet';
29
32
  if (IS_ANDROID) {
30
33
  // Android crashes when blurRadius is smaller than 1
31
34
  return Math.max(parseFloat(value), 1);
@@ -37,6 +40,7 @@ export const processBoxShadow: ValueProcessor<
37
40
  ReadonlyArray<BoxShadowValue> | string,
38
41
  ProcessedBoxShadowValue[] | undefined
39
42
  > = (value, context) => {
43
+ 'worklet';
40
44
  if (value === 'none') {
41
45
  return;
42
46
  }
@@ -1,5 +1,4 @@
1
1
  'use strict';
2
- 'worklet';
3
2
  import { ReanimatedError } from '../../errors';
4
3
  import type { TransformsArray, ValueProcessor } from '../../types';
5
4
  import { isAngle, isNumber, isNumberArray, isPercentage } from '../../utils';
@@ -10,6 +9,7 @@ export const ERROR_MESSAGES = {
10
9
  };
11
10
 
12
11
  function parseValues(valueString: string): (string | number)[] {
12
+ 'worklet';
13
13
  return valueString.split(',').map((value) => {
14
14
  const trimmedValue = value.trim();
15
15
  if (['deg', 'rad', '%'].some((unit) => trimmedValue.endsWith(unit))) {
@@ -21,18 +21,21 @@ function parseValues(valueString: string): (string | number)[] {
21
21
  }
22
22
 
23
23
  function parseTranslateX(values: (number | string)[]): TransformsArray {
24
+ 'worklet';
24
25
  return values.length === 1 && (isNumber(values[0]) || isPercentage(values[0]))
25
26
  ? [{ translateX: values[0] }]
26
27
  : [];
27
28
  }
28
29
 
29
30
  function parseTranslateY(values: (number | string)[]): TransformsArray {
31
+ 'worklet';
30
32
  return values.length === 1 && (isNumber(values[0]) || isPercentage(values[0]))
31
33
  ? [{ translateY: values[0] }]
32
34
  : [];
33
35
  }
34
36
 
35
37
  function parseTranslate(values: (number | string)[]): TransformsArray {
38
+ 'worklet';
36
39
  if (values.length > 2) {
37
40
  return [];
38
41
  }
@@ -43,18 +46,21 @@ function parseTranslate(values: (number | string)[]): TransformsArray {
43
46
  }
44
47
 
45
48
  function parseScaleX(values: (number | string)[]): TransformsArray {
49
+ 'worklet';
46
50
  return values.length === 1 && isNumber(values[0])
47
51
  ? [{ scaleX: values[0] }]
48
52
  : [];
49
53
  }
50
54
 
51
55
  function parseScaleY(values: (number | string)[]): TransformsArray {
56
+ 'worklet';
52
57
  return values.length === 1 && isNumber(values[0])
53
58
  ? [{ scaleY: values[0] }]
54
59
  : [];
55
60
  }
56
61
 
57
62
  function parseScale(values: (number | string)[]): TransformsArray {
63
+ 'worklet';
58
64
  if (values.length > 2) {
59
65
  return [];
60
66
  }
@@ -71,6 +77,7 @@ function parseRotate(
71
77
  key: string,
72
78
  values: (string | number)[]
73
79
  ): TransformsArray {
80
+ 'worklet';
74
81
  return values.length === 1 && (isAngle(values[0]) || values[0] === 0)
75
82
  ? ([
76
83
  { [key]: values[0] === 0 ? '0deg' : values[0] },
@@ -79,18 +86,21 @@ function parseRotate(
79
86
  }
80
87
 
81
88
  function parseSkewX(values: (number | string)[]): TransformsArray {
89
+ 'worklet';
82
90
  return values.length === 1 && (isAngle(values[0]) || values[0] === 0)
83
91
  ? [{ skewX: values[0] === 0 ? '0deg' : values[0] }]
84
92
  : [];
85
93
  }
86
94
 
87
95
  function parseSkewY(values: (number | string)[]): TransformsArray {
96
+ 'worklet';
88
97
  return values.length === 1 && (isAngle(values[0]) || values[0] === 0)
89
98
  ? [{ skewY: values[0] === 0 ? '0deg' : values[0] }]
90
99
  : [];
91
100
  }
92
101
 
93
102
  function parseSkew(values: (number | string)[]): TransformsArray {
103
+ 'worklet';
94
104
  if (values.length > 2) {
95
105
  return [];
96
106
  }
@@ -101,6 +111,7 @@ function parseSkew(values: (number | string)[]): TransformsArray {
101
111
  }
102
112
 
103
113
  function parseMatrix(values: (number | string)[]): TransformsArray {
114
+ 'worklet';
104
115
  let matrixValues: number[] = [];
105
116
 
106
117
  if (isNumberArray(values)) {
@@ -121,12 +132,14 @@ function parseMatrix(values: (number | string)[]): TransformsArray {
121
132
  }
122
133
 
123
134
  function parsePerspective(values: (number | string)[]): TransformsArray {
135
+ 'worklet';
124
136
  return values.length === 1 && isNumber(values[0])
125
137
  ? [{ perspective: values[0] }]
126
138
  : [];
127
139
  }
128
140
 
129
141
  const parseTransformProperty = (transform: string): TransformsArray => {
142
+ 'worklet';
130
143
  const [key, valueString] = transform.split(/\(\s*/);
131
144
  const values = parseValues(valueString.replace(/\)$/g, ''));
132
145
 
@@ -166,6 +179,7 @@ const parseTransformProperty = (transform: string): TransformsArray => {
166
179
  export const processTransform: ValueProcessor<TransformsArray | string> = (
167
180
  value
168
181
  ) => {
182
+ 'worklet';
169
183
  if (typeof value !== 'string') {
170
184
  return value;
171
185
  }