@oxyhq/bloom 0.1.12 → 0.1.13

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.
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect } from 'react';
2
- import { ActivityIndicator, View, type ViewStyle } from 'react-native';
2
+ import { ActivityIndicator, type ViewStyle } from 'react-native';
3
3
 
4
4
  // Lazy-loaded dependencies for the SVG spinner.
5
5
  // Falls back to ActivityIndicator if react-native-svg or react-native-reanimated are not installed.
@@ -41,23 +41,22 @@ interface SpinnerIconProps {
41
41
  style?: ViewStyle;
42
42
  }
43
43
 
44
+ type AnimatedSpinnerProps = SpinnerIconProps & {
45
+ svg: NonNullable<SvgModuleType>;
46
+ reanimated: NonNullable<ReanimatedType>;
47
+ };
48
+
44
49
  /**
45
- * iOS-style SVG spinner with 8 rotating rectangles and an opacity gradient trail.
46
- * Requires react-native-svg and react-native-reanimated as peer dependencies.
47
- * Falls back to ActivityIndicator if either is missing.
50
+ * Inner component that unconditionally calls Reanimated hooks.
51
+ * Only rendered when both react-native-svg and react-native-reanimated are available.
48
52
  */
49
- export const SpinnerIcon: React.FC<SpinnerIconProps> = ({
53
+ const AnimatedSpinner: React.FC<AnimatedSpinnerProps> = ({
50
54
  color = '#005c67',
51
55
  size = 26,
52
56
  style,
57
+ svg,
58
+ reanimated,
53
59
  }) => {
54
- const svg = getSvgModule();
55
- const reanimated = getReanimated();
56
-
57
- if (!svg || !reanimated) {
58
- return <ActivityIndicator size={size > 30 ? 'large' : 'small'} color={color} />;
59
- }
60
-
61
60
  const { default: Svg, Rect } = svg;
62
61
  const {
63
62
  default: Animated,
@@ -68,19 +67,19 @@ export const SpinnerIcon: React.FC<SpinnerIconProps> = ({
68
67
  Easing,
69
68
  } = reanimated;
70
69
 
71
- // eslint-disable-next-line react-hooks/rules-of-hooks
72
70
  const rotation = useSharedValue(0);
73
71
 
74
- // eslint-disable-next-line react-hooks/rules-of-hooks
75
72
  useEffect(() => {
76
73
  rotation.value = withRepeat(
77
74
  withTiming(360, { duration: 400, easing: Easing.linear }),
78
75
  -1,
79
- false
76
+ false,
80
77
  );
81
- }, [rotation, withRepeat, withTiming, Easing]);
78
+ // Reanimated shared values are stable references; withRepeat/withTiming/Easing
79
+ // are module-level functions from the lazily-loaded module and are stable too.
80
+ // eslint-disable-next-line react-hooks/exhaustive-deps
81
+ }, []);
82
82
 
83
- // eslint-disable-next-line react-hooks/rules-of-hooks
84
83
  const animatedStyle = useAnimatedStyle(() => ({
85
84
  transform: [{ rotate: `${rotation.value}deg` }],
86
85
  }));
@@ -112,4 +111,32 @@ export const SpinnerIcon: React.FC<SpinnerIconProps> = ({
112
111
  );
113
112
  };
114
113
 
114
+ /**
115
+ * iOS-style SVG spinner with 8 rotating rectangles and an opacity gradient trail.
116
+ * Requires react-native-svg and react-native-reanimated as peer dependencies.
117
+ * Falls back to ActivityIndicator if either is missing.
118
+ */
119
+ export const SpinnerIcon: React.FC<SpinnerIconProps> = ({
120
+ color = '#005c67',
121
+ size = 26,
122
+ style,
123
+ }) => {
124
+ const svg = getSvgModule();
125
+ const reanimated = getReanimated();
126
+
127
+ if (!svg || !reanimated) {
128
+ return <ActivityIndicator size={size > 30 ? 'large' : 'small'} color={color} />;
129
+ }
130
+
131
+ return (
132
+ <AnimatedSpinner
133
+ color={color}
134
+ size={size}
135
+ style={style}
136
+ svg={svg}
137
+ reanimated={reanimated}
138
+ />
139
+ );
140
+ };
141
+
115
142
  SpinnerIcon.displayName = 'SpinnerIcon';