@getuserfeedback/react 0.7.51 → 0.8.0
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/chunk-rh952c0b.js +6 -0
- package/dist/chunk-rh952c0b.js.map +10 -0
- package/dist/index.d.ts +32 -29
- package/dist/index.js +2 -2
- package/dist/index.js.map +2 -2
- package/dist/internal/inline-flow.d.ts +3 -3
- package/dist/internal/inline-flow.js +2 -2
- package/dist/internal/inline-flow.js.map +3 -3
- package/package.json +2 -2
- package/dist/chunk-qnr7k8dw.js +0 -6
- package/dist/chunk-qnr7k8dw.js.map +0 -10
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import{createClient as k}from"@getuserfeedback/sdk";import{createContext as P,useCallback as u,useContext as C,useEffect as y,useMemo as g,useRef as p,useState as R,useSyncExternalStore as L}from"react";import{jsx as B}from"react/jsx-runtime";var O={isOpen:!1,isLoading:!1,shouldRenderContainer:!1,width:void 0,height:void 0},x=(e)=>({isOpen:e.isOpen,isLoading:e.isLoading,width:e.width,height:e.height}),E=(e,n)=>e.isOpen===n.isOpen&&e.isLoading===n.isLoading&&e.width===n.width&&e.height===n.height,T={isOpen:!1,isLoading:!1,width:void 0,height:void 0},D=(e)=>typeof e.width==="number"&&typeof e.height==="number";function M(e){let n=p(e.getFlowState());return u(()=>{let o=e.getFlowState(),a=n.current;if(E(a,o))return a;return n.current=o,o},[e])}function U(e,n,o){let a=M(e),t=p(null),s=p(null),i=u(()=>{let l=a();if(t.current===l){let c=s.current;if(c!==null)return c}let r=n(l);return t.current=l,s.current=r,r},[a,n]);return L((l)=>e.subscribeFlowState(()=>{l()},{emitInitial:!1}),i,o)}var m=P(null),h=new WeakMap,I=(e,n)=>e<n?-1:e>n?1:0,S=(e)=>{if(e!==void 0&&!Array.isArray(e))return null;let n=[],o=new Set,a=!1;for(let t of e??[]){if(typeof t!=="object"||t===null)return null;let s=Reflect.get(t,"kind");if(s==="open-url"){if(a||typeof Reflect.get(t,"handler")!=="function")return null;a=!0,n.push("open-url");continue}if(s!=="custom")return null;let i=Reflect.get(t,"key"),l=Reflect.get(t,"version");if(typeof i!=="string"||i.trim().length===0||!Number.isSafeInteger(l)||l<=0||typeof Reflect.get(t,"handler")!=="function")return null;let r=`custom:${JSON.stringify([i.trim(),l])}`;if(o.has(r))return null;o.add(r),n.push(r)}return JSON.stringify(n.sort(I))};function K({children:e,clientOptions:n}){let o=p(S(n.actions)),a=S(n.actions);if(a!==null&&o.current!==null&&a!==o.current)throw Error("GetUserFeedbackProvider clientOptions.actions definitions cannot change after mount. Keep each custom key and version fixed for the provider lifetime; handler functions may change.");let t=k(n),s=p(null),i=U(t,x,()=>O),l=u((d,f)=>{if(s.current!==d||h.get(t)!==d)return;t.setDefaultContainerPolicy({kind:"hostContainer",host:f,sharing:"perFlowRun"})},[t]),r=u((d,f)=>{let b=h.get(t);if(b!==void 0&&b!==d)throw Error("Only one useFlowContainer consumer can be mounted for a getuserfeedback client");return h.set(t,d),s.current=d,t.setDefaultContainerPolicy({kind:"hostContainer",host:f,sharing:"perFlowRun"}),()=>{if(s.current!==d||h.get(t)!==d)return;s.current=null,h.delete(t),t.setDefaultContainerPolicy({kind:"floating"})}},[t]),c=g(()=>{if(!i.isOpen&&!i.isLoading)return O;return{isOpen:i.isOpen,isLoading:i.isLoading,shouldRenderContainer:!0,width:i.width,height:i.height}},[i]),F=g(()=>({client:t,apiKey:n.apiKey,setDefaultFlowContainer:l,registerDefaultFlowContainerConsumer:r,defaultFlowContainerState:c}),[t,n.apiKey,c,r,l]);return B(m.Provider,{value:F,children:e})}var G=(e)=>{let{flowRun:n,openFlow:o,prerenderFlow:a,prefetchOnMount:t=!1,hideCloseButton:s}=e,i=e.mode==="container",l=p(null),r=U(n,(w)=>w,()=>T),c=u((w)=>o({container:i?l.current??null:void 0,hideCloseButton:s,metadata:w?.metadata}),[s,o,i]),F=u(()=>n.close(),[n]),d=u((w)=>w?c():F(),[F,c]),f=u((w)=>{if(!i)return;l.current=w,n.setContainer(w)},[n,i]),b=D(r),v=i&&(r.isOpen||r.isLoading&&b);return y(()=>{if(!t)return;n.prefetch()},[n,t]),{isOpen:r.isOpen,isLoading:r.isLoading,width:r.width,height:r.height,shouldRenderContainer:v,setOpen:d,open:c,close:F,prerender:()=>a({container:i?l.current??null:void 0,hideCloseButton:s}),containerRef:f}};function H(e){let n=e.container??"default";if(p(n).current!==n)throw Error("useFlow container mode cannot change while mounted; remount the hook to change it");let a=n==="custom"?"container":"default",t=G({flowRun:e.flowRun,mode:a,openFlow:e.openFlow,prerenderFlow:e.prerenderFlow,prefetchOnMount:e.prefetchOnMount,hideCloseButton:e.hideCloseButton});if(a==="container")return{container:"custom",isOpen:t.isOpen,isLoading:t.isLoading,width:t.width,height:t.height,shouldRenderContainer:t.shouldRenderContainer,open:t.open,setOpen:t.setOpen,prerender:t.prerender,containerRef:t.containerRef};return{container:"default",isOpen:t.isOpen,isLoading:t.isLoading,width:t.width,height:t.height,open:t.open,close:t.close,prerender:t.prerender}}function N(e){let n=C(m);if(!n)throw Error("useFlow must be used within a GetUserFeedbackProvider");let o=g(()=>n.client.flow(e.flowId),[n.client,e.flowId]),a=u(({container:s,hideCloseButton:i,metadata:l})=>o.open(s===void 0?{hideCloseButton:i,metadata:l}:{container:s,hideCloseButton:i,metadata:l}),[o]),t=u(({hideCloseButton:s})=>o.prerender({hideCloseButton:s}),[o]);return H({flowRun:o,openFlow:a,prerenderFlow:t,container:e.container,prefetchOnMount:e.prefetchOnMount,hideCloseButton:e.hideCloseButton})}function V(){let e=C(m);if(!e)throw Error("useFlowContainer must be used within a GetUserFeedbackProvider");let{client:n,defaultFlowContainerState:o,registerDefaultFlowContainerConsumer:a,setDefaultFlowContainer:t}=e,s=p({}),i=p(null);y(()=>a(s.current,i.current),[a]);let l=u((c)=>{i.current=c,t(s.current,c)},[t]),r=u(()=>n.close(),[n]);return{isOpen:o.isOpen,isLoading:o.isLoading,shouldRenderContainer:o.shouldRenderContainer,width:o.width,height:o.height,close:r,containerRef:l}}function _(){let e=C(m);if(!e)throw Error("useFeedback must be used within a GetUserFeedbackProvider");let[n,o]=R(0),[a,t]=R(0),s=u(async(l)=>{o((r)=>r+1);try{return await e.client.feedback.fetch(l)}finally{o((r)=>r-1)}},[e.client]),i=u(async(l)=>{t((r)=>r+1);try{return await e.client.feedback.submit(l)}finally{t((r)=>r-1)}},[e.client]);return{fetch:s,isFetching:n>0,isSubmitting:a>0,submit:i}}function W(){let e=C(m);if(!e)throw Error("useGetUserFeedback must be used within a GetUserFeedbackProvider");return e.client}
|
|
3
|
+
export{m as a,K as b,H as c,N as d,V as e,_ as f,W as g};
|
|
4
|
+
|
|
5
|
+
//# debugId=2A3BAF05E5F53B9164756E2164756E21
|
|
6
|
+
//# sourceMappingURL=chunk-rh952c0b.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client.tsx"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"\"use client\";\n\nimport {\n\ttype Client,\n\ttype ClientOptions,\n\tcreateClient,\n\ttype FeedbackInput,\n\ttype FetchFeedbackInput,\n\ttype FetchFeedbackResult,\n\ttype FlowRun,\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\"`. Remount the hook to change this mode.\n\t */\n\tcontainer?: \"default\" | \"custom\";\n\t/** When true, the view does not show a close button. */\n\thideCloseButton?: boolean;\n}\n\ntype UseFlowPresentationOptions = Pick<\n\tUseFlowOptions,\n\t\"container\" | \"hideCloseButton\" | \"prefetchOnMount\"\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 UseCustomFlowReturn {\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 useFlowContainer(): container ref and aggregate flow state\n * for flows using the default presentation in the same logical client\n * (including targeting-engine opens). Mount exactly one consumer per logical\n * client.\n */\nexport interface UseFlowContainerReturn {\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 provider-wide 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 all open flows owned by this logical client. */\n\tclose: () => Promise<void>;\n\t/** Ref callback for the provider-wide 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: (owner: object, element: HTMLElement | null) => void;\n\tregisterDefaultFlowContainerConsumer: (\n\t\towner: object,\n\t\telement: HTMLElement | null,\n\t) => () => void;\n\tdefaultFlowContainerState: DefaultFlowContainerState;\n};\n\nexport const GetUserFeedbackContext =\n\tcreateContext<GetUserFeedbackContextValue | null>(null);\n\nconst flowContainerOwnerByClient = new WeakMap<Client, object>();\n\nexport interface GetUserFeedbackProviderProps {\n\t/** Application subtree that can use getuserfeedback hooks. */\n\tchildren: ReactNode;\n\t/**\n\t * Core SDK client options used to create/reuse the underlying client.\n\t * Action definitions must remain fixed for the provider's mounted\n\t * lifetime; handlers may change while their custom key and version stay\n\t * the same.\n\t */\n\tclientOptions: ClientOptions;\n}\n\nconst compareText = (left: string, right: string): number =>\n\tleft < right ? -1 : left > right ? 1 : 0;\n\nconst toActionDefinitionsKey = (\n\tactions: ClientOptions[\"actions\"],\n): string | null => {\n\tif (actions !== undefined && !Array.isArray(actions)) {\n\t\treturn null;\n\t}\n\tconst identities: string[] = [];\n\tconst customIdentities = new Set<string>();\n\tlet hasOpenUrl = false;\n\tfor (const registration of actions ?? []) {\n\t\tif (typeof registration !== \"object\" || registration === null) {\n\t\t\treturn null;\n\t\t}\n\t\tconst kind = Reflect.get(registration, \"kind\");\n\t\tif (kind === \"open-url\") {\n\t\t\tif (\n\t\t\t\thasOpenUrl ||\n\t\t\t\ttypeof Reflect.get(registration, \"handler\") !== \"function\"\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\thasOpenUrl = true;\n\t\t\tidentities.push(\"open-url\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== \"custom\") {\n\t\t\treturn null;\n\t\t}\n\t\tconst key = Reflect.get(registration, \"key\");\n\t\tconst version = Reflect.get(registration, \"version\");\n\t\tif (\n\t\t\ttypeof key !== \"string\" ||\n\t\t\tkey.trim().length === 0 ||\n\t\t\t!Number.isSafeInteger(version) ||\n\t\t\tversion <= 0 ||\n\t\t\ttypeof Reflect.get(registration, \"handler\") !== \"function\"\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t\tconst identity = `custom:${JSON.stringify([key.trim(), version])}`;\n\t\tif (customIdentities.has(identity)) return null;\n\t\tcustomIdentities.add(identity);\n\t\tidentities.push(identity);\n\t}\n\treturn JSON.stringify(identities.sort(compareText));\n};\n\n/**\n * Provider for getuserfeedback React hooks.\n * Wrap your app (or a subtree) so `useFeedback`, `useFlow`,\n * `useFlowContainer`, and `useGetUserFeedback` can access a client\n * created from `clientOptions`.\n *\n * If your app uses `useFlowContainer()`, flows using the default presentation\n * in this subtree (including targeting-engine opens) target that container.\n * If the container ref is not mounted yet, loader keeps flows parked until it is.\n * Mount exactly one `useFlowContainer()` consumer per logical client. Providers\n * with the same API key and targeting context reuse that client.\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 AppFlowContainer() {\n * const { close, containerRef, shouldRenderContainer, width, height } = useFlowContainer();\n *\n * return (\n * <Dialog open={shouldRenderContainer} onOpenChange={(open) => { if (!open) void close(); }}>\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 * <AppFlowContainer /> // Targeted flows display in your dialog.\n * </GetUserFeedbackProvider>\n * );\n * }\n * ```\n */\nexport function GetUserFeedbackProvider({\n\tchildren,\n\tclientOptions,\n}: GetUserFeedbackProviderProps): ReactElement {\n\tconst initialActionDefinitionsKeyRef = useRef(\n\t\ttoActionDefinitionsKey(clientOptions.actions),\n\t);\n\tconst actionDefinitionsKey = toActionDefinitionsKey(clientOptions.actions);\n\tif (\n\t\tactionDefinitionsKey !== null &&\n\t\tinitialActionDefinitionsKeyRef.current !== null &&\n\t\tactionDefinitionsKey !== initialActionDefinitionsKeyRef.current\n\t) {\n\t\tthrow new Error(\n\t\t\t\"GetUserFeedbackProvider clientOptions.actions definitions cannot change after mount. Keep each custom key and version fixed for the provider lifetime; handler functions may change.\",\n\t\t);\n\t}\n\tconst client = createClient(clientOptions);\n\tconst defaultFlowContainerOwnerRef = useRef<object | null>(null);\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(owner: object, element: HTMLElement | null) => {\n\t\t\tif (\n\t\t\t\tdefaultFlowContainerOwnerRef.current !== owner ||\n\t\t\t\tflowContainerOwnerByClient.get(client) !== owner\n\t\t\t) {\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\t(owner: object, element: HTMLElement | null) => {\n\t\t\tconst currentOwner = flowContainerOwnerByClient.get(client);\n\t\t\tif (currentOwner !== undefined && currentOwner !== owner) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Only one useFlowContainer consumer can be mounted for a getuserfeedback client\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tflowContainerOwnerByClient.set(client, owner);\n\t\t\tdefaultFlowContainerOwnerRef.current = owner;\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\n\t\t\treturn () => {\n\t\t\t\tif (\n\t\t\t\t\tdefaultFlowContainerOwnerRef.current !== owner ||\n\t\t\t\t\tflowContainerOwnerByClient.get(client) !== owner\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tdefaultFlowContainerOwnerRef.current = null;\n\t\t\t\tflowContainerOwnerByClient.delete(client);\n\t\t\t\tclient.setDefaultContainerPolicy({ kind: \"floating\" });\n\t\t\t};\n\t\t},\n\t\t[client],\n\t);\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 FlowControllerRun = Pick<\n\tFlowRun,\n\t\"setContainer\" | \"getFlowState\" | \"subscribeFlowState\" | \"prefetch\" | \"close\"\n>;\n\ntype FlowControllerOpenInput = {\n\tcontainer: HTMLDivElement | null | undefined;\n\tmetadata?: UseFlowOpenOptions[\"metadata\"];\n\thideCloseButton?: boolean;\n};\n\nexport type UseFlowControllerOptions = {\n\tflowRun: FlowControllerRun;\n\tmode: \"default\" | \"container\";\n\topenFlow: (input: FlowControllerOpenInput) => Promise<void>;\n\tprerenderFlow: (input: {\n\t\tcontainer: HTMLDivElement | null | undefined;\n\t\thideCloseButton?: boolean;\n\t}) => Promise<void>;\n\tprefetchOnMount?: boolean;\n\thideCloseButton?: boolean;\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\ntype UseFlowRunOptions = UseFlowPresentationOptions & {\n\tflowRun: FlowControllerRun;\n\topenFlow: UseFlowControllerOptions[\"openFlow\"];\n\tprerenderFlow: UseFlowControllerOptions[\"prerenderFlow\"];\n};\n\nconst useFlowController = (\n\toptions: UseFlowControllerOptions,\n): UseFlowControllerReturn => {\n\tconst {\n\t\tflowRun,\n\t\topenFlow,\n\t\tprerenderFlow,\n\t\tprefetchOnMount = false,\n\t\thideCloseButton,\n\t} = options;\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\topenFlow({\n\t\t\t\tcontainer: requiresContainer\n\t\t\t\t\t? (customContainerRef.current ?? null)\n\t\t\t\t\t: undefined,\n\t\t\t\thideCloseButton,\n\t\t\t\tmetadata: openOptions?.metadata,\n\t\t\t}),\n\t\t[hideCloseButton, openFlow, 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: (): Promise<void> =>\n\t\t\tprerenderFlow({\n\t\t\t\tcontainer: requiresContainer\n\t\t\t\t\t? (customContainerRef.current ?? null)\n\t\t\t\t\t: undefined,\n\t\t\t\thideCloseButton,\n\t\t\t}),\n\t\tcontainerRef,\n\t};\n};\n\nexport function useFlowRun(\n\toptions: UseFlowRunOptions & { container?: \"default\" },\n): UseFlowReturn;\nexport function useFlowRun(\n\toptions: UseFlowRunOptions & { container: \"custom\" },\n): UseCustomFlowReturn;\nexport function useFlowRun(\n\toptions: UseFlowRunOptions,\n): UseFlowReturn | UseCustomFlowReturn;\nexport function useFlowRun(\n\toptions: UseFlowRunOptions,\n): UseFlowReturn | UseCustomFlowReturn {\n\tconst container = options.container ?? \"default\";\n\tconst initialContainerRef = useRef(container);\n\tif (initialContainerRef.current !== container) {\n\t\tthrow new Error(\n\t\t\t\"useFlow container mode cannot change while mounted; remount the hook to change it\",\n\t\t);\n\t}\n\tconst mode = container === \"custom\" ? \"container\" : \"default\";\n\tconst controller = useFlowController({\n\t\tflowRun: options.flowRun,\n\t\tmode,\n\t\topenFlow: options.openFlow,\n\t\tprerenderFlow: options.prerenderFlow,\n\t\tprefetchOnMount: options.prefetchOnMount,\n\t\thideCloseButton: options.hideCloseButton,\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 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 * @see docs/custom-wrapper.md — integration levels 1 and 2, the default floating\n * container and the per-flow custom container, cited by path so the internal\n * set stays reachable. Level 3 is {@link useFlowContainer}.\n */\nexport function useFlow(\n\toptions: UseFlowOptions & { container?: \"default\" },\n): UseFlowReturn;\nexport function useFlow(\n\toptions: UseFlowOptions & { container: \"custom\" },\n): UseCustomFlowReturn;\nexport function useFlow(\n\toptions: UseFlowOptions,\n): UseFlowReturn | UseCustomFlowReturn {\n\tconst ctx = useContext(GetUserFeedbackContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"useFlow must be used within a GetUserFeedbackProvider\");\n\t}\n\tconst flowRun = useMemo(\n\t\t() => ctx.client.flow(options.flowId),\n\t\t[ctx.client, options.flowId],\n\t);\n\tconst openFlow = useCallback(\n\t\t({ container, hideCloseButton, metadata }: FlowControllerOpenInput) =>\n\t\t\tflowRun.open(\n\t\t\t\tcontainer === undefined\n\t\t\t\t\t? { hideCloseButton, metadata }\n\t\t\t\t\t: { container, hideCloseButton, metadata },\n\t\t\t),\n\t\t[flowRun],\n\t);\n\tconst prerenderFlow = useCallback(\n\t\t({ hideCloseButton }: { hideCloseButton?: boolean }) =>\n\t\t\tflowRun.prerender({ hideCloseButton }),\n\t\t[flowRun],\n\t);\n\treturn useFlowRun({\n\t\tflowRun,\n\t\topenFlow,\n\t\tprerenderFlow,\n\t\tcontainer: options.container,\n\t\tprefetchOnMount: options.prefetchOnMount,\n\t\thideCloseButton: options.hideCloseButton,\n\t});\n}\n\n/**\n * @name useFlowContainer\n * @description Register and control the single default container for this provider subtree. Mount exactly one consumer per logical client.\n * @example Display any flow in your own dialog\n * ```tsx\n * function AppFlowContainer() {\n * const { close, containerRef, shouldRenderContainer, width, height } = useFlowContainer();\n * return (\n * <Dialog open={shouldRenderContainer} onOpenChange={(open) => { if (!open) void close(); }}>\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 * <AppFlowContainer />\n * </GetUserFeedbackProvider>\n * );\n * }\n * ```\n * @see docs/specs/2026-08-28-sdk-flow-container-contract.md\n */\nexport function useFlowContainer(): UseFlowContainerReturn {\n\tconst ctx = useContext(GetUserFeedbackContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"useFlowContainer 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\tconst ownerRef = useRef<object>({});\n\tconst containerElementRef = useRef<HTMLDivElement | null>(null);\n\n\tuseEffect(\n\t\t() =>\n\t\t\tregisterDefaultFlowContainerConsumer(\n\t\t\t\townerRef.current,\n\t\t\t\tcontainerElementRef.current,\n\t\t\t),\n\t\t[registerDefaultFlowContainerConsumer],\n\t);\n\n\tconst containerRef = useCallback(\n\t\t(element: HTMLDivElement | null): void => {\n\t\t\tcontainerElementRef.current = element;\n\t\t\tsetDefaultFlowContainer(ownerRef.current, element);\n\t\t},\n\t\t[setDefaultFlowContainer],\n\t);\n\n\tconst close = useCallback((): Promise<void> => client.close(), [client]);\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\tclose,\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
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "2A3BAF05E5F53B9164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
|
-
import { ClientOptions, FetchFeedbackInput, FetchFeedbackResult, FeedbackInput, SubmitFeedbackResult,
|
|
2
|
+
import { ClientOptions, OpenFlowOptions, FetchFeedbackInput, FetchFeedbackResult, FeedbackInput, SubmitFeedbackResult, Client } from '@getuserfeedback/sdk';
|
|
3
3
|
|
|
4
4
|
/** Return value for useFeedback(). */
|
|
5
5
|
interface UseFeedbackReturn {
|
|
@@ -59,7 +59,7 @@ interface UseFlowReturn {
|
|
|
59
59
|
/**
|
|
60
60
|
* Return value for useFlow() when container is `"custom"`: state and callbacks for host-managed container flows.
|
|
61
61
|
*/
|
|
62
|
-
interface
|
|
62
|
+
interface UseCustomFlowReturn {
|
|
63
63
|
readonly container: "custom";
|
|
64
64
|
/** True when the flow is visible. */
|
|
65
65
|
isOpen: boolean;
|
|
@@ -81,23 +81,25 @@ interface UseFlowContainerReturn {
|
|
|
81
81
|
height?: number;
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
|
-
* Return value for
|
|
85
|
-
* for
|
|
84
|
+
* Return value for useFlowContainer(): container ref and aggregate flow state
|
|
85
|
+
* for flows using the default presentation in the same logical client
|
|
86
|
+
* (including targeting-engine opens). Mount exactly one consumer per logical
|
|
87
|
+
* client.
|
|
86
88
|
*/
|
|
87
|
-
interface
|
|
89
|
+
interface UseFlowContainerReturn {
|
|
88
90
|
/** True when any flow is visible. */
|
|
89
91
|
isOpen: boolean;
|
|
90
92
|
/** True after any flow open is requested while the flow is not visible yet. */
|
|
91
93
|
isLoading: boolean;
|
|
92
|
-
/** True when your host UI should render the
|
|
94
|
+
/** True when your host UI should render the provider-wide flow container. */
|
|
93
95
|
shouldRenderContainer: boolean;
|
|
94
96
|
/** Active flow width in pixels (when known). */
|
|
95
97
|
width?: number;
|
|
96
98
|
/** Active flow height in pixels (when known). */
|
|
97
99
|
height?: number;
|
|
98
|
-
/** Close
|
|
99
|
-
|
|
100
|
-
/** Ref callback for the
|
|
100
|
+
/** Close all open flows owned by this logical client. */
|
|
101
|
+
close: () => Promise<void>;
|
|
102
|
+
/** Ref callback for the provider-wide flow container element. */
|
|
101
103
|
containerRef: (element: HTMLDivElement | null) => void;
|
|
102
104
|
}
|
|
103
105
|
interface GetUserFeedbackProviderProps {
|
|
@@ -114,12 +116,14 @@ interface GetUserFeedbackProviderProps {
|
|
|
114
116
|
/**
|
|
115
117
|
* Provider for getuserfeedback React hooks.
|
|
116
118
|
* Wrap your app (or a subtree) so `useFeedback`, `useFlow`,
|
|
117
|
-
* `
|
|
119
|
+
* `useFlowContainer`, and `useGetUserFeedback` can access a client
|
|
118
120
|
* created from `clientOptions`.
|
|
119
121
|
*
|
|
120
|
-
* If your app uses `
|
|
121
|
-
* (including targeting-engine opens) target that container.
|
|
122
|
+
* If your app uses `useFlowContainer()`, flows using the default presentation
|
|
123
|
+
* in this subtree (including targeting-engine opens) target that container.
|
|
122
124
|
* If the container ref is not mounted yet, loader keeps flows parked until it is.
|
|
125
|
+
* Mount exactly one `useFlowContainer()` consumer per logical client. Providers
|
|
126
|
+
* with the same API key and targeting context reuse that client.
|
|
123
127
|
*
|
|
124
128
|
* @example Basic usage
|
|
125
129
|
* ```tsx
|
|
@@ -134,11 +138,11 @@ interface GetUserFeedbackProviderProps {
|
|
|
134
138
|
*
|
|
135
139
|
* @example Display *any* flow in your own dialog (a shadcn/ui dialog in this example):
|
|
136
140
|
* ```tsx
|
|
137
|
-
* function
|
|
138
|
-
* const { containerRef, shouldRenderContainer, width, height
|
|
141
|
+
* function AppFlowContainer() {
|
|
142
|
+
* const { close, containerRef, shouldRenderContainer, width, height } = useFlowContainer();
|
|
139
143
|
*
|
|
140
144
|
* return (
|
|
141
|
-
* <Dialog open={shouldRenderContainer} onOpenChange={
|
|
145
|
+
* <Dialog open={shouldRenderContainer} onOpenChange={(open) => { if (!open) void close(); }}>
|
|
142
146
|
* <DialogContent ref={containerRef} style={{ width, height }} />
|
|
143
147
|
* </Dialog>
|
|
144
148
|
* );
|
|
@@ -148,7 +152,7 @@ interface GetUserFeedbackProviderProps {
|
|
|
148
152
|
* return (
|
|
149
153
|
* <GetUserFeedbackProvider clientOptions={{ apiKey: "YOUR_API_KEY" }}>
|
|
150
154
|
* <AppRoutes />
|
|
151
|
-
* <
|
|
155
|
+
* <AppFlowContainer /> // Targeted flows display in your dialog.
|
|
152
156
|
* </GetUserFeedbackProvider>
|
|
153
157
|
* );
|
|
154
158
|
* }
|
|
@@ -175,23 +179,23 @@ declare function GetUserFeedbackProvider({ children, clientOptions, }: GetUserFe
|
|
|
175
179
|
* ```
|
|
176
180
|
* @see docs/custom-wrapper.md — integration levels 1 and 2, the default floating
|
|
177
181
|
* container and the per-flow custom container, cited by path so the internal
|
|
178
|
-
* set stays reachable. Level 3 is {@link
|
|
182
|
+
* set stays reachable. Level 3 is {@link useFlowContainer}.
|
|
179
183
|
*/
|
|
180
184
|
declare function useFlow(options: UseFlowOptions & {
|
|
181
185
|
container?: "default";
|
|
182
186
|
}): UseFlowReturn;
|
|
183
187
|
declare function useFlow(options: UseFlowOptions & {
|
|
184
188
|
container: "custom";
|
|
185
|
-
}):
|
|
189
|
+
}): UseCustomFlowReturn;
|
|
186
190
|
/**
|
|
187
|
-
* @name
|
|
188
|
-
* @description Register and control
|
|
191
|
+
* @name useFlowContainer
|
|
192
|
+
* @description Register and control the single default container for this provider subtree. Mount exactly one consumer per logical client.
|
|
189
193
|
* @example Display any flow in your own dialog
|
|
190
194
|
* ```tsx
|
|
191
|
-
* function
|
|
192
|
-
* const { containerRef, shouldRenderContainer, width, height
|
|
195
|
+
* function AppFlowContainer() {
|
|
196
|
+
* const { close, containerRef, shouldRenderContainer, width, height } = useFlowContainer();
|
|
193
197
|
* return (
|
|
194
|
-
* <Dialog open={shouldRenderContainer} onOpenChange={
|
|
198
|
+
* <Dialog open={shouldRenderContainer} onOpenChange={(open) => { if (!open) void close(); }}>
|
|
195
199
|
* <DialogContent ref={containerRef} style={{ width, height }} />
|
|
196
200
|
* </Dialog>
|
|
197
201
|
* );
|
|
@@ -201,15 +205,14 @@ declare function useFlow(options: UseFlowOptions & {
|
|
|
201
205
|
* return (
|
|
202
206
|
* <GetUserFeedbackProvider clientOptions={{ apiKey: "YOUR_API_KEY" }}>
|
|
203
207
|
* <AppRoutes />
|
|
204
|
-
* <
|
|
208
|
+
* <AppFlowContainer />
|
|
205
209
|
* </GetUserFeedbackProvider>
|
|
206
210
|
* );
|
|
207
211
|
* }
|
|
208
212
|
* ```
|
|
209
|
-
* @see docs/
|
|
210
|
-
* serving every flow in a provider subtree.
|
|
213
|
+
* @see docs/specs/2026-08-28-sdk-flow-container-contract.md
|
|
211
214
|
*/
|
|
212
|
-
declare function
|
|
215
|
+
declare function useFlowContainer(): UseFlowContainerReturn;
|
|
213
216
|
/**
|
|
214
217
|
* Submit feedback or explicitly fetch the JWT-authenticated user's feedback.
|
|
215
218
|
*
|
|
@@ -247,5 +250,5 @@ declare function useGetUserFeedback(): Client;
|
|
|
247
250
|
|
|
248
251
|
declare const REACT_SDK_VERSION: string;
|
|
249
252
|
|
|
250
|
-
export { GetUserFeedbackProvider, REACT_SDK_VERSION,
|
|
251
|
-
export type { GetUserFeedbackProviderProps,
|
|
253
|
+
export { GetUserFeedbackProvider, REACT_SDK_VERSION, useFeedback, useFlow, useFlowContainer, useGetUserFeedback };
|
|
254
|
+
export type { GetUserFeedbackProviderProps, UseCustomFlowReturn, UseFeedbackReturn, UseFlowContainerReturn, UseFlowOpenOptions, UseFlowOptions, UseFlowReturn };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{b as
|
|
2
|
+
import{b as t,d as r,e as _,f as s,g as n}from"./chunk-rh952c0b.js";var e="0.8.0".trim(),o=e.length>0?e:"0.0.0-local";export{t as GetUserFeedbackProvider,o as REACT_SDK_VERSION,s as useFeedback,r as useFlow,_ as useFlowContainer,n as useGetUserFeedback};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=B2B775F2A75B0F0864756E2164756E21
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"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"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";oEAEA,IAAM,EAEF,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";oEAEA,IAAM,EAEF,QAAyB,KAAK,EAKrB,EACZ,EAAgB,OAAS,EAAI,EAAkB",
|
|
8
|
+
"debugId": "B2B775F2A75B0F0864756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -33,7 +33,7 @@ interface UseFlowReturn {
|
|
|
33
33
|
/**
|
|
34
34
|
* Return value for useFlow() when container is `"custom"`: state and callbacks for host-managed container flows.
|
|
35
35
|
*/
|
|
36
|
-
interface
|
|
36
|
+
interface UseCustomFlowReturn {
|
|
37
37
|
readonly container: "custom";
|
|
38
38
|
/** True when the flow is visible. */
|
|
39
39
|
isOpen: boolean;
|
|
@@ -74,7 +74,7 @@ declare function useFlow(options: UseFlowOptions & {
|
|
|
74
74
|
}): UseFlowReturn;
|
|
75
75
|
declare function useFlow(options: UseFlowOptions & {
|
|
76
76
|
container: "custom";
|
|
77
|
-
}):
|
|
77
|
+
}): UseCustomFlowReturn;
|
|
78
78
|
|
|
79
79
|
export { useFlow };
|
|
80
|
-
export type {
|
|
80
|
+
export type { UseCustomFlowReturn, UseFlowOptions, UseFlowReturn };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{a as
|
|
2
|
+
import{a as s,c as i}from"../chunk-rh952c0b.js";import{createInlineFlow as F}from"@getuserfeedback/sdk/internal/inline-flow";import{useCallback as l,useContext as p,useRef as f,useState as a}from"react";function R(t){let n=p(s);if(!n)throw Error("useFlow must be used within a GetUserFeedbackProvider");if(f(n.client).current!==n.client)throw Error("useFlow must be remounted when the GetUserFeedbackProvider client changes");let[e]=a(()=>F(n.client,t.flow)),u=l(({container:o,hideCloseButton:r,metadata:c})=>{if(o!==void 0)e.setContainer(o);return e.open({hideCloseButton:r,metadata:c})},[e]),w=l(({container:o,hideCloseButton:r})=>{if(o!==void 0)e.setContainer(o);return e.prerender({hideCloseButton:r})},[e]);return i({flowRun:e,openFlow:u,prerenderFlow:w,container:t.container,prefetchOnMount:t.prefetchOnMount,hideCloseButton:t.hideCloseButton})}export{R as useFlow};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=49A3C1D11CF83FD564756E2164756E21
|
|
5
5
|
//# sourceMappingURL=inline-flow.js.map
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/internal/inline-flow.tsx"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"\"use client\";\n\nimport {\n\tcreateInlineFlow,\n\ttype InlineFlow,\n} from \"@getuserfeedback/sdk/internal/inline-flow\";\nimport { useCallback, useContext, useRef, useState } from \"react\";\nimport {\n\tGetUserFeedbackContext,\n\ttype
|
|
5
|
+
"\"use client\";\n\nimport {\n\tcreateInlineFlow,\n\ttype InlineFlow,\n} from \"@getuserfeedback/sdk/internal/inline-flow\";\nimport { useCallback, useContext, useRef, useState } from \"react\";\nimport {\n\tGetUserFeedbackContext,\n\ttype UseCustomFlowReturn,\n\ttype UseFlowControllerOptions,\n\ttype UseFlowReturn,\n\tuseFlowRun,\n} from \"../client\";\n\n/**\n * Internal supplied-flow options; intentionally absent from the public root.\n * The hook captures one provider client and immutable definition snapshot for\n * its mounted lifetime; remount the consumer to change either one.\n *\n * @see docs/specs/2026-08-02-flow-interaction-model.md\n */\nexport interface UseFlowOptions {\n\tflow: InlineFlow;\n\tprefetchOnMount?: boolean;\n\t/** Remount the hook to change container mode. */\n\tcontainer?: \"default\" | \"custom\";\n\thideCloseButton?: boolean;\n}\n\nexport function useFlow(\n\toptions: UseFlowOptions & { container?: \"default\" },\n): UseFlowReturn;\nexport function useFlow(\n\toptions: UseFlowOptions & { container: \"custom\" },\n): UseCustomFlowReturn;\nexport function useFlow(\n\toptions: UseFlowOptions,\n): UseFlowReturn | UseCustomFlowReturn {\n\tconst context = useContext(GetUserFeedbackContext);\n\tif (!context) {\n\t\tthrow new Error(\"useFlow must be used within a GetUserFeedbackProvider\");\n\t}\n\tconst initialClientRef = useRef(context.client);\n\tif (initialClientRef.current !== context.client) {\n\t\tthrow new Error(\n\t\t\t\"useFlow must be remounted when the GetUserFeedbackProvider client changes\",\n\t\t);\n\t}\n\tconst [flowRun] = useState(() =>\n\t\tcreateInlineFlow(context.client, options.flow),\n\t);\n\tconst openFlow = useCallback<UseFlowControllerOptions[\"openFlow\"]>(\n\t\t({ container, hideCloseButton, metadata }) => {\n\t\t\tif (container !== undefined) {\n\t\t\t\tflowRun.setContainer(container);\n\t\t\t}\n\t\t\treturn flowRun.open({ hideCloseButton, metadata });\n\t\t},\n\t\t[flowRun],\n\t);\n\tconst prerenderFlow = useCallback<UseFlowControllerOptions[\"prerenderFlow\"]>(\n\t\t({ container, hideCloseButton }) => {\n\t\t\tif (container !== undefined) {\n\t\t\t\tflowRun.setContainer(container);\n\t\t\t}\n\t\t\treturn flowRun.prerender({ hideCloseButton });\n\t\t},\n\t\t[flowRun],\n\t);\n\treturn useFlowRun({\n\t\tflowRun,\n\t\topenFlow,\n\t\tprerenderFlow,\n\t\tcontainer: options.container,\n\t\tprefetchOnMount: options.prefetchOnMount,\n\t\thideCloseButton: options.hideCloseButton,\n\t});\n}\n\nexport type { InlineFlow } from \"@getuserfeedback/sdk/internal/inline-flow\";\nexport type { UseCustomFlowReturn, UseFlowReturn } from \"../client\";\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";gDAEA,2BACC,kDAGD,sBAAS,gBAAa,YAAY,cAAQ,cA8BnC,SAAS,CAAO,CACtB,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";gDAEA,2BACC,kDAGD,sBAAS,gBAAa,YAAY,cAAQ,cA8BnC,SAAS,CAAO,CACtB,EACsC,CACtC,IAAM,EAAU,EAAW,CAAsB,EACjD,GAAI,CAAC,EACJ,MAAU,MAAM,uDAAuD,EAGxE,GADyB,EAAO,EAAQ,MAAM,EACzB,UAAY,EAAQ,OACxC,MAAU,MACT,2EACD,EAED,IAAO,GAAW,EAAS,IAC1B,EAAiB,EAAQ,OAAQ,EAAQ,IAAI,CAC9C,EACM,EAAW,EAChB,EAAG,YAAW,kBAAiB,cAAe,CAC7C,GAAI,IAAc,OACjB,EAAQ,aAAa,CAAS,EAE/B,OAAO,EAAQ,KAAK,CAAE,kBAAiB,UAAS,CAAC,GAElD,CAAC,CAAO,CACT,EACM,EAAgB,EACrB,EAAG,YAAW,qBAAsB,CACnC,GAAI,IAAc,OACjB,EAAQ,aAAa,CAAS,EAE/B,OAAO,EAAQ,UAAU,CAAE,iBAAgB,CAAC,GAE7C,CAAC,CAAO,CACT,EACA,OAAO,EAAW,CACjB,UACA,WACA,gBACA,UAAW,EAAQ,UACnB,gBAAiB,EAAQ,gBACzB,gBAAiB,EAAQ,eAC1B,CAAC",
|
|
8
|
+
"debugId": "49A3C1D11CF83FD564756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getuserfeedback/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "getuserfeedback React SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"getuserfeedback",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"lint": "biome check ."
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@getuserfeedback/sdk": "^0.
|
|
48
|
+
"@getuserfeedback/sdk": "^0.15.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"react": ">=18.0.0"
|
package/dist/chunk-qnr7k8dw.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import{createClient as v}from"@getuserfeedback/sdk";import{createContext as P,useCallback as u,useContext as h,useEffect as O,useMemo as b,useRef as p,useState as C,useSyncExternalStore as k}from"react";import{jsx as B}from"react/jsx-runtime";var g={isOpen:!1,isLoading:!1,shouldRenderContainer:!1,width:void 0,height:void 0},L=(e)=>({isOpen:e.isOpen,isLoading:e.isLoading,width:e.width,height:e.height}),x=(e,n)=>e.isOpen===n.isOpen&&e.isLoading===n.isLoading&&e.width===n.width&&e.height===n.height,D={isOpen:!1,isLoading:!1,width:void 0,height:void 0},E=(e)=>typeof e.width==="number"&&typeof e.height==="number";function T(e){let n=p(e.getFlowState());return u(()=>{let o=e.getFlowState(),l=n.current;if(x(l,o))return l;return n.current=o,o},[e])}function S(e,n,o){let l=T(e),t=p(null),a=p(null),s=u(()=>{let i=l();if(t.current===i){let c=a.current;if(c!==null)return c}let r=n(i);return t.current=i,a.current=r,r},[l,n]);return k((i)=>e.subscribeFlowState(()=>{i()},{emitInitial:!1}),s,o)}var F=P(null),I=(e,n)=>e<n?-1:e>n?1:0,R=(e)=>{if(e!==void 0&&!Array.isArray(e))return null;let n=[],o=new Set,l=!1;for(let t of e??[]){if(typeof t!=="object"||t===null)return null;let a=Reflect.get(t,"kind");if(a==="open-url"){if(l||typeof Reflect.get(t,"handler")!=="function")return null;l=!0,n.push("open-url");continue}if(a!=="custom")return null;let s=Reflect.get(t,"key"),i=Reflect.get(t,"version");if(typeof s!=="string"||s.trim().length===0||!Number.isSafeInteger(i)||i<=0||typeof Reflect.get(t,"handler")!=="function")return null;let r=`custom:${JSON.stringify([s.trim(),i])}`;if(o.has(r))return null;o.add(r),n.push(r)}return JSON.stringify(n.sort(I))};function K({children:e,clientOptions:n}){let o=p(R(n.actions)),l=R(n.actions);if(l!==null&&o.current!==null&&l!==o.current)throw Error("GetUserFeedbackProvider clientOptions.actions definitions cannot change after mount. Keep each custom key and version fixed for the provider lifetime; handler functions may change.");let t=v(n),a=p(null),s=p(0),i=S(t,L,()=>g),r=u((f)=>{if(a.current=f,s.current===0)return;t.setDefaultContainerPolicy({kind:"hostContainer",host:f,sharing:"perFlowRun"})},[t]),c=u(()=>{if(s.current+=1,s.current===1)t.setDefaultContainerPolicy({kind:"hostContainer",host:a.current,sharing:"perFlowRun"});return()=>{if(s.current=Math.max(0,s.current-1),s.current===0)t.setDefaultContainerPolicy({kind:"floating"})}},[t]),w=b(()=>{if(!i.isOpen&&!i.isLoading)return g;return{isOpen:i.isOpen,isLoading:i.isLoading,shouldRenderContainer:!0,width:i.width,height:i.height}},[i]),m=b(()=>({client:t,apiKey:n.apiKey,setDefaultFlowContainer:r,registerDefaultFlowContainerConsumer:c,defaultFlowContainerState:w}),[t,n.apiKey,w,c,r]);return B(F.Provider,{value:m,children:e})}var M=(e)=>{let{flowRun:n,openFlow:o,prerenderFlow:l,prefetchOnMount:t=!1,hideCloseButton:a}=e,s=e.mode==="container",i=p(null),r=S(n,(d)=>d,()=>D),c=u((d)=>o({container:s?i.current??null:void 0,hideCloseButton:a,metadata:d?.metadata}),[a,o,s]),w=u(()=>n.close(),[n]),m=u((d)=>d?c():w(),[w,c]),f=u((d)=>{if(!s)return;i.current=d,n.setContainer(d)},[n,s]),U=E(r),y=s&&(r.isOpen||r.isLoading&&U);return O(()=>{if(!t)return;n.prefetch()},[n,t]),{isOpen:r.isOpen,isLoading:r.isLoading,width:r.width,height:r.height,shouldRenderContainer:y,setOpen:m,open:c,close:w,prerender:()=>l({container:s?i.current??null:void 0,hideCloseButton:a}),containerRef:f}};function G(e){let n=e.container??"default";if(p(n).current!==n)throw Error("useFlow container mode cannot change while mounted; remount the hook to change it");let l=n==="custom"?"container":"default",t=M({flowRun:e.flowRun,mode:l,openFlow:e.openFlow,prerenderFlow:e.prerenderFlow,prefetchOnMount:e.prefetchOnMount,hideCloseButton:e.hideCloseButton});if(l==="container")return{container:"custom",isOpen:t.isOpen,isLoading:t.isLoading,width:t.width,height:t.height,shouldRenderContainer:t.shouldRenderContainer,open:t.open,setOpen:t.setOpen,prerender:t.prerender,containerRef:t.containerRef};return{container:"default",isOpen:t.isOpen,isLoading:t.isLoading,width:t.width,height:t.height,open:t.open,close:t.close,prerender:t.prerender}}function N(e){let n=h(F);if(!n)throw Error("useFlow must be used within a GetUserFeedbackProvider");let o=b(()=>n.client.flow(e.flowId),[n.client,e.flowId]),l=u(({container:a,hideCloseButton:s,metadata:i})=>o.open(a===void 0?{hideCloseButton:s,metadata:i}:{container:a,hideCloseButton:s,metadata:i}),[o]),t=u(({hideCloseButton:a})=>o.prerender({hideCloseButton:a}),[o]);return G({flowRun:o,openFlow:l,prerenderFlow:t,container:e.container,prefetchOnMount:e.prefetchOnMount,hideCloseButton:e.hideCloseButton})}function V(){let e=h(F);if(!e)throw Error("useDefaultFlowContainer must be used within a GetUserFeedbackProvider");let{client:n,defaultFlowContainerState:o,registerDefaultFlowContainerConsumer:l,setDefaultFlowContainer:t}=e;O(()=>l(),[l]);let a=u((r)=>{t(r)},[t]),s=u(()=>n.close(),[n]),i=u((r)=>{if(r)return Promise.resolve();return s()},[s]);return{isOpen:o.isOpen,isLoading:o.isLoading,shouldRenderContainer:o.shouldRenderContainer,width:o.width,height:o.height,setOpen:i,containerRef:a}}function _(){let e=h(F);if(!e)throw Error("useFeedback must be used within a GetUserFeedbackProvider");let[n,o]=C(0),[l,t]=C(0),a=u(async(i)=>{o((r)=>r+1);try{return await e.client.feedback.fetch(i)}finally{o((r)=>r-1)}},[e.client]),s=u(async(i)=>{t((r)=>r+1);try{return await e.client.feedback.submit(i)}finally{t((r)=>r-1)}},[e.client]);return{fetch:a,isFetching:n>0,isSubmitting:l>0,submit:s}}function j(){let e=h(F);if(!e)throw Error("useGetUserFeedback must be used within a GetUserFeedbackProvider");return e.client}
|
|
3
|
-
export{F as a,K as b,G as c,N as d,V as e,_ as f,j as g};
|
|
4
|
-
|
|
5
|
-
//# debugId=12E088381A2D1EB364756E2164756E21
|
|
6
|
-
//# sourceMappingURL=chunk-qnr7k8dw.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/client.tsx"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"\"use client\";\n\nimport {\n\ttype Client,\n\ttype ClientOptions,\n\tcreateClient,\n\ttype FeedbackInput,\n\ttype FetchFeedbackInput,\n\ttype FetchFeedbackResult,\n\ttype FlowRun,\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\"`. Remount the hook to change this mode.\n\t */\n\tcontainer?: \"default\" | \"custom\";\n\t/** When true, the view does not show a close button. */\n\thideCloseButton?: boolean;\n}\n\ntype UseFlowPresentationOptions = Pick<\n\tUseFlowOptions,\n\t\"container\" | \"hideCloseButton\" | \"prefetchOnMount\"\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\nexport const GetUserFeedbackContext =\n\tcreateContext<GetUserFeedbackContextValue | null>(null);\n\nexport interface GetUserFeedbackProviderProps {\n\t/** Application subtree that can use getuserfeedback hooks. */\n\tchildren: ReactNode;\n\t/**\n\t * Core SDK client options used to create/reuse the underlying client.\n\t * Action definitions must remain fixed for the provider's mounted\n\t * lifetime; handlers may change while their custom key and version stay\n\t * the same.\n\t */\n\tclientOptions: ClientOptions;\n}\n\nconst compareText = (left: string, right: string): number =>\n\tleft < right ? -1 : left > right ? 1 : 0;\n\nconst toActionDefinitionsKey = (\n\tactions: ClientOptions[\"actions\"],\n): string | null => {\n\tif (actions !== undefined && !Array.isArray(actions)) {\n\t\treturn null;\n\t}\n\tconst identities: string[] = [];\n\tconst customIdentities = new Set<string>();\n\tlet hasOpenUrl = false;\n\tfor (const registration of actions ?? []) {\n\t\tif (typeof registration !== \"object\" || registration === null) {\n\t\t\treturn null;\n\t\t}\n\t\tconst kind = Reflect.get(registration, \"kind\");\n\t\tif (kind === \"open-url\") {\n\t\t\tif (\n\t\t\t\thasOpenUrl ||\n\t\t\t\ttypeof Reflect.get(registration, \"handler\") !== \"function\"\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\thasOpenUrl = true;\n\t\t\tidentities.push(\"open-url\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== \"custom\") {\n\t\t\treturn null;\n\t\t}\n\t\tconst key = Reflect.get(registration, \"key\");\n\t\tconst version = Reflect.get(registration, \"version\");\n\t\tif (\n\t\t\ttypeof key !== \"string\" ||\n\t\t\tkey.trim().length === 0 ||\n\t\t\t!Number.isSafeInteger(version) ||\n\t\t\tversion <= 0 ||\n\t\t\ttypeof Reflect.get(registration, \"handler\") !== \"function\"\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t\tconst identity = `custom:${JSON.stringify([key.trim(), version])}`;\n\t\tif (customIdentities.has(identity)) return null;\n\t\tcustomIdentities.add(identity);\n\t\tidentities.push(identity);\n\t}\n\treturn JSON.stringify(identities.sort(compareText));\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 initialActionDefinitionsKeyRef = useRef(\n\t\ttoActionDefinitionsKey(clientOptions.actions),\n\t);\n\tconst actionDefinitionsKey = toActionDefinitionsKey(clientOptions.actions);\n\tif (\n\t\tactionDefinitionsKey !== null &&\n\t\tinitialActionDefinitionsKeyRef.current !== null &&\n\t\tactionDefinitionsKey !== initialActionDefinitionsKeyRef.current\n\t) {\n\t\tthrow new Error(\n\t\t\t\"GetUserFeedbackProvider clientOptions.actions definitions cannot change after mount. Keep each custom key and version fixed for the provider lifetime; handler functions may change.\",\n\t\t);\n\t}\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 FlowControllerRun = Pick<\n\tFlowRun,\n\t\"setContainer\" | \"getFlowState\" | \"subscribeFlowState\" | \"prefetch\" | \"close\"\n>;\n\ntype FlowControllerOpenInput = {\n\tcontainer: HTMLDivElement | null | undefined;\n\tmetadata?: UseFlowOpenOptions[\"metadata\"];\n\thideCloseButton?: boolean;\n};\n\nexport type UseFlowControllerOptions = {\n\tflowRun: FlowControllerRun;\n\tmode: \"default\" | \"container\";\n\topenFlow: (input: FlowControllerOpenInput) => Promise<void>;\n\tprerenderFlow: (input: {\n\t\tcontainer: HTMLDivElement | null | undefined;\n\t\thideCloseButton?: boolean;\n\t}) => Promise<void>;\n\tprefetchOnMount?: boolean;\n\thideCloseButton?: boolean;\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\ntype UseFlowRunOptions = UseFlowPresentationOptions & {\n\tflowRun: FlowControllerRun;\n\topenFlow: UseFlowControllerOptions[\"openFlow\"];\n\tprerenderFlow: UseFlowControllerOptions[\"prerenderFlow\"];\n};\n\nconst useFlowController = (\n\toptions: UseFlowControllerOptions,\n): UseFlowControllerReturn => {\n\tconst {\n\t\tflowRun,\n\t\topenFlow,\n\t\tprerenderFlow,\n\t\tprefetchOnMount = false,\n\t\thideCloseButton,\n\t} = options;\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\topenFlow({\n\t\t\t\tcontainer: requiresContainer\n\t\t\t\t\t? (customContainerRef.current ?? null)\n\t\t\t\t\t: undefined,\n\t\t\t\thideCloseButton,\n\t\t\t\tmetadata: openOptions?.metadata,\n\t\t\t}),\n\t\t[hideCloseButton, openFlow, 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: (): Promise<void> =>\n\t\t\tprerenderFlow({\n\t\t\t\tcontainer: requiresContainer\n\t\t\t\t\t? (customContainerRef.current ?? null)\n\t\t\t\t\t: undefined,\n\t\t\t\thideCloseButton,\n\t\t\t}),\n\t\tcontainerRef,\n\t};\n};\n\nexport function useFlowRun(\n\toptions: UseFlowRunOptions & { container?: \"default\" },\n): UseFlowReturn;\nexport function useFlowRun(\n\toptions: UseFlowRunOptions & { container: \"custom\" },\n): UseFlowContainerReturn;\nexport function useFlowRun(\n\toptions: UseFlowRunOptions,\n): UseFlowReturn | UseFlowContainerReturn;\nexport function useFlowRun(\n\toptions: UseFlowRunOptions,\n): UseFlowReturn | UseFlowContainerReturn {\n\tconst container = options.container ?? \"default\";\n\tconst initialContainerRef = useRef(container);\n\tif (initialContainerRef.current !== container) {\n\t\tthrow new Error(\n\t\t\t\"useFlow container mode cannot change while mounted; remount the hook to change it\",\n\t\t);\n\t}\n\tconst mode = container === \"custom\" ? \"container\" : \"default\";\n\tconst controller = useFlowController({\n\t\tflowRun: options.flowRun,\n\t\tmode,\n\t\topenFlow: options.openFlow,\n\t\tprerenderFlow: options.prerenderFlow,\n\t\tprefetchOnMount: options.prefetchOnMount,\n\t\thideCloseButton: options.hideCloseButton,\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 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 * @see docs/custom-wrapper.md — integration levels 1 and 2, the default floating\n * container and the per-flow custom container, cited by path so the internal\n * set stays reachable. Level 3 is {@link useDefaultFlowContainer}.\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 ctx = useContext(GetUserFeedbackContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"useFlow must be used within a GetUserFeedbackProvider\");\n\t}\n\tconst flowRun = useMemo(\n\t\t() => ctx.client.flow(options.flowId),\n\t\t[ctx.client, options.flowId],\n\t);\n\tconst openFlow = useCallback(\n\t\t({ container, hideCloseButton, metadata }: FlowControllerOpenInput) =>\n\t\t\tflowRun.open(\n\t\t\t\tcontainer === undefined\n\t\t\t\t\t? { hideCloseButton, metadata }\n\t\t\t\t\t: { container, hideCloseButton, metadata },\n\t\t\t),\n\t\t[flowRun],\n\t);\n\tconst prerenderFlow = useCallback(\n\t\t({ hideCloseButton }: { hideCloseButton?: boolean }) =>\n\t\t\tflowRun.prerender({ hideCloseButton }),\n\t\t[flowRun],\n\t);\n\treturn useFlowRun({\n\t\tflowRun,\n\t\topenFlow,\n\t\tprerenderFlow,\n\t\tcontainer: options.container,\n\t\tprefetchOnMount: options.prefetchOnMount,\n\t\thideCloseButton: options.hideCloseButton,\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 * @see docs/custom-wrapper.md — integration level 3, one custom container\n * serving every flow in a provider subtree.\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
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "12E088381A2D1EB364756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|