@getuserfeedback/react 0.6.2 → 0.6.10

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 CHANGED
@@ -1,10 +1,8 @@
1
1
  # @getuserfeedback/react
2
2
 
3
- A secure and performant SDK for [getuserfeedback.com](https://getuserfeedback.com).
3
+ In-product surveys for React apps, from [getuserfeedback.com](https://getuserfeedback.com). Ask one short question at the right moment, and read every answer.
4
4
 
5
- `@getuserfeedback/react` lets you add Widget messages and micro-surveys optimized to help you connect with users, build trust, guide development, and avoid building in a vacuum.
6
-
7
- > Using plain JavaScript or another framework? Check out [@getuserfeedback/sdk](https://www.npmjs.com/package/@getuserfeedback/sdk).
5
+ > Plain JavaScript or another framework? Use [@getuserfeedback/sdk](https://www.npmjs.com/package/@getuserfeedback/sdk).
8
6
 
9
7
  ## Install
10
8
 
@@ -14,105 +12,13 @@ npm install @getuserfeedback/react
14
12
 
15
13
  Requires `react >= 18`.
16
14
 
17
- ## Get started
18
-
19
- ### 1. Get an API key
20
- Sign up on [getuserfeedback.com](https://getuserfeedback.com) and grab your key in Settings.
21
-
22
- ### 2. Add the provider
23
-
24
- ```tsx
25
- import { GetUserFeedbackProvider } from "@getuserfeedback/react";
26
-
27
- export function App() {
28
- return (
29
- <GetUserFeedbackProvider clientOptions={{ apiKey: "YOUR_API_KEY" }}>
30
- <AppRoutes />
31
- </GetUserFeedbackProvider>
32
- );
33
- }
34
- ```
35
-
36
- ### 3. Start collecting responses
37
-
38
- Pick one of our curated templates on [getuserfeedback.com/templates](https://getuserfeedback.com/templates) — from a post-signup welcome message to customer satisfaction surveys, feedback forms, and more. You can also customize everything or start from scratch.
39
-
40
- ### 4. Get feedback — improve product — repeat
41
- Our widgets are optimized to get you *more* responses. Polished UI, crafted copy, templates, and a million subtle tricks. Result — you get more responses, make better roadmap calls, and find product-market fit faster.
42
-
43
- ### Bonus
44
- Our AI-powered theme editor allows a complete overhaul of the widget look and feel with a single prompt. Demo: [getuserfeedback.com/themes](https://getuserfeedback.com/themes).
45
-
46
- ## Advanced use cases
47
- ### Feedback form
48
- You can open Widget surveys from code, e.g., show a feedback form when the user clicks a dedicated button in your UI.
49
-
50
- ```tsx
51
- import { useFlow } from "@getuserfeedback/react";
52
-
53
- const CONTACT_SUPPORT_FLOW_ID = "YOUR_FLOW_ID";
54
-
55
- export function ContactSupportMenuItem() {
56
- const { open } = useFlow({ flowId: CONTACT_SUPPORT_FLOW_ID });
57
-
58
- return (
59
- <button type="button" onClick={() => open()}>
60
- Contact support
61
- </button>
62
- );
63
- }
64
- ```
65
-
66
- ### Bring your own UI
67
- By default, flows are displayed in a floating container and [themed](https://getuserfeedback.com/themes) accordingly. Beyond that, you can replace the default floating container with your own. This gives you unprecedented customization options for a seamless user experience.
15
+ ## For AI agents
68
16
 
69
- For example, if you're using shadcn/ui dialogs throughout your product, our widgets can be seamlessly rendered into them and appear just like any other part of your app.
17
+ Installing this for someone? Start with our MCP server, not with this page. Connect `https://mcp.getuserfeedback.com` (listed in the MCP registry as `com.getuserfeedback/mcp`) and read its get-started resource — `getuserfeedback://docs/get-started`. It walks the whole path in order: workspace, API key (the MCP hands it to you), this package's install, the first survey, and which steps need a human.
70
18
 
71
- ```tsx
72
- import { useFlow } from "@getuserfeedback/react";
73
- import { Button, Dialog, DialogContent } from "ui";
74
-
75
- export function FeedbackDialog() {
76
- const {
77
- isLoading,
78
- setOpen,
79
- shouldRenderContainer,
80
- containerRef,
81
- width,
82
- height
83
- } = useFlow({ flowId: "YOUR_FLOW_ID", container: "custom" });
84
-
85
- return (
86
- <>
87
- <Button
88
- type="button"
89
- onClick={() => setOpen(true)}
90
- disabled={isLoading}
91
- >
92
- Open feedback
93
- </Button>
94
- <Dialog open={shouldRenderContainer} onOpenChange={setOpen}>
95
- <DialogContent
96
- ref={containerRef}
97
- style={{ width, height }}
98
- />
99
- </Dialog>
100
- </>
101
- );
102
- }
103
- ```
104
-
105
- ## API Overview
106
-
107
- - `GetUserFeedbackProvider`
108
- - `useGetUserFeedback()`
109
- - `useFeedback()`
110
- - `useFlow({ flowId, prefetchOnMount?, hideCloseButton?, container?: "default" | "custom" })`
111
- - `useDefaultFlowContainer()`
112
-
113
- ## `GetUserFeedbackProvider`
19
+ ## Get started
114
20
 
115
- Initialize the SDK client.
21
+ Grab your Public API key from the dashboard — Settings → Widget — and mount the provider near the root of your app:
116
22
 
117
23
  ```tsx
118
24
  import { GetUserFeedbackProvider } from "@getuserfeedback/react";
@@ -120,505 +26,38 @@ import { GetUserFeedbackProvider } from "@getuserfeedback/react";
120
26
  export function App() {
121
27
  return (
122
28
  <GetUserFeedbackProvider clientOptions={{ apiKey: "YOUR_API_KEY" }}>
123
- <AppRoutes />
124
- </GetUserFeedbackProvider>
125
- );
126
- }
127
- ```
128
-
129
- ### Options
130
-
131
- Pass SDK options via `clientOptions`:
132
-
133
- - `apiKey` (`string`, required): your project API key.
134
- - `colorScheme` (`"light" | "dark" | "system" | { autoDetectColorScheme: string[] }`, optional):
135
- controls widget theme mode. See [Dark mode](#dark-mode).
136
- - `disableAutoLoad` (`boolean`, optional): if `true`, call `client.load()` manually.
137
- - `disableTelemetry` (`boolean`, optional): disables anonymous telemetry used for performance and error monitoring.
138
-
139
- ### Delay widget load
140
-
141
- If you want to manually control when the widget starts loading:
142
-
143
- ```tsx
144
- import { useEffect } from "react";
145
- import {
146
- GetUserFeedbackProvider,
147
- useGetUserFeedback,
148
- } from "@getuserfeedback/react";
149
-
150
- function LoadWidgetAfterConsent({
151
- hasResolvedConsent,
152
- }: {
153
- hasResolvedConsent: boolean;
154
- }) {
155
- const client = useGetUserFeedback();
156
-
157
- useEffect(() => {
158
- if (!hasResolvedConsent) {
159
- return;
160
- }
161
-
162
- client.load();
163
- }, [client, hasResolvedConsent]);
164
-
165
- return null;
166
- }
167
-
168
- export function App({ hasResolvedConsent }: { hasResolvedConsent: boolean }) {
169
- return (
170
- <GetUserFeedbackProvider
171
- clientOptions={{ apiKey: "YOUR_API_KEY", disableAutoLoad: true }}
172
- >
173
- <AppRoutes />
174
- <LoadWidgetAfterConsent hasResolvedConsent={hasResolvedConsent} />
175
- </GetUserFeedbackProvider>
176
- );
177
- }
178
- ```
179
-
180
- ## Submit feedback
181
-
182
- Use `useFeedback()` when your app renders the feedback controls. The complete
183
- feedback payload is provided when the user submits it.
184
-
185
- ```tsx
186
- import { useFeedback } from "@getuserfeedback/react";
187
-
188
- export function HelpfulButton({
189
- onError,
190
- }: {
191
- onError: (error: unknown) => void;
192
- }) {
193
- const { submit, isSubmitting } = useFeedback();
194
-
195
- async function markHelpful() {
196
- try {
197
- await submit({
198
- target: {
199
- collection: "docs-page",
200
- id: "getting-started",
201
- },
202
- category: "helpfulness",
203
- value: true,
204
- });
205
- } catch (error) {
206
- onError(error);
207
- }
208
- }
209
-
210
- return (
211
- <button
212
- type="button"
213
- disabled={isSubmitting}
214
- onClick={markHelpful}
215
- >
216
- Helpful
217
- </button>
218
- );
219
- }
220
- ```
221
-
222
- `isSubmitting` remains `true` while submissions from that hook are pending.
223
- `submit()` resolves with the accepted evaluation receipt and rejects if capture
224
- fails.
225
-
226
- ### Read previous feedback
227
-
228
- Call `fetch()` only in contexts that need to restore feedback previously given
229
- by the current user. It does not run automatically. Feedback readback requires
230
- `auth.jwt`; calling `identify()` alone does not authorize it.
231
-
232
- ```tsx
233
- const { fetch, isFetching } = useFeedback();
234
-
235
- const { items } = await fetch({
236
- selectors: [
237
- {
238
- target: { collection: "docs-page", id: "getting-started" },
239
- category: "helpfulness",
240
- },
241
- ],
242
- });
243
- ```
244
-
245
- `isFetching` remains `true` while fetches from that hook are pending. Results
246
- stay aligned with selector order, with `evaluation: null` when no match exists.
247
-
248
- ## Identify users
249
-
250
- Use identity to unlock cohort targeting and attach responses to user profiles.
251
-
252
- ### `client.identify(userId, traits?)` or `client.identify(traits)`
253
-
254
- ```tsx
255
- import { useEffect } from "react";
256
- import { useGetUserFeedback } from "@getuserfeedback/react";
257
-
258
- type User = {
259
- id: string;
260
- email?: string;
261
- firstName?: string;
262
- lastName?: string;
263
- };
264
-
265
- export function Identify({ user }: { user: User | null }) {
266
- const client = useGetUserFeedback();
267
-
268
- useEffect(() => {
269
- if (!user) {
270
- return;
271
- }
272
-
273
- client.identify(user.id, {
274
- email: user.email,
275
- firstName: user.firstName,
276
- lastName: user.lastName,
277
- });
278
- }, [client, user]);
279
-
280
- return null;
281
- }
282
- ```
283
-
284
- ### `client.reset()`
285
-
286
- Call this on logout to clear active identity state and auth (if you use auth):
287
-
288
- ```tsx
289
- import { useGetUserFeedback } from "@getuserfeedback/react";
290
- import { useAuth } from "./auth";
291
-
292
- export function LogoutButton() {
293
- const { signOut } = useAuth();
294
- const { reset } = useGetUserFeedback();
295
-
296
- const handleLogout = async () => {
297
- await signOut();
298
- await reset();
299
- };
300
-
301
- return (
302
- <button type="button" onClick={handleLogout}>
303
- Log out
304
- </button>
305
- );
306
- }
307
- ```
308
-
309
- ## Dark mode
310
-
311
- If you're using industry-standard ways to indicate when dark mode is *on*, the widget will pick it up and automatically keep itself in sync. If you only have light mode, the widget will stay in light mode.
312
-
313
- Default behavior:
314
- - The widget observes `class` and `data-theme` attributes on both `html` and `body`.
315
- - `class="dark"` / `data-theme="dark"` enables dark mode.
316
- - `class="light"` / `data-theme="light"` enables light mode.
317
- - `class="system"` / `data-theme="system"` follows the user's system preference (`prefers-color-scheme`).
318
- - If nothing is detected, it falls back to `"light"`.
319
-
320
- You can control the behavior using the `colorScheme` option when creating a client, and you can also update it later.
321
-
322
- ### Set a static color scheme at startup
323
-
324
- ```tsx
325
- import { GetUserFeedbackProvider } from "@getuserfeedback/react";
326
-
327
- export function App() {
328
- return (
329
- <GetUserFeedbackProvider
330
- clientOptions={{
331
- apiKey: "YOUR_API_KEY",
332
- colorScheme: "dark", // set to a static value
333
- }}
334
- >
335
- <AppRoutes />
336
- </GetUserFeedbackProvider>
337
- );
338
- }
339
- ```
340
-
341
- `colorScheme` supports:
342
- - `{ autoDetectColorScheme: string[] }`
343
- - `"light" | "dark" | "system"`
344
-
345
- ### Update color scheme at runtime
346
-
347
- ```tsx
348
- import { useEffect } from "react";
349
- import { useGetUserFeedback } from "@getuserfeedback/react";
350
-
351
- type ThemePreference = "light" | "dark" | "system";
352
-
353
- export function SyncWidgetTheme({
354
- themePreference,
355
- }: {
356
- themePreference: ThemePreference;
357
- }) {
358
- const client = useGetUserFeedback();
359
-
360
- useEffect(() => {
361
- client.configure({ colorScheme: themePreference });
362
- }, [client, themePreference]);
363
-
364
- return null;
365
- }
366
- ```
367
-
368
- You can also switch runtime behavior back to host-driven auto-detection:
369
-
370
- ```tsx
371
- import { useEffect } from "react";
372
- import { useGetUserFeedback } from "@getuserfeedback/react";
373
-
374
- export function SyncWidgetToAppTheme({
375
- useAppTheme,
376
- }: {
377
- useAppTheme: boolean;
378
- }) {
379
- const client = useGetUserFeedback();
380
-
381
- useEffect(() => {
382
- if (!useAppTheme) {
383
- return;
384
- }
385
-
386
- client.configure({
387
- colorScheme: {
388
- autoDetectColorScheme: ["class", "data-theme"], // default
389
- },
390
- });
391
- }, [client, useAppTheme]);
392
-
393
- return null;
394
- }
395
- ```
396
-
397
- ## Auth (optional)
398
-
399
- You can run the SDK without auth. This is standard industry practice for client-side widgets like ours, so it is not enforced by default. However, we encourage you to implement auth for stricter controls.
400
-
401
- Enable JWT validation in your workspace settings and pass a signed token from your app.
402
-
403
- ### Clerk example: set, refresh, and clear auth token
404
-
405
- ```tsx
406
- import { useEffect } from "react";
407
- import { useAuth } from "@clerk/clerk-react";
408
- import { useGetUserFeedback } from "@getuserfeedback/react";
409
-
410
- const AUTH_REFRESH_INTERVAL_MS = 5 * 60 * 1000;
411
-
412
- // Mount once inside both <ClerkProvider> and <GetUserFeedbackProvider>.
413
- export function GetUserFeedbackClerkAuth() {
414
- const client = useGetUserFeedback();
415
- const { isLoaded, userId, sessionId, getToken } = useAuth();
416
-
417
- useEffect(() => {
418
- if (!isLoaded) {
419
- return;
420
- }
421
-
422
- let isDisposed = false;
423
-
424
- const syncAuthToken = async () => {
425
- // Signed out: clear auth token.
426
- if (!userId) {
427
- await client.configure({ auth: { jwt: null } });
428
- return;
429
- }
430
-
431
- // Signed in: fetch/refresh Clerk JWT and pass it to the SDK.
432
- const token = await getToken({ template: "getuserfeedback" });
433
- if (isDisposed) {
434
- return;
435
- }
436
-
437
- if (!token) {
438
- await client.configure({ auth: { jwt: null } });
439
- return;
440
- }
441
-
442
- await client.configure({ auth: { jwt: { token } } });
443
- };
444
-
445
- syncAuthToken();
446
- const refreshTimer = window.setInterval(() => {
447
- syncAuthToken();
448
- }, AUTH_REFRESH_INTERVAL_MS);
449
-
450
- return () => {
451
- isDisposed = true;
452
- window.clearInterval(refreshTimer);
453
- };
454
- }, [client, getToken, isLoaded, sessionId, userId]);
455
-
456
- return null;
457
- }
458
- ```
459
-
460
- ## Privacy and consent (GDPR, CCPA, etc)
461
-
462
- Consent settings control non-essential data scopes: analytics, storage, personalization, ads.
463
-
464
- By default, the widget starts with `granted` consent. For compliance with privacy regulations like GDPR and CCPA, you may want to choose a different default.
465
-
466
- ### Set default consent to `pending`
467
- ```tsx
468
- import { GetUserFeedbackProvider } from "@getuserfeedback/react";
469
-
470
- export function App() {
471
- return (
472
- <GetUserFeedbackProvider
473
- clientOptions={{
474
- apiKey: "YOUR_API_KEY",
475
- defaultConsent: "pending", // set to `pending`
476
- }}
477
- >
478
- <AppRoutes />
29
+ <YourApp />
479
30
  </GetUserFeedbackProvider>
480
31
  );
481
32
  }
482
33
  ```
483
- With `pending` consent set by default, all non-essential data scopes are considered effectively denied.
484
34
 
485
- ### Update consent at runtime
486
-
487
- For example, sync consent from your cookie banner or CMP state:
35
+ If your app has signed-in users, also identify them. It lets surveys target signed-in users, and each answer arrives attributed to the person instead of anonymous. Call identify from an effect keyed on your auth state — resetting only when a signed-in user signs out, so anonymous visitors keep their identity — and render the component anywhere inside the provider:
488
36
 
489
37
  ```tsx
490
- import { useEffect } from "react";
38
+ import { useEffect, useRef } from "react";
491
39
  import { useGetUserFeedback } from "@getuserfeedback/react";
492
- import { useCookieConsent } from "./cookie-consent";
493
40
 
494
- export function GetUserFeedbackConsentSync() {
41
+ function IdentifyUser({ user }: { user: { id: string; email: string } | null }) {
495
42
  const client = useGetUserFeedback();
496
- const { hasAnswered, analyticsEnabled } = useCookieConsent();
497
-
43
+ const wasIdentified = useRef(false);
498
44
  useEffect(() => {
499
- if (!hasAnswered) {
500
- client.configure({ consent: "pending" });
501
- return;
502
- }
503
-
504
- if (!analyticsEnabled) {
505
- client.configure({ consent: "denied" });
506
- return;
45
+ if (user) {
46
+ client.identify(user.id, { email: user.email });
47
+ wasIdentified.current = true;
48
+ } else if (wasIdentified.current) {
49
+ wasIdentified.current = false;
50
+ client.reset();
507
51
  }
508
-
509
- client.configure({
510
- consent: ["analytics.measurement", "analytics.storage"],
511
- });
512
- }, [analyticsEnabled, client, hasAnswered]);
513
-
52
+ }, [user, client]);
514
53
  return null;
515
54
  }
516
55
  ```
517
56
 
518
- Or, when users save privacy settings, pass explicit granted scopes:
519
-
520
- ```tsx
521
- import { useGetUserFeedback } from "@getuserfeedback/react";
522
-
523
- type PrivacySettings = {
524
- analyticsEnabled: boolean;
525
- personalizedAdsEnabled: boolean;
526
- };
527
-
528
- export function useSavePrivacySettings() {
529
- const client = useGetUserFeedback();
530
-
531
- return async ({
532
- analyticsEnabled,
533
- personalizedAdsEnabled,
534
- }: PrivacySettings) => {
535
- const grantedScopes: Array<
536
- | "analytics.measurement"
537
- | "analytics.storage"
538
- | "ads.storage"
539
- | "ads.user_data"
540
- | "ads.personalization"
541
- > = [];
542
-
543
- if (analyticsEnabled) {
544
- grantedScopes.push("analytics.measurement", "analytics.storage");
545
- }
57
+ That's it. The widget is running, and surveys you publish in the dashboard show up based on the targeting you set there — nothing shows until you publish something.
546
58
 
547
- if (personalizedAdsEnabled) {
548
- grantedScopes.push(
549
- "ads.storage",
550
- "ads.user_data",
551
- "ads.personalization",
552
- );
553
- }
554
-
555
- await client.configure({
556
- consent: grantedScopes.length > 0 ? grantedScopes : "denied",
557
- });
558
- };
559
- }
560
-
561
- ```
562
- `defaultConsent` supports:
563
- - `"pending" | "granted" (default) | "denied" | "revoked"`
564
- - or a granted-scope list like `["analytics.measurement", "analytics.storage"]`
565
-
566
- ### Impact of different consent settings
567
-
568
- - Response collection: never affected.
569
- - Opening Widget surveys: never affected.
570
- - Cohort targeting: rules that depend on persisted activity, identity continuity, or storage-backed signals require both `analytics.measurement` and `analytics.storage`.
571
- - Context targeting: rules based on current-page context (URL, referrer, timing, host signals) require `analytics.measurement` only.
572
-
573
- ## Advanced — open Widget surveys from code
574
-
575
- ### Open a survey
576
-
577
- ```tsx
578
- import { useFlow } from "@getuserfeedback/react";
579
-
580
- const BUG_REPORT_FLOW_ID = "YOUR_FLOW_ID";
581
-
582
- export function ReportBugButton() {
583
- const { open } = useFlow({ flowId: BUG_REPORT_FLOW_ID });
584
-
585
- return (
586
- <button type="button" onClick={() => open()}>
587
- Report a bug
588
- </button>
589
- );
590
- }
591
- ```
592
-
593
- ### Prefetch and prerender
594
-
595
- Prefetching loads flow resources over the network. Prerendering warms up the UI
596
- before opening. Opening still handles the render step if you have not prerendered
597
- first.
598
-
599
- ```tsx
600
- import { useFlow } from "@getuserfeedback/react";
601
-
602
- const FEEDBACK_FLOW_ID = "YOUR_FLOW_ID";
603
-
604
- export function HelpMenuFeedbackItem() {
605
- const { prerender, open } = useFlow({
606
- flowId: FEEDBACK_FLOW_ID,
607
- prefetchOnMount: true,
608
- });
609
-
610
- return (
611
- <button
612
- type="button"
613
- onMouseEnter={() => prerender()}
614
- onFocus={() => prerender()}
615
- onClick={() => open()}
616
- >
617
- Share product feedback
618
- </button>
619
- );
620
- }
621
- ```
59
+ - Full guide: [getuserfeedback.com/docs/get-started/react-sdk](https://getuserfeedback.com/docs/get-started/react-sdk)
60
+ - API reference: [getuserfeedback.com/docs/reference/react-sdk-reference](https://getuserfeedback.com/docs/reference/react-sdk-reference)
622
61
 
623
62
  ## Links
624
63
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import{createClient as $}from"@getuserfeedback/sdk";import{createContext as j,useCallback as K,useContext as z,useEffect as L,useMemo as F,useRef as q,useState as H,useSyncExternalStore as k}from"react";import{jsx as g}from"react/jsx-runtime";var J={isOpen:!1,isLoading:!1,shouldRenderContainer:!1,width:void 0,height:void 0},p=(U)=>({isOpen:U.isOpen,isLoading:U.isLoading,width:U.width,height:U.height}),r=(U,O)=>U.isOpen===O.isOpen&&U.isLoading===O.isLoading&&U.width===O.width&&U.height===O.height,D={isOpen:!1,isLoading:!1,width:void 0,height:void 0},P=(U)=>typeof U.width==="number"&&typeof U.height==="number";function V(U){let O=q(U.getFlowState());return K(()=>{let G=U.getFlowState(),R=O.current;if(r(R,G))return R;return O.current=G,G},[U])}function M(U,O,G){let R=V(U),I=q(null),A=q(null),v=K(()=>{let E=R();if(I.current===E){let N=A.current;if(N!==null)return N}let _=O(E);return I.current=E,A.current=_,_},[R,O]);return k((E)=>U.subscribeFlowState(()=>{E()},{emitInitial:!1}),v,G)}var y=j(null);function w({children:U,clientOptions:O}){let G=$(O),R=q(null),I=q(0),A=M(G,p,()=>J),v=K((b)=>{if(R.current=b,I.current===0)return;G.setDefaultContainerPolicy({kind:"hostContainer",host:b,sharing:"perFlowRun"})},[G]),E=K(()=>{if(I.current+=1,I.current===1)G.setDefaultContainerPolicy({kind:"hostContainer",host:R.current,sharing:"perFlowRun"});return()=>{if(I.current=Math.max(0,I.current-1),I.current===0)G.setDefaultContainerPolicy({kind:"floating"})}},[G]),_=F(()=>{if(!A.isOpen&&!A.isLoading)return J;return{isOpen:A.isOpen,isLoading:A.isLoading,shouldRenderContainer:!0,width:A.width,height:A.height}},[A]),N=F(()=>({client:G,apiKey:O.apiKey,setDefaultFlowContainer:v,registerDefaultFlowContainerConsumer:E,defaultFlowContainerState:_}),[G,O.apiKey,_,E,v]);return g(y.Provider,{value:N,children:U})}var h=(U)=>{let O=z(y);if(!O)throw Error("useFlow must be used within a GetUserFeedbackProvider");let{client:G}=O,{flowId:R,prefetchOnMount:I=!1,hideCloseButton:A}=U.flow,v=F(()=>G.flow(R),[G,R]),E=U.mode==="container",_=q(null),N=M(v,(T)=>T,()=>D),b=K((T)=>!E?v.open({hideCloseButton:A,metadata:T?.metadata}):v.open({container:_.current??null,hideCloseButton:A,metadata:T?.metadata}),[v,A,E]),B=K(()=>v.close(),[v]),W=K((T)=>T?b():B(),[B,b]),X=K((T)=>{if(!E)return;_.current=T,v.setContainer(T)},[v,E]),Y=P(N),Z=E&&(N.isOpen||N.isLoading&&Y);return L(()=>{if(!I)return;v.prefetch()},[v,I]),{isOpen:N.isOpen,isLoading:N.isLoading,width:N.width,height:N.height,shouldRenderContainer:Z,setOpen:W,open:b,close:B,prerender:()=>v.prerender({hideCloseButton:A}),containerRef:X}};function m(U){let G=(U.container??"default")==="custom"?"container":"default",R=h({flow:{flowId:U.flowId,prefetchOnMount:U.prefetchOnMount,hideCloseButton:U.hideCloseButton},mode:G});if(G==="container")return{container:"custom",isOpen:R.isOpen,isLoading:R.isLoading,width:R.width,height:R.height,shouldRenderContainer:R.shouldRenderContainer,open:R.open,setOpen:R.setOpen,prerender:R.prerender,containerRef:R.containerRef};return{container:"default",isOpen:R.isOpen,isLoading:R.isLoading,width:R.width,height:R.height,open:R.open,close:R.close,prerender:R.prerender}}function d(){let U=z(y);if(!U)throw Error("useDefaultFlowContainer must be used within a GetUserFeedbackProvider");let{client:O,defaultFlowContainerState:G,registerDefaultFlowContainerConsumer:R,setDefaultFlowContainer:I}=U;L(()=>R(),[R]);let A=K((_)=>{I(_)},[I]),v=K(()=>O.close(),[O]),E=K((_)=>{if(_)return Promise.resolve();return v()},[v]);return{isOpen:G.isOpen,isLoading:G.isLoading,shouldRenderContainer:G.shouldRenderContainer,width:G.width,height:G.height,setOpen:E,containerRef:A}}function x(){let U=z(y);if(!U)throw Error("useFeedback must be used within a GetUserFeedbackProvider");let[O,G]=H(0),[R,I]=H(0),A=K(async(E)=>{G((_)=>_+1);try{return await U.client.feedback.fetch(E)}finally{G((_)=>_-1)}},[U.client]),v=K(async(E)=>{I((_)=>_+1);try{return await U.client.feedback.submit(E)}finally{I((_)=>_-1)}},[U.client]);return{fetch:A,isFetching:O>0,isSubmitting:R>0,submit:v}}function f(){let U=z(y);if(!U)throw Error("useGetUserFeedback must be used within a GetUserFeedbackProvider");return U.client}var Q="0.6.2".trim(),S=Q.length>0?Q:"0.0.0-local";export{f as useGetUserFeedback,m as useFlow,x as useFeedback,d as useDefaultFlowContainer,S as REACT_SDK_VERSION,w as GetUserFeedbackProvider};
2
+ import{createClient as $}from"@getuserfeedback/sdk";import{createContext as j,useCallback as K,useContext as z,useEffect as L,useMemo as F,useRef as q,useState as H,useSyncExternalStore as k}from"react";import{jsx as g}from"react/jsx-runtime";var J={isOpen:!1,isLoading:!1,shouldRenderContainer:!1,width:void 0,height:void 0},p=(U)=>({isOpen:U.isOpen,isLoading:U.isLoading,width:U.width,height:U.height}),r=(U,O)=>U.isOpen===O.isOpen&&U.isLoading===O.isLoading&&U.width===O.width&&U.height===O.height,D={isOpen:!1,isLoading:!1,width:void 0,height:void 0},P=(U)=>typeof U.width==="number"&&typeof U.height==="number";function V(U){let O=q(U.getFlowState());return K(()=>{let G=U.getFlowState(),R=O.current;if(r(R,G))return R;return O.current=G,G},[U])}function M(U,O,G){let R=V(U),I=q(null),A=q(null),v=K(()=>{let E=R();if(I.current===E){let N=A.current;if(N!==null)return N}let _=O(E);return I.current=E,A.current=_,_},[R,O]);return k((E)=>U.subscribeFlowState(()=>{E()},{emitInitial:!1}),v,G)}var y=j(null);function w({children:U,clientOptions:O}){let G=$(O),R=q(null),I=q(0),A=M(G,p,()=>J),v=K((b)=>{if(R.current=b,I.current===0)return;G.setDefaultContainerPolicy({kind:"hostContainer",host:b,sharing:"perFlowRun"})},[G]),E=K(()=>{if(I.current+=1,I.current===1)G.setDefaultContainerPolicy({kind:"hostContainer",host:R.current,sharing:"perFlowRun"});return()=>{if(I.current=Math.max(0,I.current-1),I.current===0)G.setDefaultContainerPolicy({kind:"floating"})}},[G]),_=F(()=>{if(!A.isOpen&&!A.isLoading)return J;return{isOpen:A.isOpen,isLoading:A.isLoading,shouldRenderContainer:!0,width:A.width,height:A.height}},[A]),N=F(()=>({client:G,apiKey:O.apiKey,setDefaultFlowContainer:v,registerDefaultFlowContainerConsumer:E,defaultFlowContainerState:_}),[G,O.apiKey,_,E,v]);return g(y.Provider,{value:N,children:U})}var h=(U)=>{let O=z(y);if(!O)throw Error("useFlow must be used within a GetUserFeedbackProvider");let{client:G}=O,{flowId:R,prefetchOnMount:I=!1,hideCloseButton:A}=U.flow,v=F(()=>G.flow(R),[G,R]),E=U.mode==="container",_=q(null),N=M(v,(T)=>T,()=>D),b=K((T)=>!E?v.open({hideCloseButton:A,metadata:T?.metadata}):v.open({container:_.current??null,hideCloseButton:A,metadata:T?.metadata}),[v,A,E]),B=K(()=>v.close(),[v]),W=K((T)=>T?b():B(),[B,b]),X=K((T)=>{if(!E)return;_.current=T,v.setContainer(T)},[v,E]),Y=P(N),Z=E&&(N.isOpen||N.isLoading&&Y);return L(()=>{if(!I)return;v.prefetch()},[v,I]),{isOpen:N.isOpen,isLoading:N.isLoading,width:N.width,height:N.height,shouldRenderContainer:Z,setOpen:W,open:b,close:B,prerender:()=>v.prerender({hideCloseButton:A}),containerRef:X}};function m(U){let G=(U.container??"default")==="custom"?"container":"default",R=h({flow:{flowId:U.flowId,prefetchOnMount:U.prefetchOnMount,hideCloseButton:U.hideCloseButton},mode:G});if(G==="container")return{container:"custom",isOpen:R.isOpen,isLoading:R.isLoading,width:R.width,height:R.height,shouldRenderContainer:R.shouldRenderContainer,open:R.open,setOpen:R.setOpen,prerender:R.prerender,containerRef:R.containerRef};return{container:"default",isOpen:R.isOpen,isLoading:R.isLoading,width:R.width,height:R.height,open:R.open,close:R.close,prerender:R.prerender}}function d(){let U=z(y);if(!U)throw Error("useDefaultFlowContainer must be used within a GetUserFeedbackProvider");let{client:O,defaultFlowContainerState:G,registerDefaultFlowContainerConsumer:R,setDefaultFlowContainer:I}=U;L(()=>R(),[R]);let A=K((_)=>{I(_)},[I]),v=K(()=>O.close(),[O]),E=K((_)=>{if(_)return Promise.resolve();return v()},[v]);return{isOpen:G.isOpen,isLoading:G.isLoading,shouldRenderContainer:G.shouldRenderContainer,width:G.width,height:G.height,setOpen:E,containerRef:A}}function x(){let U=z(y);if(!U)throw Error("useFeedback must be used within a GetUserFeedbackProvider");let[O,G]=H(0),[R,I]=H(0),A=K(async(E)=>{G((_)=>_+1);try{return await U.client.feedback.fetch(E)}finally{G((_)=>_-1)}},[U.client]),v=K(async(E)=>{I((_)=>_+1);try{return await U.client.feedback.submit(E)}finally{I((_)=>_-1)}},[U.client]);return{fetch:A,isFetching:O>0,isSubmitting:R>0,submit:v}}function f(){let U=z(y);if(!U)throw Error("useGetUserFeedback must be used within a GetUserFeedbackProvider");return U.client}var Q="0.6.10".trim(),S=Q.length>0?Q:"0.0.0-local";export{f as useGetUserFeedback,m as useFlow,x as useFeedback,d as useDefaultFlowContainer,S as REACT_SDK_VERSION,w as GetUserFeedbackProvider};
3
3
 
4
- //# debugId=40692E37516B248764756E2164756E21
4
+ //# debugId=0480976B43E9968064756E2164756E21
5
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -5,7 +5,7 @@
5
5
  "\"use client\";\n\nimport {\n\ttype Client,\n\ttype ClientOptions,\n\tcreateClient,\n\ttype FeedbackInput,\n\ttype FetchFeedbackInput,\n\ttype FetchFeedbackResult,\n\ttype FlowState,\n\ttype OpenFlowOptions as SdkOpenFlowOptions,\n\ttype SubmitFeedbackResult,\n} from \"@getuserfeedback/sdk\";\nimport type { ReactElement, ReactNode } from \"react\";\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n\tuseSyncExternalStore,\n} from \"react\";\n\n/** Return value for useFeedback(). */\nexport interface UseFeedbackReturn {\n\t/** Fetch feedback matching each selector for the JWT-authenticated user. */\n\tfetch: (input: FetchFeedbackInput) => Promise<FetchFeedbackResult>;\n\t/** True while one or more fetches from this hook are pending. */\n\tisFetching: boolean;\n\t/** True while one or more submissions from this hook are pending. */\n\tisSubmitting: boolean;\n\t/** Submit feedback about the current app or a specific target. */\n\tsubmit: (input: FeedbackInput) => Promise<SubmitFeedbackResult>;\n}\n\n/**\n * Options for useFlow().\n */\nexport interface UseFlowOptions {\n\t/** The flow/survey ID to control. */\n\tflowId: string;\n\t/** Prefetch the flow resources on mount so it opens faster. Default `false`. */\n\tprefetchOnMount?: boolean;\n\t/**\n\t * Where the flow mounts: `\"default\"` (floating container) or `\"custom\"` (your container via containerRef).\n\t * Default `\"default\"`.\n\t */\n\tcontainer?: \"default\" | \"custom\";\n\t/** When true, the view does not show a close button. */\n\thideCloseButton?: boolean;\n}\n\n/**\n * Per-open options for useFlow(). These apply to the specific response created\n * by that open action and do not affect prerendering.\n */\nexport interface UseFlowOpenOptions {\n\t/** Optional response metadata to preserve with the eventual submission. */\n\tmetadata?: SdkOpenFlowOptions[\"metadata\"];\n}\n\n/**\n * Return value for useFlow() when container is `\"default\"`: state and callbacks for the floating flow.\n */\nexport interface UseFlowReturn {\n\treadonly container: \"default\";\n\t/** True when the flow is visible. */\n\tisOpen: boolean;\n\t/** True after open is requested while the flow is not visible yet. */\n\tisLoading: boolean;\n\t/** Open the flow. */\n\topen: (options?: UseFlowOpenOptions) => Promise<void>;\n\t/** Close the flow. */\n\tclose: () => Promise<void>;\n\t/** Prerendering warms up the flow for instant display later. */\n\tprerender: () => Promise<void>;\n\t/** Flow width in pixels (when known). */\n\twidth?: number;\n\t/** Flow height in pixels (when known). */\n\theight?: number;\n}\n\n/**\n * Return value for useFlow() when container is `\"custom\"`: state and callbacks for host-managed container flows.\n */\nexport interface UseFlowContainerReturn {\n\treadonly container: \"custom\";\n\t/** True when the flow is visible. */\n\tisOpen: boolean;\n\t/** True after open is requested while the flow is not visible yet. */\n\tisLoading: boolean;\n\t/** True when your host UI should render the custom container element. */\n\tshouldRenderContainer: boolean;\n\t/** Open the flow in the custom container. */\n\topen: (options?: UseFlowOpenOptions) => Promise<void>;\n\t/** Open the flow when `true`, close when `false`. */\n\tsetOpen: (next: boolean) => Promise<void>;\n\t/** Prerendering warms up the flow for instant display later. */\n\tprerender: () => Promise<void>;\n\t/** Ref callback: attach this to the container element where the flow should render. */\n\tcontainerRef: (element: HTMLDivElement | null) => void;\n\t/** Flow width in pixels (when known). */\n\twidth?: number;\n\t/** Flow height in pixels (when known). */\n\theight?: number;\n}\n\n/**\n * Return value for useDefaultFlowContainer(): container ref and aggregate flow state\n * for all flows in the same provider subtree (including targeting-engine opens).\n */\nexport interface UseDefaultFlowContainerReturn {\n\t/** True when any flow is visible. */\n\tisOpen: boolean;\n\t/** True after any flow open is requested while the flow is not visible yet. */\n\tisLoading: boolean;\n\t/** True when your host UI should render the default flow container. */\n\tshouldRenderContainer: boolean;\n\t/** Active flow width in pixels (when known). */\n\twidth?: number;\n\t/** Active flow height in pixels (when known). */\n\theight?: number;\n\t/** Close currently displayed flows when `false`; opening is flow-driven. */\n\tsetOpen: (next: boolean) => Promise<void>;\n\t/** Ref callback for the default flow container element. */\n\tcontainerRef: (element: HTMLDivElement | null) => void;\n}\n\ntype InstanceFlowRenderState = {\n\tisOpen: boolean;\n\tisLoading: boolean;\n\twidth?: number;\n\theight?: number;\n};\n\ntype DefaultFlowContainerState = {\n\tisOpen: boolean;\n\tisLoading: boolean;\n\tshouldRenderContainer: boolean;\n\twidth?: number;\n\theight?: number;\n};\n\nconst DEFAULT_FLOW_CONTAINER_STATE: DefaultFlowContainerState = {\n\tisOpen: false,\n\tisLoading: false,\n\tshouldRenderContainer: false,\n\twidth: undefined,\n\theight: undefined,\n};\n\nconst toInstanceFlowRenderState = (\n\tstate: FlowState,\n): InstanceFlowRenderState => ({\n\tisOpen: state.isOpen,\n\tisLoading: state.isLoading,\n\twidth: state.width,\n\theight: state.height,\n});\n\nconst isSameFlowState = (\n\ta: Pick<FlowState, \"isOpen\" | \"isLoading\" | \"width\" | \"height\">,\n\tb: Pick<FlowState, \"isOpen\" | \"isLoading\" | \"width\" | \"height\">,\n): boolean =>\n\ta.isOpen === b.isOpen &&\n\ta.isLoading === b.isLoading &&\n\ta.width === b.width &&\n\ta.height === b.height;\n\ntype FlowStateStore = {\n\tgetFlowState: () => FlowState;\n\tsubscribeFlowState: (\n\t\tlistener: (state: FlowState) => void,\n\t\toptions?: { emitInitial?: boolean },\n\t) => () => void;\n};\n\nconst FALLBACK_FLOW_STATE: FlowState = {\n\tisOpen: false,\n\tisLoading: false,\n\twidth: undefined,\n\theight: undefined,\n};\n\nconst hasPreparedFlowState = (state: FlowState): boolean =>\n\ttypeof state.width === \"number\" && typeof state.height === \"number\";\n\nfunction useStableFlowStateSnapshot(store: FlowStateStore): () => FlowState {\n\tconst snapshotRef = useRef<FlowState>(store.getFlowState());\n\n\treturn useCallback((): FlowState => {\n\t\tconst next = store.getFlowState();\n\t\tconst previous = snapshotRef.current;\n\t\tif (isSameFlowState(previous, next)) {\n\t\t\treturn previous;\n\t\t}\n\t\tsnapshotRef.current = next;\n\t\treturn next;\n\t}, [store]);\n}\n\nfunction useFlowStateStoreValue<TState>(\n\tstore: FlowStateStore,\n\tproject: (state: FlowState) => TState,\n\tgetServerSnapshot: () => TState,\n): TState {\n\tconst getFlowStateSnapshot = useStableFlowStateSnapshot(store);\n\tconst lastSourceSnapshotRef = useRef<FlowState | null>(null);\n\tconst lastProjectedSnapshotRef = useRef<TState | null>(null);\n\tconst getProjectedSnapshot = useCallback((): TState => {\n\t\tconst sourceSnapshot = getFlowStateSnapshot();\n\t\tif (lastSourceSnapshotRef.current === sourceSnapshot) {\n\t\t\tconst cachedProjectedSnapshot = lastProjectedSnapshotRef.current;\n\t\t\tif (cachedProjectedSnapshot !== null) {\n\t\t\t\treturn cachedProjectedSnapshot;\n\t\t\t}\n\t\t}\n\t\tconst projectedSnapshot = project(sourceSnapshot);\n\t\tlastSourceSnapshotRef.current = sourceSnapshot;\n\t\tlastProjectedSnapshotRef.current = projectedSnapshot;\n\t\treturn projectedSnapshot;\n\t}, [getFlowStateSnapshot, project]);\n\n\treturn useSyncExternalStore<TState>(\n\t\t(onStoreChange) =>\n\t\t\tstore.subscribeFlowState(\n\t\t\t\t() => {\n\t\t\t\t\tonStoreChange();\n\t\t\t\t},\n\t\t\t\t{ emitInitial: false },\n\t\t\t),\n\t\tgetProjectedSnapshot,\n\t\tgetServerSnapshot,\n\t);\n}\n\ntype GetUserFeedbackContextValue = {\n\tclient: Client;\n\tapiKey: string;\n\tsetDefaultFlowContainer: (element: HTMLElement | null) => void;\n\tregisterDefaultFlowContainerConsumer: () => () => void;\n\tdefaultFlowContainerState: DefaultFlowContainerState;\n};\n\nconst GetUserFeedbackContext =\n\tcreateContext<GetUserFeedbackContextValue | null>(null);\n\nexport interface GetUserFeedbackProviderProps {\n\t/** Application subtree that can use getuserfeedback hooks. */\n\tchildren: ReactNode;\n\t/** Core SDK client options used to create/reuse the underlying client. */\n\tclientOptions: ClientOptions;\n}\n\n/**\n * Provider for getuserfeedback React hooks.\n * Wrap your app (or a subtree) so `useFeedback`, `useFlow`,\n * `useDefaultFlowContainer`, and `useGetUserFeedback` can access a client\n * created from `clientOptions`.\n *\n * If your app uses `useDefaultFlowContainer()`, all flows in this subtree\n * (including targeting-engine opens) target that container.\n * If the container ref is not mounted yet, loader keeps flows parked until it is.\n *\n * @example Basic usage\n * ```tsx\n * function App() {\n * return (\n * <GetUserFeedbackProvider clientOptions={{ apiKey: \"YOUR_API_KEY\" }}>\n * <Routes />\n * </GetUserFeedbackProvider>\n * );\n * }\n * ```\n *\n * @example Display *any* flow in your own dialog (a shadcn/ui dialog in this example):\n * ```tsx\n * function DefaultFlowContainer() {\n * const { containerRef, shouldRenderContainer, width, height, setOpen } = useDefaultFlowContainer();\n *\n * return (\n * <Dialog open={shouldRenderContainer} onOpenChange={setOpen}>\n * <DialogContent ref={containerRef} style={{ width, height }} />\n * </Dialog>\n * );\n * }\n *\n * function App() {\n * return (\n * <GetUserFeedbackProvider clientOptions={{ apiKey: \"YOUR_API_KEY\" }}>\n * <AppRoutes />\n * <DefaultFlowContainer /> // Flows will be triggered by the targeting engine and displayed in your own dialog\n * </GetUserFeedbackProvider>\n * );\n * }\n * ```\n */\nexport function GetUserFeedbackProvider({\n\tchildren,\n\tclientOptions,\n}: GetUserFeedbackProviderProps): ReactElement {\n\tconst client = createClient(clientOptions);\n\tconst defaultFlowContainerRef = useRef<HTMLElement | null>(null);\n\tconst defaultFlowContainerConsumerCountRef = useRef(0);\n\tconst instanceFlowState = useFlowStateStoreValue<InstanceFlowRenderState>(\n\t\tclient,\n\t\ttoInstanceFlowRenderState,\n\t\t() => DEFAULT_FLOW_CONTAINER_STATE,\n\t);\n\n\tconst setDefaultFlowContainer = useCallback(\n\t\t(element: HTMLElement | null) => {\n\t\t\tdefaultFlowContainerRef.current = element;\n\t\t\tif (defaultFlowContainerConsumerCountRef.current === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tclient.setDefaultContainerPolicy({\n\t\t\t\tkind: \"hostContainer\",\n\t\t\t\thost: element,\n\t\t\t\tsharing: \"perFlowRun\",\n\t\t\t});\n\t\t},\n\t\t[client],\n\t);\n\n\tconst registerDefaultFlowContainerConsumer = useCallback(() => {\n\t\tdefaultFlowContainerConsumerCountRef.current += 1;\n\t\tif (defaultFlowContainerConsumerCountRef.current === 1) {\n\t\t\tclient.setDefaultContainerPolicy({\n\t\t\t\tkind: \"hostContainer\",\n\t\t\t\thost: defaultFlowContainerRef.current,\n\t\t\t\tsharing: \"perFlowRun\",\n\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tdefaultFlowContainerConsumerCountRef.current = Math.max(\n\t\t\t\t0,\n\t\t\t\tdefaultFlowContainerConsumerCountRef.current - 1,\n\t\t\t);\n\t\t\tif (defaultFlowContainerConsumerCountRef.current === 0) {\n\t\t\t\tclient.setDefaultContainerPolicy({ kind: \"floating\" });\n\t\t\t}\n\t\t};\n\t}, [client]);\n\n\tconst defaultFlowContainerState = useMemo<DefaultFlowContainerState>(() => {\n\t\tif (!instanceFlowState.isOpen && !instanceFlowState.isLoading) {\n\t\t\treturn DEFAULT_FLOW_CONTAINER_STATE;\n\t\t}\n\t\treturn {\n\t\t\tisOpen: instanceFlowState.isOpen,\n\t\t\tisLoading: instanceFlowState.isLoading,\n\t\t\tshouldRenderContainer: true,\n\t\t\twidth: instanceFlowState.width,\n\t\t\theight: instanceFlowState.height,\n\t\t};\n\t}, [instanceFlowState]);\n\n\tconst contextValue = useMemo(\n\t\t() => ({\n\t\t\tclient,\n\t\t\tapiKey: clientOptions.apiKey,\n\t\t\tsetDefaultFlowContainer,\n\t\t\tregisterDefaultFlowContainerConsumer,\n\t\t\tdefaultFlowContainerState,\n\t\t}),\n\t\t[\n\t\t\tclient,\n\t\t\tclientOptions.apiKey,\n\t\t\tdefaultFlowContainerState,\n\t\t\tregisterDefaultFlowContainerConsumer,\n\t\t\tsetDefaultFlowContainer,\n\t\t],\n\t);\n\n\treturn (\n\t\t<GetUserFeedbackContext.Provider value={contextValue}>\n\t\t\t{children}\n\t\t</GetUserFeedbackContext.Provider>\n\t);\n}\n\ntype UseFlowControllerOptions = {\n\tflow: UseFlowOptions;\n\tmode: \"default\" | \"container\";\n};\n\ntype UseFlowControllerReturn = {\n\tisOpen: boolean;\n\tisLoading: boolean;\n\twidth?: number;\n\theight?: number;\n\tshouldRenderContainer: boolean;\n\tsetOpen: (next: boolean) => Promise<void>;\n\topen: (options?: UseFlowOpenOptions) => Promise<void>;\n\tclose: () => Promise<void>;\n\tprerender: () => Promise<void>;\n\tcontainerRef: (element: HTMLDivElement | null) => void;\n};\n\nconst useFlowController = (\n\toptions: UseFlowControllerOptions,\n): UseFlowControllerReturn => {\n\tconst ctx = useContext(GetUserFeedbackContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"useFlow must be used within a GetUserFeedbackProvider\");\n\t}\n\tconst { client } = ctx;\n\tconst { flowId, prefetchOnMount = false, hideCloseButton } = options.flow;\n\tconst flowRun = useMemo(() => client.flow(flowId), [client, flowId]);\n\tconst requiresContainer = options.mode === \"container\";\n\tconst customContainerRef = useRef<HTMLDivElement | null>(null);\n\n\t/** Flow state from loader events; open/loading + dimensions. */\n\tconst flowState = useFlowStateStoreValue<FlowState>(\n\t\tflowRun,\n\t\t(state) => state,\n\t\t() => FALLBACK_FLOW_STATE,\n\t);\n\n\tconst open = useCallback(\n\t\t(openOptions?: UseFlowOpenOptions): Promise<void> =>\n\t\t\t!requiresContainer\n\t\t\t\t? flowRun.open({\n\t\t\t\t\t\thideCloseButton,\n\t\t\t\t\t\tmetadata: openOptions?.metadata,\n\t\t\t\t\t})\n\t\t\t\t: flowRun.open({\n\t\t\t\t\t\tcontainer: customContainerRef.current ?? null,\n\t\t\t\t\t\thideCloseButton,\n\t\t\t\t\t\tmetadata: openOptions?.metadata,\n\t\t\t\t\t}),\n\t\t[flowRun, hideCloseButton, requiresContainer],\n\t);\n\n\tconst close = useCallback((): Promise<void> => flowRun.close(), [flowRun]);\n\n\tconst setOpen = useCallback(\n\t\t(next: boolean): Promise<void> => (next ? open() : close()),\n\t\t[close, open],\n\t);\n\n\tconst containerRef = useCallback(\n\t\t(element: HTMLDivElement | null): void => {\n\t\t\tif (!requiresContainer) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcustomContainerRef.current = element;\n\t\t\tflowRun.setContainer(element);\n\t\t},\n\t\t[flowRun, requiresContainer],\n\t);\n\n\tconst hasPreparedCustomView = hasPreparedFlowState(flowState);\n\tconst shouldRenderContainer =\n\t\trequiresContainer &&\n\t\t(flowState.isOpen || (flowState.isLoading && hasPreparedCustomView));\n\n\tuseEffect(() => {\n\t\tif (!prefetchOnMount) {\n\t\t\treturn;\n\t\t}\n\t\tflowRun.prefetch();\n\t}, [flowRun, prefetchOnMount]);\n\n\treturn {\n\t\tisOpen: flowState.isOpen,\n\t\tisLoading: flowState.isLoading,\n\t\twidth: flowState.width,\n\t\theight: flowState.height,\n\t\tshouldRenderContainer,\n\t\tsetOpen,\n\t\topen,\n\t\tclose,\n\t\tprerender: () => flowRun.prerender({ hideCloseButton }),\n\t\tcontainerRef,\n\t};\n};\n\n/**\n * @name useFlow\n * @description Open a Widget survey in the default floating container or your own container.\n * @example Default (floating) container\n * ```tsx\n * const { open, isLoading } = useFlow({ flowId: \"sur_123\" });\n * await open({\n * metadata: {\n * tags: {\n * journey_stage: \"onboarding\",\n * },\n * },\n * });\n * ```\n * @example Custom container\n * ```tsx\n * const { containerRef, shouldRenderContainer, open } = useFlow({ flowId: \"sur_123\", container: \"custom\" });\n * ```\n */\nexport function useFlow(\n\toptions: UseFlowOptions & { container?: \"default\" },\n): UseFlowReturn;\nexport function useFlow(\n\toptions: UseFlowOptions & { container: \"custom\" },\n): UseFlowContainerReturn;\nexport function useFlow(\n\toptions: UseFlowOptions,\n): UseFlowReturn | UseFlowContainerReturn {\n\tconst container = options.container ?? \"default\";\n\tconst mode = container === \"custom\" ? \"container\" : \"default\";\n\tconst controller = useFlowController({\n\t\tflow: {\n\t\t\tflowId: options.flowId,\n\t\t\tprefetchOnMount: options.prefetchOnMount,\n\t\t\thideCloseButton: options.hideCloseButton,\n\t\t},\n\t\tmode,\n\t});\n\n\tif (mode === \"container\") {\n\t\treturn {\n\t\t\tcontainer: \"custom\",\n\t\t\tisOpen: controller.isOpen,\n\t\t\tisLoading: controller.isLoading,\n\t\t\twidth: controller.width,\n\t\t\theight: controller.height,\n\t\t\tshouldRenderContainer: controller.shouldRenderContainer,\n\t\t\topen: controller.open,\n\t\t\tsetOpen: controller.setOpen,\n\t\t\tprerender: controller.prerender,\n\t\t\tcontainerRef: controller.containerRef,\n\t\t};\n\t}\n\n\treturn {\n\t\tcontainer: \"default\",\n\t\tisOpen: controller.isOpen,\n\t\tisLoading: controller.isLoading,\n\t\twidth: controller.width,\n\t\theight: controller.height,\n\t\topen: controller.open,\n\t\tclose: controller.close,\n\t\tprerender: controller.prerender,\n\t};\n}\n\n/**\n * @name useDefaultFlowContainer\n * @description Register and control a default flow container for all flows in this provider subtree.\n * @example Display any flow in your own dialog\n * ```tsx\n * function DefaultFlowContainer() {\n * const { containerRef, shouldRenderContainer, width, height, setOpen } = useDefaultFlowContainer();\n * return (\n * <Dialog open={shouldRenderContainer} onOpenChange={setOpen}>\n * <DialogContent ref={containerRef} style={{ width, height }} />\n * </Dialog>\n * );\n * }\n *\n * function App() {\n * return (\n * <GetUserFeedbackProvider clientOptions={{ apiKey: \"YOUR_API_KEY\" }}>\n * <AppRoutes />\n * <DefaultFlowContainer />\n * </GetUserFeedbackProvider>\n * );\n * }\n * ```\n */\nexport function useDefaultFlowContainer(): UseDefaultFlowContainerReturn {\n\tconst ctx = useContext(GetUserFeedbackContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"useDefaultFlowContainer must be used within a GetUserFeedbackProvider\",\n\t\t);\n\t}\n\n\tconst {\n\t\tclient,\n\t\tdefaultFlowContainerState,\n\t\tregisterDefaultFlowContainerConsumer,\n\t\tsetDefaultFlowContainer,\n\t} = ctx;\n\n\tuseEffect(\n\t\t() => registerDefaultFlowContainerConsumer(),\n\t\t[registerDefaultFlowContainerConsumer],\n\t);\n\n\tconst containerRef = useCallback(\n\t\t(element: HTMLDivElement | null): void => {\n\t\t\tsetDefaultFlowContainer(element);\n\t\t},\n\t\t[setDefaultFlowContainer],\n\t);\n\n\tconst close = useCallback((): Promise<void> => client.close(), [client]);\n\n\tconst setOpen = useCallback(\n\t\t(next: boolean): Promise<void> => {\n\t\t\tif (next) {\n\t\t\t\treturn Promise.resolve();\n\t\t\t}\n\t\t\treturn close();\n\t\t},\n\t\t[close],\n\t);\n\n\treturn {\n\t\tisOpen: defaultFlowContainerState.isOpen,\n\t\tisLoading: defaultFlowContainerState.isLoading,\n\t\tshouldRenderContainer: defaultFlowContainerState.shouldRenderContainer,\n\t\twidth: defaultFlowContainerState.width,\n\t\theight: defaultFlowContainerState.height,\n\t\tsetOpen,\n\t\tcontainerRef,\n\t};\n}\n\n/**\n * Submit feedback or explicitly fetch the JWT-authenticated user's feedback.\n *\n * Neither operation runs automatically. Each promise returns the corresponding\n * SDK result and rejects when the operation fails.\n */\nexport function useFeedback(): UseFeedbackReturn {\n\tconst ctx = useContext(GetUserFeedbackContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"useFeedback must be used within a GetUserFeedbackProvider\",\n\t\t);\n\t}\n\n\tconst [pendingFetchCount, setPendingFetchCount] = useState(0);\n\tconst [pendingSubmissionCount, setPendingSubmissionCount] = useState(0);\n\tconst fetch = useCallback(\n\t\tasync (input: FetchFeedbackInput): Promise<FetchFeedbackResult> => {\n\t\t\tsetPendingFetchCount((count) => count + 1);\n\t\t\ttry {\n\t\t\t\treturn await ctx.client.feedback.fetch(input);\n\t\t\t} finally {\n\t\t\t\tsetPendingFetchCount((count) => count - 1);\n\t\t\t}\n\t\t},\n\t\t[ctx.client],\n\t);\n\tconst submit = useCallback(\n\t\tasync (input: FeedbackInput): Promise<SubmitFeedbackResult> => {\n\t\t\tsetPendingSubmissionCount((count) => count + 1);\n\t\t\ttry {\n\t\t\t\treturn await ctx.client.feedback.submit(input);\n\t\t\t} finally {\n\t\t\t\tsetPendingSubmissionCount((count) => count - 1);\n\t\t\t}\n\t\t},\n\t\t[ctx.client],\n\t);\n\n\treturn {\n\t\tfetch,\n\t\tisFetching: pendingFetchCount > 0,\n\t\tisSubmitting: pendingSubmissionCount > 0,\n\t\tsubmit,\n\t};\n}\n\n/**\n * Hook for accessing the getuserfeedback client instance.\n *\n * @see https://getuserfeedback.com/docs/reference/react-sdk-reference\n * @see https://getuserfeedback.com/docs/reference/events\n *\n * @example Basic usage\n * ```tsx\n * const client = useGetUserFeedback();\n *\n * // on login\n * client.identify('user-123', { email: 'user@example.com' });\n *\n * // track a product event\n * client.track(\"Checkout Started\", { plan: \"pro\" });\n *\n * // on logout\n * client.reset();\n * ```\n *\n * @example Override color scheme\n * ```tsx\n * const client = useGetUserFeedback();\n * await client.configure({ colorScheme: \"dark\" });\n * ```\n */\nexport function useGetUserFeedback(): Client {\n\tconst ctx = useContext(GetUserFeedbackContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"useGetUserFeedback must be used within a GetUserFeedbackProvider\",\n\t\t);\n\t}\n\treturn ctx.client;\n}\n",
6
6
  "declare const __GX_REACT_SDK_VERSION__: string | undefined;\n\nconst reactSdkVersion =\n\ttypeof __GX_REACT_SDK_VERSION__ === \"string\"\n\t\t? __GX_REACT_SDK_VERSION__.trim()\n\t\t: \"\";\n\n// Build scripts inject __GX_REACT_SDK_VERSION__ for published artifacts.\n// Source-linked workspace usage may not inject defines, so keep a safe fallback.\nexport const REACT_SDK_VERSION =\n\treactSdkVersion.length > 0 ? reactSdkVersion : \"0.0.0-local\";\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "40692E37516B248764756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "0480976B43E9968064756E2164756E21",
10
10
  "names": []
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getuserfeedback/react",
3
- "version": "0.6.2",
3
+ "version": "0.6.10",
4
4
  "description": "getuserfeedback React SDK",
5
5
  "keywords": [
6
6
  "getuserfeedback",
@@ -41,7 +41,7 @@
41
41
  "lint": "biome check ."
42
42
  },
43
43
  "dependencies": {
44
- "@getuserfeedback/sdk": "^0.9.1"
44
+ "@getuserfeedback/sdk": "^0.9.8"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": ">=18.0.0"