@getuserfeedback/react-native 5.15.2 → 5.15.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/README.md +16 -0
- package/dist/native-color-scheme.d.ts +31 -0
- package/dist/native-color-scheme.js +44 -0
- package/dist/native-flow-content.js +41 -13
- package/dist/native-provider-client-controller.d.ts +3 -0
- package/dist/native-provider-client-controller.js +20 -1
- package/dist/native-provider.js +36 -7
- package/dist/native-runtime-root.js +3 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -45,6 +45,22 @@ export function App() {
|
|
|
45
45
|
|
|
46
46
|
That is enough to receive flows published for automatic Widget delivery.
|
|
47
47
|
|
|
48
|
+
## Native color scheme
|
|
49
|
+
|
|
50
|
+
For flows using the native renderer, set `clientOptions.colorScheme` to
|
|
51
|
+
`"light"`, `"dark"`, or `"system"`. Omitted values and browser auto-detect
|
|
52
|
+
objects follow the device appearance on native (light when unavailable).
|
|
53
|
+
|
|
54
|
+
Scheme-only prop changes and `client.configure({ colorScheme: "dark" })`
|
|
55
|
+
repaint the SDK's default native palette without restarting the flow or
|
|
56
|
+
clearing its draft. An unchanged prop does not override a later configure call.
|
|
57
|
+
The selection belongs to that client: runtime recreation retains it, while a
|
|
58
|
+
replacement client (for example, a new API key) starts from its initial prop.
|
|
59
|
+
Native repaint does not wait for Core: configure still forwards to Core and
|
|
60
|
+
retains its existing promise/error behavior, but remote failure does not roll
|
|
61
|
+
back native appearance. WebView flows keep their existing scheme forwarding
|
|
62
|
+
and browser auto-detection behavior. This does not add a style override API.
|
|
63
|
+
|
|
48
64
|
- [React Native SDK guide](https://getuserfeedback.com/docs/get-started/react-native-sdk)
|
|
49
65
|
- [React Native SDK reference](https://getuserfeedback.com/docs/reference/react-native-sdk-reference)
|
|
50
66
|
- [Package versions](https://www.npmjs.com/package/@getuserfeedback/react-native?activeTab=versions)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const NativeColorSchemeContext: import("react").Context<import("@getuserfeedback/protocol/host").ColorSchemeConfig | undefined>;
|
|
2
|
+
export declare function useNativeColorScheme(): {
|
|
3
|
+
scheme: "dark" | "light";
|
|
4
|
+
palette: {
|
|
5
|
+
background: string;
|
|
6
|
+
text: string;
|
|
7
|
+
muted: string;
|
|
8
|
+
input: string;
|
|
9
|
+
border: string;
|
|
10
|
+
placeholder: string;
|
|
11
|
+
button: string;
|
|
12
|
+
buttonText: string;
|
|
13
|
+
accent: string;
|
|
14
|
+
disabled: string;
|
|
15
|
+
disabledText: string;
|
|
16
|
+
error: string;
|
|
17
|
+
} | {
|
|
18
|
+
background: string;
|
|
19
|
+
text: string;
|
|
20
|
+
muted: string;
|
|
21
|
+
input: string;
|
|
22
|
+
border: string;
|
|
23
|
+
placeholder: string;
|
|
24
|
+
button: string;
|
|
25
|
+
buttonText: string;
|
|
26
|
+
accent: string;
|
|
27
|
+
disabled: string;
|
|
28
|
+
disabledText: string;
|
|
29
|
+
error: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
// Host-local presentation only; never the acknowledged Core configuration.
|
|
3
|
+
export const NativeColorSchemeContext = createContext(undefined);
|
|
4
|
+
const palettes = {
|
|
5
|
+
light: {
|
|
6
|
+
background: "#ffffff",
|
|
7
|
+
text: "#17202a",
|
|
8
|
+
muted: "#475569",
|
|
9
|
+
input: "#ffffff",
|
|
10
|
+
border: "#64748b",
|
|
11
|
+
placeholder: "#64748b",
|
|
12
|
+
button: "#e7eefb",
|
|
13
|
+
buttonText: "#17202a",
|
|
14
|
+
accent: "#2563eb",
|
|
15
|
+
disabled: "#e5e7eb",
|
|
16
|
+
disabledText: "#4b5563",
|
|
17
|
+
error: "#aa0000",
|
|
18
|
+
},
|
|
19
|
+
dark: {
|
|
20
|
+
background: "#111827",
|
|
21
|
+
text: "#f3f4f6",
|
|
22
|
+
muted: "#cbd5e1",
|
|
23
|
+
input: "#1f2937",
|
|
24
|
+
border: "#94a3b8",
|
|
25
|
+
placeholder: "#94a3b8",
|
|
26
|
+
button: "#1e3a5f",
|
|
27
|
+
buttonText: "#f8fafc",
|
|
28
|
+
accent: "#93c5fd",
|
|
29
|
+
disabled: "#374151",
|
|
30
|
+
disabledText: "#cbd5e1",
|
|
31
|
+
error: "#fca5a5",
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
export function useNativeColorScheme() {
|
|
35
|
+
const requested = useContext(NativeColorSchemeContext);
|
|
36
|
+
const device = require("react-native").useColorScheme();
|
|
37
|
+
// Browser auto-detection has no DOM on native; use the device preference.
|
|
38
|
+
const scheme = requested === "light" || requested === "dark"
|
|
39
|
+
? requested
|
|
40
|
+
: device === "dark"
|
|
41
|
+
? "dark"
|
|
42
|
+
: "light";
|
|
43
|
+
return { scheme, palette: palettes[scheme] };
|
|
44
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createElement, useLayoutEffect, useRef, useState, } from "react";
|
|
2
|
+
import { useNativeColorScheme } from "./native-color-scheme.js";
|
|
2
3
|
/** Thin native editor: drafts only. Core owns validation, navigation and submission. */
|
|
3
4
|
export function NativeFlowContent({ controller, presentationMode = "overlay", record, }) {
|
|
4
5
|
const flow = record.nativeFlow;
|
|
@@ -7,6 +8,7 @@ export function NativeFlowContent({ controller, presentationMode = "overlay", re
|
|
|
7
8
|
const { projection, interaction } = flow;
|
|
8
9
|
const { View, Text, TextInput, Pressable, ScrollView, useWindowDimensions, } = require("react-native");
|
|
9
10
|
const { height: windowHeight } = useWindowDimensions();
|
|
11
|
+
const { scheme, palette } = useNativeColorScheme();
|
|
10
12
|
const [draft, setDraft] = useState(projection.answers);
|
|
11
13
|
const rawDraft = useRef(draft);
|
|
12
14
|
const scroll = useRef(null);
|
|
@@ -68,16 +70,20 @@ export function NativeFlowContent({ controller, presentationMode = "overlay", re
|
|
|
68
70
|
onPress,
|
|
69
71
|
style: {
|
|
70
72
|
padding: 12,
|
|
71
|
-
backgroundColor: buttonDisabled ?
|
|
73
|
+
backgroundColor: buttonDisabled ? palette.disabled : palette.button,
|
|
72
74
|
borderRadius: 6,
|
|
73
75
|
marginTop: 8,
|
|
74
76
|
},
|
|
75
|
-
}, createElement(Text, {
|
|
77
|
+
}, createElement(Text, {
|
|
78
|
+
style: {
|
|
79
|
+
color: buttonDisabled ? palette.disabledText : palette.buttonText,
|
|
80
|
+
},
|
|
81
|
+
}, label));
|
|
76
82
|
return createElement(ScrollView, {
|
|
77
83
|
ref: scroll,
|
|
78
84
|
style: Object.assign(Object.assign({}, (presentationMode === "content"
|
|
79
85
|
? { flexGrow: 0, flexShrink: 1, maxHeight: windowHeight }
|
|
80
|
-
: { flex: 1, maxHeight: "100%" })), { width: "100%", backgroundColor:
|
|
86
|
+
: { flex: 1, maxHeight: "100%" })), { width: "100%", backgroundColor: palette.background }),
|
|
81
87
|
keyboardShouldPersistTaps: "handled",
|
|
82
88
|
nestedScrollEnabled: presentationMode === "content",
|
|
83
89
|
// Report the actual viewport, never the window ceiling or inner content.
|
|
@@ -87,29 +93,39 @@ export function NativeFlowContent({ controller, presentationMode = "overlay", re
|
|
|
87
93
|
testID: "native-flow-renderer",
|
|
88
94
|
style: { padding: 24, gap: 12 },
|
|
89
95
|
}, projection.mode === "simulated"
|
|
90
|
-
? createElement(Text, {
|
|
96
|
+
? createElement(Text, {
|
|
97
|
+
testID: "native-flow-simulated",
|
|
98
|
+
style: { color: palette.muted },
|
|
99
|
+
}, "SIMULATED — no response is saved")
|
|
91
100
|
: null, ...projection.blocks.map((block) => {
|
|
92
101
|
var _a;
|
|
93
102
|
if (block.kind === "statement")
|
|
94
|
-
return createElement(View, { key: block.key }, ...block.paragraphs.map((text, index) => createElement(Text, { key: index }, text)));
|
|
103
|
+
return createElement(View, { key: block.key }, ...block.paragraphs.map((text, index) => createElement(Text, { key: index, style: { color: palette.text } }, text)));
|
|
95
104
|
const value = draft[block.key];
|
|
96
105
|
const requiredLabel = block.required ? ", required" : "";
|
|
97
106
|
const selected = Array.isArray(value)
|
|
98
107
|
? ((_a = value[0]) !== null && _a !== void 0 ? _a : "")
|
|
99
108
|
: (value !== null && value !== void 0 ? value : "");
|
|
100
|
-
return createElement(View, { key: block.key, style: { gap: 6 } }, createElement(Text, {}, block.label + (block.required ? " *" : "")), block.description
|
|
109
|
+
return createElement(View, { key: block.key, style: { gap: 6 } }, createElement(Text, { style: { color: palette.text } }, block.label + (block.required ? " *" : "")), block.description
|
|
110
|
+
? createElement(Text, { style: { color: palette.muted } }, block.description)
|
|
111
|
+
: null, block.kind === "text"
|
|
101
112
|
? createElement(TextInput, {
|
|
102
113
|
accessibilityLabel: block.label + requiredLabel,
|
|
103
114
|
accessibilityHint: block.description,
|
|
104
115
|
value: selected,
|
|
105
116
|
placeholder: block.placeholder,
|
|
117
|
+
placeholderTextColor: palette.placeholder,
|
|
118
|
+
keyboardAppearance: scheme,
|
|
119
|
+
selectionColor: palette.accent,
|
|
120
|
+
cursorColor: palette.accent,
|
|
106
121
|
editable: !disabled,
|
|
107
122
|
maxLength: 4000,
|
|
108
123
|
onChangeText: (text) => update(block.key, text),
|
|
109
124
|
style: {
|
|
110
|
-
color:
|
|
125
|
+
color: disabled ? palette.disabledText : palette.text,
|
|
126
|
+
backgroundColor: disabled ? palette.disabled : palette.input,
|
|
111
127
|
borderWidth: 1,
|
|
112
|
-
borderColor:
|
|
128
|
+
borderColor: palette.border,
|
|
113
129
|
borderRadius: 4,
|
|
114
130
|
padding: 10,
|
|
115
131
|
},
|
|
@@ -132,12 +148,20 @@ export function NativeFlowContent({ controller, presentationMode = "overlay", re
|
|
|
132
148
|
disabled,
|
|
133
149
|
onPress: () => update(block.key, option.value),
|
|
134
150
|
style: { padding: 10 },
|
|
135
|
-
}, createElement(Text, {
|
|
136
|
-
|
|
151
|
+
}, createElement(Text, {
|
|
152
|
+
style: {
|
|
153
|
+
color: disabled ? palette.disabledText : palette.text,
|
|
154
|
+
},
|
|
155
|
+
}, `${selected === option.value ? "●" : "○"} ${option.label}`)))), projection.errors[block.key]
|
|
156
|
+
? createElement(Text, { accessibilityRole: "alert", style: { color: palette.error } }, projection.errors[block.key])
|
|
137
157
|
: null);
|
|
138
|
-
}), ...projection.formErrors.map((text, index) => createElement(Text, {
|
|
158
|
+
}), ...projection.formErrors.map((text, index) => createElement(Text, {
|
|
159
|
+
key: `error-${index}`,
|
|
160
|
+
accessibilityRole: "alert",
|
|
161
|
+
style: { color: palette.error },
|
|
162
|
+
}, text)), ...projection.terminal.map((text, index) => createElement(Text, { key: `terminal-${index}`, style: { color: palette.text } }, text)), projection.status === "succeeded" &&
|
|
139
163
|
(projection.mode === "simulated" || projection.terminal.length === 0)
|
|
140
|
-
? createElement(Text, { testID: "native-flow-complete" }, projection.mode === "simulated"
|
|
164
|
+
? createElement(Text, { testID: "native-flow-complete", style: { color: palette.text } }, projection.mode === "simulated"
|
|
141
165
|
? "SIMULATED completion — nothing saved"
|
|
142
166
|
: "Thank you")
|
|
143
167
|
: null, projection.canGoBack ? button("Back", () => interact("back")) : null, interaction === "draft-failed"
|
|
@@ -155,6 +179,10 @@ export function NativeFlowContent({ controller, presentationMode = "overlay", re
|
|
|
155
179
|
disabled: !record.isActive,
|
|
156
180
|
onPress: () => controller.closeNativeFlow(record),
|
|
157
181
|
style: { padding: 12 },
|
|
158
|
-
}, createElement(Text, {
|
|
182
|
+
}, createElement(Text, {
|
|
183
|
+
style: {
|
|
184
|
+
color: !record.isActive ? palette.disabledText : palette.text,
|
|
185
|
+
},
|
|
186
|
+
}, "Close"))
|
|
159
187
|
: null));
|
|
160
188
|
}
|
|
@@ -4,10 +4,13 @@ import { type OpenRequestDispatcher } from "@getuserfeedback/sdk/internal/open-r
|
|
|
4
4
|
export declare function createNativeProviderClientController(input: {
|
|
5
5
|
instanceId: string;
|
|
6
6
|
onError?: (error: Error) => void;
|
|
7
|
+
initialColorScheme?: ConfigureOptions["colorScheme"];
|
|
7
8
|
}): {
|
|
8
9
|
client: import("./client.js").Client;
|
|
9
10
|
directSessionController: import("./native-direct-command-session-controller.js").NativeDirectCommandSessionController;
|
|
10
11
|
flowRegistry: import("./native-provider-flow-registry.js").NativeProviderFlowRegistry;
|
|
12
|
+
getNativeColorScheme: () => import("@getuserfeedback/protocol/host").ColorSchemeConfig | undefined;
|
|
13
|
+
subscribeNativeColorScheme: (listener: () => void) => () => void;
|
|
11
14
|
getRuntimeConfiguration: () => ConfigureOptions;
|
|
12
15
|
observeOpenRequest: (payload: Parameters<OpenRequestDispatcher["dispatch"]>[0]) => ReturnType<OpenRequestDispatcher["dispatch"]>;
|
|
13
16
|
dispose: () => void;
|
|
@@ -4,6 +4,9 @@ import { createNativeProviderClient, parseRequiredString, } from "./native-provi
|
|
|
4
4
|
import { createNativeProviderCommandController } from "./native-provider-command-controller.js";
|
|
5
5
|
import { createNativeProviderFlowRegistry } from "./native-provider-flow-registry.js";
|
|
6
6
|
export function createNativeProviderClientController(input) {
|
|
7
|
+
// Presentation belongs to this client, independently of Core acknowledgement.
|
|
8
|
+
let nativeColorScheme = input.initialColorScheme;
|
|
9
|
+
const colorSchemeListeners = new Set();
|
|
7
10
|
let runtimeConfiguration = {};
|
|
8
11
|
const updateRuntimeConfiguration = (updates) => {
|
|
9
12
|
runtimeConfiguration = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, runtimeConfiguration), (updates.auth === undefined ? {} : { auth: updates.auth })), (updates.capabilities === undefined
|
|
@@ -44,7 +47,15 @@ export function createNativeProviderClientController(input) {
|
|
|
44
47
|
catch (error) {
|
|
45
48
|
return commands.reject(error);
|
|
46
49
|
}
|
|
47
|
-
const settlement = await commands.runOperation((dispatch) =>
|
|
50
|
+
const settlement = await commands.runOperation((dispatch) => {
|
|
51
|
+
if (canonicalCommand.kind === "configure" &&
|
|
52
|
+
canonicalCommand.opts.colorScheme !== undefined) {
|
|
53
|
+
nativeColorScheme = canonicalCommand.opts.colorScheme;
|
|
54
|
+
for (const listener of colorSchemeListeners)
|
|
55
|
+
listener();
|
|
56
|
+
}
|
|
57
|
+
return dispatch(canonicalCommand);
|
|
58
|
+
}, options);
|
|
48
59
|
if (canonicalCommand.kind === "configure" && settlement !== undefined) {
|
|
49
60
|
updateRuntimeConfiguration(canonicalCommand.opts);
|
|
50
61
|
}
|
|
@@ -57,9 +68,17 @@ export function createNativeProviderClientController(input) {
|
|
|
57
68
|
client,
|
|
58
69
|
directSessionController: session,
|
|
59
70
|
flowRegistry: flows,
|
|
71
|
+
getNativeColorScheme: () => nativeColorScheme,
|
|
72
|
+
subscribeNativeColorScheme: (listener) => {
|
|
73
|
+
colorSchemeListeners.add(listener);
|
|
74
|
+
return () => {
|
|
75
|
+
colorSchemeListeners.delete(listener);
|
|
76
|
+
};
|
|
77
|
+
},
|
|
60
78
|
getRuntimeConfiguration: () => (Object.assign({}, runtimeConfiguration)),
|
|
61
79
|
observeOpenRequest,
|
|
62
80
|
dispose: () => {
|
|
81
|
+
colorSchemeListeners.clear();
|
|
63
82
|
flows.reset();
|
|
64
83
|
commands.dispose();
|
|
65
84
|
},
|
package/dist/native-provider.js
CHANGED
|
@@ -9,12 +9,13 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { parseInitOptions } from "@getuserfeedback/protocol";
|
|
12
|
+
import { DEFAULT_AUTO_DETECT_COLOR_SCHEME_ATTRS, parseInitOptions, } from "@getuserfeedback/protocol";
|
|
13
13
|
import { createUniqueId } from "@getuserfeedback/protocol/host";
|
|
14
14
|
import { createActionRegistry, } from "@getuserfeedback/sdk/internal/action-registry";
|
|
15
15
|
import { resolveLinkRouter } from "@getuserfeedback/sdk/internal/link-router";
|
|
16
|
-
import { createContext, createElement, Fragment, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
|
|
16
|
+
import { createContext, createElement, Fragment, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from "react";
|
|
17
17
|
import { NativeStandardFlowContainer } from "./flow-container.js";
|
|
18
|
+
import { NativeColorSchemeContext } from "./native-color-scheme.js";
|
|
18
19
|
import { NativeFlowContainerContext, } from "./native-flow-container-context.js";
|
|
19
20
|
import { createNativeProviderClientController } from "./native-provider-client-controller.js";
|
|
20
21
|
import { REACT_NATIVE_PINNED_CORE_URL } from "./native-runtime-endpoints.js";
|
|
@@ -123,7 +124,9 @@ export function GetUserFeedbackProvider({ children, clientOptions, instanceId: i
|
|
|
123
124
|
const actionRegistry = useNativeActionRegistry(clientOptions.actions);
|
|
124
125
|
const linkRouter = useNativeLinkRouter(clientOptions.links);
|
|
125
126
|
const normalizedClientOptions = parseNativeInitOptions(clientOptions, actionRegistry.definitions);
|
|
126
|
-
const
|
|
127
|
+
const { colorScheme } = normalizedClientOptions, runtimeIdentityOptions = __rest(normalizedClientOptions, ["colorScheme"]);
|
|
128
|
+
const clientOptionsKey = toClientOptionsKey(runtimeIdentityOptions);
|
|
129
|
+
const colorSchemePropKey = toClientOptionsKey(colorScheme);
|
|
127
130
|
const coreUrl = (_b = (_a = normalizedClientOptions.runtimeEndpoints) === null || _a === void 0 ? void 0 : _a.coreUrl) !== null && _b !== void 0 ? _b : REACT_NATIVE_PINNED_CORE_URL;
|
|
128
131
|
const onErrorRef = useRef(onError);
|
|
129
132
|
onErrorRef.current = onError;
|
|
@@ -140,14 +143,40 @@ export function GetUserFeedbackProvider({ children, clientOptions, instanceId: i
|
|
|
140
143
|
apiKey: normalizedClientOptions.apiKey,
|
|
141
144
|
hostCapabilities: normalizedClientOptions.hostCapabilities,
|
|
142
145
|
});
|
|
143
|
-
const
|
|
146
|
+
const createControllerOwner = () => ({
|
|
144
147
|
identityKey: clientIdentityKey,
|
|
148
|
+
colorSchemePropKey,
|
|
145
149
|
controller: createNativeProviderClientController({
|
|
146
150
|
instanceId,
|
|
147
151
|
onError: reportError,
|
|
152
|
+
initialColorScheme: colorScheme,
|
|
148
153
|
}),
|
|
149
|
-
})
|
|
154
|
+
});
|
|
155
|
+
let [controllerOwner, setControllerOwner] = useState(createControllerOwner);
|
|
156
|
+
// Initialize the whole owner together, before committing a replacement client.
|
|
157
|
+
// Scheme-only prop changes update that owner without replacing it.
|
|
158
|
+
if (controllerOwner.identityKey !== clientIdentityKey) {
|
|
159
|
+
controllerOwner = createControllerOwner();
|
|
160
|
+
setControllerOwner(controllerOwner);
|
|
161
|
+
}
|
|
150
162
|
const controller = controllerOwner.controller;
|
|
163
|
+
const hostColorScheme = useSyncExternalStore(controller.subscribeNativeColorScheme, controller.getNativeColorScheme, controller.getNativeColorScheme);
|
|
164
|
+
useLayoutEffect(() => {
|
|
165
|
+
if (controllerOwner.colorSchemePropKey === colorSchemePropKey)
|
|
166
|
+
return;
|
|
167
|
+
controllerOwner.colorSchemePropKey = colorSchemePropKey;
|
|
168
|
+
// Prop changes share configure's forwarding path, not runtime identity.
|
|
169
|
+
// Unchanged props must not undo a later imperative configure.
|
|
170
|
+
void controller.client
|
|
171
|
+
.configure({
|
|
172
|
+
colorScheme: colorScheme !== null && colorScheme !== void 0 ? colorScheme : {
|
|
173
|
+
autoDetectColorScheme: [...DEFAULT_AUTO_DETECT_COLOR_SCHEME_ATTRS],
|
|
174
|
+
},
|
|
175
|
+
})
|
|
176
|
+
.catch(() => {
|
|
177
|
+
// The controller reports remote failures; local appearance is retained.
|
|
178
|
+
});
|
|
179
|
+
}, [colorScheme, colorSchemePropKey, controller, controllerOwner]);
|
|
151
180
|
const attachViewProjection = useCallback((nextProjection) => {
|
|
152
181
|
setProjection(nextProjection);
|
|
153
182
|
return () => setProjection((current) => current === nextProjection ? null : current);
|
|
@@ -199,7 +228,7 @@ export function GetUserFeedbackProvider({ children, clientOptions, instanceId: i
|
|
|
199
228
|
}, [controller]);
|
|
200
229
|
const getRuntimeConfiguration = useCallback(() => controller.getRuntimeConfiguration(), [controller]);
|
|
201
230
|
const handleHandleInvalidated = useCallback((message) => controller.onHandleInvalidated(message), [controller]);
|
|
202
|
-
return createElement(GetUserFeedbackContext.Provider, { value: controller.client }, createElement(NativeFlowContainerContext.Provider, { value: flowContainerContext }, createElement(Fragment, null, children, createElement(NativeStandardFlowContainer), createElement(NativeProviderRuntime, {
|
|
231
|
+
return createElement(NativeColorSchemeContext.Provider, { value: hostColorScheme }, createElement(GetUserFeedbackContext.Provider, { value: controller.client }, createElement(NativeFlowContainerContext.Provider, { value: flowContainerContext }, createElement(Fragment, null, children, createElement(NativeStandardFlowContainer), createElement(NativeProviderRuntime, {
|
|
203
232
|
attachViewProjection,
|
|
204
233
|
coreUrl,
|
|
205
234
|
coreWebViewComponent: webViewComponent,
|
|
@@ -215,7 +244,7 @@ export function GetUserFeedbackProvider({ children, clientOptions, instanceId: i
|
|
|
215
244
|
onHandleInvalidated: handleHandleInvalidated,
|
|
216
245
|
observeOpenRequest: controller.observeOpenRequest,
|
|
217
246
|
viewWebViewComponent: webViewComponent,
|
|
218
|
-
}))));
|
|
247
|
+
})))));
|
|
219
248
|
}
|
|
220
249
|
/**
|
|
221
250
|
* Returns the React Native SDK client from the nearest provider.
|
|
@@ -40,7 +40,9 @@ export function NativeRuntimeRoot({ attachViewProjection, coreUrl, coreWebViewCo
|
|
|
40
40
|
const onStartupTerminalErrorRef = useRef(onStartupTerminalError);
|
|
41
41
|
onStartupTerminalErrorRef.current = onStartupTerminalError;
|
|
42
42
|
const createStartupCommandRef = useRef(createStartupCommand);
|
|
43
|
-
|
|
43
|
+
useLayoutEffect(() => {
|
|
44
|
+
createStartupCommandRef.current = createStartupCommand;
|
|
45
|
+
}, [createStartupCommand]);
|
|
44
46
|
const hostActionsRef = useRef(hostActions);
|
|
45
47
|
hostActionsRef.current = hostActions;
|
|
46
48
|
const linkRouterRef = useRef(linkRouter);
|
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 : "5.15.
|
|
6
|
+
export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "5.15.4";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getuserfeedback/react-native",
|
|
3
|
-
"version": "5.15.
|
|
3
|
+
"version": "5.15.4",
|
|
4
4
|
"description": "getuserfeedback React Native SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"getuserfeedback",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"lint": "biome check ."
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@getuserfeedback/protocol": "^6.0.
|
|
58
|
-
"@getuserfeedback/sdk": "^0.19.
|
|
57
|
+
"@getuserfeedback/protocol": "^6.0.4",
|
|
58
|
+
"@getuserfeedback/sdk": "^0.19.5",
|
|
59
59
|
"robot3": "^1.2.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|