reachat 1.6.1 → 1.7.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,13 @@
1
+ import { ReactNode, FC } from 'react';
2
+ import { ChatTheme } from '../theme';
3
+ export interface AppBarProps {
4
+ /**
5
+ * Content to display in the header
6
+ */
7
+ content?: ReactNode;
8
+ /**
9
+ * Custom theme for the appbar
10
+ */
11
+ theme?: ChatTheme;
12
+ }
13
+ export declare const AppBar: FC<AppBarProps>;
@@ -0,0 +1 @@
1
+ export * from './AppBar';
@@ -2,7 +2,7 @@ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { useState, useRef, useEffect } from "react";
4
4
  import { AnimatePresence, motion } from "motion/react";
5
- import { a as SvgCopy } from "./index-BoPOnul2.js";
5
+ import { a as SvgCopy } from "./index-B4HlLXxa.js";
6
6
  import { IconButton } from "reablocks";
7
7
  const sanitizeSVGCell = (cell) => {
8
8
  const trimmed = cell.trim();
@@ -145,4 +145,4 @@ const CSVFileRenderer = ({ name, url, fileIcon }) => {
145
145
  export {
146
146
  CSVFileRenderer as default
147
147
  };
148
- //# sourceMappingURL=CSVFileRenderer-CaUQ0d1z.js.map
148
+ //# sourceMappingURL=CSVFileRenderer-Cio05GLC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CSVFileRenderer-CaUQ0d1z.js","sources":["../src/utils/sanitize.ts","../src/utils/parseCSV.ts","../src/assets/download.svg?react","../src/SessionMessages/SessionMessage/MessageFile/renderers/CSVFileRenderer.tsx"],"sourcesContent":["\n/**\n * Sanitizes cell content to prevent CSV injection and other potential vulnerabilities.\n * Based on the documentation of OWASP for CSV Injection\n * https://owasp.org/www-community/attacks/CSV_Injection\n * @param cell The cell content to sanitize.\n * @returns The sanitized cell content.\n */\nexport const sanitizeSVGCell = (cell: string): string => {\n const trimmed = cell.trim();\n // Escape double quotes by doubling them\n const escaped = trimmed.replace(/\"/g, '\"\"');\n // Add single quote prefix only for potentially dangerous content\n const prefix = /^[=+\\-@]/.test(trimmed) ? '\\'' : '';\n // Only wrap in quotes if the content contains special characters\n const needsQuotes = /[\",\\n\\r]/.test(escaped) || prefix;\n\n return needsQuotes ? `\"${prefix}${escaped}\"` : escaped;\n};\n","import { sanitizeSVGCell } from './sanitize';\n\n/**\n * Parses a CSV string from a local file and returns an array of rows.\n * Sanitizes cell data to prevent injection attacks.\n * @param csvString The raw CSV string content to parse.\n * @returns The parsed CSV data as a 2D array of strings.\n */\nexport const parseCSV = (csvString: string): string[][] => {\n try {\n const rows = csvString.split('\\n');\n return rows.map((row) => row.split(',').map((cell) => sanitizeSVGCell(cell)));\n } catch (error) {\n console.error('Error parsing CSV:', error);\n throw new Error('Failed to parse CSV file.');\n }\n};\n","import * as React from \"react\";\nconst SvgDownload = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", strokeWidth: 1, strokeLinecap: \"round\", strokeLinejoin: \"round\", className: \"lucide lucide-cloud-download\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M12 12v9\" }), /* @__PURE__ */ React.createElement(\"path\", { d: \"m8 17 4 4 4-4\" }));\nexport default SvgDownload;\n","import { FC, useEffect, useState, ReactElement, useRef } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { parseCSV } from '@/utils/parseCSV';\nimport DownloadIcon from '@/assets/download.svg?react';\nimport PlaceholderIcon from '@/assets/copy.svg?react';\nimport { IconButton } from 'reablocks';\n\ninterface CSVFileRendererProps {\n /**\n * Name of the file.\n */\n name?: string;\n\n /**\n * URL of the file.\n */\n url: string;\n\n /**\n * Icon to for file type.\n */\n fileIcon?: ReactElement;\n}\n\n/**\n * Renderer for CSV files that fetches and displays a snippet of the file data.\n */\nconst CSVFileRenderer: FC<CSVFileRendererProps> = ({ name, url, fileIcon }) => {\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [csvData, setCsvData] = useState<string[][]>([]);\n const [error, setError] = useState<string | null>(null);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const modalRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const fetchCsvData = async () => {\n try {\n setIsLoading(true);\n const response = await fetch(url);\n const data = parseCSV(await response.text());\n setCsvData(data);\n } catch {\n setError('Failed to load CSV file.');\n } finally {\n setIsLoading(false);\n }\n };\n\n fetchCsvData();\n }, [url]);\n\n const toggleModal = () => {\n setIsModalOpen(prev => !prev);\n };\n\n const handleClickOutside = (event: MouseEvent) => {\n if (modalRef.current && !modalRef.current.contains(event.target as Node)) {\n setIsModalOpen(false);\n }\n };\n\n useEffect(() => {\n if (isModalOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n } else {\n document.removeEventListener('mousedown', handleClickOutside);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [isModalOpen]);\n\n const downloadCSV = () => {\n if (csvData.length === 0) return;\n\n const csvContent = csvData.map(row => row.join(',')).join('\\n');\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.setAttribute('download', `${name || 'data'}`);\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n };\n\n const renderTable = (data: string[][], maxRows?: number) => (\n <motion.table\n layout\n className=\"w-full\"\n transition={{ type: 'spring', stiffness: 100, damping: 20 }}\n >\n <thead className=\"sticky top-0 bg-gray-200 dark:bg-gray-800 z-10\">\n <tr>\n <th className=\"py-4 px-6\">#</th>\n {data[0].map((header, index) => (\n <th key={`header-${index}`} className=\"py-4 px-6\">\n {header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.slice(1, maxRows).map((row, rowIndex) => (\n <tr\n key={`row-${rowIndex}`}\n className=\"border-b border-panel-accent hover:bg-panel-accent/40 transition-colors text-base text-text-secondary\"\n >\n <td className=\"py-4 px-6\">{rowIndex + 1}</td>\n {row.map((cell, cellIndex) => (\n <td\n key={`cell-${rowIndex}-${cellIndex}`}\n className=\"py-4 px-6 dark:bg-vulcan light:bg-mystic\"\n >\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </motion.table>\n );\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex justify-between items-center gap-4\">\n <div className=\"csv-icon flex items-center\">\n {fileIcon}\n {name && <figcaption className=\"ml-1\">{name}</figcaption>}\n </div>\n <div className=\"csv-icon flex items-center gap-6\">\n <IconButton size=\"small\" variant=\"text\" onClick={downloadCSV}>\n <DownloadIcon />\n </IconButton>\n <IconButton size=\"small\" variant=\"text\" onClick={toggleModal}>\n <PlaceholderIcon />\n </IconButton>\n </div>\n </div>\n\n {error && <div className=\"error-message\">{error}</div>}\n\n {isLoading && !csvData && (\n <div className=\"text-text-secondary\">Loading...</div>\n )}\n\n <div className=\"flex justify-between\">\n {!error && csvData.length > 0 && renderTable(csvData, 6)}\n </div>\n\n <AnimatePresence>\n {isModalOpen && (\n <motion.div\n className=\"fixed inset-0 bg-black/70 flex justify-center items-center z-50\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n >\n <motion.div\n ref={modalRef}\n className=\"bg-white dark:bg-gray-900 rounded-md w-11/12 h-5/6 overflow-auto\"\n initial={{ scale: 0.8 }}\n animate={{ scale: 1 }}\n exit={{ scale: 0.8 }}\n transition={{ duration: 0.3 }}\n >\n {!error && csvData.length > 0 && renderTable(csvData)}\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n};\n\nexport default CSVFileRenderer;\n"],"names":["url","DownloadIcon","PlaceholderIcon"],"mappings":"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"}
1
+ {"version":3,"file":"CSVFileRenderer-Cio05GLC.js","sources":["../src/utils/sanitize.ts","../src/utils/parseCSV.ts","../src/assets/download.svg?react","../src/SessionMessages/SessionMessage/MessageFile/renderers/CSVFileRenderer.tsx"],"sourcesContent":["\n/**\n * Sanitizes cell content to prevent CSV injection and other potential vulnerabilities.\n * Based on the documentation of OWASP for CSV Injection\n * https://owasp.org/www-community/attacks/CSV_Injection\n * @param cell The cell content to sanitize.\n * @returns The sanitized cell content.\n */\nexport const sanitizeSVGCell = (cell: string): string => {\n const trimmed = cell.trim();\n // Escape double quotes by doubling them\n const escaped = trimmed.replace(/\"/g, '\"\"');\n // Add single quote prefix only for potentially dangerous content\n const prefix = /^[=+\\-@]/.test(trimmed) ? '\\'' : '';\n // Only wrap in quotes if the content contains special characters\n const needsQuotes = /[\",\\n\\r]/.test(escaped) || prefix;\n\n return needsQuotes ? `\"${prefix}${escaped}\"` : escaped;\n};\n","import { sanitizeSVGCell } from './sanitize';\n\n/**\n * Parses a CSV string from a local file and returns an array of rows.\n * Sanitizes cell data to prevent injection attacks.\n * @param csvString The raw CSV string content to parse.\n * @returns The parsed CSV data as a 2D array of strings.\n */\nexport const parseCSV = (csvString: string): string[][] => {\n try {\n const rows = csvString.split('\\n');\n return rows.map((row) => row.split(',').map((cell) => sanitizeSVGCell(cell)));\n } catch (error) {\n console.error('Error parsing CSV:', error);\n throw new Error('Failed to parse CSV file.');\n }\n};\n","import * as React from \"react\";\nconst SvgDownload = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", strokeWidth: 1, strokeLinecap: \"round\", strokeLinejoin: \"round\", className: \"lucide lucide-cloud-download\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M12 12v9\" }), /* @__PURE__ */ React.createElement(\"path\", { d: \"m8 17 4 4 4-4\" }));\nexport default SvgDownload;\n","import { FC, useEffect, useState, ReactElement, useRef } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { parseCSV } from '@/utils/parseCSV';\nimport DownloadIcon from '@/assets/download.svg?react';\nimport PlaceholderIcon from '@/assets/copy.svg?react';\nimport { IconButton } from 'reablocks';\n\ninterface CSVFileRendererProps {\n /**\n * Name of the file.\n */\n name?: string;\n\n /**\n * URL of the file.\n */\n url: string;\n\n /**\n * Icon to for file type.\n */\n fileIcon?: ReactElement;\n}\n\n/**\n * Renderer for CSV files that fetches and displays a snippet of the file data.\n */\nconst CSVFileRenderer: FC<CSVFileRendererProps> = ({ name, url, fileIcon }) => {\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [csvData, setCsvData] = useState<string[][]>([]);\n const [error, setError] = useState<string | null>(null);\n const [isModalOpen, setIsModalOpen] = useState(false);\n const modalRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const fetchCsvData = async () => {\n try {\n setIsLoading(true);\n const response = await fetch(url);\n const data = parseCSV(await response.text());\n setCsvData(data);\n } catch {\n setError('Failed to load CSV file.');\n } finally {\n setIsLoading(false);\n }\n };\n\n fetchCsvData();\n }, [url]);\n\n const toggleModal = () => {\n setIsModalOpen(prev => !prev);\n };\n\n const handleClickOutside = (event: MouseEvent) => {\n if (modalRef.current && !modalRef.current.contains(event.target as Node)) {\n setIsModalOpen(false);\n }\n };\n\n useEffect(() => {\n if (isModalOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n } else {\n document.removeEventListener('mousedown', handleClickOutside);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [isModalOpen]);\n\n const downloadCSV = () => {\n if (csvData.length === 0) return;\n\n const csvContent = csvData.map(row => row.join(',')).join('\\n');\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.setAttribute('download', `${name || 'data'}`);\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n };\n\n const renderTable = (data: string[][], maxRows?: number) => (\n <motion.table\n layout\n className=\"w-full\"\n transition={{ type: 'spring', stiffness: 100, damping: 20 }}\n >\n <thead className=\"sticky top-0 bg-gray-200 dark:bg-gray-800 z-10\">\n <tr>\n <th className=\"py-4 px-6\">#</th>\n {data[0].map((header, index) => (\n <th key={`header-${index}`} className=\"py-4 px-6\">\n {header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.slice(1, maxRows).map((row, rowIndex) => (\n <tr\n key={`row-${rowIndex}`}\n className=\"border-b border-panel-accent hover:bg-panel-accent/40 transition-colors text-base text-text-secondary\"\n >\n <td className=\"py-4 px-6\">{rowIndex + 1}</td>\n {row.map((cell, cellIndex) => (\n <td\n key={`cell-${rowIndex}-${cellIndex}`}\n className=\"py-4 px-6 dark:bg-vulcan light:bg-mystic\"\n >\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </motion.table>\n );\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex justify-between items-center gap-4\">\n <div className=\"csv-icon flex items-center\">\n {fileIcon}\n {name && <figcaption className=\"ml-1\">{name}</figcaption>}\n </div>\n <div className=\"csv-icon flex items-center gap-6\">\n <IconButton size=\"small\" variant=\"text\" onClick={downloadCSV}>\n <DownloadIcon />\n </IconButton>\n <IconButton size=\"small\" variant=\"text\" onClick={toggleModal}>\n <PlaceholderIcon />\n </IconButton>\n </div>\n </div>\n\n {error && <div className=\"error-message\">{error}</div>}\n\n {isLoading && !csvData && (\n <div className=\"text-text-secondary\">Loading...</div>\n )}\n\n <div className=\"flex justify-between\">\n {!error && csvData.length > 0 && renderTable(csvData, 6)}\n </div>\n\n <AnimatePresence>\n {isModalOpen && (\n <motion.div\n className=\"fixed inset-0 bg-black/70 flex justify-center items-center z-50\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n >\n <motion.div\n ref={modalRef}\n className=\"bg-white dark:bg-gray-900 rounded-md w-11/12 h-5/6 overflow-auto\"\n initial={{ scale: 0.8 }}\n animate={{ scale: 1 }}\n exit={{ scale: 0.8 }}\n transition={{ duration: 0.3 }}\n >\n {!error && csvData.length > 0 && renderTable(csvData)}\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n};\n\nexport default CSVFileRenderer;\n"],"names":["url","DownloadIcon","PlaceholderIcon"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { ReactNode, CSSProperties } from 'react';
2
+ export type Position = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
3
+ export interface ChatBubbleProps {
4
+ /**
5
+ * The main content to be rendered.
6
+ */
7
+ children: ReactNode;
8
+ /**
9
+ * The content to be rendered in the trigger bubble.
10
+ */
11
+ bubbleContent: ReactNode;
12
+ /**
13
+ * The position of the chat bubble on the screen.
14
+ * @default 'bottom-left'
15
+ */
16
+ position?: Position;
17
+ /**
18
+ * Custom CSS styles to override the default positioning.
19
+ */
20
+ customPosition?: CSSProperties;
21
+ /**
22
+ * The DOM element where the chat bubble should be rendered.
23
+ * @default document.body
24
+ */
25
+ portalTarget?: HTMLElement | null;
26
+ /**
27
+ * Additional CSS classes to apply to the chat bubble.
28
+ */
29
+ className?: string;
30
+ }
31
+ export declare const ChatBubble: import('react').NamedExoticComponent<ChatBubbleProps>;
@@ -0,0 +1 @@
1
+ export * from './ChatBubble';
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { S as SvgFile } from "./index-BoPOnul2.js";
2
+ import { S as SvgFile } from "./index-B4HlLXxa.js";
3
3
  import { cn, Ellipsis } from "reablocks";
4
4
  const DefaultFileRenderer = ({
5
5
  name,
@@ -12,4 +12,4 @@ const DefaultFileRenderer = ({
12
12
  export {
13
13
  DefaultFileRenderer as default
14
14
  };
15
- //# sourceMappingURL=DefaultFileRenderer-DgP6fkxg.js.map
15
+ //# sourceMappingURL=DefaultFileRenderer-C-vGWeXN.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultFileRenderer-DgP6fkxg.js","sources":["../src/SessionMessages/SessionMessage/MessageFile/renderers/DefaultFileRenderer.tsx"],"sourcesContent":["import { FC, ReactElement } from 'react';\nimport FileIcon from '@/assets/file.svg?react';\nimport { Ellipsis, cn } from 'reablocks';\n\ninterface DefaultFileRendererProps {\n /**\n * Limit for the name.\n */\n limit?: number;\n\n /**\n * Name of the file.\n */\n name?: string;\n\n /**\n * URL of the file.\n */\n url: string;\n\n /**\n * Icon to for file type.\n */\n fileIcon?: ReactElement;\n}\n\n/**\n * Default renderer for unspecified file types.\n */\nconst DefaultFileRenderer: FC<DefaultFileRendererProps> = ({\n name,\n limit = 100,\n fileIcon = <FileIcon />,\n}) => (\n <figure className=\"flex items-center gap-2\">\n {fileIcon}\n {name && (\n <figcaption className={cn('file-name-class')}>\n <Ellipsis value={name} limit={limit} />\n </figcaption>\n )}\n </figure>\n);\n\nexport default DefaultFileRenderer;\n"],"names":["FileIcon"],"mappings":";;;AA6BA,MAAM,sBAAoD,CAAC;AAAA,EACzD;AAAA,EACA,QAAQ;AAAA,EACR,+BAAYA,SAAS,CAAA,CAAA;AACvB,MACE,qBAAC,UAAO,EAAA,WAAU,2BACf,UAAA;AAAA,EAAA;AAAA,EACA,QACC,oBAAC,cAAW,EAAA,WAAW,GAAG,iBAAiB,GACzC,UAAA,oBAAC,UAAS,EAAA,OAAO,MAAM,MAAc,CAAA,EACvC,CAAA;AAAA,EAEJ,CAAA;"}
1
+ {"version":3,"file":"DefaultFileRenderer-C-vGWeXN.js","sources":["../src/SessionMessages/SessionMessage/MessageFile/renderers/DefaultFileRenderer.tsx"],"sourcesContent":["import { FC, ReactElement } from 'react';\nimport FileIcon from '@/assets/file.svg?react';\nimport { Ellipsis, cn } from 'reablocks';\n\ninterface DefaultFileRendererProps {\n /**\n * Limit for the name.\n */\n limit?: number;\n\n /**\n * Name of the file.\n */\n name?: string;\n\n /**\n * URL of the file.\n */\n url: string;\n\n /**\n * Icon to for file type.\n */\n fileIcon?: ReactElement;\n}\n\n/**\n * Default renderer for unspecified file types.\n */\nconst DefaultFileRenderer: FC<DefaultFileRendererProps> = ({\n name,\n limit = 100,\n fileIcon = <FileIcon />,\n}) => (\n <figure className=\"flex items-center gap-2\">\n {fileIcon}\n {name && (\n <figcaption className={cn('file-name-class')}>\n <Ellipsis value={name} limit={limit} />\n </figcaption>\n )}\n </figure>\n);\n\nexport default DefaultFileRenderer;\n"],"names":["FileIcon"],"mappings":";;;AA6BA,MAAM,sBAAoD,CAAC;AAAA,EACzD;AAAA,EACA,QAAQ;AAAA,EACR,+BAAYA,SAAS,CAAA,CAAA;AACvB,MACE,qBAAC,UAAO,EAAA,WAAU,2BACf,UAAA;AAAA,EAAA;AAAA,EACA,QACC,oBAAC,cAAW,EAAA,WAAW,GAAG,iBAAiB,GACzC,UAAA,oBAAC,UAAS,EAAA,OAAO,MAAM,MAAc,CAAA,EACvC,CAAA;AAAA,EAEJ,CAAA;"}
@@ -1,2 +1,6 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
- export declare const SessionMessagePanel: FC<PropsWithChildren>;
2
+ interface SessionMessagePanelProps extends PropsWithChildren {
3
+ allowBack?: boolean;
4
+ }
5
+ export declare const SessionMessagePanel: FC<SessionMessagePanelProps>;
6
+ export {};
@@ -1,2 +1,9 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
- export declare const SessionsList: FC<PropsWithChildren>;
2
+ import { Template } from '../types';
3
+ export interface SessionsListProps extends PropsWithChildren {
4
+ /**
5
+ * Templates to show when no session is active
6
+ */
7
+ templates?: Template[];
8
+ }
9
+ export declare const SessionsList: FC<SessionsListProps>;
package/dist/docs.json CHANGED
@@ -297,6 +297,180 @@
297
297
  }
298
298
  }
299
299
  },
300
+ {
301
+ "tags": {},
302
+ "filePath": "src/AppBar/AppBar.tsx",
303
+ "description": "",
304
+ "displayName": "AppBar",
305
+ "methods": [],
306
+ "props": {
307
+ "content": {
308
+ "defaultValue": null,
309
+ "description": "Content to display in the header",
310
+ "name": "content",
311
+ "parent": {
312
+ "fileName": "src/AppBar/AppBar.tsx",
313
+ "name": "AppBarProps"
314
+ },
315
+ "declarations": [
316
+ {
317
+ "fileName": "src/AppBar/AppBar.tsx",
318
+ "name": "AppBarProps"
319
+ }
320
+ ],
321
+ "required": false,
322
+ "type": {
323
+ "name": "ReactNode"
324
+ }
325
+ },
326
+ "theme": {
327
+ "defaultValue": null,
328
+ "description": "Custom theme for the appbar",
329
+ "name": "theme",
330
+ "parent": {
331
+ "fileName": "src/AppBar/AppBar.tsx",
332
+ "name": "AppBarProps"
333
+ },
334
+ "declarations": [
335
+ {
336
+ "fileName": "src/AppBar/AppBar.tsx",
337
+ "name": "AppBarProps"
338
+ }
339
+ ],
340
+ "required": false,
341
+ "type": {
342
+ "name": "ChatTheme"
343
+ }
344
+ }
345
+ }
346
+ },
347
+ {
348
+ "tags": {},
349
+ "filePath": "src/ChatBubble/ChatBubble.tsx",
350
+ "description": "",
351
+ "displayName": "ChatBubble",
352
+ "methods": [],
353
+ "props": {
354
+ "children": {
355
+ "defaultValue": null,
356
+ "description": "The main content to be rendered.",
357
+ "name": "children",
358
+ "parent": {
359
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
360
+ "name": "ChatBubbleProps"
361
+ },
362
+ "declarations": [
363
+ {
364
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
365
+ "name": "ChatBubbleProps"
366
+ }
367
+ ],
368
+ "required": true,
369
+ "type": {
370
+ "name": "ReactNode"
371
+ }
372
+ },
373
+ "bubbleContent": {
374
+ "defaultValue": null,
375
+ "description": "The content to be rendered in the trigger bubble.",
376
+ "name": "bubbleContent",
377
+ "parent": {
378
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
379
+ "name": "ChatBubbleProps"
380
+ },
381
+ "declarations": [
382
+ {
383
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
384
+ "name": "ChatBubbleProps"
385
+ }
386
+ ],
387
+ "required": true,
388
+ "type": {
389
+ "name": "ReactNode"
390
+ }
391
+ },
392
+ "position": {
393
+ "defaultValue": {
394
+ "value": "'bottom-left'"
395
+ },
396
+ "description": "The position of the chat bubble on the screen.",
397
+ "name": "position",
398
+ "parent": {
399
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
400
+ "name": "ChatBubbleProps"
401
+ },
402
+ "declarations": [
403
+ {
404
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
405
+ "name": "ChatBubbleProps"
406
+ }
407
+ ],
408
+ "required": false,
409
+ "type": {
410
+ "name": "Position"
411
+ }
412
+ },
413
+ "customPosition": {
414
+ "defaultValue": null,
415
+ "description": "Custom CSS styles to override the default positioning.",
416
+ "name": "customPosition",
417
+ "parent": {
418
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
419
+ "name": "ChatBubbleProps"
420
+ },
421
+ "declarations": [
422
+ {
423
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
424
+ "name": "ChatBubbleProps"
425
+ }
426
+ ],
427
+ "required": false,
428
+ "type": {
429
+ "name": "CSSProperties"
430
+ }
431
+ },
432
+ "portalTarget": {
433
+ "defaultValue": {
434
+ "value": "document.body"
435
+ },
436
+ "description": "The DOM element where the chat bubble should be rendered.",
437
+ "name": "portalTarget",
438
+ "parent": {
439
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
440
+ "name": "ChatBubbleProps"
441
+ },
442
+ "declarations": [
443
+ {
444
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
445
+ "name": "ChatBubbleProps"
446
+ }
447
+ ],
448
+ "required": false,
449
+ "type": {
450
+ "name": "HTMLElement"
451
+ }
452
+ },
453
+ "className": {
454
+ "defaultValue": null,
455
+ "description": "Additional CSS classes to apply to the chat bubble.",
456
+ "name": "className",
457
+ "parent": {
458
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
459
+ "name": "ChatBubbleProps"
460
+ },
461
+ "declarations": [
462
+ {
463
+ "fileName": "src/ChatBubble/ChatBubble.tsx",
464
+ "name": "ChatBubbleProps"
465
+ }
466
+ ],
467
+ "required": false,
468
+ "type": {
469
+ "name": "string"
470
+ }
471
+ }
472
+ }
473
+ },
300
474
  {
301
475
  "tags": {},
302
476
  "filePath": "src/ChatInput/ChatInput.tsx",
@@ -744,7 +918,29 @@
744
918
  "description": "",
745
919
  "displayName": "SessionMessagePanel",
746
920
  "methods": [],
747
- "props": {}
921
+ "props": {
922
+ "allowBack": {
923
+ "defaultValue": {
924
+ "value": "true"
925
+ },
926
+ "description": "",
927
+ "name": "allowBack",
928
+ "parent": {
929
+ "fileName": "src/SessionMessages/SessionMessagePanel.tsx",
930
+ "name": "SessionMessagePanelProps"
931
+ },
932
+ "declarations": [
933
+ {
934
+ "fileName": "src/SessionMessages/SessionMessagePanel.tsx",
935
+ "name": "SessionMessagePanelProps"
936
+ }
937
+ ],
938
+ "required": false,
939
+ "type": {
940
+ "name": "boolean"
941
+ }
942
+ }
943
+ }
748
944
  },
749
945
  {
750
946
  "tags": {},
@@ -1047,7 +1243,27 @@
1047
1243
  "description": "",
1048
1244
  "displayName": "SessionsList",
1049
1245
  "methods": [],
1050
- "props": {}
1246
+ "props": {
1247
+ "templates": {
1248
+ "defaultValue": null,
1249
+ "description": "Templates to show when no session is active",
1250
+ "name": "templates",
1251
+ "parent": {
1252
+ "fileName": "src/SessionsList/SessionsList.tsx",
1253
+ "name": "SessionsListProps"
1254
+ },
1255
+ "declarations": [
1256
+ {
1257
+ "fileName": "src/SessionsList/SessionsList.tsx",
1258
+ "name": "SessionsListProps"
1259
+ }
1260
+ ],
1261
+ "required": false,
1262
+ "type": {
1263
+ "name": "Template[]"
1264
+ }
1265
+ }
1266
+ }
1051
1267
  },
1052
1268
  {
1053
1269
  "tags": {},
@@ -1,7 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { createContext, useContext, useRef, forwardRef, useState, useEffect, useImperativeHandle, lazy, useMemo, Suspense, useCallback } from "react";
4
- import { Button, cn, Textarea, Ellipsis, DateFormat, IconButton, Card, Divider, useInfinityList, useComponentTheme, List, ListItem } from "reablocks";
4
+ import { Button, cn, Textarea, Ellipsis, DateFormat, IconButton, Card, Divider, useInfinityList, useComponentTheme, ListItem, List } from "reablocks";
5
5
  import { Slot } from "@radix-ui/react-slot";
6
6
  import { motion, AnimatePresence } from "motion/react";
7
7
  import ReactMarkdown from "react-markdown";
@@ -171,7 +171,10 @@ const SessionMessagesHeader = ({ children }) => {
171
171
  ] }) });
172
172
  };
173
173
  const SvgBack = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1, strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-chevron-left", ...props }, /* @__PURE__ */ React.createElement("path", { d: "m15 18-6-6 6-6" }));
174
- const SessionMessagePanel = ({ children }) => {
174
+ const SessionMessagePanel = ({
175
+ children,
176
+ allowBack = true
177
+ }) => {
175
178
  const { activeSessionId, theme, isCompact, selectSession, viewType } = useContext(ChatContext);
176
179
  const isVisible = isCompact && activeSessionId || viewType === "chat" || !isCompact;
177
180
  return isVisible && /* @__PURE__ */ jsx(
@@ -193,7 +196,7 @@ const SessionMessagePanel = ({ children }) => {
193
196
  [theme.messages.console]: !isCompact
194
197
  }),
195
198
  children: /* @__PURE__ */ jsxs("div", { className: cn(theme.messages.inner), children: [
196
- isCompact && viewType !== "chat" && /* @__PURE__ */ jsxs(
199
+ allowBack && isCompact && viewType !== "chat" && /* @__PURE__ */ jsxs(
197
200
  Button,
198
201
  {
199
202
  variant: "text",
@@ -1331,8 +1334,8 @@ function remarkCve() {
1331
1334
  }
1332
1335
  }
1333
1336
  const SvgFile = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 16, height: 16, viewBox: "0 0 16 16", fill: "currentColor", ...props }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.7036 1.37034C3.04741 1.02653 3.51373 0.833374 3.99996 0.833374H9.33329H9.33331C9.47275 0.833374 9.59885 0.890449 9.68954 0.98251L13.6843 4.97722C13.7763 5.0679 13.8333 5.19398 13.8333 5.33337L13.8333 5.3379V13.3334C13.8333 13.8196 13.6401 14.2859 13.2963 14.6297C12.9525 14.9736 12.4862 15.1667 12 15.1667H3.99996C3.51373 15.1667 3.04741 14.9736 2.7036 14.6297C2.35978 14.2859 2.16663 13.8196 2.16663 13.3334V2.66671C2.16663 2.18048 2.35978 1.71416 2.7036 1.37034ZM3.99996 1.83337H8.83331V5.33337C8.83331 5.60952 9.05717 5.83337 9.33331 5.83337H12.8333V13.3334C12.8333 13.5544 12.7455 13.7663 12.5892 13.9226C12.4329 14.0789 12.221 14.1667 12 14.1667H3.99996C3.77895 14.1667 3.56698 14.0789 3.4107 13.9226C3.25442 13.7663 3.16663 13.5544 3.16663 13.3334V2.66671C3.16663 2.44569 3.25442 2.23373 3.4107 2.07745C3.56698 1.92117 3.77895 1.83337 3.99996 1.83337ZM9.83331 2.5405L12.1262 4.83337H9.83331V2.5405ZM5.33331 8.16663C5.05717 8.16663 4.83331 8.39048 4.83331 8.66663C4.83331 8.94277 5.05717 9.16663 5.33331 9.16663H10.6666C10.9428 9.16663 11.1666 8.94277 11.1666 8.66663C11.1666 8.39048 10.9428 8.16663 10.6666 8.16663H5.33331ZM4.83331 11.3334C4.83331 11.0572 5.05717 10.8334 5.33331 10.8334H10.6666C10.9428 10.8334 11.1666 11.0572 11.1666 11.3334C11.1666 11.6095 10.9428 11.8334 10.6666 11.8334H5.33331C5.05717 11.8334 4.83331 11.6095 4.83331 11.3334ZM5.33331 5.5C5.05717 5.5 4.83331 5.72386 4.83331 6C4.83331 6.27614 5.05717 6.5 5.33331 6.5H6.66665C6.94279 6.5 7.16665 6.27614 7.16665 6C7.16665 5.72386 6.94279 5.5 6.66665 5.5H5.33331Z" }));
1334
- const DefaultFileRenderer = lazy(() => import("./DefaultFileRenderer-DgP6fkxg.js"));
1335
- const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-CaUQ0d1z.js"));
1337
+ const DefaultFileRenderer = lazy(() => import("./DefaultFileRenderer-C-vGWeXN.js"));
1338
+ const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-Cio05GLC.js"));
1336
1339
  const ImageFileRenderer = lazy(() => import("./ImageFileRenderer-C8tVW3I8.js"));
1337
1340
  const PDFFileRenderer = lazy(() => import("./PDFFileRenderer-DQdFS2l6.js"));
1338
1341
  const FILE_TYPE_RENDERER_MAP = {
@@ -1721,6 +1724,7 @@ const chatTheme = {
1721
1724
  console: "flex w-full gap-4 h-full",
1722
1725
  companion: "w-full h-full overflow-hidden",
1723
1726
  empty: "text-center flex-1",
1727
+ appbar: "flex p-5",
1724
1728
  sessions: {
1725
1729
  base: "overflow-auto",
1726
1730
  console: "min-w-[150px] w-[30%] max-w-[300px] dark:bg-[#11111F] bg-[#F2F3F7] p-5 rounded-3xl",
@@ -1762,7 +1766,10 @@ const chatTheme = {
1762
1766
  "relative font-semibold mb-4 px-4 py-4 pb-2 rounded-3xl rounded-br-none text-typography border bg-gray-200 border-gray-300 text-gray-900",
1763
1767
  "dark:bg-gray-900/60 dark:border-gray-700/50 dark:text-gray-100"
1764
1768
  ].join(" "),
1765
- response: ["relative data-[compact=false]:px-4 text-gray-900", "dark:text-gray-100"].join(" "),
1769
+ response: [
1770
+ "relative data-[compact=false]:px-4 text-gray-900",
1771
+ "dark:text-gray-100"
1772
+ ].join(" "),
1766
1773
  overlay: `overflow-y-hidden max-h-[350px] after:content-[''] after:absolute after:inset-x-0 after:bottom-0 after:h-16 after:bg-gradient-to-b after:from-transparent dark:after:to-gray-900 after:to-gray-200`,
1767
1774
  cursor: "inline-block w-1 h-4 bg-current",
1768
1775
  expand: "absolute bottom-1 right-1 z-10",
@@ -1958,31 +1965,6 @@ const Chat = ({
1958
1965
  }
1959
1966
  ) }) });
1960
1967
  };
1961
- const SessionsList = ({ children }) => {
1962
- const { theme, isCompact, activeSessionId } = useContext(ChatContext);
1963
- const isVisible = isCompact && !activeSessionId;
1964
- return (!isCompact || isVisible) && /* @__PURE__ */ jsx(
1965
- motion.div,
1966
- {
1967
- initial: { translateX: "-100%" },
1968
- animate: {
1969
- translateX: "0%",
1970
- transition: {
1971
- type: "tween",
1972
- ease: "linear",
1973
- duration: 0.2,
1974
- when: "beforeChildren"
1975
- }
1976
- },
1977
- exit: { translateX: "-100%" },
1978
- className: cn(theme.sessions.base, {
1979
- [theme.sessions.companion]: isCompact,
1980
- [theme.sessions.console]: !isCompact
1981
- }),
1982
- children: /* @__PURE__ */ jsx(List, { children })
1983
- }
1984
- );
1985
- };
1986
1968
  const SvgTrash = (props) => /* @__PURE__ */ React.createElement("svg", { width: 14, height: 14, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props }, /* @__PURE__ */ React.createElement("g", { id: "Delete" }, /* @__PURE__ */ React.createElement("path", { id: "Vector", d: "M5.97905 1.16666C5.90859 1.16576 5.83895 1.18189 5.77605 1.21368C5.71316 1.24547 5.65888 1.29199 5.61783 1.34926C5.57677 1.40654 5.55016 1.47288 5.54025 1.54265C5.53034 1.61242 5.53743 1.68355 5.56092 1.75H4.27007C3.7342 1.75 3.2324 2.01817 2.93535 2.46435L2.24492 3.5H2.18738C2.12941 3.49918 2.07185 3.50989 2.01805 3.5315C1.96425 3.55312 1.91529 3.58522 1.874 3.62593C1.83271 3.66663 1.79993 3.71514 1.77755 3.76863C1.75518 3.82211 1.74365 3.87952 1.74365 3.9375C1.74365 3.99548 1.75518 4.05288 1.77755 4.10636C1.79993 4.15985 1.83271 4.20836 1.874 4.24907C1.91529 4.28977 1.96425 4.32187 2.01805 4.34349C2.07185 4.3651 2.12941 4.37582 2.18738 4.375H2.41012C2.44765 4.38067 2.48576 4.38143 2.52348 4.37727L3.24468 11.1084C3.33169 11.9199 4.02367 12.5417 4.83973 12.5417H9.15947C9.97553 12.5417 10.6675 11.9199 10.7545 11.1084L11.4763 4.37727C11.5133 4.38124 11.5506 4.38047 11.5874 4.375H11.8124C11.8704 4.37582 11.9279 4.3651 11.9817 4.34349C12.0355 4.32187 12.0845 4.28977 12.1258 4.24907C12.1671 4.20836 12.1998 4.15985 12.2222 4.10636C12.2446 4.05288 12.2561 3.99548 12.2561 3.9375C12.2561 3.87952 12.2446 3.82211 12.2222 3.76863C12.1998 3.71514 12.1671 3.66663 12.1258 3.62593C12.0845 3.58522 12.0355 3.55312 11.9817 3.5315C11.9279 3.50989 11.8704 3.49918 11.8124 3.5H11.7548L11.0644 2.46435C10.7671 2.01841 10.2654 1.75 9.7297 1.75H8.43885C8.46234 1.68355 8.46943 1.61242 8.45952 1.54265C8.44961 1.47288 8.423 1.40654 8.38194 1.34926C8.34089 1.29199 8.2866 1.24547 8.22371 1.21368C8.16082 1.18189 8.09118 1.16576 8.02072 1.16666H5.97905ZM4.27007 2.625H9.7297C9.97394 2.625 10.2009 2.74639 10.3364 2.9497L10.7033 3.5H3.29651L3.66338 2.9497L3.66395 2.94913C3.79913 2.74608 4.02543 2.625 4.27007 2.625ZM3.40361 4.375H10.5962L9.88465 11.015C9.8445 11.3894 9.53575 11.6667 9.15947 11.6667H4.83973C4.46345 11.6667 4.15527 11.3894 4.11512 11.015L3.40361 4.375Z", fill: "currentColor" })));
1987
1969
  const SvgChat = (props) => /* @__PURE__ */ React.createElement("svg", { width: 16, height: 17, viewBox: "0 0 16 17", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M8 3C4.55375 3 1.75 5.23753 1.75 7.98828C1.75 9.70653 2.83659 11.2762 4.62109 12.188C4.11184 13.0465 3.62587 13.7378 3.62012 13.7461C3.50687 13.9071 3.49862 14.1196 3.59912 14.2891C3.69012 14.4418 3.8543 14.5342 4.0293 14.5342C4.0483 14.5342 4.06743 14.533 4.08643 14.5308C4.15168 14.5233 5.66214 14.3364 7.50439 12.9604C7.67239 12.9712 7.8385 12.9766 8 12.9766C11.4462 12.9766 14.25 10.739 14.25 7.98828C14.25 5.23753 11.4462 3 8 3ZM8 4C10.8948 4 13.25 5.78903 13.25 7.98828C13.25 10.1875 10.8948 11.9766 8 11.9766C7.8055 11.9766 7.60225 11.968 7.396 11.9497C7.271 11.9382 7.1454 11.9752 7.0459 12.0527C6.3589 12.5855 5.72033 12.9308 5.20508 13.1528C5.38383 12.8648 5.57691 12.5418 5.76416 12.2061C5.83416 12.0813 5.84705 11.9324 5.7998 11.7974C5.75255 11.6624 5.64983 11.5542 5.51758 11.5C3.81033 10.7993 2.75 9.45328 2.75 7.98828C2.75 5.78903 5.10525 4 8 4ZM5.5 7.25C5.08575 7.25 4.75 7.58575 4.75 8C4.75 8.41425 5.08575 8.75 5.5 8.75C5.91425 8.75 6.25 8.41425 6.25 8C6.25 7.58575 5.91425 7.25 5.5 7.25ZM8 7.25C7.58575 7.25 7.25 7.58575 7.25 8C7.25 8.41425 7.58575 8.75 8 8.75C8.41425 8.75 8.75 8.41425 8.75 8C8.75 7.58575 8.41425 7.25 8 7.25ZM10.5 7.25C10.0857 7.25 9.75 7.58575 9.75 8C9.75 8.41425 10.0857 8.75 10.5 8.75C10.9143 8.75 11.25 8.41425 11.25 8C11.25 7.58575 10.9143 7.25 10.5 7.25Z", fill: "currentColor" }));
1988
1970
  const SessionListItem = ({
@@ -2023,6 +2005,48 @@ const SessionListItem = ({
2023
2005
  }
2024
2006
  );
2025
2007
  };
2008
+ const SessionsList = ({
2009
+ children,
2010
+ templates
2011
+ }) => {
2012
+ const { theme, isCompact, activeSessionId, createSession } = useContext(ChatContext);
2013
+ const isVisible = isCompact && !activeSessionId;
2014
+ return (!isCompact || isVisible) && /* @__PURE__ */ jsxs(
2015
+ motion.div,
2016
+ {
2017
+ initial: { translateX: "-100%" },
2018
+ animate: {
2019
+ translateX: "0%",
2020
+ transition: {
2021
+ type: "tween",
2022
+ ease: "linear",
2023
+ duration: 0.2,
2024
+ when: "beforeChildren"
2025
+ }
2026
+ },
2027
+ exit: { translateX: "-100%" },
2028
+ className: cn(theme.sessions.base, {
2029
+ [theme.sessions.companion]: isCompact,
2030
+ [theme.sessions.console]: !isCompact
2031
+ }),
2032
+ children: [
2033
+ /* @__PURE__ */ jsx(List, { children }),
2034
+ templates && !activeSessionId && /* @__PURE__ */ jsx("div", { className: "mt-4", children: templates.map((template) => /* @__PURE__ */ jsx("div", { onClick: () => createSession == null ? void 0 : createSession(), children: /* @__PURE__ */ jsx(
2035
+ SessionListItem,
2036
+ {
2037
+ session: {
2038
+ id: template.id,
2039
+ title: template.title,
2040
+ conversations: []
2041
+ },
2042
+ chatIcon: template.icon,
2043
+ deletable: false
2044
+ }
2045
+ ) }, template.id)) })
2046
+ ]
2047
+ }
2048
+ );
2049
+ };
2026
2050
  const SvgPlus = (props) => /* @__PURE__ */ React.createElement("svg", { width: 17, height: 17, viewBox: "0 0 17 17", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props }, /* @__PURE__ */ React.createElement("g", { id: "add" }, /* @__PURE__ */ React.createElement("path", { id: "Vector", d: "M13.1667 9.16658H9.16671V13.1666H7.83337V9.16658H3.83337V7.83325H7.83337V3.83325H9.16671V7.83325H13.1667V9.16658Z", fill: "currentColor" })));
2027
2051
  const NewSessionButton = ({
2028
2052
  children,
@@ -2130,7 +2154,15 @@ const SessionGroups = ({ children }) => {
2130
2154
  const groups = useMemo(() => groupSessionsByDate(sessions), [sessions]);
2131
2155
  return /* @__PURE__ */ jsx(Fragment, { children: children ? children(groups) : groups.map(({ heading, sessions: sessions2 }) => /* @__PURE__ */ jsx(SessionsGroup, { heading, children: sessions2.map((session) => /* @__PURE__ */ jsx(SessionListItem, { session }, session.id)) })) });
2132
2156
  };
2157
+ const AppBar = ({
2158
+ content,
2159
+ theme: customTheme = chatTheme
2160
+ }) => {
2161
+ const theme = useComponentTheme("chat", customTheme);
2162
+ return /* @__PURE__ */ jsx("div", { className: cn(theme.appbar), children: content });
2163
+ };
2133
2164
  export {
2165
+ AppBar as A,
2134
2166
  ChatInput as C,
2135
2167
  FileInput as F,
2136
2168
  MessageSource as M,
@@ -2164,4 +2196,4 @@ export {
2164
2196
  light as y,
2165
2197
  ChatContext as z
2166
2198
  };
2167
- //# sourceMappingURL=index-BoPOnul2.js.map
2199
+ //# sourceMappingURL=index-B4HlLXxa.js.map