expo-invoke 2.6.14 → 2.7.0

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 (149) hide show
  1. package/android/src/main/java/expo/modules/invoke/ExpoInvokeModule.kt +35 -0
  2. package/android/src/main/java/expo/modules/invoke/InvokeSliceProvider.kt +9 -0
  3. package/build/plugin/codegen/generateSwiftIntents.js +22 -0
  4. package/build/plugin/codegen/generateSwiftIntents.js.map +1 -1
  5. package/build/plugin/codegen/generateSwiftLiveActivities.d.ts +17 -0
  6. package/build/plugin/codegen/generateSwiftLiveActivities.js +165 -0
  7. package/build/plugin/codegen/generateSwiftLiveActivities.js.map +1 -0
  8. package/build/plugin/codegen/generateSwiftWidget.d.ts +5 -0
  9. package/build/plugin/codegen/generateSwiftWidget.js.map +1 -1
  10. package/build/plugin/ios/widgets/withAppGroupEntitlements.d.ts +6 -0
  11. package/build/plugin/ios/widgets/withAppGroupEntitlements.js +27 -0
  12. package/build/plugin/ios/widgets/withAppGroupEntitlements.js.map +1 -0
  13. package/build/plugin/ios/widgets/withAppInfoPlist.d.ts +7 -0
  14. package/build/plugin/ios/widgets/withAppInfoPlist.js +12 -0
  15. package/build/plugin/ios/widgets/withAppInfoPlist.js.map +1 -0
  16. package/build/plugin/ios/widgets/withEasConfig.d.ts +8 -0
  17. package/build/plugin/ios/widgets/withEasConfig.js +52 -0
  18. package/build/plugin/ios/widgets/withEasConfig.js.map +1 -0
  19. package/build/plugin/ios/widgets/withIosWarning.d.ts +7 -0
  20. package/build/plugin/ios/widgets/withIosWarning.js +10 -0
  21. package/build/plugin/ios/widgets/withIosWarning.js.map +1 -0
  22. package/build/plugin/ios/widgets/withIosWidgets.d.ts +11 -0
  23. package/build/plugin/ios/widgets/withIosWidgets.js +83 -0
  24. package/build/plugin/ios/widgets/withIosWidgets.js.map +1 -0
  25. package/build/plugin/ios/widgets/withPodsLinking.d.ts +6 -0
  26. package/build/plugin/ios/widgets/withPodsLinking.js +102 -0
  27. package/build/plugin/ios/widgets/withPodsLinking.js.map +1 -0
  28. package/build/plugin/ios/widgets/withPushNotifications.d.ts +6 -0
  29. package/build/plugin/ios/widgets/withPushNotifications.js +12 -0
  30. package/build/plugin/ios/widgets/withPushNotifications.js.map +1 -0
  31. package/build/plugin/ios/widgets/withWidgetSourceFiles.d.ts +10 -0
  32. package/build/plugin/ios/widgets/withWidgetSourceFiles.js +379 -0
  33. package/build/plugin/ios/widgets/withWidgetSourceFiles.js.map +1 -0
  34. package/build/plugin/ios/widgets/xcode/addBuildPhases.d.ts +12 -0
  35. package/build/plugin/ios/widgets/xcode/addBuildPhases.js +41 -0
  36. package/build/plugin/ios/widgets/xcode/addBuildPhases.js.map +1 -0
  37. package/build/plugin/ios/widgets/xcode/addPbxGroup.d.ts +5 -0
  38. package/build/plugin/ios/widgets/xcode/addPbxGroup.js +20 -0
  39. package/build/plugin/ios/widgets/xcode/addPbxGroup.js.map +1 -0
  40. package/build/plugin/ios/widgets/xcode/addProductFile.d.ts +7 -0
  41. package/build/plugin/ios/widgets/xcode/addProductFile.js +41 -0
  42. package/build/plugin/ios/widgets/xcode/addProductFile.js.map +1 -0
  43. package/build/plugin/ios/widgets/xcode/addTargetDependency.d.ts +4 -0
  44. package/build/plugin/ios/widgets/xcode/addTargetDependency.js +17 -0
  45. package/build/plugin/ios/widgets/xcode/addTargetDependency.js.map +1 -0
  46. package/build/plugin/ios/widgets/xcode/addToPbxNativeTargetSection.d.ts +14 -0
  47. package/build/plugin/ios/widgets/xcode/addToPbxNativeTargetSection.js +29 -0
  48. package/build/plugin/ios/widgets/xcode/addToPbxNativeTargetSection.js.map +1 -0
  49. package/build/plugin/ios/widgets/xcode/addToPbxProjectSection.d.ts +4 -0
  50. package/build/plugin/ios/widgets/xcode/addToPbxProjectSection.js +20 -0
  51. package/build/plugin/ios/widgets/xcode/addToPbxProjectSection.js.map +1 -0
  52. package/build/plugin/ios/widgets/xcode/addXCConfigurationList.d.ts +11 -0
  53. package/build/plugin/ios/widgets/xcode/addXCConfigurationList.js +37 -0
  54. package/build/plugin/ios/widgets/xcode/addXCConfigurationList.js.map +1 -0
  55. package/build/plugin/ios/widgets/xcode/withTargetXcodeProject.d.ts +10 -0
  56. package/build/plugin/ios/widgets/xcode/withTargetXcodeProject.js +86 -0
  57. package/build/plugin/ios/widgets/xcode/withTargetXcodeProject.js.map +1 -0
  58. package/build/plugin/ios/withIOSInvoke.d.ts +6 -15
  59. package/build/plugin/ios/withIOSInvoke.js +54 -25
  60. package/build/plugin/ios/withIOSInvoke.js.map +1 -1
  61. package/build/plugin/ios/withWidgetExtension.d.ts +5 -0
  62. package/build/plugin/ios/withWidgetExtension.js +36 -6
  63. package/build/plugin/ios/withWidgetExtension.js.map +1 -1
  64. package/build/plugin/src/withInvoke.d.ts +34 -23
  65. package/build/plugin/src/withInvoke.js +16 -27
  66. package/build/plugin/src/withInvoke.js.map +1 -1
  67. package/build/plugin/types/WidgetConfig.type.d.ts +54 -0
  68. package/build/plugin/types/WidgetConfig.type.js +3 -0
  69. package/build/plugin/types/WidgetConfig.type.js.map +1 -0
  70. package/build/plugin/types/WidgetFamily.type.d.ts +10 -0
  71. package/build/plugin/types/WidgetFamily.type.js +13 -0
  72. package/build/plugin/types/WidgetFamily.type.js.map +1 -0
  73. package/build/src/hooks/useLiveActivity.d.ts +20 -10
  74. package/build/src/hooks/useLiveActivity.d.ts.map +1 -1
  75. package/build/src/hooks/useLiveActivity.js +20 -10
  76. package/build/src/hooks/useLiveActivity.js.map +1 -1
  77. package/build/src/index.d.ts +2 -0
  78. package/build/src/index.d.ts.map +1 -1
  79. package/build/src/index.js +5 -0
  80. package/build/src/index.js.map +1 -1
  81. package/build/src/module.d.ts +4 -0
  82. package/build/src/module.d.ts.map +1 -1
  83. package/build/src/module.js +8 -0
  84. package/build/src/module.js.map +1 -1
  85. package/build/src/web/index.d.ts +10 -1
  86. package/build/src/web/index.d.ts.map +1 -1
  87. package/build/src/web/index.js +4 -0
  88. package/build/src/web/index.js.map +1 -1
  89. package/build/src/widgets/ExpoWidgets.d.ts +12 -0
  90. package/build/src/widgets/ExpoWidgets.d.ts.map +1 -0
  91. package/build/src/widgets/ExpoWidgets.ios.d.ts +12 -0
  92. package/build/src/widgets/ExpoWidgets.ios.d.ts.map +1 -0
  93. package/build/src/widgets/ExpoWidgets.ios.js +3 -0
  94. package/build/src/widgets/ExpoWidgets.ios.js.map +1 -0
  95. package/build/src/widgets/ExpoWidgets.js +42 -0
  96. package/build/src/widgets/ExpoWidgets.js.map +1 -0
  97. package/build/src/widgets/Widgets.d.ts +119 -0
  98. package/build/src/widgets/Widgets.d.ts.map +1 -0
  99. package/build/src/widgets/Widgets.js +158 -0
  100. package/build/src/widgets/Widgets.js.map +1 -0
  101. package/build/src/widgets/Widgets.types.d.ts +263 -0
  102. package/build/src/widgets/Widgets.types.d.ts.map +1 -0
  103. package/build/src/widgets/Widgets.types.js +2 -0
  104. package/build/src/widgets/Widgets.types.js.map +1 -0
  105. package/build/src/widgets/index.d.ts +3 -0
  106. package/build/src/widgets/index.d.ts.map +1 -0
  107. package/build/src/widgets/index.js +2 -0
  108. package/build/src/widgets/index.js.map +1 -0
  109. package/bundle/__tests__/decorator.test.ts +89 -0
  110. package/bundle/decorator.ts +61 -0
  111. package/bundle/expo-modules-core-stub.ts +1 -0
  112. package/bundle/expo-stub.ts +15 -0
  113. package/bundle/index.ts +69 -0
  114. package/bundle/jsx-runtime-stub.ts +71 -0
  115. package/bundle/react-native-stub.ts +3 -0
  116. package/bundle/react-stub.ts +13 -0
  117. package/expo-module.config.json +1 -1
  118. package/ios/LiveActivity/LiveActivityManager.swift +15 -14
  119. package/ios/Module/ExpoInvokeModule.swift +124 -0
  120. package/ios/Widget/WidgetManager.swift +25 -8
  121. package/ios/Widgets/LiveActivity.swift +81 -0
  122. package/ios/Widgets/LiveActivityFactory.swift +49 -0
  123. package/ios/Widgets/Widget/AppIntent.swift +130 -0
  124. package/ios/Widgets/Widget/Buttons.swift +62 -0
  125. package/ios/Widgets/Widget/DynamicView.swift +161 -0
  126. package/ios/Widgets/Widget/EntryView.swift +36 -0
  127. package/ios/Widgets/Widget/Fragment.swift +13 -0
  128. package/ios/Widgets/Widget/LiveActivityBanner.swift +19 -0
  129. package/ios/Widgets/Widget/RedBoxView.swift +83 -0
  130. package/ios/Widgets/Widget/TimelineEntry.swift +8 -0
  131. package/ios/Widgets/Widget/TimelineProvider.swift +45 -0
  132. package/ios/Widgets/Widget/Type.swift +6 -0
  133. package/ios/Widgets/Widget/Utils.swift +116 -0
  134. package/ios/Widgets/Widget/WidgetLiveActivity.swift +104 -0
  135. package/ios/Widgets/Widget/WidgetsJSRuntime.swift +148 -0
  136. package/ios/Widgets/WidgetObject.swift +31 -0
  137. package/ios/Widgets/WidgetsContext.swift +7 -0
  138. package/ios/Widgets/WidgetsEvents.swift +16 -0
  139. package/ios/Widgets/WidgetsExceptions.swift +25 -0
  140. package/ios/Widgets/WidgetsModule.swift +149 -0
  141. package/ios/Widgets/WidgetsRecords.swift +22 -0
  142. package/ios/Widgets/WidgetsStorage.swift +58 -0
  143. package/metro.widget.config.js +76 -0
  144. package/package.json +11 -1
  145. package/scripts/autolinking.rb +34 -0
  146. package/scripts/build-bundle.mjs +69 -0
  147. package/scripts/with-node.sh +44 -0
  148. package/scripts/xcode-build-bundle.sh +23 -0
  149. package/spm.config.json +40 -0
@@ -0,0 +1,263 @@
1
+ import { SharedObject } from 'expo-modules-core';
2
+ import type { ReactNode } from 'react';
3
+ import type { after } from './Widgets';
4
+ /**
5
+ * The rendering mode of the widget as provided by WidgetKit.
6
+ * - `fullColor` — Home screen widgets (default).
7
+ * - `accented` — Tinted widgets (iOS 18+) and watchOS.
8
+ * - `vibrant` — Lock screen widgets.
9
+ */
10
+ export type WidgetRenderingMode = 'fullColor' | 'accented' | 'vibrant';
11
+ /**
12
+ * The level of detail the view is recommended to have.
13
+ * The system can update the levelOfDetail value based on user proximity or other system specific factors and allow content customization adapting to show different levels of details.
14
+ * - `simplified` — The system recommends showing a simplified view with less details.
15
+ * - `default` — The system has no specific recommendation for the level of detail.
16
+ * @platform iOS 26+
17
+ */
18
+ export type LevelOfDetail = 'simplified' | 'default';
19
+ /**
20
+ * The size family of the current Live Activity.
21
+ * A Live Activity you initiate on one device can also appear on a remote device that renders the Live Activity in a different family size. As a result, it renders for a specific family, depending on both the device and the location in which it appears.
22
+ * @platform iOS 18+
23
+ */
24
+ export type ActivityFamily = 'small' | 'medium';
25
+ /**
26
+ * The widget family (size).
27
+ * - `systemSmall` - Small square widget (2x2 grid).
28
+ * - `systemMedium` - Medium widget (4x2 grid).
29
+ * - `systemLarge` - Large widget (4x4 grid).
30
+ * - `systemExtraLarge` - Extra large widget (iPad only, 6x4 grid).
31
+ * - `accessoryCircular` - Circular accessory widget for the Lock Screen.
32
+ * - `accessoryRectangular` - Rectangular accessory widget for the Lock Screen.
33
+ * - `accessoryInline` - Inline accessory widget for the Lock Screen.
34
+ */
35
+ export type WidgetFamily = 'systemSmall' | 'systemMedium' | 'systemLarge' | 'systemExtraLarge' | 'accessoryCircular' | 'accessoryRectangular' | 'accessoryInline';
36
+ export type WidgetEnvironment<T extends object | undefined = undefined> = {
37
+ /**
38
+ * The date of this timeline entry.
39
+ */
40
+ date: Date;
41
+ /**
42
+ * The widget family.
43
+ */
44
+ widgetFamily: WidgetFamily;
45
+ /**
46
+ * The color scheme of the widget's environment.
47
+ */
48
+ colorScheme?: 'light' | 'dark';
49
+ /**
50
+ * A Boolean value that indicates whether the display or environment currently requires reduced luminance.
51
+ *
52
+ * When you detect this condition, lower the overall brightness of your view.
53
+ * For example, you can change large, filled shapes to be stroked, and choose less bright colors.
54
+ * @platform iOS 16+
55
+ */
56
+ isLuminanceReduced?: boolean;
57
+ /**
58
+ * The widget's rendering mode, based on where the system is displaying it.
59
+ * @platform iOS 16+
60
+ */
61
+ widgetRenderingMode?: WidgetRenderingMode;
62
+ /**
63
+ * A Boolean value that indicates whether an accessory family widget can display an accessory label.
64
+ * @platform iOS 16+
65
+ */
66
+ showsWidgetLabel?: boolean;
67
+ /**
68
+ * The content margins for the widget.
69
+ * @platform iOS 17+
70
+ */
71
+ widgetContentMargins?: {
72
+ top: number;
73
+ bottom: number;
74
+ leading: number;
75
+ trailing: number;
76
+ };
77
+ /**
78
+ * The level of detail the view is recommended to have.
79
+ * @platform iOS 26+
80
+ */
81
+ levelOfDetail?: LevelOfDetail;
82
+ /**
83
+ * Widget configuration parameters.
84
+ * @platform iOS 17+
85
+ */
86
+ configuration: T;
87
+ };
88
+ export type LiveActivityEnvironment = {
89
+ /**
90
+ * The color scheme of the activity's environment.
91
+ */
92
+ colorScheme: 'light' | 'dark';
93
+ /**
94
+ * Whether the activity is displayed in a context with reduced luminance.
95
+ * @platform iOS 16+
96
+ */
97
+ isLuminanceReduced?: boolean;
98
+ /**
99
+ * Whether the activity is currently displayed in fullscreen.
100
+ * @platform iOS 16.1+
101
+ */
102
+ isActivityFullscreen?: boolean;
103
+ /**
104
+ * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.
105
+ * @platform iOS 18+
106
+ */
107
+ isActivityUpdateReduced?: boolean;
108
+ /**
109
+ * The size family of the current Live Activity.
110
+ * @platform iOS 18+
111
+ */
112
+ activityFamily?: ActivityFamily;
113
+ /**
114
+ * The level of detail the view is recommended to have.
115
+ * @platform iOS 26+
116
+ */
117
+ levelOfDetail?: LevelOfDetail;
118
+ };
119
+ export type WidgetTimelineEntry<T extends object = object> = {
120
+ /**
121
+ * Date when widget should update.
122
+ */
123
+ date: Date;
124
+ /**
125
+ * Props to be passed to the widget.
126
+ */
127
+ props: T;
128
+ };
129
+ export type ExpoTimelineEntry = {
130
+ timestamp: number;
131
+ props: Record<string, any>;
132
+ };
133
+ /**
134
+ * Defines the layout sections for an iOS Live Activity.
135
+ */
136
+ export type LiveActivityLayout = {
137
+ /**
138
+ * The main banner content displayed in Notifications Center.
139
+ */
140
+ banner: ReactNode;
141
+ /**
142
+ * The small banner content displayed in CarPlay and WatchOS. Falls back to `banner` if not provided.
143
+ */
144
+ bannerSmall?: ReactNode;
145
+ /**
146
+ * The leading content in the compact Dynamic Island presentation.
147
+ */
148
+ compactLeading?: ReactNode;
149
+ /**
150
+ * The trailing content in the compact Dynamic Island presentation.
151
+ */
152
+ compactTrailing?: ReactNode;
153
+ /**
154
+ * The minimal content shown when the Dynamic Island is in its smallest form.
155
+ */
156
+ minimal?: ReactNode;
157
+ /**
158
+ * The center content in the expanded Dynamic Island presentation.
159
+ */
160
+ expandedCenter?: ReactNode;
161
+ /**
162
+ * The leading content in the expanded Dynamic Island presentation.
163
+ */
164
+ expandedLeading?: ReactNode;
165
+ /**
166
+ * The trailing content in the expanded Dynamic Island presentation.
167
+ */
168
+ expandedTrailing?: ReactNode;
169
+ /**
170
+ * The bottom content in the expanded Dynamic Island presentation.
171
+ */
172
+ expandedBottom?: ReactNode;
173
+ };
174
+ /**
175
+ * A function that returns the layout for a Live Activity.
176
+ */
177
+ export type LiveActivityComponent<T extends object = object> = (props: T, environment: LiveActivityEnvironment) => LiveActivityLayout;
178
+ /**
179
+ * Event emitted when a user interacts with a widget.
180
+ */
181
+ export type UserInteractionEvent = {
182
+ /**
183
+ * Widget that triggered the interaction.
184
+ */
185
+ source: string;
186
+ /**
187
+ * Button/toggle that was pressed.
188
+ */
189
+ target: string;
190
+ /**
191
+ * Timestamp of the event.
192
+ */
193
+ timestamp: number;
194
+ /**
195
+ * The event type identifier.
196
+ */
197
+ type: 'ExpoWidgetsUserInteraction';
198
+ };
199
+ /**
200
+ * Event emitted when a push token is received for a live activity.
201
+ */
202
+ export type PushTokenEvent = {
203
+ /**
204
+ * The ID of the live activity.
205
+ */
206
+ activityId: string;
207
+ /**
208
+ * The push token for the live activity.
209
+ */
210
+ pushToken: string;
211
+ };
212
+ /**
213
+ * Event emitted when a push-to-start token is received.
214
+ */
215
+ export type PushToStartTokenEvent = {
216
+ /**
217
+ * The push-to-start token for starting live activities remotely.
218
+ */
219
+ activityPushToStartToken: string;
220
+ };
221
+ /**
222
+ * Dismissal policy for ending a live activity.
223
+ * - `'default'` - The system’s default dismissal policy for the Live Activity.
224
+ * - `'immediate'` - The system immediately removes the Live Activity that ended.
225
+ * - `after(date)` - The system removes the Live Activity that ended at the specified time within a four-hour window.
226
+ */
227
+ export type LiveActivityDismissalPolicy = 'default' | 'immediate' | ReturnType<typeof after>;
228
+ export type ExpoWidgetsEvents = {
229
+ /**
230
+ * Function that is invoked when user interacts with a widget.
231
+ * @param event Interaction event details.
232
+ */
233
+ onExpoWidgetsUserInteraction: (event: UserInteractionEvent) => void;
234
+ /**
235
+ * Function that is invoked when a push-to-start token is received.
236
+ * @param event Token event details.
237
+ */
238
+ onExpoWidgetsPushToStartTokenReceived: (event: PushToStartTokenEvent) => void;
239
+ };
240
+ export type LiveActivityEvents = {
241
+ /**
242
+ * Function that is invoked when a push token is received for a live activity.
243
+ * @param event Token event details.
244
+ */
245
+ onExpoWidgetsTokenReceived: (event: PushTokenEvent) => void;
246
+ };
247
+ export declare class NativeWidgetObject extends SharedObject {
248
+ constructor(name: string, layout: string);
249
+ reload(): void;
250
+ updateTimeline(entries: ExpoTimelineEntry[]): void;
251
+ getTimeline(): Promise<ExpoTimelineEntry[]>;
252
+ }
253
+ export declare class NativeLiveActivityFactory extends SharedObject {
254
+ constructor(name: string, layout: string);
255
+ start(props?: string, url?: string): NativeLiveActivity;
256
+ getInstances(): NativeLiveActivity[];
257
+ }
258
+ export declare class NativeLiveActivity extends SharedObject<LiveActivityEvents> {
259
+ update(props?: string): Promise<void>;
260
+ end(dismissalPolicy?: string, afterDate?: number, state?: string, contentDate?: number): Promise<void>;
261
+ getPushToken(): Promise<string | null>;
262
+ }
263
+ //# sourceMappingURL=Widgets.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Widgets.types.d.ts","sourceRoot":"","sources":["../../../src/widgets/Widgets.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Widgets.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Widgets.types.js","sourceRoot":"","sources":["../../../src/widgets/Widgets.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export * from './Widgets';
2
+ export type { ExpoWidgetsEvents, LevelOfDetail, LiveActivityComponent, LiveActivityDismissalPolicy, LiveActivityEnvironment, LiveActivityEvents, LiveActivityLayout, PushTokenEvent, PushToStartTokenEvent, UserInteractionEvent, WidgetEnvironment, WidgetFamily, WidgetRenderingMode, WidgetTimelineEntry, } from './Widgets.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/widgets/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,2BAA2B,EAC3B,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Widgets';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/widgets/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,89 @@
1
+ import '../index';
2
+ import { jsx, jsxs } from '../jsx-runtime-stub';
3
+
4
+ jest.mock('@expo/ui/swift-ui', () => ({}));
5
+ jest.mock('@expo/ui/swift-ui/modifiers', () => ({}));
6
+
7
+ describe('jsx-runtime-stub', () => {
8
+ afterEach(() => {
9
+ delete globalThis.__expoWidgetLayout;
10
+ });
11
+
12
+ it('adds button targets during render', () => {
13
+ globalThis.__expoWidgetLayout = () =>
14
+ jsxs('View', {
15
+ children: [
16
+ jsx('Button', { label: 'First', onButtonPress: () => ({ id: 'first' }) }),
17
+ jsx('Button', { label: 'Second', onButtonPress: () => ({ id: 'second' }) }),
18
+ ],
19
+ });
20
+
21
+ const tree = globalThis.__expoWidgetRender({}, { timestamp: 1 }) as any;
22
+
23
+ expect(tree.props.children[0].props.target).toBe('__expo_widgets_target_0');
24
+ expect(tree.props.children[1].props.target).toBe('__expo_widgets_target_1');
25
+ });
26
+
27
+ it('uses the nearest keyed parent when generating button targets', () => {
28
+ globalThis.__expoWidgetLayout = () =>
29
+ jsx(
30
+ 'Row',
31
+ {
32
+ children: jsx('Wrapper', {
33
+ children: jsx('Button', {
34
+ label: 'Press',
35
+ onButtonPress: () => ({ id: 'nested' }),
36
+ }),
37
+ }),
38
+ },
39
+ 'row-1'
40
+ );
41
+
42
+ const tree = globalThis.__expoWidgetRender({}, { timestamp: 1 }) as any;
43
+
44
+ expect(tree.props.children.props.children.props.target).toBe('__expo_widgets_target_0_row-1');
45
+ });
46
+
47
+ it('preserves explicit button targets', () => {
48
+ globalThis.__expoWidgetLayout = () =>
49
+ jsx('Button', {
50
+ label: 'Custom',
51
+ target: 'custom-target',
52
+ onButtonPress: () => ({ id: 'custom' }),
53
+ });
54
+
55
+ const tree = globalThis.__expoWidgetRender({}, { timestamp: 1 }) as any;
56
+
57
+ expect(tree.props.target).toBe('custom-target');
58
+ });
59
+
60
+ it('reuses generated button targets when handling presses', () => {
61
+ const firstPress = jest.fn(() => ({ id: 'first' }));
62
+ const secondPress = jest.fn(() => ({ id: 'second' }));
63
+
64
+ globalThis.__expoWidgetLayout = () =>
65
+ jsxs('View', {
66
+ children: [
67
+ jsx(
68
+ 'Row',
69
+ { children: jsx('Button', { label: 'First', onButtonPress: firstPress }) },
70
+ 'row-1'
71
+ ),
72
+ jsx(
73
+ 'Row',
74
+ { children: jsx('Button', { label: 'Second', onButtonPress: secondPress }) },
75
+ 'row-2'
76
+ ),
77
+ ],
78
+ });
79
+
80
+ const tree = globalThis.__expoWidgetRender({}, { timestamp: 1 }) as any;
81
+ const secondTarget = tree.props.children[1].props.children.props.target;
82
+
83
+ const result = globalThis.__expoWidgetHandlePress({}, { timestamp: 1, target: secondTarget });
84
+
85
+ expect(result).toEqual({ id: 'second' });
86
+ expect(firstPress).not.toHaveBeenCalled();
87
+ expect(secondPress).toHaveBeenCalledTimes(1);
88
+ });
89
+ });
@@ -0,0 +1,61 @@
1
+ import { ReactElementNode } from './jsx-runtime-stub';
2
+
3
+ export function decorateInteractiveTargets(node: unknown) {
4
+ return decorateNode(node, {
5
+ nearestParentKey: null,
6
+ nextTargetIndex: {
7
+ current: 0,
8
+ },
9
+ typesToDecorate: ['Button'],
10
+ });
11
+ }
12
+
13
+ function decorateNode(
14
+ node: unknown,
15
+ context: {
16
+ nearestParentKey: string | null;
17
+ nextTargetIndex: {
18
+ current: number;
19
+ };
20
+ typesToDecorate: string[];
21
+ }
22
+ ): unknown {
23
+ if (Array.isArray(node)) {
24
+ return node.map((child) => decorateNode(child, context));
25
+ }
26
+
27
+ if (!isReactElementNode(node)) {
28
+ return node;
29
+ }
30
+
31
+ const props = node.props ?? {};
32
+
33
+ if (props.target == null && context.typesToDecorate.includes(node.type as string)) {
34
+ props.target = buildButtonTargetId(context.nextTargetIndex.current, context.nearestParentKey);
35
+ context.nextTargetIndex.current += 1;
36
+ }
37
+
38
+ if ('children' in props) {
39
+ props.children = decorateNode(props.children, {
40
+ nearestParentKey: node.key ?? context.nearestParentKey,
41
+ nextTargetIndex: context.nextTargetIndex,
42
+ typesToDecorate: context.typesToDecorate,
43
+ });
44
+ }
45
+
46
+ return node;
47
+ }
48
+
49
+ function isReactElementNode(node: unknown): node is ReactElementNode {
50
+ return Boolean(node) && typeof node === 'object' && 'type' in node && 'props' in node;
51
+ }
52
+
53
+ function buildButtonTargetId(index: number, parentKey: string | null) {
54
+ const baseTarget = `__expo_widgets_target_${index}`;
55
+
56
+ if (!parentKey) {
57
+ return baseTarget;
58
+ }
59
+
60
+ return `${baseTarget}_${parentKey}`;
61
+ }
@@ -0,0 +1 @@
1
+ export function useReleasingSharedObject() {}
@@ -0,0 +1,15 @@
1
+ export function requireNativeModule(name: string) {
2
+ return {};
3
+ }
4
+
5
+ export function requireNativeView(moduleName: string, viewName: string) {
6
+ const wrapper = {
7
+ [viewName]: (props?: Record<string, any>) => {
8
+ return {
9
+ type: viewName,
10
+ props: props || {},
11
+ };
12
+ },
13
+ };
14
+ return wrapper[viewName] as unknown as React.ComponentType<any>;
15
+ }
@@ -0,0 +1,69 @@
1
+ /* eslint-disable no-var */
2
+
3
+ import * as swiftUI from '@expo/ui/swift-ui';
4
+ import * as modifiers from '@expo/ui/swift-ui/modifiers';
5
+
6
+ import { decorateInteractiveTargets } from './decorator';
7
+ import * as jsxRuntime from './jsx-runtime-stub';
8
+ import * as ReactNative from './react-native-stub';
9
+ import * as React from './react-stub';
10
+
11
+ type Dictionary = Record<string, unknown>;
12
+
13
+ declare global {
14
+ var __expoWidgetLayout: (props: Dictionary, environment: Dictionary) => Dictionary;
15
+ var __expoWidgetRender: (props: Dictionary, environment: Dictionary) => Dictionary;
16
+ var __expoWidgetHandlePress: (
17
+ props: Dictionary,
18
+ environment: Dictionary & { target?: string }
19
+ ) => Dictionary | undefined;
20
+ }
21
+
22
+ const __expoWidgetRender = function (props: Dictionary, environment: Dictionary) {
23
+ const { timestamp, ...rest } = environment;
24
+ const decoratedEnvironment: Dictionary = { ...rest };
25
+ if (timestamp) {
26
+ decoratedEnvironment.date = new Date(timestamp as number);
27
+ }
28
+
29
+ return decorateInteractiveTargets(globalThis.__expoWidgetLayout(props, decoratedEnvironment));
30
+ };
31
+
32
+ const __expoWidgetHandlePress = function (
33
+ props: Dictionary,
34
+ environment: Dictionary & { target?: string }
35
+ ) {
36
+ const { target, ...renderEnvironment } = environment;
37
+
38
+ function findAndCallOnPress(node?: Dictionary): Dictionary | undefined {
39
+ const props = node?.props as {
40
+ onButtonPress?: () => Dictionary;
41
+ target?: string;
42
+ children?: unknown;
43
+ };
44
+ if (props?.onButtonPress && props?.target === target) {
45
+ return props.onButtonPress();
46
+ }
47
+
48
+ for (const child of React.Children.toArray(props?.children)) {
49
+ const result = findAndCallOnPress(child as Dictionary);
50
+ if (result) {
51
+ return result;
52
+ }
53
+ }
54
+ }
55
+
56
+ const node = globalThis.__expoWidgetRender(props, renderEnvironment);
57
+ return findAndCallOnPress(node as Dictionary);
58
+ };
59
+
60
+ Object.assign(globalThis, {
61
+ ...swiftUI,
62
+ ...modifiers,
63
+ ...jsxRuntime,
64
+ ...React,
65
+ ...ReactNative,
66
+ React,
67
+ __expoWidgetRender,
68
+ __expoWidgetHandlePress,
69
+ });
@@ -0,0 +1,71 @@
1
+ import { Fragment } from './react-stub';
2
+
3
+ export type ReactElementNode = {
4
+ type: unknown;
5
+ key: string | null;
6
+ props: Record<string, any>;
7
+ };
8
+
9
+ function ReactElement(
10
+ type: unknown,
11
+ key: string | null,
12
+ props: Record<string, any>
13
+ ): ReactElementNode {
14
+ if (typeof type === 'function') {
15
+ return (type as any)(props);
16
+ }
17
+
18
+ const element = {
19
+ type,
20
+ key,
21
+ props,
22
+ };
23
+
24
+ return element;
25
+ }
26
+
27
+ function jsxProd(
28
+ type: unknown,
29
+ config: any,
30
+ maybeKey?: string | number | bigint
31
+ ): ReactElementNode {
32
+ let key = null;
33
+ if (maybeKey !== undefined) {
34
+ key = '' + maybeKey;
35
+ }
36
+ if (hasValidKey(config)) {
37
+ key = '' + config.key;
38
+ }
39
+
40
+ let props: Record<string, any>;
41
+ if (!('key' in config)) {
42
+ props = config;
43
+ } else {
44
+ props = {};
45
+ for (const propName in config) {
46
+ if (propName !== 'key') {
47
+ props[propName] = config[propName];
48
+ }
49
+ }
50
+ }
51
+
52
+ return ReactElement(type, key, props);
53
+ }
54
+
55
+ function hasValidKey(config: any) {
56
+ return config.key !== undefined;
57
+ }
58
+
59
+ const jsxFileName = 'widget';
60
+ export {
61
+ Fragment,
62
+ Fragment as _Fragment,
63
+ jsxFileName as _jsxFileName,
64
+ jsxProd,
65
+ jsxProd as jsx,
66
+ jsxProd as jsxs,
67
+ jsxProd as jsxDEV,
68
+ jsxProd as _jsx,
69
+ jsxProd as _jsxs,
70
+ jsxProd as _jsxDEV,
71
+ };
@@ -0,0 +1,3 @@
1
+ export const PlatformColor = (...names: string[]) => {
2
+ return { semantic: names };
3
+ };
@@ -0,0 +1,13 @@
1
+ export const Fragment = 'react.fragment';
2
+
3
+ export const Children = {
4
+ toArray(children: unknown) {
5
+ if (children === undefined || children === null) {
6
+ return [];
7
+ }
8
+ return Array.isArray(children) ? children : [children];
9
+ },
10
+ };
11
+ export const isValidElement = (value: unknown) => {
12
+ return Boolean(value) && typeof value === 'object' && 'type' in (value as object);
13
+ };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "platforms": ["ios", "android"],
3
3
  "ios": {
4
- "modules": ["ExpoInvokeModule"]
4
+ "modules": ["ExpoInvokeModule", "WidgetsModule"]
5
5
  },
6
6
  "android": {
7
7
  "modules": ["expo.modules.invoke.ExpoInvokeModule"]