@getuserfeedback/react-native 3.0.40 → 3.0.42

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.
package/dist/index.js CHANGED
@@ -694,6 +694,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
694
694
  return createElement(GetUserFeedbackNativeContext.Provider, {
695
695
  value: contextValue,
696
696
  }, children, createElement(ProviderWidgetHostOverlay, {
697
+ frameAppearance: widgetHostVisibility.frameAppearance,
697
698
  isVisible: isWidgetHostVisible,
698
699
  nativeView: NativeView,
699
700
  onRequestDismiss: handleWidgetHostDismiss,
@@ -0,0 +1,9 @@
1
+ import { type ComponentType, type ReactElement } from "react";
2
+ import type { NativeViewRecordController } from "./native-view-record-controller.js";
3
+ export type NativeViewHostProjectionProps = {
4
+ controller: NativeViewRecordController;
5
+ onInvalidMessage?: (error: Error, value: unknown) => void;
6
+ webViewComponent?: ComponentType<Record<string, unknown>>;
7
+ webViewProps?: Record<string, unknown>;
8
+ };
9
+ export declare function NativeViewHostProjection({ controller, onInvalidMessage, webViewComponent, webViewProps, }: NativeViewHostProjectionProps): ReactElement;
@@ -0,0 +1,42 @@
1
+ import { createElement, Fragment, useCallback, useEffect, useRef, useSyncExternalStore, } from "react";
2
+ import { ViewWebViewHost } from "./view-webview-host.js";
3
+ function NativeViewHostProjectionEntry({ controller, onInvalidMessage, record, webViewComponent, webViewProps, }) {
4
+ const detachConnectionRef = useRef(null);
5
+ const detachConnection = useCallback(() => {
6
+ const detach = detachConnectionRef.current;
7
+ detachConnectionRef.current = null;
8
+ detach === null || detach === void 0 ? void 0 : detach();
9
+ }, []);
10
+ const handleConnected = useCallback((connection) => {
11
+ detachConnection();
12
+ const controllerDetach = controller.attachViewReadinessConnection({
13
+ allocationId: record.allocationId,
14
+ connection,
15
+ });
16
+ detachConnectionRef.current = controllerDetach;
17
+ }, [controller, detachConnection, record.allocationId]);
18
+ useEffect(() => detachConnection, [detachConnection]);
19
+ return createElement(ViewWebViewHost, {
20
+ generation: record.generation,
21
+ onConnected: handleConnected,
22
+ onDisconnected: detachConnection,
23
+ onInvalidMessage,
24
+ srcdoc: record.srcdoc,
25
+ viewId: record.viewId,
26
+ webViewComponent,
27
+ webViewProps,
28
+ });
29
+ }
30
+ export function NativeViewHostProjection({ controller, onInvalidMessage, webViewComponent, webViewProps, }) {
31
+ const records = useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
32
+ return createElement(Fragment, null, records.map((record) => createElement(NativeViewHostProjectionEntry, {
33
+ controller,
34
+ onInvalidMessage,
35
+ record,
36
+ webViewComponent,
37
+ webViewProps,
38
+ key: record.allocationId,
39
+ })));
40
+ }
41
+ // TODO(migration): Compose CoreWebViewHost, a mount-stable NativeViewRecordController, and this projection behind one private native runtime root while the provider runtime remains active.
42
+ // [from=private-native-view-rendering-proof] [to=private-native-runtime-composition] [scope=slice] [priority=high] [impact=high] [risk=high] [epic=runtime-neutral-view-host-orchestration] [epic_order=50]
@@ -3,7 +3,7 @@ import type { CoreWebViewHostConnection } from "./core-webview-host-controller.j
3
3
  import type { ViewWebViewHostConnection } from "./view-webview-host-controller.js";
4
4
  type NativeViewActivationState = "idle" | "prerendering" | "activation-requested" | "prerendering-activation-requested" | "prerendered" | "active";
5
5
  type NativeViewSizeReport = Omit<EventViewSize, "gen" | "t" | "viewId">;
6
- type NativeViewRecord = Readonly<{
6
+ export type NativeViewRecord = Readonly<{
7
7
  allocationId: number;
8
8
  activationState: NativeViewActivationState;
9
9
  generation: number;
@@ -348,5 +348,3 @@ function toViewSizeReport(event) {
348
348
  layoutTransactionId: event.layoutTransactionId,
349
349
  };
350
350
  }
351
- // TODO(migration): Render the controller's identity-safe records through ViewWebViewHost and attach each connected view transport. Keep the provider runtime active during this proof.
352
- // [from=private-native-view-readiness-routing] [to=private-native-view-rendering-proof] [scope=slice] [priority=high] [impact=high] [risk=high] [epic=runtime-neutral-view-host-orchestration] [epic_order=40]
@@ -1,10 +1,11 @@
1
- import { type InstanceViewHostSnapshotsChangedDetail, type ViewHostSnapshot, type WidgetLayoutTransitionPolicy } from "@getuserfeedback/protocol/host";
1
+ import { type InstanceViewHostSnapshotsChangedDetail, type ViewHostSnapshot, type WidgetFrameAppearance, type WidgetLayoutTransitionPolicy } from "@getuserfeedback/protocol/host";
2
2
  type ProviderWidgetHostReadyState = {
3
3
  hostEpoch: number;
4
4
  readySequence: number;
5
5
  sourceKey: string;
6
6
  };
7
7
  export type ProviderWidgetHostVisibility = {
8
+ frameAppearance?: WidgetFrameAppearance;
8
9
  flowHeight?: number;
9
10
  flowHandleId?: string;
10
11
  hostSourceVersion: number | null;
@@ -24,6 +24,7 @@ export function createProviderWidgetHostLifecycleController(initialHostSourceKey
24
24
  nextTransitionPolicySequence = transitionPolicySequence;
25
25
  }
26
26
  return {
27
+ frameAppearance: snapshot.frameAppearance,
27
28
  flowHeight: snapshot.height,
28
29
  flowHandleId: snapshot.flowHandleId,
29
30
  hostSourceVersion,
@@ -1,4 +1,4 @@
1
- import { type WidgetLayoutComparableSizeUpdate, type WidgetLayoutSizeUpdate, type WidgetLayoutTimedCapableTransitionPlan, type WidgetLayoutTransitionPolicy } from "@getuserfeedback/protocol/host";
1
+ import { type WidgetFrameAppearance, type WidgetLayoutComparableSizeUpdate, type WidgetLayoutSizeUpdate, type WidgetLayoutTimedCapableTransitionPlan, type WidgetLayoutTransitionPolicy } from "@getuserfeedback/protocol/host";
2
2
  import { type ComponentType, type ReactElement, type ReactNode } from "react";
3
3
  import type { WidgetHostProps } from "./widget-host.js";
4
4
  type NativeViewComponent = ComponentType<Record<string, unknown>>;
@@ -24,12 +24,17 @@ export declare function toProviderWidgetHostStyle({ isVisible, webViewStyle, }:
24
24
  isVisible: boolean;
25
25
  webViewStyle: unknown;
26
26
  }): unknown;
27
- export declare function toProviderWidgetSheetStyle(input: {
27
+ export declare function toProviderWidgetSheetSurfaceStyles(input: {
28
+ frameAppearance?: WidgetFrameAppearance;
28
29
  isVisible: boolean;
29
30
  sheetHostLayoutUpdate: WidgetLayoutComparableSizeUpdate | undefined;
30
- }): unknown;
31
- export declare function ProviderWidgetHostOverlay({ children, isVisible, nativeView, onRequestDismiss, sheetHostLayoutUpdate, }: {
31
+ }): {
32
+ contentStyle: unknown;
33
+ sheetStyle: unknown;
34
+ };
35
+ export declare function ProviderWidgetHostOverlay({ children, frameAppearance, isVisible, nativeView, onRequestDismiss, sheetHostLayoutUpdate, }: {
32
36
  children?: ReactNode;
37
+ frameAppearance?: WidgetFrameAppearance;
33
38
  isVisible: boolean;
34
39
  nativeView: NativeViewComponent;
35
40
  onRequestDismiss: () => void;
@@ -24,21 +24,29 @@ const WIDGET_SHEET_BACKDROP_STYLE = {
24
24
  right: 0,
25
25
  top: 0,
26
26
  };
27
- const WIDGET_SHEET_STYLE = {
27
+ const WIDGET_SHEET_LAYOUT_STYLE = {
28
28
  backgroundColor: "#ffffff",
29
- borderTopLeftRadius: 24,
30
- borderTopRightRadius: 24,
31
29
  bottom: 0,
32
30
  left: 0,
33
- overflow: "hidden",
34
31
  position: "absolute",
35
32
  right: 0,
33
+ };
34
+ const WIDGET_SHEET_FRAME_STYLE = {
36
35
  shadowColor: "#000000",
37
36
  shadowOffset: { height: -4, width: 0 },
38
37
  shadowOpacity: 0.16,
39
38
  shadowRadius: 18,
40
39
  elevation: 18,
41
40
  };
41
+ const WIDGET_SHEET_CONTENT_BASE_STYLE = {
42
+ backgroundColor: "#ffffff",
43
+ flex: 1,
44
+ overflow: "hidden",
45
+ };
46
+ const WIDGET_SHEET_RADIUS_STYLE = {
47
+ borderTopLeftRadius: 24,
48
+ borderTopRightRadius: 24,
49
+ };
42
50
  const WIDGET_SHEET_DRAG_HANDLE_TOUCH_STYLE = {
43
51
  alignItems: "center",
44
52
  elevation: 19,
@@ -190,11 +198,16 @@ export function toProviderWidgetHostStyle({ isVisible, webViewStyle, }) {
190
198
  ? [visiblePresentationStyle, VISIBLE_WIDGET_HOST_STYLE]
191
199
  : VISIBLE_WIDGET_HOST_STYLE;
192
200
  }
193
- export function toProviderWidgetSheetStyle(input) {
194
- var _a;
201
+ export function toProviderWidgetSheetSurfaceStyles(input) {
202
+ var _a, _b;
195
203
  const sheetHostViewport = (_a = input.sheetHostLayoutUpdate) === null || _a === void 0 ? void 0 : _a.size;
196
- return input.isVisible && sheetHostViewport !== undefined
197
- ? Object.assign(Object.assign({}, WIDGET_SHEET_STYLE), { height: sheetHostViewport.height }) : HIDDEN_WIDGET_HOST_STYLE;
204
+ const hasFrame = ((_b = input.frameAppearance) === null || _b === void 0 ? void 0 : _b.kind) !== "none";
205
+ return {
206
+ contentStyle: Object.assign(Object.assign({}, WIDGET_SHEET_CONTENT_BASE_STYLE), (hasFrame ? WIDGET_SHEET_RADIUS_STYLE : {})),
207
+ sheetStyle: input.isVisible && sheetHostViewport !== undefined
208
+ ? Object.assign(Object.assign(Object.assign({}, WIDGET_SHEET_LAYOUT_STYLE), (hasFrame
209
+ ? Object.assign(Object.assign({}, WIDGET_SHEET_RADIUS_STYLE), WIDGET_SHEET_FRAME_STYLE) : {})), { height: sheetHostViewport.height }) : HIDDEN_WIDGET_HOST_STYLE,
210
+ };
198
211
  }
199
212
  function useProviderWidgetSheetPresentation(input) {
200
213
  var _a, _b, _c, _d;
@@ -205,10 +218,6 @@ function useProviderWidgetSheetPresentation(input) {
205
218
  const animatedSheetView = useMemo(() => animationRuntime
206
219
  ? animationRuntime.Animated.createAnimatedComponent(input.nativeView)
207
220
  : input.nativeView, [animationRuntime, input.nativeView]);
208
- const staticStyle = toProviderWidgetSheetStyle({
209
- isVisible: input.isVisible,
210
- sheetHostLayoutUpdate: input.sheetHostLayoutUpdate,
211
- });
212
221
  const sheetHostViewport = (_a = input.sheetHostLayoutUpdate) === null || _a === void 0 ? void 0 : _a.size;
213
222
  const height = sheetHostViewport === null || sheetHostViewport === void 0 ? void 0 : sheetHostViewport.height;
214
223
  const shouldUseAnimatedStyle = animationRuntime !== null &&
@@ -269,15 +278,15 @@ function useProviderWidgetSheetPresentation(input) {
269
278
  if (!shouldUseAnimatedStyle) {
270
279
  return {
271
280
  sheetView,
272
- style: staticStyle,
281
+ style: input.staticStyle,
273
282
  };
274
283
  }
275
284
  return {
276
285
  sheetView,
277
- style: Object.assign(Object.assign({}, staticStyle), { height: (_d = animatedHeightRef.current) !== null && _d !== void 0 ? _d : height }),
286
+ style: Object.assign(Object.assign({}, input.staticStyle), { height: (_d = animatedHeightRef.current) !== null && _d !== void 0 ? _d : height }),
278
287
  };
279
288
  }
280
- export function ProviderWidgetHostOverlay({ children, isVisible, nativeView, onRequestDismiss, sheetHostLayoutUpdate, }) {
289
+ export function ProviderWidgetHostOverlay({ children, frameAppearance, isVisible, nativeView, onRequestDismiss, sheetHostLayoutUpdate, }) {
281
290
  const dragStartYRef = useRef(undefined);
282
291
  const handleDragGrant = useCallback((event) => {
283
292
  dragStartYRef.current = toResponderPageY(event);
@@ -331,10 +340,16 @@ export function ProviderWidgetHostOverlay({ children, isVisible, nativeView, onR
331
340
  const sheetHostViewport = sheetHostLayoutUpdate === null || sheetHostLayoutUpdate === void 0 ? void 0 : sheetHostLayoutUpdate.size;
332
341
  const isSheetVisible = isVisible && sheetHostViewport !== undefined;
333
342
  const pointerEvents = isSheetVisible ? "auto" : "none";
343
+ const surfaceStyles = toProviderWidgetSheetSurfaceStyles({
344
+ frameAppearance,
345
+ isVisible,
346
+ sheetHostLayoutUpdate,
347
+ });
334
348
  const sheetPresentation = useProviderWidgetSheetPresentation({
335
349
  isVisible,
336
350
  nativeView,
337
351
  sheetHostLayoutUpdate,
352
+ staticStyle: surfaceStyles.sheetStyle,
338
353
  });
339
354
  return createElement(nativeView, {
340
355
  pointerEvents,
@@ -352,10 +367,14 @@ export function ProviderWidgetHostOverlay({ children, isVisible, nativeView, onR
352
367
  pointerEvents,
353
368
  style: sheetPresentation.style,
354
369
  testID: "gx-widget-host-sheet",
370
+ }, createElement(nativeView, {
371
+ pointerEvents,
372
+ style: surfaceStyles.contentStyle,
373
+ testID: "gx-widget-host-sheet-content",
355
374
  }, children, isSheetVisible
356
375
  ? createElement(nativeView, Object.assign(Object.assign({}, dragHandleGestureProps), { style: WIDGET_SHEET_DRAG_HANDLE_TOUCH_STYLE, testID: "gx-widget-host-drag-handle" }), createElement(nativeView, {
357
376
  style: WIDGET_SHEET_DRAG_HANDLE_INDICATOR_STYLE,
358
377
  testID: "gx-widget-host-drag-handle-indicator",
359
378
  }))
360
- : null));
379
+ : null)));
361
380
  }
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.40";
6
+ export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "3.0.42";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getuserfeedback/react-native",
3
- "version": "3.0.40",
3
+ "version": "3.0.42",
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.11.1",
48
- "@getuserfeedback/sdk": "^0.10.9",
47
+ "@getuserfeedback/protocol": "^3.12.0",
48
+ "@getuserfeedback/sdk": "^0.10.10",
49
49
  "robot3": "^1.2.0"
50
50
  },
51
51
  "peerDependencies": {