@getuserfeedback/react-native 3.0.56 → 3.0.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- import { planWidgetLayoutTransition, toInstantWidgetLayoutSizeUpdate, } from "@getuserfeedback/protocol/host";
2
- import { createElement, useCallback, useEffect, useMemo, useRef, } from "react";
1
+ import { areWidgetFrameAppearancesEqual, planWidgetLayoutTransition, toInstantWidgetLayoutSizeUpdate, } from "@getuserfeedback/protocol/host";
2
+ import { createElement, useCallback, useEffect, useMemo, useRef, useState, } from "react";
3
3
  import { toProviderWidgetFrameAppearance } from "./provider-widget-frame-appearance.js";
4
4
  const HIDDEN_WIDGET_HOST_STYLE = {
5
5
  bottom: 0,
@@ -298,6 +298,14 @@ function useProviderWidgetSheetPresentation(input) {
298
298
  const animationRuntime = useMemo(resolveNativeAnimationRuntime, []);
299
299
  const animatedValuesRef = useRef(null);
300
300
  const animationRef = useRef([]);
301
+ const presentationAttemptRef = useRef(0);
302
+ // Border and shadow stay static across RN capability levels; this clock
303
+ // settles their swap on the same schedule as the numeric frame animation.
304
+ const presentationProgressRef = useRef(null);
305
+ const pendingFrameAppearanceRef = useRef(undefined);
306
+ const presentedFrameAppearanceRef = useRef(input.frameAppearance);
307
+ const presentedSurfaceStylesRef = useRef(input.surfaceStyles);
308
+ const [, setPresentationRevision] = useState(0);
301
309
  const consumedTransitionSequenceRef = useRef(undefined);
302
310
  const previousFrameRef = useRef(undefined);
303
311
  const animatedSurfaceView = useMemo(() => animationRuntime
@@ -312,11 +320,14 @@ function useProviderWidgetSheetPresentation(input) {
312
320
  typeof topRightRadius === "number"
313
321
  ? { height, topLeftRadius, topRightRadius }
314
322
  : undefined, [height, topLeftRadius, topRightRadius]);
323
+ const hasPendingTimedTransition = input.transitionSequence !== undefined &&
324
+ consumedTransitionSequenceRef.current !== input.transitionSequence;
315
325
  const shouldUseAnimatedStyle = animationRuntime !== null &&
316
326
  input.isVisible &&
317
327
  frame !== undefined &&
318
328
  previousFrameRef.current !== undefined &&
319
- ((_b = input.sheetHostLayoutUpdate) === null || _b === void 0 ? void 0 : _b.transition.kind) === "timed";
329
+ ((_b = input.sheetHostLayoutUpdate) === null || _b === void 0 ? void 0 : _b.transition.kind) === "timed" &&
330
+ (hasPendingTimedTransition || animationRef.current.length > 0);
320
331
  const surfaceView = animationRuntime ? animatedSurfaceView : input.nativeView;
321
332
  if (animationRuntime && frame && animatedValuesRef.current === null) {
322
333
  animatedValuesRef.current = {
@@ -324,6 +335,7 @@ function useProviderWidgetSheetPresentation(input) {
324
335
  topLeftRadius: new animationRuntime.Animated.Value(frame.topLeftRadius),
325
336
  topRightRadius: new animationRuntime.Animated.Value(frame.topRightRadius),
326
337
  };
338
+ presentationProgressRef.current = new animationRuntime.Animated.Value(0);
327
339
  }
328
340
  useEffect(() => {
329
341
  var _a, _b, _c;
@@ -341,8 +353,12 @@ function useProviderWidgetSheetPresentation(input) {
341
353
  animationRef.current = retained;
342
354
  };
343
355
  if (!animationRuntime || !frame || !input.isVisible) {
356
+ presentationAttemptRef.current += 1;
357
+ pendingFrameAppearanceRef.current = undefined;
344
358
  stopAnimations();
345
359
  previousFrameRef.current = undefined;
360
+ presentedFrameAppearanceRef.current = input.frameAppearance;
361
+ presentedSurfaceStylesRef.current = input.surfaceStyles;
346
362
  return;
347
363
  }
348
364
  const animatedValues = animatedValuesRef.current;
@@ -359,7 +375,11 @@ function useProviderWidgetSheetPresentation(input) {
359
375
  consumedTransitionSequenceRef.current = input.transitionSequence;
360
376
  }
361
377
  if (previousFrame === undefined || (transition === null || transition === void 0 ? void 0 : transition.kind) === "instant") {
378
+ presentationAttemptRef.current += 1;
379
+ pendingFrameAppearanceRef.current = undefined;
362
380
  stopAnimations();
381
+ presentedFrameAppearanceRef.current = input.frameAppearance;
382
+ presentedSurfaceStylesRef.current = input.surfaceStyles;
363
383
  animatedValues.height.setValue(frame.height);
364
384
  animatedValues.topLeftRadius.setValue(frame.topLeftRadius);
365
385
  animatedValues.topRightRadius.setValue(frame.topRightRadius);
@@ -371,6 +391,23 @@ function useProviderWidgetSheetPresentation(input) {
371
391
  topRightRadius: animatedValues.topRightRadius,
372
392
  };
373
393
  if (!shouldAnimate) {
394
+ const hasActiveAppearanceTransition = animationRef.current.some((animation) => animation.property === "appearance");
395
+ const didUncoordinatedAppearanceChange = hasActiveAppearanceTransition &&
396
+ !areWidgetFrameAppearancesEqual(pendingFrameAppearanceRef.current, input.frameAppearance);
397
+ if (didUncoordinatedAppearanceChange) {
398
+ presentationAttemptRef.current += 1;
399
+ pendingFrameAppearanceRef.current = undefined;
400
+ stopAnimations("appearance");
401
+ presentedSurfaceStylesRef.current = input.surfaceStyles;
402
+ presentedFrameAppearanceRef.current = input.frameAppearance;
403
+ setPresentationRevision((revision) => revision + 1);
404
+ }
405
+ else if (!hasActiveAppearanceTransition &&
406
+ !areWidgetFrameAppearancesEqual(presentedFrameAppearanceRef.current, input.frameAppearance)) {
407
+ presentedSurfaceStylesRef.current = input.surfaceStyles;
408
+ presentedFrameAppearanceRef.current = input.frameAppearance;
409
+ setPresentationRevision((revision) => revision + 1);
410
+ }
374
411
  for (const property of [
375
412
  "height",
376
413
  "topLeftRadius",
@@ -383,6 +420,28 @@ function useProviderWidgetSheetPresentation(input) {
383
420
  }
384
421
  return;
385
422
  }
423
+ const targetSurfaceStyles = input.surfaceStyles;
424
+ const targetFrameAppearance = input.frameAppearance;
425
+ const didFrameAppearanceChange = !areWidgetFrameAppearancesEqual(presentedFrameAppearanceRef.current, targetFrameAppearance);
426
+ const hasActiveAppearanceTransition = animationRef.current.some((animation) => animation.property === "appearance");
427
+ const shouldReplaceAppearanceTransition = didFrameAppearanceChange || hasActiveAppearanceTransition;
428
+ const presentationAttempt = shouldReplaceAppearanceTransition
429
+ ? presentationAttemptRef.current + 1
430
+ : presentationAttemptRef.current;
431
+ if (shouldReplaceAppearanceTransition) {
432
+ presentationAttemptRef.current = presentationAttempt;
433
+ pendingFrameAppearanceRef.current = undefined;
434
+ stopAnimations("appearance");
435
+ }
436
+ const presentTargetSurfaceStyles = () => {
437
+ if (presentationAttemptRef.current !== presentationAttempt) {
438
+ return;
439
+ }
440
+ presentedFrameAppearanceRef.current = targetFrameAppearance;
441
+ presentedSurfaceStylesRef.current = targetSurfaceStyles;
442
+ pendingFrameAppearanceRef.current = undefined;
443
+ setPresentationRevision((revision) => revision + 1);
444
+ };
386
445
  const easing = transition.easing.kind === "cubic-bezier"
387
446
  ? (_c = (_b = animationRuntime.Easing) === null || _b === void 0 ? void 0 : _b.bezier) === null || _c === void 0 ? void 0 : _c.call(_b, ...transition.easing.points)
388
447
  : undefined;
@@ -408,17 +467,37 @@ function useProviderWidgetSheetPresentation(input) {
408
467
  animations.push(animate(property, values[property], frame[property]));
409
468
  }
410
469
  }
470
+ if (didFrameAppearanceChange && presentationProgressRef.current !== null) {
471
+ presentationProgressRef.current.setValue(0);
472
+ pendingFrameAppearanceRef.current = targetFrameAppearance;
473
+ animations.push(animate("appearance", presentationProgressRef.current, 1));
474
+ }
475
+ if (animations.length === 0) {
476
+ pendingFrameAppearanceRef.current = undefined;
477
+ presentedFrameAppearanceRef.current = targetFrameAppearance;
478
+ presentedSurfaceStylesRef.current = targetSurfaceStyles;
479
+ return;
480
+ }
411
481
  animationRef.current.push(...animations);
412
482
  for (const animation of animations) {
413
- animation.handle.start(() => {
483
+ animation.handle.start((result) => {
414
484
  animationRef.current = animationRef.current.filter((candidate) => candidate !== animation);
485
+ if (animation.property !== "appearance") {
486
+ return;
487
+ }
488
+ if ((result === null || result === void 0 ? void 0 : result.finished) !== false &&
489
+ presentationAttemptRef.current === presentationAttempt) {
490
+ presentTargetSurfaceStyles();
491
+ }
415
492
  });
416
493
  }
417
494
  }, [
418
495
  animationRuntime,
419
496
  frame,
497
+ input.frameAppearance,
420
498
  input.isVisible,
421
499
  (_c = input.sheetHostLayoutUpdate) === null || _c === void 0 ? void 0 : _c.transition,
500
+ input.surfaceStyles,
422
501
  input.transitionSequence,
423
502
  ]);
424
503
  useEffect(() => () => {
@@ -432,14 +511,15 @@ function useProviderWidgetSheetPresentation(input) {
432
511
  if (!shouldUseAnimatedStyle || animatedValues === null) {
433
512
  return Object.assign(Object.assign({}, input.surfaceStyles), { surfaceView });
434
513
  }
514
+ const presentedSurfaceStyles = presentedSurfaceStylesRef.current;
435
515
  const animatedRadiusStyle = {
436
516
  borderTopLeftRadius: animatedValues.topLeftRadius,
437
517
  borderTopRightRadius: animatedValues.topRightRadius,
438
518
  };
439
519
  return {
440
- contentStyle: Object.assign(Object.assign({}, input.surfaceStyles.contentStyle), animatedRadiusStyle),
441
- frameStyle: Object.assign(Object.assign({}, input.surfaceStyles.frameStyle), animatedRadiusStyle),
442
- sheetStyle: Object.assign(Object.assign(Object.assign({}, input.surfaceStyles.sheetStyle), animatedRadiusStyle), { height: animatedValues.height }),
520
+ contentStyle: Object.assign(Object.assign({}, presentedSurfaceStyles.contentStyle), animatedRadiusStyle),
521
+ frameStyle: Object.assign(Object.assign({}, presentedSurfaceStyles.frameStyle), animatedRadiusStyle),
522
+ sheetStyle: Object.assign(Object.assign(Object.assign({}, presentedSurfaceStyles.sheetStyle), animatedRadiusStyle), { height: animatedValues.height }),
443
523
  surfaceView,
444
524
  };
445
525
  }
@@ -498,13 +578,14 @@ export function ProviderWidgetHostOverlay({ children, frameAppearance, isVisible
498
578
  const isSheetVisible = isVisible && sheetHostViewport !== undefined;
499
579
  const pointerEvents = isSheetVisible ? "auto" : "none";
500
580
  const nativeBoxShadowSupport = useMemo(resolveNativeBoxShadowSupport, []);
501
- const surfaceStyles = toProviderWidgetSheetSurfaceStyles({
581
+ const surfaceStyles = useMemo(() => toProviderWidgetSheetSurfaceStyles({
502
582
  frameAppearance,
503
583
  isVisible,
504
584
  sheetHostLayoutUpdate,
505
585
  nativeBoxShadowSupport,
506
- });
586
+ }), [frameAppearance, isVisible, nativeBoxShadowSupport, sheetHostLayoutUpdate]);
507
587
  const sheetPresentation = useProviderWidgetSheetPresentation({
588
+ frameAppearance,
508
589
  isVisible,
509
590
  nativeView,
510
591
  sheetHostLayoutUpdate,
package/dist/version.js CHANGED
@@ -3,4 +3,4 @@ const reactNativeSdkVersion = typeof __GX_REACT_NATIVE_SDK_VERSION__ === "string
3
3
  : "";
4
4
  // Build scripts patch this fallback to the package version for published artifacts.
5
5
  // Source-linked workspace usage keeps the local fallback.
6
- export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "3.0.56";
6
+ export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "3.0.58";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getuserfeedback/react-native",
3
- "version": "3.0.56",
3
+ "version": "3.0.58",
4
4
  "description": "getuserfeedback React Native SDK",
5
5
  "keywords": [
6
6
  "getuserfeedback",
@@ -44,8 +44,8 @@
44
44
  "lint": "biome check ."
45
45
  },
46
46
  "dependencies": {
47
- "@getuserfeedback/protocol": "^3.15.0",
48
- "@getuserfeedback/sdk": "^0.10.18",
47
+ "@getuserfeedback/protocol": "^3.16.0",
48
+ "@getuserfeedback/sdk": "^0.10.20",
49
49
  "robot3": "^1.2.0"
50
50
  },
51
51
  "peerDependencies": {