diff --git a/.storybook/theme.ts b/.storybook/theme.ts index 4787ff6..8939607 100644 --- a/.storybook/theme.ts +++ b/.storybook/theme.ts @@ -1,5 +1,5 @@ import { create } from '@storybook/theming/create'; -import ReachatLogo from './logo.svg'; +import ReachatLogo from '../src/assets/logo/logo.svg?react'; export default create({ base: 'dark', diff --git a/package-lock.json b/package-lock.json index ce10ad6..fddbdac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "reachat", - "version": "1.6.0", + "version": "1.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "reachat", - "version": "1.6.0", + "version": "1.6.1", "license": "Apache-2.0", "dependencies": { "@ai-sdk/openai": "^1.1.9", diff --git a/package.json b/package.json index 2932800..55989f5 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,9 @@ "source": "src/index.ts", "exports": { ".": { + "types": "./dist/index.d.ts", "import": "./dist/index.js", - "require": "./dist/index.umd.cjs", - "types": "./dist/index.d.ts" + "require": "./dist/index.umd.cjs" }, "./docs.json": "./dist/docs.json", "./index.css": "./dist/index.css" diff --git a/src/AppBar/AppBar.tsx b/src/AppBar/AppBar.tsx new file mode 100644 index 0000000..80dfc64 --- /dev/null +++ b/src/AppBar/AppBar.tsx @@ -0,0 +1,16 @@ +import React, { ReactNode, FC, useContext } from 'react'; +import { cn } from 'reablocks'; +import { ChatContext } from '../ChatContext'; + +export interface AppBarProps { + /** + * Content to display in the header + */ + content?: ReactNode; +} + +export const AppBar: FC = ({ content }) => { + const { theme } = useContext(ChatContext); + + return
{content}
; +}; diff --git a/src/AppBar/index.ts b/src/AppBar/index.ts new file mode 100644 index 0000000..60f2f0e --- /dev/null +++ b/src/AppBar/index.ts @@ -0,0 +1 @@ +export * from './AppBar'; diff --git a/src/assets/close-fill.svg b/src/assets/close-fill.svg new file mode 100644 index 0000000..4d05cbf --- /dev/null +++ b/src/assets/close-fill.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.storybook/logo.png b/src/assets/logo/logo.png similarity index 100% rename from .storybook/logo.png rename to src/assets/logo/logo.png diff --git a/.storybook/logo.svg b/src/assets/logo/logo.svg similarity index 100% rename from .storybook/logo.svg rename to src/assets/logo/logo.svg diff --git a/src/index.ts b/src/index.ts index b21e45e..fc120c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,3 +6,4 @@ export * from './types'; export * from './theme'; export * from './Markdown'; export * from './ChatContext'; +export * from './AppBar'; diff --git a/src/theme.ts b/src/theme.ts index 3c8e247..9c0b069 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -3,6 +3,7 @@ export interface ChatTheme { console: string; companion: string; empty: string; + header: string; sessions: { base: string; console: string; @@ -89,6 +90,7 @@ export const chatTheme: ChatTheme = { console: 'flex w-full gap-4 h-full', companion: 'w-full h-full overflow-hidden', empty: 'text-center flex-1', + header: 'pb-10', sessions: { base: 'overflow-auto', console: @@ -132,7 +134,10 @@ export const chatTheme: ChatTheme = { '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', 'dark:bg-gray-900/60 dark:border-gray-700/50 dark:text-gray-100' ].join(' '), - response: ['relative data-[compact=false]:px-4 text-gray-900', 'dark:text-gray-100'].join(' '), + response: [ + 'relative data-[compact=false]:px-4 text-gray-900', + 'dark:text-gray-100' + ].join(' '), 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`, cursor: 'inline-block w-1 h-4 bg-current', expand: 'absolute bottom-1 right-1 z-10', @@ -167,7 +172,8 @@ export const chatTheme: ChatTheme = { th: 'px-4 py-2 text-left font-bold border-b border-gray-500', td: 'px-4 py-2', code: 'm-2 rounded-b relative', - toolbar: 'text-xs dark:bg-gray-700/50 flex items-center justify-between px-2 py-1 rounded-t sticky top-0 backdrop-blur-md bg-gray-200 ', + toolbar: + 'text-xs dark:bg-gray-700/50 flex items-center justify-between px-2 py-1 rounded-t sticky top-0 backdrop-blur-md bg-gray-200 ', li: 'mb-2 ml-6', ul: 'mb-4 list-disc', ol: 'mb-4 list-decimal' diff --git a/stories/Chat.stories.tsx b/stories/Chat.stories.tsx index 09bb9da..d01773e 100644 --- a/stories/Chat.stories.tsx +++ b/stories/Chat.stories.tsx @@ -5,7 +5,8 @@ import { ChatInput, SessionMessagePanel, SessionMessage, - Session + Session, + AppBar } from '../src'; import { fakeSessions, @@ -15,6 +16,10 @@ import { import { useState } from 'react'; import Placeholder from '@/assets/placeholder.svg?react'; import PlaceholderDark from '@/assets/placeholder-dark.svg?react'; +import ReachatLogo from '@/assets/logo/logo.svg?react'; +import IconSearch from '@/assets/search.svg?react'; +import IconClose from '@/assets/close-fill.svg?react'; +import { IconButton } from 'reablocks'; export default { title: 'Demos/Chat', @@ -185,3 +190,76 @@ export const Empty = () => { ); }; + +export const WithAppBar = () => { + const [activeId, setActiveId] = useState(fakeSessions[0].id); + const [sessions, setSessions] = useState([ + ...fakeSessions, + ...sessionsWithFiles, + ...sessionWithSources + ]); + + return ( +
+ { + const newId = (sessions.length + 1).toLocaleString(); + setSessions([ + ...sessions, + { + id: newId, + title: `New Session #${newId}`, + createdAt: new Date(), + updatedAt: new Date(), + conversations: [] + } + ]); + setActiveId(newId); + }} + onSelectSession={setActiveId} + onDeleteSession={() => alert('delete!')} + > +
+ +
+ + + +
+
+ +
+
+ + + +
+
+ } + /> + + + + +
+ + + ); +}; diff --git a/stories/Companion.stories.tsx b/stories/Companion.stories.tsx index 2a8be7a..26efe6a 100644 --- a/stories/Companion.stories.tsx +++ b/stories/Companion.stories.tsx @@ -8,7 +8,8 @@ import { ChatInput, SessionMessagePanel, SessionMessagesHeader, - Session + Session, + AppBar } from '../src'; import { fakeSessions, @@ -16,9 +17,13 @@ import { sessionsWithFiles } from './examples'; import { useState } from 'react'; +import { IconButton } from 'reablocks'; import Placeholder from '@/assets/placeholder.svg?react'; import PlaceholderDark from '@/assets/placeholder-dark.svg?react'; +import ReachatLogo from '@/assets/logo/logo.svg?react'; +import IconSearch from '@/assets/search.svg?react'; +import IconClose from '@/assets/close-fill.svg?react'; export default { title: 'Demos/Companion', @@ -116,3 +121,78 @@ export const Empty = () => { ); }; + +export const WithAppBar = () => { + const [activeId, setActiveId] = useState(); + const [sessions, setSessions] = useState([ + ...fakeSessions, + ...sessionsWithFiles, + ...sessionWithSources + ]); + return ( +
+ { + const newId = (sessions.length + 1).toLocaleString(); + setSessions([ + ...sessions, + { + id: newId, + title: `New Session #${newId}`, + createdAt: new Date(), + updatedAt: new Date(), + conversations: [] + } + ]); + setActiveId(newId); + }} + onSelectSession={setActiveId} + onDeleteSession={() => alert('delete!')} + > + +
+ + + +
+
+ +
+
+ + + +
+
+ } + /> + + + + + + + + + + + + ); +}; diff --git a/stories/Console.stories.tsx b/stories/Console.stories.tsx index 2ac507d..a082672 100644 --- a/stories/Console.stories.tsx +++ b/stories/Console.stories.tsx @@ -16,7 +16,7 @@ import { SessionMessagesHeader, ChatContext, SessionMessage, - Conversation + AppBar } from '../src'; import { Card, @@ -46,6 +46,9 @@ import { sessionsWithPartialConversation, sessionWithCSVFiles } from './examples'; +import ReachatLogo from '@/assets/logo/logo.svg?react'; +import IconSearch from '@/assets/search.svg?react'; +import IconClose from '@/assets/close-fill.svg?react'; export default { title: 'Demos/Console',