@perspective-ai/sdk-react 1.0.0-alpha.2 → 1.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/Widget.tsx","../src/PopupButton.tsx","../src/SliderButton.tsx","../src/FloatBubble.tsx","../src/Fullpage.tsx","../src/hooks/useThemeSync.ts"],"names":["useRef","useEffect","useCallback","jsx","useState","useMemo"],"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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStableCallback<T extends (...args: any[]) => any>(\n callback: T | undefined\n): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n return useCallback(\n ((...args: Parameters<T>) => callbackRef.current?.(...args)) as T,\n []\n );\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 {\n useRef,\n useCallback,\n useState,\n useEffect,\n useMemo,\n type ReactNode,\n type ButtonHTMLAttributes,\n type RefObject,\n} from \"react\";\nimport {\n openPopup,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\n/** Handle for programmatic control of popup button */\nexport interface PopupButtonHandle {\n open: () => void;\n close: () => void;\n toggle: () => void;\n unmount: () => void;\n readonly isOpen: boolean;\n readonly researchId: string;\n}\n\nexport interface PopupButtonProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"onError\" | \"onSubmit\"> {\n /** Button content */\n children: ReactNode;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<PopupButtonHandle | null>;\n}\n\n/**\n * Button that opens a popup modal when clicked.\n * Supports both controlled and uncontrolled modes.\n */\nexport function PopupButton({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n children,\n open,\n onOpenChange,\n embedRef,\n onClick,\n ...buttonProps\n}: PopupButtonProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n\n const isControlled = open !== undefined;\n const isOpen = isControlled ? open : 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 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 handle = openPopup({\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 return handle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const proxyHandle = useMemo<PopupButtonHandle>(\n () => ({\n open: () => {\n createPopup();\n setOpen(true);\n },\n close: () => {\n handleRef.current?.destroy();\n handleRef.current = null;\n setOpen(false);\n },\n toggle: () => {\n if (handleRef.current) {\n handleRef.current.destroy();\n handleRef.current = null;\n setOpen(false);\n } else {\n createPopup();\n setOpen(true);\n }\n },\n unmount: () => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setOpen(false);\n },\n get isOpen() {\n return isOpen;\n },\n researchId,\n }),\n [createPopup, setOpen, researchId, isOpen]\n );\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = proxyHandle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, proxyHandle]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (open && !handleRef.current) {\n createPopup();\n } else if (!open && handleRef.current) {\n handleRef.current.destroy();\n handleRef.current = null;\n }\n }, [open, isControlled, createPopup]);\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (e.defaultPrevented) return;\n\n if (isOpen && handleRef.current) {\n handleRef.current.destroy();\n handleRef.current = null;\n setOpen(false);\n } else {\n createPopup();\n setOpen(true);\n }\n },\n [onClick, isOpen, createPopup, setOpen]\n );\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n data-testid=\"perspective-popup-button\"\n {...buttonProps}\n >\n {children}\n </button>\n );\n}\n","import {\n useRef,\n useCallback,\n useState,\n useEffect,\n useMemo,\n type ReactNode,\n type ButtonHTMLAttributes,\n type RefObject,\n} from \"react\";\nimport {\n openSlider,\n type EmbedConfig,\n type EmbedHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\n\n/** Handle for programmatic control of slider button */\nexport interface SliderButtonHandle {\n open: () => void;\n close: () => void;\n toggle: () => void;\n unmount: () => void;\n readonly isOpen: boolean;\n readonly researchId: string;\n}\n\nexport interface SliderButtonProps\n extends\n Omit<EmbedConfig, \"type\">,\n Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"onError\" | \"onSubmit\"> {\n /** Button content */\n children: ReactNode;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Ref to access the handle for programmatic control */\n embedRef?: RefObject<SliderButtonHandle | null>;\n}\n\n/**\n * Button that opens a slider panel when clicked.\n * Supports both controlled and uncontrolled modes.\n */\nexport function SliderButton({\n researchId,\n params,\n brand,\n theme,\n host,\n onReady,\n onSubmit,\n onNavigate,\n onClose,\n onError,\n children,\n open,\n onOpenChange,\n embedRef,\n onClick,\n ...buttonProps\n}: SliderButtonProps) {\n const handleRef = useRef<EmbedHandle | null>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n\n const isControlled = open !== undefined;\n const isOpen = isControlled ? open : 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 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 handle = openSlider({\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 return handle;\n }, [\n researchId,\n params,\n brand,\n theme,\n host,\n stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const proxyHandle = useMemo<SliderButtonHandle>(\n () => ({\n open: () => {\n createSlider();\n setOpen(true);\n },\n close: () => {\n handleRef.current?.destroy();\n handleRef.current = null;\n setOpen(false);\n },\n toggle: () => {\n if (handleRef.current) {\n handleRef.current.destroy();\n handleRef.current = null;\n setOpen(false);\n } else {\n createSlider();\n setOpen(true);\n }\n },\n unmount: () => {\n handleRef.current?.unmount();\n handleRef.current = null;\n setOpen(false);\n },\n get isOpen() {\n return isOpen;\n },\n researchId,\n }),\n [createSlider, setOpen, researchId, isOpen]\n );\n\n useEffect(() => {\n if (embedRef) {\n embedRef.current = proxyHandle;\n }\n return () => {\n if (embedRef) {\n embedRef.current = null;\n }\n };\n }, [embedRef, proxyHandle]);\n\n useEffect(() => {\n if (!isControlled) return;\n\n if (open && !handleRef.current) {\n createSlider();\n } else if (!open && handleRef.current) {\n handleRef.current.destroy();\n handleRef.current = null;\n }\n }, [open, isControlled, createSlider]);\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (e.defaultPrevented) return;\n\n if (isOpen && handleRef.current) {\n handleRef.current.destroy();\n handleRef.current = null;\n setOpen(false);\n } else {\n createSlider();\n setOpen(true);\n }\n },\n [onClick, isOpen, createSlider, setOpen]\n );\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n data-testid=\"perspective-slider-button\"\n {...buttonProps}\n >\n {children}\n </button>\n );\n}\n","import { useRef, useEffect, type RefObject } from \"react\";\nimport {\n createFloatBubble,\n type EmbedConfig,\n type FloatHandle,\n} from \"@perspective-ai/sdk\";\nimport { useStableCallback } from \"./hooks/useStableCallback\";\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 * Renders a floating button in the corner of the screen.\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 handleRef = useRef<FloatHandle | 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 = 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 = 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 bubble is added to document.body\n return null;\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 { 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"]}
1
+ {"version":3,"sources":["../src/hooks/useStableCallback.ts","../src/hooks/usePopup.ts","../src/hooks/useSlider.ts","../src/hooks/useFloatBubble.ts","../src/hooks/useThemeSync.ts","../src/Widget.tsx","../src/Fullpage.tsx","../src/FloatBubble.tsx"],"names":["useRef","useCallback","useEffect","useState"],"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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStableCallback<T extends (...args: any[]) => any>(\n callback: T | undefined\n): T {\n const callbackRef = useRef(callback);\n\n useIsomorphicLayoutEffect(() => {\n callbackRef.current = callback;\n });\n\n return useCallback(\n ((...args: Parameters<T>) => callbackRef.current?.(...args)) as T,\n []\n );\n}\n","import { useCallback, useState, useEffect, useRef } from \"react\";\nimport {\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 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 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 stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroyPopup = useCallback(() => {\n if (handleRef.current) {\n handleRef.current.destroy();\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();\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();\n }\n }, [controlledOpen, isControlled, createPopup, destroyPopup]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.destroy();\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 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 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 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 stableOnReady,\n stableOnSubmit,\n stableOnNavigate,\n stableOnClose,\n stableOnError,\n ]);\n\n const destroySlider = useCallback(() => {\n if (handleRef.current) {\n handleRef.current.destroy();\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();\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();\n }\n }, [controlledOpen, isControlled, createSlider, destroySlider]);\n\n useEffect(() => {\n return () => {\n if (handleRef.current) {\n handleRef.current.destroy();\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 { 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perspective-ai/sdk-react",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.3",
4
4
  "description": "React components for Perspective AI embed SDK",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -25,9 +25,16 @@
25
25
  ],
26
26
  "keywords": [
27
27
  "perspective",
28
+ "perspective-ai",
28
29
  "embed",
30
+ "sdk",
29
31
  "react",
32
+ "ai",
33
+ "llm",
34
+ "conversational-ai",
35
+ "research",
30
36
  "interview",
37
+ "voice-agent",
31
38
  "widget"
32
39
  ],
33
40
  "author": "Perspective AI",
@@ -49,7 +56,7 @@
49
56
  "react-dom": "^18.0.0 || ^19.0.0"
50
57
  },
51
58
  "dependencies": {
52
- "@perspective-ai/sdk": "^1.0.0-alpha.2"
59
+ "@perspective-ai/sdk": "^1.0.0-alpha.3"
53
60
  },
54
61
  "devDependencies": {
55
62
  "@testing-library/dom": "^10.4.1",
@@ -1,8 +1,6 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
2
  import { render, cleanup } from "@testing-library/react";
3
- import { createRef } from "react";
4
3
  import { FloatBubble } from "./FloatBubble";
5
- import type { FloatHandle } from "@perspective-ai/sdk";
6
4
 
7
5
  const mockUnmount = vi.fn();
8
6
  const mockOpen = vi.fn();
@@ -92,43 +90,6 @@ describe("FloatBubble", () => {
92
90
  expect(config.host).toBe("https://custom.example.com");
93
91
  });
94
92
 
95
- it("exposes handle via embedRef", () => {
96
- const mockHandle: FloatHandle = {
97
- unmount: mockUnmount,
98
- update: mockUpdate,
99
- destroy: mockUnmount,
100
- open: mockOpen,
101
- close: mockClose,
102
- toggle: mockToggle,
103
- researchId: "test-research-id",
104
- type: "float",
105
- iframe: null,
106
- container: null,
107
- isOpen: false,
108
- };
109
- mockCreateFloatBubble.mockReturnValueOnce(mockHandle);
110
-
111
- const embedRef = createRef<FloatHandle | null>();
112
-
113
- render(<FloatBubble researchId="test-research-id" embedRef={embedRef} />);
114
-
115
- expect(embedRef.current).toBe(mockHandle);
116
- });
117
-
118
- it("clears embedRef on unmount", () => {
119
- const embedRef = createRef<FloatHandle | null>();
120
-
121
- const { unmount } = render(
122
- <FloatBubble researchId="test-research-id" embedRef={embedRef} />
123
- );
124
-
125
- expect(embedRef.current).not.toBeNull();
126
-
127
- unmount();
128
-
129
- expect(embedRef.current).toBeNull();
130
- });
131
-
132
93
  it("re-creates float bubble when researchId changes", () => {
133
94
  const { rerender } = render(<FloatBubble researchId="research-1" />);
134
95
 
@@ -1,10 +1,6 @@
1
- import { useRef, useEffect, type RefObject } from "react";
2
- import {
3
- createFloatBubble,
4
- type EmbedConfig,
5
- type FloatHandle,
6
- } from "@perspective-ai/sdk";
7
- import { useStableCallback } from "./hooks/useStableCallback";
1
+ import { useEffect, type RefObject } from "react";
2
+ import { type EmbedConfig, type FloatHandle } from "@perspective-ai/sdk";
3
+ import { useFloatBubble } from "./hooks/useFloatBubble";
8
4
 
9
5
  export interface FloatBubbleProps extends Omit<EmbedConfig, "type"> {
10
6
  /** Ref to access the handle for programmatic control */
@@ -13,7 +9,12 @@ export interface FloatBubbleProps extends Omit<EmbedConfig, "type"> {
13
9
 
14
10
  /**
15
11
  * Floating bubble widget that expands into a chat window.
16
- * Renders a floating button in the corner of the screen.
12
+ * This is a convenience wrapper around useFloatBubble hook.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <FloatBubble researchId="abc" onSubmit={handleSubmit} />
17
+ * ```
17
18
  */
18
19
  export function FloatBubble({
19
20
  researchId,
@@ -28,56 +29,29 @@ export function FloatBubble({
28
29
  onError,
29
30
  embedRef,
30
31
  }: FloatBubbleProps) {
31
- const handleRef = useRef<FloatHandle | null>(null);
32
-
33
- // Stable callbacks
34
- const stableOnReady = useStableCallback(onReady);
35
- const stableOnSubmit = useStableCallback(onSubmit);
36
- const stableOnNavigate = useStableCallback(onNavigate);
37
- const stableOnClose = useStableCallback(onClose);
38
- const stableOnError = useStableCallback(onError);
32
+ const { handle } = useFloatBubble({
33
+ researchId,
34
+ params,
35
+ brand,
36
+ theme,
37
+ host,
38
+ onReady,
39
+ onSubmit,
40
+ onNavigate,
41
+ onClose,
42
+ onError,
43
+ });
39
44
 
40
45
  useEffect(() => {
41
- const handle = createFloatBubble({
42
- researchId,
43
- params,
44
- brand,
45
- theme,
46
- host,
47
- onReady: stableOnReady,
48
- onSubmit: stableOnSubmit,
49
- onNavigate: stableOnNavigate,
50
- onClose: stableOnClose,
51
- onError: stableOnError,
52
- });
53
-
54
- handleRef.current = handle;
55
-
56
46
  if (embedRef) {
57
47
  embedRef.current = handle;
58
48
  }
59
-
60
49
  return () => {
61
- handle.unmount();
62
- handleRef.current = null;
63
50
  if (embedRef) {
64
51
  embedRef.current = null;
65
52
  }
66
53
  };
67
- }, [
68
- researchId,
69
- params,
70
- brand,
71
- theme,
72
- host,
73
- stableOnReady,
74
- stableOnSubmit,
75
- stableOnNavigate,
76
- stableOnClose,
77
- stableOnError,
78
- embedRef,
79
- ]);
54
+ }, [embedRef, handle]);
80
55
 
81
- // This component doesn't render anything - the bubble is added to document.body
82
56
  return null;
83
57
  }
@@ -0,0 +1,91 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { renderHook, cleanup, act } from "@testing-library/react";
3
+ import { useFloatBubble } from "./useFloatBubble";
4
+
5
+ const mockOpen = vi.fn();
6
+ const mockClose = vi.fn();
7
+ const mockUnmount = vi.fn();
8
+ const mockToggle = vi.fn();
9
+ const mockDestroy = vi.fn();
10
+ const mockUpdate = vi.fn();
11
+
12
+ const stableMockHandle = {
13
+ open: mockOpen,
14
+ close: mockClose,
15
+ unmount: mockUnmount,
16
+ toggle: mockToggle,
17
+ destroy: mockDestroy,
18
+ update: mockUpdate,
19
+ isOpen: false,
20
+ researchId: "test-research-id",
21
+ type: "float" as const,
22
+ iframe: null,
23
+ container: null,
24
+ };
25
+
26
+ vi.mock("@perspective-ai/sdk", () => ({
27
+ createFloatBubble: vi.fn(() => stableMockHandle),
28
+ }));
29
+
30
+ import { createFloatBubble } from "@perspective-ai/sdk";
31
+ const mockCreateFloatBubble = vi.mocked(createFloatBubble);
32
+
33
+ describe("useFloatBubble", () => {
34
+ beforeEach(() => {
35
+ vi.clearAllMocks();
36
+ stableMockHandle.isOpen = false;
37
+ });
38
+
39
+ afterEach(() => {
40
+ cleanup();
41
+ });
42
+
43
+ it("creates bubble on mount and cleans up on unmount", () => {
44
+ const { unmount } = renderHook(() =>
45
+ useFloatBubble({ researchId: "test-research-id" })
46
+ );
47
+
48
+ expect(mockCreateFloatBubble).toHaveBeenCalledTimes(1);
49
+ expect(mockCreateFloatBubble).toHaveBeenCalledWith(
50
+ expect.objectContaining({ researchId: "test-research-id" })
51
+ );
52
+
53
+ unmount();
54
+
55
+ expect(mockUnmount).toHaveBeenCalledTimes(1);
56
+ });
57
+
58
+ it("returns expected interface", () => {
59
+ const { result, unmount } = renderHook(() =>
60
+ useFloatBubble({ researchId: "test-research-id" })
61
+ );
62
+
63
+ expect(result.current.open).toBeInstanceOf(Function);
64
+ expect(result.current.close).toBeInstanceOf(Function);
65
+ expect(result.current.toggle).toBeInstanceOf(Function);
66
+ expect(result.current.unmount).toBeInstanceOf(Function);
67
+ expect(result.current.handle).not.toBeNull();
68
+ expect(typeof result.current.isOpen).toBe("boolean");
69
+
70
+ unmount();
71
+ });
72
+
73
+ it("manual unmount clears handle and prevents double cleanup", () => {
74
+ const { result, unmount } = renderHook(() =>
75
+ useFloatBubble({ researchId: "test-research-id" })
76
+ );
77
+
78
+ expect(result.current.handle).not.toBeNull();
79
+
80
+ act(() => {
81
+ result.current.unmount();
82
+ });
83
+
84
+ expect(mockUnmount).toHaveBeenCalledTimes(1);
85
+ expect(result.current.handle).toBeNull();
86
+
87
+ unmount();
88
+
89
+ expect(mockUnmount).toHaveBeenCalledTimes(1);
90
+ });
91
+ });
@@ -0,0 +1,180 @@
1
+ import { useCallback, useState, useEffect, useRef } from "react";
2
+ import {
3
+ createFloatBubble,
4
+ type EmbedConfig,
5
+ type FloatHandle,
6
+ } from "@perspective-ai/sdk";
7
+ import { useStableCallback } from "./useStableCallback";
8
+
9
+ /** Options for useFloatBubble hook */
10
+ export interface UseFloatBubbleOptions extends Omit<EmbedConfig, "type"> {
11
+ /** Controlled open state */
12
+ open?: boolean;
13
+ /** Callback when open state changes */
14
+ onOpenChange?: (open: boolean) => void;
15
+ }
16
+
17
+ /** Return type for useFloatBubble hook */
18
+ export interface UseFloatBubbleReturn {
19
+ /** Open the float bubble window */
20
+ open: () => void;
21
+ /** Close the float bubble window */
22
+ close: () => void;
23
+ /** Toggle the float bubble window */
24
+ toggle: () => void;
25
+ /** Unmount the float bubble entirely */
26
+ unmount: () => void;
27
+ /** Whether the float bubble window is currently open */
28
+ isOpen: boolean;
29
+ /** The underlying SDK handle (null until mounted) */
30
+ handle: FloatHandle | null;
31
+ }
32
+
33
+ /**
34
+ * Headless hook for float bubble lifecycle management.
35
+ * Creates a floating bubble button that expands into a chat window.
36
+ * The bubble mounts on component mount and unmounts on component unmount.
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * // Basic usage - bubble mounts on component mount
41
+ * useFloatBubble({ researchId: "abc" });
42
+ *
43
+ * // With programmatic control
44
+ * const { open, close, isOpen } = useFloatBubble({ researchId: "abc" });
45
+ * <button onClick={open}>Open Chat</button>
46
+ * ```
47
+ */
48
+ export function useFloatBubble(
49
+ options: UseFloatBubbleOptions
50
+ ): UseFloatBubbleReturn {
51
+ const {
52
+ researchId,
53
+ params,
54
+ brand,
55
+ theme,
56
+ host,
57
+ onReady,
58
+ onSubmit,
59
+ onNavigate,
60
+ onClose,
61
+ onError,
62
+ open: controlledOpen,
63
+ onOpenChange,
64
+ } = options;
65
+
66
+ const [handle, setHandle] = useState<FloatHandle | null>(null);
67
+ const [internalOpen, setInternalOpen] = useState(false);
68
+ const handleRef = useRef<FloatHandle | null>(null);
69
+
70
+ const isControlled = controlledOpen !== undefined;
71
+
72
+ const stableOnReady = useStableCallback(onReady);
73
+ const stableOnSubmit = useStableCallback(onSubmit);
74
+ const stableOnNavigate = useStableCallback(onNavigate);
75
+ const stableOnError = useStableCallback(onError);
76
+
77
+ const handleClose = useCallback(() => {
78
+ setInternalOpen(false);
79
+ if (isControlled) {
80
+ onOpenChange?.(false);
81
+ }
82
+ onClose?.();
83
+ }, [isControlled, onOpenChange, onClose]);
84
+
85
+ const stableOnClose = useStableCallback(handleClose);
86
+
87
+ useEffect(() => {
88
+ const newHandle = createFloatBubble({
89
+ researchId,
90
+ params,
91
+ brand,
92
+ theme,
93
+ host,
94
+ onReady: stableOnReady,
95
+ onSubmit: stableOnSubmit,
96
+ onNavigate: stableOnNavigate,
97
+ onClose: stableOnClose,
98
+ onError: stableOnError,
99
+ });
100
+
101
+ handleRef.current = newHandle;
102
+ setHandle(newHandle);
103
+
104
+ return () => {
105
+ if (handleRef.current === newHandle) {
106
+ newHandle.unmount();
107
+ handleRef.current = null;
108
+ setHandle(null);
109
+ }
110
+ };
111
+ }, [
112
+ researchId,
113
+ params,
114
+ brand,
115
+ theme,
116
+ host,
117
+ stableOnReady,
118
+ stableOnSubmit,
119
+ stableOnNavigate,
120
+ stableOnClose,
121
+ stableOnError,
122
+ ]);
123
+
124
+ useEffect(() => {
125
+ if (!isControlled || !handle) return;
126
+
127
+ if (controlledOpen && !handle.isOpen) {
128
+ handle.open();
129
+ } else if (!controlledOpen && handle.isOpen) {
130
+ handle.close();
131
+ }
132
+ }, [controlledOpen, isControlled, handle]);
133
+
134
+ const openFn = useCallback(() => {
135
+ if (isControlled) {
136
+ onOpenChange?.(true);
137
+ } else {
138
+ handleRef.current?.open();
139
+ setInternalOpen(true);
140
+ }
141
+ }, [isControlled, onOpenChange]);
142
+
143
+ const closeFn = useCallback(() => {
144
+ if (isControlled) {
145
+ onOpenChange?.(false);
146
+ } else {
147
+ handleRef.current?.close();
148
+ setInternalOpen(false);
149
+ }
150
+ }, [isControlled, onOpenChange]);
151
+
152
+ const toggleFn = useCallback(() => {
153
+ const currentlyOpen = handleRef.current?.isOpen ?? internalOpen;
154
+ if (currentlyOpen) {
155
+ closeFn();
156
+ } else {
157
+ openFn();
158
+ }
159
+ }, [internalOpen, openFn, closeFn]);
160
+
161
+ const unmountFn = useCallback(() => {
162
+ handleRef.current?.unmount();
163
+ handleRef.current = null;
164
+ setHandle(null);
165
+ setInternalOpen(false);
166
+ }, []);
167
+
168
+ const isOpen = isControlled
169
+ ? controlledOpen
170
+ : (handle?.isOpen ?? internalOpen);
171
+
172
+ return {
173
+ open: openFn,
174
+ close: closeFn,
175
+ toggle: toggleFn,
176
+ unmount: unmountFn,
177
+ isOpen,
178
+ handle,
179
+ };
180
+ }