@bootdesk/js-web-adapter-react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ChatWidget.tsx","../src/hooks/useChatClient.ts","../src/hooks/useMessages.ts","../src/hooks/useStreaming.ts","../src/hooks/useTyping.ts","../src/hooks/usePushNotifications.ts","../src/hooks/useAttachmentUpload.ts","../src/types/AttachmentUpload.ts","../src/hooks/useBridge.ts","../src/i18n/LocaleProvider.tsx","../src/i18n/types.ts","../src/i18n/locales/en.json","../src/i18n/locales/en-US.json","../src/i18n/locales/en-GB.json","../src/i18n/locales/pt.json","../src/i18n/locales/pt-BR.json","../src/i18n/locales/pt-PT.json","../src/i18n/locales/es.json","../src/i18n/mergeLocale.ts","../src/components/FloatingButton.tsx","../src/components/Header.tsx","../src/components/MessageList.tsx","../src/cards/CardContext.tsx","../src/utils/markdown.tsx","../src/cards/DefaultCard.tsx","../src/cards/ImageCard.tsx","../src/utils/formatSize.ts","../src/cards/FileCard.tsx","../src/cards/CardRenderer.tsx","../src/components/MessageContent.tsx","../src/utils/formatTimestamp.ts","../src/components/InputArea.tsx","../src/components/Dropzone.tsx","../src/components/AttachmentList.tsx","../src/components/TypingIndicator.tsx","../src/providers/ChatProvider.tsx","../src/components/ErrorBoundary.tsx","../src/components/PushPermissionPrompt.tsx","../src/components/PushToggle.tsx","../src/index.ts"],"sourcesContent":["import React, { useState, useCallback, useEffect } from \"react\";\nimport { WebChatClient } from \"@bootdesk/js-web-adapter-core\";\n\nimport { useBridge, useMessages, useTyping } from \"../hooks\";\nimport { FloatingButton } from \"./FloatingButton\";\nimport { Header } from \"./Header\";\nimport { MessageList } from \"./MessageList\";\nimport { InputArea } from \"./InputArea\";\nimport { TypingIndicator } from \"./TypingIndicator\";\n\ntype DisplayMode = \"floating\" | \"fullscreen\" | \"embedded\";\nexport type ThemeMode = \"light\" | \"dark\" | \"auto\";\n\nexport interface ChatWidgetProps {\n client: WebChatClient;\n initialMode?: DisplayMode;\n theme?: ThemeMode;\n onThemeChange?: (theme: ThemeMode) => void;\n position?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n className?: {\n container?: string;\n header?: string;\n messageList?: string;\n inputArea?: string;\n };\n showClose?: boolean;\n showFullscreenToggle?: boolean;\n title?: string;\n placeholder?: string;\n onOpen?: () => void;\n onClose?: () => void;\n embedded?: boolean;\n floatingButton?: {\n icon?: React.ReactNode;\n openIcon?: React.ReactNode;\n badgeCount?: number;\n size?: number;\n backgroundColor?: string;\n ariaLabel?: string;\n className?: string;\n };\n enableAttachments?: boolean;\n uploadConfig?: import(\"../types/AttachmentUpload\").UploadConfig;\n accept?: string;\n maxFileSize?: number;\n renderPushPrompt?: () => React.ReactNode;\n}\n\nexport function ChatWidget({\n client,\n initialMode = \"floating\",\n theme: themeProp,\n onThemeChange,\n position = \"bottom-right\",\n className,\n showClose = true,\n showFullscreenToggle = true,\n title = \"Chat\",\n placeholder = \"Type a message...\",\n onOpen,\n onClose,\n embedded,\n floatingButton,\n enableAttachments = false,\n uploadConfig,\n accept,\n maxFileSize,\n renderPushPrompt,\n}: ChatWidgetProps): React.JSX.Element {\n const {\n config: iframeConfig,\n isInIframe,\n notifyMessage,\n notifyViewportConfig,\n onNotificationClicked,\n } = useBridge();\n\n const autoEmbedded = isInIframe && embedded !== false;\n const effectiveEmbedded = embedded === true || autoEmbedded;\n const effectiveMode = effectiveEmbedded ? \"embedded\" : initialMode;\n\n const [theme, setTheme] = useState<ThemeMode>(() => {\n if (themeProp) return themeProp;\n try {\n const stored = localStorage.getItem(\"chat-theme\");\n if (stored === \"light\" || stored === \"dark\" || stored === \"auto\") return stored;\n } catch {}\n return \"auto\";\n });\n const [systemDark, setSystemDark] = useState(\n () =>\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-color-scheme: dark)\").matches,\n );\n\n const effectiveTheme: ThemeMode = theme === \"auto\" ? (systemDark ? \"dark\" : \"light\") : theme;\n\n useEffect(() => {\n if (themeProp && themeProp !== theme) {\n setTheme(themeProp);\n try {\n localStorage.setItem(\"chat-theme\", themeProp);\n } catch {}\n }\n }, [themeProp]);\n\n useEffect(() => {\n if (theme !== \"auto\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const handler = (e: MediaQueryListEvent) => setSystemDark(e.matches);\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [theme]);\n\n const handleThemeChange = (newTheme: ThemeMode): void => {\n setTheme(newTheme);\n try {\n localStorage.setItem(\"chat-theme\", newTheme);\n } catch {}\n onThemeChange?.(newTheme);\n };\n\n const [isOpen, setIsOpen] = useState(effectiveMode === \"fullscreen\");\n const [displayMode, setDisplayMode] = useState<DisplayMode>(effectiveMode);\n const [isConnected] = useState(true);\n\n const [isSmallScreen, setIsSmallScreen] = useState(\n () => typeof window !== \"undefined\" && window.innerWidth < 800,\n );\n\n useEffect(() => {\n const mq = window.matchMedia(\"(max-width: 799px)\");\n const handler = (e: MediaQueryListEvent) => {\n setIsSmallScreen(e.matches);\n if (e.matches) setDisplayMode(\"fullscreen\");\n };\n setIsSmallScreen(mq.matches);\n if (mq.matches) setDisplayMode(\"fullscreen\");\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, []);\n\n useEffect(() => {\n if (initialMode !== \"fullscreen\") return;\n if (!isSmallScreen) setIsOpen(true);\n }, [initialMode, isSmallScreen]);\n\n useEffect(() => {\n if (isInIframe) {\n notifyViewportConfig(\"interactive-widget=resizes-content\");\n return () => notifyViewportConfig(\"\");\n }\n\n const isFullscreen = displayMode === \"fullscreen\" || isSmallScreen;\n const active = isOpen && isFullscreen;\n\n const meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) return;\n\n if (active) {\n const original = meta.getAttribute(\"content\") ?? \"\";\n if (!original.includes(\"interactive-widget=\")) {\n meta.setAttribute(\"content\", `${original}, interactive-widget=resizes-content`);\n }\n return () => {\n meta.setAttribute(\"content\", original);\n };\n }\n }, [isOpen, displayMode, isSmallScreen, isInIframe, notifyViewportConfig]);\n\n const { messages, sendMessage, loading, isLoadingHistory, reloadMessages } = useMessages(\n client,\n isOpen || effectiveEmbedded,\n );\n const { isSomeoneTyping } = useTyping(client);\n\n useEffect(() => {\n if (!isInIframe || !iframeConfig) return;\n if (iframeConfig.theme?.cssVariables) {\n const root = document.documentElement;\n for (const [key, value] of Object.entries(iframeConfig.theme.cssVariables)) {\n root.style.setProperty(key, value as string);\n }\n }\n const mode = (iframeConfig as any).theme?.mode;\n if (mode === \"light\" || mode === \"dark\" || mode === \"auto\") {\n setTheme(mode);\n }\n }, [isInIframe, iframeConfig]);\n\n useEffect(() => {\n if (!isInIframe) return;\n onNotificationClicked(() => {\n reloadMessages();\n });\n }, [isInIframe, onNotificationClicked, reloadMessages]);\n\n const effectiveTitle = (isInIframe && iframeConfig?.title) || title;\n const effectivePlaceholder = (isInIframe && iframeConfig?.placeholder) || placeholder;\n\n const currentUserId = \"getCurrentUserId\" in client ? client.getCurrentUserId() : \"\";\n\n const handleSend = useCallback(\n async (\n text: string,\n attachments: Array<{ url: string; name: string; mimeType: string; size: number }> = [],\n ) => {\n await sendMessage(text, attachments);\n if (isInIframe) {\n notifyMessage(text);\n }\n },\n [sendMessage, isInIframe, notifyMessage],\n );\n\n const handleActionClick = useCallback(\n (messageId: string, actionId: string, value: string) => {\n client.sendAction(messageId, actionId, value).catch((err) => {\n console.error(\"Action failed:\", err);\n });\n },\n [client],\n );\n\n const handleReactionClick = useCallback((_messageId: string, _emoji: string) => {}, []);\n\n const toggleOpen = useCallback(() => {\n setIsOpen((prev) => {\n if (!prev) onOpen?.();\n else onClose?.();\n return !prev;\n });\n }, [onOpen, onClose]);\n\n const toggleFullscreen = useCallback(() => {\n setDisplayMode((prev) => (prev === \"fullscreen\" ? \"floating\" : \"fullscreen\"));\n }, []);\n\n const close = useCallback(() => {\n setIsOpen(false);\n setDisplayMode(\"floating\");\n onClose?.();\n }, [onClose]);\n\n const embeddedClose = useCallback(() => {\n if (isInIframe) {\n window.parent.postMessage({ type: \"chat-close\" }, \"*\");\n }\n }, [isInIframe]);\n\n if (effectiveEmbedded) {\n return (\n <div\n className=\"flex flex-col h-full min-h-[300px] overflow-hidden bg-chat-background\"\n data-chat-widget=\"embedded\"\n data-chat-theme={effectiveTheme}\n >\n <Header\n title={effectiveTitle}\n isFullscreen={false}\n showConnectionStatus\n isConnected={isConnected}\n className={className?.header}\n theme={theme}\n onThemeChange={handleThemeChange}\n onClose={isInIframe ? embeddedClose : undefined}\n />\n\n <MessageList\n messages={messages}\n currentUserId={currentUserId}\n isLoading={isLoadingHistory || loading}\n onActionClick={handleActionClick}\n onReactionClick={handleReactionClick}\n className={className?.messageList}\n />\n\n {isSomeoneTyping && <TypingIndicator />}\n\n {renderPushPrompt?.()}\n\n <InputArea\n onSend={handleSend}\n placeholder={effectivePlaceholder}\n className={className?.inputArea}\n enableAttachments={enableAttachments}\n uploadConfig={uploadConfig}\n accept={accept}\n maxFileSize={maxFileSize}\n />\n </div>\n );\n }\n\n return (\n <>\n {!effectiveEmbedded && !isOpen && (\n <FloatingButton\n onClick={toggleOpen}\n isOpen={isOpen}\n position={position}\n icon={floatingButton?.icon}\n openIcon={floatingButton?.openIcon}\n badgeCount={floatingButton?.badgeCount}\n size={floatingButton?.size}\n backgroundColor={floatingButton?.backgroundColor}\n ariaLabel={floatingButton?.ariaLabel}\n className={floatingButton?.className}\n />\n )}\n\n {isOpen && (\n <div\n className={`flex flex-col overflow-hidden ${\n displayMode === \"fullscreen\"\n ? \"fixed inset-0 z-50\"\n : `absolute ${position === \"bottom-right\" ? \"bottom-20 right-5\" : position === \"bottom-left\" ? \"bottom-20 left-5\" : \"\"} w-[480px] max-w-[min(800px,calc(100dvw-40px))] h-dvh max-h-[min(600px,80dvh)] z-10 shadow-xl border border-chat-border rounded-2xl`\n } bg-chat-background`}\n data-chat-widget={displayMode}\n data-chat-position={position}\n data-chat-theme={effectiveTheme}\n >\n <Header\n title={effectiveTitle}\n onClose={displayMode === \"floating\" ? close : showClose ? close : undefined}\n onToggleFullscreen={\n showFullscreenToggle && !isSmallScreen ? toggleFullscreen : undefined\n }\n isFullscreen={displayMode === \"fullscreen\"}\n showConnectionStatus\n isConnected={isConnected}\n className={className?.header}\n theme={theme}\n onThemeChange={handleThemeChange}\n />\n\n <MessageList\n messages={messages}\n currentUserId={currentUserId}\n isLoading={isLoadingHistory || loading}\n onActionClick={handleActionClick}\n onReactionClick={handleReactionClick}\n className={className?.messageList}\n />\n\n {isSomeoneTyping && <TypingIndicator />}\n\n {renderPushPrompt?.()}\n\n <InputArea\n onSend={handleSend}\n placeholder={effectivePlaceholder}\n disabled={loading}\n className={className?.inputArea}\n enableAttachments={enableAttachments}\n uploadConfig={uploadConfig}\n accept={accept}\n maxFileSize={maxFileSize}\n />\n </div>\n )}\n </>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { WebChatClient, WebChatClientConfig, BroadcastClient } from \"@bootdesk/js-web-adapter-core\";\n\nexport function useChatClient(\n config: Omit<WebChatClientConfig, \"broadcastClient\"> & {\n broadcastClient?: BroadcastClient;\n },\n): WebChatClient {\n const client = useMemo(() => new WebChatClient(config), [config]);\n\n useEffect(() => {\n client.connect().catch((error) => {\n console.error(\"Failed to connect chat client:\", error);\n });\n\n return () => {\n client.disconnect();\n };\n }, [client]);\n\n return client;\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\nimport { WebChatClient } from \"@bootdesk/js-web-adapter-core\";\nimport { Message } from \"@bootdesk/js-web-adapter-core\";\n\ninterface UseMessagesResult {\n messages: Message[];\n loading: boolean;\n isLoadingHistory: boolean;\n hasMore: boolean;\n loadMore: () => Promise<void>;\n reloadMessages: () => Promise<void>;\n retryLoad: () => Promise<void>;\n loadError: Error | null;\n canEdit: boolean;\n canDelete: boolean;\n canReact: boolean;\n sendMessage: (\n text: string,\n attachments?: Array<{\n url: string;\n name: string;\n mimeType: string;\n size: number;\n }>,\n ) => Promise<void>;\n editMessage: (id: string, text: string) => Promise<void>;\n deleteMessage: (id: string) => Promise<void>;\n addReaction: (id: string, emoji: string) => Promise<void>;\n removeReaction: (id: string, emoji: string) => Promise<void>;\n}\n\nexport function useMessages(client: WebChatClient, enabled = true): UseMessagesResult {\n const [messages, setMessages] = useState<Message[]>([]);\n const [loading, setLoading] = useState(false);\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\n const [hasMore, setHasMore] = useState(false);\n const [nextCursor, setNextCursor] = useState<number | undefined>(undefined);\n const [loadError, setLoadError] = useState<Error | null>(null);\n\n const abortRef = useRef<AbortController | null>(null);\n\n useEffect(() => {\n if (!enabled) return;\n\n if (abortRef.current) {\n abortRef.current.abort();\n }\n\n const controller = new AbortController();\n abortRef.current = controller;\n const { signal } = controller;\n\n setIsLoadingHistory(true);\n setLoadError(null);\n\n const loadInitial = async () => {\n try {\n const result = await client.loadMessages({ limit: 50, skipStateSeed: true }, signal);\n if (signal.aborted) return;\n setMessages(result.messages);\n setHasMore(result.hasMore);\n setNextCursor(result.nextCursor);\n } catch (error) {\n if (signal.aborted) return;\n setLoadError(error instanceof Error ? error : new Error(\"Failed to load messages\"));\n } finally {\n if (!signal.aborted) {\n setIsLoadingHistory(false);\n }\n }\n };\n\n loadInitial();\n\n return () => {\n controller.abort();\n if (abortRef.current === controller) {\n abortRef.current = null;\n }\n };\n }, [client, enabled]);\n\n const reloadMessages = useCallback(async () => {\n setIsLoadingHistory(true);\n setLoadError(null);\n try {\n const result = await client.loadMessages({ limit: 50, skipStateSeed: true });\n setMessages(result.messages);\n setHasMore(result.hasMore);\n setNextCursor(result.nextCursor);\n } catch (error) {\n setLoadError(error instanceof Error ? error : new Error(\"Failed to reload messages\"));\n } finally {\n setIsLoadingHistory(false);\n }\n }, [client]);\n\n const retryLoad = useCallback(async () => {\n setLoadError(null);\n setIsLoadingHistory(true);\n try {\n const result = await client.loadMessages({ limit: 50, skipStateSeed: true });\n setMessages(result.messages);\n setHasMore(result.hasMore);\n setNextCursor(result.nextCursor);\n } catch (error) {\n setLoadError(error instanceof Error ? error : new Error(\"Failed to load messages\"));\n } finally {\n setIsLoadingHistory(false);\n }\n }, [client]);\n\n useEffect(() => {\n const unsubscribes: Array<() => void> = [];\n\n unsubscribes.push(\n client.addEventListener(\"message:added\", (message: Message) => {\n setMessages((prev) => {\n if (prev.some((m) => m.id === message.id)) return prev;\n return [...prev, message];\n });\n }),\n );\n\n const features = client.getFeatures();\n if (features.editMessages) {\n unsubscribes.push(\n client.addEventListener(\n \"message:edited\",\n ({ messageId, newText }: { messageId: string; newText: string }) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === messageId ? { ...msg, content: { ...msg.content, text: newText } } : msg,\n ),\n );\n },\n ),\n );\n }\n\n if (features.deleteMessages) {\n unsubscribes.push(\n client.addEventListener(\"message:deleted\", ({ messageId }: { messageId: string }) => {\n setMessages((prev) => prev.filter((msg) => msg.id !== messageId));\n }),\n );\n }\n\n if (features.reactions) {\n unsubscribes.push(\n client.addEventListener(\n \"reaction:added\",\n ({ messageId, emoji }: { messageId: string; emoji: string }) => {\n setMessages((prev) =>\n prev.map((msg) => {\n if (msg.id !== messageId || !msg.reactions) return msg;\n const existing = msg.reactions.find((r) => r.emoji === emoji);\n if (existing) {\n return {\n ...msg,\n reactions: msg.reactions.map((r) =>\n r.emoji === emoji ? { ...r, count: r.count + 1 } : r,\n ),\n };\n }\n return {\n ...msg,\n reactions: [...msg.reactions, { emoji, count: 1, users: [] }],\n };\n }),\n );\n },\n ),\n );\n\n unsubscribes.push(\n client.addEventListener(\n \"reaction:removed\",\n ({ messageId, emoji }: { messageId: string; emoji: string }) => {\n setMessages((prev) =>\n prev.map((msg) => {\n if (msg.id !== messageId || !msg.reactions) return msg;\n const idx = msg.reactions.findIndex((r) => r.emoji === emoji);\n if (idx === -1) return msg;\n const updated = [...msg.reactions];\n if (updated[idx].count <= 1) {\n updated.splice(idx, 1);\n } else {\n updated[idx] = { ...updated[idx], count: updated[idx].count - 1 };\n }\n return { ...msg, reactions: updated };\n }),\n );\n },\n ),\n );\n }\n\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }, [client]);\n\n const sendMessage = useCallback(\n async (\n text: string,\n attachments?: Array<{\n url: string;\n name: string;\n mimeType: string;\n size: number;\n }>,\n ) => {\n setLoading(true);\n try {\n await client.sendMessage(text, attachments || []);\n } finally {\n setLoading(false);\n }\n },\n [client],\n );\n\n const editMessage = useCallback(\n async (id: string, text: string) => {\n if (!client.getFeatures().editMessages) {\n throw new Error(\"Edit messages not enabled. Set features.editMessages = true.\");\n }\n const endpoint = client.getEndpoints().editMessage || \"/api/chat/messages/{id}/edit\";\n await client.getHttpClient().editMessage(id, text, endpoint);\n setMessages((prev) =>\n prev.map((msg) => (msg.id === id ? { ...msg, content: { ...msg.content, text } } : msg)),\n );\n },\n [client],\n );\n\n const deleteMessage = useCallback(\n async (id: string) => {\n if (!client.getFeatures().deleteMessages) {\n throw new Error(\"Delete messages not enabled. Set features.deleteMessages = true.\");\n }\n const endpoint = client.getEndpoints().deleteMessage || \"/api/chat/messages/{id}\";\n await client.getHttpClient().deleteMessage(id, endpoint);\n setMessages((prev) => prev.filter((msg) => msg.id !== id));\n },\n [client],\n );\n\n const addReaction = useCallback(\n async (id: string, emoji: string) => {\n await client.addReaction(id, emoji);\n },\n [client],\n );\n\n const removeReaction = useCallback(\n async (id: string, emoji: string) => {\n await client.removeReaction(id, emoji);\n },\n [client],\n );\n\n const loadMore = useCallback(async () => {\n if (!nextCursor || isLoadingHistory) return;\n\n setIsLoadingHistory(true);\n try {\n const result = await client.loadMessages({\n limit: 50,\n before: nextCursor,\n });\n setMessages((prev) => [...result.messages, ...prev]);\n setHasMore(result.hasMore);\n setNextCursor(result.nextCursor);\n } catch (error) {\n console.error(\"Failed to load more messages:\", error);\n } finally {\n setIsLoadingHistory(false);\n }\n }, [client, nextCursor, isLoadingHistory]);\n\n const features = client.getFeatures();\n const canEdit = !!features.editMessages;\n const canDelete = !!features.deleteMessages;\n const canReact = !!features.reactions;\n\n return {\n messages,\n loading,\n isLoadingHistory,\n hasMore,\n loadMore,\n reloadMessages,\n retryLoad,\n loadError,\n canEdit,\n canDelete,\n canReact,\n sendMessage,\n editMessage,\n deleteMessage,\n addReaction,\n removeReaction,\n };\n}\n","import { useState, useEffect } from \"react\";\nimport { WebChatClient } from \"@bootdesk/js-web-adapter-core\";\n\ninterface StreamingState {\n messageId: string;\n fullText: string;\n isComplete: boolean;\n}\n\ninterface UseStreamingResult {\n streamingMessages: Map<string, StreamingState>;\n isStreaming: boolean;\n}\n\nexport function useStreaming(client: WebChatClient): UseStreamingResult {\n const [streamingMessages, setStreamingMessages] = useState<Map<string, StreamingState>>(\n new Map(),\n );\n\n useEffect(() => {\n const unsub = client.onStreamingChunk((event) => {\n setStreamingMessages((prev) => {\n const next = new Map(prev);\n\n const existing = next.get(event.messageId);\n const newText = (existing?.fullText || \"\") + event.chunk;\n\n if (event.isFinal) {\n next.delete(event.messageId);\n } else {\n next.set(event.messageId, {\n messageId: event.messageId,\n fullText: newText,\n isComplete: event.isFinal,\n });\n }\n\n return next;\n });\n });\n\n return unsub;\n }, [client]);\n\n const isStreaming = streamingMessages.size > 0;\n\n return { streamingMessages, isStreaming };\n}\n","import { useState, useEffect, useRef } from \"react\";\nimport { WebChatClient } from \"@bootdesk/js-web-adapter-core\";\n\ninterface UseTypingResult {\n typingUsers: Set<string>;\n isSomeoneTyping: boolean;\n}\n\nexport function useTyping(client: WebChatClient): UseTypingResult {\n const [typingUsers, setTypingUsers] = useState<Set<string>>(new Set());\n const timeoutsRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n useEffect(() => {\n const unsub = client.onTypingStarted((event) => {\n const existing = timeoutsRef.current.get(event.userId);\n if (existing) clearTimeout(existing);\n\n setTypingUsers((prev) => new Set(prev).add(event.userId));\n\n const timeoutId = setTimeout(() => {\n timeoutsRef.current.delete(event.userId);\n setTypingUsers((prev) => {\n const next = new Set(prev);\n next.delete(event.userId);\n return next;\n });\n }, 3000);\n\n timeoutsRef.current.set(event.userId, timeoutId);\n });\n\n return () => {\n unsub();\n for (const id of timeoutsRef.current.values()) {\n clearTimeout(id);\n }\n timeoutsRef.current.clear();\n };\n }, [client]);\n\n const isSomeoneTyping = typingUsers.size > 0;\n\n return { typingUsers, isSomeoneTyping };\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\nimport { PushManager, PushConfig, PushSubscriptionStatus } from \"@bootdesk/js-web-adapter-core\";\n\ninterface UsePushNotificationsOptions {\n enabled?: boolean;\n getVapidPublicKey: () => Promise<string>;\n onSubscribe: PushConfig[\"onSubscribe\"];\n onUnsubscribe: PushConfig[\"onUnsubscribe\"];\n serviceWorkerUrl?: string;\n notificationOptions?: PushConfig[\"notificationOptions\"];\n}\n\nexport function usePushNotifications(options: UsePushNotificationsOptions) {\n const { enabled = false } = options;\n const [status, setStatus] = useState<PushSubscriptionStatus>(\"unsupported\");\n const pushManagerRef = useRef<PushManager | null>(null);\n\n useEffect(() => {\n if (!enabled) return;\n\n const pushManager = new PushManager({\n getVapidPublicKey: options.getVapidPublicKey,\n onSubscribe: options.onSubscribe,\n onUnsubscribe: options.onUnsubscribe,\n serviceWorkerUrl: options.serviceWorkerUrl,\n notificationOptions: options.notificationOptions,\n });\n\n pushManagerRef.current = pushManager;\n\n const unsubscribeStatus = pushManager.onStatusChange(setStatus);\n\n pushManager.initialize();\n\n return () => {\n unsubscribeStatus();\n };\n }, [enabled]);\n\n const subscribe = useCallback(async () => {\n await pushManagerRef.current?.subscribe();\n }, []);\n\n const unsubscribe = useCallback(async () => {\n await pushManagerRef.current?.unsubscribe();\n }, []);\n\n return {\n status,\n isSupported: PushManager.isSupported(),\n isSubscribed: status === \"subscribed\",\n subscribe,\n unsubscribe,\n };\n}\n","import { useState, useCallback, useRef } from \"react\";\nimport { PendingAttachment, UploadConfig, isMultiStepUpload } from \"../types/AttachmentUpload\";\n\nfunction generateAttachmentId(): string {\n return `att-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\nexport function useAttachmentUpload(uploadConfig: UploadConfig) {\n const [attachments, setAttachments] = useState<PendingAttachment[]>([]);\n const abortControllers = useRef<Map<string, AbortController>>(new Map());\n const uploadFileRef = useRef<(attachment: PendingAttachment) => Promise<void>>();\n\n const addFiles = useCallback((files: FileList | File[]) => {\n const fileArray = Array.isArray(files) ? files : Array.from(files);\n\n const newAttachments: PendingAttachment[] = fileArray.map((file) => ({\n id: generateAttachmentId(),\n file,\n name: file.name,\n mimeType: file.type,\n size: file.size,\n status: \"pending\",\n progress: 0,\n }));\n\n setAttachments((prev) => [...prev, ...newAttachments]);\n\n newAttachments.forEach((att) => uploadFileRef.current?.(att));\n }, []);\n\n const uploadFile = useCallback(\n async (attachment: PendingAttachment) => {\n const controller = new AbortController();\n abortControllers.current.set(attachment.id, controller);\n\n try {\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === attachment.id ? { ...a, status: \"uploading\", progress: 0 } : a,\n ),\n );\n\n if (isMultiStepUpload(uploadConfig)) {\n const signedUrl = await uploadConfig.requestSignedUrl({\n name: attachment.name,\n mimeType: attachment.mimeType,\n size: attachment.size,\n });\n\n if (controller.signal.aborted) return;\n\n const uploadSuccess = await uploadConfig.uploadToSignedUrl(\n signedUrl,\n attachment.file,\n (progress) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === attachment.id ? { ...a, progress } : a)),\n );\n },\n );\n\n if (controller.signal.aborted) return;\n\n if (!uploadSuccess) {\n throw new Error(\"Upload to signed URL failed\");\n }\n\n const finalUrl = await uploadConfig.confirmUpload(signedUrl, {\n name: attachment.name,\n mimeType: attachment.mimeType,\n size: attachment.size,\n });\n\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === attachment.id\n ? { ...a, status: \"uploaded\", progress: 100, url: finalUrl }\n : a,\n ),\n );\n } else {\n const formData = new FormData();\n formData.append(\"file\", attachment.file);\n\n const xhr = new XMLHttpRequest();\n\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable) {\n const progress = Math.round((e.loaded / e.total) * 100);\n setAttachments((prev) =>\n prev.map((a) => (a.id === attachment.id ? { ...a, progress } : a)),\n );\n }\n });\n\n const response = await new Promise<{ url: string }>((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(JSON.parse(xhr.responseText));\n } else {\n reject(new Error(`Upload failed: ${xhr.status}`));\n }\n };\n xhr.onerror = () => reject(new Error(\"Network error\"));\n xhr.onabort = () => reject(new Error(\"Upload cancelled\"));\n\n xhr.open(\"POST\", uploadConfig.endpoint);\n if (uploadConfig.headers) {\n Object.entries(uploadConfig.headers).forEach(([key, value]) => {\n xhr.setRequestHeader(key, value);\n });\n }\n xhr.send(formData);\n });\n\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === attachment.id\n ? { ...a, status: \"uploaded\", progress: 100, url: response.url }\n : a,\n ),\n );\n }\n } catch (error) {\n if (controller.signal.aborted) return;\n\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === attachment.id\n ? {\n ...a,\n status: \"error\",\n error: error instanceof Error ? error.message : \"Upload failed\",\n }\n : a,\n ),\n );\n } finally {\n abortControllers.current.delete(attachment.id);\n }\n },\n [uploadConfig],\n );\n\n uploadFileRef.current = uploadFile;\n\n const removeAttachment = useCallback((id: string) => {\n const controller = abortControllers.current.get(id);\n if (controller) {\n controller.abort();\n }\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const clearAttachments = useCallback(() => {\n abortControllers.current.forEach((c) => c.abort());\n abortControllers.current.clear();\n setAttachments([]);\n }, []);\n\n const resetUploads = useCallback(() => {\n setAttachments((prev) =>\n prev.map((a) =>\n a.status === \"error\" ? { ...a, status: \"pending\", progress: 0, error: undefined } : a,\n ),\n );\n }, []);\n\n const getUploadedAttachments = useCallback(() => {\n return attachments.filter((a) => a.status === \"uploaded\" && a.url);\n }, [attachments]);\n\n const isUploading = attachments.some((a) => a.status === \"uploading\");\n\n const isComplete =\n attachments.length > 0 &&\n attachments.every((a) => a.status === \"uploaded\" || a.status === \"error\");\n\n return {\n attachments,\n addFiles,\n removeAttachment,\n clearAttachments,\n resetUploads,\n getUploadedAttachments,\n isUploading,\n isComplete,\n };\n}\n","export interface PendingAttachment {\n id: string;\n file: File;\n name: string;\n mimeType: string;\n size: number;\n status: \"pending\" | \"uploading\" | \"uploaded\" | \"error\";\n progress: number;\n url?: string;\n error?: string;\n}\n\nexport interface SignedUploadUrl {\n uploadUrl: string;\n finalUrl: string;\n headers?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AttachmentUploadConfig {\n requestSignedUrl: (file: {\n name: string;\n mimeType: string;\n size: number;\n }) => Promise<SignedUploadUrl>;\n uploadToSignedUrl: (\n signedUrl: SignedUploadUrl,\n file: File,\n onProgress?: (pct: number) => void,\n ) => Promise<boolean>;\n confirmUpload: (\n signedUrl: SignedUploadUrl,\n fileMeta: { name: string; mimeType: string; size: number },\n ) => Promise<string>;\n}\n\nexport interface SimpleUploadConfig {\n endpoint: string;\n headers?: Record<string, string>;\n}\n\nexport type UploadConfig = AttachmentUploadConfig | SimpleUploadConfig;\n\nexport function isMultiStepUpload(config: UploadConfig): config is AttachmentUploadConfig {\n return \"requestSignedUrl\" in config;\n}\n","import { useState, useCallback, useEffect, useRef } from \"react\";\n\ninterface BridgeResult {\n config: any;\n isInIframe: boolean;\n notifyMessage: (text: string) => void;\n notifyViewportConfig: (viewportContent: string) => void;\n onNotificationClicked: (cb: () => void) => void;\n}\n\nexport function useBridge(): BridgeResult {\n const notificationCbRef = useRef<(() => void) | null>(null);\n const [config, setConfig] = useState<any>(null);\n\n const isInIframe = typeof window !== \"undefined\" && window !== window.parent;\n\n const notifyMessage = useCallback(\n (text: string) => {\n if (!isInIframe) return;\n window.parent.postMessage({ type: \"chat-message\", text }, \"*\");\n },\n [isInIframe],\n );\n\n const notifyViewportConfig = useCallback(\n (viewportContent: string) => {\n if (!isInIframe) return;\n window.parent.postMessage({ type: \"chat-viewport-config\", content: viewportContent }, \"*\");\n },\n [isInIframe],\n );\n\n const onNotificationClicked = useCallback((cb: () => void) => {\n notificationCbRef.current = cb;\n }, []);\n\n useEffect(() => {\n if (!isInIframe) return;\n\n function handleMessage(event: MessageEvent) {\n const data = event.data as Record<string, unknown>;\n if (!data || typeof data !== \"object\" || !data.type) return;\n\n if (data.type === \"chat-config\") {\n const configData = { ...data };\n delete configData.type;\n setConfig(configData);\n }\n\n if (data.type === \"chat-notification-clicked\") {\n notificationCbRef.current?.();\n }\n }\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [isInIframe]);\n\n return { config, isInIframe, notifyMessage, notifyViewportConfig, onNotificationClicked };\n}\n","import React, { createContext, useContext, useMemo } from \"react\";\nimport { LocaleStrings, LocaleConfig } from \"./types\";\nimport { mergeLocale } from \"./mergeLocale\";\n\ninterface LocaleContextValue {\n locale: string;\n strings: LocaleStrings;\n t: (path: string) => string;\n}\n\nconst LocaleContext = createContext<LocaleContextValue | undefined>(undefined);\n\ninterface LocaleProviderProps {\n children: React.ReactNode;\n locale?: LocaleConfig | string;\n}\n\nexport function LocaleProvider({ children, locale }: LocaleProviderProps): React.JSX.Element {\n const config = useMemo<LocaleConfig>(() => {\n if (!locale) return { locale: \"en\" };\n if (typeof locale === \"string\") return { locale };\n return locale;\n }, [locale]);\n\n const value = useMemo(() => {\n const strings = mergeLocale(config.locale, config.overrides);\n\n const t = (path: string): string => {\n const parts = path.split(\".\");\n let current: any = strings;\n for (const part of parts) {\n if (current == null) return path;\n current = current[part];\n }\n return typeof current === \"string\" ? current : path;\n };\n\n return { locale: config.locale, strings, t };\n }, [config.locale, config.overrides]);\n\n return <LocaleContext.Provider value={value}>{children}</LocaleContext.Provider>;\n}\n\nexport function useLocale(): LocaleContextValue {\n const context = useContext(LocaleContext);\n if (!context) {\n const strings = mergeLocale(\"en\");\n return {\n locale: \"en\",\n strings,\n t: (path: string) => {\n const parts = path.split(\".\");\n let current: any = strings;\n for (const part of parts) {\n if (current == null) return path;\n current = current[part];\n }\n return typeof current === \"string\" ? current : path;\n },\n };\n }\n return context;\n}\n","export interface LocaleStrings {\n chatWidget: {\n title: string;\n placeholder: string;\n openChat: string;\n closeChat: string;\n connectionStatus: {\n connected: string;\n disconnected: string;\n };\n };\n inputArea: {\n send: string;\n uploading: string;\n dropzone: {\n dropFiles: string;\n dropOrClick: string;\n };\n };\n typingIndicator: {\n typing: string;\n isTyping: string;\n };\n messageList: {\n emptyState: string;\n };\n attachmentList: {\n remove: string;\n uploadFailed: string;\n };\n header: {\n enterFullscreen: string;\n exitFullscreen: string;\n closeChat: string;\n lightMode: string;\n darkMode: string;\n autoMode: string;\n };\n floatingButton: {\n openChat: string;\n closeChat: string;\n };\n common: {\n loading: string;\n error: string;\n retry: string;\n cancel: string;\n download: string;\n };\n}\n\nexport type SupportedLocale = \"en\" | \"en-US\" | \"en-GB\" | \"pt\" | \"pt-BR\" | \"pt-PT\" | \"es\";\n\nexport function getBaseLocale(locale: string): string {\n return locale.split(\"-\")[0] || locale;\n}\n\nexport function getFallbackChain(locale: string): string[] {\n const base = getBaseLocale(locale);\n if (locale === base) {\n return [locale, \"en\"];\n }\n return [locale, base, \"en\"];\n}\n\nexport type PartialLocaleStrings = Partial<{\n [K in keyof LocaleStrings]: Partial<LocaleStrings[K]>;\n}> & {\n chatWidget?: Partial<LocaleStrings[\"chatWidget\"]> & {\n connectionStatus?: Partial<LocaleStrings[\"chatWidget\"][\"connectionStatus\"]>;\n };\n inputArea?: Partial<LocaleStrings[\"inputArea\"]> & {\n dropzone?: Partial<LocaleStrings[\"inputArea\"][\"dropzone\"]>;\n };\n messageList?: Partial<LocaleStrings[\"messageList\"]>;\n common?: Partial<LocaleStrings[\"common\"]>;\n};\n\nexport interface LocaleConfig {\n locale: string;\n overrides?: PartialLocaleStrings;\n}\n","{\n \"chatWidget\": {\n \"title\": \"Chat\",\n \"placeholder\": \"Type a message...\",\n \"openChat\": \"Open chat\",\n \"closeChat\": \"Close chat\",\n \"connectionStatus\": {\n \"connected\": \"Connected\",\n \"disconnected\": \"Disconnected\"\n }\n },\n \"inputArea\": {\n \"send\": \"Send\",\n \"uploading\": \"Uploading...\",\n \"dropzone\": {\n \"dropFiles\": \"Drop files here\",\n \"dropOrClick\": \"Drop or click to attach\"\n }\n },\n \"typingIndicator\": {\n \"typing\": \"typing\",\n \"isTyping\": \"is typing...\"\n },\n \"messageList\": {\n \"emptyState\": \"No messages yet. Start the conversation!\"\n },\n \"attachmentList\": {\n \"remove\": \"Remove\",\n \"uploadFailed\": \"Upload failed\"\n },\n \"header\": {\n \"enterFullscreen\": \"Enter fullscreen\",\n \"exitFullscreen\": \"Exit fullscreen\",\n \"closeChat\": \"Close chat\",\n \"lightMode\": \"Light mode\",\n \"darkMode\": \"Dark mode\",\n \"autoMode\": \"System theme\"\n },\n \"floatingButton\": {\n \"openChat\": \"Open chat\",\n \"closeChat\": \"Close chat\"\n },\n \"common\": {\n \"loading\": \"Loading...\",\n \"error\": \"Error\",\n \"retry\": \"Retry\",\n \"cancel\": \"Cancel\",\n \"download\": \"Download\"\n }\n}\n","{\n \"chatWidget\": {\n \"title\": \"Chat\"\n }\n}\n","{\n \"chatWidget\": {\n \"title\": \"Chat\"\n },\n \"common\": {\n \"loading\": \"Loading...\"\n }\n}\n","{\n \"chatWidget\": {\n \"title\": \"Chat\",\n \"placeholder\": \"Digite uma mensagem...\",\n \"openChat\": \"Abrir chat\",\n \"closeChat\": \"Fechar chat\",\n \"connectionStatus\": {\n \"connected\": \"Conectado\",\n \"disconnected\": \"Desconectado\"\n }\n },\n \"inputArea\": {\n \"send\": \"Enviar\",\n \"uploading\": \"Enviando...\",\n \"dropzone\": {\n \"dropFiles\": \"Solte arquivos aqui\",\n \"dropOrClick\": \"Solte ou clique para anexar\"\n }\n },\n \"typingIndicator\": {\n \"typing\": \"digitando\",\n \"isTyping\": \"está digitando...\"\n },\n \"messageList\": {\n \"emptyState\": \"Nenhuma mensagem ainda. Inicie a conversa!\"\n },\n \"attachmentList\": {\n \"remove\": \"Remover\",\n \"uploadFailed\": \"Falha no envio\"\n },\n \"header\": {\n \"enterFullscreen\": \"Tela cheia\",\n \"exitFullscreen\": \"Sair da tela cheia\",\n \"closeChat\": \"Fechar chat\"\n },\n \"floatingButton\": {\n \"openChat\": \"Abrir chat\",\n \"closeChat\": \"Fechar chat\"\n },\n \"common\": {\n \"loading\": \"Carregando...\",\n \"error\": \"Erro\",\n \"retry\": \"Tentar novamente\",\n \"cancel\": \"Cancelar\",\n \"download\": \"Baixar\"\n }\n}\n","{\n \"chatWidget\": {\n \"placeholder\": \"Digite uma mensagem...\"\n },\n \"inputArea\": {\n \"send\": \"Enviar\",\n \"uploading\": \"Enviando...\",\n \"dropzone\": {\n \"dropFiles\": \"Solte arquivos aqui\",\n \"dropOrClick\": \"Solte ou clique para anexar\"\n }\n },\n \"typingIndicator\": {\n \"isTyping\": \"está digitando...\"\n },\n \"attachmentList\": {\n \"uploadFailed\": \"Falha no envio\"\n },\n \"common\": {\n \"loading\": \"Carregando...\",\n \"retry\": \"Tentar novamente\"\n }\n}\n","{\n \"chatWidget\": {\n \"placeholder\": \"Escreva uma mensagem...\"\n },\n \"inputArea\": {\n \"send\": \"Enviar\",\n \"uploading\": \"A enviar...\",\n \"dropzone\": {\n \"dropFiles\": \"Largue ficheiros aqui\",\n \"dropOrClick\": \"Largue ou clique para anexar\"\n }\n },\n \"typingIndicator\": {\n \"isTyping\": \"está a escrever...\"\n },\n \"attachmentList\": {\n \"uploadFailed\": \"Falha no envio\"\n },\n \"common\": {\n \"loading\": \"A carregar...\",\n \"retry\": \"Tentar novamente\"\n }\n}\n","{\n \"chatWidget\": {\n \"title\": \"Chat\",\n \"placeholder\": \"Escribe un mensaje...\",\n \"openChat\": \"Abrir chat\",\n \"closeChat\": \"Cerrar chat\",\n \"connectionStatus\": {\n \"connected\": \"Conectado\",\n \"disconnected\": \"Desconectado\"\n }\n },\n \"inputArea\": {\n \"send\": \"Enviar\",\n \"uploading\": \"Subiendo...\",\n \"dropzone\": {\n \"dropFiles\": \"Suelta archivos aquí\",\n \"dropOrClick\": \"Suelta o haz clic para adjuntar\"\n }\n },\n \"typingIndicator\": {\n \"typing\": \"escribiendo\",\n \"isTyping\": \"está escribiendo...\"\n },\n \"messageList\": {\n \"emptyState\": \"No hay mensajes todavía. ¡Inicia la conversación!\"\n },\n \"attachmentList\": {\n \"remove\": \"Eliminar\",\n \"uploadFailed\": \"Error al subir\"\n },\n \"header\": {\n \"enterFullscreen\": \"Pantalla completa\",\n \"exitFullscreen\": \"Salir de pantalla completa\",\n \"closeChat\": \"Cerrar chat\"\n },\n \"floatingButton\": {\n \"openChat\": \"Abrir chat\",\n \"closeChat\": \"Cerrar chat\"\n },\n \"common\": {\n \"loading\": \"Cargando...\",\n \"error\": \"Error\",\n \"retry\": \"Reintentar\",\n \"cancel\": \"Cancelar\",\n \"download\": \"Descargar\"\n }\n}\n","import { LocaleStrings, PartialLocaleStrings, getFallbackChain } from \"./types\";\nimport en from \"./locales/en.json\";\nimport enUS from \"./locales/en-US.json\";\nimport enGB from \"./locales/en-GB.json\";\nimport pt from \"./locales/pt.json\";\nimport ptBR from \"./locales/pt-BR.json\";\nimport ptPT from \"./locales/pt-PT.json\";\nimport es from \"./locales/es.json\";\n\nfunction deepMerge(target: Record<string, any>, source: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = { ...target };\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n targetVal &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(targetVal, sourceVal);\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n\nconst systemLocales: Record<string, LocaleStrings> = {\n en: en as LocaleStrings,\n \"en-US\": deepMerge(en as LocaleStrings, enUS as Partial<LocaleStrings>) as LocaleStrings,\n \"en-GB\": deepMerge(en as LocaleStrings, enGB as Partial<LocaleStrings>) as LocaleStrings,\n pt: pt as LocaleStrings,\n \"pt-BR\": deepMerge(pt as LocaleStrings, ptBR as Partial<LocaleStrings>) as LocaleStrings,\n \"pt-PT\": deepMerge(pt as LocaleStrings, ptPT as Partial<LocaleStrings>) as LocaleStrings,\n es: es as LocaleStrings,\n};\n\nexport function registerLocale(locale: string, strings: LocaleStrings): void {\n systemLocales[locale] = strings;\n}\n\nexport function mergeLocale(locale: string, overrides?: PartialLocaleStrings): LocaleStrings {\n const chain = getFallbackChain(locale);\n\n let base = systemLocales[\"en\"] || (en as LocaleStrings);\n\n for (const code of chain) {\n if (code === \"en\") continue;\n const localeStrings = systemLocales[code];\n if (localeStrings) {\n base = deepMerge(base, localeStrings) as unknown as LocaleStrings;\n }\n }\n\n if (!overrides) return base;\n\n return deepMerge(base, overrides) as LocaleStrings;\n}\n\nexport function getAvailableLocales(): string[] {\n return Object.keys(systemLocales);\n}\n","import React from \"react\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\n\ninterface FloatingButtonProps {\n onClick: () => void;\n isOpen: boolean;\n position?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n className?: string;\n icon?: React.ReactNode;\n openIcon?: React.ReactNode;\n badgeCount?: number;\n size?: number;\n backgroundColor?: string;\n ariaLabel?: string;\n}\n\nexport function FloatingButton({\n onClick,\n isOpen,\n position = \"bottom-right\",\n className,\n icon,\n openIcon,\n badgeCount,\n size = 60,\n backgroundColor,\n ariaLabel,\n}: FloatingButtonProps): React.JSX.Element {\n const { t } = useLocale();\n\n const positionClasses: Record<string, string> = {\n \"bottom-right\": \"fixed bottom-5 right-5\",\n \"bottom-left\": \"fixed bottom-5 left-5\",\n \"top-right\": \"fixed top-5 right-5\",\n \"top-left\": \"fixed top-5 left-5\",\n };\n\n const iconSize = Math.floor(size * 0.4);\n\n return (\n <button\n onClick={onClick}\n className={`${positionClasses[position]} chat-floating-button hover:scale-105 transition-transform ${className || \"\"}`}\n style={{ width: size, height: size, backgroundColor }}\n data-chat-floating-button=\"true\"\n data-testid=\"chat-floating-button\"\n aria-label={\n ariaLabel || (isOpen ? t(\"floatingButton.closeChat\") : t(\"floatingButton.openChat\"))\n }\n >\n {badgeCount && badgeCount > 0 && (\n <span\n className=\"absolute -top-1 -right-1 min-w-5 h-5 rounded-full bg-chat-error text-white text-xs font-bold flex items-center justify-center px-1\"\n data-chat-badge=\"true\"\n >\n {badgeCount > 99 ? \"99+\" : badgeCount}\n </span>\n )}\n\n {isOpen\n ? openIcon ||\n icon || (\n <svg\n width={iconSize}\n height={iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#fff\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n )\n : icon || (\n <svg\n width={iconSize}\n height={iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#fff\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n )}\n </button>\n );\n}\n","import React from \"react\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\n\ninterface HeaderProps {\n title?: string;\n onClose?: () => void;\n onToggleFullscreen?: () => void;\n isFullscreen?: boolean;\n showConnectionStatus?: boolean;\n isConnected?: boolean;\n className?: string;\n theme?: string;\n onThemeChange?: (theme: \"light\" | \"dark\" | \"auto\") => void;\n}\n\nexport function Header({\n title = \"Chat\",\n onClose,\n onToggleFullscreen,\n isFullscreen = false,\n showConnectionStatus = true,\n isConnected = true,\n className,\n theme,\n onThemeChange,\n}: HeaderProps): React.JSX.Element {\n const { t } = useLocale();\n\n return (\n <div\n className={`chat-header ${className || \"\"}`}\n data-chat-header=\"true\"\n data-testid=\"chat-header\"\n >\n <div className=\"flex items-center gap-2\">\n {showConnectionStatus && (\n <div\n className={`w-2 h-2 rounded-full ${isConnected ? \"bg-chat-success\" : \"bg-chat-error\"}`}\n data-chat-connection-status=\"true\"\n title={isConnected ? \"Connected\" : \"Disconnected\"}\n />\n )}\n <h2 className=\"m-0 text-base font-semibold text-chat-text\">{title}</h2>\n </div>\n\n <div className=\"flex items-center gap-1\">\n {onThemeChange && (\n <button\n onClick={() =>\n onThemeChange(theme === \"light\" ? \"dark\" : theme === \"dark\" ? \"auto\" : \"light\")\n }\n className=\"p-1 bg-transparent border-none cursor-pointer text-chat-text-secondary rounded hover:bg-chat-surface transition\"\n data-chat-theme-toggle=\"true\"\n aria-label={\n theme === \"light\"\n ? t(\"header.darkMode\")\n : theme === \"dark\"\n ? t(\"header.autoMode\")\n : t(\"header.lightMode\")\n }\n title={\n theme === \"light\"\n ? t(\"header.darkMode\")\n : theme === \"dark\"\n ? t(\"header.autoMode\")\n : t(\"header.lightMode\")\n }\n >\n {theme === \"light\" ? (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n ) : theme === \"dark\" ? (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\" />\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\" />\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\" />\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\" />\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\" />\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\" />\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\" />\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\" />\n </svg>\n ) : (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\" />\n <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\" />\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\" />\n </svg>\n )}\n </button>\n )}\n\n {onToggleFullscreen && (\n <button\n onClick={onToggleFullscreen}\n className=\"p-1 bg-transparent border-none cursor-pointer text-chat-text-secondary rounded hover:bg-chat-surface transition\"\n data-chat-fullscreen-toggle=\"true\"\n aria-label={isFullscreen ? t(\"header.exitFullscreen\") : t(\"header.enterFullscreen\")}\n title={isFullscreen ? t(\"header.exitFullscreen\") : t(\"header.enterFullscreen\")}\n >\n {isFullscreen ? (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\" />\n </svg>\n ) : (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\" />\n </svg>\n )}\n </button>\n )}\n\n {onClose && (\n <button\n onClick={onClose}\n className=\"p-1 bg-transparent border-none cursor-pointer text-chat-text-secondary rounded hover:bg-chat-surface transition\"\n data-chat-close=\"true\"\n aria-label={t(\"header.closeChat\")}\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n );\n}\n","import React, { useRef, useEffect, useMemo } from \"react\";\nimport { Message } from \"@bootdesk/js-web-adapter-core\";\nimport { MessageContent } from \"./MessageContent\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\nimport { formatTimestamp } from \"../utils/formatTimestamp\";\n\ninterface MessageListProps {\n messages: Message[];\n currentUserId: string;\n isLoading?: boolean;\n onReactionClick?: (messageId: string, emoji: string) => void;\n onActionClick?: (messageId: string, actionId: string, value: string) => void;\n className?: string;\n}\n\nexport function MessageList({\n messages,\n currentUserId,\n isLoading = false,\n onReactionClick,\n onActionClick,\n className,\n}: MessageListProps): React.JSX.Element {\n const { t } = useLocale();\n const containerRef = useRef<HTMLDivElement>(null);\n const listEndRef = useRef<HTMLDivElement>(null);\n const hasInitiallyScrolled = useRef(false);\n const isNearBottom = useRef(true);\n\n useEffect(() => {\n if (!hasInitiallyScrolled.current && messages.length > 0) {\n listEndRef.current?.scrollIntoView?.();\n hasInitiallyScrolled.current = true;\n }\n }, [messages.length]);\n\n const prevMessagesLength = useRef(messages.length);\n\n useEffect(() => {\n if (messages.length > prevMessagesLength.current) {\n listEndRef.current?.scrollIntoView?.({ behavior: \"smooth\" });\n }\n prevMessagesLength.current = messages.length;\n }, [messages.length]);\n\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const handleScroll = () => {\n const threshold = 100;\n isNearBottom.current = el.scrollHeight - el.scrollTop - el.clientHeight < threshold;\n };\n\n el.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n const observer = new ResizeObserver(() => {\n if (isNearBottom.current) {\n listEndRef.current?.scrollIntoView?.({ behavior: \"smooth\" });\n }\n });\n\n observer.observe(el);\n\n return () => {\n el.removeEventListener(\"scroll\", handleScroll);\n observer.disconnect();\n };\n }, []);\n\n const groupedMessages = useMemo(() => {\n const groups: Array<{ user: string; messages: Message[] }> = [];\n let currentGroup: { user: string; messages: Message[] } | null = null;\n\n for (const message of messages) {\n const userId = message.author.id;\n\n if (!currentGroup || currentGroup.user !== userId) {\n if (currentGroup) {\n groups.push(currentGroup);\n }\n currentGroup = { user: userId, messages: [message] };\n } else {\n currentGroup.messages.push(message);\n }\n }\n\n if (currentGroup) {\n groups.push(currentGroup);\n }\n\n return groups;\n }, [messages]);\n\n return (\n <div\n ref={containerRef}\n className={`chat-message-list flex-1 min-h-0 overflow-y-auto ${className || \"\"}`}\n data-chat-message-list=\"true\"\n data-testid=\"chat-message-list\"\n >\n {groupedMessages.length === 0 && !isLoading && (\n <div className=\"flex flex-col items-center justify-center h-full min-h-[200px] text-center px-6\">\n <div className=\"text-chat-text-secondary text-sm\">{t(\"messageList.emptyState\")}</div>\n </div>\n )}\n\n {groupedMessages.map((group, groupIndex) => {\n const isOwn = group.user === currentUserId;\n const firstMessage = group.messages[0]!;\n\n return (\n <div key={`${group.user}-${groupIndex}`} className=\"flex flex-col gap-1\">\n {firstMessage.author.name && (\n <div className=\"text-xs text-chat-text-secondary\">{firstMessage.author.name}</div>\n )}\n\n {group.messages.map((message, msgIndex) => (\n <div key={message.id} className=\"flex flex-col\" data-chat-message-id={message.id}>\n <div className={isOwn ? \"chat-message-bubble-own\" : \"chat-message-bubble-other\"}>\n <MessageContent message={message} onActionClick={onActionClick} />\n </div>\n\n {message.reactions && message.reactions.length > 0 && (\n <div className=\"flex gap-1 mt-1\">\n {message.reactions.map((reaction, rIndex) => (\n <button\n key={`${reaction.emoji}-${rIndex}`}\n onClick={() => onReactionClick?.(message.id, reaction.emoji)}\n className={`flex items-center gap-1 px-2 py-0.5 border border-chat-border rounded-full text-sm cursor-pointer transition ${\n reaction.hasReacted\n ? \"bg-chat-surface\"\n : \"bg-transparent hover:bg-chat-surface\"\n }`}\n data-chat-reaction={reaction.emoji}\n >\n <span>{reaction.emoji}</span>\n <span className=\"text-chat-text-secondary\">{reaction.count}</span>\n </button>\n ))}\n </div>\n )}\n\n {msgIndex === 0 && (\n <div className=\"text-xs text-chat-text-secondary mt-1\">\n {formatTimestamp(message.timestamp)}\n </div>\n )}\n </div>\n ))}\n </div>\n );\n })}\n\n {isLoading && groupedMessages.length === 0 && (\n <div className=\"flex items-center justify-center min-h-[200px]\" data-chat-loading=\"true\">\n <div className=\"flex gap-1.5\">\n <span\n className=\"w-2 h-2 rounded-full bg-chat-text-secondary animate-bounce\"\n style={{ animationDelay: \"0ms\" }}\n />\n <span\n className=\"w-2 h-2 rounded-full bg-chat-text-secondary animate-bounce\"\n style={{ animationDelay: \"160ms\" }}\n />\n <span\n className=\"w-2 h-2 rounded-full bg-chat-text-secondary animate-bounce\"\n style={{ animationDelay: \"320ms\" }}\n />\n </div>\n </div>\n )}\n\n {isLoading && groupedMessages.length > 0 && (\n <div className=\"flex justify-center py-4\" data-chat-loading=\"true\">\n <div className=\"text-chat-text-secondary\">{t(\"common.loading\")}</div>\n </div>\n )}\n\n <div ref={listEndRef} className=\"h-px\" />\n </div>\n );\n}\n","import React, { createContext, useContext, useMemo } from \"react\";\nimport { CardRenderer, CardRendererMap } from \"./types\";\nimport { DefaultCard } from \"./DefaultCard\";\nimport { ImageCardComponent } from \"./ImageCard\";\nimport { FileCardComponent } from \"./FileCard\";\n\ninterface CardContextValue {\n renderers: CardRendererMap;\n registerRenderer: (type: string, renderer: CardRenderer) => void;\n getRenderer: (type: string) => CardRenderer | undefined;\n}\n\nconst CardContext = createContext<CardContextValue | undefined>(undefined);\n\ninterface CardProviderProps {\n children: React.ReactNode;\n renderers?: Record<string, CardRenderer>;\n}\n\nexport function CardProvider({ children, renderers }: CardProviderProps): React.JSX.Element {\n const value = useMemo(() => {\n const defaultRenderers: CardRendererMap = new Map([\n [\"card\", DefaultCard],\n [\"image\", ImageCardComponent],\n [\"file\", FileCardComponent],\n ]);\n\n if (renderers) {\n Object.entries(renderers).forEach(([type, renderer]) => {\n defaultRenderers.set(type, renderer);\n });\n }\n\n return {\n renderers: defaultRenderers,\n registerRenderer: (type: string, renderer: CardRenderer) => {\n defaultRenderers.set(type, renderer);\n },\n getRenderer: (type: string) => {\n return defaultRenderers.get(type);\n },\n };\n }, [renderers]);\n\n return <CardContext.Provider value={value}>{children}</CardContext.Provider>;\n}\n\nexport function useCardRegistry() {\n const context = useContext(CardContext);\n if (!context) {\n throw new Error(\"useCardRegistry must be used within CardProvider\");\n }\n return context;\n}\n","import React from \"react\";\nimport { marked } from \"marked\";\nimport DOMPurify from \"dompurify\";\n\nconst renderer = new marked.Renderer();\nrenderer.link = ({ href, text }): string => {\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${text}</a>`;\n};\n\nmarked.setOptions({\n gfm: true,\n breaks: true,\n renderer,\n});\n\nexport function renderMarkdown(text: string): string {\n const rawHtml = marked.parse(text) as string;\n return DOMPurify.sanitize(rawHtml, { ADD_ATTR: [\"target\"] });\n}\n\nexport function MarkdownRenderer({\n text,\n className,\n}: {\n text: string;\n className?: string;\n}): React.JSX.Element {\n return (\n <div\n className={`prose prose-sm max-w-none prose-headings:font-semibold prose-a:text-chat-primary prose-a:no-underline hover:prose-a:underline prose-code:bg-chat-surface prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-code:font-mono prose-code:text-sm prose-blockquote:border-l-chat-border prose-blockquote:text-chat-text-secondary ${className || \"\"}`}\n dangerouslySetInnerHTML={{ __html: renderMarkdown(text) }}\n />\n );\n}\n","import React from \"react\";\nimport { PHPCard } from \"@bootdesk/js-web-adapter-core\";\nimport { CardRendererProps } from \"./types\";\nimport { MarkdownRenderer } from \"../utils/markdown\";\n\nexport function DefaultCard({\n card: rawCard,\n onActionClick,\n}: CardRendererProps): React.JSX.Element | null {\n if (rawCard.type !== \"card\") {\n return null;\n }\n\n const card = rawCard as PHPCard;\n\n return (\n <div\n className=\"border border-chat-border rounded-lg overflow-hidden max-w-sm bg-[var(--chat-background)]\"\n data-chat-card=\"default\"\n >\n {card.header && (\n <div className=\"px-3 py-2 bg-chat-surface border-b border-chat-border font-semibold text-sm\">\n <MarkdownRenderer text={card.header} />\n </div>\n )}\n\n {card.image && (\n <img\n src={card.image.url}\n alt={card.image.alt || \"\"}\n className=\"block w-full h-auto max-h-48 object-cover\"\n data-chat-card-image=\"true\"\n />\n )}\n\n {card.sections?.map((section, index) => (\n <div key={index} className=\"px-3 py-2\" data-chat-section={index}>\n {section.text && (\n <div className=\"mb-2 text-sm leading-relaxed\">\n <MarkdownRenderer text={section.text} />\n </div>\n )}\n\n {section.fields?.map((field, fieldIndex) => (\n <div key={fieldIndex} className=\"mb-1 last:mb-0\" data-chat-field={fieldIndex}>\n {field.title && (\n <div className=\"text-xs text-chat-text-secondary font-medium\">{field.title}</div>\n )}\n <div className=\"text-sm text-chat-text\">{field.value}</div>\n </div>\n ))}\n </div>\n ))}\n\n {card.elements?.map((element, elIndex) => {\n switch (element.type) {\n case \"text\":\n return (\n <div\n key={`el-${elIndex}`}\n className={`px-3 py-2 text-sm ${\n element.style === \"muted\"\n ? \"text-chat-text-secondary\"\n : element.style === \"bold\"\n ? \"text-chat-text font-bold\"\n : \"text-chat-text\"\n }`}\n >\n <MarkdownRenderer text={element.content} />\n </div>\n );\n case \"divider\":\n return <hr key={`el-${elIndex}`} className=\"border-0 border-t border-chat-border\" />;\n case \"link\":\n return (\n <a\n key={`el-${elIndex}`}\n href={element.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block px-3 py-2 text-chat-primary text-sm no-underline hover:underline\"\n >\n {element.label}\n </a>\n );\n case \"table\":\n return (\n <table key={`el-${elIndex}`} className=\"w-full border-collapse text-xs\">\n {element.headers.length > 0 && (\n <thead>\n <tr>\n {element.headers.map((h, i) => (\n <th\n key={i}\n className=\"px-2 py-1 text-left border-b border-chat-border font-semibold\"\n >\n {h}\n </th>\n ))}\n </tr>\n </thead>\n )}\n <tbody>\n {element.rows.map((row, rIdx) => (\n <tr key={rIdx}>\n {row.map((cell, cIdx) => (\n <td key={cIdx} className=\"px-2 py-1 border-b border-chat-border\">\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n );\n case \"link_button\":\n return (\n <a\n key={`el-${elIndex}`}\n href={element.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`block px-2 py-1.5 mx-2 my-1 rounded text-sm font-medium text-center no-underline ${\n element.style === \"primary\"\n ? \"bg-chat-primary text-white\"\n : element.style === \"danger\"\n ? \"bg-chat-error text-white\"\n : \"bg-chat-surface text-chat-text hover:bg-chat-background\"\n }`}\n >\n {element.label}\n </a>\n );\n case \"image\":\n return (\n <img\n key={`el-${elIndex}`}\n src={element.url}\n alt={element.alt || \"\"}\n className=\"block w-full h-auto max-h-36 object-cover\"\n />\n );\n default:\n return null;\n }\n })}\n\n {card.actions && card.actions.length > 0 && (\n <div className=\"flex flex-wrap gap-2 px-3 py-2\" data-chat-actions=\"true\">\n {card.actions.map((action) => (\n <button\n key={action.id}\n onClick={() => onActionClick?.(action.id, action.value || \"\")}\n className={`px-3 py-1.5 border border-chat-border rounded text-sm font-medium transition cursor-pointer ${\n action.style === \"primary\"\n ? \"bg-chat-primary text-white border-transparent hover:bg-chat-primary-hover\"\n : action.style === \"danger\"\n ? \"bg-chat-error text-white border-transparent hover:opacity-90\"\n : \"bg-chat-surface text-chat-text hover:bg-chat-background\"\n }`}\n data-chat-action={action.id}\n >\n {action.label}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport { ImageCard as ImageCardType } from \"@bootdesk/js-web-adapter-core\";\nimport { CardRendererProps } from \"./types\";\n\nexport function ImageCardComponent({ card: rawCard }: CardRendererProps): React.JSX.Element | null {\n if (rawCard.type !== \"image\") {\n return null;\n }\n\n const card = rawCard as ImageCardType;\n\n return (\n <div className=\"rounded-lg overflow-hidden max-w-full\" data-chat-card=\"image\">\n <img\n src={card.url}\n alt={card.alt || \"\"}\n className=\"block max-w-full h-auto\"\n data-chat-image=\"true\"\n />\n {card.title && <div className=\"px-3 py-2 text-sm bg-chat-surface\">{card.title}</div>}\n </div>\n );\n}\n","export function formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import React from \"react\";\nimport { FileCard as FileCardType } from \"@bootdesk/js-web-adapter-core\";\nimport { CardRendererProps } from \"./types\";\nimport { formatSize } from \"../utils/formatSize\";\n\nexport function FileCardComponent({ card: rawCard }: CardRendererProps): React.JSX.Element | null {\n if (rawCard.type !== \"file\") {\n return null;\n }\n\n const card = rawCard as FileCardType;\n\n return (\n <div\n className=\"flex items-center gap-3 p-3 border border-chat-border rounded-lg max-w-xs\"\n data-chat-card=\"file\"\n >\n <div className=\"w-10 h-10 flex items-center justify-center bg-chat-surface rounded\">📄</div>\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">{card.name}</div>\n {card.size && (\n <div className=\"text-xs text-chat-text-secondary\">{formatSize(card.size)}</div>\n )}\n </div>\n\n <a\n href={card.url}\n download={card.name}\n className=\"px-3 py-2 bg-chat-primary text-white rounded text-sm font-medium no-underline hover:opacity-90\"\n data-chat-file-download=\"true\"\n >\n Download\n </a>\n </div>\n );\n}\n","import React from \"react\";\nimport { Card, CustomCard } from \"@bootdesk/js-web-adapter-core\";\nimport { CardRendererProps } from \"./types\";\nimport { useCardRegistry } from \"./CardContext\";\nimport { DefaultCard } from \"./DefaultCard\";\n\nexport function CardRenderer({ card, onActionClick }: CardRendererProps): React.JSX.Element | null {\n const { getRenderer } = useCardRegistry();\n\n const Renderer = getRenderer(card.type);\n\n if (Renderer) {\n return <Renderer card={card} onActionClick={onActionClick} />;\n }\n\n if (isPHPCard(card)) {\n return <DefaultCard card={card} onActionClick={onActionClick} />;\n }\n\n return (\n <div style={{ padding: \"8px\", background: \"#f3f4f6\", borderRadius: \"4px\" }}>\n <pre style={{ fontSize: \"12px\", overflow: \"auto\" }}>{JSON.stringify(card, null, 2)}</pre>\n </div>\n );\n}\n\nfunction isPHPCard(card: Card | CustomCard): card is Card {\n return card.type === \"card\";\n}\n","import React from \"react\";\nimport { Message } from \"@bootdesk/js-web-adapter-core\";\nimport { CardRenderer } from \"../cards/CardRenderer\";\nimport { MarkdownRenderer } from \"../utils/markdown\";\n\ninterface MessageContentProps {\n message: Message;\n onActionClick?: (messageId: string, actionId: string, value: string) => void;\n}\n\nexport function MessageContent({ message, onActionClick }: MessageContentProps): React.JSX.Element {\n return (\n <div data-chat-message-content=\"true\">\n {message.content.text && !message.content.cards?.length && (\n <div className=\"break-words text-sm leading-relaxed\" data-chat-text=\"true\">\n <MarkdownRenderer text={message.content.text} />\n </div>\n )}\n\n {message.content.cards?.map((card, index) => (\n <div key={index} className={index > 0 ? \"mt-2\" : undefined}>\n <CardRenderer\n card={card}\n onActionClick={(actionId, value) => onActionClick?.(message.id, actionId, value)}\n />\n </div>\n ))}\n\n {message.attachments?.map((attachment) => {\n const isImage = attachment.type === \"image\" || attachment.mimeType?.startsWith(\"image/\");\n\n return (\n <div key={attachment.id} className=\"mt-2\">\n {isImage ? (\n <a href={attachment.url} target=\"_blank\" rel=\"noopener noreferrer\">\n <img\n src={attachment.url}\n alt={attachment.name || \"Image\"}\n className=\"max-w-full rounded object-cover\"\n loading=\"lazy\"\n data-chat-attachment={attachment.id}\n />\n </a>\n ) : (\n <a\n href={attachment.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-2 px-3 py-2 bg-chat-surface rounded text-sm no-underline text-chat-text hover:bg-chat-background transition\"\n data-chat-attachment={attachment.id}\n >\n 📎 {attachment.name}\n </a>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","export function formatTimestamp(timestamp: number): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n\n if (diffMins < 1) return \"Just now\";\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffMins < 1440) return `${Math.floor(diffMins / 60)}h ago`;\n return date.toLocaleDateString();\n}\n","import React, { useState, useRef, useEffect } from \"react\";\nimport { useAttachmentUpload } from \"../hooks/useAttachmentUpload\";\nimport { Dropzone } from \"./Dropzone\";\nimport { AttachmentList } from \"./AttachmentList\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\n\ninterface InputAreaProps {\n onSend: (\n text: string,\n attachments: Array<{ url: string; name: string; mimeType: string; size: number }>,\n ) => Promise<void>;\n disabled?: boolean;\n placeholder?: string;\n className?: string;\n enableAttachments?: boolean;\n uploadConfig?: import(\"../types/AttachmentUpload\").UploadConfig;\n accept?: string;\n maxFileSize?: number;\n}\n\nexport function InputArea({\n onSend,\n disabled = false,\n placeholder = \"Type a message...\",\n className,\n enableAttachments = false,\n uploadConfig,\n accept,\n maxFileSize,\n}: InputAreaProps): React.JSX.Element {\n const [text, setText] = useState(\"\");\n const [showDropzone, setShowDropzone] = useState(false);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const sendingRef = useRef(false);\n\n const { attachments, addFiles, removeAttachment, clearAttachments, isUploading } =\n useAttachmentUpload(uploadConfig!);\n\n const { t } = useLocale();\n\n useEffect(() => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textarea.style.height = \"auto\";\n textarea.style.height = Math.min(textarea.scrollHeight, 120) + \"px\";\n }, [text]);\n\n const handleSubmit = async () => {\n const trimmed = text.trim();\n if ((!trimmed && attachments.length === 0) || disabled || sendingRef.current) return;\n if (isUploading) return;\n\n sendingRef.current = true;\n\n const uploadedAttachments = attachments\n .filter((a) => a.status === \"uploaded\" && a.url)\n .map((a) => ({\n url: a.url!,\n name: a.name,\n mimeType: a.mimeType,\n size: a.size,\n }));\n\n setText(\"\");\n setShowDropzone(false);\n clearAttachments();\n try {\n await onSend(trimmed, uploadedAttachments);\n } finally {\n sendingRef.current = false;\n }\n setTimeout(() => textareaRef.current?.focus(), 0);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const canSend =\n (text.trim().length > 0 || attachments.some((a) => a.status === \"uploaded\")) && !isUploading;\n\n return (\n <div\n className={`chat-input-area ${className || \"\"}`}\n data-chat-input-area=\"true\"\n data-testid=\"chat-input-area\"\n >\n {enableAttachments && attachments.length > 0 && (\n <AttachmentList attachments={attachments} onRemove={removeAttachment} />\n )}\n\n {enableAttachments && showDropzone && uploadConfig && (\n <Dropzone\n onFilesSelected={addFiles}\n disabled={disabled || isUploading}\n accept={accept}\n maxSize={maxFileSize}\n />\n )}\n\n <div className=\"flex gap-3\">\n {enableAttachments && uploadConfig && (\n <button\n onClick={() => setShowDropzone((prev) => !prev)}\n disabled={disabled}\n className={`p-2 rounded-lg cursor-pointer transition ${\n showDropzone\n ? \"bg-chat-primary/10 text-chat-primary\"\n : \"bg-transparent text-chat-text-secondary\"\n } disabled:cursor-not-allowed disabled:opacity-50`}\n data-chat-attachment-toggle=\"true\"\n aria-label=\"Toggle file attachment\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </svg>\n </button>\n )}\n\n <textarea\n ref={textareaRef}\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"chat-input\"\n data-chat-input=\"true\"\n rows={1}\n />\n\n <button\n onClick={handleSubmit}\n disabled={disabled || !canSend}\n className=\"chat-send-button\"\n data-chat-send-button=\"true\"\n aria-label={t(\"inputArea.send\")}\n >\n {isUploading ? (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"animate-spin\"\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n ) : (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n )}\n </button>\n </div>\n </div>\n );\n}\n","import React, { useCallback, useState, useRef } from \"react\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\n\ninterface DropzoneProps {\n onFilesSelected: (files: FileList | File[]) => void;\n disabled?: boolean;\n accept?: string;\n maxSize?: number;\n multiple?: boolean;\n className?: string;\n}\n\nexport function Dropzone({\n onFilesSelected,\n disabled = false,\n accept,\n maxSize,\n multiple = true,\n className,\n}: DropzoneProps): React.JSX.Element {\n const { t } = useLocale();\n const [isDragging, setIsDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const dragCounter = useRef(0);\n\n const handleDragEnter = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter.current++;\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {\n setIsDragging(true);\n }\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter.current--;\n if (dragCounter.current === 0) {\n setIsDragging(false);\n }\n }, []);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n dragCounter.current = 0;\n if (disabled) return;\n\n const files = e.dataTransfer.files;\n if (files && files.length > 0) {\n const filtered = filterFiles(files, maxSize, accept);\n if (filtered.length > 0) {\n onFilesSelected(multiple ? filtered : [filtered[0]!]);\n }\n }\n },\n [disabled, maxSize, accept, multiple, onFilesSelected],\n );\n\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n const files = e.target.files;\n if (files && files.length > 0) {\n const filtered = filterFiles(files, maxSize, accept);\n if (filtered.length > 0) {\n onFilesSelected(multiple ? filtered : [filtered[0]!]);\n }\n }\n if (inputRef.current) inputRef.current.value = \"\";\n },\n [disabled, maxSize, accept, multiple, onFilesSelected],\n );\n\n const handleClick = useCallback(() => {\n inputRef.current?.click();\n }, []);\n\n function filterFiles(files: FileList, maxSize?: number, accept?: string): File[] {\n return Array.from(files).filter((file) => {\n if (maxSize && file.size > maxSize) return false;\n if (accept) {\n const accepted = accept.split(\",\").map((a) => a.trim().toLowerCase());\n const mimeType = file.type.toLowerCase();\n const ext = \".\" + file.name.split(\".\").pop()?.toLowerCase();\n return accepted.some((a) => {\n if (a.endsWith(\"/*\")) return mimeType.startsWith(a.replace(\"/*\", \"/\"));\n return a === mimeType || a === ext;\n });\n }\n return true;\n });\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") handleClick();\n }}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n className={`flex items-center justify-center p-2 border-2 border-dashed rounded-lg cursor-pointer transition ${\n isDragging ? \"border-chat-primary bg-chat-primary/10\" : \"border-chat-border\"\n } ${disabled ? \"cursor-not-allowed opacity-50\" : \"\"} ${className || \"\"}`}\n data-chat-dropzone=\"true\"\n data-testid=\"chat-dropzone\"\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleInputChange}\n className=\"hidden\"\n disabled={disabled}\n aria-hidden=\"true\"\n />\n <div className=\"text-center\">\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={isDragging ? \"var(--chat-primary)\" : \"var(--chat-text-secondary)\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"mx-auto mb-1\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n <div className=\"text-xs text-chat-text-secondary\">\n {isDragging ? t(\"inputArea.dropzone.dropFiles\") : t(\"inputArea.dropzone.dropOrClick\")}\n </div>\n </div>\n </div>\n );\n}\n","import React from \"react\";\nimport { PendingAttachment } from \"../types/AttachmentUpload\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\nimport { formatSize } from \"../utils/formatSize\";\n\ninterface AttachmentListProps {\n attachments: PendingAttachment[];\n onRemove?: (id: string) => void;\n className?: string;\n}\n\nexport function AttachmentList({\n attachments,\n onRemove,\n className,\n}: AttachmentListProps): React.JSX.Element {\n const { t } = useLocale();\n\n if (attachments.length === 0) return <></>;\n\n function getFileIcon(mimeType: string): string {\n if (mimeType.startsWith(\"image/\")) return \"🖼️\";\n if (mimeType === \"application/pdf\") return \"📄\";\n if (mimeType.includes(\"video\")) return \"🎬\";\n if (mimeType.includes(\"audio\")) return \"🎵\";\n return \"📎\";\n }\n\n return (\n <div className={`flex flex-wrap gap-1 p-1 ${className || \"\"}`} data-chat-attachment-list=\"true\">\n {attachments.map((att) => (\n <div\n key={att.id}\n className={`flex items-center gap-1 px-2 py-1 text-xs rounded border max-w-[200px] ${\n att.status === \"error\"\n ? \"bg-chat-error/15 border-chat-error\"\n : \"bg-chat-surface shadow-sm border-chat-border\"\n }`}\n data-chat-attachment-item={att.id}\n >\n <span>{getFileIcon(att.mimeType)}</span>\n <div className=\"flex-1 min-w-0\">\n <div\n className={`overflow-hidden text-ellipsis whitespace-nowrap ${\n att.status === \"error\" ? \"text-chat-error\" : \"text-chat-text\"\n }`}\n >\n {att.name}\n </div>\n <div className=\"text-[10px] text-chat-text-secondary\">\n {att.status === \"uploading\"\n ? `${att.progress}%`\n : att.status === \"error\"\n ? att.error || t(\"attachmentList.uploadFailed\")\n : formatSize(att.size)}\n </div>\n {att.status === \"uploading\" && (\n <div className=\"h-0.5 bg-chat-border rounded overflow-hidden mt-0.5\">\n <div\n className=\"h-full bg-chat-primary transition-[width] duration-150\"\n style={{ width: `${att.progress}%` }}\n />\n </div>\n )}\n </div>\n {onRemove && att.status !== \"uploading\" && (\n <button\n onClick={() => onRemove(att.id)}\n className=\"bg-none border-none cursor-pointer text-chat-text-secondary p-0.5 leading-none hover:text-chat-error\"\n aria-label={`Remove ${att.name}`}\n >\n ×\n </button>\n )}\n </div>\n ))}\n </div>\n );\n}\n","import React from \"react\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\n\ninterface TypingIndicatorProps {\n users?: string[];\n}\n\nexport function TypingIndicator({ users = [] }: TypingIndicatorProps): React.JSX.Element {\n const { t } = useLocale();\n\n return (\n <div\n className=\"chat-typing-indicator\"\n data-chat-typing-indicator=\"true\"\n data-testid=\"chat-typing-indicator\"\n >\n <span className=\"flex items-center gap-2\">\n <span className=\"flex gap-1\">\n <span\n className=\"w-1.5 h-1.5 rounded-full bg-chat-text-secondary animate-bounce\"\n style={{ animationDelay: \"0ms\" }}\n />\n <span\n className=\"w-1.5 h-1.5 rounded-full bg-chat-text-secondary animate-bounce\"\n style={{ animationDelay: \"160ms\" }}\n />\n <span\n className=\"w-1.5 h-1.5 rounded-full bg-chat-text-secondary animate-bounce\"\n style={{ animationDelay: \"320ms\" }}\n />\n </span>\n {users.length > 0 && ` ${users[0]} ${t(\"typingIndicator.isTyping\")}`}\n </span>\n </div>\n );\n}\n","import React, { createContext, useContext } from \"react\";\nimport { WebChatClient } from \"@bootdesk/js-web-adapter-core\";\nimport { CardProvider } from \"../cards/CardContext\";\nimport type { CardRenderer } from \"../cards/types\";\n\ninterface ChatContextValue {\n client: WebChatClient;\n}\n\nconst ChatContext = createContext<ChatContextValue | undefined>(undefined);\n\ninterface ChatProviderProps {\n children: React.ReactNode;\n client: WebChatClient;\n cardRenderers?: Record<string, CardRenderer>;\n}\n\nexport function ChatProvider({\n children,\n client,\n cardRenderers,\n}: ChatProviderProps): React.JSX.Element {\n return (\n <CardProvider renderers={cardRenderers}>\n <ChatContext.Provider value={{ client }}>{children}</ChatContext.Provider>\n </CardProvider>\n );\n}\n\nexport function useChatContext(): ChatContextValue {\n const context = useContext(ChatContext);\n if (!context) {\n throw new Error(\"useChatContext must be used within ChatProvider\");\n }\n return context;\n}\n\nexport { ChatWidget } from \"../components/ChatWidget\";\n","import React, { Component } from \"react\";\nimport type { ReactNode } from \"react\";\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode | ((error: Error) => ReactNode);\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { error };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.props.onError?.(error, errorInfo);\n }\n\n render(): ReactNode {\n if (!this.state.error) return this.props.children;\n\n const { fallback } = this.props;\n if (typeof fallback === \"function\") {\n return (fallback as (error: Error) => ReactNode)(this.state.error);\n }\n if (fallback) return fallback;\n\n return (\n <div\n className=\"flex flex-col items-center justify-center p-6 text-center\"\n data-chat-error-boundary=\"true\"\n >\n <div className=\"text-chat-error text-lg font-semibold mb-2\">Something went wrong</div>\n <div className=\"text-chat-text-secondary text-sm mb-4\">{this.state.error.message}</div>\n <button\n onClick={() => this.setState({ error: null })}\n className=\"px-4 py-2 bg-chat-primary text-white rounded text-sm cursor-pointer hover:opacity-90\"\n >\n Try again\n </button>\n </div>\n );\n }\n}\n","import React, { useState } from \"react\";\nimport { usePushNotifications } from \"../hooks/usePushNotifications\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\n\ninterface PushPermissionPromptProps {\n autoHide?: boolean;\n title?: string;\n description?: string;\n onStatusChange?: (enabled: boolean) => void;\n getVapidPublicKey: () => Promise<string>;\n onSubscribe: (sub: PushSubscriptionJSON) => Promise<void>;\n onUnsubscribe: (sub: PushSubscriptionJSON) => Promise<void>;\n}\n\nexport function PushPermissionPrompt({\n autoHide = true,\n title,\n description,\n onStatusChange,\n getVapidPublicKey,\n onSubscribe,\n onUnsubscribe,\n}: PushPermissionPromptProps) {\n const { t } = useLocale();\n const { status, isSupported, isSubscribed, subscribe, unsubscribe } = usePushNotifications({\n enabled: true,\n getVapidPublicKey,\n onSubscribe,\n onUnsubscribe,\n });\n\n const [dismissed, setDismissed] = useState(false);\n\n if (!isSupported) return null;\n if (autoHide && (isSubscribed || status === \"denied\")) return null;\n if (dismissed) return null;\n\n const handleEnable = async () => {\n await subscribe();\n onStatusChange?.(true);\n };\n\n const handleDisable = async () => {\n await unsubscribe();\n onStatusChange?.(false);\n };\n\n return (\n <div\n className=\"p-3 bg-chat-surface rounded-lg flex items-start gap-3\"\n data-chat-push-prompt=\"true\"\n >\n <div className=\"flex-1\">\n <div className=\"font-semibold mb-1 text-chat-text\">{title || t(\"push.title\")}</div>\n <div className=\"text-sm text-chat-text-secondary\">\n {description || t(\"push.description\")}\n </div>\n </div>\n <div className=\"flex gap-2\">\n {!isSubscribed && status !== \"denied\" && (\n <button\n onClick={handleEnable}\n className=\"px-3 py-1.5 bg-chat-primary text-white border-none rounded cursor-pointer text-sm hover:opacity-90\"\n >\n {t(\"push.enable\")}\n </button>\n )}\n {isSubscribed && (\n <button\n onClick={handleDisable}\n className=\"px-3 py-1.5 bg-transparent text-chat-text-secondary border border-chat-border rounded cursor-pointer text-sm hover:bg-chat-surface\"\n >\n {t(\"push.disable\")}\n </button>\n )}\n <button\n onClick={() => setDismissed(true)}\n className=\"px-1.5 bg-transparent border-none cursor-pointer text-chat-text-secondary hover:text-chat-text\"\n >\n ✕\n </button>\n </div>\n </div>\n );\n}\n","import React from \"react\";\nimport { usePushNotifications } from \"../hooks/usePushNotifications\";\nimport { useLocale } from \"../i18n/LocaleProvider\";\n\ninterface PushToggleProps {\n getVapidPublicKey: () => Promise<string>;\n onSubscribe: (sub: PushSubscriptionJSON) => Promise<void>;\n onUnsubscribe: (sub: PushSubscriptionJSON) => Promise<void>;\n}\n\nexport function PushToggle({ getVapidPublicKey, onSubscribe, onUnsubscribe }: PushToggleProps) {\n const { t } = useLocale();\n const { status, isSupported, isSubscribed, subscribe, unsubscribe } = usePushNotifications({\n enabled: true,\n getVapidPublicKey,\n onSubscribe,\n onUnsubscribe,\n });\n\n if (!isSupported) {\n return <div className=\"text-sm text-chat-text-secondary\">{t(\"push.unsupported\")}</div>;\n }\n\n if (status === \"denied\") {\n return <div className=\"text-sm text-chat-text-secondary\">{t(\"push.denied\")}</div>;\n }\n\n return (\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={isSubscribed}\n onChange={async (e) => {\n if (e.target.checked) await subscribe();\n else await unsubscribe();\n }}\n disabled={status === \"subscribing\"}\n className=\"w-4 h-4 cursor-pointer\"\n />\n <span className=\"text-sm\">\n {status === \"subscribing\" ? t(\"push.subscribing\") : t(\"push.notifications\")}\n </span>\n </label>\n );\n}\n","export { ChatWidget } from \"./components/ChatWidget\";\nexport type { ChatWidgetProps } from \"./components/ChatWidget\";\n\nexport { Header } from \"./components/Header\";\nexport { MessageList } from \"./components/MessageList\";\nexport { MessageContent } from \"./components/MessageContent\";\nexport { InputArea } from \"./components/InputArea\";\nexport { TypingIndicator } from \"./components/TypingIndicator\";\nexport { FloatingButton } from \"./components/FloatingButton\";\n\nexport { CardRenderer } from \"./cards/CardRenderer\";\nexport { DefaultCard } from \"./cards/DefaultCard\";\nexport { ImageCardComponent as ImageCardComponent } from \"./cards/ImageCard\";\nexport { FileCardComponent as FileCardComponent } from \"./cards/FileCard\";\nexport { CardProvider, useCardRegistry } from \"./cards/CardContext\";\nexport { ChatProvider, useChatContext } from \"./providers/ChatProvider\";\nexport type { CardRendererProps, CardRenderer as CardRendererType } from \"./cards/types\";\n\nexport { useChatClient } from \"./hooks/useChatClient\";\nexport { useMessages } from \"./hooks/useMessages\";\nexport { useStreaming } from \"./hooks/useStreaming\";\nexport { useTyping } from \"./hooks/useTyping\";\nexport { useCardRegistry as useCardRendererRegistry } from \"./cards/CardContext\";\n\nexport { MarkdownRenderer, renderMarkdown } from \"./utils/markdown\";\n\nexport { ErrorBoundary } from \"./components/ErrorBoundary\";\nexport { Dropzone } from \"./components/Dropzone\";\nexport { AttachmentList } from \"./components/AttachmentList\";\nexport { useAttachmentUpload } from \"./hooks/useAttachmentUpload\";\nexport type {\n PendingAttachment,\n AttachmentUploadConfig,\n SimpleUploadConfig,\n UploadConfig,\n SignedUploadUrl,\n} from \"./types/AttachmentUpload\";\n\nexport { LocaleProvider, useLocale, registerLocale, getAvailableLocales } from \"./i18n\";\nexport type { LocaleStrings, PartialLocaleStrings, LocaleConfig, SupportedLocale } from \"./i18n\";\n\nexport { PushPermissionPrompt } from \"./components/PushPermissionPrompt\";\nexport { PushToggle } from \"./components/PushToggle\";\nexport { usePushNotifications } from \"./hooks/usePushNotifications\";\nexport type {\n PushSubscriptionStatus,\n PushConfig,\n PushEventData,\n} from \"@bootdesk/js-web-adapter-core\";\nexport { PushManager, createPushSubscriptionHandlers } from \"@bootdesk/js-web-adapter-core\";\n\nexport type { Message, User, Card, PHPCard, CustomCard } from \"@bootdesk/js-web-adapter-core\";\n\nexport {\n WebChatClient,\n PusherBroadcastClient,\n LaravelEchoBroadcastClient,\n} from \"@bootdesk/js-web-adapter-core\";\n"],"mappings":"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","names":["useState","useCallback","useEffect","useEffect","features","useState","useEffect","useState","useEffect","useRef","useState","useEffect","useCallback","useRef","useState","useCallback","useRef","useState","useRef","useCallback","useState","useCallback","useEffect","useRef","useMemo","useMemo","jsx","jsx","jsxs","useRef","useEffect","useMemo","createContext","useContext","useMemo","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","createContext","useMemo","renderer","useContext","jsx","jsx","jsxs","jsx","jsxs","useRef","useEffect","useMemo","useState","useRef","useEffect","useCallback","useState","useRef","jsx","jsxs","useState","useRef","useCallback","maxSize","accept","jsx","jsxs","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","Fragment","jsx","jsxs","useState","useEffect","useCallback","createContext","useContext","jsx","createContext","useContext","jsx","jsxs","useState","jsx","jsxs","useState","jsx","jsxs","PushManager","WebChatClient"]}
@@ -0,0 +1 @@
1
+ *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--chat-primary:#6366f1;--chat-primary-hover:#4f46e5;--chat-secondary:#8b5cf6;--chat-background:#fff;--chat-surface:#f9fafb;--chat-text:#111827;--chat-text-secondary:#6b7280;--chat-border:#e5e7eb;--chat-own-message:#6366f1;--chat-own-message-text:#fff;--chat-other-message:#f3f4f6;--chat-other-message-text:#111827;--chat-error:#ef4444;--chat-success:#10b981;--chat-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}[data-chat-theme=dark]{--chat-primary:#818cf8;--chat-primary-hover:#6366f1;--chat-secondary:#a78bfa;--chat-background:#1e1e2e;--chat-surface:#2a2a3c;--chat-text:#e2e8f0;--chat-text-secondary:#94a3b8;--chat-border:#3e3e5c;--chat-own-message:#818cf8;--chat-own-message-text:#fff;--chat-other-message:#2a2a3c;--chat-other-message-text:#e2e8f0;--chat-error:#f87171;--chat-success:#4ade80}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.chat-header{display:flex;align-items:center;justify-content:space-between;border-bottom-width:1px;border-color:var(--chat-border);background-color:var(--chat-surface);padding:.75rem 1rem}.chat-message-list{display:flex;flex:1 1 0%;flex-direction:column;gap:.5rem;overflow:auto;background-color:var(--chat-background);padding:1rem;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--chat-text-secondary) transparent}.chat-message-list::-webkit-scrollbar{width:6px}.chat-message-list::-webkit-scrollbar-track{background:transparent}.chat-message-list::-webkit-scrollbar-thumb{background-color:var(--chat-text-secondary);border-radius:3px}.chat-message-list::-webkit-scrollbar-thumb:hover{background-color:var(--chat-text)}.chat-message-bubble-own{border-radius:1rem;border-bottom-right-radius:.125rem;background-color:var(--chat-own-message);color:var(--chat-own-message-text)}.chat-message-bubble-other,.chat-message-bubble-own{padding:.5rem .75rem;overflow-wrap:break-word;word-break:break-word}.chat-message-bubble-other{border-radius:1rem;border-bottom-left-radius:.125rem;background-color:var(--chat-other-message);color:var(--chat-other-message-text)}.chat-input-area{display:flex;flex-direction:column;gap:.5rem;border-top-width:1px;border-color:var(--chat-border);background-color:var(--chat-surface);padding:1rem}.chat-input{flex:1 1 0%;resize:none;border-radius:.5rem;border-width:1px;border-color:var(--chat-border);background-color:var(--chat-background);padding:.5rem .75rem;font-size:1rem;line-height:1.5rem;color:var(--chat-text)}.chat-input::-moz-placeholder{color:var(--chat-text-secondary)}.chat-input::placeholder{color:var(--chat-text-secondary)}.chat-input:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--chat-primary)}.chat-input{font-family:var(--chat-font-family);scrollbar-width:thin;scrollbar-color:var(--chat-text-secondary) transparent}.chat-input::-webkit-scrollbar{width:6px}.chat-input::-webkit-scrollbar-track{background:transparent}.chat-input::-webkit-scrollbar-thumb{background-color:var(--chat-text-secondary);border-radius:3px}.chat-input::-webkit-scrollbar-thumb:hover{background-color:var(--chat-text)}.chat-send-button{border-radius:.5rem;background-color:var(--chat-primary);padding:.5rem 1rem;font-weight:500;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.chat-send-button:hover{background-color:var(--chat-primary-hover)}.chat-send-button:disabled{cursor:not-allowed;opacity:.5}.chat-floating-button{display:flex;align-items:center;justify-content:center;border-radius:9999px;background-color:var(--chat-primary);--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.chat-floating-button:hover{--tw-scale-x:1.05;--tw-scale-y:1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.chat-typing-indicator{padding-right:1rem;padding-left:1.5rem;font-size:.875rem;line-height:1.25rem;font-style:italic;color:var(--chat-text-secondary)}[data-chat-widget=fullscreen]{height:100dvh}[data-chat-widget=floating]{max-height:min(600px,80dvh)}@supports (padding:max(0px)){[data-chat-widget=fullscreen]{padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);padding-bottom:env(safe-area-inset-bottom)}[data-chat-widget=floating]{margin-bottom:env(safe-area-inset-bottom,0)}}@media screen and (max-width:768px){[data-chat-input]{font-size:16px!important}}@media screen and (max-width:799px){[data-chat-widget=floating]{position:fixed!important;inset:0!important;width:100%!important;max-width:none!important;max-height:none!important;border-radius:0!important;z-index:50!important;padding-bottom:env(safe-area-inset-bottom,0)!important}}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.inset-0{inset:0}.-right-1{right:-.25rem}.-top-1{top:-.25rem}.bottom-20{bottom:5rem}.bottom-5{bottom:1.25rem}.left-5{left:1.25rem}.right-5{right:1.25rem}.top-5{top:1.25rem}.z-10{z-index:10}.z-50{z-index:50}.m-0{margin:0}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem}.mb-1,.my-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.hidden{display:none}.h-0\.5{height:.125rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-2{height:.5rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-auto{height:auto}.h-dvh{height:100dvh}.h-full{height:100%}.h-px{height:1px}.max-h-36{max-height:9rem}.max-h-48{max-height:12rem}.max-h-\[min\(600px\2c 80dvh\)\]{max-height:min(600px,80dvh)}.min-h-0{min-height:0}.min-h-\[200px\]{min-height:200px}.min-h-\[300px\]{min-height:300px}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-2{width:.5rem}.w-4{width:1rem}.w-\[480px\]{width:480px}.w-full{width:100%}.min-w-0{min-width:0}.min-w-5{min-width:1.25rem}.max-w-\[200px\]{max-width:200px}.max-w-\[min\(800px\2c calc\(100dvw-40px\)\)\]{max-width:min(800px,calc(100dvw - 40px))}.max-w-full{max-width:100%}.max-w-none{max-width:none}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.border-collapse{border-collapse:collapse}@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-bounce{animation:bounce 1s infinite}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;white-space:nowrap}.text-ellipsis,.truncate{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-0{border-width:0}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-chat-border{border-color:var(--chat-border)}.border-chat-error{border-color:var(--chat-error)}.border-chat-primary{border-color:var(--chat-primary)}.border-transparent{border-color:transparent}.bg-\[var\(--chat-background\)\],.bg-chat-background{background-color:var(--chat-background)}.bg-chat-border{background-color:var(--chat-border)}.bg-chat-error{background-color:var(--chat-error)}.bg-chat-primary{background-color:var(--chat-primary)}.bg-chat-success{background-color:var(--chat-success)}.bg-chat-surface{background-color:var(--chat-surface)}.bg-chat-text-secondary{background-color:var(--chat-text-secondary)}.bg-transparent{background-color:transparent}.bg-none{background-image:none}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-\[10px\]{font-size:10px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.text-chat-error{color:var(--chat-error)}.text-chat-primary{color:var(--chat-primary)}.text-chat-text{color:var(--chat-text)}.text-chat-text-secondary{color:var(--chat-text-secondary)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.no-underline{text-decoration-line:none}.opacity-50{opacity:.5}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-sm,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150,.transition-transform{transition-duration:.15s}.last\:mb-0:last-child{margin-bottom:0}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-chat-background:hover{background-color:var(--chat-background)}.hover\:bg-chat-primary-hover:hover{background-color:var(--chat-primary-hover)}.hover\:bg-chat-surface:hover{background-color:var(--chat-surface)}.hover\:text-chat-error:hover{color:var(--chat-error)}.hover\:text-chat-text:hover{color:var(--chat-text)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@bootdesk/js-web-adapter-react",
3
+ "version": "0.1.0",
4
+ "description": "React components for BootDesk Chat SDK WebAdapter",
5
+ "type": "module",
6
+ "types": "./dist/index.d.ts",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./styles.css": "./dist/styles.css"
16
+ },
17
+ "files": ["dist"],
18
+ "scripts": {
19
+ "build": "tsup && tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css --minify",
20
+ "build:dev": "tsup && tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css",
21
+ "test": "vitest run",
22
+ "test:ui": "vitest --ui",
23
+ "lint": "eslint src",
24
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
25
+ "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
26
+ "typecheck": "tsc --noEmit",
27
+ "docs": "typedoc --out ../../docs/_build/js/react src"
28
+ },
29
+ "peerDependencies": {
30
+ "react": "^18.0.0 || ^19.0.0",
31
+ "react-dom": "^18.0.0 || ^19.0.0",
32
+ "@bootdesk/js-web-adapter-core": "^0.1.0",
33
+ "marked": "^18.0.0",
34
+ "dompurify": "^3.4.5",
35
+ "@bootdesk/chat-widget-bridge": "^0.1.0"
36
+ },
37
+ "peerDependenciesMeta": {
38
+ "@bootdesk/chat-widget-bridge": {
39
+ "optional": true
40
+ }
41
+ },
42
+ "devDependencies": {
43
+ "@bootdesk/js-web-adapter-core": "*",
44
+ "@eslint/js": "^10.0.1",
45
+ "@testing-library/jest-dom": "^6.0.0",
46
+ "@testing-library/react": "^16.0.0",
47
+ "@types/dompurify": "^3.0.0",
48
+ "@types/react": "^18.0.0",
49
+ "@types/react-dom": "^18.0.0",
50
+ "dompurify": "^3.4.5",
51
+ "eslint": "^10.4.0",
52
+ "eslint-config-prettier": "^10.1.8",
53
+ "jsdom": "^25.0.0",
54
+ "marked": "^18.0.0",
55
+ "prettier": "^3.8.3",
56
+ "react": "^18.0.0",
57
+ "react-dom": "^18.0.0",
58
+ "tailwindcss": "^3.4.0",
59
+ "tsup": "^8.0.0",
60
+ "typescript": "^5.0.0",
61
+ "typescript-eslint": "^8.59.4",
62
+ "vitest": "^1.0.0"
63
+ }
64
+ }