@getuserfeedback/react-native 1.3.2 → 1.3.4

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
@@ -13,6 +13,8 @@ import { assertNoSegmentExternalIdsInValueArgument, CommandSettlementError, Comm
13
13
  import { parseWebViewTransportNativeMessage } from "@getuserfeedback/protocol/webview-transport";
14
14
  import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
15
15
  import { useResolvedHostViewport } from "./host-viewport.js";
16
+ import { applyProviderOverlayFlowState, applyProviderOverlayHandleInvalidated, createDefaultProviderOverlayState, DEFAULT_PROVIDER_OVERLAY_VISIBILITY, updateProviderOverlayReadySequence, } from "./provider-overlay-state.js";
17
+ import { ProviderWidgetHostOverlay, toProviderWidgetHostStyle, toProviderWidgetSheetHostViewport, } from "./provider-widget-host-overlay.js";
16
18
  import { REACT_NATIVE_SDK_VERSION } from "./version.js";
17
19
  import { WidgetHost, } from "./widget-host.js";
18
20
  export { REACT_NATIVE_SDK_VERSION } from "./version.js";
@@ -28,88 +30,6 @@ const CLIENT_META = {
28
30
  loader: "sdk",
29
31
  transport: "loader",
30
32
  };
31
- const HIDDEN_WIDGET_HOST_STYLE = {
32
- height: 1,
33
- left: -1,
34
- opacity: 0,
35
- position: "absolute",
36
- top: -1,
37
- width: 1,
38
- };
39
- const WIDGET_SHEET_OVERLAY_STYLE = {
40
- bottom: 0,
41
- left: 0,
42
- position: "absolute",
43
- right: 0,
44
- top: 0,
45
- zIndex: 2147483647,
46
- };
47
- const WIDGET_SHEET_BACKDROP_STYLE = {
48
- backgroundColor: "rgba(15, 23, 42, 0.36)",
49
- bottom: 0,
50
- left: 0,
51
- position: "absolute",
52
- right: 0,
53
- top: 0,
54
- };
55
- const WIDGET_SHEET_STYLE = {
56
- backgroundColor: "#ffffff",
57
- borderTopLeftRadius: 24,
58
- borderTopRightRadius: 24,
59
- bottom: 0,
60
- left: 0,
61
- overflow: "hidden",
62
- position: "absolute",
63
- right: 0,
64
- shadowColor: "#000000",
65
- shadowOffset: { height: -4, width: 0 },
66
- shadowOpacity: 0.16,
67
- shadowRadius: 18,
68
- elevation: 18,
69
- };
70
- const VISIBLE_WIDGET_HOST_STYLE = {
71
- flex: 1,
72
- };
73
- const VISIBLE_WIDGET_HOST_LAYOUT_STYLE_KEYS = new Set([
74
- "alignSelf",
75
- "bottom",
76
- "display",
77
- "end",
78
- "flex",
79
- "flexBasis",
80
- "flexGrow",
81
- "flexShrink",
82
- "height",
83
- "left",
84
- "margin",
85
- "marginBottom",
86
- "marginEnd",
87
- "marginHorizontal",
88
- "marginLeft",
89
- "marginRight",
90
- "marginStart",
91
- "marginTop",
92
- "marginVertical",
93
- "maxHeight",
94
- "maxWidth",
95
- "minHeight",
96
- "minWidth",
97
- "position",
98
- "right",
99
- "start",
100
- "top",
101
- "width",
102
- ]);
103
- const DEFAULT_WIDGET_SHEET_HEIGHT_RATIO = 0.86;
104
- const DEFAULT_WIDGET_SHEET_MIN_HEIGHT = 320;
105
- const DEFAULT_WIDGET_HOST_VISIBILITY = {
106
- flowHandleId: null,
107
- hostSourceVersion: null,
108
- isVisible: false,
109
- origin: null,
110
- readySequence: null,
111
- sourceKey: null,
112
- };
113
33
  const createUniqueId = (prefix) => {
114
34
  if (typeof globalThis.crypto !== "undefined" &&
115
35
  typeof globalThis.crypto.randomUUID === "function") {
@@ -157,39 +77,6 @@ function resolveNativeView() {
157
77
  return FallbackNativeView;
158
78
  }
159
79
  }
160
- function toSheetHostViewport(viewport) {
161
- if (!viewport) {
162
- return undefined;
163
- }
164
- const desiredHeight = Math.max(DEFAULT_WIDGET_SHEET_MIN_HEIGHT, Math.round(viewport.height * DEFAULT_WIDGET_SHEET_HEIGHT_RATIO));
165
- return {
166
- width: viewport.width,
167
- height: Math.min(viewport.height, desiredHeight),
168
- };
169
- }
170
- function toVisibleWidgetHostPresentationStyle(style) {
171
- if (style === undefined || style === null) {
172
- return undefined;
173
- }
174
- if (Array.isArray(style)) {
175
- const styles = style
176
- .map(toVisibleWidgetHostPresentationStyle)
177
- .filter((entry) => entry !== undefined && entry !== null);
178
- return styles.length > 0 ? styles : undefined;
179
- }
180
- if (typeof style !== "object") {
181
- return style;
182
- }
183
- const presentationStyle = {};
184
- for (const [key, value] of Object.entries(style)) {
185
- if (!VISIBLE_WIDGET_HOST_LAYOUT_STYLE_KEYS.has(key)) {
186
- presentationStyle[key] = value;
187
- }
188
- }
189
- return Object.keys(presentationStyle).length > 0
190
- ? presentationStyle
191
- : undefined;
192
- }
193
80
  const toIdentifyCommandPayload = (identifyInput, traitsOrOptions, options) => {
194
81
  if (typeof identifyInput === "string") {
195
82
  assertNoSegmentExternalIdsInValueArgument({
@@ -254,11 +141,11 @@ const toCommandSettlementError = (event) => {
254
141
  });
255
142
  };
256
143
  export function GetUserFeedbackProvider({ autoInit = true, children, commandTimeoutMs = DEFAULT_COMMAND_TIMEOUT_MS, configureOptions, hostViewport, instanceId: instanceIdProp, initOptions, loaderUrl, onCommandError, onInvalidWebMessage, onWebMessage, source, webViewComponent, webViewProps, }) {
257
- var _a, _b, _c;
144
+ var _a, _b;
258
145
  const NativeView = useMemo(resolveNativeView, []);
259
146
  const [instanceId] = useState(() => { var _a; return (_a = normalizeOptionalString(instanceIdProp)) !== null && _a !== void 0 ? _a : createUniqueId("rn"); });
260
147
  const [nativeMessages, setNativeMessages] = useState([]);
261
- const [widgetHostVisibility, setWidgetHostVisibility] = useState(DEFAULT_WIDGET_HOST_VISIBILITY);
148
+ const [widgetHostVisibility, setWidgetHostVisibility] = useState(DEFAULT_PROVIDER_OVERLAY_VISIBILITY);
262
149
  const resolvedHostViewport = useResolvedHostViewport(hostViewport);
263
150
  const nativeMessagesRef = useRef([]);
264
151
  const pendingCommandsRef = useRef(new Map());
@@ -266,7 +153,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
266
153
  const flowHandleCacheEpochRef = useRef(0);
267
154
  const flowHandleIdsByFlowIdRef = useRef(new Map());
268
155
  const flowCommandSequencesByFlowIdRef = useRef(new Map());
269
- const visibleFlowHandleIdsRef = useRef(new Set());
156
+ const providerOverlayStateRef = useRef(createDefaultProviderOverlayState());
270
157
  const initOptionsRef = useRef(initOptions);
271
158
  const configureOptionsRef = useRef(configureOptions);
272
159
  const initOptionsKey = useMemo(() => toJsonKey(initOptions), [initOptions]);
@@ -293,7 +180,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
293
180
  startupQueuedKeyRef.current = null;
294
181
  flowHandleCacheEpochRef.current += 1;
295
182
  flowHandleIdsByFlowIdRef.current.clear();
296
- visibleFlowHandleIdsRef.current.clear();
183
+ providerOverlayStateRef.current = createDefaultProviderOverlayState();
297
184
  }
298
185
  initOptionsRef.current = initOptions;
299
186
  configureOptionsRef.current = configureOptions;
@@ -528,14 +415,16 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
528
415
  didReissueDeliveredCommands = reissueDeliveredPendingActionCommands();
529
416
  }
530
417
  lastReadyRef.current = Object.assign(Object.assign({}, event), { hostEpoch: hostEpochRef.current });
531
- setWidgetHostVisibility((visibility) => {
532
- if (!visibility.isVisible ||
533
- visibility.sourceKey !== event.sourceKey ||
534
- visibility.hostSourceVersion !== hostSourceVersionRef.current) {
535
- return visibility;
536
- }
537
- return Object.assign(Object.assign({}, visibility), { readySequence: event.readySequence });
418
+ const nextVisibility = updateProviderOverlayReadySequence({
419
+ ready: {
420
+ hostSourceVersion: hostSourceVersionRef.current,
421
+ readySequence: event.readySequence,
422
+ sourceKey: event.sourceKey,
423
+ },
424
+ visibility: providerOverlayStateRef.current.visibility,
538
425
  });
426
+ providerOverlayStateRef.current = Object.assign(Object.assign({}, providerOverlayStateRef.current), { visibility: nextVisibility });
427
+ setWidgetHostVisibility(nextVisibility);
539
428
  enqueueStartupCommands({ force: previous !== null });
540
429
  startPendingCommandTimeouts();
541
430
  return didReissueDeliveredCommands;
@@ -562,8 +451,8 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
562
451
  reissueDeliveredPendingActionCommands();
563
452
  }
564
453
  lastReadyRef.current = null;
565
- setWidgetHostVisibility(DEFAULT_WIDGET_HOST_VISIBILITY);
566
- visibleFlowHandleIdsRef.current.clear();
454
+ providerOverlayStateRef.current = createDefaultProviderOverlayState();
455
+ setWidgetHostVisibility(providerOverlayStateRef.current.visibility);
567
456
  pausePendingCommandTimeouts();
568
457
  }, [
569
458
  handleWidgetReady,
@@ -580,26 +469,14 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
580
469
  }, []);
581
470
  const handleFlowHandleInvalidated = useCallback((flowHandleId) => {
582
471
  deleteCachedFlowHandleId(flowHandleId);
583
- visibleFlowHandleIdsRef.current.delete(flowHandleId);
584
- if (visibleFlowHandleIdsRef.current.size > 0) {
585
- return;
586
- }
587
- setWidgetHostVisibility((visibility) => {
588
- if (visibility.origin !== "handle") {
589
- return visibility;
590
- }
591
- return {
592
- flowHandleId: null,
593
- hostSourceVersion: visibility.hostSourceVersion,
594
- isVisible: false,
595
- origin: null,
596
- readySequence: visibility.readySequence,
597
- sourceKey: visibility.sourceKey,
598
- };
472
+ const nextState = applyProviderOverlayHandleInvalidated({
473
+ flowHandleId,
474
+ state: providerOverlayStateRef.current,
599
475
  });
476
+ providerOverlayStateRef.current = nextState;
477
+ setWidgetHostVisibility(nextState.visibility);
600
478
  }, [deleteCachedFlowHandleId]);
601
479
  const handleFlowStateChanged = useCallback((detail, options) => {
602
- var _a, _b;
603
480
  if (detail.instanceId !== instanceId) {
604
481
  return;
605
482
  }
@@ -607,83 +484,18 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
607
484
  if (!readyState) {
608
485
  return;
609
486
  }
610
- const isVisible = detail.isOpen || detail.isLoading;
611
- if (options.origin === "aggregate") {
612
- if (isVisible) {
613
- visibleFlowHandleIdsRef.current.clear();
614
- }
615
- else if (visibleFlowHandleIdsRef.current.size > 0) {
616
- const flowHandleId = (_a = visibleFlowHandleIdsRef.current.values().next().value) !== null && _a !== void 0 ? _a : null;
617
- setWidgetHostVisibility({
618
- flowHandleId,
619
- hostSourceVersion: hostSourceVersionRef.current,
620
- isVisible: true,
621
- origin: "handle",
622
- readySequence: readyState.readySequence,
623
- sourceKey: readyState.sourceKey,
624
- });
625
- return;
626
- }
627
- }
628
- if (options.origin === "handle") {
629
- if (detail.flowHandleId === undefined) {
630
- return;
631
- }
632
- if (isVisible) {
633
- visibleFlowHandleIdsRef.current.add(detail.flowHandleId);
634
- }
635
- else {
636
- visibleFlowHandleIdsRef.current.delete(detail.flowHandleId);
637
- }
638
- }
639
- if (!isVisible && options.origin === "handle") {
640
- if (visibleFlowHandleIdsRef.current.size > 0) {
641
- return;
642
- }
643
- setWidgetHostVisibility((visibility) => {
644
- if (visibility.origin !== "handle") {
645
- return visibility;
646
- }
647
- return {
648
- flowHandleId: null,
649
- hostSourceVersion: hostSourceVersionRef.current,
650
- isVisible: false,
651
- origin: null,
652
- readySequence: readyState.readySequence,
653
- sourceKey: readyState.sourceKey,
654
- };
655
- });
656
- return;
657
- }
658
- if (isVisible && options.origin === "handle") {
659
- setWidgetHostVisibility((visibility) => {
660
- var _a;
661
- if (visibility.isVisible &&
662
- visibility.origin === "aggregate" &&
663
- visibility.hostSourceVersion === hostSourceVersionRef.current &&
664
- visibility.readySequence === readyState.readySequence &&
665
- visibility.sourceKey === readyState.sourceKey) {
666
- return visibility;
667
- }
668
- return {
669
- flowHandleId: (_a = detail.flowHandleId) !== null && _a !== void 0 ? _a : null,
670
- hostSourceVersion: hostSourceVersionRef.current,
671
- isVisible: true,
672
- origin: "handle",
673
- readySequence: readyState.readySequence,
674
- sourceKey: readyState.sourceKey,
675
- };
676
- });
677
- return;
678
- }
679
- setWidgetHostVisibility({
680
- flowHandleId: options.origin === "handle" ? ((_b = detail.flowHandleId) !== null && _b !== void 0 ? _b : null) : null,
681
- hostSourceVersion: hostSourceVersionRef.current,
682
- isVisible,
487
+ const nextState = applyProviderOverlayFlowState({
488
+ detail,
683
489
  origin: options.origin,
684
- readySequence: readyState.readySequence,
685
- sourceKey: readyState.sourceKey,
490
+ ready: {
491
+ hostSourceVersion: hostSourceVersionRef.current,
492
+ readySequence: readyState.readySequence,
493
+ sourceKey: readyState.sourceKey,
494
+ },
495
+ state: providerOverlayStateRef.current,
686
496
  });
497
+ providerOverlayStateRef.current = nextState;
498
+ setWidgetHostVisibility(nextState.visibility);
687
499
  }, [instanceId]);
688
500
  const handleWebMessage = useCallback((message) => {
689
501
  var _a;
@@ -778,7 +590,8 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
778
590
  return;
779
591
  }
780
592
  visibilitySourceKeyRef.current = hostSourceKey;
781
- setWidgetHostVisibility(DEFAULT_WIDGET_HOST_VISIBILITY);
593
+ providerOverlayStateRef.current = createDefaultProviderOverlayState();
594
+ setWidgetHostVisibility(providerOverlayStateRef.current.visibility);
782
595
  }, [hostSourceKey]);
783
596
  const contextValue = useMemo(() => ({
784
597
  instanceId,
@@ -845,23 +658,14 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
845
658
  widgetHostVisibility.hostSourceVersion === hostSourceVersionRef.current &&
846
659
  widgetHostVisibility.sourceKey === ((_a = lastReadyRef.current) === null || _a === void 0 ? void 0 : _a.sourceKey) &&
847
660
  widgetHostVisibility.readySequence === ((_b = lastReadyRef.current) === null || _b === void 0 ? void 0 : _b.readySequence);
848
- const sheetHostViewport = toSheetHostViewport(hostViewport !== null && hostViewport !== void 0 ? hostViewport : resolvedHostViewport);
661
+ const sheetHostViewport = toProviderWidgetSheetHostViewport(hostViewport !== null && hostViewport !== void 0 ? hostViewport : resolvedHostViewport);
849
662
  const widgetHostViewport = isWidgetHostVisible
850
663
  ? sheetHostViewport
851
664
  : (hostViewport !== null && hostViewport !== void 0 ? hostViewport : resolvedHostViewport);
852
- const widgetSheetStyle = sheetHostViewport
853
- ? Object.assign(Object.assign({}, WIDGET_SHEET_STYLE), { height: sheetHostViewport.height }) : Object.assign(Object.assign({}, WIDGET_SHEET_STYLE), { height: "86%" });
854
- const widgetHostStyle = isWidgetHostVisible
855
- ? VISIBLE_WIDGET_HOST_STYLE
856
- : HIDDEN_WIDGET_HOST_STYLE;
857
- const visiblePresentationStyle = isWidgetHostVisible
858
- ? toVisibleWidgetHostPresentationStyle(webViewProps === null || webViewProps === void 0 ? void 0 : webViewProps.style)
859
- : undefined;
860
- const composedWebViewStyle = isWidgetHostVisible
861
- ? visiblePresentationStyle !== undefined
862
- ? [visiblePresentationStyle, widgetHostStyle]
863
- : widgetHostStyle
864
- : ((_c = webViewProps === null || webViewProps === void 0 ? void 0 : webViewProps.style) !== null && _c !== void 0 ? _c : widgetHostStyle);
665
+ const composedWebViewStyle = toProviderWidgetHostStyle({
666
+ isVisible: isWidgetHostVisible,
667
+ webViewStyle: webViewProps === null || webViewProps === void 0 ? void 0 : webViewProps.style,
668
+ });
865
669
  const widgetHost = createElement(WidgetHost, {
866
670
  hostViewport: widgetHostViewport,
867
671
  instanceId,
@@ -876,25 +680,11 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
876
680
  });
877
681
  return createElement(GetUserFeedbackNativeContext.Provider, {
878
682
  value: contextValue,
879
- }, children, createElement(NativeView, {
880
- pointerEvents: isWidgetHostVisible ? "auto" : "none",
881
- style: isWidgetHostVisible
882
- ? WIDGET_SHEET_OVERLAY_STYLE
883
- : HIDDEN_WIDGET_HOST_STYLE,
884
- testID: "gx-widget-host-overlay",
885
- }, createElement(NativeView, {
886
- pointerEvents: isWidgetHostVisible ? "auto" : "none",
887
- style: isWidgetHostVisible
888
- ? WIDGET_SHEET_BACKDROP_STYLE
889
- : HIDDEN_WIDGET_HOST_STYLE,
890
- testID: "gx-widget-host-backdrop",
891
- }), createElement(NativeView, {
892
- pointerEvents: isWidgetHostVisible ? "auto" : "none",
893
- style: isWidgetHostVisible
894
- ? widgetSheetStyle
895
- : HIDDEN_WIDGET_HOST_STYLE,
896
- testID: "gx-widget-host-sheet",
897
- }, widgetHost)));
683
+ }, children, createElement(ProviderWidgetHostOverlay, {
684
+ isVisible: isWidgetHostVisible,
685
+ nativeView: NativeView,
686
+ sheetHostViewport,
687
+ }, widgetHost));
898
688
  }
899
689
  export function useGetUserFeedbackNative() {
900
690
  const context = useContext(GetUserFeedbackNativeContext);
@@ -0,0 +1,43 @@
1
+ export type ProviderOverlayVisibilityOrigin = "aggregate" | "handle";
2
+ export type ProviderOverlayVisibility = {
3
+ flowHandleId: string | null;
4
+ hostSourceVersion: number | null;
5
+ isVisible: boolean;
6
+ origin: ProviderOverlayVisibilityOrigin | null;
7
+ readySequence: number | null;
8
+ sourceKey: string | null;
9
+ };
10
+ export type ProviderOverlayReadyIdentity = {
11
+ hostSourceVersion: number;
12
+ readySequence: number;
13
+ sourceKey: string;
14
+ };
15
+ export type ProviderOverlayFlowStateDetail = {
16
+ flowHandleId?: string;
17
+ isLoading: boolean;
18
+ isOpen: boolean;
19
+ };
20
+ export type ProviderOverlayState = {
21
+ visibility: ProviderOverlayVisibility;
22
+ visibleFlowHandleIds: Set<string>;
23
+ };
24
+ export type ProviderOverlayStateInput = {
25
+ visibility: ProviderOverlayVisibility;
26
+ visibleFlowHandleIds: ReadonlySet<string>;
27
+ };
28
+ export declare const DEFAULT_PROVIDER_OVERLAY_VISIBILITY: ProviderOverlayVisibility;
29
+ export declare const createDefaultProviderOverlayState: () => ProviderOverlayState;
30
+ export declare function updateProviderOverlayReadySequence({ ready, visibility, }: {
31
+ ready: ProviderOverlayReadyIdentity;
32
+ visibility: ProviderOverlayVisibility;
33
+ }): ProviderOverlayVisibility;
34
+ export declare function applyProviderOverlayFlowState({ detail, origin, ready, state, }: {
35
+ detail: ProviderOverlayFlowStateDetail;
36
+ origin: ProviderOverlayVisibilityOrigin;
37
+ ready: ProviderOverlayReadyIdentity;
38
+ state: ProviderOverlayStateInput;
39
+ }): ProviderOverlayState;
40
+ export declare function applyProviderOverlayHandleInvalidated({ flowHandleId, state, }: {
41
+ flowHandleId: string;
42
+ state: ProviderOverlayStateInput;
43
+ }): ProviderOverlayState;
@@ -0,0 +1,134 @@
1
+ export const DEFAULT_PROVIDER_OVERLAY_VISIBILITY = {
2
+ flowHandleId: null,
3
+ hostSourceVersion: null,
4
+ isVisible: false,
5
+ origin: null,
6
+ readySequence: null,
7
+ sourceKey: null,
8
+ };
9
+ export const createDefaultProviderOverlayState = () => ({
10
+ visibility: DEFAULT_PROVIDER_OVERLAY_VISIBILITY,
11
+ visibleFlowHandleIds: new Set(),
12
+ });
13
+ const toVisibleProviderOverlayVisibility = ({ flowHandleId, origin, ready, }) => ({
14
+ flowHandleId,
15
+ hostSourceVersion: ready.hostSourceVersion,
16
+ isVisible: true,
17
+ origin,
18
+ readySequence: ready.readySequence,
19
+ sourceKey: ready.sourceKey,
20
+ });
21
+ const toHiddenProviderOverlayVisibility = (visibility) => ({
22
+ flowHandleId: null,
23
+ hostSourceVersion: visibility.hostSourceVersion,
24
+ isVisible: false,
25
+ origin: null,
26
+ readySequence: visibility.readySequence,
27
+ sourceKey: visibility.sourceKey,
28
+ });
29
+ const isVisibilityForReadyIdentity = (visibility, ready) => visibility.hostSourceVersion === ready.hostSourceVersion &&
30
+ visibility.readySequence === ready.readySequence &&
31
+ visibility.sourceKey === ready.sourceKey;
32
+ export function updateProviderOverlayReadySequence({ ready, visibility, }) {
33
+ if (!visibility.isVisible ||
34
+ visibility.sourceKey !== ready.sourceKey ||
35
+ visibility.hostSourceVersion !== ready.hostSourceVersion) {
36
+ return visibility;
37
+ }
38
+ return Object.assign(Object.assign({}, visibility), { readySequence: ready.readySequence });
39
+ }
40
+ export function applyProviderOverlayFlowState({ detail, origin, ready, state, }) {
41
+ var _a;
42
+ const isVisible = detail.isOpen || detail.isLoading;
43
+ const visibleFlowHandleIds = new Set(state.visibleFlowHandleIds);
44
+ if (origin === "aggregate") {
45
+ if (isVisible) {
46
+ visibleFlowHandleIds.clear();
47
+ return {
48
+ visibleFlowHandleIds,
49
+ visibility: toVisibleProviderOverlayVisibility({
50
+ flowHandleId: null,
51
+ origin,
52
+ ready,
53
+ }),
54
+ };
55
+ }
56
+ if (visibleFlowHandleIds.size > 0) {
57
+ return {
58
+ visibleFlowHandleIds,
59
+ visibility: toVisibleProviderOverlayVisibility({
60
+ flowHandleId: (_a = visibleFlowHandleIds.values().next().value) !== null && _a !== void 0 ? _a : null,
61
+ origin: "handle",
62
+ ready,
63
+ }),
64
+ };
65
+ }
66
+ return {
67
+ visibleFlowHandleIds,
68
+ visibility: {
69
+ flowHandleId: null,
70
+ hostSourceVersion: ready.hostSourceVersion,
71
+ isVisible: false,
72
+ origin,
73
+ readySequence: ready.readySequence,
74
+ sourceKey: ready.sourceKey,
75
+ },
76
+ };
77
+ }
78
+ if (detail.flowHandleId === undefined) {
79
+ return {
80
+ visibleFlowHandleIds,
81
+ visibility: state.visibility,
82
+ };
83
+ }
84
+ if (isVisible) {
85
+ visibleFlowHandleIds.add(detail.flowHandleId);
86
+ if (state.visibility.isVisible &&
87
+ state.visibility.origin === "aggregate" &&
88
+ isVisibilityForReadyIdentity(state.visibility, ready)) {
89
+ return {
90
+ visibleFlowHandleIds,
91
+ visibility: state.visibility,
92
+ };
93
+ }
94
+ return {
95
+ visibleFlowHandleIds,
96
+ visibility: toVisibleProviderOverlayVisibility({
97
+ flowHandleId: detail.flowHandleId,
98
+ origin,
99
+ ready,
100
+ }),
101
+ };
102
+ }
103
+ visibleFlowHandleIds.delete(detail.flowHandleId);
104
+ if (visibleFlowHandleIds.size > 0) {
105
+ return {
106
+ visibleFlowHandleIds,
107
+ visibility: state.visibility,
108
+ };
109
+ }
110
+ if (state.visibility.origin !== "handle") {
111
+ return {
112
+ visibleFlowHandleIds,
113
+ visibility: state.visibility,
114
+ };
115
+ }
116
+ return {
117
+ visibleFlowHandleIds,
118
+ visibility: toHiddenProviderOverlayVisibility(state.visibility),
119
+ };
120
+ }
121
+ export function applyProviderOverlayHandleInvalidated({ flowHandleId, state, }) {
122
+ const visibleFlowHandleIds = new Set(state.visibleFlowHandleIds);
123
+ visibleFlowHandleIds.delete(flowHandleId);
124
+ if (visibleFlowHandleIds.size > 0 || state.visibility.origin !== "handle") {
125
+ return {
126
+ visibleFlowHandleIds,
127
+ visibility: state.visibility,
128
+ };
129
+ }
130
+ return {
131
+ visibleFlowHandleIds,
132
+ visibility: toHiddenProviderOverlayVisibility(state.visibility),
133
+ };
134
+ }
@@ -0,0 +1,15 @@
1
+ import { type ComponentType, type ReactElement, type ReactNode } from "react";
2
+ import type { WidgetHostProps } from "./widget-host.js";
3
+ type NativeViewComponent = ComponentType<Record<string, unknown>>;
4
+ export declare function toProviderWidgetSheetHostViewport(viewport: WidgetHostProps["hostViewport"]): WidgetHostProps["hostViewport"];
5
+ export declare function toProviderWidgetHostStyle({ isVisible, webViewStyle, }: {
6
+ isVisible: boolean;
7
+ webViewStyle: unknown;
8
+ }): unknown;
9
+ export declare function ProviderWidgetHostOverlay({ children, isVisible, nativeView, sheetHostViewport, }: {
10
+ children?: ReactNode;
11
+ isVisible: boolean;
12
+ nativeView: NativeViewComponent;
13
+ sheetHostViewport: WidgetHostProps["hostViewport"];
14
+ }): ReactElement;
15
+ export {};
@@ -0,0 +1,135 @@
1
+ import { createElement, } from "react";
2
+ const HIDDEN_WIDGET_HOST_STYLE = {
3
+ height: 1,
4
+ left: -1,
5
+ opacity: 0,
6
+ position: "absolute",
7
+ top: -1,
8
+ width: 1,
9
+ };
10
+ const WIDGET_SHEET_OVERLAY_STYLE = {
11
+ bottom: 0,
12
+ left: 0,
13
+ position: "absolute",
14
+ right: 0,
15
+ top: 0,
16
+ zIndex: 2147483647,
17
+ };
18
+ const WIDGET_SHEET_BACKDROP_STYLE = {
19
+ backgroundColor: "rgba(15, 23, 42, 0.36)",
20
+ bottom: 0,
21
+ left: 0,
22
+ position: "absolute",
23
+ right: 0,
24
+ top: 0,
25
+ };
26
+ const WIDGET_SHEET_STYLE = {
27
+ backgroundColor: "#ffffff",
28
+ borderTopLeftRadius: 24,
29
+ borderTopRightRadius: 24,
30
+ bottom: 0,
31
+ left: 0,
32
+ overflow: "hidden",
33
+ position: "absolute",
34
+ right: 0,
35
+ shadowColor: "#000000",
36
+ shadowOffset: { height: -4, width: 0 },
37
+ shadowOpacity: 0.16,
38
+ shadowRadius: 18,
39
+ elevation: 18,
40
+ };
41
+ const VISIBLE_WIDGET_HOST_STYLE = {
42
+ flex: 1,
43
+ };
44
+ const VISIBLE_WIDGET_HOST_LAYOUT_STYLE_KEYS = new Set([
45
+ "alignSelf",
46
+ "bottom",
47
+ "display",
48
+ "end",
49
+ "flex",
50
+ "flexBasis",
51
+ "flexGrow",
52
+ "flexShrink",
53
+ "height",
54
+ "left",
55
+ "margin",
56
+ "marginBottom",
57
+ "marginEnd",
58
+ "marginHorizontal",
59
+ "marginLeft",
60
+ "marginRight",
61
+ "marginStart",
62
+ "marginTop",
63
+ "marginVertical",
64
+ "maxHeight",
65
+ "maxWidth",
66
+ "minHeight",
67
+ "minWidth",
68
+ "position",
69
+ "right",
70
+ "start",
71
+ "top",
72
+ "width",
73
+ ]);
74
+ const DEFAULT_WIDGET_SHEET_HEIGHT_RATIO = 0.86;
75
+ const DEFAULT_WIDGET_SHEET_MIN_HEIGHT = 320;
76
+ export function toProviderWidgetSheetHostViewport(viewport) {
77
+ if (!viewport) {
78
+ return undefined;
79
+ }
80
+ const desiredHeight = Math.max(DEFAULT_WIDGET_SHEET_MIN_HEIGHT, Math.round(viewport.height * DEFAULT_WIDGET_SHEET_HEIGHT_RATIO));
81
+ return {
82
+ width: viewport.width,
83
+ height: Math.min(viewport.height, desiredHeight),
84
+ };
85
+ }
86
+ function toVisibleWidgetHostPresentationStyle(style) {
87
+ if (style === undefined || style === null) {
88
+ return undefined;
89
+ }
90
+ if (Array.isArray(style)) {
91
+ const styles = style
92
+ .map(toVisibleWidgetHostPresentationStyle)
93
+ .filter((entry) => entry !== undefined && entry !== null);
94
+ return styles.length > 0 ? styles : undefined;
95
+ }
96
+ if (typeof style !== "object") {
97
+ return style;
98
+ }
99
+ const presentationStyle = {};
100
+ for (const [key, value] of Object.entries(style)) {
101
+ if (!VISIBLE_WIDGET_HOST_LAYOUT_STYLE_KEYS.has(key)) {
102
+ presentationStyle[key] = value;
103
+ }
104
+ }
105
+ return Object.keys(presentationStyle).length > 0
106
+ ? presentationStyle
107
+ : undefined;
108
+ }
109
+ export function toProviderWidgetHostStyle({ isVisible, webViewStyle, }) {
110
+ if (!isVisible) {
111
+ return webViewStyle !== null && webViewStyle !== void 0 ? webViewStyle : HIDDEN_WIDGET_HOST_STYLE;
112
+ }
113
+ const visiblePresentationStyle = toVisibleWidgetHostPresentationStyle(webViewStyle);
114
+ return visiblePresentationStyle !== undefined
115
+ ? [visiblePresentationStyle, VISIBLE_WIDGET_HOST_STYLE]
116
+ : VISIBLE_WIDGET_HOST_STYLE;
117
+ }
118
+ export function ProviderWidgetHostOverlay({ children, isVisible, nativeView, sheetHostViewport, }) {
119
+ const widgetSheetStyle = sheetHostViewport
120
+ ? Object.assign(Object.assign({}, WIDGET_SHEET_STYLE), { height: sheetHostViewport.height }) : Object.assign(Object.assign({}, WIDGET_SHEET_STYLE), { height: "86%" });
121
+ const pointerEvents = isVisible ? "auto" : "none";
122
+ return createElement(nativeView, {
123
+ pointerEvents,
124
+ style: isVisible ? WIDGET_SHEET_OVERLAY_STYLE : HIDDEN_WIDGET_HOST_STYLE,
125
+ testID: "gx-widget-host-overlay",
126
+ }, createElement(nativeView, {
127
+ pointerEvents,
128
+ style: isVisible ? WIDGET_SHEET_BACKDROP_STYLE : HIDDEN_WIDGET_HOST_STYLE,
129
+ testID: "gx-widget-host-backdrop",
130
+ }), createElement(nativeView, {
131
+ pointerEvents,
132
+ style: isVisible ? widgetSheetStyle : HIDDEN_WIDGET_HOST_STYLE,
133
+ testID: "gx-widget-host-sheet",
134
+ }, children));
135
+ }
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 : "1.3.2";
6
+ export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "1.3.4";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getuserfeedback/react-native",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "description": "getuserfeedback React Native SDK",
5
5
  "keywords": [
6
6
  "getuserfeedback",
@@ -43,8 +43,8 @@
43
43
  "lint": "ultracite check ."
44
44
  },
45
45
  "dependencies": {
46
- "@getuserfeedback/protocol": "^1.2.0",
47
- "@getuserfeedback/sdk": "^0.7.0",
46
+ "@getuserfeedback/protocol": "^1.3.0",
47
+ "@getuserfeedback/sdk": "^0.7.1",
48
48
  "robot3": "^1.2.0"
49
49
  },
50
50
  "peerDependencies": {