@perspective-ai/sdk-react 1.4.0 → 1.5.0-pr-33-20260324104317

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var react = require('react');
4
4
  var sdk = require('@perspective-ai/sdk');
5
+ var server = require('react-dom/server');
5
6
  var jsxRuntime = require('react/jsx-runtime');
6
7
 
7
8
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
@@ -303,6 +304,9 @@ function useFloatBubble(options) {
303
304
  brand,
304
305
  theme,
305
306
  host,
307
+ channel,
308
+ welcomeMessage,
309
+ launcher,
306
310
  onReady,
307
311
  onSubmit,
308
312
  onNavigate,
@@ -327,6 +331,23 @@ function useFloatBubble(options) {
327
331
  onClose?.();
328
332
  }, [isControlled, onOpenChange, onClose]);
329
333
  const stableOnClose = useStableCallback(handleClose);
334
+ const resolvedLauncher = react.useMemo(() => {
335
+ if (!launcher) return void 0;
336
+ const { icon, ...rest } = launcher;
337
+ if (icon === false || icon === null || icon === void 0 || icon === 0 || icon === "") {
338
+ return Object.keys(rest).length > 0 ? rest : void 0;
339
+ }
340
+ if (react.isValidElement(icon)) {
341
+ return { ...rest, icon: { svg: server.renderToStaticMarkup(icon) } };
342
+ }
343
+ if (icon === "default" || icon === "avatar") {
344
+ return { ...rest, icon };
345
+ }
346
+ if (typeof icon === "object" && ("url" in icon || "svg" in icon)) {
347
+ return { ...rest, icon };
348
+ }
349
+ return Object.keys(rest).length > 0 ? rest : void 0;
350
+ }, [launcher]);
330
351
  react.useEffect(() => {
331
352
  const newHandle = sdk.createFloatBubble({
332
353
  researchId,
@@ -334,6 +355,9 @@ function useFloatBubble(options) {
334
355
  brand,
335
356
  theme,
336
357
  host,
358
+ channel,
359
+ welcomeMessage,
360
+ launcher: resolvedLauncher,
337
361
  onReady: stableOnReady,
338
362
  onSubmit: stableOnSubmit,
339
363
  onNavigate: stableOnNavigate,
@@ -355,6 +379,9 @@ function useFloatBubble(options) {
355
379
  brand,
356
380
  theme,
357
381
  host,
382
+ channel,
383
+ welcomeMessage,
384
+ resolvedLauncher,
358
385
  stableOnReady,
359
386
  stableOnSubmit,
360
387
  stableOnNavigate,
@@ -592,6 +619,9 @@ function FloatBubble({
592
619
  brand,
593
620
  theme,
594
621
  host,
622
+ channel,
623
+ welcomeMessage,
624
+ launcher,
595
625
  onReady,
596
626
  onSubmit,
597
627
  onNavigate,
@@ -605,6 +635,9 @@ function FloatBubble({
605
635
  brand,
606
636
  theme,
607
637
  host,
638
+ channel,
639
+ welcomeMessage,
640
+ launcher,
608
641
  onReady,
609
642
  onSubmit,
610
643
  onNavigate,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useLayoutEffect","useEffect","useRef","useCallback","useState","openPopup","getPersistedOpenState","openSlider","createFloatBubble","markShown","shouldShow","setupTrigger","createWidget","jsx","createFullpage"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n\n // Fix #5: useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({ researchId, ...embedConfig });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { useRef, useEffect, type HTMLAttributes, type RefObject } from \"react\";\nimport {\n createWidget,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{ minHeight: 500, ...style }}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport {\n createFullpage,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // This component doesn't render anything - the fullpage overlay is added to document.body\n return null;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport { useFloatBubble } from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return null;\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useLayoutEffect","useEffect","useRef","useCallback","useState","openPopup","getPersistedOpenState","openSlider","useMemo","isValidElement","renderToStaticMarkup","createFloatBubble","markShown","shouldShow","setupTrigger","createWidget","jsx","createFullpage"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import {\n useCallback,\n useState,\n useEffect,\n useRef,\n useMemo,\n isValidElement,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n type LauncherConfig,\n} from \"@perspective-ai/sdk\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Launcher config with React support — icon accepts ReactNode in addition to SDK types */\nexport interface LauncherConfigReact extends Omit<LauncherConfig, \"icon\"> {\n icon?: LauncherConfig[\"icon\"] | ReactNode;\n}\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n // Resolve ReactNode icons to SVG strings for the core SDK\n const resolvedLauncher = useMemo((): EmbedConfig[\"launcher\"] | undefined => {\n if (!launcher) return undefined;\n const { icon, ...rest } = launcher;\n // Filter out falsy ReactNode values (e.g., `condition && <Icon />` producing `false`)\n if (\n icon === false ||\n icon === null ||\n icon === undefined ||\n icon === 0 ||\n icon === \"\"\n ) {\n return Object.keys(rest).length > 0 ? rest : undefined;\n }\n if (isValidElement(icon)) {\n return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };\n }\n // Only pass through valid LauncherIcon values to core SDK\n if (icon === \"default\" || icon === \"avatar\") {\n return { ...rest, icon: icon as \"default\" | \"avatar\" };\n }\n if (\n typeof icon === \"object\" &&\n (\"url\" in icon || \"svg\" in icon)\n ) {\n return { ...rest, icon: icon as { url: string } | { svg: string } };\n }\n // Unrecognized icon value (truthy primitives, arrays, etc.) — ignore it\n return Object.keys(rest).length > 0 ? rest : undefined;\n }, [launcher]);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher: resolvedLauncher,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n resolvedLauncher,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n\n // Fix #5: useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({ researchId, ...embedConfig });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { useRef, useEffect, type HTMLAttributes, type RefObject } from \"react\";\nimport {\n createWidget,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{ minHeight: 500, ...style }}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport {\n createFullpage,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // This component doesn't render anything - the fullpage overlay is added to document.body\n return null;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport {\n useFloatBubble,\n type LauncherConfigReact,\n} from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return null;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- import { EmbedConfig, EmbedHandle, FloatHandle, TriggerConfig, ShowOnce } from '@perspective-ai/sdk';
1
+ import { EmbedConfig, EmbedHandle, LauncherConfig, FloatHandle, TriggerConfig, ShowOnce } from '@perspective-ai/sdk';
2
2
  export { AutoOpenConfig, BrandColors, EmbedConfig, EmbedError, EmbedHandle, FloatHandle, ShowOnce, ThemeValue, TriggerConfig } from '@perspective-ai/sdk';
3
+ import { ReactNode, HTMLAttributes, RefObject } from 'react';
3
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
- import { HTMLAttributes, RefObject } from 'react';
5
5
 
6
6
  /** Options for usePopup hook */
7
7
  interface UsePopupOptions extends Omit<EmbedConfig, "type"> {
@@ -76,12 +76,18 @@ interface UseSliderReturn {
76
76
  */
77
77
  declare function useSlider(options: UseSliderOptions): UseSliderReturn;
78
78
 
79
+ /** Launcher config with React support — icon accepts ReactNode in addition to SDK types */
80
+ interface LauncherConfigReact extends Omit<LauncherConfig, "icon"> {
81
+ icon?: LauncherConfig["icon"] | ReactNode;
82
+ }
79
83
  /** Options for useFloatBubble hook */
80
- interface UseFloatBubbleOptions extends Omit<EmbedConfig, "type"> {
84
+ interface UseFloatBubbleOptions extends Omit<EmbedConfig, "type" | "launcher"> {
81
85
  /** Controlled open state */
82
86
  open?: boolean;
83
87
  /** Callback when open state changes */
84
88
  onOpenChange?: (open: boolean) => void;
89
+ /** Customize the floating launcher button appearance */
90
+ launcher?: LauncherConfigReact;
85
91
  }
86
92
  /** Return type for useFloatBubble hook */
87
93
  interface UseFloatBubbleReturn {
@@ -157,9 +163,11 @@ interface FullpageProps extends Omit<EmbedConfig, "type"> {
157
163
  */
158
164
  declare function Fullpage({ researchId, params, brand, theme, host, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FullpageProps): null;
159
165
 
160
- interface FloatBubbleProps extends Omit<EmbedConfig, "type"> {
166
+ interface FloatBubbleProps extends Omit<EmbedConfig, "type" | "launcher"> {
161
167
  /** Ref to access the handle for programmatic control */
162
168
  embedRef?: RefObject<FloatHandle | null>;
169
+ /** Customize the floating launcher button appearance */
170
+ launcher?: LauncherConfigReact;
163
171
  }
164
172
  /**
165
173
  * Floating bubble widget that expands into a chat window.
@@ -170,6 +178,6 @@ interface FloatBubbleProps extends Omit<EmbedConfig, "type"> {
170
178
  * <FloatBubble researchId="abc" onSubmit={handleSubmit} />
171
179
  * ```
172
180
  */
173
- declare function FloatBubble({ researchId, params, brand, theme, host, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): null;
181
+ declare function FloatBubble({ researchId, params, brand, theme, host, channel, welcomeMessage, launcher, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): null;
174
182
 
175
183
  export { FloatBubble, type FloatBubbleProps, Fullpage, type FullpageProps, type UseAutoOpenOptions, type UseAutoOpenReturn, type UseFloatBubbleOptions, type UseFloatBubbleReturn, type UsePopupOptions, type UsePopupReturn, type UseSliderOptions, type UseSliderReturn, Widget, type WidgetProps, useAutoOpen, useFloatBubble, usePopup, useSlider, useStableCallback, useThemeSync };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { EmbedConfig, EmbedHandle, FloatHandle, TriggerConfig, ShowOnce } from '@perspective-ai/sdk';
1
+ import { EmbedConfig, EmbedHandle, LauncherConfig, FloatHandle, TriggerConfig, ShowOnce } from '@perspective-ai/sdk';
2
2
  export { AutoOpenConfig, BrandColors, EmbedConfig, EmbedError, EmbedHandle, FloatHandle, ShowOnce, ThemeValue, TriggerConfig } from '@perspective-ai/sdk';
3
+ import { ReactNode, HTMLAttributes, RefObject } from 'react';
3
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
- import { HTMLAttributes, RefObject } from 'react';
5
5
 
6
6
  /** Options for usePopup hook */
7
7
  interface UsePopupOptions extends Omit<EmbedConfig, "type"> {
@@ -76,12 +76,18 @@ interface UseSliderReturn {
76
76
  */
77
77
  declare function useSlider(options: UseSliderOptions): UseSliderReturn;
78
78
 
79
+ /** Launcher config with React support — icon accepts ReactNode in addition to SDK types */
80
+ interface LauncherConfigReact extends Omit<LauncherConfig, "icon"> {
81
+ icon?: LauncherConfig["icon"] | ReactNode;
82
+ }
79
83
  /** Options for useFloatBubble hook */
80
- interface UseFloatBubbleOptions extends Omit<EmbedConfig, "type"> {
84
+ interface UseFloatBubbleOptions extends Omit<EmbedConfig, "type" | "launcher"> {
81
85
  /** Controlled open state */
82
86
  open?: boolean;
83
87
  /** Callback when open state changes */
84
88
  onOpenChange?: (open: boolean) => void;
89
+ /** Customize the floating launcher button appearance */
90
+ launcher?: LauncherConfigReact;
85
91
  }
86
92
  /** Return type for useFloatBubble hook */
87
93
  interface UseFloatBubbleReturn {
@@ -157,9 +163,11 @@ interface FullpageProps extends Omit<EmbedConfig, "type"> {
157
163
  */
158
164
  declare function Fullpage({ researchId, params, brand, theme, host, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FullpageProps): null;
159
165
 
160
- interface FloatBubbleProps extends Omit<EmbedConfig, "type"> {
166
+ interface FloatBubbleProps extends Omit<EmbedConfig, "type" | "launcher"> {
161
167
  /** Ref to access the handle for programmatic control */
162
168
  embedRef?: RefObject<FloatHandle | null>;
169
+ /** Customize the floating launcher button appearance */
170
+ launcher?: LauncherConfigReact;
163
171
  }
164
172
  /**
165
173
  * Floating bubble widget that expands into a chat window.
@@ -170,6 +178,6 @@ interface FloatBubbleProps extends Omit<EmbedConfig, "type"> {
170
178
  * <FloatBubble researchId="abc" onSubmit={handleSubmit} />
171
179
  * ```
172
180
  */
173
- declare function FloatBubble({ researchId, params, brand, theme, host, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): null;
181
+ declare function FloatBubble({ researchId, params, brand, theme, host, channel, welcomeMessage, launcher, onReady, onSubmit, onNavigate, onClose, onError, embedRef, }: FloatBubbleProps): null;
174
182
 
175
183
  export { FloatBubble, type FloatBubbleProps, Fullpage, type FullpageProps, type UseAutoOpenOptions, type UseAutoOpenReturn, type UseFloatBubbleOptions, type UseFloatBubbleReturn, type UsePopupOptions, type UsePopupReturn, type UseSliderOptions, type UseSliderReturn, Widget, type WidgetProps, useAutoOpen, useFloatBubble, usePopup, useSlider, useStableCallback, useThemeSync };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { useRef, useLayoutEffect, useEffect, useCallback, useState } from 'react';
1
+ import { useRef, useLayoutEffect, useEffect, useCallback, useState, useMemo, isValidElement } from 'react';
2
2
  import { openPopup, getPersistedOpenState, openSlider, createFloatBubble, markShown, shouldShow, setupTrigger, createWidget, createFullpage } from '@perspective-ai/sdk';
3
+ import { renderToStaticMarkup } from 'react-dom/server';
3
4
  import { jsx } from 'react/jsx-runtime';
4
5
 
5
6
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
@@ -301,6 +302,9 @@ function useFloatBubble(options) {
301
302
  brand,
302
303
  theme,
303
304
  host,
305
+ channel,
306
+ welcomeMessage,
307
+ launcher,
304
308
  onReady,
305
309
  onSubmit,
306
310
  onNavigate,
@@ -325,6 +329,23 @@ function useFloatBubble(options) {
325
329
  onClose?.();
326
330
  }, [isControlled, onOpenChange, onClose]);
327
331
  const stableOnClose = useStableCallback(handleClose);
332
+ const resolvedLauncher = useMemo(() => {
333
+ if (!launcher) return void 0;
334
+ const { icon, ...rest } = launcher;
335
+ if (icon === false || icon === null || icon === void 0 || icon === 0 || icon === "") {
336
+ return Object.keys(rest).length > 0 ? rest : void 0;
337
+ }
338
+ if (isValidElement(icon)) {
339
+ return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };
340
+ }
341
+ if (icon === "default" || icon === "avatar") {
342
+ return { ...rest, icon };
343
+ }
344
+ if (typeof icon === "object" && ("url" in icon || "svg" in icon)) {
345
+ return { ...rest, icon };
346
+ }
347
+ return Object.keys(rest).length > 0 ? rest : void 0;
348
+ }, [launcher]);
328
349
  useEffect(() => {
329
350
  const newHandle = createFloatBubble({
330
351
  researchId,
@@ -332,6 +353,9 @@ function useFloatBubble(options) {
332
353
  brand,
333
354
  theme,
334
355
  host,
356
+ channel,
357
+ welcomeMessage,
358
+ launcher: resolvedLauncher,
335
359
  onReady: stableOnReady,
336
360
  onSubmit: stableOnSubmit,
337
361
  onNavigate: stableOnNavigate,
@@ -353,6 +377,9 @@ function useFloatBubble(options) {
353
377
  brand,
354
378
  theme,
355
379
  host,
380
+ channel,
381
+ welcomeMessage,
382
+ resolvedLauncher,
356
383
  stableOnReady,
357
384
  stableOnSubmit,
358
385
  stableOnNavigate,
@@ -590,6 +617,9 @@ function FloatBubble({
590
617
  brand,
591
618
  theme,
592
619
  host,
620
+ channel,
621
+ welcomeMessage,
622
+ launcher,
593
623
  onReady,
594
624
  onSubmit,
595
625
  onNavigate,
@@ -603,6 +633,9 @@ function FloatBubble({
603
633
  brand,
604
634
  theme,
605
635
  host,
636
+ channel,
637
+ welcomeMessage,
638
+ launcher,
606
639
  onReady,
607
640
  onSubmit,
608
641
  onNavigate,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useRef","useCallback","useEffect","useState","getPersistedOpenState","openPopup"],"mappings":"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","file":"index.js","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n\n // Fix #5: useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({ researchId, ...embedConfig });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { useRef, useEffect, type HTMLAttributes, type RefObject } from \"react\";\nimport {\n createWidget,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{ minHeight: 500, ...style }}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport {\n createFullpage,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // This component doesn't render anything - the fullpage overlay is added to document.body\n return null;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport { useFloatBubble } from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return null;\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useAutoOpen.ts","../src/hooks/useThemeSync.ts","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useRef","useCallback","useEffect","useState","getPersistedOpenState","openPopup"],"mappings":"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","file":"index.js","sourcesContent":["import { useRef, useCallback, useLayoutEffect, useEffect } from \"react\";\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport function useStableCallback<\n T extends ((...args: any[]) => any) | undefined,\n>(callback: T): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n // Always create the stable wrapper (hooks can't be conditional),\n // but return undefined when no callback is provided to preserve\n // truthiness semantics for consumers that branch on it.\n const stable = useCallback(\n ((...args: any[]) => callbackRef.current?.(...args)) as NonNullable<T>,\n []\n );\n\n return callback ? stable : callback;\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for usePopup hook */\nexport interface UsePopupOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for usePopup hook */\nexport interface UsePopupReturn {\n /** Open the popup */\n open: () => void;\n /** Close the popup */\n close: () => void;\n /** Toggle the popup */\n toggle: () => void;\n /** Whether the popup is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic popup control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * // Basic usage with custom trigger\n * const { open, isOpen } = usePopup({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Open Survey</MyCustomButton>\n *\n * // Controlled mode\n * const [isOpen, setIsOpen] = useState(false);\n * const popup = usePopup({\n * researchId: \"abc\",\n * open: isOpen,\n * onOpenChange: setIsOpen\n * });\n * ```\n */\nexport function usePopup(options: UsePopupOptions): UsePopupReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createPopup = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openPopup({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createPopup();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createPopup]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroyPopup(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroyPopup]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createPopup();\n } else if (!controlledOpen && handleRef.current) {\n destroyPopup(\"destroy\");\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"popup\", host }) !== true) {\n return;\n }\n\n createPopup();\n setInternalOpen(true);\n }, [createPopup, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\n getPersistedOpenState,\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Options for useSlider hook */\nexport interface UseSliderOptions extends Omit<EmbedConfig, \"type\"> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n}\n\n/** Return type for useSlider hook */\nexport interface UseSliderReturn {\n /** Open the slider */\n open: () => void;\n /** Close the slider */\n close: () => void;\n /** Toggle the slider */\n toggle: () => void;\n /** Whether the slider is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null when closed) */\n handle: EmbedHandle | null;\n}\n\n/**\n * Headless hook for programmatic slider control.\n * Use this when you need custom trigger elements or programmatic control.\n *\n * @example\n * ```tsx\n * const { open, isOpen } = useSlider({ researchId: \"abc\" });\n * <MyCustomButton onClick={open}>Give Feedback</MyCustomButton>\n * ```\n */\nexport function useSlider(options: UseSliderOptions): UseSliderReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (isControlled) {\n onOpenChange?.(value);\n } else {\n setInternalOpen(value);\n }\n },\n [isControlled, onOpenChange]\n );\n\n const handleClose = useCallback(() => {\n handleRef.current = null;\n setHandle(null);\n setOpen(false);\n onClose?.();\n }, [setOpen, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n const createSlider = useCallback(() => {\n if (handleRef.current) return handleRef.current;\n\n const newHandle = openSlider({\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n return newHandle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n disableClose,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback((mode: \"destroy\" | \"unmount\") => {\n if (handleRef.current) {\n if (mode === \"destroy\") {\n handleRef.current.destroy();\n } else {\n handleRef.current.unmount();\n }\n handleRef.current = null;\n setHandle(null);\n }\n }, []);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n createSlider();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange, createSlider]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n destroySlider(\"destroy\");\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange, destroySlider]);\n\n const toggleFn = useCallback(() => {\n if (isOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [isOpen, openFn, closeFn]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (controlledOpen && !handleRef.current) {\n createSlider();\n } else if (!controlledOpen && handleRef.current) {\n destroySlider(\"destroy\");\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n if (isControlled || handleRef.current) return;\n\n if (getPersistedOpenState({ researchId, type: \"slider\", host }) !== true) {\n return;\n }\n\n createSlider();\n setInternalOpen(true);\n }, [createSlider, host, isControlled, researchId]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.unmount();\n handleRef.current = null;\n }\n };\n }, []);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n isOpen,\n handle,\n };\n}\n","import {\n useCallback,\n useState,\n useEffect,\n useRef,\n useMemo,\n isValidElement,\n} from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n type LauncherConfig,\n} from \"@perspective-ai/sdk\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/** Launcher config with React support — icon accepts ReactNode in addition to SDK types */\nexport interface LauncherConfigReact extends Omit<LauncherConfig, \"icon\"> {\n icon?: LauncherConfig[\"icon\"] | ReactNode;\n}\n\n/** Options for useFloatBubble hook */\nexport interface UseFloatBubbleOptions extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/** Return type for useFloatBubble hook */\nexport interface UseFloatBubbleReturn {\n /** Open the float bubble window */\n open: () => void;\n /** Close the float bubble window */\n close: () => void;\n /** Toggle the float bubble window */\n toggle: () => void;\n /** Unmount the float bubble entirely */\n unmount: () => void;\n /** Whether the float bubble window is currently open */\n isOpen: boolean;\n /** The underlying SDK handle (null until mounted) */\n handle: FloatHandle | null;\n}\n\n/**\n * Headless hook for float bubble lifecycle management.\n * Creates a floating bubble button that expands into a chat window.\n * The bubble mounts on component mount and unmounts on component unmount.\n *\n * @example\n * ```tsx\n * // Basic usage - bubble mounts on component mount\n * useFloatBubble({ researchId: \"abc\" });\n *\n * // With programmatic control\n * const { open, close, isOpen } = useFloatBubble({ researchId: \"abc\" });\n * <button onClick={open}>Open Chat</button>\n * ```\n */\nexport function useFloatBubble(\n options: UseFloatBubbleOptions\n): UseFloatBubbleReturn {\n const {\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n open: controlledOpen,\n onOpenChange,\n } = options;\n\n const [handle, setHandle] = useState<FloatHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const handleRef = useRef<FloatHandle | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnError = useStableCallback(onError);\n\n const handleClose = useCallback(() => {\n setInternalOpen(false);\n if (isControlled) {\n onOpenChange?.(false);\n }\n onClose?.();\n }, [isControlled, onOpenChange, onClose]);\n\n const stableOnClose = useStableCallback(handleClose);\n\n // Resolve ReactNode icons to SVG strings for the core SDK\n const resolvedLauncher = useMemo((): EmbedConfig[\"launcher\"] | undefined => {\n if (!launcher) return undefined;\n const { icon, ...rest } = launcher;\n // Filter out falsy ReactNode values (e.g., `condition && <Icon />` producing `false`)\n if (\n icon === false ||\n icon === null ||\n icon === undefined ||\n icon === 0 ||\n icon === \"\"\n ) {\n return Object.keys(rest).length > 0 ? rest : undefined;\n }\n if (isValidElement(icon)) {\n return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };\n }\n // Only pass through valid LauncherIcon values to core SDK\n if (icon === \"default\" || icon === \"avatar\") {\n return { ...rest, icon: icon as \"default\" | \"avatar\" };\n }\n if (\n typeof icon === \"object\" &&\n (\"url\" in icon || \"svg\" in icon)\n ) {\n return { ...rest, icon: icon as { url: string } | { svg: string } };\n }\n // Unrecognized icon value (truthy primitives, arrays, etc.) — ignore it\n return Object.keys(rest).length > 0 ? rest : undefined;\n }, [launcher]);\n\n useEffect(() => {\n const newHandle = createFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher: resolvedLauncher,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = newHandle;\n setHandle(newHandle);\n\n return () => {\n if (handleRef.current === newHandle) {\n newHandle.unmount();\n handleRef.current = null;\n setHandle(null);\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n resolvedLauncher,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n useEffect(() => {\n if (!isControlled || !handle) return;\n\n if (controlledOpen && !handle.isOpen) {\n handle.open();\n } else if (!controlledOpen && handle.isOpen) {\n handle.close();\n }\n }, [controlledOpen, isControlled, handle]);\n\n const openFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(true);\n } else {\n handleRef.current?.open();\n setInternalOpen(true);\n }\n }, [isControlled, onOpenChange]);\n\n const closeFn = useCallback(() => {\n if (isControlled) {\n onOpenChange?.(false);\n } else {\n handleRef.current?.close();\n setInternalOpen(false);\n }\n }, [isControlled, onOpenChange]);\n\n const toggleFn = useCallback(() => {\n const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;\n if (currentlyOpen) {\n closeFn();\n } else {\n openFn();\n }\n }, [internalOpen, openFn, closeFn]);\n\n const unmountFn = useCallback(() => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setHandle(null);\n setInternalOpen(false);\n }, []);\n\n const isOpen = isControlled\n ? controlledOpen\n : (handle?.isOpen ?? internalOpen);\n\n return {\n open: openFn,\n close: closeFn,\n toggle: toggleFn,\n unmount: unmountFn,\n isOpen,\n handle,\n };\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n openPopup,\n setupTrigger,\n shouldShow,\n markShown,\n} from \"@perspective-ai/sdk\";\nimport type { EmbedConfig, TriggerConfig, ShowOnce } from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./useStableCallback\";\n\nexport interface UseAutoOpenOptions extends Omit<\n EmbedConfig,\n \"type\" | \"autoOpen\"\n> {\n trigger: TriggerConfig;\n showOnce?: ShowOnce; // default: \"session\"\n}\n\nexport interface UseAutoOpenReturn {\n /** Cancel the pending trigger */\n cancel: () => void;\n /** Whether the trigger has fired */\n triggered: boolean;\n}\n\nexport function useAutoOpen(options: UseAutoOpenOptions): UseAutoOpenReturn {\n const { trigger, showOnce = \"session\", researchId, ...embedConfig } = options;\n const cleanupRef = useRef<(() => void) | null>(null);\n const [triggered, setTriggered] = useState(false);\n const triggerDelay = trigger.type === \"timeout\" ? trigger.delay : undefined;\n\n // Fix #5: useStableCallback so the trigger always calls with latest config\n const stableOnTrigger = useStableCallback(() => {\n markShown(researchId, showOnce);\n openPopup({ researchId, ...embedConfig });\n });\n\n useEffect(() => {\n if (!shouldShow(researchId, showOnce)) return;\n\n cleanupRef.current = setupTrigger(trigger, () => {\n setTriggered((prev) => {\n if (prev) return prev; // already fired\n stableOnTrigger();\n return true;\n });\n });\n\n return () => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n };\n // Primitive deps only — avoids re-triggering on object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [researchId, trigger.type, triggerDelay, showOnce]);\n\n const cancel = useCallback(() => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n }, []);\n\n return { cancel, triggered };\n}\n","import { useState, useEffect } from \"react\";\n\ntype Theme = \"light\" | \"dark\";\ntype ThemeInput = \"light\" | \"dark\" | \"system\";\n\n/**\n * Hook to resolve theme based on override and system preference.\n * Listens for system preference changes when theme is \"system\".\n */\nexport function useThemeSync(theme: ThemeInput = \"system\"): Theme {\n // Always start with a deterministic value for SSR hydration safety.\n // The actual system preference is synced in useEffect.\n const [resolved, setResolved] = useState<Theme>(\n theme !== \"system\" ? theme : \"light\"\n );\n\n useEffect(() => {\n if (theme !== \"system\") {\n setResolved(theme);\n return;\n }\n\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n // Set initial value\n setResolved(mq.matches ? \"dark\" : \"light\");\n\n const handler = (e: MediaQueryListEvent) =>\n setResolved(e.matches ? \"dark\" : \"light\");\n\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n return resolved;\n}\n","import { useRef, useEffect, type HTMLAttributes, type RefObject } from \"react\";\nimport {\n createWidget,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface WidgetProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<HTMLAttributes<HTMLDivElement>, \"onError\" | \"onSubmit\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Inline widget embed component.\n * Renders the interview directly in a container.\n */\nexport function Widget({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n className,\n style,\n ...divProps\n}: WidgetProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks to avoid re-mounting on callback changes\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handle = createWidget(container, {\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{ minHeight: 500, ...style }}\n data-testid=\"perspective-widget\"\n {...divProps}\n />\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport {\n createFullpage,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\nexport interface FullpageProps extends Omit<EmbedConfig, \"type\"> {\n /** Ref to access the embed handle for programmatic control */\n embedRef?: RefObject<EmbedHandle | null>;\n}\n\n/**\n * Full viewport embed component.\n * Takes over the entire screen with the interview.\n */\nexport function Fullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FullpageProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n\n // Stable callbacks\n const stableOnReady = useStableCallback(onReady);\n const stableOnSubmit = useStableCallback(onSubmit);\n const stableOnNavigate = useStableCallback(onNavigate);\n const stableOnClose = useStableCallback(onClose);\n const stableOnError = useStableCallback(onError);\n\n useEffect(() => {\n const handle = createFullpage({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady: stableOnReady,\n onSubmit: stableOnSubmit,\n onNavigate: stableOnNavigate,\n onClose: stableOnClose,\n onError: stableOnError,\n });\n\n handleRef.current = handle;\n\n if (embedRef) {\n embedRef.current = handle;\n }\n\n return () => {\n handle.unmount();\n handleRef.current = null;\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n embedRef,\n ]);\n\n // This component doesn't render anything - the fullpage overlay is added to document.body\n return null;\n}\n","import { useEffect, type RefObject } from \"react\";\nimport { type EmbedConfig, type FloatHandle } from \"@perspective-ai/sdk\";\nimport {\n useFloatBubble,\n type LauncherConfigReact,\n} from \"./hooks/useFloatBubble\";\n\nexport interface FloatBubbleProps extends Omit<\n EmbedConfig,\n \"type\" | \"launcher\"\n> {\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<FloatHandle | null>;\n /** Customize the floating launcher button appearance */\n launcher?: LauncherConfigReact;\n}\n\n/**\n * Floating bubble widget that expands into a chat window.\n * This is a convenience wrapper around useFloatBubble hook.\n *\n * @example\n * ```tsx\n * <FloatBubble researchId=\"abc\" onSubmit={handleSubmit} />\n * ```\n */\nexport function FloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n embedRef,\n}: FloatBubbleProps) {\n const { handle } = useFloatBubble({\n researchId,\n params,\n brand,\n theme,\n host,\n channel,\n welcomeMessage,\n launcher,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n });\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = handle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, handle]);\n\n return null;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perspective-ai/sdk-react",
3
- "version": "1.4.0",
3
+ "version": "1.5.0-pr-33-20260324104317",
4
4
  "description": "React components for Perspective AI embed SDK",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -56,7 +56,7 @@
56
56
  "react-dom": "^18.0.0 || ^19.0.0"
57
57
  },
58
58
  "dependencies": {
59
- "@perspective-ai/sdk": "^1.4.0"
59
+ "@perspective-ai/sdk": "^1.5.0-pr-33-20260324104317"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@testing-library/dom": "^10.4.1",
@@ -1,10 +1,18 @@
1
1
  import { useEffect, type RefObject } from "react";
2
2
  import { type EmbedConfig, type FloatHandle } from "@perspective-ai/sdk";
3
- import { useFloatBubble } from "./hooks/useFloatBubble";
3
+ import {
4
+ useFloatBubble,
5
+ type LauncherConfigReact,
6
+ } from "./hooks/useFloatBubble";
4
7
 
5
- export interface FloatBubbleProps extends Omit<EmbedConfig, "type"> {
8
+ export interface FloatBubbleProps extends Omit<
9
+ EmbedConfig,
10
+ "type" | "launcher"
11
+ > {
6
12
  /** Ref to access the handle for programmatic control */
7
13
  embedRef?: RefObject<FloatHandle | null>;
14
+ /** Customize the floating launcher button appearance */
15
+ launcher?: LauncherConfigReact;
8
16
  }
9
17
 
10
18
  /**
@@ -22,6 +30,9 @@ export function FloatBubble({
22
30
  brand,
23
31
  theme,
24
32
  host,
33
+ channel,
34
+ welcomeMessage,
35
+ launcher,
25
36
  onReady,
26
37
  onSubmit,
27
38
  onNavigate,
@@ -35,6 +46,9 @@ export function FloatBubble({
35
46
  brand,
36
47
  theme,
37
48
  host,
49
+ channel,
50
+ welcomeMessage,
51
+ launcher,
38
52
  onReady,
39
53
  onSubmit,
40
54
  onNavigate,
@@ -1,17 +1,37 @@
1
- import { useCallback, useState, useEffect, useRef } from "react";
1
+ import {
2
+ useCallback,
3
+ useState,
4
+ useEffect,
5
+ useRef,
6
+ useMemo,
7
+ isValidElement,
8
+ } from "react";
9
+ import type { ReactNode } from "react";
2
10
  import {
3
11
  createFloatBubble,
4
12
  type EmbedConfig,
5
13
  type FloatHandle,
14
+ type LauncherConfig,
6
15
  } from "@perspective-ai/sdk";
16
+ import { renderToStaticMarkup } from "react-dom/server";
7
17
  import { useStableCallback } from "./useStableCallback";
8
18
 
19
+ /** Launcher config with React support — icon accepts ReactNode in addition to SDK types */
20
+ export interface LauncherConfigReact extends Omit<LauncherConfig, "icon"> {
21
+ icon?: LauncherConfig["icon"] | ReactNode;
22
+ }
23
+
9
24
  /** Options for useFloatBubble hook */
10
- export interface UseFloatBubbleOptions extends Omit<EmbedConfig, "type"> {
25
+ export interface UseFloatBubbleOptions extends Omit<
26
+ EmbedConfig,
27
+ "type" | "launcher"
28
+ > {
11
29
  /** Controlled open state */
12
30
  open?: boolean;
13
31
  /** Callback when open state changes */
14
32
  onOpenChange?: (open: boolean) => void;
33
+ /** Customize the floating launcher button appearance */
34
+ launcher?: LauncherConfigReact;
15
35
  }
16
36
 
17
37
  /** Return type for useFloatBubble hook */
@@ -54,6 +74,9 @@ export function useFloatBubble(
54
74
  brand,
55
75
  theme,
56
76
  host,
77
+ channel,
78
+ welcomeMessage,
79
+ launcher,
57
80
  onReady,
58
81
  onSubmit,
59
82
  onNavigate,
@@ -84,6 +107,37 @@ export function useFloatBubble(
84
107
 
85
108
  const stableOnClose = useStableCallback(handleClose);
86
109
 
110
+ // Resolve ReactNode icons to SVG strings for the core SDK
111
+ const resolvedLauncher = useMemo((): EmbedConfig["launcher"] | undefined => {
112
+ if (!launcher) return undefined;
113
+ const { icon, ...rest } = launcher;
114
+ // Filter out falsy ReactNode values (e.g., `condition && <Icon />` producing `false`)
115
+ if (
116
+ icon === false ||
117
+ icon === null ||
118
+ icon === undefined ||
119
+ icon === 0 ||
120
+ icon === ""
121
+ ) {
122
+ return Object.keys(rest).length > 0 ? rest : undefined;
123
+ }
124
+ if (isValidElement(icon)) {
125
+ return { ...rest, icon: { svg: renderToStaticMarkup(icon) } };
126
+ }
127
+ // Only pass through valid LauncherIcon values to core SDK
128
+ if (icon === "default" || icon === "avatar") {
129
+ return { ...rest, icon: icon as "default" | "avatar" };
130
+ }
131
+ if (
132
+ typeof icon === "object" &&
133
+ ("url" in icon || "svg" in icon)
134
+ ) {
135
+ return { ...rest, icon: icon as { url: string } | { svg: string } };
136
+ }
137
+ // Unrecognized icon value (truthy primitives, arrays, etc.) — ignore it
138
+ return Object.keys(rest).length > 0 ? rest : undefined;
139
+ }, [launcher]);
140
+
87
141
  useEffect(() => {
88
142
  const newHandle = createFloatBubble({
89
143
  researchId,
@@ -91,6 +145,9 @@ export function useFloatBubble(
91
145
  brand,
92
146
  theme,
93
147
  host,
148
+ channel,
149
+ welcomeMessage,
150
+ launcher: resolvedLauncher,
94
151
  onReady: stableOnReady,
95
152
  onSubmit: stableOnSubmit,
96
153
  onNavigate: stableOnNavigate,
@@ -114,6 +171,9 @@ export function useFloatBubble(
114
171
  brand,
115
172
  theme,
116
173
  host,
174
+ channel,
175
+ welcomeMessage,
176
+ resolvedLauncher,
117
177
  stableOnReady,
118
178
  stableOnSubmit,
119
179
  stableOnNavigate,