rampkit-expo-dev 0.0.39 → 0.0.41

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.
@@ -2,6 +2,7 @@ import { RampKitContext } from "./types";
2
2
  export declare const injectedHardening = "\n(function(){\n try {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) { meta = document.createElement('meta'); meta.name = 'viewport'; document.head.appendChild(meta); }\n meta.setAttribute('content','width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover');\n var style = document.createElement('style');\n style.textContent='html,body{overflow-x:hidden!important;} html,body,*{-webkit-user-select:none!important;user-select:none!important;-webkit-touch-callout:none!important;-ms-user-select:none!important;touch-action: pan-y;} *{-webkit-tap-highlight-color: rgba(0,0,0,0)!important;} ::selection{background: transparent!important;} ::-moz-selection{background: transparent!important;} a,img{-webkit-user-drag:none!important;user-drag:none!important;-webkit-touch-callout:none!important} input,textarea{caret-color:transparent!important;-webkit-user-select:none!important;user-select:none!important}';\n document.head.appendChild(style);\n var prevent=function(e){e.preventDefault&&e.preventDefault();};\n document.addEventListener('gesturestart',prevent,{passive:false});\n document.addEventListener('gesturechange',prevent,{passive:false});\n document.addEventListener('gestureend',prevent,{passive:false});\n document.addEventListener('dblclick',prevent,{passive:false});\n document.addEventListener('wheel',function(e){ if(e.ctrlKey) e.preventDefault(); },{passive:false});\n document.addEventListener('touchmove',function(e){ if(e.scale && e.scale !== 1) e.preventDefault(); },{passive:false});\n document.addEventListener('selectstart',prevent,{passive:false,capture:true});\n document.addEventListener('contextmenu',prevent,{passive:false,capture:true});\n document.addEventListener('copy',prevent,{passive:false,capture:true});\n document.addEventListener('cut',prevent,{passive:false,capture:true});\n document.addEventListener('paste',prevent,{passive:false,capture:true});\n document.addEventListener('dragstart',prevent,{passive:false,capture:true});\n // Belt-and-suspenders: aggressively clear any attempted selection\n var clearSel=function(){\n try{var sel=window.getSelection&&window.getSelection(); if(sel&&sel.removeAllRanges) sel.removeAllRanges();}catch(_){} }\n document.addEventListener('selectionchange',clearSel,{passive:true,capture:true});\n document.onselectstart=function(){ clearSel(); return false; };\n try{ document.documentElement.style.webkitUserSelect='none'; document.documentElement.style.userSelect='none'; }catch(_){ }\n try{ document.body.style.webkitUserSelect='none'; document.body.style.userSelect='none'; }catch(_){ }\n var __selTimer = setInterval(clearSel, 160);\n window.addEventListener('pagehide',function(){ try{ clearInterval(__selTimer); }catch(_){} });\n // Continuously enforce no-select on all elements and new nodes\n var enforceNoSelect = function(el){\n try{\n el.style && (el.style.webkitUserSelect='none', el.style.userSelect='none', el.style.webkitTouchCallout='none');\n el.setAttribute && (el.setAttribute('unselectable','on'), el.setAttribute('contenteditable','false'));\n }catch(_){}\n }\n try{\n var all=document.getElementsByTagName('*');\n for(var i=0;i<all.length;i++){ enforceNoSelect(all[i]); }\n var obs = new MutationObserver(function(muts){\n for(var j=0;j<muts.length;j++){\n var m=muts[j];\n if(m.type==='childList'){\n m.addedNodes && m.addedNodes.forEach && m.addedNodes.forEach(function(n){ if(n && n.nodeType===1){ enforceNoSelect(n); var q=n.getElementsByTagName? n.getElementsByTagName('*'): []; for(var k=0;k<q.length;k++){ enforceNoSelect(q[k]); }}});\n } else if(m.type==='attributes'){\n enforceNoSelect(m.target);\n }\n }\n });\n obs.observe(document.documentElement,{ childList:true, subtree:true, attributes:true, attributeFilter:['contenteditable','style'] });\n }catch(_){ }\n } catch(_) {}\n})(); true;\n";
3
3
  export declare const injectedNoSelect = "\n(function(){\n try {\n if (window.__rkNoSelectApplied) return true;\n window.__rkNoSelectApplied = true;\n var style = document.getElementById('rk-no-select-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'rk-no-select-style';\n style.innerHTML = \"\n * {\n user-select: none !important;\n -webkit-user-select: none !important;\n -webkit-touch-callout: none !important;\n }\n ::selection {\n background: transparent !important;\n }\n \";\n document.head.appendChild(style);\n }\n var prevent = function(e){ if(e && e.preventDefault) e.preventDefault(); return false; };\n document.addEventListener('contextmenu', prevent, { passive: false, capture: true });\n document.addEventListener('selectstart', prevent, { passive: false, capture: true });\n } catch (_) {}\n true;\n})();\n";
4
4
  export declare const injectedVarsHandler = "\n(function(){\n try {\n if (window.__rkVarsHandlerApplied) return true;\n window.__rkVarsHandlerApplied = true;\n \n // Handler function that updates variables and notifies the page\n window.__rkHandleVarsUpdate = function(vars) {\n if (!vars || typeof vars !== 'object') return;\n // Update the global variables object\n window.__rampkitVariables = vars;\n // Dispatch a custom event that the page's JS can listen to for re-rendering\n try {\n document.dispatchEvent(new CustomEvent('rampkit:vars-updated', { detail: vars }));\n } catch(e) {}\n // Also try calling a global handler if the page defined one\n try {\n if (typeof window.onRampkitVarsUpdate === 'function') {\n window.onRampkitVarsUpdate(vars);\n }\n } catch(e) {}\n };\n \n // Listen for message events from React Native\n document.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n \n // Also listen on window for compatibility\n window.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n } catch (_) {}\n true;\n})();\n";
5
+ export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n \n // Add styles for button animations\n var style = document.createElement('style');\n style.id = 'rk-button-anim-style';\n style.innerHTML = `\n /* Base transition for all interactive elements */\n [data-rampkit-action],\n [data-rampkit-navigate],\n [data-rampkit-tap],\n [onclick],\n button,\n a[href],\n .rk-interactive,\n .rk-button {\n transform: scale(1);\n opacity: 1;\n will-change: transform, opacity;\n }\n \n /* Pressed state - applied via JS */\n .rk-pressed {\n transform: scale(0.97) !important;\n opacity: 0.8 !important;\n transition: transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), \n opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1) !important;\n }\n \n /* Released state - spring-like bounce back */\n .rk-released {\n transform: scale(1) !important;\n opacity: 1 !important;\n transition: transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), \n opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1) !important;\n }\n `;\n document.head.appendChild(style);\n \n // Check if element is interactive\n function isInteractive(el) {\n if (!el || !el.tagName) return false;\n var tag = el.tagName.toLowerCase();\n if (tag === 'button' || tag === 'a') return true;\n if (el.hasAttribute('data-rampkit-action')) return true;\n if (el.hasAttribute('data-rampkit-navigate')) return true;\n if (el.hasAttribute('data-rampkit-tap')) return true;\n if (el.hasAttribute('onclick')) return true;\n if (el.classList.contains('rk-interactive')) return true;\n if (el.classList.contains('rk-button')) return true;\n return false;\n }\n \n // Find the interactive parent element\n function findInteractiveElement(el) {\n var current = el;\n var maxDepth = 10; // Prevent infinite loops\n while (current && maxDepth > 0) {\n if (isInteractive(current)) return current;\n current = current.parentElement;\n maxDepth--;\n }\n return null;\n }\n \n // Track currently pressed element\n var pressedElement = null;\n var pressTimeout = null;\n \n // Handle touch start - immediate press animation\n function handleTouchStart(e) {\n try {\n var target = findInteractiveElement(e.target);\n if (!target) return;\n \n // Clear any pending release animation\n if (pressTimeout) {\n clearTimeout(pressTimeout);\n pressTimeout = null;\n }\n \n // Remove released class and add pressed class\n target.classList.remove('rk-released');\n target.classList.add('rk-pressed');\n pressedElement = target;\n } catch(_) {}\n }\n \n // Handle touch end - spring release animation\n function handleTouchEnd(e) {\n try {\n if (!pressedElement) return;\n var target = pressedElement;\n \n // Switch from pressed to released for spring animation\n target.classList.remove('rk-pressed');\n target.classList.add('rk-released');\n \n // Clean up after animation completes\n pressTimeout = setTimeout(function() {\n target.classList.remove('rk-released');\n pressTimeout = null;\n }, 300);\n \n pressedElement = null;\n } catch(_) {}\n }\n \n // Handle touch cancel - reset without animation\n function handleTouchCancel(e) {\n try {\n if (!pressedElement) return;\n pressedElement.classList.remove('rk-pressed');\n pressedElement.classList.remove('rk-released');\n pressedElement = null;\n if (pressTimeout) {\n clearTimeout(pressTimeout);\n pressTimeout = null;\n }\n } catch(_) {}\n }\n \n // Use capture phase to get events before they're handled\n document.addEventListener('touchstart', handleTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', handleTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', handleTouchCancel, { passive: true, capture: true });\n \n // Also handle mouse events for web testing\n document.addEventListener('mousedown', handleTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', handleTouchEnd, { passive: true, capture: true });\n document.addEventListener('mouseleave', handleTouchCancel, { passive: true, capture: true });\n \n } catch (_) {}\n true;\n})();\n";
5
6
  export type ScreenPayload = {
6
7
  id: string;
7
8
  html: string;
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.injectedVarsHandler = exports.injectedNoSelect = exports.injectedHardening = void 0;
39
+ exports.injectedButtonAnimations = exports.injectedVarsHandler = exports.injectedNoSelect = exports.injectedHardening = void 0;
40
40
  exports.showRampkitOverlay = showRampkitOverlay;
41
41
  exports.hideRampkitOverlay = hideRampkitOverlay;
42
42
  exports.closeRampkitOverlay = closeRampkitOverlay;
@@ -173,6 +173,147 @@ exports.injectedVarsHandler = `
173
173
  true;
174
174
  })();
175
175
  `;
176
+ // Button tap animation script - handles spring animations for interactive elements
177
+ // Triggers on touchstart (not click) for immediate feedback
178
+ exports.injectedButtonAnimations = `
179
+ (function(){
180
+ try {
181
+ if (window.__rkButtonAnimApplied) return true;
182
+ window.__rkButtonAnimApplied = true;
183
+
184
+ // Add styles for button animations
185
+ var style = document.createElement('style');
186
+ style.id = 'rk-button-anim-style';
187
+ style.innerHTML = \`
188
+ /* Base transition for all interactive elements */
189
+ [data-rampkit-action],
190
+ [data-rampkit-navigate],
191
+ [data-rampkit-tap],
192
+ [onclick],
193
+ button,
194
+ a[href],
195
+ .rk-interactive,
196
+ .rk-button {
197
+ transform: scale(1);
198
+ opacity: 1;
199
+ will-change: transform, opacity;
200
+ }
201
+
202
+ /* Pressed state - applied via JS */
203
+ .rk-pressed {
204
+ transform: scale(0.97) !important;
205
+ opacity: 0.8 !important;
206
+ transition: transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1),
207
+ opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1) !important;
208
+ }
209
+
210
+ /* Released state - spring-like bounce back */
211
+ .rk-released {
212
+ transform: scale(1) !important;
213
+ opacity: 1 !important;
214
+ transition: transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1),
215
+ opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1) !important;
216
+ }
217
+ \`;
218
+ document.head.appendChild(style);
219
+
220
+ // Check if element is interactive
221
+ function isInteractive(el) {
222
+ if (!el || !el.tagName) return false;
223
+ var tag = el.tagName.toLowerCase();
224
+ if (tag === 'button' || tag === 'a') return true;
225
+ if (el.hasAttribute('data-rampkit-action')) return true;
226
+ if (el.hasAttribute('data-rampkit-navigate')) return true;
227
+ if (el.hasAttribute('data-rampkit-tap')) return true;
228
+ if (el.hasAttribute('onclick')) return true;
229
+ if (el.classList.contains('rk-interactive')) return true;
230
+ if (el.classList.contains('rk-button')) return true;
231
+ return false;
232
+ }
233
+
234
+ // Find the interactive parent element
235
+ function findInteractiveElement(el) {
236
+ var current = el;
237
+ var maxDepth = 10; // Prevent infinite loops
238
+ while (current && maxDepth > 0) {
239
+ if (isInteractive(current)) return current;
240
+ current = current.parentElement;
241
+ maxDepth--;
242
+ }
243
+ return null;
244
+ }
245
+
246
+ // Track currently pressed element
247
+ var pressedElement = null;
248
+ var pressTimeout = null;
249
+
250
+ // Handle touch start - immediate press animation
251
+ function handleTouchStart(e) {
252
+ try {
253
+ var target = findInteractiveElement(e.target);
254
+ if (!target) return;
255
+
256
+ // Clear any pending release animation
257
+ if (pressTimeout) {
258
+ clearTimeout(pressTimeout);
259
+ pressTimeout = null;
260
+ }
261
+
262
+ // Remove released class and add pressed class
263
+ target.classList.remove('rk-released');
264
+ target.classList.add('rk-pressed');
265
+ pressedElement = target;
266
+ } catch(_) {}
267
+ }
268
+
269
+ // Handle touch end - spring release animation
270
+ function handleTouchEnd(e) {
271
+ try {
272
+ if (!pressedElement) return;
273
+ var target = pressedElement;
274
+
275
+ // Switch from pressed to released for spring animation
276
+ target.classList.remove('rk-pressed');
277
+ target.classList.add('rk-released');
278
+
279
+ // Clean up after animation completes
280
+ pressTimeout = setTimeout(function() {
281
+ target.classList.remove('rk-released');
282
+ pressTimeout = null;
283
+ }, 300);
284
+
285
+ pressedElement = null;
286
+ } catch(_) {}
287
+ }
288
+
289
+ // Handle touch cancel - reset without animation
290
+ function handleTouchCancel(e) {
291
+ try {
292
+ if (!pressedElement) return;
293
+ pressedElement.classList.remove('rk-pressed');
294
+ pressedElement.classList.remove('rk-released');
295
+ pressedElement = null;
296
+ if (pressTimeout) {
297
+ clearTimeout(pressTimeout);
298
+ pressTimeout = null;
299
+ }
300
+ } catch(_) {}
301
+ }
302
+
303
+ // Use capture phase to get events before they're handled
304
+ document.addEventListener('touchstart', handleTouchStart, { passive: true, capture: true });
305
+ document.addEventListener('touchend', handleTouchEnd, { passive: true, capture: true });
306
+ document.addEventListener('touchcancel', handleTouchCancel, { passive: true, capture: true });
307
+
308
+ // Also handle mouse events for web testing
309
+ document.addEventListener('mousedown', handleTouchStart, { passive: true, capture: true });
310
+ document.addEventListener('mouseup', handleTouchEnd, { passive: true, capture: true });
311
+ document.addEventListener('mouseleave', handleTouchCancel, { passive: true, capture: true });
312
+
313
+ } catch (_) {}
314
+ true;
315
+ })();
316
+ `;
176
317
  function performRampkitHaptic(event) {
177
318
  if (!event || event.action !== "haptic") {
178
319
  // Backwards compatible default
@@ -272,7 +413,7 @@ function preloadRampkitOverlay(opts) {
272
413
  opacity: 0,
273
414
  top: -1000,
274
415
  left: -1000,
275
- }, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { originWhitelist: ["*"], source: { html: docs[0] || "<html></html>" }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, hideKeyboardAccessoryView: true }) }));
416
+ }, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { originWhitelist: ["*"], source: { html: docs[0] || "<html></html>" }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler + exports.injectedButtonAnimations, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, hideKeyboardAccessoryView: true }) }));
276
417
  preloadSibling = new react_native_root_siblings_1.default((0, jsx_runtime_1.jsx)(HiddenPreloader, {}));
277
418
  }
278
419
  catch (e) {
@@ -432,14 +573,9 @@ function Overlay(props) {
432
573
  const [onboardingCompleted, setOnboardingCompleted] = (0, react_1.useState)(false);
433
574
  const overlayOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
434
575
  const fadeOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
435
- // slideFade animation values
436
- const slideFadeOutgoingOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
437
- const slideFadeOutgoingTranslateX = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
438
- const slideFadeIncomingOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
439
- const slideFadeIncomingTranslateX = (0, react_1.useRef)(new react_native_1.Animated.Value(SLIDE_FADE_OFFSET)).current;
440
- const [slideFadeActive, setSlideFadeActive] = (0, react_1.useState)(false);
441
- const [slideFadeOutgoingIndex, setSlideFadeOutgoingIndex] = (0, react_1.useState)(null);
442
- const [slideFadeIncomingIndex, setSlideFadeIncomingIndex] = (0, react_1.useState)(null);
576
+ // slideFade animation values - animates the PagerView container
577
+ const pagerOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
578
+ const pagerTranslateX = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
443
579
  const allLoaded = loadedCount >= props.screens.length;
444
580
  const hasTrackedInitialScreen = (0, react_1.useRef)(false);
445
581
  // shared vars across all webviews
@@ -521,68 +657,55 @@ function Overlay(props) {
521
657
  });
522
658
  return;
523
659
  }
524
- // slideFade animation: simultaneous opacity and translateX animation
525
- // for both outgoing and incoming views
660
+ // slideFade animation: smooth slide + fade transition
661
+ // Animates the PagerView container out, switches page, then animates back in
526
662
  if (animationType === "slidefade") {
527
663
  setIsTransitioning(true);
528
664
  // Determine direction: forward (nextIndex > index) or backward
529
665
  const isForward = nextIndex > index;
530
666
  const direction = isForward ? 1 : -1;
531
- // Set up the slideFade overlay indices
532
- setSlideFadeOutgoingIndex(index);
533
- setSlideFadeIncomingIndex(nextIndex);
534
- // Set initial positions for the animation
535
- // Outgoing: starts visible at position 0
536
- slideFadeOutgoingOpacity.setValue(1);
537
- slideFadeOutgoingTranslateX.setValue(0);
538
- // Incoming: starts invisible, offset in the direction we're navigating
539
- slideFadeIncomingOpacity.setValue(0);
540
- slideFadeIncomingTranslateX.setValue(SLIDE_FADE_OFFSET * direction);
541
- // Activate the slideFade overlay
542
- setSlideFadeActive(true);
543
- // Switch the underlying PagerView immediately (without animation)
544
- // so when the overlay fades away, the correct page is underneath
545
- requestAnimationFrame(() => {
546
- var _a, _b, _c, _d;
547
- // @ts-ignore: method exists on PagerView instance
548
- (_c = (_b = (_a = pagerRef.current) === null || _a === void 0 ? void 0 : _a.setPageWithoutAnimation) === null || _b === void 0 ? void 0 : _b.call(_a, nextIndex)) !== null && _c !== void 0 ? _c : (_d = pagerRef.current) === null || _d === void 0 ? void 0 : _d.setPage(nextIndex);
549
- });
550
- // Run all 4 animations simultaneously
667
+ const halfDuration = SLIDE_FADE_DURATION / 2;
551
668
  const timingConfig = {
552
- duration: SLIDE_FADE_DURATION,
669
+ duration: halfDuration,
553
670
  easing: react_native_1.Easing.out(react_native_1.Easing.ease),
554
671
  useNativeDriver: true,
555
672
  };
673
+ // Phase 1: Fade out and slide the current page in exit direction
556
674
  react_native_1.Animated.parallel([
557
- // Outgoing: fade out and slide in opposite direction
558
- react_native_1.Animated.timing(slideFadeOutgoingOpacity, {
675
+ react_native_1.Animated.timing(pagerOpacity, {
559
676
  toValue: 0,
560
677
  ...timingConfig,
561
678
  }),
562
- react_native_1.Animated.timing(slideFadeOutgoingTranslateX, {
563
- toValue: -SLIDE_FADE_OFFSET * direction,
564
- ...timingConfig,
565
- }),
566
- // Incoming: fade in and slide to center
567
- react_native_1.Animated.timing(slideFadeIncomingOpacity, {
568
- toValue: 1,
569
- ...timingConfig,
570
- }),
571
- react_native_1.Animated.timing(slideFadeIncomingTranslateX, {
572
- toValue: 0,
679
+ react_native_1.Animated.timing(pagerTranslateX, {
680
+ toValue: -SLIDE_FADE_OFFSET * direction * 0.5, // Slide out in opposite direction
573
681
  ...timingConfig,
574
682
  }),
575
683
  ]).start(() => {
576
- // Animation complete - deactivate overlay and reset values
577
- setSlideFadeActive(false);
578
- setSlideFadeOutgoingIndex(null);
579
- setSlideFadeIncomingIndex(null);
580
- // Reset outgoing view values for next animation
581
- slideFadeOutgoingOpacity.setValue(1);
582
- slideFadeOutgoingTranslateX.setValue(0);
583
- // Send vars to the new page
584
- sendVarsToWebView(nextIndex);
585
- setIsTransitioning(false);
684
+ var _a, _b, _c, _d;
685
+ // Switch page instantly while invisible
686
+ // @ts-ignore: method exists on PagerView instance
687
+ (_c = (_b = (_a = pagerRef.current) === null || _a === void 0 ? void 0 : _a.setPageWithoutAnimation) === null || _b === void 0 ? void 0 : _b.call(_a, nextIndex)) !== null && _c !== void 0 ? _c : (_d = pagerRef.current) === null || _d === void 0 ? void 0 : _d.setPage(nextIndex);
688
+ // Set up for incoming animation - start from the direction we're navigating from
689
+ pagerTranslateX.setValue(SLIDE_FADE_OFFSET * direction * 0.5);
690
+ // Phase 2: Fade in and slide the new page to center
691
+ react_native_1.Animated.parallel([
692
+ react_native_1.Animated.timing(pagerOpacity, {
693
+ toValue: 1,
694
+ duration: halfDuration,
695
+ easing: react_native_1.Easing.out(react_native_1.Easing.ease),
696
+ useNativeDriver: true,
697
+ }),
698
+ react_native_1.Animated.timing(pagerTranslateX, {
699
+ toValue: 0,
700
+ duration: halfDuration,
701
+ easing: react_native_1.Easing.out(react_native_1.Easing.ease),
702
+ useNativeDriver: true,
703
+ }),
704
+ ]).start(() => {
705
+ // Send vars to the new page
706
+ sendVarsToWebView(nextIndex);
707
+ setIsTransitioning(false);
708
+ });
586
709
  });
587
710
  return;
588
711
  }
@@ -839,138 +962,166 @@ function Overlay(props) {
839
962
  styles.root,
840
963
  !visible && styles.invisible,
841
964
  visible && { opacity: overlayOpacity },
842
- ], pointerEvents: visible && !isClosing ? "auto" : "none", children: [(0, jsx_runtime_1.jsx)(react_native_pager_view_1.default, { ref: pagerRef, style: react_native_1.StyleSheet.absoluteFill, scrollEnabled: false, initialPage: 0, onPageSelected: onPageSelected, offscreenPageLimit: props.screens.length, overScrollMode: "never", children: docs.map((doc, i) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.page, renderToHardwareTextureAndroid: true, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { ref: (r) => (webviewsRef.current[i] = r), style: styles.webview, originWhitelist: ["*"], source: { html: doc }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, hideKeyboardAccessoryView: true, onLoadEnd: () => {
843
- setLoadedCount((c) => c + 1);
844
- if (i === 0) {
845
- setFirstPageLoaded(true);
846
- // Track initial screen view
847
- if (!hasTrackedInitialScreen.current && props.onScreenChange && props.screens[0]) {
848
- hasTrackedInitialScreen.current = true;
849
- props.onScreenChange(0, props.screens[0].id);
850
- }
851
- }
852
- // Initialize this page with current vars (isInitialLoad=true to enable stale filter)
853
- if (__DEV__)
854
- console.log("[Rampkit] onLoadEnd init send vars", i);
855
- sendVarsToWebView(i, true);
856
- }, onMessage: (ev) => {
857
- var _a, _b, _c, _d;
858
- const raw = ev.nativeEvent.data;
859
- console.log("raw", raw);
860
- // Accept either raw strings or JSON payloads from your editor
861
- try {
862
- // JSON path
863
- const data = JSON.parse(raw);
864
- // 1) Variables from a page → update shared + broadcast to OTHER pages
865
- // This mirrors the iOS SDK pattern with stale value filtering.
866
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:variables" &&
867
- (data === null || data === void 0 ? void 0 : data.vars) &&
868
- typeof data.vars === "object") {
869
- if (__DEV__)
870
- console.log("[Rampkit] received variables from page", i, data.vars);
871
- // Check if this page is within the stale value window
872
- // (we recently sent vars to it and it may be echoing back defaults)
873
- const now = Date.now();
874
- const lastSendTime = lastVarsSendTimeRef.current[i] || 0;
875
- const timeSinceSend = now - lastSendTime;
876
- const isWithinStaleWindow = timeSinceSend < STALE_VALUE_WINDOW_MS;
877
- if (__DEV__) {
878
- console.log("[Rampkit] stale check:", {
879
- pageIndex: i,
880
- isWithinStaleWindow,
881
- timeSinceSend,
882
- });
965
+ ], pointerEvents: visible && !isClosing ? "auto" : "none", children: [(0, jsx_runtime_1.jsx)(react_native_1.Animated.View, { style: [
966
+ react_native_1.StyleSheet.absoluteFill,
967
+ {
968
+ opacity: pagerOpacity,
969
+ transform: [{ translateX: pagerTranslateX }],
970
+ },
971
+ ], children: (0, jsx_runtime_1.jsx)(react_native_pager_view_1.default, { ref: pagerRef, style: react_native_1.StyleSheet.absoluteFill, scrollEnabled: false, initialPage: 0, onPageSelected: onPageSelected, offscreenPageLimit: props.screens.length, overScrollMode: "never", children: docs.map((doc, i) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.page, renderToHardwareTextureAndroid: true, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { ref: (r) => (webviewsRef.current[i] = r), style: styles.webview, originWhitelist: ["*"], source: { html: doc }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler + exports.injectedButtonAnimations, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, hideKeyboardAccessoryView: true, onLoadEnd: () => {
972
+ setLoadedCount((c) => c + 1);
973
+ if (i === 0) {
974
+ setFirstPageLoaded(true);
975
+ // Track initial screen view
976
+ if (!hasTrackedInitialScreen.current && props.onScreenChange && props.screens[0]) {
977
+ hasTrackedInitialScreen.current = true;
978
+ props.onScreenChange(0, props.screens[0].id);
883
979
  }
884
- let changed = false;
885
- const newVars = {};
886
- for (const [key, value] of Object.entries(data.vars)) {
887
- const hasHostVal = Object.prototype.hasOwnProperty.call(varsRef.current, key);
888
- const hostVal = varsRef.current[key];
889
- // Stale value filtering (matches iOS SDK behavior):
890
- // If we're within the stale window, don't let empty/default values
891
- // overwrite existing non-empty host values.
892
- // This prevents pages from clobbering user input with cached defaults
893
- // when they first become active/visible.
894
- if (isWithinStaleWindow && hasHostVal) {
895
- const hostIsNonEmpty = hostVal !== "" && hostVal !== null && hostVal !== undefined;
896
- const incomingIsEmpty = value === "" || value === null || value === undefined;
897
- if (hostIsNonEmpty && incomingIsEmpty) {
898
- if (__DEV__) {
899
- console.log(`[Rampkit] filtering stale empty value for key "${key}": keeping "${hostVal}"`);
980
+ }
981
+ // Initialize this page with current vars (isInitialLoad=true to enable stale filter)
982
+ if (__DEV__)
983
+ console.log("[Rampkit] onLoadEnd init send vars", i);
984
+ sendVarsToWebView(i, true);
985
+ }, onMessage: (ev) => {
986
+ var _a, _b, _c, _d;
987
+ const raw = ev.nativeEvent.data;
988
+ console.log("raw", raw);
989
+ // Accept either raw strings or JSON payloads from your editor
990
+ try {
991
+ // JSON path
992
+ const data = JSON.parse(raw);
993
+ // 1) Variables from a page → update shared + broadcast to OTHER pages
994
+ // This mirrors the iOS SDK pattern with stale value filtering.
995
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:variables" &&
996
+ (data === null || data === void 0 ? void 0 : data.vars) &&
997
+ typeof data.vars === "object") {
998
+ if (__DEV__)
999
+ console.log("[Rampkit] received variables from page", i, data.vars);
1000
+ // Check if this page is within the stale value window
1001
+ // (we recently sent vars to it and it may be echoing back defaults)
1002
+ const now = Date.now();
1003
+ const lastSendTime = lastVarsSendTimeRef.current[i] || 0;
1004
+ const timeSinceSend = now - lastSendTime;
1005
+ const isWithinStaleWindow = timeSinceSend < STALE_VALUE_WINDOW_MS;
1006
+ if (__DEV__) {
1007
+ console.log("[Rampkit] stale check:", {
1008
+ pageIndex: i,
1009
+ isWithinStaleWindow,
1010
+ timeSinceSend,
1011
+ });
1012
+ }
1013
+ let changed = false;
1014
+ const newVars = {};
1015
+ for (const [key, value] of Object.entries(data.vars)) {
1016
+ const hasHostVal = Object.prototype.hasOwnProperty.call(varsRef.current, key);
1017
+ const hostVal = varsRef.current[key];
1018
+ // Stale value filtering (matches iOS SDK behavior):
1019
+ // If we're within the stale window, don't let empty/default values
1020
+ // overwrite existing non-empty host values.
1021
+ // This prevents pages from clobbering user input with cached defaults
1022
+ // when they first become active/visible.
1023
+ if (isWithinStaleWindow && hasHostVal) {
1024
+ const hostIsNonEmpty = hostVal !== "" && hostVal !== null && hostVal !== undefined;
1025
+ const incomingIsEmpty = value === "" || value === null || value === undefined;
1026
+ if (hostIsNonEmpty && incomingIsEmpty) {
1027
+ if (__DEV__) {
1028
+ console.log(`[Rampkit] filtering stale empty value for key "${key}": keeping "${hostVal}"`);
1029
+ }
1030
+ continue; // Skip this key, keep host value
900
1031
  }
901
- continue; // Skip this key, keep host value
1032
+ }
1033
+ // Accept the update if value is different
1034
+ if (!hasHostVal || hostVal !== value) {
1035
+ newVars[key] = value;
1036
+ changed = true;
902
1037
  }
903
1038
  }
904
- // Accept the update if value is different
905
- if (!hasHostVal || hostVal !== value) {
906
- newVars[key] = value;
907
- changed = true;
1039
+ if (changed) {
1040
+ varsRef.current = { ...varsRef.current, ...newVars };
1041
+ // Broadcast to all WebViews EXCEPT the source (index i)
1042
+ // This prevents echo loops and matches iOS SDK behavior
1043
+ broadcastVars(i);
908
1044
  }
1045
+ return;
909
1046
  }
910
- if (changed) {
911
- varsRef.current = { ...varsRef.current, ...newVars };
912
- // Broadcast to all WebViews EXCEPT the source (index i)
913
- // This prevents echo loops and matches iOS SDK behavior
914
- broadcastVars(i);
1047
+ // 2) A page asked for current vars → send only to that page
1048
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-vars") {
1049
+ if (__DEV__)
1050
+ console.log("[Rampkit] request-vars from page", i);
1051
+ sendVarsToWebView(i);
1052
+ return;
915
1053
  }
916
- return;
917
- }
918
- // 2) A page asked for current vars send only to that page
919
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-vars") {
920
- if (__DEV__)
921
- console.log("[Rampkit] request-vars from page", i);
922
- sendVarsToWebView(i);
923
- return;
924
- }
925
- // 3) A page requested an in-app review prompt
926
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-review" ||
927
- (data === null || data === void 0 ? void 0 : data.type) === "rampkit:review") {
928
- (async () => {
929
- try {
930
- const available = await RampKitNative_1.StoreReview.isAvailableAsync();
931
- if (available) {
932
- await RampKitNative_1.StoreReview.requestReview();
1054
+ // 3) A page requested an in-app review prompt
1055
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-review" ||
1056
+ (data === null || data === void 0 ? void 0 : data.type) === "rampkit:review") {
1057
+ (async () => {
1058
+ try {
1059
+ const available = await RampKitNative_1.StoreReview.isAvailableAsync();
1060
+ if (available) {
1061
+ await RampKitNative_1.StoreReview.requestReview();
1062
+ }
933
1063
  }
1064
+ catch (_) { }
1065
+ })();
1066
+ return;
1067
+ }
1068
+ // 4) A page requested notification permission
1069
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-notification-permission") {
1070
+ handleNotificationPermissionRequest({
1071
+ ios: data === null || data === void 0 ? void 0 : data.ios,
1072
+ android: data === null || data === void 0 ? void 0 : data.android,
1073
+ behavior: data === null || data === void 0 ? void 0 : data.behavior,
1074
+ });
1075
+ return;
1076
+ }
1077
+ // 5) Onboarding finished event from page
1078
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:onboarding-finished") {
1079
+ setOnboardingCompleted(true);
1080
+ try {
1081
+ (_a = props.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(props, data === null || data === void 0 ? void 0 : data.payload);
934
1082
  }
935
1083
  catch (_) { }
936
- })();
937
- return;
938
- }
939
- // 4) A page requested notification permission
940
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-notification-permission") {
941
- handleNotificationPermissionRequest({
942
- ios: data === null || data === void 0 ? void 0 : data.ios,
943
- android: data === null || data === void 0 ? void 0 : data.android,
944
- behavior: data === null || data === void 0 ? void 0 : data.behavior,
945
- });
946
- return;
947
- }
948
- // 5) Onboarding finished event from page
949
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:onboarding-finished") {
950
- setOnboardingCompleted(true);
951
- try {
952
- (_a = props.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(props, data === null || data === void 0 ? void 0 : data.payload);
1084
+ handleRequestClose({ completed: true });
1085
+ return;
953
1086
  }
954
- catch (_) { }
955
- handleRequestClose({ completed: true });
956
- return;
957
- }
958
- // 6) Request to show paywall
959
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:show-paywall") {
960
- try {
961
- (_b = props.onShowPaywall) === null || _b === void 0 ? void 0 : _b.call(props, data === null || data === void 0 ? void 0 : data.payload);
1087
+ // 6) Request to show paywall
1088
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:show-paywall") {
1089
+ try {
1090
+ (_b = props.onShowPaywall) === null || _b === void 0 ? void 0 : _b.call(props, data === null || data === void 0 ? void 0 : data.payload);
1091
+ }
1092
+ catch (_) { }
1093
+ return;
962
1094
  }
963
- catch (_) { }
964
- return;
965
- }
966
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
967
- (data === null || data === void 0 ? void 0 : data.type) === "continue") {
968
- handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
969
- return;
970
- }
971
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:navigate") {
972
- const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
973
- if (target === "__goBack__") {
1095
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
1096
+ (data === null || data === void 0 ? void 0 : data.type) === "continue") {
1097
+ handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1098
+ return;
1099
+ }
1100
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:navigate") {
1101
+ const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
1102
+ if (target === "__goBack__") {
1103
+ if (i > 0) {
1104
+ navigateToIndex(i - 1, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1105
+ }
1106
+ else {
1107
+ handleRequestClose();
1108
+ }
1109
+ return;
1110
+ }
1111
+ if (!target || target === "__continue__") {
1112
+ handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1113
+ return;
1114
+ }
1115
+ const targetIndex = props.screens.findIndex((s) => s.id === target);
1116
+ if (targetIndex >= 0) {
1117
+ navigateToIndex(targetIndex, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1118
+ }
1119
+ else {
1120
+ handleAdvance(i);
1121
+ }
1122
+ return;
1123
+ }
1124
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:goBack") {
974
1125
  if (i > 0) {
975
1126
  navigateToIndex(i - 1, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
976
1127
  }
@@ -979,89 +1130,56 @@ function Overlay(props) {
979
1130
  }
980
1131
  return;
981
1132
  }
982
- if (!target || target === "__continue__") {
983
- handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1133
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
1134
+ handleRequestClose();
984
1135
  return;
985
1136
  }
986
- const targetIndex = props.screens.findIndex((s) => s.id === target);
987
- if (targetIndex >= 0) {
988
- navigateToIndex(targetIndex, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1137
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:haptic") {
1138
+ performRampkitHaptic(data);
1139
+ return;
989
1140
  }
990
- else {
1141
+ }
1142
+ catch (_e) {
1143
+ // String path
1144
+ if (raw === "rampkit:tap" ||
1145
+ raw === "next" ||
1146
+ raw === "continue") {
991
1147
  handleAdvance(i);
1148
+ return;
992
1149
  }
993
- return;
994
- }
995
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:goBack") {
996
- if (i > 0) {
997
- navigateToIndex(i - 1, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
1150
+ if (raw === "rampkit:request-review" || raw === "rampkit:review") {
1151
+ (async () => {
1152
+ try {
1153
+ const available = await RampKitNative_1.StoreReview.isAvailableAsync();
1154
+ if (available) {
1155
+ await RampKitNative_1.StoreReview.requestReview();
1156
+ }
1157
+ }
1158
+ catch (_) { }
1159
+ })();
1160
+ return;
998
1161
  }
999
- else {
1000
- handleRequestClose();
1162
+ if (raw === "rampkit:request-notification-permission") {
1163
+ handleNotificationPermissionRequest(undefined);
1164
+ return;
1001
1165
  }
1002
- return;
1003
- }
1004
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
1005
- handleRequestClose();
1006
- return;
1007
- }
1008
- if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:haptic") {
1009
- performRampkitHaptic(data);
1010
- return;
1011
- }
1012
- }
1013
- catch (_e) {
1014
- // String path
1015
- if (raw === "rampkit:tap" ||
1016
- raw === "next" ||
1017
- raw === "continue") {
1018
- handleAdvance(i);
1019
- return;
1020
- }
1021
- if (raw === "rampkit:request-review" || raw === "rampkit:review") {
1022
- (async () => {
1166
+ if (raw === "rampkit:onboarding-finished") {
1167
+ setOnboardingCompleted(true);
1023
1168
  try {
1024
- const available = await RampKitNative_1.StoreReview.isAvailableAsync();
1025
- if (available) {
1026
- await RampKitNative_1.StoreReview.requestReview();
1027
- }
1169
+ (_c = props.onOnboardingFinished) === null || _c === void 0 ? void 0 : _c.call(props, undefined);
1028
1170
  }
1029
1171
  catch (_) { }
1030
- })();
1031
- return;
1032
- }
1033
- if (raw === "rampkit:request-notification-permission") {
1034
- handleNotificationPermissionRequest(undefined);
1035
- return;
1036
- }
1037
- if (raw === "rampkit:onboarding-finished") {
1038
- setOnboardingCompleted(true);
1039
- try {
1040
- (_c = props.onOnboardingFinished) === null || _c === void 0 ? void 0 : _c.call(props, undefined);
1041
- }
1042
- catch (_) { }
1043
- handleRequestClose({ completed: true });
1044
- return;
1045
- }
1046
- if (raw === "rampkit:show-paywall") {
1047
- try {
1048
- (_d = props.onShowPaywall) === null || _d === void 0 ? void 0 : _d.call(props);
1049
- }
1050
- catch (_) { }
1051
- return;
1052
- }
1053
- if (raw === "rampkit:goBack") {
1054
- if (i > 0) {
1055
- navigateToIndex(i - 1);
1172
+ handleRequestClose({ completed: true });
1173
+ return;
1056
1174
  }
1057
- else {
1058
- handleRequestClose();
1175
+ if (raw === "rampkit:show-paywall") {
1176
+ try {
1177
+ (_d = props.onShowPaywall) === null || _d === void 0 ? void 0 : _d.call(props);
1178
+ }
1179
+ catch (_) { }
1180
+ return;
1059
1181
  }
1060
- return;
1061
- }
1062
- if (raw.startsWith("rampkit:navigate:")) {
1063
- const target = raw.slice("rampkit:navigate:".length);
1064
- if (target === "__goBack__") {
1182
+ if (raw === "rampkit:goBack") {
1065
1183
  if (i > 0) {
1066
1184
  navigateToIndex(i - 1);
1067
1185
  }
@@ -1070,58 +1188,55 @@ function Overlay(props) {
1070
1188
  }
1071
1189
  return;
1072
1190
  }
1073
- if (!target || target === "__continue__") {
1074
- handleAdvance(i);
1191
+ if (raw.startsWith("rampkit:navigate:")) {
1192
+ const target = raw.slice("rampkit:navigate:".length);
1193
+ if (target === "__goBack__") {
1194
+ if (i > 0) {
1195
+ navigateToIndex(i - 1);
1196
+ }
1197
+ else {
1198
+ handleRequestClose();
1199
+ }
1200
+ return;
1201
+ }
1202
+ if (!target || target === "__continue__") {
1203
+ handleAdvance(i);
1204
+ return;
1205
+ }
1206
+ const targetIndex = props.screens.findIndex((s) => s.id === target);
1207
+ if (targetIndex >= 0) {
1208
+ navigateToIndex(targetIndex);
1209
+ }
1210
+ else {
1211
+ handleAdvance(i);
1212
+ }
1075
1213
  return;
1076
1214
  }
1077
- const targetIndex = props.screens.findIndex((s) => s.id === target);
1078
- if (targetIndex >= 0) {
1079
- navigateToIndex(targetIndex);
1215
+ if (raw === "rampkit:close") {
1216
+ handleRequestClose();
1217
+ return;
1080
1218
  }
1081
- else {
1082
- handleAdvance(i);
1219
+ if (raw.startsWith("haptic:")) {
1220
+ performRampkitHaptic({
1221
+ type: "rampkit:haptic",
1222
+ nodeId: null,
1223
+ nodeType: null,
1224
+ animation: "none",
1225
+ action: "haptic",
1226
+ hapticType: "impact",
1227
+ impactStyle: "Medium",
1228
+ notificationType: null,
1229
+ timestamp: Date.now(),
1230
+ });
1231
+ return;
1083
1232
  }
1084
- return;
1085
1233
  }
1086
- if (raw === "rampkit:close") {
1087
- handleRequestClose();
1088
- return;
1089
- }
1090
- if (raw.startsWith("haptic:")) {
1091
- performRampkitHaptic({
1092
- type: "rampkit:haptic",
1093
- nodeId: null,
1094
- nodeType: null,
1095
- animation: "none",
1096
- action: "haptic",
1097
- hapticType: "impact",
1098
- impactStyle: "Medium",
1099
- notificationType: null,
1100
- timestamp: Date.now(),
1101
- });
1102
- return;
1103
- }
1104
- }
1105
- // No-op for other messages, but useful to log while testing
1106
- // console.log("WebView message:", raw);
1107
- }, onError: (e) => {
1108
- // You can surface an inline error UI here if you want
1109
- console.warn("WebView error:", e.nativeEvent);
1110
- } }) }, props.screens[i].id))) }), slideFadeActive && slideFadeOutgoingIndex !== null && slideFadeIncomingIndex !== null && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_native_1.Animated.View, { pointerEvents: "none", style: [
1111
- react_native_1.StyleSheet.absoluteFillObject,
1112
- styles.slideFadeLayer,
1113
- {
1114
- opacity: slideFadeOutgoingOpacity,
1115
- transform: [{ translateX: slideFadeOutgoingTranslateX }],
1116
- },
1117
- ], children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { style: styles.webview, originWhitelist: ["*"], source: { html: docs[slideFadeOutgoingIndex] }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, hideKeyboardAccessoryView: true }) }), (0, jsx_runtime_1.jsx)(react_native_1.Animated.View, { pointerEvents: "none", style: [
1118
- react_native_1.StyleSheet.absoluteFillObject,
1119
- styles.slideFadeLayer,
1120
- {
1121
- opacity: slideFadeIncomingOpacity,
1122
- transform: [{ translateX: slideFadeIncomingTranslateX }],
1123
- },
1124
- ], children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { style: styles.webview, originWhitelist: ["*"], source: { html: docs[slideFadeIncomingIndex] }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, hideKeyboardAccessoryView: true }) })] })), (0, jsx_runtime_1.jsx)(react_native_1.Animated.View, { pointerEvents: isTransitioning ? "auto" : "none", style: [
1234
+ // No-op for other messages, but useful to log while testing
1235
+ // console.log("WebView message:", raw);
1236
+ }, onError: (e) => {
1237
+ // You can surface an inline error UI here if you want
1238
+ console.warn("WebView error:", e.nativeEvent);
1239
+ } }) }, props.screens[i].id))) }) }), (0, jsx_runtime_1.jsx)(react_native_1.Animated.View, { pointerEvents: isTransitioning ? "auto" : "none", style: [
1125
1240
  react_native_1.StyleSheet.absoluteFillObject,
1126
1241
  styles.curtain,
1127
1242
  { opacity: fadeOpacity },
@@ -1144,9 +1259,5 @@ const styles = react_native_1.StyleSheet.create({
1144
1259
  center: { flex: 1, alignItems: "center", justifyContent: "center" },
1145
1260
  webview: { flex: 1 },
1146
1261
  curtain: { backgroundColor: "white" },
1147
- slideFadeLayer: {
1148
- backgroundColor: "white",
1149
- zIndex: 10000,
1150
- },
1151
1262
  });
1152
1263
  exports.default = Overlay;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rampkit-expo-dev",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "The Expo SDK for RampKit. Build, test, and personalize app onboardings with instant updates.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",