import { useState, useRef, FC, useContext, useEffect } from 'react'; import AttachIcon from './assets/paperclip.svg?react'; import { Meta } from '@storybook/react-vite'; import { Chat, Session, remarkCve, SessionsList, SessionsGroup, SessionListItem, NewSessionButton, SessionMessages, SessionGroups, ChatInput, SessionListItemProps, SessionMessagePanel, SessionMessagesHeader, ChatContext, Message, SessionMessage, MessageStatus, MessageStatusStep, MessageStatusState } from 'reachat'; import { Card, Chip, cn, DateFormat, Divider, IconButton, List, ListItem, Menu } from 'reablocks'; import { subDays, subMinutes, subHours } from 'date-fns'; import MenuIcon from './assets/menu.svg?react'; import Placeholder from './assets/placeholder.svg?react'; import PlaceholderDark from './assets/placeholder-dark.svg?react'; import { MessageActions } from 'reachat'; import { MessageFiles } from 'reachat'; import { MessageSources } from 'reachat'; import { fakeSessions, fakeSessionsWithEmbeds, sessionWithSources, sessionsWithFiles, sessionsWithPendingResponse, sessionWithCSVFiles, createSendMessageHandler } from './examples'; export default { title: 'Demos/Console', component: Chat } as Meta; export const Basic = () => { const [activeId, setActiveId] = useState(fakeSessions[0].id); const [sessions, setSessions] = useState(fakeSessions); return (
alert('delete!')} onSendMessage={createSendMessageHandler(setSessions, activeId)} >
); }; export const Embeds = () => { const [activeId, setActiveId] = useState('1'); const [sessions, setSessions] = useState(fakeSessionsWithEmbeds); return (
alert('delete!')} onSendMessage={createSendMessageHandler(setSessions, activeId)} >
); }; export const DefaultSession = () => { const [activeId, setActiveId] = useState('1'); const [sessions, setSessions] = useState(fakeSessions); return (
alert('delete!')} onSendMessage={createSendMessageHandler(setSessions, activeId)} >
); }; export const Loading = () => { return (
alert('delete!')} >
); }; export const FileUploads = () => { const [sessions, setSessions] = useState(sessionsWithFiles); const [selectedFile, setSelectedFile] = useState(null); return (
setSessions((sessions) => { const session = sessions[0]; setSelectedFile(null); return [{ ...session, messages: [ ...session.messages, { id: (Math.random() * 100).toString(), role: 'user', createdAt: new Date(), content: message, ...(selectedFile ? { files: [{ name: selectedFile.name, size: selectedFile.size, type: selectedFile.type, }]} : {}) } ] }]; })} onFileUpload={setSelectedFile} onDeleteSession={() => alert('delete!')} > } allowedFiles={['.pdf', '.docx']} />
); }; export const DefaultInputValue = () => { const [activeId, setActiveId] = useState('1'); const [sessions, setSessions] = useState(fakeSessions); return (
alert('delete!')} onSendMessage={createSendMessageHandler(setSessions, activeId)} >
); }; export const UndeleteableSessions = () => { const [activeId, setActiveId] = useState('1'); const [sessions, setSessions] = useState(fakeSessions); return (
{groups => groups.map(({ heading, sessions }) => ( {sessions.map(s => ( ))} )) }
); }; export const SessionGrouping = () => { const createSessionWithDate = ( id: string, title: string, daysAgo: number ): Session => ({ id, title, createdAt: subDays(new Date(), daysAgo), updatedAt: subDays(new Date(), daysAgo), messages: [ { id: `${id}-1`, role: 'user', content: 'Sample question', createdAt: subDays(new Date(), daysAgo) }, { id: `${id}-2`, role: 'assistant', content: 'Sample response', createdAt: subDays(new Date(), daysAgo), updatedAt: subDays(new Date(), daysAgo) } ] }); const sessionsWithVariousDates: Session[] = [ createSessionWithDate('1', 'Today Session', 0), createSessionWithDate('2', 'Yesterday Session', 1), createSessionWithDate('3', 'Yesterday Session 2', 1), createSessionWithDate('4', 'Last Week Session', 6), createSessionWithDate('5', 'Two Weeks Ago Session', 14), createSessionWithDate('6', 'Last Month Session', 32), createSessionWithDate('7', 'Two Months Ago Session', 65), createSessionWithDate('8', 'Six Months Ago Session', 180), createSessionWithDate('9', 'Last Year Session', 370), createSessionWithDate('10', 'Two Years Ago Session', 740) ]; return (
{}} >
); }; export const HundredSessions = () => { const generateFakeSessions = (count: number): Session[] => { return Array.from({ length: count }, (_, index) => ({ id: `session-${index + 1}`, title: `Session ${index + 1}`, createdAt: subDays(new Date(), index), updatedAt: subDays(new Date(), index), messages: [ { id: `msg-${index}-1`, role: 'user', content: `Question for session ${index + 1}`, createdAt: subDays(new Date(), index) }, { id: `msg-${index}-2`, role: 'assistant', content: `Response for session ${index + 1}`, createdAt: subDays(new Date(), index), updatedAt: subDays(new Date(), index) } ] })); }; const hundredSessions = generateFakeSessions(100); return (
); }; export const HundredMessages = () => { const generateFakeMessages = (turns: number): Message[] => Array.from({ length: turns }, (_, index) => [ { id: `msg-${index + 1}-user`, role: 'user', content: `Question ${index + 1}: What is the meaning of life, the universe, and everything?`, createdAt: subMinutes(new Date(), turns - index) }, { id: `msg-${index + 1}-assistant`, role: 'assistant', content: `Answer ${index + 1}: According to The Hitchhiker's Guide to the Galaxy, it's 42. But in reality, that's a complex philosophical question that has puzzled humanity for centuries.`, createdAt: subMinutes(new Date(), turns - index), updatedAt: subMinutes(new Date(), turns - index) } ]).flat(); const sessionWithHundredMessages: Session[] = [ { id: 'session-100', title: 'Session with 100 Messages', createdAt: subHours(new Date(), 5), updatedAt: new Date(), messages: generateFakeMessages(50) } ]; return (
); }; export const LongSessionNames = () => { const generateFakeSessionsWithLongNames = (count: number) => { return Array.from({ length: count }, (_, index) => ({ id: `session-${index + 1}`, title: `Session ${index + 1}: This is a very long session name to test how the UI handles overflow and text wrapping in the session list. It should be truncated or wrapped appropriately to ensure a good user experience.`, createdAt: subHours(new Date(), count - index), updatedAt: new Date(), messages: [ { id: '1-user', role: 'user', content: 'Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics?', createdAt: new Date() }, { id: '1-assistant', role: 'assistant', content: 'Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics?', createdAt: new Date(), updatedAt: new Date() } ] })); }; const sessionsWithLongNames = generateFakeSessionsWithLongNames(10); return (
); }; export const MarkdownShowcase = () => { const markdownQuestion = ` **What is the purpose of life?** `; const markdownResponse = ` **The purpose of life is a philosophical question concerning the significance of life or existence in general.** 1. Burning of fossil fuels (coal, oil, and natural gas) 2. Deforestation and land-use changes 3. Industrial processes 4. Agriculture and livestock farming or - Burning - Deforestation - Industrial - Agriculture Here is a table to illustrate different perspectives: | Perspective | Description | |-------------------|-----------------------------------------------------------------------------| | Religious | Belief in a higher power or divine purpose. | | Philosophical | Various theories including existentialism, nihilism, and absurdism. | | Scientific | Understanding life through biology, evolution, and the universe. | | Personal | Individual goals, happiness, and fulfillment. | \`\`\`python def purpose_of_life(): return 42 \`\`\` \`\`\`json { "perspectives": [ { "type": "Religious", "description": "Belief in a higher power or divine purpose." }, { "type": "Philosophical", "description": "Various theories including existentialism, nihilism, and absurdism." }, { "type": "Scientific", "description": "Understanding life through biology, evolution, and the universe." }, { "type": "Personal", "description": "Individual goals, happiness, and fulfillment." } ] } \`\`\` The answer to the ultimate question of life, the universe, and everything is **42**. \`\`\`math L = \\frac{1}{2} \\rho v^2 S C_L \`\`\` [Perspective](https://en.wikipedia.org/wiki/Philosophical_question) `; const sessionWithMarkdown: Session[] = [ { id: 'session-markdown', title: 'Markdown Showcase', createdAt: subHours(new Date(), 1), updatedAt: new Date(), messages: [ { id: 'message-1', role: 'user', content: markdownQuestion, createdAt: new Date() }, { id: 'message-2', role: 'assistant', content: markdownResponse, createdAt: new Date() } ] } ]; return (
); }; export const CVEExample = () => { const markdownQuestion = `# Security Report Please review the following CVEs: - CVE-2021-34527 - CVE-2021-44228 - CVE-2021-45046 `; const markdownResponse = `## Analysis The listed CVEs are critical vulnerabilities that need immediate attention. - CVE-2021-34527 - CVE-2021-44228 - CVE-2021-45046 `; const sessionWithMarkdown: Session[] = [ { id: 'session-cve', title: 'CVE Showcase', createdAt: subHours(new Date(), 1), updatedAt: new Date(), messages: [ { id: 'message-1', role: 'user', content: markdownQuestion, createdAt: new Date() }, { id: 'message-2', role: 'assistant', content: markdownResponse, createdAt: new Date() } ] } ]; return (
); }; export const Empty = () => { return (
alert('delete!')} > {groups => ( <> {groups.map(({ heading, sessions }) => ( {sessions.map(s => ( ))} ))} {groups.length === 0 && (

No sessions yet. Start a new session!

)} )}

Welcome to Reachat, a UI library for effortlessly building and customizing chat experiences with Tailwind.

} />
); }; export const ConversationSources = () => { const [activeId, setActiveId] = useState('session-sources'); const [sessions, setSessions] = useState(sessionWithSources); return (
); }; const CustomMessagesHeader: FC = () => { const { activeSession } = useContext(ChatContext); return (

{activeSession?.title}

); }; const CustomUserMessage: FC = ({ content, files }) => ( <> This is my question: {content} ); const CustomAssistantMessage: FC = ({ content }) => (
This is the response: {content}
); const CustomMessageFile: FC = ({ name, type }) => ( {name || type} ); const CustomMessageSource: FC = ({ title, url, image }) => { const { theme } = useContext(ChatContext); return ( alert('take me to ' + url)} start={ image && ( {title} ) } > {title || url} ); }; const CustomSessionListItem: FC = ({ session, children, ...rest }) => { const [open, setOpen] = useState(false); const btnRef = useRef(null); return ( <> { e.stopPropagation(); setOpen(true); }} > } > {session.title} setOpen(false)} reference={btnRef} appendToBody={false} > alert('rename')}>Rename alert('delete')}>Delete ); }; export const CustomComponents = () => { const [activeId, setActiveId] = useState('1'); const [sessions, setSessions] = useState([ ...fakeSessions, ...sessionsWithFiles, ...sessionWithSources ]); return (
{groups => groups.map(({ heading, sessions }) => ( {sessions.map(s => ( ))} )) } {messages => messages.map((message, index) => ( {message.role === 'user' ? ( ) : ( <> )} )) }
); }; export const ImageFiles = () => { const staticImageFiles = [ { id: '1', name: 'landscape.jpg', type: 'image/jpeg', url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faustin.1ee6ee64.jpg&w=640&q=75' }, { id: '2', name: 'portrait.jpg', type: 'image/jpeg', url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fandrew.50c21037.jpeg&w=640&q=75' }, { id: '3', name: 'abstract.png', type: 'image/jpg', url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fkyle.52befaed.jpg&w=640&q=75' }, { id: '4', name: 'nature.jpg', type: 'image/jpeg', url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsteph.8a52b5d2.jpg&w=640&q=75' } ]; const [sessions, setSessions] = useState([ { id: 'session-images', title: 'Multiple Image Files Showcase', createdAt: subHours(new Date(), 1), updatedAt: new Date(), messages: [ { id: 'message-1', role: 'user', content: 'Analyze these images and describe what you see.', createdAt: new Date(), files: staticImageFiles }, { id: 'message-2', role: 'assistant', content: 'I\'m sorry, but as an AI language model, I cannot actually see or analyze images. I can only process and respond to text input. If you\'d like me to describe or analyze images, you would need to provide detailed textual descriptions of the images.', createdAt: new Date() }, { id: 'message-3', role: 'user', content: 'Analyze these images and describe what you see.', createdAt: new Date(), files: [staticImageFiles[0]] }, { id: 'message-4', role: 'assistant', content: 'I\'m sorry, but as an AI language model, I cannot actually see or analyze images. I can only process and respond to text input. If you\'d like me to describe or analyze images, you would need to provide detailed textual descriptions of the images.', createdAt: new Date() } ] } ]); return (
); }; export const CSVPreview = () => { const [sessions, setSessions] = useState(sessionWithCSVFiles); return (
alert('delete!')} onSendMessage={createSendMessageHandler(setSessions, '1')} >
); }; export const WithToolStatus = () => { const [status, setStatus] = useState('loading'); const [steps, setSteps] = useState([ { id: '1', text: 'Reading src/index.ts', status: 'loading' } ]); useEffect(() => { const timeline = [ { delay: 1500, action: () => { setSteps(prev => prev.map(s => (s.id === '1' ? { ...s, status: 'complete' as const } : s)) ); } }, { delay: 2000, action: () => { setSteps(prev => [ ...prev, { id: '2', text: 'Searching for dependencies', status: 'loading' as const } ]); } }, { delay: 3500, action: () => { setSteps(prev => prev.map(s => (s.id === '2' ? { ...s, status: 'complete' as const } : s)) ); } }, { delay: 4000, action: () => { setSteps(prev => [ ...prev, { id: '3', text: 'Analyzing code patterns', status: 'loading' as const } ]); } }, { delay: 6000, action: () => { setSteps(prev => prev.map(s => (s.id === '3' ? { ...s, status: 'complete' as const } : s)) ); setStatus('complete'); } } ]; const timeouts = timeline.map(item => setTimeout(item.action, item.delay)); return () => timeouts.forEach(clearTimeout); }, []); const sessionWithToolStatus: Session[] = [ { id: 'session-tool-status', title: 'Tool Status Demo', createdAt: subHours(new Date(), 1), updatedAt: new Date(), messages: [ { id: 'message-1', role: 'user', content: 'Can you analyze my codebase and find any issues?', createdAt: new Date() }, { id: 'message-2', role: 'assistant', content: 'I\'ll analyze your codebase now. Let me read through the files and check for any potential issues.', createdAt: new Date() } ] } ]; return (
{messages => ( <> {messages.map((message, index) => ( ))}
)}
); };