reachat 2.1.0-alpha.7 → 2.1.0-alpha.8

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.
@@ -3,7 +3,7 @@ import { AnimatePresence, motion } from "motion/react";
3
3
  import { IconButton } from "reablocks";
4
4
  import * as React from "react";
5
5
  import { useContext, useState, useRef, useEffect } from "react";
6
- import { C as ChatContext, a as SvgCopy } from "./index-Dex9wQ_j.js";
6
+ import { C as ChatContext, a as SvgCopy } from "./index-DRRvnZUj.js";
7
7
  const SvgDownload = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "24px", height: "24px", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M 11 2 C 10.448 2 10 2.448 10 3 L 10 11 L 6.5 11 A 0.5 0.5 0 0 0 6 11.5 A 0.5 0.5 0 0 0 6.1464844 11.853516 A 0.5 0.5 0 0 0 6.1777344 11.882812 L 11.283203 16.697266 L 11.316406 16.728516 A 1 1 0 0 0 12 17 A 1 1 0 0 0 12.683594 16.728516 L 12.697266 16.716797 A 1 1 0 0 0 12.707031 16.705078 L 17.810547 11.892578 A 0.5 0.5 0 0 0 17.839844 11.865234 L 17.847656 11.859375 A 0.5 0.5 0 0 0 17.853516 11.853516 A 0.5 0.5 0 0 0 18 11.5 A 0.5 0.5 0 0 0 17.5 11 L 14 11 L 14 3 C 14 2.448 13.552 2 13 2 L 12 2 L 11 2 z M 3 20 A 1.0001 1.0001 0 1 0 3 22 L 21 22 A 1.0001 1.0001 0 1 0 21 20 L 3 20 z", fill: "currentColor" }));
8
8
  const sanitizeSVGCell = (cell) => {
9
9
  const trimmed = cell.trim();
@@ -139,4 +139,4 @@ const CSVFileRenderer = ({ name, url, fileIcon }) => {
139
139
  export {
140
140
  CSVFileRenderer as default
141
141
  };
142
- //# sourceMappingURL=CSVFileRenderer-C2bdkP1w.js.map
142
+ //# sourceMappingURL=CSVFileRenderer-CaWN5iTb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CSVFileRenderer-C2bdkP1w.js","sources":["../src/assets/download.svg?react","../src/utils/sanitize.ts","../src/utils/parseCSV.ts","../src/SessionMessages/SessionMessage/MessageFile/renderers/CSVFileRenderer.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgDownload = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", viewBox: \"0 0 24 24\", width: \"24px\", height: \"24px\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M 11 2 C 10.448 2 10 2.448 10 3 L 10 11 L 6.5 11 A 0.5 0.5 0 0 0 6 11.5 A 0.5 0.5 0 0 0 6.1464844 11.853516 A 0.5 0.5 0 0 0 6.1777344 11.882812 L 11.283203 16.697266 L 11.316406 16.728516 A 1 1 0 0 0 12 17 A 1 1 0 0 0 12.683594 16.728516 L 12.697266 16.716797 A 1 1 0 0 0 12.707031 16.705078 L 17.810547 11.892578 A 0.5 0.5 0 0 0 17.839844 11.865234 L 17.847656 11.859375 A 0.5 0.5 0 0 0 17.853516 11.853516 A 0.5 0.5 0 0 0 18 11.5 A 0.5 0.5 0 0 0 17.5 11 L 14 11 L 14 3 C 14 2.448 13.552 2 13 2 L 12 2 L 11 2 z M 3 20 A 1.0001 1.0001 0 1 0 3 22 L 21 22 A 1.0001 1.0001 0 1 0 21 20 L 3 20 z\", fill: \"currentColor\" }));\nexport default SvgDownload;\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 { AnimatePresence, motion } from 'motion/react';\nimport { IconButton } from 'reablocks';\nimport type { FC, ReactElement } from 'react';\nimport { useContext, useEffect, useRef, useState } from 'react';\n\nimport PlaceholderIcon from '@/assets/copy.svg?react';\nimport DownloadIcon from '@/assets/download.svg?react';\nimport { ChatContext } from '@/ChatContext';\nimport { parseCSV } from '@/utils/parseCSV';\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 { theme } = useContext(ChatContext);\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 light:border-gray-700 hover:bg-panel-accent hover:light:bg-gray-700/40 transition-colors text-base\"\n >\n <td className=\"py-4 px-6\">{rowIndex + 1}</td>\n {row.map((cell, cellIndex) => (\n <td key={`cell-${rowIndex}-${cellIndex}`} className=\"py-4 px-6\">\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </motion.table>\n );\n\n return (\n <div className={theme.messages.message.csvPreview.base}>\n <div className={theme.messages.message.csvPreview.header.base}>\n <div className={theme.messages.message.csvPreview.header.icon}>\n {fileIcon}\n {name && <figcaption className=\"ml-1\">{name}</figcaption>}\n </div>\n <div className={theme.messages.message.csvPreview.header.actions}>\n <IconButton size=\"medium\" variant=\"text\" onClick={downloadCSV}>\n <DownloadIcon />\n </IconButton>\n <IconButton size=\"medium\" 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={theme.messages.message.csvPreview.tableContainer}>\n {!error && csvData.length > 0 && renderTable(csvData, 6)}\n </div>\n\n <AnimatePresence>\n {isModalOpen && (\n <motion.div\n className={theme.messages.message.csvPreview.dialog.base}\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={theme.messages.message.csvPreview.dialog.container}\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-CaWN5iTb.js","sources":["../src/assets/download.svg?react","../src/utils/sanitize.ts","../src/utils/parseCSV.ts","../src/SessionMessages/SessionMessage/MessageFile/renderers/CSVFileRenderer.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgDownload = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", viewBox: \"0 0 24 24\", width: \"24px\", height: \"24px\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M 11 2 C 10.448 2 10 2.448 10 3 L 10 11 L 6.5 11 A 0.5 0.5 0 0 0 6 11.5 A 0.5 0.5 0 0 0 6.1464844 11.853516 A 0.5 0.5 0 0 0 6.1777344 11.882812 L 11.283203 16.697266 L 11.316406 16.728516 A 1 1 0 0 0 12 17 A 1 1 0 0 0 12.683594 16.728516 L 12.697266 16.716797 A 1 1 0 0 0 12.707031 16.705078 L 17.810547 11.892578 A 0.5 0.5 0 0 0 17.839844 11.865234 L 17.847656 11.859375 A 0.5 0.5 0 0 0 17.853516 11.853516 A 0.5 0.5 0 0 0 18 11.5 A 0.5 0.5 0 0 0 17.5 11 L 14 11 L 14 3 C 14 2.448 13.552 2 13 2 L 12 2 L 11 2 z M 3 20 A 1.0001 1.0001 0 1 0 3 22 L 21 22 A 1.0001 1.0001 0 1 0 21 20 L 3 20 z\", fill: \"currentColor\" }));\nexport default SvgDownload;\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 { AnimatePresence, motion } from 'motion/react';\nimport { IconButton } from 'reablocks';\nimport type { FC, ReactElement } from 'react';\nimport { useContext, useEffect, useRef, useState } from 'react';\n\nimport PlaceholderIcon from '@/assets/copy.svg?react';\nimport DownloadIcon from '@/assets/download.svg?react';\nimport { ChatContext } from '@/ChatContext';\nimport { parseCSV } from '@/utils/parseCSV';\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 { theme } = useContext(ChatContext);\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 light:border-gray-700 hover:bg-panel-accent hover:light:bg-gray-700/40 transition-colors text-base\"\n >\n <td className=\"py-4 px-6\">{rowIndex + 1}</td>\n {row.map((cell, cellIndex) => (\n <td key={`cell-${rowIndex}-${cellIndex}`} className=\"py-4 px-6\">\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </motion.table>\n );\n\n return (\n <div className={theme.messages.message.csvPreview.base}>\n <div className={theme.messages.message.csvPreview.header.base}>\n <div className={theme.messages.message.csvPreview.header.icon}>\n {fileIcon}\n {name && <figcaption className=\"ml-1\">{name}</figcaption>}\n </div>\n <div className={theme.messages.message.csvPreview.header.actions}>\n <IconButton size=\"medium\" variant=\"text\" onClick={downloadCSV}>\n <DownloadIcon />\n </IconButton>\n <IconButton size=\"medium\" 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={theme.messages.message.csvPreview.tableContainer}>\n {!error && csvData.length > 0 && renderTable(csvData, 6)}\n </div>\n\n <AnimatePresence>\n {isModalOpen && (\n <motion.div\n className={theme.messages.message.csvPreview.dialog.base}\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={theme.messages.message.csvPreview.dialog.container}\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,6 +1,6 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { cn, Ellipsis } from "reablocks";
3
- import { S as SvgFile } from "./index-Dex9wQ_j.js";
3
+ import { S as SvgFile } from "./index-DRRvnZUj.js";
4
4
  const DefaultFileRenderer = ({
5
5
  name,
6
6
  limit = 100,
@@ -12,4 +12,4 @@ const DefaultFileRenderer = ({
12
12
  export {
13
13
  DefaultFileRenderer as default
14
14
  };
15
- //# sourceMappingURL=DefaultFileRenderer-D-KDDNtN.js.map
15
+ //# sourceMappingURL=DefaultFileRenderer-C30msYzW.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultFileRenderer-D-KDDNtN.js","sources":["../src/SessionMessages/SessionMessage/MessageFile/renderers/DefaultFileRenderer.tsx"],"sourcesContent":["import { cn, Ellipsis } from 'reablocks';\nimport type { FC, ReactElement } from 'react';\n\nimport FileIcon from '@/assets/file.svg?react';\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":";;;AA8BA,MAAM,sBAAoD,CAAC;AAAA,EACzD;AAAA,EACA,QAAQ;AAAA,EACR,+BAAYA,SAAA,CAAA,CAAS;AACvB,MACE,qBAAC,UAAA,EAAO,WAAU,2BACf,UAAA;AAAA,EAAA;AAAA,EACA,QACC,oBAAC,cAAA,EAAW,WAAW,GAAG,iBAAiB,GACzC,UAAA,oBAAC,UAAA,EAAS,OAAO,MAAM,MAAA,CAAc,EAAA,CACvC;AAAA,EAAA,CAEJ;"}
1
+ {"version":3,"file":"DefaultFileRenderer-C30msYzW.js","sources":["../src/SessionMessages/SessionMessage/MessageFile/renderers/DefaultFileRenderer.tsx"],"sourcesContent":["import { cn, Ellipsis } from 'reablocks';\nimport type { FC, ReactElement } from 'react';\n\nimport FileIcon from '@/assets/file.svg?react';\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":";;;AA8BA,MAAM,sBAAoD,CAAC;AAAA,EACzD;AAAA,EACA,QAAQ;AAAA,EACR,+BAAYA,SAAA,CAAA,CAAS;AACvB,MACE,qBAAC,UAAA,EAAO,WAAU,2BACf,UAAA;AAAA,EAAA;AAAA,EACA,QACC,oBAAC,cAAA,EAAW,WAAW,GAAG,iBAAiB,GACzC,UAAA,oBAAC,UAAA,EAAS,OAAO,MAAM,MAAA,CAAc,EAAA,CACvC;AAAA,EAAA,CAEJ;"}
@@ -1,5 +1,6 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
2
  import { Plugin } from 'unified';
3
+ import { ChatTheme } from '../theme';
3
4
  interface MarkdownWrapperProps extends PropsWithChildren {
4
5
  /**
5
6
  * Remark plugins to apply to the markdown content.
@@ -9,6 +10,10 @@ interface MarkdownWrapperProps extends PropsWithChildren {
9
10
  * Rehype plugins to apply to the markdown content.
10
11
  */
11
12
  rehypePlugins?: Plugin[];
13
+ /**
14
+ * Theme to apply to the markdown content.
15
+ */
16
+ theme: ChatTheme;
12
17
  }
13
18
  export declare const Markdown: FC<MarkdownWrapperProps>;
14
19
  export {};
@@ -1,6 +1,10 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
2
  import { Conversation } from '../../types';
3
3
  interface SessionMessageProps extends PropsWithChildren {
4
+ /**
5
+ * Class name to apply to the root element.
6
+ */
7
+ className?: string;
4
8
  /**
5
9
  * Conversation to render.
6
10
  */
@@ -1,6 +1,10 @@
1
1
  import { ReactNode, default as React } from 'react';
2
2
  import { Conversation } from '../types';
3
3
  interface SessionMessagesProps {
4
+ /**
5
+ * Class name to apply to the root element.
6
+ */
7
+ className?: string;
4
8
  /**
5
9
  * Content to display when there are no sessions selected or a new session is started.
6
10
  */
package/dist/docs.json CHANGED
@@ -919,6 +919,25 @@
919
919
  "type": {
920
920
  "name": "Plugin[]"
921
921
  }
922
+ },
923
+ "theme": {
924
+ "defaultValue": null,
925
+ "description": "Theme to apply to the markdown content.",
926
+ "name": "theme",
927
+ "parent": {
928
+ "fileName": "src/Markdown/Markdown.tsx",
929
+ "name": "MarkdownWrapperProps"
930
+ },
931
+ "declarations": [
932
+ {
933
+ "fileName": "src/Markdown/Markdown.tsx",
934
+ "name": "MarkdownWrapperProps"
935
+ }
936
+ ],
937
+ "required": true,
938
+ "type": {
939
+ "name": "ChatTheme"
940
+ }
922
941
  }
923
942
  }
924
943
  },
@@ -991,6 +1010,25 @@
991
1010
  "displayName": "SessionMessages",
992
1011
  "methods": [],
993
1012
  "props": {
1013
+ "className": {
1014
+ "defaultValue": null,
1015
+ "description": "Class name to apply to the root element.",
1016
+ "name": "className",
1017
+ "parent": {
1018
+ "fileName": "src/SessionMessages/SessionMessages.tsx",
1019
+ "name": "SessionMessagesProps"
1020
+ },
1021
+ "declarations": [
1022
+ {
1023
+ "fileName": "src/SessionMessages/SessionMessages.tsx",
1024
+ "name": "SessionMessagesProps"
1025
+ }
1026
+ ],
1027
+ "required": false,
1028
+ "type": {
1029
+ "name": "string"
1030
+ }
1031
+ },
994
1032
  "newSessionContent": {
995
1033
  "defaultValue": null,
996
1034
  "description": "Content to display when there are no sessions selected or a new session is started.",
@@ -1771,6 +1809,25 @@
1771
1809
  "displayName": "SessionMessage",
1772
1810
  "methods": [],
1773
1811
  "props": {
1812
+ "className": {
1813
+ "defaultValue": null,
1814
+ "description": "Class name to apply to the root element.",
1815
+ "name": "className",
1816
+ "parent": {
1817
+ "fileName": "src/SessionMessages/SessionMessage/SessionMessage.tsx",
1818
+ "name": "SessionMessageProps"
1819
+ },
1820
+ "declarations": [
1821
+ {
1822
+ "fileName": "src/SessionMessages/SessionMessage/SessionMessage.tsx",
1823
+ "name": "SessionMessageProps"
1824
+ }
1825
+ ],
1826
+ "required": false,
1827
+ "type": {
1828
+ "name": "string"
1829
+ }
1830
+ },
1774
1831
  "conversation": {
1775
1832
  "defaultValue": null,
1776
1833
  "description": "Conversation to render.",
@@ -1486,56 +1486,54 @@ const TableDataCell = ({ children, ...props }) => /* @__PURE__ */ jsx("td", { ..
1486
1486
  const Markdown = ({
1487
1487
  children,
1488
1488
  remarkPlugins,
1489
- rehypePlugins = [rehypeKatex]
1490
- }) => {
1491
- const { theme } = useContext(ChatContext);
1492
- return /* @__PURE__ */ jsx(
1493
- ReactMarkdown,
1494
- {
1495
- remarkPlugins,
1496
- rehypePlugins,
1497
- components: {
1498
- code: ({ className, ...props }) => /* @__PURE__ */ jsx(
1499
- CodeHighlighter,
1500
- {
1501
- ...props,
1502
- language: className,
1503
- className: cn(theme.messages.message.markdown.code, className),
1504
- copyClassName: cn(theme.messages.message.markdown.copy),
1505
- toolbarClassName: cn(theme.messages.message.markdown.toolbar)
1506
- }
1507
- ),
1508
- table: (props) => /* @__PURE__ */ jsx(
1509
- TableComponent,
1510
- {
1511
- ...props,
1512
- className: cn(theme.messages.message.markdown.table)
1513
- }
1514
- ),
1515
- th: (props) => /* @__PURE__ */ jsx(
1516
- TableHeaderCell,
1517
- {
1518
- ...props,
1519
- className: cn(theme.messages.message.markdown.th)
1520
- }
1521
- ),
1522
- td: (props) => /* @__PURE__ */ jsx(
1523
- TableDataCell,
1524
- {
1525
- ...props,
1526
- className: cn(theme.messages.message.markdown.td)
1527
- }
1528
- ),
1529
- a: (props) => /* @__PURE__ */ jsx("a", { ...props, className: cn(theme.messages.message.markdown.a) }),
1530
- p: (props) => /* @__PURE__ */ jsx("p", { ...props, className: cn(theme.messages.message.markdown.p) }),
1531
- li: (props) => /* @__PURE__ */ jsx("li", { ...props, className: cn(theme.messages.message.markdown.li) }),
1532
- ul: (props) => /* @__PURE__ */ jsx("ul", { ...props, className: cn(theme.messages.message.markdown.ul) }),
1533
- ol: (props) => /* @__PURE__ */ jsx("ol", { ...props, className: cn(theme.messages.message.markdown.ol) })
1534
- },
1535
- children
1536
- }
1537
- );
1538
- };
1489
+ rehypePlugins = [rehypeKatex],
1490
+ theme
1491
+ }) => /* @__PURE__ */ jsx(
1492
+ ReactMarkdown,
1493
+ {
1494
+ remarkPlugins,
1495
+ rehypePlugins,
1496
+ components: {
1497
+ code: ({ className, ...props }) => /* @__PURE__ */ jsx(
1498
+ CodeHighlighter,
1499
+ {
1500
+ ...props,
1501
+ language: className,
1502
+ className: cn(theme.messages.message.markdown.code, className),
1503
+ copyClassName: cn(theme.messages.message.markdown.copy),
1504
+ toolbarClassName: cn(theme.messages.message.markdown.toolbar)
1505
+ }
1506
+ ),
1507
+ table: (props) => /* @__PURE__ */ jsx(
1508
+ TableComponent,
1509
+ {
1510
+ ...props,
1511
+ className: cn(theme.messages.message.markdown.table)
1512
+ }
1513
+ ),
1514
+ th: (props) => /* @__PURE__ */ jsx(
1515
+ TableHeaderCell,
1516
+ {
1517
+ ...props,
1518
+ className: cn(theme.messages.message.markdown.th)
1519
+ }
1520
+ ),
1521
+ td: (props) => /* @__PURE__ */ jsx(
1522
+ TableDataCell,
1523
+ {
1524
+ ...props,
1525
+ className: cn(theme.messages.message.markdown.td)
1526
+ }
1527
+ ),
1528
+ a: (props) => /* @__PURE__ */ jsx("a", { ...props, className: cn(theme.messages.message.markdown.a) }),
1529
+ p: (props) => /* @__PURE__ */ jsx("p", { ...props, className: cn(theme.messages.message.markdown.p) }),
1530
+ li: (props) => /* @__PURE__ */ jsx("li", { ...props, className: cn(theme.messages.message.markdown.li) }),
1531
+ ul: (props) => /* @__PURE__ */ jsx("ul", { ...props, className: cn(theme.messages.message.markdown.ul) }),
1532
+ ol: (props) => /* @__PURE__ */ jsx("ol", { ...props, className: cn(theme.messages.message.markdown.ol) })
1533
+ },
1534
+ children
1535
+ }
1536
+ );
1539
1537
  const CVE_REGEX = /(CVE-(19|20)\d{2}-\d{4,7})/gi;
1540
1538
  function remarkCve() {
1541
1539
  return (tree) => {
@@ -1633,9 +1631,9 @@ ${response}`),
1633
1631
  };
1634
1632
  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" }));
1635
1633
  const DefaultFileRenderer = lazy(
1636
- () => import("./DefaultFileRenderer-D-KDDNtN.js")
1634
+ () => import("./DefaultFileRenderer-C30msYzW.js")
1637
1635
  );
1638
- const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-C2bdkP1w.js"));
1636
+ const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-CaWN5iTb.js"));
1639
1637
  const ImageFileRenderer = lazy(() => import("./ImageFileRenderer-C8tVW3I8.js"));
1640
1638
  const PDFFileRenderer = lazy(() => import("./PDFFileRenderer-BBn2EVrV.js"));
1641
1639
  const FILE_TYPE_RENDERER_MAP = {
@@ -1742,7 +1740,7 @@ const MessageQuestion = ({
1742
1740
  ...props,
1743
1741
  children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
1744
1742
  /* @__PURE__ */ jsx(MessageFiles, { files }),
1745
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: question }),
1743
+ /* @__PURE__ */ jsx(Markdown, { remarkPlugins, theme, children: question }),
1746
1744
  isLong && !expanded && /* @__PURE__ */ jsx(
1747
1745
  Button,
1748
1746
  {
@@ -1770,7 +1768,7 @@ const MessageResponse = ({
1770
1768
  "data-compact": isCompact,
1771
1769
  className: cn(theme.messages.message.response),
1772
1770
  children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
1773
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: response }),
1771
+ /* @__PURE__ */ jsx(Markdown, { remarkPlugins, theme, children: response }),
1774
1772
  isLoading && /* @__PURE__ */ jsx(
1775
1773
  motion.div,
1776
1774
  {
@@ -1856,13 +1854,14 @@ const messageVariants = {
1856
1854
  }
1857
1855
  };
1858
1856
  const SessionMessage = ({
1857
+ className,
1859
1858
  conversation,
1860
1859
  isLast,
1861
1860
  children
1862
1861
  }) => {
1863
1862
  const { theme, isLoading } = useContext(ChatContext);
1864
1863
  return /* @__PURE__ */ jsxs(motion.div, { variants: messageVariants, children: [
1865
- /* @__PURE__ */ jsx(Card, { className: cn(theme.messages.message.base), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
1864
+ /* @__PURE__ */ jsx(Card, { className: cn(theme.messages.message.base, className), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
1866
1865
  /* @__PURE__ */ jsx(
1867
1866
  MessageQuestion,
1868
1867
  {
@@ -1946,6 +1945,7 @@ const SessionMessages = ({
1946
1945
  children,
1947
1946
  newSessionContent,
1948
1947
  limit = 10,
1948
+ className,
1949
1949
  showMoreText = "Show more",
1950
1950
  autoScroll = true
1951
1951
  }) => {
@@ -1976,7 +1976,7 @@ const SessionMessages = ({
1976
1976
  if (!activeSession) {
1977
1977
  return /* @__PURE__ */ jsx(SessionEmpty, { children: newSessionContent });
1978
1978
  }
1979
- return /* @__PURE__ */ jsxs("div", { className: cn(theme.messages.content), ref: contentRef, children: [
1979
+ return /* @__PURE__ */ jsxs("div", { className: cn(theme.messages.content, className), ref: contentRef, children: [
1980
1980
  hasMore && /* @__PURE__ */ jsx(
1981
1981
  Button,
1982
1982
  {
@@ -2219,6 +2219,7 @@ export {
2219
2219
  AppBar as A,
2220
2220
  chatTheme as B,
2221
2221
  ChatContext as C,
2222
+ groupSessionsByDate as D,
2222
2223
  FileInput as F,
2223
2224
  Markdown as M,
2224
2225
  NewSessionButton as N,
@@ -2251,4 +2252,4 @@ export {
2251
2252
  SessionsGroup as y,
2252
2253
  SessionsList as z
2253
2254
  };
2254
- //# sourceMappingURL=index-Dex9wQ_j.js.map
2255
+ //# sourceMappingURL=index-DRRvnZUj.js.map