@leonsilicon/react-native-wishlist 0.0.0 → 0.0.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.
Files changed (67) hide show
  1. package/README.md +11 -3
  2. package/cpp/ContentContainer/MGContentContainerComponentDescriptor.h +11 -15
  3. package/cpp/ItemProvider/ComponentsPool.cpp +3 -2
  4. package/cpp/ItemProvider/ShadowNodeBinding.cpp +3 -2
  5. package/cpp/ItemProvider/ShadowNodeCopyMachine.cpp +0 -50
  6. package/cpp/ItemProvider/ShadowNodeCopyMachine.h +2 -3
  7. package/lib/commonjs/Components/CaseBase.js +17 -0
  8. package/lib/commonjs/Components/CaseBase.js.map +1 -0
  9. package/lib/commonjs/Components/Pressable.js +54 -7
  10. package/lib/commonjs/Components/Pressable.js.map +1 -1
  11. package/lib/commonjs/Components/Switch.js +10 -10
  12. package/lib/commonjs/Components/Switch.js.map +1 -1
  13. package/lib/commonjs/Specs/NativeContentContainer.js +2 -3
  14. package/lib/commonjs/Specs/NativeContentContainer.js.map +1 -1
  15. package/lib/commonjs/Specs/NativeTemplateContainer.js +2 -3
  16. package/lib/commonjs/Specs/NativeTemplateContainer.js.map +1 -1
  17. package/lib/commonjs/Specs/NativeTemplateInterceptor.js +2 -3
  18. package/lib/commonjs/Specs/NativeTemplateInterceptor.js.map +1 -1
  19. package/lib/commonjs/Specs/NativeWishlist.js +3 -5
  20. package/lib/commonjs/Specs/NativeWishlist.js.map +1 -1
  21. package/lib/commonjs/TemplateValue.js +6 -0
  22. package/lib/commonjs/TemplateValue.js.map +1 -1
  23. package/lib/commonjs/createTemplateComponent.js +2 -2
  24. package/lib/commonjs/createTemplateComponent.js.map +1 -1
  25. package/lib/module/Components/CaseBase.js +12 -0
  26. package/lib/module/Components/CaseBase.js.map +1 -0
  27. package/lib/module/Components/Pressable.js +56 -9
  28. package/lib/module/Components/Pressable.js.map +1 -1
  29. package/lib/module/Components/Switch.js +3 -7
  30. package/lib/module/Components/Switch.js.map +1 -1
  31. package/lib/module/Specs/NativeContentContainer.js +1 -1
  32. package/lib/module/Specs/NativeContentContainer.js.map +1 -1
  33. package/lib/module/Specs/NativeTemplateContainer.js +1 -1
  34. package/lib/module/Specs/NativeTemplateContainer.js.map +1 -1
  35. package/lib/module/Specs/NativeTemplateInterceptor.js +1 -1
  36. package/lib/module/Specs/NativeTemplateInterceptor.js.map +1 -1
  37. package/lib/module/Specs/NativeWishlist.js +1 -2
  38. package/lib/module/Specs/NativeWishlist.js.map +1 -1
  39. package/lib/module/TemplateValue.js +6 -0
  40. package/lib/module/TemplateValue.js.map +1 -1
  41. package/lib/module/createTemplateComponent.js +1 -1
  42. package/lib/module/createTemplateComponent.js.map +1 -1
  43. package/lib/typescript/Components/CaseBase.d.ts +3 -0
  44. package/lib/typescript/Components/CaseBase.d.ts.map +1 -0
  45. package/lib/typescript/Components/Pressable.d.ts.map +1 -1
  46. package/lib/typescript/Components/Switch.d.ts +2 -2
  47. package/lib/typescript/Components/Switch.d.ts.map +1 -1
  48. package/lib/typescript/Specs/NativeContentContainer.d.ts +2 -2
  49. package/lib/typescript/Specs/NativeContentContainer.d.ts.map +1 -1
  50. package/lib/typescript/Specs/NativeTemplateContainer.d.ts +2 -2
  51. package/lib/typescript/Specs/NativeTemplateContainer.d.ts.map +1 -1
  52. package/lib/typescript/Specs/NativeTemplateInterceptor.d.ts +2 -2
  53. package/lib/typescript/Specs/NativeTemplateInterceptor.d.ts.map +1 -1
  54. package/lib/typescript/Specs/NativeWishlist.d.ts +3 -4
  55. package/lib/typescript/Specs/NativeWishlist.d.ts.map +1 -1
  56. package/lib/typescript/TemplateValue.d.ts +5 -0
  57. package/lib/typescript/TemplateValue.d.ts.map +1 -1
  58. package/package.json +38 -40
  59. package/src/Components/CaseBase.tsx +6 -0
  60. package/src/Components/Pressable.tsx +70 -12
  61. package/src/Components/Switch.tsx +4 -5
  62. package/src/Specs/NativeContentContainer.ts +1 -2
  63. package/src/Specs/NativeTemplateContainer.ts +1 -2
  64. package/src/Specs/NativeTemplateInterceptor.ts +1 -2
  65. package/src/Specs/NativeWishlist.ts +7 -6
  66. package/src/TemplateValue.tsx +5 -0
  67. package/src/createTemplateComponent.tsx +1 -1
@@ -1,17 +1,20 @@
1
1
  import React, { forwardRef } from 'react';
2
- import { NativeModules, View, ViewProps } from 'react-native';
2
+ import { DeviceEventEmitter, NativeModules, View, ViewProps } from 'react-native';
3
3
  import { createTemplateComponent } from '../createTemplateComponent';
4
4
  import { useTemplateCallback } from '../EventHandler';
5
5
  import { getUIInflatorRegistry } from '../InflatorRepository';
6
- import { createRunInJsFn } from '../WishlistJsRuntime';
6
+ import { createRunInWishlistFn, createRunInJsFn } from '../WishlistJsRuntime';
7
7
 
8
- // TODO(janic): Figure out why those cannot be imported directly from RNGH in the example app.
8
+ // Mirrors `RNGestureHandlerActionType` in react-native-gesture-handler. On the
9
+ // new architecture every state-change action type routes through
10
+ // `sendDeviceEventWithName:@"onGestureHandlerStateChange"` (a global JS device
11
+ // event), so we listen via `DeviceEventEmitter` and dispatch into the wishlist
12
+ // worklet runtime ourselves rather than relying on Fabric event observers.
9
13
  const ActionType = {
10
14
  REANIMATED_WORKLET: 1,
11
15
  NATIVE_ANIMATED_EVENT: 2,
12
16
  JS_FUNCTION_OLD_API: 3,
13
17
  JS_FUNCTION_NEW_API: 4,
14
- DIRECT_EVENT: 5,
15
18
  } as const;
16
19
 
17
20
  type ActionTypeT = (typeof ActionType)[keyof typeof ActionType];
@@ -38,12 +41,20 @@ type RNGestureHandlerModuleProps = {
38
41
  flushOperations: () => void;
39
42
  };
40
43
 
41
- let _handlerTag = 1000;
44
+ // Start above the range RNGH typically issues for handlers created via JS so
45
+ // our auto-generated tags don't collide with user-created gestures. Offset by
46
+ // a per-load random base so a Metro JS reload doesn't reuse the tags from the
47
+ // previous load (RNGH's native registry persists across JS reloads and would
48
+ // throw `HandlerAlreadyRegistered`).
49
+ let _handlerTag = 100000 + Math.floor(Math.random() * 1_000_000);
42
50
 
43
51
  export function getNextHandlerTag(): number {
44
52
  return _handlerTag++;
45
53
  }
46
54
 
55
+ const _attachedViewTags = new Set<number>();
56
+ const _handlerTagToViewTag = new Map<number, number>();
57
+
47
58
  const RNGestureHandlerModule: RNGestureHandlerModuleProps =
48
59
  NativeModules.RNGestureHandlerModule;
49
60
 
@@ -56,22 +67,69 @@ export const State = {
56
67
  END: 5,
57
68
  } as const;
58
69
 
70
+ const dispatchGestureEventToWishlistRuntime = createRunInWishlistFn(
71
+ (viewTag: number, event: any) => {
72
+ 'worklet';
73
+ const handleEvent = global.handleEvent;
74
+ if (typeof handleEvent === 'function') {
75
+ handleEvent('onGestureHandlerStateChange', viewTag, event);
76
+ }
77
+ },
78
+ );
79
+
80
+ let _gestureListenerInstalled = false;
81
+ function installGestureListener() {
82
+ if (_gestureListenerInstalled) {
83
+ return;
84
+ }
85
+ _gestureListenerInstalled = true;
86
+ DeviceEventEmitter.addListener(
87
+ 'onGestureHandlerStateChange',
88
+ (event: { handlerTag: number; state: number }) => {
89
+ const viewTag = _handlerTagToViewTag.get(event.handlerTag);
90
+ if (viewTag == null) {
91
+ return;
92
+ }
93
+ dispatchGestureEventToWishlistRuntime(viewTag, event);
94
+ },
95
+ );
96
+ }
97
+
59
98
  type PressableProps = ViewProps & {
60
99
  onPress?: ((item: any, rootItem: any) => void) | null;
61
100
  };
62
101
 
63
102
  const attachGestureHandler = createRunInJsFn((tag: number) => {
64
- // TODO: Do we need to detach handlers?
103
+ if (_attachedViewTags.has(tag)) {
104
+ return;
105
+ }
106
+ _attachedViewTags.add(tag);
107
+ installGestureListener();
65
108
  const handlerTag = getNextHandlerTag();
66
- RNGestureHandlerModule.createGestureHandler(
67
- 'TapGestureHandler',
68
- handlerTag,
69
- {},
70
- );
109
+ _handlerTagToViewTag.set(handlerTag, tag);
110
+ try {
111
+ RNGestureHandlerModule.createGestureHandler(
112
+ 'TapGestureHandler',
113
+ handlerTag,
114
+ {},
115
+ );
116
+ } catch (e) {
117
+ // RNGH keeps its handler registry alive across Metro JS reloads. If a
118
+ // handler with this tag already exists from a prior load, drop it and
119
+ // retry — losing the stale handler is fine since its view is gone too.
120
+ try {
121
+ RNGestureHandlerModule.dropGestureHandler(handlerTag);
122
+ } catch {}
123
+ RNGestureHandlerModule.createGestureHandler(
124
+ 'TapGestureHandler',
125
+ handlerTag,
126
+ {},
127
+ );
128
+ }
71
129
  RNGestureHandlerModule.attachGestureHandler(
72
130
  handlerTag,
73
131
  tag,
74
- ActionType.DIRECT_EVENT,
132
+ ActionType.JS_FUNCTION_OLD_API,
75
133
  );
76
134
  RNGestureHandlerModule.flushOperations();
77
135
  });
@@ -1,7 +1,10 @@
1
- import React, { forwardRef } from 'react';
1
+ import React from 'react';
2
2
  import { View, ViewStyle } from 'react-native';
3
3
  import { createTemplateComponent } from '../createTemplateComponent';
4
4
  import type { TemplateValue } from '../TemplateValue';
5
+ import { CaseBase } from './CaseBase';
6
+
7
+ export { CaseBase };
5
8
 
6
9
  const SwitchTemplateComponent = createTemplateComponent(View);
7
10
 
@@ -23,10 +26,6 @@ export function Switch(props: SwitchProps) {
23
26
  return <SwitchTemplateComponent {...props} children={children} />;
24
27
  }
25
28
 
26
- export const CaseBase = forwardRef<any, any>((props, ref) => {
27
- return <View {...props} ref={ref} />;
28
- });
29
-
30
29
  const CaseTemplateComponent = createTemplateComponent(CaseBase, {
31
30
  addProps: (item, props) => {
32
31
  'worklet';
@@ -1,5 +1,4 @@
1
- import type { ViewProps } from 'react-native';
2
- import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
1
+ import { codegenNativeComponent, type ViewProps } from 'react-native';
3
2
 
4
3
  export interface NativeContentContainerProps extends ViewProps {}
5
4
 
@@ -1,5 +1,4 @@
1
- import type { ViewProps } from 'react-native';
2
- import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
1
+ import { codegenNativeComponent, type ViewProps } from 'react-native';
3
2
 
4
3
  export interface NativeTemplateContainerProps extends ViewProps {
5
4
  inflatorId: string;
@@ -1,5 +1,4 @@
1
- import type { ViewProps } from 'react-native';
2
- import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
1
+ import { codegenNativeComponent, type ViewProps } from 'react-native';
3
2
 
4
3
  export interface NativeTemplateInterceptorProps extends ViewProps {}
5
4
 
@@ -1,14 +1,15 @@
1
1
  import type * as React from 'react';
2
- import type { ViewProps } from 'react-native';
2
+ import {
3
+ codegenNativeCommands,
4
+ codegenNativeComponent,
5
+ type HostComponent,
6
+ type ViewProps,
7
+ } from 'react-native';
3
8
  import type {
4
9
  DirectEventHandler,
5
10
  Double,
6
11
  Int32,
7
12
  } from 'react-native/Libraries/Types/CodegenTypes';
8
- import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
9
- import codegenNativeComponent, {
10
- NativeComponentType,
11
- } from 'react-native/Libraries/Utilities/codegenNativeComponent';
12
13
 
13
14
  export type EventInFile = Readonly<{
14
15
  value: Double;
@@ -21,7 +22,7 @@ export interface WishlistProps extends ViewProps {
21
22
  onEndReached?: DirectEventHandler<Readonly<{}>>;
22
23
  }
23
24
 
24
- type NativeType = NativeComponentType<WishlistProps>;
25
+ type NativeType = HostComponent<WishlistProps>;
25
26
 
26
27
  export type ScrollToItem = (
27
28
  viewRef: React.ElementRef<NativeType>,
@@ -86,6 +86,11 @@ export function isTemplateValue(
86
86
  );
87
87
  }
88
88
 
89
+ /**
90
+ * The `mapper` runs on the UI worklet runtime. Mark it (and any nested function
91
+ * literals it passes to helpers like `Array#reduce`) with a leading
92
+ * `'worklet';` statement so `react-native-worklets-core` can compile them.
93
+ */
89
94
  export function useTemplateValue<ItemT, ValueT>(
90
95
  mapper: TemplateValueMapper<ItemT, ValueT>,
91
96
  ): TemplateValue<ValueT> {
@@ -5,7 +5,7 @@ import { ForEachBase } from './Components/ForEachBase';
5
5
  import InflatorRepository, {
6
6
  getUIInflatorRegistry,
7
7
  } from './InflatorRepository';
8
- import { CaseBase } from './Components/Switch';
8
+ import { CaseBase } from './Components/CaseBase';
9
9
  import { useTemplateContext } from './TemplateContext';
10
10
  import {
11
11
  createTemplateValue,