@momo-kits/foundation 0.162.2-sp.1 → 0.162.2-sp.2

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.
@@ -8,7 +8,7 @@ import { type HeaderAnimatedProps } from '../types';
8
8
  import React from 'react';
9
9
  import { Image } from '../../Image';
10
10
  import { Colors } from '../../Consts';
11
- import { useNormalizedSharedValue } from './useAnimatedCompat';
11
+ import { useNormalizedSharedValue } from '../utils';
12
12
 
13
13
  const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
14
14
  animatedValue,
@@ -7,7 +7,7 @@ import { ApplicationContext, MiniAppContext } from '../../Context';
7
7
  import { Colors, Styles } from '../../Consts';
8
8
  import { Image } from '../../Image';
9
9
  import BackgroundImageView from './BackgroundImageView';
10
- import { useNormalizedSharedValue } from './useAnimatedCompat';
10
+ import { useNormalizedSharedValue } from '../utils';
11
11
 
12
12
  const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
13
13
  animatedValue,
@@ -17,7 +17,7 @@ import BackgroundImageView from './BackgroundImageView';
17
17
  import {
18
18
  AnimatedCompatValue,
19
19
  useNormalizedSharedValue,
20
- } from './useAnimatedCompat';
20
+ } from '../utils';
21
21
 
22
22
  const SCREEN_PADDING = 12;
23
23
  const BACK_WIDTH = 28;
@@ -24,7 +24,7 @@ import { Skeleton } from '../../Skeleton';
24
24
  import {
25
25
  AnimatedCompatValue,
26
26
  useNormalizedSharedValue,
27
- } from './useAnimatedCompat';
27
+ } from '../utils';
28
28
 
29
29
  type HeaderTitleInterpolate = {
30
30
  inputRange: number[];
@@ -11,7 +11,7 @@ import React, { useContext } from 'react';
11
11
  import { SearchHeaderProps } from '../types';
12
12
  import { ApplicationContext, MiniAppContext } from '../../Context';
13
13
  import { Text } from '../../Text';
14
- import { useNormalizedSharedValue } from './useAnimatedCompat';
14
+ import { useNormalizedSharedValue } from '../utils';
15
15
 
16
16
  const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
17
17
  (
@@ -5,8 +5,9 @@ import {
5
5
  } from '@react-navigation/stack';
6
6
  import type { HeaderTitleProps, NavigationOptions } from './types';
7
7
  import { Colors, Spacing } from '../Consts';
8
- import { AppState, Platform } from 'react-native';
8
+ import { Animated, AppState, Platform } from 'react-native';
9
9
  import type { SharedValue } from 'react-native-reanimated';
10
+ import { useSharedValue } from 'react-native-reanimated';
10
11
  import {
11
12
  MiniAppContext,
12
13
  ScreenContext,
@@ -229,6 +230,43 @@ const useAppState = () => {
229
230
  };
230
231
  };
231
232
 
233
+ /**
234
+ * Union of the two animation runtimes an internal foundation component might
235
+ * receive. Public Screen props still accept React Native Animated.Value only;
236
+ * this type keeps lower-level header/floating components compatible while they
237
+ * render with reanimated.
238
+ */
239
+ export type AnimatedCompatValue = Animated.Value | SharedValue<number>;
240
+
241
+ const isRNAnimatedValue = (v: unknown): v is Animated.Value =>
242
+ !!v &&
243
+ typeof (v as Animated.Value).setValue === 'function' &&
244
+ typeof (v as Animated.Value).interpolate === 'function';
245
+
246
+ const isSharedValue = (v: unknown): v is SharedValue<number> =>
247
+ !!v && !isRNAnimatedValue(v) && 'value' in (v as object);
248
+
249
+ const useNormalizedSharedValue = (
250
+ input?: AnimatedCompatValue,
251
+ ): SharedValue<number> => {
252
+ const fallback = useSharedValue(0);
253
+
254
+ useEffect(() => {
255
+ if (!isRNAnimatedValue(input)) {
256
+ return;
257
+ }
258
+ const id = input.addListener(({ value }) => {
259
+ fallback.value = value;
260
+ });
261
+ return () => input.removeListener(id);
262
+ }, [input, fallback]);
263
+
264
+ if (isSharedValue(input)) {
265
+ return input;
266
+ }
267
+ return fallback;
268
+ };
269
+
232
270
  export {
233
271
  getStackOptions,
234
272
  getModalOptions,
@@ -237,4 +275,5 @@ export {
237
275
  setAutomationID,
238
276
  useComponentId,
239
277
  useAppState,
278
+ useNormalizedSharedValue,
240
279
  };
@@ -18,7 +18,7 @@ import { useScaleSize } from '../Text';
18
18
  import {
19
19
  AnimatedCompatValue,
20
20
  useNormalizedSharedValue,
21
- } from '../Application/Components/useAnimatedCompat';
21
+ } from '../Application/utils';
22
22
 
23
23
  export interface FloatingButtonProps {
24
24
  label?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.162.2-sp.1",
3
+ "version": "0.162.2-sp.2",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},
@@ -1,63 +0,0 @@
1
- import { useEffect } from 'react';
2
- import { Animated } from 'react-native';
3
- import { useSharedValue, type SharedValue } from 'react-native-reanimated';
4
-
5
- /**
6
- * Union of the two animation runtimes a consumer might hand to a foundation
7
- * component. react-native `Animated.Value` (legacy) and reanimated
8
- * `SharedValue` are different objects and cannot be used interchangeably, so
9
- * foundation components normalize whatever they receive into a `SharedValue`
10
- * via {@link useNormalizedSharedValue} before rendering with reanimated.
11
- */
12
- export type AnimatedCompatValue = Animated.Value | SharedValue<number>;
13
-
14
- /**
15
- * A react-native `Animated.Value` exposes `setValue`/`interpolate` methods; a
16
- * reanimated `SharedValue` does not.
17
- */
18
- export const isRNAnimatedValue = (v: unknown): v is Animated.Value =>
19
- !!v &&
20
- typeof (v as Animated.Value).setValue === 'function' &&
21
- typeof (v as Animated.Value).interpolate === 'function';
22
-
23
- /**
24
- * Heuristic: a reanimated `SharedValue` carries a `value` accessor but none of
25
- * the `Animated.Value` methods.
26
- */
27
- export const isSharedValue = (v: unknown): v is SharedValue<number> =>
28
- !!v && !isRNAnimatedValue(v) && 'value' in (v as object);
29
-
30
- /**
31
- * Normalize an incoming animated value (either runtime, or nothing) into a
32
- * reanimated `SharedValue<number>` that foundation components can drive with
33
- * `useAnimatedStyle`/`interpolate`.
34
- *
35
- * - SharedValue → returned as-is (zero overhead, shares the same UI-thread cell)
36
- * - Animated.Value → bridged: a JS-thread `addListener` mirrors its value into
37
- * an internal SharedValue. NOTE: when the source `Animated.Value` is driven
38
- * by `Animated.event(..., { useNativeDriver: true })`, `addListener` does NOT
39
- * fire per frame, so the bridge stays flat. For the Screen-driven case the
40
- * bridge is fed from the scroll `listener` instead (see Screen.tsx); this
41
- * hook's listener is the safety net for standalone / JS-driven usage.
42
- * - undefined → a fresh internal SharedValue stuck at 0
43
- */
44
- export function useNormalizedSharedValue(
45
- input?: AnimatedCompatValue,
46
- ): SharedValue<number> {
47
- const fallback = useSharedValue(0);
48
-
49
- useEffect(() => {
50
- if (!isRNAnimatedValue(input)) {
51
- return;
52
- }
53
- const id = input.addListener(({ value }) => {
54
- fallback.value = value;
55
- });
56
- return () => input.removeListener(id);
57
- }, [input, fallback]);
58
-
59
- if (isSharedValue(input)) {
60
- return input;
61
- }
62
- return fallback;
63
- }